Compare commits

...

8 Commits

10 changed files with 88 additions and 71 deletions

View File

@ -7,8 +7,7 @@ import jnr.ffi.Runtime;
import jnr.ffi.annotations.IgnoreError;
import jnr.ffi.annotations.LongLong;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings({"UnnecessaryModifier", "SpellCheckingInspection", "unused"})
public interface LuaJNR {
@ -34,7 +33,7 @@ public interface LuaJNR {
@IgnoreError
public long lua_atpanic(@NotNull Pointer luaState, @LongLong long fn);
@IgnoreError
public long luaL_traceback(@NotNull Pointer luaState, @NotNull Pointer forState, @NotNull String message, int level);
public long luaL_traceback(@NotNull Pointer luaState, @NotNull Pointer forState, @Nullable 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.

View File

@ -1,7 +1,10 @@
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.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.io.readBinaryString
import ru.dbotthepony.kommons.io.readVarInt
@ -48,10 +51,16 @@ class StarboundPak(val path: File, callback: (finished: Boolean, status: String)
get() = false
private var frozen = false
private val innerChildren = Object2ObjectLinkedOpenHashMap<String, IStarboundFile>()
private var innerChildren: Object2ObjectMap<String, IStarboundFile> = Object2ObjectArrayMap(2)
fun put(value: IStarboundFile) {
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
}
@ -61,7 +70,8 @@ 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()})")
}
override val children: Map<String, IStarboundFile> = Collections.unmodifiableMap(innerChildren)
override var children: Map<String, IStarboundFile> = Object2ObjectMaps.unmodifiable(innerChildren)
private set
fun freeze() {
check(!frozen) { "Already frozen" }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -327,6 +327,10 @@ class MonsterEntity(val variant: MonsterVariant, level: Double? = null) : ActorE
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> {
val notifications = statusController.experienceDamage(damage.request)
val totalDamage = notifications.sumOf { it.healthLost }

View File

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

View File

@ -90,6 +90,8 @@ local entityTypes = {
local function entityTypeNamesToIntegers(input, fullName)
if input then
local output = {}
for i, v in ipairs(input) do
-- 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
@ -99,10 +101,10 @@ local function entityTypeNamesToIntegers(input, fullName)
error('invalid entity type ' .. tostring(v) .. ' for ' .. fullName .. ' in types table at index ' .. i, 3)
end
input[i] = lookup
output[i] = lookup
end
return input
return output
end
end