Loading item from module using Groovy

This commit is contained in:
Song Minjae
2017-04-26 23:53:22 +09:00
parent 05c9c8f5df
commit 49d3c9f55b
27 changed files with 291 additions and 67 deletions

View File

@@ -1,4 +1,4 @@
package net.torvald
package net.torvald.dataclass
import java.util.*

View File

@@ -2,7 +2,6 @@ package net.torvald.terrarum
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.ui.UIVitalMetre
/**

View File

@@ -1,21 +1,41 @@
package net.torvald.terrarum
import net.torvald.CSVFetcher
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.ItemCodex
import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
import java.io.File
import java.io.FileNotFoundException
import java.io.FileReader
import java.nio.file.FileSystems
import javax.script.ScriptEngineManager
import javax.script.Invocable
/**
* Modules Resource Manager
*
*
* NOTE!!: Usage of Groovy is only temporary; if Kotlin's "JSR 223" is no longer experimental and
* is readily available, ditch that Groovy.
*
*
* Created by SKYHi14 on 2017-04-17.
*/
object ModMgr {
data class ModuleMetadata(val order: Int, val isDir: Boolean, val desc: String, val libraries: Array<String>) {
data class ModuleMetadata(
val order: Int,
val isDir: Boolean,
val desc: String,
val entryPoint: String,
val libraries: Array<String>
) {
override fun toString() =
"\tModule #$order -- $desc\n" +
"\tEntry point: $entryPoint\n" +
"\tExternal libraries: ${libraries.joinToString(", ")}"
}
const val modDir = "./assets/modules"
@@ -38,12 +58,46 @@ object ModMgr {
println("[ModMgr] Loading module $moduleName")
val description = it[1]
val libs = it[2].split(';').toTypedArray()
val entryPoint = it[2]
val libs = it[3].split(';').toTypedArray()
val isDir = FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory
moduleInfo[moduleName] = ModuleMetadata(index, isDir, description, libs)
moduleInfo[moduleName] = ModuleMetadata(index, isDir, description, entryPoint, libs)
println(moduleInfo[moduleName])
// run entry script in entry point
if (entryPoint.isNotBlank()) {
val extension = entryPoint.split('.').last()
val engine = ScriptEngineManager().getEngineByExtension(extension)!!
val invocable = engine as Invocable
engine.eval(FileReader(getFile(moduleName, entryPoint)))
invocable.invokeFunction("invoke", moduleName)
}
println("[ModMgr] $moduleName loaded successfully")
}
/*val manager = ScriptEngineManager()
val factories = manager.engineFactories
for (f in factories) {
println("engine name:" + f.engineName)
println("engine version:" + f.engineVersion)
println("language name:" + f.languageName)
println("language version:" + f.languageVersion)
println("names:" + f.names)
println("mime:" + f.mimeTypes)
println("extension:" + f.extensions)
println("-----------------------------------------------")
}*/
/*val engine = ScriptEngineManager().getEngineByExtension("groovy")!!
engine.eval(FileReader(getFile("basegame", "/items/testpick.groovy")))
val newPick = (engine as Invocable).invokeFunction("invoke", 8449) as InventoryItem
ItemCodex[8449] = newPick*/
}
private fun checkExistence(module: String) {
@@ -74,4 +128,27 @@ object ModMgr {
return dir.listFiles()
}
}
object GameItemLoader {
val itemPath = "items/"
@JvmStatic operator fun invoke(module: String) {
val engine = ScriptEngineManager().getEngineByExtension("groovy")!!
val invocable = engine as Invocable
val csv = CSVFetcher.readFromModule(module, itemPath + "itemid.csv")
csv.forEach {
val filename = it["filename"].toString()
val script = getFile(module, itemPath + filename).readText()
val itemID = it["id"].toInt()
engine.eval(script)
ItemCodex[itemID] = invocable.invokeFunction("invoke", itemID) as InventoryItem
}
}
}
}

View File

