Compare commits

..

No commits in common. "826419b5459ad7abc6e62192c857a0967c3c596b" and "f9b339c0e487390dc49ea2ea50c9bb16b29c82b5" have entirely different histories.

10 changed files with 71 additions and 88 deletions

View File

@ -7,7 +7,8 @@ import jnr.ffi.Runtime;
import jnr.ffi.annotations.IgnoreError; import jnr.ffi.annotations.IgnoreError;
import jnr.ffi.annotations.LongLong; import jnr.ffi.annotations.LongLong;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
@SuppressWarnings({"UnnecessaryModifier", "SpellCheckingInspection", "unused"}) @SuppressWarnings({"UnnecessaryModifier", "SpellCheckingInspection", "unused"})
public interface LuaJNR { public interface LuaJNR {
@ -33,7 +34,7 @@ public interface LuaJNR {
@IgnoreError @IgnoreError
public long lua_atpanic(@NotNull Pointer luaState, @LongLong long fn); public long lua_atpanic(@NotNull Pointer luaState, @LongLong long fn);
@IgnoreError @IgnoreError
public long luaL_traceback(@NotNull Pointer luaState, @NotNull Pointer forState, @Nullable String message, int level); public long luaL_traceback(@NotNull Pointer luaState, @NotNull Pointer forState, @NotNull String message, int level);
/** /**
* Creates a new thread, pushes it on the stack, and returns a pointer to a lua_State that represents this new thread. The new thread returned by this function shares with the original thread its global environment, but has an independent execution stack. * Creates a new thread, pushes it on the stack, and returns a pointer to a lua_State that represents this new thread. The new thread returned by this function shares with the original thread its global environment, but has an independent execution stack.

View File

@ -1,10 +1,7 @@
package ru.dbotthepony.kstarbound.io package ru.dbotthepony.kstarbound.io
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap
import it.unimi.dsi.fastutil.objects.Object2ObjectMap
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps
import ru.dbotthepony.kommons.gson.get import ru.dbotthepony.kommons.gson.get
import ru.dbotthepony.kommons.io.readBinaryString import ru.dbotthepony.kommons.io.readBinaryString
import ru.dbotthepony.kommons.io.readVarInt import ru.dbotthepony.kommons.io.readVarInt
@ -51,16 +48,10 @@ class StarboundPak(val path: File, callback: (finished: Boolean, status: String)
get() = false get() = false
private var frozen = false private var frozen = false
private var innerChildren: Object2ObjectMap<String, IStarboundFile> = Object2ObjectArrayMap(2) private val innerChildren = Object2ObjectLinkedOpenHashMap<String, IStarboundFile>()
fun put(value: IStarboundFile) { fun put(value: IStarboundFile) {
check(!frozen) { "Can't put, already frozen!" } check(!frozen) { "Can't put, already frozen!" }
if (innerChildren is Object2ObjectArrayMap && innerChildren.size >= 8) {
innerChildren = Object2ObjectLinkedOpenHashMap(innerChildren)
children = Object2ObjectMaps.unmodifiable(innerChildren)
}
innerChildren[value.name] = value innerChildren[value.name] = value
} }
@ -70,8 +61,7 @@ class StarboundPak(val path: File, callback: (finished: Boolean, status: String)
return innerChildren.computeIfAbsent(name, Object2ObjectFunction { SBDirectory(it as String, this) }) as? SBDirectory ?: throw IllegalStateException("$name already exists (in ${computeFullPath()})") return innerChildren.computeIfAbsent(name, Object2ObjectFunction { SBDirectory(it as String, this) }) as? SBDirectory ?: throw IllegalStateException("$name already exists (in ${computeFullPath()})")
} }
override var children: Map<String, IStarboundFile> = Object2ObjectMaps.unmodifiable(innerChildren) override val children: Map<String, IStarboundFile> = Collections.unmodifiableMap(innerChildren)
private set
fun freeze() { fun freeze() {
check(!frozen) { "Already frozen" } check(!frozen) { "Already frozen" }

View File

@ -71,13 +71,15 @@ class LuaSharedState(val handlesThread: LuaThread, private val cleanable: Cleana
val peek = it.peek() val peek = it.peek()
if (peek == LuaType.STRING) { if (peek == LuaType.STRING) {
val err = LuaRuntimeException(it.lua.traceback(it.lua.getString(), 1)) it.lua.traceback(it.lua.getString()!!, 1)
val err = LuaRuntimeException(it.lua.getString())
it.lua.push(err) it.lua.push(err)
} else if (peek == LuaType.USERDATA) { } else if (peek == LuaType.USERDATA) {
val obj = it.nextObject<Any>() val obj = it.nextObject<Any>()
if (obj is Throwable && obj !is LuaRuntimeException) { if (obj is Throwable && obj !is LuaRuntimeException) {
val err = LuaRuntimeException(it.lua.traceback(obj.toString(), 1), cause = obj, writeStackTrace = false) it.lua.traceback(obj.toString(), 1)
val err = LuaRuntimeException(it.lua.getString(), cause = obj, writeStackTrace = false)
it.lua.push(err) it.lua.push(err)
} }
} }

View File

@ -340,9 +340,8 @@ class LuaThread private constructor(
return callConditional(numResults, { block(this); true })!! return callConditional(numResults, { block(this); true })!!
} }
fun traceback(message: String? = null, level: Int = 0): String { fun traceback(message: String, level: Int = 0) {
LuaJNR.INSTANCE.luaL_traceback(pointer, pointer, message, level) LuaJNR.INSTANCE.luaL_traceback(pointer, pointer, message, level)
return popString()!!
} }
fun invokeGlobal(name: String): Boolean { fun invokeGlobal(name: String): Boolean {
@ -1213,13 +1212,10 @@ class LuaThread private constructor(
fun nextBoolean(position: Int = this.position++): Boolean { fun nextBoolean(position: Int = this.position++): Boolean {
if (position !in 1 ..this.top) if (position !in 1 ..this.top)
return false throw IllegalArgumentException("bad argument #$position: boolean expected, got nil")
return when (typeAt(position)) { return this@LuaThread.getBoolean(position)
LuaType.NONE, LuaType.NIL -> false ?: throw IllegalArgumentException("bad argument #$position: boolean expected, got ${this@LuaThread.typeAt(position)}")
LuaType.BOOLEAN -> this@LuaThread.getBooleanRaw(position)
else -> true
}
} }
} }
@ -1669,18 +1665,8 @@ class LuaThread private constructor(
val num = value.asNumber val num = value.asNumber
when (num) { when (num) {
is Int, is Long -> push(num.toLong()) is Int, is Long -> this.push(num.toLong())
is Float, is Double -> push(num.toDouble()) else -> this.push(num.toDouble())
else -> {
// lazy parsed number
val str = value.asString
if (str.none { it == '.' } || str.endsWith(".0")) {
push(num.toLong())
} else {
push(num.toDouble())
}
}
} }
} else if (value.isString) { } else if (value.isString) {
this.push(value.asString) this.push(value.asString)
@ -1725,8 +1711,7 @@ class LuaThread private constructor(
} }
override fun toString(): String { override fun toString(): String {
val p = pointer.address().toString(16) return "LuaThread at ${pointer.address()}"
return "LuaThread at 0x${if (p.length < 12) "0".repeat(12 - p.length) else ""}${p}"
} }
companion object { companion object {

View File

@ -271,8 +271,8 @@ fun provideAnimatorBindings(self: Animator, lua: LuaThread) {
lua.pushBinding(self, "rotateGroup", ::rotateGroup) lua.pushBinding(self, "rotateGroup", ::rotateGroup)
lua.pushBinding(self, "currentRotationAngle", ::currentRotationAngle) lua.pushBinding(self, "currentRotationAngle", ::currentRotationAngle)
lua.pushBinding(self, "targetRotationAngle", ::targetRotationAngle) lua.pushBinding(self, "targetRotationAngle", ::targetRotationAngle)
lua.pushBinding(self, "translateTransformationGroup", ::translateTransformGroup) lua.pushBinding(self, "translateTransformGroup", ::translateTransformGroup)
lua.pushBinding(self, "rotateTransformationGroup", ::rotateTransformGroup) lua.pushBinding(self, "rotateTransformGroup", ::rotateTransformGroup)
lua.pushBinding(self, "scaleTransformationGroup", ::scaleTransformationGroup) lua.pushBinding(self, "scaleTransformationGroup", ::scaleTransformationGroup)
lua.pushBinding(self, "transformTransformationGroup", ::transformTransformationGroup) lua.pushBinding(self, "transformTransformationGroup", ::transformTransformationGroup)
lua.pushBinding(self, "resetTransformationGroup", ::resetTransformationGroup) lua.pushBinding(self, "resetTransformationGroup", ::resetTransformationGroup)

View File

@ -286,7 +286,6 @@ private fun createBehaviorTree(args: LuaThread.ArgStack): Int {
push(blackboard) push(blackboard)
push(root) push(root)
push(mergedParams.name)
}[0] }[0]
args.lua.call { args.lua.call {

View File

@ -613,7 +613,7 @@ class ActorMovementController() : MovementController() {
if (isGroundMovement) { if (isGroundMovement) {
this.isRunning = isRunning && controlMove != null this.isRunning = isRunning && controlMove != null
this.isWalking = !isRunning && controlMove != null this.isWalking = !isRunning && controlMove != null
this.isCrouching = controlCrouch && controlMove == null this.isCrouching = controlCrouch && controlMove != null
} }
isFlying = controlFly != null isFlying = controlFly != null

View File

@ -327,10 +327,6 @@ class MonsterEntity(val variant: MonsterVariant, level: Double? = null) : ActorE
private val deathDamageKinds = ObjectArraySet<String>() private val deathDamageKinds = ObjectArraySet<String>()
override fun toString(): String {
return "MonsterEntity[${variant.type}@${variant.seed} / ${if (isInWorld) world.toString() else "not in world"} / $position]"
}
override fun experienceDamage(damage: DamageRequestPacket): List<DamageNotification> { override fun experienceDamage(damage: DamageRequestPacket): List<DamageNotification> {
val notifications = statusController.experienceDamage(damage.request) val notifications = statusController.experienceDamage(damage.request)
val totalDamage = notifications.sumOf { it.healthLost } val totalDamage = notifications.sumOf { it.healthLost }

View File

@ -71,13 +71,7 @@ local function blackboardSet(self, t, key, value)
end end
function blackboardPrototype:set(t, key, value) function blackboardPrototype:set(t, key, value)
local lookup = mappedParameterTypes[t] blackboardSet(self, mappedParameterTypes[t], key, value)
if not lookup then
error('unknown blackboard value type ' .. tostring(t))
end
blackboardSet(self, lookup, key, value)
end end
function blackboardPrototype:setRaw(t, key, value) function blackboardPrototype:setRaw(t, key, value)
@ -269,18 +263,21 @@ do
return FAILURE return FAILURE
end end
if nodeStatus == nil then
--table.remove(stack)
return RUNNING
end
if nodeExtra ~= nil then if nodeExtra ~= nil then
blackboard:setOutput(self, nodeExtra) blackboard:setOutput(self, nodeExtra)
end end
--table.remove(stack) --table.remove(stack)
if nodeStatus == nil then if nodeStatus then
return RUNNING
elseif nodeStatus == false then
return FAILURE
else
return SUCCESS return SUCCESS
else
return FAILURE
end end
end end
end end
@ -345,12 +342,22 @@ do
return FAILURE return FAILURE
end end
if nodeStatus == true then if nodeStatus == nil then
local s = coroutine_status(coroutine)
if s == 'dead' then
-- quite unexpected, but whatever
--table.remove(stack)
return SUCCESS
else
self.coroutine = coroutine
end
elseif nodeStatus then
--table.remove(stack)
return SUCCESS return SUCCESS
elseif nodeStatus == false then
return FAILURE
else else
self.coroutine = coroutine --table.remove(stack)
return FAILURE
end end
end end
@ -370,10 +377,27 @@ do
return FAILURE return FAILURE
end end
if nodeStatus == true then if nodeStatus == nil then
return SUCCESS -- another yield OR unexpected return?
elseif nodeStatus == false then
return FAILURE local s = coroutine_status(self.coroutine)
if s == 'dead' then
self.coroutine = nil
--table.remove(stack)
return SUCCESS
end
else
-- yield or return with status
self.coroutine = nil
if nodeStatus then
--table.remove(stack)
return SUCCESS
else
--table.remove(stack)
return FAILURE
end
end end
end end
end end
@ -437,9 +461,6 @@ function seqNode:run(delta, blackboard, stack)
self.index = self.index + 1 self.index = self.index + 1
end end
if isSelector then return FAILURE end
return SUCCESS
end end
function seqNode:reset() function seqNode:reset()
@ -573,19 +594,13 @@ function dynNode:run(delta, blackboard, stack)
self.calls = self.calls + 1 self.calls = self.calls + 1
--table.insert(stack, 'DynamicNode') --table.insert(stack, 'DynamicNode')
local i = 1 for i, node in ipairs(self.children) do
local children = self.children local status = runAndReset(node, delta, blackboard, stack)
while i <= self.index do if stauts == FAILURE and self.index == i then
local child = children[i]
local status = runAndReset(child, delta, blackboard, stack)
if status == FAILURE and i == self.index then
self.index = self.index + 1 self.index = self.index + 1
end elseif status ~= RUNNING and i < self.index then
node:reset()
if i < self.index and (status == SUCCESS or status == RUNNING) then
child:reset()
self.index = i self.index = i
end end
@ -593,8 +608,6 @@ function dynNode:run(delta, blackboard, stack)
--table.remove(stack) --table.remove(stack)
return status return status
end end
i = i + 1
end end
--table.remove(stack) --table.remove(stack)
@ -679,10 +692,9 @@ end
local statePrototype = {} local statePrototype = {}
statePrototype.__index = statePrototype statePrototype.__index = statePrototype
function statePrototype:ctor(blackboard, root, name) function statePrototype:ctor(blackboard, root)
self.root = root self.root = root
self._blackboard = blackboard self._blackboard = blackboard
self.name = name or 'unnamed'
return self return self
end end

View File

@ -90,8 +90,6 @@ local entityTypes = {
local function entityTypeNamesToIntegers(input, fullName) local function entityTypeNamesToIntegers(input, fullName)
if input then if input then
local output = {}
for i, v in ipairs(input) do for i, v in ipairs(input) do
-- could have used string.lower, but original engine does case-sensitive comparison here -- could have used string.lower, but original engine does case-sensitive comparison here
-- so we can save quite a lot cpu cycles for ourselves by not doing string.lower -- so we can save quite a lot cpu cycles for ourselves by not doing string.lower
@ -101,10 +99,10 @@ local function entityTypeNamesToIntegers(input, fullName)
error('invalid entity type ' .. tostring(v) .. ' for ' .. fullName .. ' in types table at index ' .. i, 3) error('invalid entity type ' .. tostring(v) .. ' for ' .. fullName .. ' in types table at index ' .. i, 3)
end end
output[i] = lookup input[i] = lookup
end end
return output return input
end end
end end