diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/EntryPoint.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/EntryPoint.kt index aa7ca1042..ef2cca203 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/EntryPoint.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/EntryPoint.kt @@ -1,5 +1,7 @@ package net.torvald.terrarum.modulecomputers +import net.torvald.terrarum.CommonResourcePool +import net.torvald.terrarum.ItemSheet import net.torvald.terrarum.ModMgr import net.torvald.terrarum.ModuleEntryPoint @@ -11,6 +13,14 @@ class EntryPoint : ModuleEntryPoint() { private val moduleName = "dwarventech" override fun invoke() { + + // load common resources to the AssetsManager + CommonResourcePool.addToLoadingList("$moduleName.items") { + ItemSheet(ModMgr.getGdxFile(moduleName, "items/items.tga")) + } + CommonResourcePool.loadAll() + + ModMgr.GameItemLoader.invoke(moduleName) ModMgr.GameBlockLoader.invoke(moduleName) ModMgr.GameWatchdogLoader.register(moduleName, NetFrameWatchdog()) diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/WirePieceNetworkBus.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/WirePieceNetworkBus.kt new file mode 100644 index 000000000..efc926c3a --- /dev/null +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/WirePieceNetworkBus.kt @@ -0,0 +1,79 @@ +package net.torvald.terrarum.modulecomputers.gameitems + +import net.torvald.terrarum.CommonResourcePool +import net.torvald.terrarum.WireCodex +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameitems.FixtureInteractionBlocked +import net.torvald.terrarum.gameitems.GameItem +import net.torvald.terrarum.gameitems.ItemID +import net.torvald.terrarum.modulebasegame.gameitems.BlockBase + +/** + * Created by minjaesong on 2025-03-30. + */ +class WirePieceNetworkBus(originalID: ItemID, private val atlasID: String, private val sheetX: Int, private val sheetY: Int) + : GameItem(originalID), FixtureInteractionBlocked { + + override var dynamicID: ItemID = originalID + override var baseMass = 0.001 + override var baseToolSize: Double? = null + override var inventoryCategory = Category.WIRE + override val canBeDynamic = false + override val materialId = "" + init { + itemImage = CommonResourcePool.getAsItemSheet(atlasID).get(sheetX, sheetY) + } + + init { + equipPosition = GameItem.EquipPosition.HAND_GRIP + originalName = "ITEM_NETWORK_BUS_WIRE" + tags.addAll(WireCodex[originalID].tags) + } + + override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long { + return BlockBase.wireStartPrimaryUse(actor,this, delta) + } + + override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) { + BlockBase.wireEffectWhenEquipped(this, delta) + } + + override fun effectOnUnequip(actor: ActorWithBody) { + BlockBase.wireEffectWhenUnequipped(this) + } +} + +/** + * Created by minjaesong on 2025-03-30. + */ +class WirePieceIOBus(originalID: ItemID, private val atlasID: String, private val sheetX: Int, private val sheetY: Int) + : GameItem(originalID), FixtureInteractionBlocked { + + override var dynamicID: ItemID = originalID + override var baseMass = 0.001 + override var baseToolSize: Double? = null + override var inventoryCategory = Category.WIRE + override val canBeDynamic = false + override val materialId = "" + init { + itemImage = CommonResourcePool.getAsItemSheet(atlasID).get(sheetX, sheetY) + } + + init { + equipPosition = GameItem.EquipPosition.HAND_GRIP + originalName = "ITEM_IO_BUS_WIRE" + tags.addAll(WireCodex[originalID].tags) + } + + override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long { + return BlockBase.wireStartPrimaryUse(actor,this, delta) + } + + override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) { + BlockBase.wireEffectWhenEquipped(this, delta) + } + + override fun effectOnUnequip(actor: ActorWithBody) { + BlockBase.wireEffectWhenUnequipped(this) + } +} \ No newline at end of file diff --git a/assets/mods/dwarventech/blocks/blocks.csv b/assets/mods/dwarventech/blocks/blocks.csv new file mode 100644 index 000000000..6ab032c66 --- /dev/null +++ b/assets/mods/dwarventech/blocks/blocks.csv @@ -0,0 +1,84 @@ +"id";"drop";"spawn";"name";"shdr";"shdg";"shdb";"shduv";"str";"dsty";"mate";"solid";"wall";"grav";"dlfn";"fv";"fr";"lumr";"lumg";"lumb";"lumuv";"refl";"tags" + + +## Notes ## +# +# Every block must have a shade value that is at least as dark as the air block's +# +# Lava/Water props are left for future references, do not delete them until FluidCodex is built # +# +# id: Block ID. ID equal to or greater than 4096 is for fluids, mainly for lighting calculation. +# drop: Which item the DroppedItem actually adds to your inventory +# spawn: Which item the DroppedItem should impersonate when spawned +# +# Drop and World can point to the item from other modules (usually 'basegame') +# To achieve that, specify the full ID, e.g. basegame:32 +# When no module ID is specified, the current module will be assumed. +# +# shdr/g/b, lumr/g/b: Shade RGB/ Lum RGB. +# valid range: float of 0..4; 1.0 for 255 +# +# solid: whether the tile has full collision (affects physics; flowers are not solid, glass is solid) +# clear: [PENDING FOR REMOVAL] whether the tile has trnasparency (affects render; flowers AND glass is clear) +# +# vscs: viscosity, (velocity) / (1 + (n/16)), 16 halves movement speed, can be used to non-fluid tiles (sticky hazard, tarmac road in Terraria) +# +# str: Strength of the block against the mining action. Larger value will make the block take longer time to be mined +# +# dsty: density. As we are putting water an 1000, it is identical to specific gravity. [g/l] +# +# dlfn: dynamic luminosity function. +# 0-static, 1-torch flicker, 2-current global light (sun, star, moon), 3-daylight at noon, +# 4-slow breath, 5-pulsate +# +# mate: material, four-letter code +# +# fv: vertical friction (boolean) +# fr: horizontal friction. 0: frictionless, <16: slippery, 16: regular, >16: sticky +# +# grav: Whether the block should fall through the empty space. N/A to not make it fall; +# 0 to fall immediately (e.g. Sand), nonzero to indicate that number of floating blocks can be supported (e.g. Scaffolding) +# +# +## Illuminators ## +# +# Illuminator white: Mercury Lamp; CIELAB of (94, -5.131, 10.613), which is made out of CIEXYZ of (0.947638, 1.146481, 0.482263), measured with ColorMunki Spectrometer (If you don't want green tinge, collect a daylight!) +# Illuminator orange: Sodium Lamp; CIE xy of (0.5375, 0.4153), CIEXYZ of (352.531139, 272.379377, 30.980339), measured with ColorMunki Spectrometer +# Defalut torch : Y 64 x 0.55183 y 0.40966 (Planckian ~1 770 K); real candlelight colour taken from Spyder5 colorimeter (for I couldn't afford i1DisplayPro/Colormunki -- at least back then!) +# Sunstone: Artificial sunlight, change colour over time in sync with sunlight. The light is set by game's code. +# Sunlight capacitor: daylight at noon. Set by game's code. +# +# BLOCK_ILLUMINATOR_CYAN is actually a SUPER_LUMINATOR, cyan colour is used as: +# 1. It has quite a brightness on RGB colour space +# 2. Helmholz-Kohlraush effect +# +# +## Tiles ## +# +# 16 colour palette : games's 16-colour palette +# Magical ice: theoretical __metallic__ ice that might form under super-high pressure (> 5 TPa). Its density is a wild guess. +# +# +## Actorblocks ## +# +# Actorblocks are virtual/placeholder blocks that accompanies actors (usually fixtures). +# Actorblocks are recognised by the "ACTORBLOCK" tag. +# +## Tags ## +# +# Tag(s) to the item which is used by the crafting system and the game's internals. Multiple tags are separated using commas. +# Each tag must be all uppercase and only [0-9A-Z] chars are supported. +# +### Internal Tags ## +## +## Some tags are reserved for internal use, which are: +## - INTERNAL: denotes that the tile is internal-use. +## - DORENDER: this internal tile must go through the standard-issue tile drawing routine. +## - INCONSEQUENTIAL: denotes that this tile can be overwritten without dropping it. Usually used with flower tiles. +# +# +## References ## +# +# * Density of various woods : http://www.engineeringtoolbox.com/wood-density-d_40.html +# * Density of various phases of ice : http://www1.lsbu.ac.uk/water/ice_phases.html +# diff --git a/assets/mods/dwarventech/items/items.tga b/assets/mods/dwarventech/items/items.tga index 8b912f445..3e63bc108 100644 --- a/assets/mods/dwarventech/items/items.tga +++ b/assets/mods/dwarventech/items/items.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98a0b60031d7ee6322371840a7a5360422e82c4afbf130da622bf9d312821e7c +oid sha256:2bd0d31a5ef701fcf01814dbf6f945a4275244a73e9d3920f8ba5ada7d9d3f05 size 2408466 diff --git a/assets/mods/dwarventech/wires/wires.csv b/assets/mods/dwarventech/wires/wires.csv index 6268ecaef..31cab7345 100644 --- a/assets/mods/dwarventech/wires/wires.csv +++ b/assets/mods/dwarventech/wires/wires.csv @@ -1,13 +1,13 @@ id;drop;name;renderclass;accept;inputcount;inputtype;outputtype;javaclass;inventoryimg;branching;tags -1;1;WIRE_THINNET;network;netframe;1;N/A;N/A;net.torvald.terrarum.modulecomputers.gameitems.WirePieceRingBus;dwarventech.items,7,4;0;"" -2;2;WIRE_IO_BUS;io_bus;io_bus;1;N/A;N/A;net.torvald.terrarum.modulecomputers.gameitems.WirePieceIOBus;dwarventech.items,7,4;0;"" +1;1;WIRE_THINNET;network;netframe;1;N/A;N/A;net.torvald.terrarum.modulecomputers.gameitems.WirePieceNetworkBus;dwarventech.items,0,1;1;"" +2;2;WIRE_IO_BUS;io_bus;io_bus;1;N/A;N/A;net.torvald.terrarum.modulecomputers.gameitems.WirePieceIOBus;dwarventech.items,1,1;1;"" # accept: which wiretype (defined elsewhere) the wires acceps. Use comma to separate multiple. N/A for electronic components (aka not wires) # inputcount: how many sides are input (outputcount is deduced from the inputcount). N/A for wires # inputtype: which wiretype it accepts. N/A for wires # outputtype: which wiretype it emits. N/A for wires -# branching: if this wire can have branches. 0: unable, 1: tee-only, 2: cross-only, 3: tee and cross. +# branching: if this wire can have branches. 0: unable and cannot be bent, 1: unable but can be bent, 2: tee-only, 3: cross-only, 4: tee and cross. # Something like a thicknet can't have branches # # comments diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index b00912a46..c37b64b27 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -37,6 +37,7 @@ import java.io.File import java.io.FileInputStream import java.io.FileNotFoundException import java.io.IOException +import java.lang.reflect.InvocationTargetException import java.net.MalformedURLException import java.net.URL import java.net.URLClassLoader @@ -525,12 +526,22 @@ object ModMgr { if (it == null) { val loadedClass = Class.forName(className) val loadedClassConstructor = loadedClass.getConstructor(*constructorTypes) - return loadedClassConstructor.newInstance(*initArgs) as T + try { + return loadedClassConstructor.newInstance(*initArgs) as T + } + catch (e: InvocationTargetException) { + throw InvocationTargetException(e, "Failed to load class '$className' with given constructor arguments") + } } else { val loadedClass = it.loadClass(className) val loadedClassConstructor = loadedClass.getConstructor(*constructorTypes) - return loadedClassConstructor.newInstance(*initArgs) as T + try { + return loadedClassConstructor.newInstance(*initArgs) as T + } + catch (e: InvocationTargetException) { + throw InvocationTargetException(e, "Failed to load class '$className' with given constructor arguments") + } } } } @@ -541,12 +552,22 @@ object ModMgr { if (it == null) { val loadedClass = Class.forName(className) val loadedClassConstructor = loadedClass.getConstructor() - return loadedClassConstructor.newInstance() as T + try { + return loadedClassConstructor.newInstance() as T + } + catch (e: InvocationTargetException) { + throw InvocationTargetException(e, "Failed to load class '$className' with zero constructor arguments") + } } else { val loadedClass = it.loadClass(className) val loadedClassConstructor = loadedClass.getConstructor() - return loadedClassConstructor.newInstance() as T + try { + return loadedClassConstructor.newInstance() as T + } + catch (e: InvocationTargetException) { + throw InvocationTargetException(e, "Failed to load class '$className' with zero constructor arguments") + } } } } diff --git a/src/net/torvald/terrarum/blockproperties/WireCodex.kt b/src/net/torvald/terrarum/blockproperties/WireCodex.kt index 2fbd04fb5..d9ba8e9d1 100644 --- a/src/net/torvald/terrarum/blockproperties/WireCodex.kt +++ b/src/net/torvald/terrarum/blockproperties/WireCodex.kt @@ -207,12 +207,14 @@ class WireCodex { val invImgSheet = invImgRef[0] val invImgX = invImgRef[1].toInt() val invImgY = invImgRef[2].toInt() - val className = record.get("javaclass") - val loadedClass = Class.forName(className) - val loadedClassConstructor = loadedClass.getConstructor(ItemID::class.java, String::class.java, Int::class.java, Int::class.java) - val loadedClassInstance = loadedClassConstructor.newInstance(prop.id, invImgSheet, invImgX, invImgY) - ItemCodex[prop.id] = loadedClassInstance as GameItem + + ModMgr.getJavaClass(modname, className, + arrayOf(ItemID::class.java, String::class.java, Int::class.java, Int::class.java), + arrayOf(prop.id, invImgSheet, invImgX, invImgY) + ).let { + ItemCodex[prop.id] = it + } printdbg(this, "Setting prop ${prop.id} ->>\t${prop.nameKey}") } diff --git a/src/net/torvald/terrarum/blockproperties/WireProp.kt b/src/net/torvald/terrarum/blockproperties/WireProp.kt index 646535cc8..6a900e126 100644 --- a/src/net/torvald/terrarum/blockproperties/WireProp.kt +++ b/src/net/torvald/terrarum/blockproperties/WireProp.kt @@ -19,7 +19,7 @@ class WireProp : TaggedProp { var inputType: String = "" var outputType: String = "" - var branching: Int = 0 // 0: can't; 1: tee-only, 2: cross-only, 3: tee and cross + var branching: Int = 0 // 0: can't; 1: can't but can be bent, 2: tee-only, 3: cross-only, 4: tee and cross /** * Mainly intended to be used by third-party modules diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt index ef077af2f..0e936503a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt @@ -119,7 +119,7 @@ object BlockBase { /** * This function assumes xy and oxy are neighboured and tiles are correctly placed * - * @param branching 0: no branching, 1: tee-only, 2: cross-only, 3: tee and cross + * @param branching 0: no branching, no bend, 1: no branching, yes bend, 2: tee-only, 3: cross-only, 4: tee and cross */ private fun setConnectivity(branching: Int, world: GameWorld, vec: Int, item: ItemID, x: Int, y: Int, ox: Int, oy: Int) { when (branching) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt index cbc73efc6..af580adf7 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemFileRef.kt @@ -83,6 +83,11 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { */ open var useItemHandler = "" + /** + * In which module the "useItemHandler" is located + */ + open var useItemHandlerModule = "basegame" + override var baseMass = 1.0 override var baseToolSize: Double? = null @@ -109,10 +114,7 @@ open class ItemFileRef(originalID: ItemID) : GameItem(originalID) { return if (useItemHandler.isNotBlank()) { try { if (classCache == null) { - val newClass = Class.forName(useItemHandler) - val newClassConstructor = newClass.getConstructor(/* no args defined */) - val newClassInstance = newClassConstructor.newInstance(/* no args defined */) - classCache = (newClassInstance as FileRefItemPrimaryUseHandler) + classCache = ModMgr.getJavaClass(useItemHandlerModule, useItemHandler) } classCache!!.use(this) } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt index 50258a60b..2c6e7591e 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIRemoCon.kt @@ -4,11 +4,8 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.App +import net.torvald.terrarum.* import net.torvald.terrarum.App.* -import net.torvald.terrarum.QNDTreeNode -import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.Yaml import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.TitleScreen @@ -60,7 +57,7 @@ open class UIRemoCon(val parent: TitleScreen, val treeRoot: QNDTreeNode) if (splittedNodeName?.size == 2 && node.data != null) { try { val tag = splittedNodeName[0].split(tagSep).getOrNull(1) - val attachedClass = loadClass(splittedNodeName[1]) // check existence + val attachedClass = loadClass("basegame", splittedNodeName[1]) // check existence screenNames[node.data!!] = splittedNodeName[1] // actual loading will by dynamic as some UIs need to be re-initialised as they're called } catch (e: java.lang.ClassNotFoundException) { @@ -70,11 +67,8 @@ open class UIRemoCon(val parent: TitleScreen, val treeRoot: QNDTreeNode) } } - private fun loadClass(name: String): UICanvas { - val newClass = Class.forName(name) - val newClassConstructor = newClass.getConstructor(this.javaClass) - val newClassInstance = newClassConstructor.newInstance(this) - return newClassInstance as UICanvas + private fun loadClass(module: String, name: String): UICanvas { + return ModMgr.getJavaClass(module, name, arrayOf(this.javaClass), arrayOf(this)) } private var mouseActionAvailable = true @@ -202,7 +196,7 @@ open class UIRemoCon(val parent: TitleScreen, val treeRoot: QNDTreeNode) printdbg(this, "$menuString has screen: ${screenNames.containsKey(menuString)}") screenNames[menuString]?.let { - val ui = loadClass(it) + val ui = loadClass("basegame", it) ui.setPosition(0,0) parent.uiFakeBlurOverlay.setAsOpen() ui.setAsOpen() diff --git a/work_files/graphics/items/dwarventech_items.kra b/work_files/graphics/items/dwarventech_items.kra index 04602b494..58a9f46be 100644 --- a/work_files/graphics/items/dwarventech_items.kra +++ b/work_files/graphics/items/dwarventech_items.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28be981d1986f6e9609edb8a51b1622cdb84bc2f9783e0f15664a7dd53fde2cf -size 129987 +oid sha256:38e0df9e70d4b9bf8608f70d43c394341cc0de61eb56dc30de4a4d459a286fe9 +size 150263