@@ -69,7 +69,7 @@ class StateInGame : BasicGameState() {
var playableActorDelegate: PlayableActorDelegate? = null // DO NOT LATEINIT!
private set
internal val player: ActorHumanoid? // currently POSSESSED actor :)
val player: ActorHumanoid? // currently POSSESSED actor :)
get() = playableActorDelegate?.actor
var screenZoom = 1.0f

View File

@@ -4,6 +4,7 @@ import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.itemproperties.IVKey
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.ui.*
import org.newdawn.slick.*
@@ -58,6 +59,7 @@ class StateUITest : BasicGameState() {
override var durability: Float = 64f
override var stackable = false
override val isDynamic = true
override val material = Material(0,0,0,0,0,0,0,0,0,0.0)
})
actor.inventory.getByDynamicID(5656)!!.item.name = "Test tool"
@@ -74,6 +76,7 @@ class StateUITest : BasicGameState() {
override var inventoryCategory: String = InventoryItem.Category.MISC
override var stackable = false
override val isDynamic = false
override val material = Material(0,0,0,0,0,0,0,0,0,0.0)
})
actor.inventory.add(ItemCodex[16], 543)

View File

@@ -7,6 +7,8 @@ import net.torvald.imagefont.GameFontImpl
import net.torvald.JsonFetcher
import net.torvald.JsonWriter
import net.torvald.imagefont.TinyAlphNum
import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY
import net.torvald.terrarum.gameworld.toUint
import org.lwjgl.input.Controllers
import org.lwjgl.opengl.*
@@ -500,6 +502,12 @@ object Terrarum : StateBasedGame(GAME_NAME) {
return file // TODO TEST CODE
}
// for external scripts (e.g. Groovy)
@JvmStatic fun getMouseTileX(): Int = appgc.mouseTileX
@JvmStatic fun getMouseTileY(): Int = appgc.mouseTileY
}
fun main(args: Array<String>) {

View File

@@ -6,6 +6,7 @@ import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gamecontroller.EnumKeyFunc
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.realestate.LandUtil
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input
@@ -147,6 +148,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "(no name)"
override var stackable = false
override val isDynamic = false
override val material = Material(0,0,0,0,0,0,0,0,0,0.0)
}
override fun update(gc: GameContainer, delta: Int) {

View File

@@ -8,6 +8,7 @@ import net.torvald.terrarum.gameactors.ai.LuaAIWrapper
import net.torvald.terrarum.gamecontroller.mouseX
import net.torvald.terrarum.gamecontroller.mouseY
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.itemproperties.Material
import org.luaj.vm2.*
import org.luaj.vm2.compiler.LuaC
import org.luaj.vm2.lib.*
@@ -59,6 +60,7 @@ open class HumanoidNPC(
override val originalName: String = actorValue.getAsString(AVKey.NAME) ?: "NPC"
override var stackable = true
override val isDynamic = false
override val material = Material(0,0,0,0,0,0,0,0,0,0.0)
override fun secondaryUse(gc: GameContainer, delta: Int): Boolean {
try {

View File

@@ -230,7 +230,8 @@ class GameWorld(val width: Int, val height: Int) {
/**
* @return true if block is broken
*/
fun inflctTerrainDamage(x: Int, y: Int, damage: Float): Boolean {
fun inflictTerrainDamage(x: Int, y: Int, damage: Double): Boolean {
val damage = damage.toFloat()
val addr = LandUtil.getTileAddr(x, y)
//println("[GameWorld] ($x, $y) Damage: $damage")
@@ -261,7 +262,8 @@ class GameWorld(val width: Int, val height: Int) {
/**
* @return true if block is broken
*/
fun inflctWallDamage(x: Int, y: Int, damage: Float): Boolean {
fun inflictWallDamage(x: Int, y: Int, damage: Double): Boolean {
val damage = damage.toFloat()
val addr = LandUtil.getTileAddr(x, y)
if (wallDamages[addr] == null) { // add new

View File

@@ -15,7 +15,7 @@ object Calculate {
*
* TODO Newtons as unit?
*/
fun pickaxePower(actor: ActorHumanoid, material: Material): Float {
@JvmStatic fun pickaxePower(actor: ActorHumanoid, material: Material): Float {
return (4.0 * material.forceMod.toDouble().sqrt() * (actor.avStrength / 1000.0)).toFloat()
}

View File

@@ -75,7 +75,7 @@ abstract class InventoryItem : Comparable<InventoryItem>, Cloneable {
*/
open val equipPosition: Int = EquipPosition.NULL
open val material: Material? = null
abstract val material: Material
/**
* Apparent mass of the item. (basemass * scale^3)

View File

@@ -3,13 +3,11 @@ package net.torvald.terrarum.itemproperties
import net.torvald.point.Point2d
import net.torvald.terrarum.KVHashMap
import net.torvald.terrarum.gameactors.CanBeAnItem
import net.torvald.terrarum.itemproperties.InventoryItem
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY
import net.torvald.terrarum.itemproperties.IVKey
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.mapdrawer.TilesDrawer
import net.torvald.terrarum.mapdrawer.TilesDrawer.wallOverlayColour
@@ -56,6 +54,7 @@ object ItemCodex {
override var stackable = true
override var inventoryCategory = Category.BLOCK
override var isDynamic = false
override val material = Material(0,0,0,0,0,0,0,0,0,0.0)
init {
itemProperties[IVKey.ITEMTYPE] = if (i in ITEM_TILES)
@@ -104,7 +103,7 @@ object ItemCodex {
}
// test copper pickaxe
itemCodex[ITEM_STATIC.first] = object : InventoryItem() {
/*itemCodex[ITEM_STATIC.first] = object : InventoryItem() {
override val originalID = ITEM_STATIC.first
override var dynamicID = originalID
override val isUnique = false
@@ -117,11 +116,7 @@ object ItemCodex {
override var equipPosition = EquipPosition.HAND_GRIP
override var inventoryCategory = Category.TOOL
override val isDynamic = true
private val testmaterial = Material(
0,0,0,0,0,0,0,0,1,0.0 // quick test material Stone
)
override val material = Material(0,0,0,0,0,0,0,0,1,0.0)
init {
itemProperties[IVKey.ITEMTYPE] = IVKey.ItemType.PICK
@@ -150,10 +145,10 @@ object ItemCodex {
// filter passed, do the job
val swingDmgToFrameDmg = delta.toDouble() / actorvalue.getAsDouble(AVKey.ACTION_INTERVAL)!!
Terrarum.ingame!!.world.inflctTerrainDamage(
Terrarum.ingame!!.world.inflictTerrainDamage(
gc.mouseTileX,
gc.mouseTileY,
Calculate.pickaxePower(Terrarum.ingame!!.player!!, testmaterial) * swingDmgToFrameDmg.toFloat()
Calculate.pickaxePower(Terrarum.ingame!!.player!!, material) * swingDmgToFrameDmg
)
return true
}
@@ -164,9 +159,8 @@ object ItemCodex {
Terrarum.ingame!!.player!!.actorValue[AVKey.__ACTION_TIMER] = 0.0
return true
}
}
}*/
// TODO read prop in Lua and fill itemCodex
// read from save (if applicable) and fill dynamicItemDescription
}
@@ -188,6 +182,13 @@ object ItemCodex {
}
}
/**
* Mainly used by GameItemLoader
*/
operator fun set(code: Int, item: InventoryItem) {
itemCodex[code] = item
}
fun getItemImage(item: InventoryItem): Image {
// terrain
if (item.originalID in ITEM_TILES) {

View File

@@ -47,13 +47,13 @@ class ItemEffectsLuaAPI(g: Globals) {
class StrikeEarth : ThreeArgFunction() {
override fun call(x: LuaValue, y: LuaValue, power: LuaValue): LuaValue {
Terrarum.ingame!!.world.inflctTerrainDamage(x.checkint(), y.checkint(), power.checkdouble().toFloat())
Terrarum.ingame!!.world.inflictTerrainDamage(x.checkint(), y.checkint(), power.checkdouble())
return LuaValue.NONE
}
}
class StrikeWall : ThreeArgFunction() {
override fun call(x: LuaValue, y: LuaValue, power: LuaValue): LuaValue {
Terrarum.ingame!!.world.inflctWallDamage(x.checkint(), y.checkint(), power.checkdouble().toFloat())
Terrarum.ingame!!.world.inflictWallDamage(x.checkint(), y.checkint(), power.checkdouble())
return LuaValue.NONE
}
}

View File

@@ -1,6 +1,6 @@
package net.torvald.terrarum.mapgenerator
import net.torvald.IntArrayStack
import net.torvald.dataclass.IntArrayStack
import net.torvald.colourutil.Col4096
import net.torvald.random.HQRNG
import org.newdawn.slick.Color

View File

@@ -17,7 +17,7 @@ constructor(override var width: Int, isBlackVariant: Boolean) : UICanvas {
private var segmentRight: Image? = null
private var segmentBody: Image? = null
private lateinit var messagesList: Array<String>
var messagesList: Array<String>
override var height: Int = 0
private val messageWindowRadius: Int