mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbe887b039 | ||
|
|
91798436cb | ||
|
|
34415f720d | ||
|
|
33b739f34f | ||
|
|
f3825c0bfb | ||
|
|
84f1c48159 | ||
|
|
514a972bcf | ||
|
|
f19a27065e | ||
|
|
324128e86a | ||
|
|
39fca59ea7 | ||
|
|
f07a6f6430 | ||
|
|
6c5ee14402 | ||
|
|
ec7ff3199d | ||
|
|
f400a5afe7 | ||
|
|
ea1702ace4 | ||
|
|
01b5569169 | ||
|
|
374cd5d4f7 | ||
|
|
c0cf9ab17d | ||
|
|
db0d3379cc | ||
|
|
42e7da2a4a | ||
|
|
30caac283a | ||
|
|
5da4cee22e | ||
|
|
ddfa2f5bf0 | ||
|
|
7d38ba866c | ||
|
|
a773786c9e | ||
|
|
43e16bf785 | ||
|
|
7906de1711 | ||
|
|
6c3ec20b3d | ||
|
|
902a086a4f | ||
|
|
91bf11a3e0 | ||
|
|
410456e173 | ||
|
|
9caf2a0d7e | ||
|
|
9525441dc0 | ||
|
|
f7b0dfb5bb | ||
|
|
549c03c2b4 | ||
|
|
91c5105a12 | ||
|
|
063483cfda | ||
|
|
a5953b8c87 | ||
|
|
c568276df6 | ||
|
|
19405b7f8d | ||
|
|
2e89dcc73a | ||
|
|
d3fe2e2bc6 | ||
|
|
5c18e03bad | ||
|
|
11a7a1f48d | ||
|
|
d24ec8296f | ||
|
|
2c1727e495 | ||
|
|
b9e7a4ba84 |
@@ -10,7 +10,6 @@
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Build Version Number" run_configuration_type="Application" />
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="ModuleComputers" />
|
||||
<artifact name="MusicPlayer" />
|
||||
<artifact name="TerrarumBuild" />
|
||||
</option>
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="QuickDirtyLint" run_configuration_type="Application" />
|
||||
|
||||
BIN
assets/graphics/gui/gradtile32.tga
LFS
Normal file
BIN
assets/graphics/gui/gradtile32.tga
LFS
Normal file
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
"17";"17";"17";"BLOCK_STONE_QUARRIED";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURAL,OREBEARING,SHALLOWROCK"
|
||||
"18";"18";"18";"BLOCK_STONE_TILE_WHITE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.18";"STONE,NORANDTILE"
|
||||
"19";"19";"19";"BLOCK_STONE_BRICKS";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"STONE,NORANDTILE"
|
||||
"20";"20";"20";"BLOCK_STONE_DEEP";"0.1252";"0.1252";"0.1252";"0.1252";"80";"24600";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURA,OREBEARING,DEEPROCK"
|
||||
"20";"20";"20";"BLOCK_STONE_DEEP";"0.1252";"0.1252";"0.1252";"0.1252";"80";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"ROCK,NATURA,OREBEARING,DEEPROCK"
|
||||
"21";"21";"21";"BLOCK_STONE_MARBLE";"0.1252";"0.1252";"0.1252";"0.1252";"48";"2400";"ROCK";"1";"1";"N/A";"0";"4";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.1";"ROCK,NATURAL,DEEPROCK"
|
||||
|
||||
# dirts
|
||||
@@ -67,7 +67,7 @@
|
||||
"149";"149";"149";"BLOCK_GLASS_CLEAN";"0.0424";"0.0424";"0.0424";"0.0636";"5";"2203";"GLAS";"1";"1";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"GLASS,NORANDTILE"
|
||||
|
||||
# platforms
|
||||
"160";"160";"160";"BLOCK_PLATFORM_STONE";"0.0312";"0.0312";"0.0312";"0.0312";"5";"2400";"ROCK";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM"
|
||||
"160";"160";"160";"BLOCK_PLATFORM_STONE";"0.0312";"0.0312";"0.0312";"0.0312";"5";"2400";"ROCK";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM,"
|
||||
"161";"161";"161";"BLOCK_PLATFORM_WOODEN";"0.0312";"0.0312";"0.0312";"0.0312";"5";"740";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM,WOODEN"
|
||||
"162";"162";"162";"BLOCK_PLATFORM_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"5";"1200";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM,WOODEN"
|
||||
"163";"163";"163";"BLOCK_PLATFORM_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"5";"670";"WOOD";"0";"0";"N/A";"0";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"PLATFORM,WOODEN"
|
||||
@@ -125,10 +125,10 @@
|
||||
"258";"258";"258";"BLOCK_DAYLIGHT_CAPACITOR";"0.1252";"0.1252";"0.1252";"0.1252";"1";"2500";"GLAS";"1";"0";"N/A";"3";"0";"16";"0.0000";"0.0000";"0.0000";"0.0000";"N/A";"N/A";"0.0";"LIGHT,NORANDTILE"
|
||||
|
||||
# more platforms
|
||||
"272";"272";"272";"BLOCK_SCAFFOLDING_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"1";"740";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,NORANDTILE,WOODEN"
|
||||
"273";"273";"273";"BLOCK_SCAFFOLDING_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1400";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,NORANDTILE,WOODEN"
|
||||
"274";"274";"274";"BLOCK_SCAFFOLDING_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"1";"670";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,NORANDTILE,WOODEN"
|
||||
"275";"275";"275";"BLOCK_SCAFFOLDING_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"1";"900";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,NORANDTILE,WOODEN"
|
||||
"272";"272";"272";"BLOCK_SCAFFOLDING_NORMAL";"0.0312";"0.0312";"0.0312";"0.0312";"1";"740";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,SCAFFOLDING,NORANDTILE,WOODEN"
|
||||
"273";"273";"273";"BLOCK_SCAFFOLDING_EBONY";"0.0312";"0.0312";"0.0312";"0.0312";"1";"1400";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,SCAFFOLDING,NORANDTILE,WOODEN"
|
||||
"274";"274";"274";"BLOCK_SCAFFOLDING_BIRCH";"0.0312";"0.0312";"0.0312";"0.0312";"1";"670";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,SCAFFOLDING,NORANDTILE,WOODEN"
|
||||
"275";"275";"275";"BLOCK_SCAFFOLDING_ROSEWOOD";"0.0312";"0.0312";"0.0312";"0.0312";"1";"900";"WOOD";"0";"0";"6";"0";"0";"16";"0.0";"0.0";"0.0";"0.0";"N/A";"N/A";"0.0";"PLATFORM,SCAFFOLDING,NORANDTILE,WOODEN"
|
||||
|
||||
# for future use
|
||||
"288";"288";"288";"BLOCK_PLASTIC_WHITE"; "0.0903";"0.0903";"0.0903";"0.1752";"36";"660";"PLST";"1";"1";"N/A";"0";"0";"16";"0";"0";"0";"0";"N/A";"N/A";"0.06";"THERMOPLASTIC,NORANDTILE"
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 18 and column 2.
|
@@ -1,3 +1,6 @@
|
||||
->Lang:MENU_OPTIONS_GAMEPLAY->h1
|
||||
gameplay_max_crafting->Lang:MENU_OPTIONS_MAX_CRAFTING->spinner,100,1000,100
|
||||
showpickaxetooltip->Lang:MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING->toggle
|
||||
showpickaxetooltip->Lang:MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING->toggle
|
||||
->Lang:MENU_OPTIONS_UNIT_OF_MEASUREMENT->h1
|
||||
gameplay_unit_distance->Lang:MENU_OPTIONS_DISTANCE_UNIT->textsel,meter=MENU_OPTIONS_UNIT_METRIC,foot=MENU_OPTIONS_UNIT_FEET,block=MENU_OPTIONS_UNIT_BLOCKS
|
||||
gameplay_unit_temperature->Lang:MENU_OPTIONS_TEMPERATURE_UNIT->textsel,celsius=MENU_OPTIONS_UNIT_CELSIUS_DNT,fahrenheit=MENU_OPTIONS_UNIT_FAHRENHEIT_DNT,kelvin=MENU_OPTIONS_UNIT_KELVIN_DNT
|
||||
|
@@ -32,25 +32,25 @@
|
||||
"basegame:272": { /* scaffolding */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 2, "item@basegame:18", 2, "basegame:161"] /* 2 sticks and 2 platform */
|
||||
[2, 2, "item@basegame:18", 2, "basegame:48"] /* 2 sticks and 2 wood */
|
||||
]
|
||||
},
|
||||
"basegame:273": { /* scaffolding */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 2, "item@basegame:18", 2, "basegame:162"] /* 2 sticks and 2 platform */
|
||||
[2, 2, "item@basegame:18", 2, "basegame:49"] /* 2 sticks and 2 wood */
|
||||
]
|
||||
},
|
||||
"basegame:274": { /* scaffolding */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 2, "item@basegame:18", 2, "basegame:163"] /* 2 sticks and 2 platform */
|
||||
[2, 2, "item@basegame:18", 2, "basegame:50"] /* 2 sticks and 2 wood */
|
||||
]
|
||||
},
|
||||
"basegame:275": { /* scaffolding */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 2, "item@basegame:18", 2, "basegame:164"] /* 2 sticks and 2 platform */
|
||||
[2, 2, "item@basegame:18", 2, "basegame:51"] /* 2 sticks and 2 wood */
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,12 @@
|
||||
[1, 20, "$ROCK", 10, "item@basegame:25", 10, "item@basegame:113"] /* 1 smelter = 20 rocks, 10 clay balls, 10 iron ingots */
|
||||
]
|
||||
},
|
||||
"item@basegame:36": { /* wire rolling mill */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 1, "$WOOD", 2, "$ROCK", 5, "item@basegame:113"] /* 1 plank, 2 stone, 5 iron ingot */
|
||||
]
|
||||
},
|
||||
|
||||
"item@basegame:256": { /* oak door */
|
||||
"workbench": "basiccrafting",
|
||||
@@ -59,7 +65,25 @@
|
||||
"item@basegame:6": { /* storage chest */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 20, "$WOOD"] /* 1 chest = 20 wood */
|
||||
[1, 20, "basegame:48"] /* 1 chest = 20 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:37": { /* storage chest */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 20, "basegame:49"] /* 1 chest = 20 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:38": { /* storage chest */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 20, "basegame:50"] /* 1 chest = 20 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:39": { /* storage chest */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 20, "basegame:51"] /* 1 chest = 20 wood */
|
||||
]
|
||||
},
|
||||
|
||||
@@ -68,5 +92,30 @@
|
||||
"ingredients": [
|
||||
[1, 4, "item@basegame:144", 14, "$WOOD", 10, "item@basegame:113"] /* 1 turntable = 4 quartz, 14 wood, 10 iron */
|
||||
]
|
||||
},
|
||||
|
||||
"item@basegame:40": { /* table */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 10, "basegame:48"] /* 10 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:41": { /* table */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 10, "basegame:49"] /* 10 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:42": { /* table */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 10, "basegame:50"] /* 10 wood */
|
||||
]
|
||||
},
|
||||
"item@basegame:43": { /* table */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[1, 10, "basegame:51"] /* 10 wood */
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
{
|
||||
"item@basegame:31": { /* gunpowder */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[3, 1, "item@basegame:147", 1, "item@basegame:29", 1, "item@basegame:129"]] /* 1 nitre, 1 charcoal, 1 iron ore */
|
||||
"ingredients": [[8, 3, "item@basegame:147", 1, "item@basegame:29"]] /* 3 nitre, 1 charcoal */
|
||||
},
|
||||
"item@basegame:32": { /* cherry bomb */
|
||||
"workbench": "",
|
||||
"ingredients": [[1, 1, "item@basegame:31", 1, "item@basegame:25"]] /* 1 gunpowder, 1 clay ball */
|
||||
},
|
||||
"item@basegame:34": { /* signal switch */
|
||||
"workbench": "",
|
||||
"ingredients": [[2, 1, "item@basegame:112", 1, "$ROCK", 1, "$WOOD"]] /* 1 copper ingot, 1 rock, 1 planks */
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,65 @@
|
||||
{
|
||||
"item@basegame:14": { /* wooden pick */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[1, 6, "$WOOD", 2, "item@basegame:18"]] /* 6 woods, 2 sticks */
|
||||
"ingredients": [[1, 5, "$WOOD", 2, "item@basegame:18"]] /* 5 woods, 2 sticks */
|
||||
},
|
||||
/*"item@basegame:22": {
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[1, 6, "$WOOD", 2, "item@basegame:18"]]
|
||||
"ingredients": [[1, 5, "$WOOD", 2, "item@basegame:18"]]
|
||||
},*/
|
||||
"item@basegame:15": { /* wooden mallet */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[1, 6, "$WOOD", 2, "item@basegame:18"]]
|
||||
"ingredients": [[1, 5, "$WOOD", 2, "item@basegame:18"]]
|
||||
},
|
||||
"item@basegame:23": { /* stone pick */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[1, 6, "$ROCK", 2, "item@basegame:18"]]
|
||||
"ingredients": [[1, 5, "$ROCK", 2, "item@basegame:18"]]
|
||||
},
|
||||
"item@basegame:24": { /* stone axe */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [[1, 6, "$ROCK", 2, "item@basegame:18"]]
|
||||
"ingredients": [[1, 5, "$ROCK", 2, "item@basegame:18"]]
|
||||
},
|
||||
|
||||
"item@basegame:1": { /* copper pick */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:112", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:112", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:2": { /* iron pick */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:113", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:113", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:3": { /* steel pick */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:26", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:26", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
|
||||
"item@basegame:12": { /* copper sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:112", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:112", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:4": { /* iron sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:113", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:113", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:13": { /* steel sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:26", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:26", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
|
||||
"item@basegame:19": { /* copper sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:112", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:112", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:20": { /* iron sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:113", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:113", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:21": { /* steel sledgehammer */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 6, "item@basegame:26", 2, "item@basegame:18"]] /* 6 bars, 2 sticks */
|
||||
"ingredients": [[1, 5, "item@basegame:26", 2, "item@basegame:18"]] /* 5 bars, 2 sticks */
|
||||
},
|
||||
"item@basegame:9": { /* wire cutter */
|
||||
"workbench": "basiccrafting,metalworking",
|
||||
"ingredients": [[1, 1, "item@basegame:112", 1, "item@basegame:113"]] /* 1 copper ingot, 1 iron ingot */
|
||||
}
|
||||
}
|
||||
44
assets/mods/basegame/crafting/wires.json
Normal file
44
assets/mods/basegame/crafting/wires.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"wire@basegame:8192": { /* signal wire red */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 1, "$SIGNALWIRE"] /* 1 other signal wire */
|
||||
]
|
||||
},
|
||||
"wire@basegame:8193": { /* signal wire green */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 1, "$SIGNALWIRE"] /* 1 other signal wire */
|
||||
] },
|
||||
"wire@basegame:8194": { /* signal wire blue */
|
||||
"workbench": "",
|
||||
"ingredients": [
|
||||
[1, 1, "$SIGNALWIRE"] /* 1 other signal wire */
|
||||
]
|
||||
},
|
||||
|
||||
"wire@basegame:8192": { /* signal wire red */
|
||||
"workbench": "wirerollingmill",
|
||||
"ingredients": [
|
||||
[10, 1, "item@basegame:112"] /* 1 copper */
|
||||
]
|
||||
},
|
||||
"wire@basegame:8193": { /* signal wire green */
|
||||
"workbench": "wirerollingmill",
|
||||
"ingredients": [
|
||||
[10, 1, "item@basegame:112"] /* 1 copper */
|
||||
] },
|
||||
"wire@basegame:8194": { /* signal wire blue */
|
||||
"workbench": "wirerollingmill",
|
||||
"ingredients": [
|
||||
[10, 1, "item@basegame:112"] /* 1 copper */
|
||||
]
|
||||
},
|
||||
|
||||
"item@basegame:35": { /* copper bulb */
|
||||
"workbench": "basiccrafting",
|
||||
"ingredients": [
|
||||
[2, 1, "item@basegame:112", 1, "item@basegame:113"] /* 1 copper, 1 iron */
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"gameplay_max_crafting": 100,
|
||||
"showpickaxetooltip": true
|
||||
"showpickaxetooltip": true,
|
||||
"gameplay_unit_distance": "meter",
|
||||
"gameplay_unit_temperature": "celsius"
|
||||
}
|
||||
@@ -6,7 +6,7 @@ id;classname;tags
|
||||
5;net.torvald.terrarum.modulebasegame.gameitems.ItemTikiTorch;FIXTURE,LIGHT
|
||||
6;net.torvald.terrarum.modulebasegame.gameitems.ItemStorageChest;FIXTURE,STORAGE
|
||||
7;net.torvald.terrarum.modulebasegame.gameitems.WireGraphDebugger;TOOL,WIRE
|
||||
8;net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter;FIXTURE
|
||||
8;net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter;FIXTURE,SIGNAL
|
||||
9;net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll;TOOL,WIRE
|
||||
10;net.torvald.terrarum.modulebasegame.gameitems.ItemTypewriter;FIXTURE,PRINTING
|
||||
11;net.torvald.terrarum.modulebasegame.gameitems.ItemWallCalendar;FIXTURE
|
||||
@@ -20,7 +20,7 @@ id;classname;tags
|
||||
19;net.torvald.terrarum.modulebasegame.gameitems.AxeCopper;TOOL,AXE
|
||||
20;net.torvald.terrarum.modulebasegame.gameitems.AxeIron;TOOL,AXE
|
||||
21;net.torvald.terrarum.modulebasegame.gameitems.AxeSteel;TOOL,AXE
|
||||
#22;net.torvald.terrarum.modulebasegame.gameitems.AxeWood;TOOL,AXE
|
||||
22;net.torvald.terrarum.modulebasegame.gameitems.AxeWood;TOOL,AXE
|
||||
23;net.torvald.terrarum.modulebasegame.gameitems.PickaxeStone;TOOL,PICK
|
||||
24;net.torvald.terrarum.modulebasegame.gameitems.AxeStone;TOOL,AXE
|
||||
25;net.torvald.terrarum.modulebasegame.gameitems.ItemClayBall;
|
||||
@@ -32,6 +32,16 @@ id;classname;tags
|
||||
31;net.torvald.terrarum.modulebasegame.gameitems.ItemGunpowder;POWDER,EXPLOSIVE
|
||||
32;net.torvald.terrarum.modulebasegame.gameitems.ItemCherryBomb;EXPLOSIVE,THROWABLE
|
||||
33;net.torvald.terrarum.modulebasegame.gameitems.ItemTorch;FIXTURE,LIGHT
|
||||
34;net.torvald.terrarum.modulebasegame.gameitems.ItemSignalSwitchManual;FIXTURE,SIGNAL
|
||||
35;net.torvald.terrarum.modulebasegame.gameitems.ItemSignalBulb;FIXTURE,SIGNAL
|
||||
36;net.torvald.terrarum.modulebasegame.gameitems.ItemWireRollingMill;FIXTURE,CRAFTING
|
||||
37;net.torvald.terrarum.modulebasegame.gameitems.ItemStorageChestEbony;FIXTURE,STORAGE
|
||||
38;net.torvald.terrarum.modulebasegame.gameitems.ItemStorageChestBirch;FIXTURE,STORAGE
|
||||
39;net.torvald.terrarum.modulebasegame.gameitems.ItemStorageChestRosewood;FIXTURE,STORAGE
|
||||
40;net.torvald.terrarum.modulebasegame.gameitems.ItemTable;FIXTURE,SURFACE
|
||||
41;net.torvald.terrarum.modulebasegame.gameitems.ItemTableEbony;FIXTURE,SURFACE
|
||||
42;net.torvald.terrarum.modulebasegame.gameitems.ItemTableBirch;FIXTURE,SURFACE
|
||||
43;net.torvald.terrarum.modulebasegame.gameitems.ItemTableRosewood;FIXTURE,SURFACE
|
||||
|
||||
# ingots
|
||||
26;net.torvald.terrarum.modulebasegame.gameitems.IngotSteel;INGOT
|
||||
|
||||
|
Binary file not shown.
15
assets/mods/basegame/locales/en/configmenu.json
Normal file
15
assets/mods/basegame/locales/en/configmenu.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"MENU_MONITOR_CALI_TITLE": "Check Monitor",
|
||||
"MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING": "Show Ore Tooltip When Mining",
|
||||
"MENU_OPTIONS_MAX_CRAFTING": "Max Number of Items for Crafting",
|
||||
"MENU_OPTIONS_UNIT_BLOCKS": "Blocks",
|
||||
"MENU_OPTIONS_UNIT_FEET": "Imperial",
|
||||
"MENU_OPTIONS_UNIT_METRIC": "Metric",
|
||||
"MENU_OPTIONS_UNIT_OF_MEASUREMENT": "Unit of Measurement",
|
||||
"MENU_OPTIONS_DISTANCE_UNIT": "Distance",
|
||||
"MENU_OPTIONS_TEMPERATURE_UNIT": "Temperature",
|
||||
|
||||
"MENU_OPTIONS_UNIT_CELSIUS_DNT": "°C",
|
||||
"MENU_OPTIONS_UNIT_FAHRENHEIT_DNT": "°F",
|
||||
"MENU_OPTIONS_UNIT_KELVIN_DNT": "K"
|
||||
}
|
||||
@@ -13,9 +13,6 @@
|
||||
"MENU_LABEL_RENAME": "Rename",
|
||||
"MENU_LABEL_USE_CODE": "Use Code",
|
||||
"MENU_MODE_BUILDINGMAKER": "POI Editor",
|
||||
"MENU_MONITOR_CALI_TITLE": "Check Monitor",
|
||||
"MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING": "Show Ore Tooltip When Mining",
|
||||
"MENU_OPTIONS_MAX_CRAFTING": "Max Number of Items for Crafting",
|
||||
"MENU_UPDATE_UPDATE_AVAILABLE": "Update Available!",
|
||||
"GAME_ACTION_GRAPPLE": "Grapple",
|
||||
"GAME_ACTION_QUICKSEL": "Quick Select",
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"TOOLTIP_item@basegame:4": "Breaks down walls",
|
||||
"TOOLTIP_item@basegame:5": "Provides light but fancier",
|
||||
"TOOLTIP_item@basegame:6": "“I am sworn to keep your burdens.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:37": "“I am sworn to keep your burdens.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:38": "“I am sworn to keep your burdens.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:39": "“I am sworn to keep your burdens.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:8": "Emits a signal",
|
||||
"TOOLTIP_item@basegame:9": "An electricians’ best friend",
|
||||
"TOOLTIP_item@basegame:10": "“Who needs a Book and Quill when you’ve got this?”", /* a jab on the Minecraft item Book and Quill */
|
||||
@@ -31,6 +34,7 @@
|
||||
"TOOLTIP_item@basegame:20": "Cuts trees",
|
||||
"TOOLTIP_item@basegame:21": "Cuts trees",
|
||||
"TOOLTIP_item@basegame:22": "Cuts trees, just barely",
|
||||
/*"TOOLTIP_item@basegame:22": "Perhaps it’s more useful for casting than actually using",*/
|
||||
"TOOLTIP_item@basegame:23": "Breaks rocks",
|
||||
"TOOLTIP_item@basegame:24": "Cuts trees",
|
||||
"TOOLTIP_item@basegame:25": "Finer grains of dirts that gets stronger when burned",
|
||||
@@ -38,6 +42,7 @@
|
||||
"TOOLTIP_item@basegame:27": "Every blacksmith gotta start from somewhere",
|
||||
"TOOLTIP_item@basegame:28": "A music vending machine (free to play)",
|
||||
"TOOLTIP_item@basegame:29": "A coal lookalike that burns just as well and is renewable",
|
||||
"TOOLTIP_item@basegame:36": "Creates wires from metal ingots",
|
||||
|
||||
"TOOLTIP_item@basegame:114": "A precious fuel for the steel production",
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"ITEM_CHARCOAL": "Charcoal",
|
||||
"ITEM_CHERRY_BOMB": "Bomb",
|
||||
"ITEM_COAL_COKE": "Coal Coke",
|
||||
"ITEM_COPPER_BULB": "Copper Bulb",
|
||||
"ITEM_DOOR_OAK": "Oak Door",
|
||||
"ITEM_DOOR_EBONY": "Ebony Door",
|
||||
"ITEM_DOOR_BIRCH": "Birch Door",
|
||||
@@ -37,6 +38,7 @@
|
||||
"ITEM_INGOT_ZINC": "Zinc Ingot",
|
||||
"ITEM_JUKEBOX": "Jukebox",
|
||||
"ITEM_LOGIC_SIGNAL_EMITTER": "Logic Signal Emitter",
|
||||
"ITEM_LOGIC_SIGNAL_SWITCH": "Logic Signal Switch",
|
||||
"ITEM_LOGS_BIRCH": "Birch Logs",
|
||||
"ITEM_LOGS_EBONY": "Ebony Logs",
|
||||
"ITEM_LOGS_OAK": "Oak Logs",
|
||||
@@ -65,11 +67,16 @@
|
||||
"ITEM_SLEDGEHAMMER_STEEL": "Steel Sledgehammer",
|
||||
"ITEM_SMELTER_SMALL": "Small Smelter",
|
||||
"ITEM_STORAGE_CHEST": "Storage Chest",
|
||||
"ITEM_TABLE_OAK": "Oak Table",
|
||||
"ITEM_TABLE_EBONY": "Ebony Table",
|
||||
"ITEM_TABLE_BIRCH": "Birch Table",
|
||||
"ITEM_TABLE_ROSEWOOD": "Rosewood Table",
|
||||
"ITEM_TIKI_TORCH": "Tiki Torch",
|
||||
"ITEM_TURNTABLE": "Turntable",
|
||||
"ITEM_TYPEWRITER": "Typewriter",
|
||||
"ITEM_WIRE": "Wire",
|
||||
"ITEM_WIRE_CUTTER": "Wire Cutter",
|
||||
"ITEM_WIRE_ROLLING_MILL": "Wire Rolling Mill",
|
||||
"ITEM_WOOD_STICK": "Stick",
|
||||
"ITEM_WOODEN_MALLET": "Wooden Mallet",
|
||||
"ITEM_WORKBENCH": "Workbench",
|
||||
|
||||
11
assets/mods/basegame/locales/koKR/configmenu.json
Normal file
11
assets/mods/basegame/locales/koKR/configmenu.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||
"MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING": "채굴 시 광석 툴팁 보이기",
|
||||
"MENU_OPTIONS_MAX_CRAFTING": "한번에 제작할 최대 아이템 수",
|
||||
"MENU_OPTIONS_UNIT_BLOCKS": "블록",
|
||||
"MENU_OPTIONS_UNIT_FEET": "피트",
|
||||
"MENU_OPTIONS_UNIT_METRIC": "미터",
|
||||
"MENU_OPTIONS_UNIT_OF_MEASUREMENT": "측정 단위",
|
||||
"MENU_OPTIONS_DISTANCE_UNIT": "거리",
|
||||
"MENU_OPTIONS_TEMPERATURE_UNIT": "온도"
|
||||
}
|
||||
@@ -12,9 +12,6 @@
|
||||
"MENU_LABEL_PREV_SAVES": "이전 세이브",
|
||||
"MENU_LABEL_RENAME": "이름 바꾸기",
|
||||
"MENU_LABEL_USE_CODE": "코드 사용",
|
||||
"MENU_MONITOR_CALI_TITLE": "모니터 확인",
|
||||
"MENU_OPTIONS_SHOW_ORES_TOOLTIP_WHEN_MINING": "채굴 시 광석 툴팁 보이기",
|
||||
"MENU_OPTIONS_MAX_CRAFTING": "한번에 제작할 최대 아이템 수",
|
||||
"MENU_UPDATE_UPDATE_AVAILABLE": "새 업데이트가 있습니다!",
|
||||
"GAME_ACTION_GRAPPLE": "매달리기",
|
||||
"GAME_ACTION_QUICKSEL": "빠른 선택",
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"TOOLTIP_item@basegame:4": "벽을 부숩니다",
|
||||
"TOOLTIP_item@basegame:5": "빛을 더 이쁘게 냅니다",
|
||||
"TOOLTIP_item@basegame:6": "“짐을 맡아두기로 한 몸이니까요.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:37": "“짐을 맡아두기로 한 몸이니까요.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:38": "“짐을 맡아두기로 한 몸이니까요.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:39": "“짐을 맡아두기로 한 몸이니까요.”", /* skyrim/lydia reference */
|
||||
"TOOLTIP_item@basegame:8": "신호를 만들어냅니다",
|
||||
"TOOLTIP_item@basegame:9": "전기공의 친한 친구",
|
||||
"TOOLTIP_item@basegame:10": "“이게 있는데 책과 깃펜이 왜 필요하죠?”", /* a jab on the Minecraft item Book and Quill */
|
||||
@@ -38,6 +41,7 @@
|
||||
"TOOLTIP_item@basegame:27": "모든 대장장이는 초보 시절이 있는 법이죠",
|
||||
"TOOLTIP_item@basegame:28": "음악 자판기입이다 (무료 플레이)",
|
||||
"TOOLTIP_item@basegame:29": "석탄과 비슷하고 똑같이 잘 타지만 재생 가능합니다",
|
||||
"TOOLTIP_item@basegame:36": "금속 주괴를 사용해 철사를 뽑아냅니다",
|
||||
|
||||
"TOOLTIP_item@basegame:114": "강철 생산의 소중한 연료입니다",
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"ITEM_CHARCOAL": "목탄",
|
||||
"ITEM_CHERRY_BOMB": "폭탄",
|
||||
"ITEM_COAL_COKE": "코크스",
|
||||
"ITEM_COPPER_BULB": "구리 전구",
|
||||
"ITEM_DOOR_OAK": "나무 문",
|
||||
"ITEM_DOOR_EBONY": "흑단 문",
|
||||
"ITEM_DOOR_BIRCH": "백단 문",
|
||||
@@ -37,6 +38,7 @@
|
||||
"ITEM_INGOT_ZINC": "아연괴",
|
||||
"ITEM_JUKEBOX": "주크박스",
|
||||
"ITEM_LOGIC_SIGNAL_EMITTER": "신호발생기",
|
||||
"ITEM_LOGIC_SIGNAL_SWITCH": "신호 스위치",
|
||||
"ITEM_LOGS_BIRCH": "백단 통나무",
|
||||
"ITEM_LOGS_EBONY": "흑단 통나무",
|
||||
"ITEM_LOGS_OAK": "통나무",
|
||||
@@ -65,11 +67,16 @@
|
||||
"ITEM_SLEDGEHAMMER_STEEL": "강철 해머",
|
||||
"ITEM_SMELTER_SMALL": "소형 고로",
|
||||
"ITEM_STORAGE_CHEST": "보관상자",
|
||||
"ITEM_TABLE_OAK": "나무 탁자",
|
||||
"ITEM_TABLE_EBONY": "흑단 탁자",
|
||||
"ITEM_TABLE_BIRCH": "백단 탁자",
|
||||
"ITEM_TABLE_ROSEWOOD": "자단 탁자",
|
||||
"ITEM_TIKI_TORCH": "티키 토치",
|
||||
"ITEM_TURNTABLE": "전축",
|
||||
"ITEM_TYPEWRITER": "타자기",
|
||||
"ITEM_WIRE": "전선",
|
||||
"ITEM_WIRE_CUTTER": "전선 절단기",
|
||||
"ITEM_WIRE_ROLLING_MILL": "철사 압연기",
|
||||
"ITEM_WOOD_STICK": "막대기",
|
||||
"ITEM_WOODEN_MALLET": "나무 망치",
|
||||
"ITEM_WORKBENCH": "작업대",
|
||||
|
||||
@@ -44,10 +44,10 @@ package=net.torvald.terrarum.modulebasegame
|
||||
entrypoint=net.torvald.terrarum.modulebasegame.EntryPoint
|
||||
|
||||
# Release date in YYYY-MM-DD
|
||||
releasedate=2024-02-19
|
||||
releasedate=2024-03-03
|
||||
|
||||
# The version, must follow Semver 2.0.0 scheme (https://semver.org/)
|
||||
version=0.4.0
|
||||
version=0.4.1
|
||||
|
||||
# External JAR that the module is compiled. If your module requires yet another library, the JAR must be compiled as a "Fatjar";
|
||||
# Due to security reasons, loading an arbitrary JAR is not allowed.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"id";"freq";"power";"scale";"ratio";"tiling";"comment";"blocktagnongrata"
|
||||
"1";"0.026";"0.010";"0.517";"1.0";"a16x16";"copper (malachite)";""
|
||||
"2";"0.045";"0.011";"0.517";"1.0";"a16x16";"iron (haematite)";""
|
||||
"2";"0.031";"0.011";"0.521";"1.0";"a16x16";"iron (haematite)";""
|
||||
"3";"0.017";"0.070";"0.511";"3.8";"a16x4";"coal";""
|
||||
"4";"0.019";"0.011";"0.511";"1.0";"a16x16";"zinc (sphalerite)";""
|
||||
"5";"0.017";"0.017";"0.511";"1.0";"a16x16";"tin (cassiterite)";""
|
||||
|
||||
|
BIN
assets/mods/basegame/sprites/fixtures/copper_bulb.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/copper_bulb.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/copper_bulb_emissive.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/copper_bulb_emissive.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/signal_switch.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/signal_switch.tga
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_2.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_2.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_3.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_3.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_4.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/storage_chest_4.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/table_1.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/table_1.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/table_2.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/table_2.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/table_3.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/table_3.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/table_4.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/table_4.tga
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/sprites/fixtures/wire_rolling_mill.tga
LFS
Normal file
BIN
assets/mods/basegame/sprites/fixtures/wire_rolling_mill.tga
LFS
Normal file
Binary file not shown.
@@ -1,11 +1,11 @@
|
||||
id;drop;name;renderclass;accept;inputcount;inputtype;outputtype;javaclass;inventoryimg;branching
|
||||
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,4;1
|
||||
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,1,4;1
|
||||
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,2,4;1
|
||||
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,0;1
|
||||
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,3,4;1
|
||||
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,4,4;1
|
||||
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,5,4;1
|
||||
id;drop;name;renderclass;accept;inputcount;inputtype;outputtype;javaclass;inventoryimg;branching;tags
|
||||
8192;8192;WIRE_RED;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,4;1;"SIGNALWIRE"
|
||||
8193;8193;WIRE_GREEN;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,1,4;1;"SIGNALWIRE"
|
||||
8194;8194;WIRE_BLUE;signal;digital_bit;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,2,4;1;"SIGNALWIRE"
|
||||
#8195;8195;WIRE_BUNDLE;signal;digital_3bits;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,0,0;1;"SIGNALWIRE"
|
||||
8196;8196;WIRE_POWER_LOW;power;power_low;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,3,4;1;"POWERWIRE_LOW"
|
||||
8197;8197;WIRE_POWER_HIGH;power;power_high;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,4,4;1;"POWERWIRE_HIGH"
|
||||
8198;8198;WIRE_ETHERNET;network;10base2;3;N/A;N/A;net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire;basegame.items,5,4;1;"ETHERNETWIRE"
|
||||
|
||||
|
||||
# accept: which wiretype (defined elsewhere) the wires acceps. Use comma to separate multiple. N/A for electronic components (aka not wires)
|
||||
|
||||
|
@@ -3,8 +3,8 @@ description=Simple music player widget
|
||||
author=CuriousTo\uA75Bvald
|
||||
package=net.torvald.terrarum.musicplayer
|
||||
entrypoint=net.torvald.terrarum.musicplayer.EntryPoint
|
||||
releasedate=2024-02-19
|
||||
version=1.0.0
|
||||
releasedate=2024-03-03
|
||||
version=1.0.1
|
||||
jar=MusicPlayer.jar
|
||||
jarhash=c8896ce5b2aa79057e1324a701c1c5bd4099a8a651f044a120ad700cedfbb16e
|
||||
dependency=basegame 0.4.0
|
||||
jarhash=53248a70a8cbfbcdd76e11549a132400305e91785ff98af514e68e8cafacdc19
|
||||
dependency=basegame 0.4.1
|
||||
|
||||
@@ -442,12 +442,12 @@ public class App implements ApplicationListener {
|
||||
|
||||
if (useFullscreen) {
|
||||
// auto resize for fullscreen
|
||||
var disp = Lwjgl3ApplicationConfiguration.getDisplayMode();
|
||||
var disp = Lwjgl3ApplicationConfiguration.getDisplayMode(Lwjgl3ApplicationConfiguration.getPrimaryMonitor());
|
||||
var newWidth = ((int)(disp.width / magn)) & 0x7FFFFFFE;
|
||||
var newHeight = ((int)(disp.height / magn)) & 0x7FFFFFFE;
|
||||
scr.setDimension(newWidth, newHeight, magn);
|
||||
|
||||
appConfig.setFullscreenMode(Lwjgl3ApplicationConfiguration.getDisplayMode());
|
||||
appConfig.setFullscreenMode(disp);
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -282,7 +282,6 @@ $BULLET Music:
|
||||
- music/discs/lucid_dream.ogg
|
||||
- music/discs/railway.ogg
|
||||
- music/discs/welded.ogg
|
||||
|
||||
℗ 2021, 2022, 2023, 2024 Orstphone
|
||||
Check out the original tracks on:
|
||||
Apple Music: <https://music.apple.com/kr/artist/orstphone/1587723053>
|
||||
@@ -300,7 +299,6 @@ $BULLET Foleys:
|
||||
- ambient/season/diurnal_winter.*.ogg
|
||||
- ambient/season/matutinal.*.ogg
|
||||
- ambient/season/nocturnal.*.ogg
|
||||
|
||||
℗ 2011, 2013, 2015, 2020, 2021 Klankbeeld
|
||||
Sound from <https://www.freesound.org/people/klankbeeld>
|
||||
|
||||
@@ -311,38 +309,31 @@ Sound from <https://www.freesound.org/people/klankbeeld>
|
||||
- effects/steps/WOOD.*.ogg
|
||||
- effects/door/wooden_open.*.ogg
|
||||
- effects/door/wooden_close.*.ogg
|
||||
|
||||
℗ 2020, 2021, 2022 Nox Sound
|
||||
Sound from <https://freesound.org/people/Nox_Sound>
|
||||
|
||||
- effects/static/phono_pops.ogg
|
||||
|
||||
℗ 2011 Veezay
|
||||
Sound from <https://freesound.org/people/veezay>
|
||||
|
||||
- effects/static/tape_hiss.ogg
|
||||
|
||||
℗ 2017 Stephen Holdaway
|
||||
Sound from <https://freesound.org/people/stecman>
|
||||
|
||||
- effects/static/film_pops_lowpass.ogg
|
||||
|
||||
℗ 2015 Joe DeShon
|
||||
Sound from <https://freesound.org/people/joedeshon>
|
||||
|
||||
- effects/static/bonfire.ogg
|
||||
|
||||
℗ 2019 DrinkingWindGames
|
||||
Sound from <https://freesound.org/people/DrinkingWindGames>
|
||||
|
||||
- effects/explosion/bang_bomb.ogg
|
||||
|
||||
℗ 2019 Richwise
|
||||
Sound from <https://freesound.org/people/richwise>
|
||||
|
||||
- effects/explosion/fuse.ogg
|
||||
- effects/explosion/fuse_continue.ogg
|
||||
|
||||
℗ 2012, 2015 j1987 and ScouseMouseJB
|
||||
Sound from <https://freesound.org/people/j1987> and <https://freesound.org/people/ScouseMouseJB>
|
||||
|
||||
@@ -351,12 +342,10 @@ Sound from <https://freesound.org/people/j1987> and <https://freesound.org/peopl
|
||||
$BULLET Impulse Responses:
|
||||
|
||||
- convolution/EchoThief - *.bin
|
||||
|
||||
EchoThief Impulse Response Library
|
||||
℗ 2013-2023 Chris Warren <cwarren@sdsu.edu>
|
||||
|
||||
- convolution/Soundwoofer - *.bin
|
||||
|
||||
Soundwoofer Free Impulse Response Library
|
||||
℗ 2018 Soundwoofer Team
|
||||
<https://soundwoofer.com/User/Index?uid=soundwoofer>
|
||||
|
||||
@@ -439,7 +439,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
}
|
||||
|
||||
open fun saveTheGame(onSuccessful: () -> Unit, onError: (Throwable) -> Unit) {
|
||||
|
||||
loadedTime_t = App.getTIME_T()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -561,13 +561,15 @@ object ModMgr {
|
||||
))
|
||||
}
|
||||
}
|
||||
Terrarum.wireCodex.fromModule(module, "wires/")
|
||||
Terrarum.wireCodex.fromModule(module, "wires/") { wire ->
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeNewItemObj(tile: BlockProp, isWall: Boolean) = object : GameItem(
|
||||
if (isWall) "wall@"+tile.id else tile.id
|
||||
) {
|
||||
override var baseMass: Double = tile.density / 100.0
|
||||
override var baseMass: Double = (tile.density / 100.0) * (if (tile.isPlatform) 0.5 else 1.0)
|
||||
override var baseToolSize: Double? = null
|
||||
override var inventoryCategory = if (isWall) Category.WALL else Category.BLOCK
|
||||
override var canBeDynamic = false
|
||||
|
||||
@@ -11,6 +11,8 @@ class Point2d() : Cloneable {
|
||||
var x: Double = 0.0
|
||||
var y: Double = 0.0
|
||||
|
||||
constructor(other: Point2d) : this(other.x, other.y)
|
||||
|
||||
constructor(x: Double, y: Double) : this() {
|
||||
this.x = x
|
||||
this.y = y
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum
|
||||
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.serialise.toUint
|
||||
import java.net.URL
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
@@ -48,6 +49,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
basegame
|
||||
"""
|
||||
|
||||
val FIXED_LATEST_DOWNLOAD_LINK = URL("https://github.com/curioustorvald/Terrarum/releases/latest")
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
@@ -66,12 +69,13 @@ basegame
|
||||
* e.g. 0x02010034 will be translated as 2.1.52
|
||||
*
|
||||
*/
|
||||
const val VERSION_RAW: Long = 0x0000_000004_000000
|
||||
const val VERSION_RAW: Long = 0x0000_000004_000001
|
||||
// Commit counts up to the Release 0.3.0: 2259
|
||||
// Commit counts up to the Release 0.3.1: 2278
|
||||
// Commit counts up to the Release 0.3.2: 2732
|
||||
// Commit counts up to the Release 0.3.3: 3020
|
||||
// Commit counts up to the Release 0.4.0: 3631
|
||||
// Commit counts up to the Release 0.4.1: 3678
|
||||
|
||||
// val VERSION_SNAPSHOT = Snapshot(0) // for normal dev
|
||||
// val VERSION_SNAPSHOT = ForcedSnapshot("24w07d") // for snapshot release
|
||||
|
||||
@@ -123,14 +123,22 @@ class AudioMixer : Disposable {
|
||||
* Return oldest dynamic track, even if the track is currently playing
|
||||
*/
|
||||
fun getFreeTrackNoMatterWhat(): TerrarumAudioMixerTrack {
|
||||
return getFreeTrack() ?: dynamicTracks.minBy { it.playStartedTime }
|
||||
synchronized(this) {
|
||||
return getFreeTrack() ?: dynamicTracks.minBy { it.playStartedTime }.also { it.checkedOutTime = System.nanoTime() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return oldest dynamic track that is not playing
|
||||
*/
|
||||
fun getFreeTrack(): TerrarumAudioMixerTrack? {
|
||||
return dynamicTracks.filter { it.trackingTarget == null && !it.isPlaying }.minByOrNull { it.playStartedTime }
|
||||
synchronized(this) {
|
||||
return dynamicTracks.filter { it.trackingTarget == null && !it.isPlaying }
|
||||
.minByOrNull { maxOf(it.checkedOutTime, it.playStartedTime) }
|
||||
.also {
|
||||
it?.checkedOutTime = System.nanoTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var listenerHeadSize = BinoPan.EARDIST_DEFAULT; private set
|
||||
@@ -144,6 +152,10 @@ class AudioMixer : Disposable {
|
||||
return (headSize0 ?: 0f).times(scale).coerceAtLeast(BinoPan.EARDIST_DEFAULT)
|
||||
}
|
||||
|
||||
private val millisecUnitTime = 100L // 48 * p, p is multiplied to compensate the time takes for writing samples
|
||||
private val sleepMS = App.audioBufferSize / millisecUnitTime
|
||||
private val sleepNS = (App.audioBufferSize / millisecUnitTime * 1000000).toInt() % 1000000
|
||||
|
||||
fun createProcessingThread(): Thread = Thread {
|
||||
// serial precessing
|
||||
while (processing) {
|
||||
@@ -168,6 +180,8 @@ class AudioMixer : Disposable {
|
||||
while (processing && !masterTrack.pcmQueue.isEmpty) {
|
||||
masterTrack.adev!!.writeSamples(masterTrack.pcmQueue.removeFirst()) // it blocks until the queue is consumed
|
||||
}
|
||||
|
||||
Thread.sleep(sleepMS, sleepNS)
|
||||
}
|
||||
|
||||
// parallel processing, it seems even on the 7950X this is less efficient than serial processing...
|
||||
|
||||
@@ -147,7 +147,7 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray)
|
||||
private val readBuf = ByteArray(fetchSize * 4)
|
||||
|
||||
init {
|
||||
printdbg(this, "App.audioMixerBufferSize=${App.audioBufferSize}")
|
||||
// printdbg(this, "App.audioMixerBufferSize=${App.audioBufferSize}")
|
||||
}
|
||||
|
||||
private fun shift(array: FloatArray, size: Int) {
|
||||
|
||||
@@ -103,6 +103,8 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
||||
return newRead
|
||||
}
|
||||
|
||||
var bufEmpty = true; private set
|
||||
|
||||
override fun run() {
|
||||
// while (running) { // uncomment to multithread
|
||||
/*synchronized(pauseLock) { // uncomment to multithread
|
||||
@@ -196,7 +198,7 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
||||
var samplesL1: FloatArray
|
||||
var samplesR1: FloatArray
|
||||
|
||||
var bufEmpty = false
|
||||
bufEmpty = false
|
||||
|
||||
// get samples and apply the fader
|
||||
if (track.trackType == TrackType.MASTER || track.trackType == TrackType.BUS) {
|
||||
@@ -379,15 +381,6 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
||||
}
|
||||
|
||||
|
||||
private fun <T> Queue<T>.removeFirstOrElse(function: () -> T): T {
|
||||
return if (this.isEmpty) {
|
||||
this.removeFirst()
|
||||
}
|
||||
else {
|
||||
function()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FeedSamplesToAdev(val bufferSize: Int, val rate: Int, val track: TerrarumAudioMixerTrack) : Runnable {
|
||||
init {
|
||||
|
||||
@@ -65,7 +65,7 @@ class TerrarumAudioMixerTrack(
|
||||
|
||||
internal val streamPlaying = AtomicBoolean(false)
|
||||
var playStartedTime = 0L; internal set
|
||||
|
||||
var checkedOutTime = 0L; internal set
|
||||
|
||||
fun copyStatusTo(other: TerrarumAudioMixerTrack) {
|
||||
other.pullNextTrack = this.pullNextTrack
|
||||
@@ -162,6 +162,9 @@ class TerrarumAudioMixerTrack(
|
||||
override fun equals(other: Any?) = this.hash == (other as TerrarumAudioMixerTrack).hash
|
||||
|
||||
fun stop() {
|
||||
printdbg("TerrarumAudioMixerTrack $name", "Stop music (mixertrack=${this.name}, musictrack=$currentTrack)")
|
||||
// printStackTrace("TerrarumAudioMixerTrack $name")
|
||||
|
||||
currentTrack?.reset()
|
||||
|
||||
streamPlaying.set(false)
|
||||
|
||||
@@ -53,7 +53,7 @@ class OreCodex {
|
||||
private fun setProp(modname: String, key: Int, record: CSVRecord) {
|
||||
val prop = OreProp()
|
||||
prop.id = "ores@$modname:$key"
|
||||
prop.tags = record.get("tags").split(',').map { it.trim() }.toHashSet()
|
||||
prop.tags = record.get("tags").split(',').map { it.trim().toUpperCase() }.toHashSet()
|
||||
prop.item = record.get("item").let { if (it == null) "" else if (it.contains(':')) it else "$modname:$it" }
|
||||
|
||||
oreProps[prop.id] = prop
|
||||
|
||||
@@ -39,15 +39,15 @@ class WireCodex {
|
||||
* @param module name of the module
|
||||
* @param path to the "wires" directory, not path to the CSV; must end with a slash!
|
||||
*/
|
||||
fun fromModule(module: String, path: String) {
|
||||
fun fromModule(module: String, path: String, blockRegisterHook: (WireProp) -> Unit) {
|
||||
printdbg(this, "Building wire properties table for module $module")
|
||||
try {
|
||||
register(module, path, CSVFetcher.readFromModule(module, path + "wires.csv"))
|
||||
register(module, path, CSVFetcher.readFromModule(module, path + "wires.csv"), blockRegisterHook)
|
||||
}
|
||||
catch (e: IOException) { e.printStackTrace() }
|
||||
}
|
||||
|
||||
fun fromCSV(module: String, path: String, csvString: String) {
|
||||
fun fromCSV(module: String, path: String, csvString: String, blockRegisterHook: (WireProp) -> Unit) {
|
||||
printdbg(this, "Building wire properties table for module $module")
|
||||
|
||||
val csvParser = org.apache.commons.csv.CSVParser.parse(
|
||||
@@ -57,10 +57,10 @@ class WireCodex {
|
||||
val csvRecordList = csvParser.records
|
||||
csvParser.close()
|
||||
|
||||
register(module, path, csvRecordList)
|
||||
register(module, path, csvRecordList, blockRegisterHook)
|
||||
}
|
||||
|
||||
private fun register(module: String, path: String, records: List<CSVRecord>) {
|
||||
private fun register(module: String, path: String, records: List<CSVRecord>, blockRegisterHook: (WireProp) -> Unit) {
|
||||
records.forEach {
|
||||
setProp(module, it.intVal("id"), it)
|
||||
}
|
||||
@@ -73,9 +73,12 @@ class WireCodex {
|
||||
val t = TextureRegionPack(ModMgr.getGdxFile(module, "$path$wireid.tga"), TILE_SIZE, TILE_SIZE)
|
||||
/*return*/t
|
||||
}
|
||||
|
||||
wireProps[id]?.let(blockRegisterHook)
|
||||
}
|
||||
|
||||
CommonResourcePool.loadAll()
|
||||
|
||||
}
|
||||
|
||||
fun getAll() = wireProps.values
|
||||
@@ -134,6 +137,7 @@ class WireCodex {
|
||||
prop.inputType = record.get("inputtype") ?: prop.accepts
|
||||
prop.outputType = record.get("outputtype") ?: prop.accepts
|
||||
prop.canBranch = record.boolVal("branching")
|
||||
prop.tags = record.get("tags").split(',').map { it.trim().toUpperCase() }.toHashSet()
|
||||
|
||||
wireProps[prop.id] = prop
|
||||
|
||||
|
||||
@@ -24,4 +24,18 @@ class WireProp {
|
||||
* Mainly intended to be used by third-party modules
|
||||
*/
|
||||
val extra = Codex()
|
||||
|
||||
@Transient var tags = HashSet<String>()
|
||||
|
||||
fun hasTag(s: String) = tags.contains(s)
|
||||
fun hasAnyTagOf(vararg s: String) = s.any { hasTag(it) }
|
||||
fun hasAnyTag(s: Collection<String>) = s.any { hasTag(it) }
|
||||
fun hasAnyTag(s: Array<String>) = s.any { hasTag(it) }
|
||||
fun hasAllTagOf(vararg s: String) = s.all { hasTag(it) }
|
||||
fun hasAllTag(s: Collection<String>) = s.all { hasTag(it) }
|
||||
fun hasAllTag(s: Array<String>) = s.all { hasTag(it) }
|
||||
fun hasNoTagOf(vararg s: String) = s.none { hasTag(it) }
|
||||
fun hasNoTag(s: Collection<String>) = s.none { hasTag(it) }
|
||||
fun hasNoTag(s: Array<String>) = s.none { hasTag(it) }
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import org.apache.commons.codec.digest.DigestUtils
|
||||
* - BE CRACKABLE (crackstation.net)
|
||||
*
|
||||
* Example passwords would be:
|
||||
* aryll -> beedle -> ciela -> daruk -> ... -> linebeck -> mido -> navi -> ...
|
||||
* aryll -> beedle -> ciela -> daruk -> epona -> ... -> linebeck -> mido -> navi -> ...
|
||||
*
|
||||
* Notes:
|
||||
* do NOT put plaintext anywhere in the code (except for comments maybe)
|
||||
@@ -36,7 +36,7 @@ internal object Authenticator : ConsoleCommand {
|
||||
// println("auth passwd: '$pwd'")
|
||||
// println("hash: $hashedPwd")
|
||||
|
||||
if ("c40232ae7b8020da3ab1449a015e7cc23f249a790856b63b1b69c6a5de019fed".equals(hashedPwd, ignoreCase = true)) {
|
||||
if ("4a26c5cd64195c4a52d2e3770e56c1d0c65861d2a03b47f8ba5d25ca033b9c42".equals(hashedPwd, ignoreCase = true)) {
|
||||
// beedle
|
||||
val msg = if (a) "Locked" else "Authenticated"
|
||||
Echo(msg)
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.gameactors
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.App.printdbgerr
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.audio.MusicContainer
|
||||
@@ -160,6 +161,10 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
||||
musicTracks[music] = track
|
||||
musicTracks1.add(track.name)
|
||||
track.stop()
|
||||
track.trackingTarget = this
|
||||
}
|
||||
else {
|
||||
printdbgerr(this, "Could not get a free track")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,9 +187,9 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
||||
it.currentTrack = music
|
||||
it.maxVolumeFun = { volume }
|
||||
it.volume = volume
|
||||
doSomethingWithTrack(it)
|
||||
// it.play()
|
||||
it.playRequested.set(true)
|
||||
doSomethingWithTrack(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ open class ActorWithBody : Actor {
|
||||
|
||||
fun setPosition(pos: Point2d) = setPosition(pos.x, pos.y)
|
||||
fun setPosition(pos: Vector2) = setPosition(pos.x, pos.y)
|
||||
|
||||
fun setPositionFromCentrePoint(pos: Vector2) = setPosition(pos.x, pos.y + (hitbox.height) / 2)
|
||||
|
||||
/**
|
||||
* ONLY FOR INITIAL SETUP
|
||||
|
||||
@@ -524,9 +524,17 @@ open class GameWorld(
|
||||
if (wiringGraph[blockAddr]!![itemID] == null)
|
||||
wiringGraph[blockAddr]!![itemID] = WiringSimCell(0, vector)
|
||||
|
||||
wiringGraph[blockAddr]!![itemID]!!.emt.set(vector)
|
||||
// out = max(old, new)
|
||||
val old = wiringGraph[blockAddr]!![itemID]!!.emt
|
||||
|
||||
wiringGraph[blockAddr]!![itemID]!!.emt.set(old max vector)
|
||||
}
|
||||
|
||||
private infix fun Vector2.max(other: Vector2) = Vector2(
|
||||
maxOf(this.x, other.x),
|
||||
maxOf(this.y, other.y)
|
||||
)
|
||||
|
||||
fun addWireRecvStateOf(x: Int, y: Int, itemID: ItemID, state: WireReceptionState) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
|
||||
@@ -13,20 +13,29 @@ import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.METER
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.SI_TO_GAME_ACC
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.mouseInInteractableRange
|
||||
import net.torvald.terrarum.gameparticles.ParticleBase
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.ItemThrowable
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.getThrowPosAndVector
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.weather.WeatherMixer
|
||||
import net.torvald.terrarum.weather.WeatherMixer.render
|
||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import net.torvald.util.CircularArray
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
|
||||
@@ -206,6 +215,17 @@ object IngameRenderer : Disposable {
|
||||
|
||||
private var oldCamX = 0
|
||||
|
||||
private fun FlippingSpriteBatch.drawFramebufferWithZoom(buf: TextureRegion, zoom: Float) {
|
||||
val t = (if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0).toFloat()
|
||||
|
||||
this.draw(buf,
|
||||
-0.5f * buf.regionWidth * zoom + 0.5f * buf.regionWidth + t * (zoom - 1f),
|
||||
-0.5f * buf.regionHeight * zoom + 0.5f * buf.regionHeight,
|
||||
buf.regionWidth * zoom,
|
||||
buf.regionHeight * zoom
|
||||
)
|
||||
}
|
||||
|
||||
operator fun invoke(
|
||||
frameDelta: Float,
|
||||
gamePaused: Boolean,
|
||||
@@ -248,6 +268,8 @@ object IngameRenderer : Disposable {
|
||||
drawToRGB(frameDelta, actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, actorsRenderOverlay, particlesContainer)
|
||||
drawToA(frameDelta, actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, actorsRenderOverlay, particlesContainer)
|
||||
drawOverlayActors(frameDelta, actorsRenderOverlay)
|
||||
|
||||
if (player != null && player is Pocketed) drawAimGuide(frameDelta, player)
|
||||
}
|
||||
|
||||
batch.color = Color.WHITE
|
||||
@@ -287,12 +309,7 @@ object IngameRenderer : Disposable {
|
||||
blendNormalStraightAlpha(batch)
|
||||
batch.shader = shaderBlendGlow
|
||||
shaderBlendGlow.setUniformi("tex1", 1)
|
||||
batch.draw(rgbTex,
|
||||
-0.5f * rgbTex.regionWidth * zoom + 0.5f * rgbTex.regionWidth,
|
||||
-0.5f * rgbTex.regionHeight * zoom + 0.5f * rgbTex.regionHeight,
|
||||
rgbTex.regionWidth * zoom,
|
||||
rgbTex.regionHeight * zoom
|
||||
)
|
||||
batch.drawFramebufferWithZoom(rgbTex, zoom)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -304,12 +321,7 @@ object IngameRenderer : Disposable {
|
||||
batch.inUse {
|
||||
blendNormalStraightAlpha(batch)
|
||||
batch.shader = null
|
||||
batch.draw(rgbTex,
|
||||
-0.5f * rgbTex.regionWidth * zoom + 0.5f * rgbTex.regionWidth,
|
||||
-0.5f * rgbTex.regionHeight * zoom + 0.5f * rgbTex.regionHeight,
|
||||
rgbTex.regionWidth * zoom,
|
||||
rgbTex.regionHeight * zoom
|
||||
)
|
||||
batch.drawFramebufferWithZoom(rgbTex, zoom)
|
||||
|
||||
// indicator
|
||||
batch.color = Color.RED
|
||||
@@ -331,12 +343,7 @@ object IngameRenderer : Disposable {
|
||||
batch.inUse {
|
||||
blendNormalStraightAlpha(batch)
|
||||
batch.shader = null
|
||||
batch.draw(aTex,
|
||||
-0.5f * aTex.regionWidth * zoom + 0.5f * aTex.regionWidth,
|
||||
-0.5f * aTex.regionHeight * zoom + 0.5f * aTex.regionHeight,
|
||||
aTex.regionWidth * zoom,
|
||||
aTex.regionHeight * zoom
|
||||
)
|
||||
batch.drawFramebufferWithZoom(aTex, zoom)
|
||||
|
||||
// indicator
|
||||
batch.color = Color.WHITE
|
||||
@@ -730,6 +737,160 @@ object IngameRenderer : Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawAimGuide(frameDelta: Float, player: ActorWithBody) {
|
||||
fboRGB_lightMixed.inActionF(camera, batch) { fb ->
|
||||
|
||||
setCameraPosition(0f, 0f)
|
||||
// BlocksDrawer.renderWhateverGlow_WALL
|
||||
|
||||
batch.inUse {
|
||||
batch.shader = null
|
||||
batch.color = Color.WHITE
|
||||
|
||||
moveCameraToWorldCoord()
|
||||
|
||||
(player as Pocketed).inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]?.let { itemID ->
|
||||
val heldItem = ItemCodex[itemID] // will be null for blocks
|
||||
// this is a case-by-case affair
|
||||
when (heldItem) {
|
||||
is ItemThrowable -> drawTrajectoryForThrowable(fb, batch, frameDelta, player, world, heldItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCameraPosition(0f, 0f)
|
||||
// BlocksDrawer.renderWhateverGlow_TERRAIN
|
||||
}
|
||||
}
|
||||
private val cubeSize = 7.0
|
||||
private val externalV = Vector2()
|
||||
private val maxStep = 56
|
||||
private fun drawTrajectoryForThrowable(frameBuffer: FrameBuffer, batch: SpriteBatch, frameDelta: Float, player: ActorWithBody, world: GameWorld, item: ItemThrowable) {
|
||||
val ww = world.width * TILE_SIZEF
|
||||
|
||||
mouseInInteractableRange(player) { mx, my, mtx, mty ->
|
||||
val (throwPos, throwVector) = getThrowPosAndVector(player)
|
||||
val grav = world.gravitation
|
||||
externalV.set(throwVector)
|
||||
|
||||
|
||||
var c = 0
|
||||
while (c < maxStep) {
|
||||
batch.color = Color(0.9f, 0.9f, 0.9f, 0.9f * (1f - (c.toFloat() / maxStep).sqr()))
|
||||
|
||||
// plot a dot
|
||||
if (c > 0) {
|
||||
Toolkit.fillArea(batch, throwPos.x.toFloat(), throwPos.y.toFloat(), 2f, 2f)
|
||||
Toolkit.fillArea(batch, throwPos.x.toFloat() + ww, throwPos.y.toFloat(), 2f, 2f)
|
||||
Toolkit.fillArea(batch, throwPos.x.toFloat() - ww, throwPos.y.toFloat(), 2f, 2f)
|
||||
}
|
||||
|
||||
// simulate physics
|
||||
applyGravitation(grav, cubeSize) // TODO use actual value instead of `cubeSize`
|
||||
// move the point
|
||||
throwPos += externalV
|
||||
// more physics
|
||||
setHorizontalFriction()
|
||||
setVerticalFriction()
|
||||
|
||||
|
||||
// break if colliding with a tile
|
||||
val hitSolid = listOf(
|
||||
throwPos + Vector2(-cubeSize/2, -cubeSize/2),
|
||||
throwPos + Vector2(-cubeSize/2, +cubeSize/2),
|
||||
throwPos + Vector2(+cubeSize/2, +cubeSize/2),
|
||||
throwPos + Vector2(+cubeSize/2, -cubeSize/2),
|
||||
).any {
|
||||
val wx = (it.x / TILE_SIZED).toInt()
|
||||
val wy = (it.y / TILE_SIZED).toInt()
|
||||
val tile = world.getTileFromTerrain(wx, wy)
|
||||
BlockCodex[tile].isSolid
|
||||
}
|
||||
|
||||
if (hitSolid)
|
||||
break
|
||||
|
||||
c++
|
||||
}
|
||||
|
||||
|
||||
1L
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val bodyFriction = BlockCodex[Block.AIR].friction.frictionToMult()
|
||||
private val bodyViscosity = BlockCodex[Block.AIR].viscosity.viscosityToMult()
|
||||
|
||||
|
||||
private fun applyGravitation(gravitation: Vector2, hitboxWidth: Double) {
|
||||
applyForce(getDrag(externalV, gravitation, hitboxWidth))
|
||||
}
|
||||
|
||||
private fun Int.frictionToMult(): Double = this / 16.0
|
||||
private fun Int.viscosityToMult(): Double = 16.0 / (16.0 + this)
|
||||
|
||||
private fun applyForce(acc: Vector2) {
|
||||
val speedMultByTile = bodyViscosity
|
||||
externalV += acc * speedMultByTile
|
||||
}
|
||||
|
||||
private fun getDrag(externalForce: Vector2, gravitation: Vector2, hitboxWidth: Double): Vector2 {
|
||||
val dragCoefficient = 1.2
|
||||
|
||||
/**
|
||||
* weight; gravitational force in action
|
||||
* W = mass * G (9.8 [m/s^2])
|
||||
*/
|
||||
val W: Vector2 = gravitation * Terrarum.PHYS_TIME_FRAME
|
||||
/**
|
||||
* Area
|
||||
*/
|
||||
val A: Double = (hitboxWidth / METER).sqr() // this is not physically accurate but it's needed to make large playable characters more controllable
|
||||
/**
|
||||
* Drag of atmosphere
|
||||
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity sqr) * A (area)
|
||||
*/
|
||||
val D: Vector2 = Vector2(externalForce.x.magnSqr(), externalForce.y.magnSqr()) * dragCoefficient * 0.5 * A// * tileDensityFluid.toDouble()
|
||||
|
||||
val V: Vector2 = (W - D) / Terrarum.PHYS_TIME_FRAME * SI_TO_GAME_ACC
|
||||
|
||||
return V
|
||||
|
||||
// FIXME v * const, where const = 1.0 for FPS=60, sqrt(2.0) for FPS=30, etc.
|
||||
// this is "close enough" solution and not perfect.
|
||||
}
|
||||
|
||||
/** about stopping
|
||||
* for about get moving, see updateMovementControl */
|
||||
private fun setHorizontalFriction() {
|
||||
val friction = 0.3 * bodyFriction
|
||||
|
||||
if (externalV.x < 0) {
|
||||
externalV.x += friction
|
||||
if (externalV.x > 0) externalV.x = 0.0 // compensate overshoot
|
||||
}
|
||||
else if (externalV.x > 0) {
|
||||
externalV.x -= friction
|
||||
if (externalV.x < 0) externalV.x = 0.0 // compensate overshoot
|
||||
}
|
||||
}
|
||||
|
||||
private fun setVerticalFriction() {
|
||||
val friction = 0.3 * bodyFriction
|
||||
|
||||
if (externalV.y < 0) {
|
||||
externalV.y += friction
|
||||
if (externalV.y > 0) externalV.y = 0.0 // compensate overshoot
|
||||
}
|
||||
else if (externalV.y > 0) {
|
||||
externalV.y -= friction
|
||||
if (externalV.y < 0) externalV.y = 0.0 // compensate overshoot
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private fun invokeInit() {
|
||||
if (!initDone) {
|
||||
|
||||
@@ -319,6 +319,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
(!tileProp.isSolid && !wallProp.isSolid).toInt().toFloat()
|
||||
}
|
||||
)
|
||||
|
||||
loadedTime_t = App.getTIME_T()
|
||||
}
|
||||
|
||||
data class NewGameParams(
|
||||
@@ -493,6 +495,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
App.savegameWorlds[world.worldIndex] = SavegameCollection.collectFromBaseFilename(File(worldsDir), worldSavefileName)
|
||||
App.savegameWorldsName[world.worldIndex] = worldName
|
||||
|
||||
loadedTime_t = App.getTIME_T()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1182,6 +1186,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
// return to normal state
|
||||
onSuccessful()
|
||||
|
||||
loadedTime_t = App.getTIME_T()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1412,6 +1418,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
val timeDiff = System.nanoTime() - start
|
||||
debugTimers.put("Last Autosave Duration", timeDiff)
|
||||
printdbg(this, "Last Autosave Duration: ${(timeDiff) / 1000000000} s")
|
||||
|
||||
|
||||
loadedTime_t = App.getTIME_T()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.serialise.ReadSimpleWorld
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemTextButton
|
||||
import net.torvald.terrarum.utils.OpenURL
|
||||
import net.torvald.terrarum.weather.WeatherMixer
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import net.torvald.util.CircularArray
|
||||
@@ -494,18 +496,47 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
// update available!
|
||||
if (App.hasUpdate) {
|
||||
batch.color = Toolkit.Theme.COL_SELECTED
|
||||
|
||||
batch.color = if (System.currentTimeMillis() % 1500 < 750L)
|
||||
Toolkit.Theme.COL_MOUSE_UP
|
||||
else
|
||||
Toolkit.Theme.COL_SELECTED
|
||||
|
||||
val tx = UIRemoCon.menubarOffX + UIRemoCon.UIRemoConElement.paddingLeft / 2 + uiRemoCon.posX
|
||||
val ty1 = UIRemoCon.menubarOffY - uiRemoCon.height + uiRemoCon.posY - 60
|
||||
val ty2 = ty1 + 28
|
||||
App.fontGame.draw(
|
||||
batch,
|
||||
Lang["MENU_UPDATE_UPDATE_AVAILABLE"],
|
||||
UIRemoCon.menubarOffX + UIRemoCon.UIRemoConElement.paddingLeft / 2 + uiRemoCon.posX,
|
||||
UIRemoCon.menubarOffY - uiRemoCon.height + uiRemoCon.posY
|
||||
tx, ty1
|
||||
)
|
||||
|
||||
|
||||
val tw = App.fontGame.getWidth("<${TerrarumAppConfiguration.FIXED_LATEST_DOWNLOAD_LINK}>")
|
||||
if (Terrarum.mouseScreenX in tx - 32 until tx + tw + 32 &&
|
||||
Terrarum.mouseScreenY in ty2 - 16 until ty2 + App.fontGame.lineHeight.toInt() + 16) {
|
||||
|
||||
if (Gdx.input.isButtonJustPressed(App.getConfigInt("config_mouseprimary"))) {
|
||||
OpenURL(TerrarumAppConfiguration.FIXED_LATEST_DOWNLOAD_LINK)
|
||||
}
|
||||
batch.color = Toolkit.Theme.COL_SELECTED
|
||||
}
|
||||
else
|
||||
batch.color = Toolkit.Theme.COL_MOUSE_UP
|
||||
|
||||
App.fontGame.draw(
|
||||
batch,
|
||||
"<${TerrarumAppConfiguration.FIXED_LATEST_DOWNLOAD_LINK}>",
|
||||
tx, ty2
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun pause() {
|
||||
}
|
||||
|
||||
|
||||
@@ -589,7 +589,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
|
||||
|
||||
private fun applyVelo(x: Int): Double {
|
||||
return if (x < WALK_FRAMES_TO_MAX_ACCEL)
|
||||
0.5 - 0.5 * Math.cos(Math.PI * x / WALK_FRAMES_TO_MAX_ACCEL)
|
||||
x.toDouble() / WALK_FRAMES_TO_MAX_ACCEL //0.5 - 0.5 * Math.cos(Math.PI * x / WALK_FRAMES_TO_MAX_ACCEL)
|
||||
else 1.0
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIQuickslotBar
|
||||
import net.torvald.terrarum.sqr
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-03-15.
|
||||
@@ -38,6 +39,21 @@ class ActorInventory() : FixtureInventory() {
|
||||
field = value
|
||||
}
|
||||
|
||||
val maxCapacityByActor: Double
|
||||
get() = maxCapacity * ((actor.actorValue.getAsDouble(AVKey.SCALE) ?: 1.0) * (actor.actorValue.getAsDouble(AVKey.SCALEBUFF) ?: 1.0)).sqr()
|
||||
|
||||
/**
|
||||
* How encumbered the actor is. 1.0 if weight of the items are exactly same as the capacity limit, >1.0 if encumbered.
|
||||
*/
|
||||
override val encumberment: Double
|
||||
get() = if (capacityMode == CAPACITY_MODE_NO_ENCUMBER)
|
||||
0.0
|
||||
else if (capacityMode == CAPACITY_MODE_WEIGHT)
|
||||
capacity / maxCapacityByActor
|
||||
else
|
||||
0.0
|
||||
|
||||
|
||||
/**
|
||||
* List of all equipped items (tools, armours, rings, necklaces, etc.)
|
||||
*
|
||||
|
||||
@@ -248,7 +248,8 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
* Condition for (if the tile is solid) is always implied regardless of this function. See [canSpawnHere0]
|
||||
*/
|
||||
open fun canSpawnOnThisFloor(itemID: ItemID): Boolean {
|
||||
return true
|
||||
val blockprop = BlockCodex[itemID]
|
||||
return blockprop.isSolid || blockprop.isPlatform
|
||||
}
|
||||
|
||||
fun canSpawnHere(posX0: Int, posY0: Int): Boolean {
|
||||
@@ -277,7 +278,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
val xs = posX until posX + blockBox.width
|
||||
cannotSpawn = cannotSpawn or xs.any { x ->
|
||||
world!!.getTileFromTerrain(x, y).let {
|
||||
!BlockCodex[it].isSolid || !canSpawnOnThisFloor(it)
|
||||
!canSpawnOnThisFloor(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.spriteanimation.SheetSpriteAnimation
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.audio.MusicContainer
|
||||
import net.torvald.terrarum.audio.decibelsToFullscale
|
||||
import net.torvald.terrarum.audio.dsp.Gain
|
||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
@@ -17,7 +15,6 @@ import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.UICrafting
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
@@ -81,6 +78,8 @@ class FixtureFurnaceAndAnvil : FixtureBase, CraftingStation {
|
||||
private var nextDelay = 0.25f
|
||||
private var spawnTimer = 0f
|
||||
|
||||
@Transient private var audioStatus = 0
|
||||
|
||||
override fun updateImpl(delta: Float) {
|
||||
super.updateImpl(delta)
|
||||
|
||||
@@ -108,17 +107,32 @@ class FixtureFurnaceAndAnvil : FixtureBase, CraftingStation {
|
||||
|
||||
// manage audio
|
||||
getTrackByAudio(static).let {
|
||||
if (it != null && !it.isPlaying) {
|
||||
startAudio(static) {
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
// printdbg(this, "Checking out track ${it?.name}")
|
||||
if (it != null) {
|
||||
|
||||
if (audioStatus == 0) {
|
||||
startAudio(static) {
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
audioStatus = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getTrackByAudio(static)?.let {
|
||||
if (it.filters[filterIndex] !is Gain) // just in case...
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
else {
|
||||
// printdbg(this, "Track is null! (old audio status=$audioStatus")
|
||||
audioStatus = 0
|
||||
}
|
||||
|
||||
(it.filters[filterIndex] as Gain).gain = 0.4f * volRand.get()
|
||||
if (it != null) {
|
||||
if (it.processor.streamBuf != null || it.playRequested.get()) {
|
||||
if (it.filters[filterIndex] !is Gain) // just in case...
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
|
||||
(it.filters[filterIndex] as Gain).gain = 0.4f * volRand.get()
|
||||
}
|
||||
else {
|
||||
audioStatus = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ open class FixtureInventory() {
|
||||
/**
|
||||
* How encumbered the actor is. 1.0 if weight of the items are exactly same as the capacity limit, >1.0 if encumbered.
|
||||
*/
|
||||
val encumberment: Double
|
||||
open val encumberment: Double
|
||||
get() = if (capacityMode == CAPACITY_MODE_NO_ENCUMBER)
|
||||
0.0
|
||||
else if (capacityMode == CAPACITY_MODE_WEIGHT)
|
||||
@@ -332,6 +332,10 @@ class InventoryPair : Comparable<InventoryPair> {
|
||||
operator fun component2() = qty
|
||||
|
||||
override fun compareTo(other: InventoryPair) = this.itm.compareTo(other.itm)
|
||||
|
||||
override fun toString(): String {
|
||||
return if (qty == -1L) "$itm" else "$itm ($qty)"
|
||||
}
|
||||
}
|
||||
|
||||
class InventoryTransactionFailedError(msg: String) : Error(msg)
|
||||
@@ -7,6 +7,9 @@ import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2021-08-08.
|
||||
*/
|
||||
class FixtureLogicSignalEmitter : Electric {
|
||||
|
||||
@Transient override val spawnNeedsFloor = false
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.spriteanimation.SheetSpriteAnimation
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-01.
|
||||
*/
|
||||
class FixtureSignalBulb : Electric {
|
||||
|
||||
@Transient override val spawnNeedsFloor = false
|
||||
@Transient override val spawnNeedsWall = true
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 1),
|
||||
nameFun = { Lang["ITEM_COPPER_BULB"] }
|
||||
)
|
||||
|
||||
init {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/copper_bulb.tga")
|
||||
val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/copper_bulb_emissive.tga")
|
||||
|
||||
density = 1400.0
|
||||
setHitboxDimension(TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE, 0, 1)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(2,1)
|
||||
it.delays = floatArrayOf(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)
|
||||
}
|
||||
|
||||
makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(2,1)
|
||||
it.delays = floatArrayOf(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = FixtureLogicSignalEmitter.MASS
|
||||
|
||||
|
||||
setWireSinkAt(0, 0, "digital_bit")
|
||||
}
|
||||
|
||||
private fun light(state: Boolean) {
|
||||
(sprite as SheetSpriteAnimation).currentRow = state.toInt()
|
||||
(spriteEmissive as SheetSpriteAnimation).currentRow = state.toInt()
|
||||
}
|
||||
|
||||
override fun onSignalHigh(readFrom: BlockBoxIndex) {
|
||||
light(true)
|
||||
}
|
||||
|
||||
override fun onSignalLow(readFrom: BlockBoxIndex) {
|
||||
light(false)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.spriteanimation.SheetSpriteAnimation
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarum.ui.MouseLatch
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-01.
|
||||
*/
|
||||
class FixtureSignalSwitchManual : Electric {
|
||||
|
||||
@Transient override val spawnNeedsFloor = false
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 1),
|
||||
nameFun = { Lang["ITEM_LOGIC_SIGNAL_SWITCH"] }
|
||||
)
|
||||
|
||||
private val variant = (Math.random() * 8).toInt()
|
||||
private var state = false // false = off
|
||||
|
||||
init {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_switch.tga")
|
||||
|
||||
density = 1400.0
|
||||
setHitboxDimension(TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE, 0, 1)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, TerrarumAppConfiguration.TILE_SIZE, TerrarumAppConfiguration.TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(2,8)
|
||||
it.currentFrame = variant
|
||||
it.delays = floatArrayOf(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = FixtureLogicSignalEmitter.MASS
|
||||
|
||||
|
||||
setWireEmitterAt(0, 0, "digital_bit")
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
super.reload()
|
||||
|
||||
(sprite as SheetSpriteAnimation).currentFrame = variant
|
||||
|
||||
(sprite as SheetSpriteAnimation).currentRow = state.toInt()
|
||||
setWireEmissionAt(0, 0, Vector2(state.toInt().toDouble(), 0.0))
|
||||
}
|
||||
|
||||
@Transient private val clickLatch = MouseLatch(listOf(App.getConfigInt("config_mousesecondary")))
|
||||
|
||||
override fun updateImpl(delta: Float) {
|
||||
super.updateImpl(delta)
|
||||
|
||||
// right click
|
||||
if (mouseUp) {
|
||||
clickLatch.latch {
|
||||
state = !state
|
||||
(sprite as SheetSpriteAnimation).currentRow = state.toInt()
|
||||
setWireEmissionAt(0, 0, Vector2(state.toInt().toDouble(), 0.0))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -289,8 +289,9 @@ class FixtureSmelterBasic : FixtureBase, CraftingStation {
|
||||
|
||||
|
||||
// manage audio
|
||||
// FIXME this code is also killing the audio played by the other fixture (FixtureFurnaceAndAnvil)
|
||||
getTrackByAudio(static).let {
|
||||
if (it == null || (temperature > 0f && !it.isPlaying)) {
|
||||
if (it == null || (temperature > 0f && !it.isPlaying && !it.playRequested.get())) {
|
||||
startAudio(static) {
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
}
|
||||
@@ -300,12 +301,13 @@ class FixtureSmelterBasic : FixtureBase, CraftingStation {
|
||||
it.filters[filterIndex] = NullFilter
|
||||
}
|
||||
}
|
||||
}
|
||||
getTrackByAudio(static)?.let {
|
||||
if (it.filters[filterIndex] !is Gain) // just in case...
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
|
||||
(it.filters[filterIndex] as Gain).gain = (it.maxVolume * temperature * volRand.get()).toFloat()
|
||||
if (it != null) {
|
||||
if (it.filters[filterIndex] !is Gain) // just in case...
|
||||
it.filters[filterIndex] = Gain(0f)
|
||||
|
||||
(it.filters[filterIndex] as Gain).gain = (it.maxVolume * temperature * volRand.get()).toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory.Companion.CAPACITY_MODE_COUNT
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChest.Companion.MASS
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChest.Companion.MAXCAP_MODE
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChest.Companion.MAXCAP_NUM
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
@@ -12,13 +15,11 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
/**
|
||||
* Created by minjaesong on 2019-07-08.
|
||||
*/
|
||||
internal class FixtureStorageChest : FixtureBase {
|
||||
|
||||
|
||||
class FixtureStorageChest : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
|
||||
mainUI = UIStorageChest(),
|
||||
inventory = FixtureInventory(40, CAPACITY_MODE_COUNT),
|
||||
inventory = FixtureInventory(MAXCAP_NUM, MAXCAP_MODE),
|
||||
nameFun = { Lang["ITEM_STORAGE_CHEST"] }
|
||||
) {
|
||||
|
||||
@@ -36,6 +37,50 @@ internal class FixtureStorageChest : FixtureBase {
|
||||
actorValue[AVKey.BASEMASS] = MASS
|
||||
|
||||
|
||||
// printStackTrace(this)
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
super.reload()
|
||||
// doing this is required as when things are deserialised, constructor is called, THEN the fields are
|
||||
// filled in, thus the initialised mainUI has a stale reference;
|
||||
// we fix it by simply giving a new reference to the mainUI
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MASS = 2.0
|
||||
const val MAXCAP_NUM = 40L
|
||||
val MAXCAP_MODE = CAPACITY_MODE_COUNT
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class FixtureStorageChestEbony : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
|
||||
mainUI = UIStorageChest(),
|
||||
inventory = FixtureInventory(MAXCAP_NUM, MAXCAP_MODE),
|
||||
nameFun = { Lang["ITEM_STORAGE_CHEST"] }
|
||||
) {
|
||||
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_2.tga")
|
||||
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 1, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 18, 18)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = MASS
|
||||
|
||||
|
||||
printStackTrace(this)
|
||||
}
|
||||
|
||||
@@ -47,8 +92,80 @@ internal class FixtureStorageChest : FixtureBase {
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MASS = 2.0
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class FixtureStorageChestBirch : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
|
||||
mainUI = UIStorageChest(),
|
||||
inventory = FixtureInventory(MAXCAP_NUM, MAXCAP_MODE),
|
||||
nameFun = { Lang["ITEM_STORAGE_CHEST"] }
|
||||
) {
|
||||
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_3.tga")
|
||||
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 1, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 18, 18)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = MASS
|
||||
|
||||
|
||||
printStackTrace(this)
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
super.reload()
|
||||
// doing this is required as when things are deserialised, constructor is called, THEN the fields are
|
||||
// filled in, thus the initialised mainUI has a stale reference;
|
||||
// we fix it by simply giving a new reference to the mainUI
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class FixtureStorageChestRosewood : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
|
||||
mainUI = UIStorageChest(),
|
||||
inventory = FixtureInventory(MAXCAP_NUM, MAXCAP_MODE),
|
||||
nameFun = { Lang["ITEM_STORAGE_CHEST"] }
|
||||
) {
|
||||
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_4.tga")
|
||||
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 1, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 18, 18)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = MASS
|
||||
|
||||
|
||||
printStackTrace(this)
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
super.reload()
|
||||
// doing this is required as when things are deserialised, constructor is called, THEN the fields are
|
||||
// filled in, thus the initialised mainUI has a stale reference;
|
||||
// we fix it by simply giving a new reference to the mainUI
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
(mainUI as UIStorageChest).chestNameFun = this.nameFun
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIStorageChest
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class FixtureTable : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 2, 2),
|
||||
nameFun = { Lang["ITEM_TABLE_OAK"] }
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/table_1.tga")
|
||||
|
||||
setHitboxDimension(2*TILE_SIZE, 2*TILE_SIZE, 0, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 32, 33)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 20.0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class FixtureTableEbony : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 2, 2),
|
||||
nameFun = { Lang["ITEM_TABLE_EBONY"] }
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/table_2.tga")
|
||||
|
||||
setHitboxDimension(2*TILE_SIZE, 2*TILE_SIZE, 0, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 32, 33)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 20.0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class FixtureTableBirch : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 2, 2),
|
||||
nameFun = { Lang["ITEM_TABLE_BIRCH"] }
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/table_3.tga")
|
||||
|
||||
setHitboxDimension(2*TILE_SIZE, 2*TILE_SIZE, 0, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 32, 33)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 20.0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class FixtureTableRosewood : FixtureBase {
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 2, 2),
|
||||
nameFun = { Lang["ITEM_TABLE_ROSEWOOD"] }
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/table_4.tga")
|
||||
|
||||
setHitboxDimension(2*TILE_SIZE, 2*TILE_SIZE, 0, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 32, 33)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 20.0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.UICrafting
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class FixtureWireRollingMill : FixtureBase, CraftingStation {
|
||||
|
||||
@Transient override val tags = listOf("wirerollingmill")
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 2, 2),
|
||||
nameFun = { Lang["ITEM_WIRE_ROLLING_MILL"] },
|
||||
mainUI = UICrafting(null)
|
||||
) {
|
||||
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/wire_rolling_mill.tga")
|
||||
|
||||
density = BlockCodex[Block.STONE].density.toDouble()
|
||||
setHitboxDimension(itemImage.texture.width, itemImage.texture.height, 0, 0)
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, itemImage.texture.width, itemImage.texture.height)).let {
|
||||
it.setRowsAndFrames(1,1)
|
||||
}
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 50.0
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.BlockCodex
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
|
||||
import net.torvald.terrarum.modulebasegame.ui.UICrafting
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIWallCalendar
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameactors.PhysProperties
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-04-26.
|
||||
*/
|
||||
class ItemCarrying : ActorWithBody {
|
||||
|
||||
var itemID: ItemID = ""; private set
|
||||
|
||||
private constructor()
|
||||
|
||||
constructor(itemID: ItemID) : super(RenderOrder.MIDTOP, PhysProperties.IMMOBILE()) {
|
||||
this.itemID = itemID
|
||||
}
|
||||
|
||||
|
||||
// just let the solver use AABB; it's cheap but works just enough
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -21,28 +21,31 @@ interface Pocketed {
|
||||
fun unequipItem(item: GameItem?) {
|
||||
if (item == null) return
|
||||
|
||||
// check equipposition of the given item
|
||||
if (item.equipPosition == GameItem.EquipPosition.NULL)
|
||||
throw Error("Unequipping the item that cannot be equipped in the first place")
|
||||
|
||||
// check if the actor even has the items
|
||||
if (!inventory.contains(item)) {
|
||||
//throw Error("Unequipping the item that does not exist in inventory")
|
||||
System.err.println("[Pocketed] Warning -- Unequipping the item that does not exist in inventory")
|
||||
return // just do nothing
|
||||
}
|
||||
|
||||
inventory.itemEquipped[item.equipPosition] = null
|
||||
// check if the actor actually have the item equipped
|
||||
if (inventory.itemEquipped[item.equipPosition] == item.dynamicID) {
|
||||
inventory.itemEquipped[item.equipPosition] = null
|
||||
|
||||
// NOTE: DON'T TOUCH QUICKSLOT HERE
|
||||
// Relevant Actorvalue is NOT being updated on time
|
||||
// They're being safely handled by UIItemInventoryElem*.touchDown() and ActorInventory.remove
|
||||
// NOTE: DON'T TOUCH QUICKSLOT HERE
|
||||
// Relevant Actorvalue is NOT being updated on time
|
||||
// They're being safely handled by UIItemInventoryElem*.touchDown() and ActorInventory.remove
|
||||
|
||||
item.effectOnUnequip(this as ActorWithBody)
|
||||
item.effectOnUnequip(this as ActorWithBody)
|
||||
}
|
||||
}
|
||||
|
||||
fun unequipItem(itemID: ItemID?) {
|
||||
itemID?.let {
|
||||
unequipItem(ItemCodex[itemID])
|
||||
} ?: return
|
||||
unequipItem(ItemCodex[itemID])
|
||||
}
|
||||
|
||||
// no need for equipSlot(Int)
|
||||
@@ -50,7 +53,13 @@ interface Pocketed {
|
||||
if (slot < 0 || slot > GameItem.EquipPosition.INDEX_MAX)
|
||||
throw IllegalArgumentException("Slot index out of range: $slot")
|
||||
|
||||
unequipItem(inventory.itemEquipped[slot])
|
||||
val itemID = inventory.itemEquipped[slot]
|
||||
|
||||
if (itemID != null) {
|
||||
val item = ItemCodex[itemID]!!
|
||||
inventory.itemEquipped[slot] = null
|
||||
item.effectOnUnequip(this as ActorWithBody)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -124,6 +124,8 @@ object AxeCore {
|
||||
else if (tileprop.hasAllTag(listOf("TREE", "TREETRUNK") + additionalCheckTags)) {
|
||||
val actionInterval = actorvalue.getAsDouble(AVKey.ACTION_INTERVAL)!!
|
||||
val swingDmgToFrameDmg = delta.toDouble() / actionInterval
|
||||
val isLargeTree = tileprop.hasTag("TREELARGE")
|
||||
val axePowerMult = if (isLargeTree) 0.5f else 1f
|
||||
|
||||
if (INGAME.WORLD_UPDATE_TIMER % 11 == (Math.random() * 3).toInt()) {
|
||||
PickaxeCore.makeNoiseTileTouching(actor, tile)
|
||||
@@ -131,7 +133,7 @@ object AxeCore {
|
||||
|
||||
INGAME.world.inflictTerrainDamage(
|
||||
x, y,
|
||||
Calculate.hatchetPower(actor, item?.material) * swingDmgToFrameDmg,
|
||||
Calculate.hatchetPower(actor, item?.material) * swingDmgToFrameDmg * axePowerMult,
|
||||
false
|
||||
).let { (tileBroken, _) ->
|
||||
// tile busted
|
||||
|
||||
@@ -8,6 +8,9 @@ import net.torvald.terrarum.itemproperties.Material
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2021-08-08.
|
||||
*/
|
||||
class ItemLogicSignalEmitter(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter") {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
|
||||
@@ -4,6 +4,9 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.terrarum.BlockCodex
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
@@ -69,7 +72,17 @@ class ItemTorch(originalID: ItemID) : LightIngredientBase(originalID) {
|
||||
override fun getLumCol() = BlockCodex[Block.TORCH].getLumCol(0, 0)
|
||||
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long {
|
||||
return BlockBase.blockStartPrimaryUse(actor, this, "basegame:176", delta)
|
||||
val mwx = (Terrarum.mouseX / TILE_SIZE).toInt()
|
||||
val mwy = (Terrarum.mouseY / TILE_SIZE).toInt()
|
||||
val wall = BlockCodex[INGAME.world.getTileFromWall(mwx, mwy)]
|
||||
val terr1 = BlockCodex[INGAME.world.getTileFromTerrain(mwx - 1, mwy)]
|
||||
val terr2 = BlockCodex[INGAME.world.getTileFromTerrain(mwx, mwy + 1)]
|
||||
val terr3 = BlockCodex[INGAME.world.getTileFromTerrain(mwx + 1, mwy)]
|
||||
|
||||
if (wall.isSolid || terr1.isSolid || terr2.isSolid || terr3.isSolid)
|
||||
return BlockBase.blockStartPrimaryUse(actor, this, "basegame:176", delta)
|
||||
else
|
||||
return -1L
|
||||
}
|
||||
|
||||
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
class ItemSeedOak(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.SaplingOak") {
|
||||
override var originalName = "ITEM_SEED_OAK"
|
||||
override var baseMass = 10.0
|
||||
override var baseMass = 1.0
|
||||
override val materialId = "OOZE"
|
||||
override var inventoryCategory = Category.GENERIC
|
||||
override val itemImage: TextureRegion
|
||||
@@ -14,7 +14,7 @@ class ItemSeedOak(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald
|
||||
}
|
||||
class ItemSeedEbony(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.SaplingEbony") {
|
||||
override var originalName = "ITEM_SEED_EBONY"
|
||||
override var baseMass = 10.0
|
||||
override var baseMass = 1.0
|
||||
override val materialId = "OOZE"
|
||||
override var inventoryCategory = Category.GENERIC
|
||||
override val itemImage: TextureRegion
|
||||
@@ -22,7 +22,7 @@ class ItemSeedEbony(originalID: ItemID) : FixtureItemBase(originalID, "net.torva
|
||||
}
|
||||
class ItemSeedBirch(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.SaplingBirch") {
|
||||
override var originalName = "ITEM_SEED_BIRCH"
|
||||
override var baseMass = 10.0
|
||||
override var baseMass = 1.0
|
||||
override val materialId = "OOZE"
|
||||
override var inventoryCategory = Category.GENERIC
|
||||
override val itemImage: TextureRegion
|
||||
@@ -30,7 +30,7 @@ class ItemSeedBirch(originalID: ItemID) : FixtureItemBase(originalID, "net.torva
|
||||
}
|
||||
class ItemSeedRosewood(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.SaplingRosewood") {
|
||||
override var originalName = "ITEM_SEED_ROSEWOOD"
|
||||
override var baseMass = 10.0
|
||||
override var baseMass = 1.0
|
||||
override val materialId = "OOZE"
|
||||
override var inventoryCategory = Category.GENERIC
|
||||
override val itemImage: TextureRegion
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-01.
|
||||
*/
|
||||
class ItemSignalBulb(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureSignalBulb") {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureLogicSignalEmitter.MASS
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(9, 3)
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_COPPER_BULB"
|
||||
|
||||
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
|
||||
super.effectWhileEquipped(actor, delta)
|
||||
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "signal"
|
||||
}
|
||||
|
||||
override fun effectOnUnequip(actor: ActorWithBody) {
|
||||
super.effectOnUnequip(actor)
|
||||
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = ""
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-01.
|
||||
*/
|
||||
class ItemSignalSwitchManual(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureSignalSwitchManual") {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureLogicSignalEmitter.MASS
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(8, 3)
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_LOGIC_SIGNAL_SWITCH"
|
||||
|
||||
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
|
||||
super.effectWhileEquipped(actor, delta)
|
||||
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "signal"
|
||||
}
|
||||
|
||||
override fun effectOnUnequip(actor: ActorWithBody) {
|
||||
super.effectOnUnequip(actor)
|
||||
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = ""
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import net.torvald.terrarum.modulebasegame.gameactors.FixtureTikiTorch
|
||||
* Created by minjaesong on 2019-07-08.
|
||||
*/
|
||||
class ItemStorageChest(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChest") {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureTikiTorch.MASS
|
||||
override val canBeDynamic = false
|
||||
@@ -20,5 +19,46 @@ class ItemStorageChest(originalID: ItemID) : FixtureItemBase(originalID, "net.to
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_STORAGE_CHEST"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class ItemStorageChestEbony(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChestEbony") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureTikiTorch.MASS
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_2.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_STORAGE_CHEST"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class ItemStorageChestBirch(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChestBirch") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureTikiTorch.MASS
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_3.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_STORAGE_CHEST"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class ItemStorageChestRosewood(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureStorageChestRosewood") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = FixtureTikiTorch.MASS
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/storage_chest_4.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_STORAGE_CHEST"
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class ItemTable(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTable") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = 20.0
|
||||
override val canBeDynamic = false
|
||||
override val materialId = "WOOD"
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/table_1.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_TABLE_OAK"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class ItemTableEbony(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTableEbony") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = 20.0
|
||||
override val canBeDynamic = false
|
||||
override val materialId = "WOOD"
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/table_2.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_TABLE_EBONY"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class ItemTableBirch(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTableBirch") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = 20.0
|
||||
override val canBeDynamic = false
|
||||
override val materialId = "WOOD"
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/table_3.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_TABLE_BIRCH"
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-03.
|
||||
*/
|
||||
class ItemTableRosewood(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTableRosewood") {
|
||||
override var dynamicID: ItemID = originalID
|
||||
override var baseMass = 20.0
|
||||
override val canBeDynamic = false
|
||||
override val materialId = "WOOD"
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/table_4.tga")
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_TABLE_ROSEWOOD"
|
||||
}
|
||||
@@ -31,19 +31,11 @@ open class ItemThrowable(originalID: ItemID, private val throwableActorClassName
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long = mouseInInteractableRange(actor) { mx, my, mtx, mty ->
|
||||
|
||||
val playerCentrePos = actor.centrePosVector
|
||||
val mousePos = Vector2(mx, my)
|
||||
|
||||
val actorPowMult = actor.avStrength / 2000.0
|
||||
val relativeX = relativeXposition(actor, mousePos)
|
||||
val relativeY = my - playerCentrePos.y
|
||||
val powX = relativeX / TILE_SIZED * 3.0 * actorPowMult
|
||||
val powY = relativeY / TILE_SIZED * 3.0 * actorPowMult
|
||||
val (throwPos, throwForce) = getThrowPosAndVector(actor)
|
||||
|
||||
val lobbed = Class.forName(throwableActorClassName).getDeclaredConstructor().newInstance() as ActorWithBody
|
||||
lobbed.setPosition(playerCentrePos)
|
||||
lobbed.externalV.set(powX, powY)
|
||||
lobbed.setPositionFromCentrePoint(throwPos)
|
||||
lobbed.externalV.set(throwForce)
|
||||
setupLobbedActor(lobbed)
|
||||
|
||||
Terrarum.ingame?.queueActorAddition(lobbed)
|
||||
@@ -52,6 +44,24 @@ open class ItemThrowable(originalID: ItemID, private val throwableActorClassName
|
||||
|
||||
1L
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pair of throwing start position, throwing force
|
||||
*/
|
||||
fun getThrowPosAndVector(actor: ActorWithBody): Pair<Vector2, Vector2> {
|
||||
val playerCentrePos = Vector2(actor.centrePosVector) // make a COPY of the actor.centrePosPoint
|
||||
val mousePos = Vector2(Terrarum.mouseX, Terrarum.mouseY)
|
||||
|
||||
val actorPowMult = actor.avStrength / 2000.0
|
||||
val relativeX = relativeXposition(actor, mousePos)
|
||||
val relativeY = mousePos.y - playerCentrePos.y
|
||||
val powX = relativeX / TILE_SIZED * 3.0 * actorPowMult
|
||||
val powY = relativeY / TILE_SIZED * 3.0 * actorPowMult
|
||||
|
||||
return Pair(playerCentrePos, Vector2(powX, powY))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class ItemWireRollingMill(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureWireRollingMill") {
|
||||
|
||||
|
||||
override var baseMass = 50.0
|
||||
override val canBeDynamic = false
|
||||
override val materialId = ""
|
||||
override val itemImage: TextureRegion
|
||||
get() = getItemImageFromSingleImage("basegame", "sprites/fixtures/wire_rolling_mill.tga")
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
override var originalName = "ITEM_WIRE_ROLLING_MILL"
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.WireCodex
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
@@ -26,6 +27,7 @@ class WirePieceSignalWire(originalID: ItemID, private val atlasID: String, priva
|
||||
init {
|
||||
equipPosition = GameItem.EquipPosition.HAND_GRIP
|
||||
originalName = "ITEM_WIRE"
|
||||
tags.addAll(WireCodex[originalID].tags)
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
|
||||
interface HasInventory {
|
||||
|
||||
fun getNegotiator(): InventoryTransactionNegotiator
|
||||
fun getFixtureInventory(): FixtureInventory
|
||||
fun getPlayerInventory(): FixtureInventory
|
||||
fun getPlayerInventory(): ActorInventory
|
||||
|
||||
}
|
||||
@@ -1,593 +1,84 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameitems.isWall
|
||||
import net.torvald.terrarum.itemproperties.CraftingCodex
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.CraftingStation
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap
|
||||
import net.torvald.terrarum.modulebasegame.ui.UITemplateHalfInventory.Companion.INVENTORY_NAME_TEXT_GAP
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarum.ui.UIItemCatBar.Companion.FILTER_CAT_ALL
|
||||
import net.torvald.unicode.getKeycapPC
|
||||
import kotlin.math.ceil
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemHorizontalFadeSlide
|
||||
|
||||
/**
|
||||
* This UI has inventory, but it's just there to display all craftable items and should not be serialised.
|
||||
*
|
||||
* Created by minjaesong on 2022-03-10.
|
||||
* Created by minjaesong on 2024-03-02.
|
||||
*/
|
||||
class UICrafting(val full: UIInventoryFull?) : UICanvas(
|
||||
toggleKeyLiteral = if (full == null) "control_key_inventory" else null,
|
||||
toggleButtonLiteral = if (full == null) "control_gamepad_start" else null
|
||||
), HasInventory {
|
||||
) {
|
||||
|
||||
override var width = Toolkit.drawWidth
|
||||
override var height = App.scr.height
|
||||
|
||||
private val playerThings = UITemplateHalfInventory(this, false).also { pt ->
|
||||
pt.itemListTouchDownFun = { gameItem, _, _, _, theButton -> if (gameItem != null) {
|
||||
val recipe = recipeClicked
|
||||
val itemID = gameItem.dynamicID
|
||||
internal val transitionalCraftingUI = UICraftingWorkbench(full, this)
|
||||
internal val transitionalTechtreePanel = UITechView(full, this)
|
||||
val transitionPanel = UIItemHorizontalFadeSlide(
|
||||
this,
|
||||
(width - UIInventoryFull.internalWidth) / 2,
|
||||
UIInventoryFull.INVENTORY_CELLS_OFFSET_Y(),
|
||||
width,
|
||||
App.scr.height,
|
||||
0f,
|
||||
listOf(transitionalCraftingUI, transitionalTechtreePanel),
|
||||
listOf()
|
||||
)
|
||||
|
||||
private val uis = listOf(transitionalCraftingUI, transitionalTechtreePanel)
|
||||
|
||||
// change ingredient used
|
||||
if (recipe != null) {
|
||||
// don't rely on highlightedness of the button to determine the item on the button is the selected
|
||||
// ingredient (because I don't fully trust my code lol)
|
||||
val targetItemToAlter =
|
||||
recipe.ingredients.filter { (key, mode) -> // altering recipe doesn't make sense if player selected a recipe that requires no tag-ingredients
|
||||
val tags = key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
(mode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.hasAllTags(tags) && (wantsWall == gameItem.originalID.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}.let {
|
||||
if (it.size > 1)
|
||||
println(
|
||||
"[UICrafting] Your recipe seems to have two similar ingredients defined\n" +
|
||||
"affected ingredients: ${it.joinToString()}\n" +
|
||||
"the recipe: ${recipe}"
|
||||
)
|
||||
it.firstOrNull()
|
||||
}
|
||||
|
||||
targetItemToAlter?.let { (key, mode) ->
|
||||
val oldItem = _getItemListIngredients().getInventory().first { (itm, qty) ->
|
||||
val tags = key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
(mode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itm]!!.hasAllTags(tags) && (wantsWall == itm.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}
|
||||
changeIngredient(recipe, oldItem, itemID)
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
// show all the items that can be made using this ingredient
|
||||
else {
|
||||
itemListCraftable.rebuild(arrayOf(itemID))
|
||||
pt.itemList.clearForceHighlightList()
|
||||
pt.itemList.addToForceHighlightList(listOf(itemID))
|
||||
|
||||
if (itemListCraftable.craftingRecipes.isEmpty()) {
|
||||
pt.itemList.clearForceHighlightList()
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
pt.itemList.clearForceHighlightList()
|
||||
recipeClicked = null
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
highlightCraftingCandidateButton(null)
|
||||
ingredients.clear()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
}}
|
||||
}
|
||||
|
||||
private val catIcons = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
|
||||
|
||||
internal val itemListCraftable: UIItemCraftingCandidateGrid // might be changed to something else
|
||||
internal val itemListIngredients: UIItemInventoryItemGrid // this one is definitely not to be changed
|
||||
private val buttonCraft: UIItemTextButton
|
||||
private val spinnerCraftCount: UIItemSpinner
|
||||
|
||||
private val ingredients = FixtureInventory() // this one is definitely not to be changed
|
||||
|
||||
private val negotiator = object : InventoryTransactionNegotiator() {
|
||||
override fun accept(player: FixtureInventory, fixture: FixtureInventory, item: GameItem, amount: Long) {
|
||||
// TODO()
|
||||
}
|
||||
|
||||
override fun refund(fixture: FixtureInventory, player: FixtureInventory, item: GameItem, amount: Long) {
|
||||
// TODO()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNegotiator() = negotiator
|
||||
override fun getFixtureInventory(): FixtureInventory = TODO()
|
||||
override fun getPlayerInventory(): FixtureInventory = INGAME.actorNowPlaying!!.inventory
|
||||
|
||||
private val halfSlotOffset = (UIItemInventoryElemSimple.height + listGap) / 2
|
||||
|
||||
private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + listGap - halfSlotOffset
|
||||
private val thisOffsetX2 = thisOffsetX + (listGap + UIItemInventoryElemWide.height) * 7
|
||||
private val thisXend = thisOffsetX + (listGap + UIItemInventoryElemWide.height) * 13 - listGap
|
||||
private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y()
|
||||
private val cellsWidth = (listGap + UIItemInventoryElemWide.height) * 6 - listGap
|
||||
|
||||
private val LAST_LINE_IN_GRID = ((UIItemInventoryElemWide.height + listGap) * (UIInventoryFull.CELLS_VRT - 2)) + 22//359 // TEMPORARY VALUE!
|
||||
|
||||
private var recipeClicked: CraftingCodex.CraftingRecipe? = null
|
||||
|
||||
private val controlHelp: String
|
||||
get() = if (App.environment == RunningEnvironment.PC)
|
||||
"${getKeycapPC(ControlPresets.getKey("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
|
||||
else
|
||||
"$gamepadLabelStart ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
||||
"$gamepadLabelLEFTRIGHT ${Lang["GAME_OBJECTIVE_MULTIPLIER"]}\u3000 " +
|
||||
"${App.gamepadLabelWest} ${Lang["GAME_ACTION_CRAFT"]}"
|
||||
|
||||
private val oldSelectedItems = ArrayList<ItemID>()
|
||||
|
||||
private val craftMult
|
||||
get() = spinnerCraftCount.value.toLong()
|
||||
|
||||
private fun _getItemListPlayer() = playerThings.itemList
|
||||
private fun _getItemListIngredients() = itemListIngredients
|
||||
private fun _getItemListCraftables() = itemListCraftable
|
||||
|
||||
init {
|
||||
val craftButtonsY = thisOffsetY + 23 + (UIItemInventoryElemWide.height + listGap) * (UIInventoryFull.CELLS_VRT - 1)
|
||||
val buttonWidth = (UIItemInventoryElemWide.height + listGap) * 3 - listGap - 2
|
||||
|
||||
// ingredient list
|
||||
itemListIngredients = UIItemInventoryItemGrid(
|
||||
this,
|
||||
{ ingredients },
|
||||
thisOffsetX,
|
||||
thisOffsetY + LAST_LINE_IN_GRID,
|
||||
6, 1,
|
||||
drawScrollOnRightside = false,
|
||||
drawWallet = false,
|
||||
hideSidebar = true,
|
||||
colourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme.copy(
|
||||
cellHighlightSubCol = Toolkit.Theme.COL_INACTIVE
|
||||
),
|
||||
keyDownFun = { _, _, _, _, _ -> },
|
||||
wheelFun = { _, _, _, _, _, _ -> },
|
||||
touchDownFun = { gameItem, amount, _, _, _ -> gameItem?.let { gameItem ->
|
||||
// if the clicked item is craftable one, present its recipe to the player //
|
||||
|
||||
CraftingRecipeCodex.getRecipesFor(gameItem.originalID)?.let { recipes ->
|
||||
// select most viable recipe (completely greedy search)
|
||||
val player = getPlayerInventory()
|
||||
// list of [Score, Ingredients, Recipe]
|
||||
recipes.map { recipe ->
|
||||
// list of (Item, How many player has, How many the recipe requires)
|
||||
val items = recipeToIngredientRecord(player, recipe, nearbyCraftingStations)
|
||||
|
||||
val score = items.fold(1L) { acc, item ->
|
||||
(item.howManyPlayerHas).times(16L) + 1L
|
||||
}
|
||||
|
||||
listOf(score, items, recipe)
|
||||
}.maxByOrNull { it[0] as Long }?.let { (_, items, recipe) ->
|
||||
val items = items as List<RecipeIngredientRecord>
|
||||
val recipe = recipe as CraftingCodex.CraftingRecipe
|
||||
|
||||
// change selected recipe to mostViableRecipe then update the UIs accordingly
|
||||
val selectedItems = ArrayList<ItemID>()
|
||||
|
||||
resetSpinner()
|
||||
|
||||
ingredients.clear()
|
||||
recipeClicked = recipe
|
||||
|
||||
items.forEach {
|
||||
val itm = it.selectedItem
|
||||
val qty = it.howManyRecipeWants
|
||||
|
||||
selectedItems.add(itm)
|
||||
ingredients.add(itm, qty)
|
||||
}
|
||||
|
||||
_getItemListPlayer().let {
|
||||
it.removeFromForceHighlightList(oldSelectedItems)
|
||||
//filterPlayerListUsing(recipeClicked) // ???
|
||||
it.addToForceHighlightList(selectedItems)
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
}
|
||||
|
||||
_getItemListIngredients().rebuild(FILTER_CAT_ALL)
|
||||
|
||||
_getItemListCraftables().highlightRecipe(recipeClicked, true)
|
||||
|
||||
oldSelectedItems.clear()
|
||||
oldSelectedItems.addAll(selectedItems)
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
} }
|
||||
)
|
||||
|
||||
// make sure grid buttons for ingredients do nothing (even if they are hidden!)
|
||||
itemListIngredients.navRemoCon.listButtonListener = { _,_, -> }
|
||||
itemListIngredients.navRemoCon.gridButtonListener = { _,_, -> }
|
||||
itemListIngredients.isCompactMode = true
|
||||
itemListIngredients.setCustomHighlightRuleSub {
|
||||
it.item?.let { ingredient ->
|
||||
return@setCustomHighlightRuleSub getPlayerInventory().searchByID(ingredient.dynamicID)?.let { itemOnPlayer ->
|
||||
itemOnPlayer.qty * craftMult >= it.amount * craftMult
|
||||
} == true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
|
||||
// crafting list to the left
|
||||
itemListCraftable = UIItemCraftingCandidateGrid(
|
||||
this,
|
||||
thisOffsetX,
|
||||
thisOffsetY,
|
||||
6, UIInventoryFull.CELLS_VRT - 2, // decrease the internal height so that craft/cancel button would fit in
|
||||
keyDownFun = { _, _, _, _, _ -> },
|
||||
touchDownFun = { gameItem, amount, _, recipe0, button ->
|
||||
(recipe0 as? CraftingCodex.CraftingRecipe).let { recipe ->
|
||||
val selectedItems = ArrayList<ItemID>()
|
||||
|
||||
val playerInventory = getPlayerInventory()
|
||||
ingredients.clear()
|
||||
recipeClicked = recipe
|
||||
// printdbg(this, "Recipe selected: $recipe")
|
||||
recipe?.ingredients?.forEach { ingredient ->
|
||||
val selectedItem = getItemForIngredient(playerInventory, ingredient)
|
||||
selectedItems.add(selectedItem)
|
||||
ingredients.add(selectedItem, ingredient.qty)
|
||||
}
|
||||
|
||||
_getItemListPlayer().removeFromForceHighlightList(oldSelectedItems)
|
||||
_getItemListPlayer().addToForceHighlightList(selectedItems)
|
||||
if (recipe != null) _getItemListPlayer().itemPage = 0
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
_getItemListIngredients().rebuild(FILTER_CAT_ALL)
|
||||
|
||||
highlightCraftingCandidateButton(recipe)
|
||||
|
||||
oldSelectedItems.clear()
|
||||
oldSelectedItems.addAll(selectedItems)
|
||||
|
||||
if (recipe == null) {
|
||||
playerThings.itemList.clearForceHighlightList()
|
||||
}
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
)
|
||||
buttonCraft = UIItemTextButton(this,
|
||||
{ Lang["GAME_ACTION_CRAFT"] }, thisOffsetX + 3 + buttonWidth + listGap, craftButtonsY, buttonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
||||
spinnerCraftCount = UIItemSpinner(this, thisOffsetX + 1, craftButtonsY, 1, 1, App.getConfigInt("basegame:gameplay_max_crafting"), 1, buttonWidth, numberToTextFunction = {"×\u200A${it.toInt()}"})
|
||||
spinnerCraftCount.selectionChangeListener = {
|
||||
itemListIngredients.numberMultiplier = it.toLong()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
itemListCraftable.numberMultiplier = it.toLong()
|
||||
itemListCraftable.rebuild()
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
|
||||
|
||||
buttonCraft.clickOnceListener = { _,_ ->
|
||||
getPlayerInventory().let { player -> recipeClicked?.let { recipe ->
|
||||
// check if player has enough amount of ingredients
|
||||
val itemCraftable = itemListIngredients.getInventory().all { (itm, qty) ->
|
||||
(player.searchByID(itm)?.qty ?: -1) >= qty * craftMult
|
||||
}
|
||||
|
||||
|
||||
if (itemCraftable) {
|
||||
itemListIngredients.getInventory().forEach { (itm, qty) ->
|
||||
player.remove(itm, qty * craftMult)
|
||||
}
|
||||
player.add(recipe.product, recipe.moq * craftMult)
|
||||
|
||||
// reset selection status after a crafting to hide the possible artefact where no-longer-craftable items are still displayed due to ingredient depletion
|
||||
resetUI() // also clears forcehighlightlist
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
} }
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
// make grid mode buttons work together
|
||||
// itemListCraftable.gridModeButtons[0].clickOnceListener = { _,_ -> setCompact(false) }
|
||||
// itemListCraftable.gridModeButtons[1].clickOnceListener = { _,_ -> setCompact(true) }
|
||||
|
||||
handler.allowESCtoClose = true
|
||||
|
||||
|
||||
val menuButtonTechView = UIItemImageButton(
|
||||
this, catIcons.get(20, 1),
|
||||
initialX = itemListCraftable.navRemoCon.posX + 12,
|
||||
initialY = itemListCraftable.navRemoCon.getIconPosY(-2) - 8,
|
||||
highlightable = true
|
||||
).also {
|
||||
it.clickOnceListener = { _, _ ->
|
||||
full?.transitionPanel?.setLeftUIto(1)
|
||||
full?.transitionPanel?.uis?.get(0)?.show()
|
||||
it.highlighted = false
|
||||
}
|
||||
}
|
||||
|
||||
val menuButtonCraft = UIItemImageButton(
|
||||
this, catIcons.get(19, 1),
|
||||
initialX = itemListCraftable.navRemoCon.posX + 12,
|
||||
initialY = itemListCraftable.navRemoCon.getIconPosY(-1) - 8,
|
||||
activeCol = Toolkit.Theme.COL_SELECTED,
|
||||
inactiveCol = Toolkit.Theme.COL_SELECTED,
|
||||
highlightable = true
|
||||
)
|
||||
|
||||
|
||||
addUIitem(itemListCraftable)
|
||||
addUIitem(itemListIngredients)
|
||||
addUIitem(playerThings)
|
||||
addUIitem(spinnerCraftCount)
|
||||
addUIitem(buttonCraft)
|
||||
// temporarily disabled for 0.4 release
|
||||
if (TerrarumAppConfiguration.VERSION_RAW >= 0x0000_000005_000000) {
|
||||
addUIitem(menuButtonCraft)
|
||||
addUIitem(menuButtonTechView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterPlayerListUsing(recipe: CraftingCodex.CraftingRecipe?) {
|
||||
if (recipe == null)
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
else {
|
||||
val items = recipe.ingredients.flatMap {
|
||||
getItemCandidatesForIngredient(getPlayerInventory(), it).map { it.itm }
|
||||
}.sorted()
|
||||
|
||||
val filterFun = { pair: InventoryPair ->
|
||||
items.binarySearch(pair.itm) >= 0
|
||||
}
|
||||
playerThings.rebuild(filterFun, recipe.product)
|
||||
}
|
||||
}
|
||||
|
||||
var nearbyCraftingStations = emptyList<String>(); protected set
|
||||
|
||||
fun getCraftingStationsWithinReach(): List<String> {
|
||||
val reach = 2 * INGAME.actorNowPlaying!!.actorValue.getAsDouble(AVKey.REACH)!! * (INGAME.actorNowPlaying!!.actorValue.getAsDouble(AVKey.REACHBUFF) ?: 1.0) * INGAME.actorNowPlaying!!.scale
|
||||
val nearbyCraftingStations = INGAME.findKNearestActors(INGAME.actorNowPlaying!!, 256) {
|
||||
it is CraftingStation && (distBetweenActors(it, INGAME.actorNowPlaying!!) < reach)
|
||||
}
|
||||
return nearbyCraftingStations.flatMap { (it.get() as CraftingStation).tags }
|
||||
}
|
||||
|
||||
private fun changeIngredient(recipe: CraftingCodex.CraftingRecipe?, old: InventoryPair, new: ItemID) {
|
||||
playerThings.itemList.removeFromForceHighlightList(oldSelectedItems)
|
||||
|
||||
oldSelectedItems.remove(old.itm)
|
||||
oldSelectedItems.add(new)
|
||||
|
||||
playerThings.itemList.addToForceHighlightList(oldSelectedItems)
|
||||
playerThings.itemList.itemPage = 0
|
||||
filterPlayerListUsing(recipe)
|
||||
|
||||
// change highlight status of itemListIngredients
|
||||
itemListIngredients.getInventory().let {
|
||||
val amount = old.qty
|
||||
it.remove(old.itm, amount)
|
||||
it.add(new, amount)
|
||||
}
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
|
||||
private fun highlightCraftingCandidateButton(recipe: CraftingCodex.CraftingRecipe?) { // a proxy function
|
||||
itemListCraftable.highlightRecipe(recipe)
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Craft! button so that the button is correctly highlighted
|
||||
*/
|
||||
fun refreshCraftButtonStatus() {
|
||||
val itemCraftable = if (itemListIngredients.getInventory().totalUniqueCount < 1) false
|
||||
else getPlayerInventory().let { player ->
|
||||
// check if player has enough amount of ingredients
|
||||
itemListIngredients.getInventory().all { (itm, qty) ->
|
||||
(player.searchByID(itm)?.qty ?: -1) >= qty * craftMult
|
||||
}
|
||||
}
|
||||
|
||||
buttonCraft.isEnabled = itemCraftable
|
||||
}
|
||||
|
||||
// reset whatever player has selected to null and bring UI to its initial state
|
||||
fun resetUI() {
|
||||
// reset spinner
|
||||
resetSpinner()
|
||||
|
||||
// reset selected recipe status
|
||||
recipeClicked = null
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
highlightCraftingCandidateButton(null)
|
||||
ingredients.clear()
|
||||
playerThings.itemList.clearForceHighlightList()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
|
||||
// reset scroll
|
||||
itemListCraftable.itemPage = 0
|
||||
playerThings.itemList.itemPage = 0
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
transitionalCraftingUI.resetUI()
|
||||
transitionalTechtreePanel.resetUI()
|
||||
}
|
||||
|
||||
private fun resetSpinner() {
|
||||
spinnerCraftCount.resetToSmallest()
|
||||
itemListIngredients.numberMultiplier = 1L
|
||||
itemListCraftable.numberMultiplier = 1L
|
||||
fun showCraftingUI() {
|
||||
transitionPanel.setLeftUIto(0)
|
||||
transitionalCraftingUI.show()
|
||||
}
|
||||
|
||||
private var openingClickLatched = false
|
||||
|
||||
override fun show() {
|
||||
nearbyCraftingStations = getCraftingStationsWithinReach()
|
||||
// printdbg(this, "Nearby crafting stations: $nearbyCraftingStations")
|
||||
|
||||
playerThings.setGetInventoryFun { INGAME.actorNowPlaying!!.inventory }
|
||||
itemListUpdate()
|
||||
|
||||
openingClickLatched = Terrarum.mouseDown
|
||||
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null)
|
||||
|
||||
resetUI()
|
||||
}
|
||||
|
||||
private var encumbrancePerc = 0f
|
||||
|
||||
private fun itemListUpdate() {
|
||||
// let itemlists be sorted
|
||||
itemListCraftable.rebuild()
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
encumbrancePerc = getPlayerInventory().let {
|
||||
it.capacity.toFloat() / it.maxCapacity
|
||||
}
|
||||
}
|
||||
|
||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (!openingClickLatched) {
|
||||
return super.touchDown(screenX, screenY, pointer, button)
|
||||
}
|
||||
return false
|
||||
fun showTechViewUI() {
|
||||
transitionPanel.setLeftUIto(1)
|
||||
transitionalTechtreePanel.show()
|
||||
}
|
||||
|
||||
override fun updateImpl(delta: Float) {
|
||||
// NO super.update due to an infinite recursion
|
||||
this.uiItems.forEach { it.update(delta) }
|
||||
uiItems.forEach { it.update(delta) }
|
||||
|
||||
if (openingClickLatched && !Terrarum.mouseDown) openingClickLatched = false
|
||||
// copy transition of parent (UIItemHorizontalFadeSlide) to this (also UIItemHorizontalFadeSlide)
|
||||
full?.let { full ->
|
||||
uis.forEach {
|
||||
it.posX = full.transitionPanel.getOffX(0)
|
||||
it.opacity = full.transitionPanel.getOpacity(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
||||
// NO super.render due to an infinite recursion
|
||||
this.uiItems.forEach { it.render(frameDelta, batch, camera) }
|
||||
|
||||
batch.color = Color.WHITE
|
||||
|
||||
// text label for two inventory grids
|
||||
val craftingLabel = Lang["GAME_CRAFTING"]
|
||||
val ingredientsLabel = Lang["GAME_INVENTORY_INGREDIENTS"]
|
||||
|
||||
App.fontGame.draw(batch, craftingLabel, thisOffsetX + (cellsWidth - App.fontGame.getWidth(craftingLabel)) / 2, thisOffsetY - INVENTORY_NAME_TEXT_GAP)
|
||||
App.fontGame.draw(batch, ingredientsLabel, thisOffsetX + (cellsWidth - App.fontGame.getWidth(ingredientsLabel)) / 2, thisOffsetY + LAST_LINE_IN_GRID - INVENTORY_NAME_TEXT_GAP)
|
||||
|
||||
|
||||
// control hints
|
||||
val controlHintXPos = thisOffsetX + 2f
|
||||
blendNormalStraightAlpha(batch)
|
||||
App.fontGame.draw(batch, controlHelp, controlHintXPos, UIInventoryFull.yEnd - 20)
|
||||
|
||||
|
||||
if (INGAME.actorNowPlaying != null) {
|
||||
//draw player encumb
|
||||
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth + 36
|
||||
val encumbBarYPos = UIInventoryFull.yEnd - 20 + 3f
|
||||
UIInventoryCells.drawEncumbranceBar(batch, encumbBarXPos, encumbBarYPos, encumbrancePerc, INGAME.actorNowPlaying!!.inventory)
|
||||
if (full == null) {
|
||||
UIInventoryFull.drawBackground(batch, opacity)
|
||||
}
|
||||
|
||||
|
||||
blendNormalStraightAlpha(batch)
|
||||
uiItems.forEach { it.render(frameDelta, batch, camera) }
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun doClosing(delta: Float) {
|
||||
super.doClosing(delta)
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
super.endOpening(delta)
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
super.endClosing(delta)
|
||||
resetUI()
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
transitionPanel.dispose()
|
||||
}
|
||||
|
||||
companion object {
|
||||
data class RecipeIngredientRecord(
|
||||
val selectedItem: ItemID,
|
||||
val howManyPlayerHas: Long,
|
||||
val howManyRecipeWants: Long,
|
||||
val craftingStationAvailable: Boolean,
|
||||
)
|
||||
init {
|
||||
addUIitem(transitionPanel)
|
||||
}
|
||||
|
||||
fun getItemCandidatesForIngredient(inventory: FixtureInventory, ingredient: CraftingCodex.CraftingIngredients): List<InventoryPair> {
|
||||
return if (ingredient.keyMode == CraftingCodex.CraftingItemKeyMode.TAG) {
|
||||
val tags = ingredient.key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
// If the player has the required item, use it; otherwise, will take an item from the ItemCodex
|
||||
inventory.filter { (itm, qty) ->
|
||||
ItemCodex[itm]?.hasAllTags(tags) == true && qty >= ingredient.qty && (wantsWall == itm.isWall()) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}
|
||||
}
|
||||
else {
|
||||
listOf(InventoryPair(ingredient.key, -1))
|
||||
}
|
||||
}
|
||||
|
||||
fun getItemForIngredient(inventory: FixtureInventory, ingredient: CraftingCodex.CraftingIngredients): ItemID {
|
||||
val candidate = getItemCandidatesForIngredient(inventory, ingredient)
|
||||
|
||||
return if (ingredient.keyMode == CraftingCodex.CraftingItemKeyMode.TAG) {
|
||||
candidate.maxByOrNull { it.qty }?.itm ?: (
|
||||
(ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.hasTag(ingredient.key)) it.key else null }) ?:
|
||||
throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed (ingredient: $ingredient)")
|
||||
)
|
||||
}
|
||||
else {
|
||||
ingredient.key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For each ingredient of the recipe, returns list of (ingredient, how many the player has the ingredient, how many the recipe wants)
|
||||
*/
|
||||
fun recipeToIngredientRecord(inventory: FixtureInventory, recipe: CraftingCodex.CraftingRecipe, nearbyCraftingStations: List<String>): List<RecipeIngredientRecord> {
|
||||
val hasStation = if (recipe.workbench.isBlank()) true else nearbyCraftingStations.containsAll(recipe.workbench.split(','))
|
||||
return recipe.ingredients.map { ingredient ->
|
||||
val selectedItem = getItemForIngredient(inventory, ingredient)
|
||||
val howManyPlayerHas = inventory.searchByID(selectedItem)?.qty ?: 0L
|
||||
val howManyTheRecipeWants = ingredient.qty
|
||||
|
||||
RecipeIngredientRecord(selectedItem, howManyPlayerHas, howManyTheRecipeWants, hasStation)
|
||||
}
|
||||
}
|
||||
override fun setPosition(x: Int, y: Int) {
|
||||
transitionalCraftingUI.setPosition(x, y)
|
||||
transitionalTechtreePanel.setPosition(x, y)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,600 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.gameitems.isWall
|
||||
import net.torvald.terrarum.itemproperties.CraftingCodex
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.CraftingStation
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.listGap
|
||||
import net.torvald.terrarum.modulebasegame.ui.UITemplateHalfInventory.Companion.INVENTORY_NAME_TEXT_GAP
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarum.ui.UIItemCatBar.Companion.FILTER_CAT_ALL
|
||||
import net.torvald.unicode.getKeycapPC
|
||||
|
||||
/**
|
||||
* This UI has inventory, but it's just there to display all craftable items and should not be serialised.
|
||||
*
|
||||
* Created by minjaesong on 2022-03-10.
|
||||
*/
|
||||
class UICraftingWorkbench(val inventoryUI: UIInventoryFull?, val parentContainer: UICrafting) : UICanvas(
|
||||
toggleKeyLiteral = if (inventoryUI == null) "control_key_inventory" else null,
|
||||
toggleButtonLiteral = if (inventoryUI == null) "control_gamepad_start" else null
|
||||
), HasInventory {
|
||||
|
||||
override var width = Toolkit.drawWidth
|
||||
override var height = App.scr.height
|
||||
|
||||
private val playerThings = UITemplateHalfInventory(this, false).also { pt ->
|
||||
pt.itemListTouchDownFun = { gameItem, _, _, _, theButton -> if (gameItem != null) {
|
||||
val recipe = recipeClicked
|
||||
val itemID = gameItem.dynamicID
|
||||
|
||||
// change ingredient used
|
||||
if (recipe != null) {
|
||||
// don't rely on highlightedness of the button to determine the item on the button is the selected
|
||||
// ingredient (because I don't fully trust my code lol)
|
||||
val targetItemToAlter =
|
||||
recipe.ingredients.filter { (key, mode) -> // altering recipe doesn't make sense if player selected a recipe that requires no tag-ingredients
|
||||
val tags = key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
(mode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.hasAllTags(tags) && (wantsWall == gameItem.originalID.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}.let {
|
||||
if (it.size > 1)
|
||||
println(
|
||||
"[UICrafting] Your recipe seems to have two similar ingredients defined\n" +
|
||||
"affected ingredients: ${it.joinToString()}\n" +
|
||||
"the recipe: ${recipe}"
|
||||
)
|
||||
it.firstOrNull()
|
||||
}
|
||||
|
||||
targetItemToAlter?.let { (key, mode) ->
|
||||
val oldItem = _getItemListIngredients().getInventory().first { (itm, qty) ->
|
||||
val tags = key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
(mode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itm]!!.hasAllTags(tags) && (wantsWall == itm.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}
|
||||
changeIngredient(recipe, oldItem, itemID)
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
// show all the items that can be made using this ingredient
|
||||
else {
|
||||
itemListCraftable.rebuild(arrayOf(itemID))
|
||||
pt.itemList.clearForceHighlightList()
|
||||
pt.itemList.addToForceHighlightList(listOf(itemID))
|
||||
|
||||
if (itemListCraftable.craftingRecipes.isEmpty()) {
|
||||
pt.itemList.clearForceHighlightList()
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
pt.itemList.clearForceHighlightList()
|
||||
recipeClicked = null
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
highlightCraftingCandidateButton(null)
|
||||
ingredients.clear()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
}}
|
||||
}
|
||||
|
||||
private val catIcons = CommonResourcePool.getAsTextureRegionPack("inventory_category")
|
||||
|
||||
|
||||
internal val itemListCraftable: UIItemCraftingCandidateGrid // might be changed to something else
|
||||
internal val itemListIngredients: UIItemInventoryItemGrid // this one is definitely not to be changed
|
||||
private val buttonCraft: UIItemTextButton
|
||||
private val spinnerCraftCount: UIItemSpinner
|
||||
|
||||
private val ingredients = FixtureInventory() // this one is definitely not to be changed
|
||||
|
||||
private val negotiator = object : InventoryTransactionNegotiator() {
|
||||
override fun accept(player: FixtureInventory, fixture: FixtureInventory, item: GameItem, amount: Long) {
|
||||
// TODO()
|
||||
}
|
||||
|
||||
override fun refund(fixture: FixtureInventory, player: FixtureInventory, item: GameItem, amount: Long) {
|
||||
// TODO()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNegotiator() = negotiator
|
||||
override fun getFixtureInventory(): FixtureInventory = TODO()
|
||||
override fun getPlayerInventory(): ActorInventory = INGAME.actorNowPlaying!!.inventory
|
||||
|
||||
private val halfSlotOffset = (UIItemInventoryElemSimple.height + listGap) / 2
|
||||
|
||||
private val thisOffsetX = UIInventoryFull.INVENTORY_CELLS_OFFSET_X() + UIItemInventoryElemSimple.height + listGap - halfSlotOffset
|
||||
private val thisOffsetX2 = thisOffsetX + (listGap + UIItemInventoryElemWide.height) * 7
|
||||
private val thisXend = thisOffsetX + (listGap + UIItemInventoryElemWide.height) * 13 - listGap
|
||||
private val thisOffsetY = UIInventoryFull.INVENTORY_CELLS_OFFSET_Y()
|
||||
private val cellsWidth = (listGap + UIItemInventoryElemWide.height) * 6 - listGap
|
||||
|
||||
private val LAST_LINE_IN_GRID = ((UIItemInventoryElemWide.height + listGap) * (UIInventoryFull.CELLS_VRT - 2)) + 22//359 // TEMPORARY VALUE!
|
||||
|
||||
private var recipeClicked: CraftingCodex.CraftingRecipe? = null
|
||||
|
||||
private val controlHelp: String
|
||||
get() = if (App.environment == RunningEnvironment.PC)
|
||||
"${getKeycapPC(ControlPresets.getKey("control_key_inventory"))} ${Lang["GAME_ACTION_CLOSE"]}"
|
||||
else
|
||||
"$gamepadLabelStart ${Lang["GAME_ACTION_CLOSE"]}\u3000 " +
|
||||
"$gamepadLabelLEFTRIGHT ${Lang["GAME_OBJECTIVE_MULTIPLIER"]}\u3000 " +
|
||||
"${App.gamepadLabelWest} ${Lang["GAME_ACTION_CRAFT"]}"
|
||||
|
||||
private val oldSelectedItems = ArrayList<ItemID>()
|
||||
|
||||
private val craftMult
|
||||
get() = spinnerCraftCount.value.toLong()
|
||||
|
||||
private fun _getItemListPlayer() = playerThings.itemList
|
||||
private fun _getItemListIngredients() = itemListIngredients
|
||||
private fun _getItemListCraftables() = itemListCraftable
|
||||
|
||||
init {
|
||||
val craftButtonsY = thisOffsetY + 23 + (UIItemInventoryElemWide.height + listGap) * (UIInventoryFull.CELLS_VRT - 1)
|
||||
val buttonWidth = (UIItemInventoryElemWide.height + listGap) * 3 - listGap - 2
|
||||
|
||||
// ingredient list
|
||||
itemListIngredients = UIItemInventoryItemGrid(
|
||||
this,
|
||||
{ ingredients },
|
||||
thisOffsetX,
|
||||
thisOffsetY + LAST_LINE_IN_GRID,
|
||||
6, 1,
|
||||
drawScrollOnRightside = false,
|
||||
drawWallet = false,
|
||||
hideSidebar = true,
|
||||
colourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme.copy(
|
||||
cellHighlightSubCol = Toolkit.Theme.COL_INACTIVE
|
||||
),
|
||||
keyDownFun = { _, _, _, _, _ -> },
|
||||
wheelFun = { _, _, _, _, _, _ -> },
|
||||
touchDownFun = { gameItem, amount, _, _, _ -> gameItem?.let { gameItem ->
|
||||
// if the clicked item is craftable one, present its recipe to the player //
|
||||
|
||||
CraftingRecipeCodex.getRecipesFor(gameItem.originalID)?.let { recipes ->
|
||||
// select most viable recipe (completely greedy search)
|
||||
val player = getPlayerInventory()
|
||||
// list of [Score, Ingredients, Recipe]
|
||||
recipes.map { recipe ->
|
||||
// list of (Item, How many player has, How many the recipe requires)
|
||||
val items = recipeToIngredientRecord(player, recipe, nearbyCraftingStations)
|
||||
|
||||
val score = items.fold(1L) { acc, item ->
|
||||
(item.howManyPlayerHas).times(16L) + 1L
|
||||
}
|
||||
|
||||
listOf(score, items, recipe)
|
||||
}.maxByOrNull { it[0] as Long }?.let { (_, items, recipe) ->
|
||||
val items = items as List<RecipeIngredientRecord>
|
||||
val recipe = recipe as CraftingCodex.CraftingRecipe
|
||||
|
||||
// change selected recipe to mostViableRecipe then update the UIs accordingly
|
||||
val selectedItems = ArrayList<ItemID>()
|
||||
|
||||
resetSpinner()
|
||||
|
||||
ingredients.clear()
|
||||
recipeClicked = recipe
|
||||
|
||||
items.forEach {
|
||||
val itm = it.selectedItem
|
||||
val qty = it.howManyRecipeWants
|
||||
|
||||
selectedItems.add(itm)
|
||||
ingredients.add(itm, qty)
|
||||
}
|
||||
|
||||
_getItemListPlayer().let {
|
||||
it.removeFromForceHighlightList(oldSelectedItems)
|
||||
//filterPlayerListUsing(recipeClicked) // ???
|
||||
it.addToForceHighlightList(selectedItems)
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
}
|
||||
|
||||
_getItemListIngredients().rebuild(FILTER_CAT_ALL)
|
||||
|
||||
_getItemListCraftables().highlightRecipe(recipeClicked, true)
|
||||
|
||||
oldSelectedItems.clear()
|
||||
oldSelectedItems.addAll(selectedItems)
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
} }
|
||||
)
|
||||
|
||||
// make sure grid buttons for ingredients do nothing (even if they are hidden!)
|
||||
itemListIngredients.navRemoCon.listButtonListener = { _,_, -> }
|
||||
itemListIngredients.navRemoCon.gridButtonListener = { _,_, -> }
|
||||
itemListIngredients.isCompactMode = true
|
||||
itemListIngredients.setCustomHighlightRuleSub {
|
||||
it.item?.let { ingredient ->
|
||||
return@setCustomHighlightRuleSub getPlayerInventory().searchByID(ingredient.dynamicID)?.let { itemOnPlayer ->
|
||||
itemOnPlayer.qty * craftMult >= it.amount * craftMult
|
||||
} == true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
|
||||
// crafting list to the left
|
||||
itemListCraftable = UIItemCraftingCandidateGrid(
|
||||
this,
|
||||
thisOffsetX,
|
||||
thisOffsetY,
|
||||
6, UIInventoryFull.CELLS_VRT - 2, // decrease the internal height so that craft/cancel button would fit in
|
||||
keyDownFun = { _, _, _, _, _ -> },
|
||||
touchDownFun = { gameItem, amount, _, recipe0, button ->
|
||||
(recipe0 as? CraftingCodex.CraftingRecipe).let { recipe ->
|
||||
val selectedItems = ArrayList<ItemID>()
|
||||
|
||||
val playerInventory = getPlayerInventory()
|
||||
ingredients.clear()
|
||||
recipeClicked = recipe
|
||||
// printdbg(this, "Recipe selected: $recipe")
|
||||
recipe?.ingredients?.forEach { ingredient ->
|
||||
val selectedItem = resolveIngredientKey(playerInventory, ingredient, recipe.product)
|
||||
selectedItems.add(selectedItem)
|
||||
ingredients.add(selectedItem, ingredient.qty)
|
||||
}
|
||||
|
||||
_getItemListPlayer().removeFromForceHighlightList(oldSelectedItems)
|
||||
_getItemListPlayer().addToForceHighlightList(selectedItems)
|
||||
if (recipe != null) _getItemListPlayer().itemPage = 0
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
_getItemListIngredients().rebuild(FILTER_CAT_ALL)
|
||||
|
||||
highlightCraftingCandidateButton(recipe)
|
||||
|
||||
oldSelectedItems.clear()
|
||||
oldSelectedItems.addAll(selectedItems)
|
||||
|
||||
if (recipe == null) {
|
||||
playerThings.itemList.clearForceHighlightList()
|
||||
}
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
}
|
||||
)
|
||||
buttonCraft = UIItemTextButton(this,
|
||||
{ Lang["GAME_ACTION_CRAFT"] }, thisOffsetX + 3 + buttonWidth + listGap, craftButtonsY, buttonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true)
|
||||
spinnerCraftCount = UIItemSpinner(this, thisOffsetX + 1, craftButtonsY, 1, 1, App.getConfigInt("basegame:gameplay_max_crafting"), 1, buttonWidth, numberToTextFunction = {"×\u200A${it.toInt()}"})
|
||||
spinnerCraftCount.selectionChangeListener = {
|
||||
itemListIngredients.numberMultiplier = it.toLong()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
itemListCraftable.numberMultiplier = it.toLong()
|
||||
itemListCraftable.rebuild()
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
|
||||
|
||||
buttonCraft.clickOnceListener = { _,_ ->
|
||||
getPlayerInventory().let { player -> recipeClicked?.let { recipe ->
|
||||
// check if player has enough amount of ingredients
|
||||
val itemCraftable = itemListIngredients.getInventory().all { (itm, qty) ->
|
||||
(player.searchByID(itm)?.qty ?: -1) >= qty * craftMult
|
||||
}
|
||||
|
||||
|
||||
if (itemCraftable) {
|
||||
val itemEquippedBefore = player.itemEquipped[GameItem.EquipPosition.HAND_GRIP]
|
||||
|
||||
itemListIngredients.getInventory().forEach { (itm, qty) ->
|
||||
player.remove(itm, qty * craftMult)
|
||||
}
|
||||
player.add(recipe.product, recipe.moq * craftMult)
|
||||
|
||||
// reset selection status after a crafting to hide the possible artefact where no-longer-craftable items are still displayed due to ingredient depletion
|
||||
resetUI() // also clears forcehighlightlist
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
|
||||
// preserve equipped item
|
||||
if (itemEquippedBefore != null && player.searchByID(itemEquippedBefore) != null) {
|
||||
player.itemEquipped[GameItem.EquipPosition.HAND_GRIP] = itemEquippedBefore
|
||||
}
|
||||
}
|
||||
} }
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
// make grid mode buttons work together
|
||||
// itemListCraftable.gridModeButtons[0].clickOnceListener = { _,_ -> setCompact(false) }
|
||||
// itemListCraftable.gridModeButtons[1].clickOnceListener = { _,_ -> setCompact(true) }
|
||||
|
||||
handler.allowESCtoClose = true
|
||||
|
||||
|
||||
val menuButtonTechView = UIItemImageButton(
|
||||
this, catIcons.get(20, 1),
|
||||
initialX = itemListCraftable.navRemoCon.posX + 12,
|
||||
initialY = itemListCraftable.navRemoCon.getIconPosY(-2) - 8,
|
||||
highlightable = true
|
||||
).also {
|
||||
it.clickOnceListener = { _, _ ->
|
||||
parentContainer.showTechViewUI()
|
||||
it.highlighted = false
|
||||
}
|
||||
}
|
||||
|
||||
val menuButtonCraft = UIItemImageButton(
|
||||
this, catIcons.get(19, 1),
|
||||
initialX = itemListCraftable.navRemoCon.posX + 12,
|
||||
initialY = itemListCraftable.navRemoCon.getIconPosY(-1) - 8,
|
||||
activeCol = Toolkit.Theme.COL_SELECTED,
|
||||
inactiveCol = Toolkit.Theme.COL_SELECTED,
|
||||
highlightable = true
|
||||
)
|
||||
|
||||
|
||||
addUIitem(itemListCraftable)
|
||||
addUIitem(itemListIngredients)
|
||||
addUIitem(playerThings)
|
||||
addUIitem(spinnerCraftCount)
|
||||
addUIitem(buttonCraft)
|
||||
// temporarily disabled for 0.4 release
|
||||
if (TerrarumAppConfiguration.VERSION_RAW >= 0x0000_000005_000000) {
|
||||
addUIitem(menuButtonCraft)
|
||||
addUIitem(menuButtonTechView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterPlayerListUsing(recipe: CraftingCodex.CraftingRecipe?) {
|
||||
if (recipe == null)
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
else {
|
||||
val items = recipe.ingredients.flatMap {
|
||||
getItemCandidatesForIngredient(getPlayerInventory(), it).map { it.itm }
|
||||
}.filter { it != recipe.product }.sorted() // filter out the product itself from the ingredient
|
||||
|
||||
val filterFun = { pair: InventoryPair ->
|
||||
items.binarySearch(pair.itm) >= 0
|
||||
}
|
||||
playerThings.rebuild(filterFun, recipe.product)
|
||||
}
|
||||
}
|
||||
|
||||
var nearbyCraftingStations = emptyList<String>(); protected set
|
||||
|
||||
fun getCraftingStationsWithinReach(): List<String> {
|
||||
val reach = 2 * INGAME.actorNowPlaying!!.actorValue.getAsDouble(AVKey.REACH)!! * (INGAME.actorNowPlaying!!.actorValue.getAsDouble(AVKey.REACHBUFF) ?: 1.0) * INGAME.actorNowPlaying!!.scale
|
||||
val nearbyCraftingStations = INGAME.findKNearestActors(INGAME.actorNowPlaying!!, 256) {
|
||||
it is CraftingStation && (distBetweenActors(it, INGAME.actorNowPlaying!!) < reach)
|
||||
}
|
||||
return nearbyCraftingStations.flatMap { (it.get() as CraftingStation).tags }
|
||||
}
|
||||
|
||||
private fun changeIngredient(recipe: CraftingCodex.CraftingRecipe?, old: InventoryPair, new: ItemID) {
|
||||
playerThings.itemList.removeFromForceHighlightList(oldSelectedItems)
|
||||
|
||||
oldSelectedItems.remove(old.itm)
|
||||
oldSelectedItems.add(new)
|
||||
|
||||
playerThings.itemList.addToForceHighlightList(oldSelectedItems)
|
||||
playerThings.itemList.itemPage = 0
|
||||
filterPlayerListUsing(recipe)
|
||||
|
||||
// change highlight status of itemListIngredients
|
||||
itemListIngredients.getInventory().let {
|
||||
val amount = old.qty
|
||||
it.remove(old.itm, amount)
|
||||
it.add(new, amount)
|
||||
}
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
|
||||
private fun highlightCraftingCandidateButton(recipe: CraftingCodex.CraftingRecipe?) { // a proxy function
|
||||
itemListCraftable.highlightRecipe(recipe)
|
||||
itemListCraftable.rebuild(FILTER_CAT_ALL)
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Craft! button so that the button is correctly highlighted
|
||||
*/
|
||||
fun refreshCraftButtonStatus() {
|
||||
val itemCraftable = if (itemListIngredients.getInventory().totalUniqueCount < 1) false
|
||||
else getPlayerInventory().let { player ->
|
||||
// check if player has enough amount of ingredients
|
||||
itemListIngredients.getInventory().all { (itm, qty) ->
|
||||
(player.searchByID(itm)?.qty ?: -1) >= qty * craftMult
|
||||
}
|
||||
}
|
||||
|
||||
buttonCraft.isEnabled = itemCraftable
|
||||
}
|
||||
|
||||
// reset whatever player has selected to null and bring UI to its initial state
|
||||
fun resetUI() {
|
||||
// reset spinner
|
||||
resetSpinner()
|
||||
|
||||
// reset selected recipe status
|
||||
recipeClicked = null
|
||||
filterPlayerListUsing(recipeClicked)
|
||||
highlightCraftingCandidateButton(null)
|
||||
ingredients.clear()
|
||||
playerThings.itemList.clearForceHighlightList()
|
||||
itemListIngredients.rebuild(FILTER_CAT_ALL)
|
||||
|
||||
// reset scroll
|
||||
itemListCraftable.itemPage = 0
|
||||
playerThings.itemList.itemPage = 0
|
||||
|
||||
refreshCraftButtonStatus()
|
||||
}
|
||||
|
||||
private fun resetSpinner() {
|
||||
spinnerCraftCount.resetToSmallest()
|
||||
itemListIngredients.numberMultiplier = 1L
|
||||
itemListCraftable.numberMultiplier = 1L
|
||||
}
|
||||
|
||||
private var openingClickLatched = false
|
||||
|
||||
override fun show() {
|
||||
nearbyCraftingStations = getCraftingStationsWithinReach()
|
||||
// printdbg(this, "Nearby crafting stations: $nearbyCraftingStations")
|
||||
|
||||
playerThings.setGetInventoryFun { INGAME.actorNowPlaying!!.inventory }
|
||||
itemListUpdate()
|
||||
|
||||
openingClickLatched = Terrarum.mouseDown
|
||||
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null)
|
||||
|
||||
resetUI()
|
||||
}
|
||||
|
||||
private var encumbrancePerc = 0f
|
||||
|
||||
private fun itemListUpdate() {
|
||||
// let itemlists be sorted
|
||||
itemListCraftable.rebuild()
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
encumbrancePerc = getPlayerInventory().encumberment.toFloat()
|
||||
}
|
||||
|
||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||
if (!openingClickLatched) {
|
||||
return super.touchDown(screenX, screenY, pointer, button)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun updateImpl(delta: Float) {
|
||||
// NO super.update due to an infinite recursion
|
||||
this.uiItems.forEach { it.update(delta) }
|
||||
|
||||
if (openingClickLatched && !Terrarum.mouseDown) openingClickLatched = false
|
||||
}
|
||||
|
||||
override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) {
|
||||
// NO super.render due to an infinite recursion
|
||||
this.uiItems.forEach { it.render(frameDelta, batch, camera) }
|
||||
|
||||
batch.color = Color.WHITE
|
||||
|
||||
// text label for two inventory grids
|
||||
val craftingLabel = Lang["GAME_CRAFTING"]
|
||||
val ingredientsLabel = Lang["GAME_INVENTORY_INGREDIENTS"]
|
||||
|
||||
App.fontGame.draw(batch, craftingLabel, thisOffsetX + (cellsWidth - App.fontGame.getWidth(craftingLabel)) / 2, thisOffsetY - INVENTORY_NAME_TEXT_GAP)
|
||||
App.fontGame.draw(batch, ingredientsLabel, thisOffsetX + (cellsWidth - App.fontGame.getWidth(ingredientsLabel)) / 2, thisOffsetY + LAST_LINE_IN_GRID - INVENTORY_NAME_TEXT_GAP)
|
||||
|
||||
|
||||
// control hints
|
||||
val controlHintXPos = thisOffsetX + 2f
|
||||
blendNormalStraightAlpha(batch)
|
||||
App.fontGame.draw(batch, controlHelp, controlHintXPos, UIInventoryFull.yEnd - 20)
|
||||
|
||||
|
||||
if (INGAME.actorNowPlaying != null) {
|
||||
//draw player encumb
|
||||
val encumbBarXPos = thisXend - UIInventoryCells.weightBarWidth + 36
|
||||
val encumbBarYPos = UIInventoryFull.yEnd - 20 + 3f
|
||||
UIInventoryCells.drawEncumbranceBar(batch, encumbBarXPos, encumbBarYPos, encumbrancePerc, INGAME.actorNowPlaying!!.inventory)
|
||||
}
|
||||
|
||||
|
||||
blendNormalStraightAlpha(batch)
|
||||
}
|
||||
|
||||
override fun doOpening(delta: Float) {
|
||||
super.doOpening(delta)
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun doClosing(delta: Float) {
|
||||
super.doClosing(delta)
|
||||
INGAME.setTooltipMessage(null)
|
||||
}
|
||||
|
||||
override fun endOpening(delta: Float) {
|
||||
super.endOpening(delta)
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
override fun endClosing(delta: Float) {
|
||||
super.endClosing(delta)
|
||||
resetUI()
|
||||
tooltipShowing.clear()
|
||||
INGAME.setTooltipMessage(null) // required!
|
||||
}
|
||||
|
||||
|
||||
override fun dispose() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
data class RecipeIngredientRecord(
|
||||
val selectedItem: ItemID,
|
||||
val howManyPlayerHas: Long,
|
||||
val howManyRecipeWants: Long,
|
||||
val craftingStationAvailable: Boolean,
|
||||
)
|
||||
|
||||
fun getItemCandidatesForIngredient(inventory: FixtureInventory, ingredient: CraftingCodex.CraftingIngredients): List<InventoryPair> {
|
||||
return if (ingredient.keyMode == CraftingCodex.CraftingItemKeyMode.TAG) {
|
||||
val tags = ingredient.key.split(',')
|
||||
val wantsWall = tags.contains("WALL")
|
||||
// If the player has the required item, use it; otherwise, will take an item from the ItemCodex
|
||||
inventory.filter { (itm, qty) ->
|
||||
ItemCodex[itm]?.hasAllTags(tags) == true && qty >= ingredient.qty && (wantsWall == itm.isWall()) // true if (wants wall and is wall) or (wants no wall and is not wall)
|
||||
}
|
||||
}
|
||||
else {
|
||||
listOf(InventoryPair(ingredient.key, -1))
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveIngredientKey(inventory: FixtureInventory, ingredient: CraftingCodex.CraftingIngredients, product: ItemID): ItemID {
|
||||
val candidate = getItemCandidatesForIngredient(inventory, ingredient).filter { it.itm != product }
|
||||
|
||||
// printdbg(this, "resolveIngredientKey product=$product, candidate=$candidate")
|
||||
|
||||
return if (ingredient.keyMode == CraftingCodex.CraftingItemKeyMode.TAG) {
|
||||
// filter out the product itself from the ingredient
|
||||
candidate.maxByOrNull { it.qty }?.itm ?: (
|
||||
(ItemCodex.itemCodex.firstNotNullOfOrNull { if (it.value.hasTag(ingredient.key)) it.key else null }) ?:
|
||||
throw NullPointerException("Item with tag '${ingredient.key}' not found. Possible cause: game or a module not updated or installed (ingredient: $ingredient)")
|
||||
)
|
||||
}
|
||||
else {
|
||||
ingredient.key
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For each ingredient of the recipe, returns list of (ingredient, how many the player has the ingredient, how many the recipe wants)
|
||||
*/
|
||||
fun recipeToIngredientRecord(inventory: FixtureInventory, recipe: CraftingCodex.CraftingRecipe, nearbyCraftingStations: List<String>): List<RecipeIngredientRecord> {
|
||||
val hasStation = if (recipe.workbench.isBlank()) true else nearbyCraftingStations.containsAll(recipe.workbench.split(','))
|
||||
return recipe.ingredients.map { ingredient ->
|
||||
val selectedItem = resolveIngredientKey(inventory, ingredient, recipe.product)
|
||||
val howManyPlayerHas = inventory.searchByID(selectedItem)?.qty ?: 0L
|
||||
val howManyTheRecipeWants = ingredient.qty
|
||||
|
||||
RecipeIngredientRecord(selectedItem, howManyPlayerHas, howManyTheRecipeWants, hasStation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.DroppedItem
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELLS_HOR
|
||||
@@ -36,7 +37,7 @@ internal class UIInventoryCells(
|
||||
val weightBarWidth = UIItemInventoryElemSimple.height * 2f + UIItemInventoryItemGrid.listGap
|
||||
// var encumbBarYPos = (App.scr.height + internalHeight).div(2) - 20 + 3f
|
||||
|
||||
fun drawEncumbranceBar(batch: SpriteBatch, encumbBarXPos: Float, encumbBarYPos: Float, encumbrancePerc: Float, actorInventory: FixtureInventory) {
|
||||
fun drawEncumbranceBar(batch: SpriteBatch, encumbBarXPos: Float, encumbBarYPos: Float, encumbrancePerc: Float, actorInventory: ActorInventory) {
|
||||
//draw player encumb
|
||||
// encumbrance meter
|
||||
val encumbranceText = Lang["GAME_INVENTORY_ENCUMBRANCE"]
|
||||
@@ -75,7 +76,7 @@ internal class UIInventoryCells(
|
||||
else
|
||||
"${(actorInventory.capacity * 100L).toLong() / 100.0}"
|
||||
|
||||
INGAME.setTooltipMessage("$capaStr/${actorInventory.maxCapacity}.0")
|
||||
INGAME.setTooltipMessage("$capaStr/${actorInventory.maxCapacityByActor}")
|
||||
tooltipShowing[10001] = true
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -140,10 +140,10 @@ class UIInventoryFull(
|
||||
|
||||
}
|
||||
|
||||
internal var xEnd = (Toolkit.drawWidth + internalWidth).div(2).toFloat()
|
||||
private set
|
||||
internal var yEnd = -YPOS_CORRECTION + (App.scr.height + internalHeight).div(2).toFloat()
|
||||
private set
|
||||
internal val xEnd: Float
|
||||
get() = (Toolkit.drawWidth + internalWidth).div(2).toFloat()
|
||||
internal val yEnd: Float
|
||||
get() = -YPOS_CORRECTION + (App.scr.height + internalHeight).div(2).toFloat()
|
||||
}
|
||||
|
||||
//val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
|
||||
@@ -247,7 +247,6 @@ class UIInventoryFull(
|
||||
|
||||
// private val transitionalMinimap = UIInventoryMinimap(this)
|
||||
internal val transitionalCraftingUI = UICrafting(this)
|
||||
internal val transitionalTechTreeViewUI = UITechView(this)
|
||||
internal val transitionalItemCells = UIInventoryCells(this)
|
||||
internal val transitionalEscMenu = UIInventoryEscMenu(this)
|
||||
val transitionPanel = UIItemHorizontalFadeSlide(
|
||||
@@ -257,7 +256,7 @@ class UIInventoryFull(
|
||||
width,
|
||||
App.scr.height,
|
||||
1f,
|
||||
listOf(transitionalCraftingUI, transitionalTechTreeViewUI),
|
||||
listOf(transitionalCraftingUI),
|
||||
listOf(transitionalItemCells),
|
||||
listOf(transitionalEscMenu)
|
||||
)
|
||||
@@ -320,7 +319,6 @@ class UIInventoryFull(
|
||||
transitionPanel.forcePosition(0)
|
||||
catBar.setSelectedPanel(0)
|
||||
transitionalCraftingUI.resetUI()
|
||||
transitionalTechTreeViewUI.resetUI()
|
||||
it.setAsOpen()
|
||||
}
|
||||
|
||||
@@ -442,9 +440,6 @@ class UIInventoryFull(
|
||||
|
||||
offsetX = ((width - internalWidth) / 2).toFloat()
|
||||
offsetY = ((App.scr.height - internalHeight) / 2).toFloat()
|
||||
|
||||
xEnd = (width + internalWidth).div(2).toFloat()
|
||||
yEnd = -YPOS_CORRECTION + (scr.height + internalHeight).div(2).toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import net.torvald.terrarum.CraftingRecipeCodex
|
||||
import net.torvald.terrarum.ItemCodex
|
||||
import net.torvald.terrarum.ui.UIItemCatBar
|
||||
import net.torvald.terrarum.ceilToInt
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
@@ -15,7 +14,7 @@ import net.torvald.terrarum.ui.UIItemCatBar.Companion.CAT_ALL
|
||||
* Created by minjaesong on 2022-06-28.
|
||||
*/
|
||||
class UIItemCraftingCandidateGrid(
|
||||
parentUI: UICrafting,
|
||||
parentUI: UICraftingWorkbench,
|
||||
initialX: Int, initialY: Int,
|
||||
horizontalCells: Int, verticalCells: Int,
|
||||
drawScrollOnRightside: Boolean = false,
|
||||
@@ -83,7 +82,7 @@ class UIItemCraftingCandidateGrid(
|
||||
|
||||
private fun isCraftable(player: FixtureInventory, recipe: CraftingCodex.CraftingRecipe, nearbyCraftingStations: List<String>): Boolean {
|
||||
// printdbg(this, "Is this recipe craftable? $recipe")
|
||||
return UICrafting.recipeToIngredientRecord(player, recipe, nearbyCraftingStations).none {
|
||||
return UICraftingWorkbench.recipeToIngredientRecord(player, recipe, nearbyCraftingStations).none {
|
||||
// printdbg(this, " considering ingredient ${it.selectedItem}, ${it.howManyRecipeWants} is required and got ${it.howManyPlayerHas}; crafting station available? ${it.craftingStationAvailable}")
|
||||
it.howManyPlayerHas <= 0L || !it.craftingStationAvailable
|
||||
}
|
||||
@@ -114,14 +113,14 @@ class UIItemCraftingCandidateGrid(
|
||||
if (currentFilter1 == CAT_ALL)
|
||||
CraftingRecipeCodex.props.forEach { (_, recipes) ->
|
||||
recipes.forEach {
|
||||
if (isCraftable((parentUI as UICrafting).getPlayerInventory(), it, (parentUI as UICrafting).nearbyCraftingStations)) {
|
||||
if (isCraftable((parentUI as UICraftingWorkbench).getPlayerInventory(), it, (parentUI as UICraftingWorkbench).nearbyCraftingStations)) {
|
||||
craftingRecipes.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
CraftingRecipeCodex.getCraftableRecipesUsingTheseItems(currentFilter1).forEach {
|
||||
if (isCraftable((parentUI as UICrafting).getPlayerInventory(), it, (parentUI as UICrafting).nearbyCraftingStations)) {
|
||||
if (isCraftable((parentUI as UICraftingWorkbench).getPlayerInventory(), it, (parentUI as UICraftingWorkbench).nearbyCraftingStations)) {
|
||||
craftingRecipes.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.ui.Movement
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import net.torvald.unicode.getKeycapConsole
|
||||
import net.torvald.unicode.getKeycapPC
|
||||
import kotlin.math.roundToInt
|
||||
@@ -70,6 +71,13 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
||||
|
||||
internal lateinit var cellLoadThread: Thread
|
||||
|
||||
init {
|
||||
CommonResourcePool.addToLoadingList("gradtile32") {
|
||||
TextureRegionPack("assets/graphics/gui/gradtile32.tga", 1, 32)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
}
|
||||
|
||||
fun advanceMode() {
|
||||
App.printdbg(this, "Load playerUUID: ${UILoadGovernor.playerUUID}, worldUUID: ${UILoadGovernor.worldUUID}")
|
||||
full.loadables = SavegameCollectionPair(App.savegamePlayers[UILoadGovernor.playerUUID], App.savegameWorlds[UILoadGovernor.worldUUID])
|
||||
@@ -175,14 +183,16 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
||||
batch.end()
|
||||
|
||||
val cells = playerCells
|
||||
val grad = CommonResourcePool.getAsTextureRegionPack("gradtile32")
|
||||
val w = 4096f
|
||||
|
||||
lateinit var savePixmap: Pixmap
|
||||
sliderFBO.inAction(camera, batch) {
|
||||
gdxClearAndEnableBlend(0f, 0f, 0f, 0f)
|
||||
|
||||
full.setCameraPosition(batch, camera, 0f, 0f)
|
||||
batch.color = Color.WHITE
|
||||
batch.inUse {
|
||||
blendNormalStraightAlpha(batch)
|
||||
for (index in 0 until cells.size) {
|
||||
val it = cells[index]
|
||||
|
||||
@@ -195,49 +205,30 @@ class UILoadList(val full: UILoadSavegame) : UICanvas() {
|
||||
if (App.getConfigBoolean("fx_streamerslayout"))
|
||||
it.posX -= uiXdiffChatOverlay
|
||||
}
|
||||
}
|
||||
savePixmap = Pixmap.createFromFrameBuffer(0, 0, sliderFBO.width, sliderFBO.height)
|
||||
savePixmap.blending = Pixmap.Blending.None
|
||||
}
|
||||
|
||||
|
||||
// implement "wipe-out" by CPU-rendering (*deep exhale*)
|
||||
//savePixmap.setColor(1f,1f,1f,0f)
|
||||
savePixmap.setColor(0f, 0f, 0f, 0f)
|
||||
savePixmap.fillRectangle(0, savePixmap.height - titleTopGradStart, savePixmap.width, titleTopGradStart)
|
||||
// top grad
|
||||
for (y in titleTopGradStart until titleTopGradEnd) {
|
||||
val alpha = (y - titleTopGradStart).toFloat() / gradAreaHeight
|
||||
for (x in 0 until savePixmap.width) {
|
||||
val col = savePixmap.getPixel(x, savePixmap.height - y)
|
||||
val blendAlpha = (col.and(0xFF) * alpha).roundToInt()
|
||||
savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha)
|
||||
// wipe out top and bottom
|
||||
blendAlphaMask(batch)
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(grad.get(3,0), 0f, 0f, w, titleTopGradStart.toFloat())
|
||||
batch.draw(grad.get(1,0), 0f, titleTopGradStart.toFloat(), w, grad.tileH.toFloat())
|
||||
batch.draw(grad.get(2,0), 0f, titleTopGradEnd.toFloat(), w, (titleBottomGradStart - titleTopGradEnd).toFloat())
|
||||
batch.draw(grad.get(0,0), 0f, titleBottomGradStart.toFloat(), w, grad.tileH.toFloat())
|
||||
batch.draw(grad.get(3,0), 0f, titleBottomGradEnd.toFloat(), w, 4096f)
|
||||
}
|
||||
}
|
||||
// bottom grad
|
||||
for (y in titleBottomGradStart until titleBottomGradEnd) {
|
||||
val alpha = 1f - ((y - titleBottomGradStart).toFloat() / gradAreaHeight)
|
||||
for (x in 0 until savePixmap.width) {
|
||||
val col = savePixmap.getPixel(x, savePixmap.height - y)
|
||||
val blendAlpha = (col.and(0xFF) * alpha).roundToInt()
|
||||
savePixmap.drawPixel(x, savePixmap.height - y, col.and(0xFFFFFF00.toInt()) or blendAlpha)
|
||||
}
|
||||
}
|
||||
savePixmap.setColor(0f, 0f, 0f, 0f)
|
||||
savePixmap.fillRectangle(0, 0, savePixmap.width, height - titleBottomGradEnd + 1)
|
||||
|
||||
|
||||
|
||||
full.setCameraPosition(batch, camera, 0f, 0f)
|
||||
val saveTex = TextureRegion(Texture(savePixmap)); saveTex.flip(false, true)
|
||||
batch.inUse {
|
||||
batch.draw(saveTex, posX + (width - uiWidth - 10) / 2f, 0f)
|
||||
batch.color = Color.WHITE
|
||||
blendNormalStraightAlpha(batch)
|
||||
(batch as FlippingSpriteBatch).drawFlipped(sliderFBO.colorBufferTexture, posX + (width - uiWidth - 10) / 2f, 0f)
|
||||
// Control help
|
||||
App.fontGame.draw(batch, controlHelp, posX + full.uiX.toFloat(), controlHelperY.toFloat())
|
||||
}
|
||||
|
||||
saveTex.texture.dispose()
|
||||
savePixmap.dispose()
|
||||
|
||||
batch.begin()
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.torvald.colourutil.cieluv_getGradient
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureSmelterBasic
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
||||
@@ -128,7 +129,7 @@ class UISmelterBasic(val smelter: FixtureSmelterBasic) : UICanvas(
|
||||
}
|
||||
}
|
||||
|
||||
fun getPlayerInventory(): FixtureInventory = INGAME.actorNowPlaying!!.inventory
|
||||
fun getPlayerInventory(): ActorInventory = INGAME.actorNowPlaying!!.inventory
|
||||
|
||||
private var listModeButtonPushed = false
|
||||
|
||||
@@ -357,9 +358,7 @@ class UISmelterBasic(val smelter: FixtureSmelterBasic) : UICanvas(
|
||||
// let itemlists be sorted
|
||||
inventoryFilter = { _: InventoryPair -> true }
|
||||
playerThings.rebuild(FILTER_CAT_ALL)
|
||||
encumbrancePerc = getPlayerInventory().let {
|
||||
it.capacity.toFloat() / it.maxCapacity
|
||||
}
|
||||
encumbrancePerc = getPlayerInventory().encumberment.toFloat()
|
||||
}
|
||||
|
||||
private var inventoryFilter = { _: InventoryPair -> true }
|
||||
@@ -368,17 +367,13 @@ class UISmelterBasic(val smelter: FixtureSmelterBasic) : UICanvas(
|
||||
// let itemlists be sorted
|
||||
inventoryFilter = filter
|
||||
playerThings.rebuild(filter)
|
||||
encumbrancePerc = getPlayerInventory().let {
|
||||
it.capacity.toFloat() / it.maxCapacity
|
||||
}
|
||||
encumbrancePerc = getPlayerInventory().encumberment.toFloat()
|
||||
}
|
||||
|
||||
private fun itemListUpdateKeepCurrentFilter() {
|
||||
// let itemlists be sorted
|
||||
playerThings.rebuild(inventoryFilter)
|
||||
encumbrancePerc = getPlayerInventory().let {
|
||||
it.capacity.toFloat() / it.maxCapacity
|
||||
}
|
||||
encumbrancePerc = getPlayerInventory().encumberment.toFloat()
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.getWidthOfCells
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
||||
@@ -44,7 +45,7 @@ internal class UIStorageChest : UICanvas(
|
||||
|
||||
override fun getNegotiator() = negotiator
|
||||
override fun getFixtureInventory(): FixtureInventory = chestInventory
|
||||
override fun getPlayerInventory(): FixtureInventory = INGAME.actorNowPlaying!!.inventory
|
||||
override fun getPlayerInventory(): ActorInventory = INGAME.actorNowPlaying!!.inventory
|
||||
|
||||
private val catBar: UIItemCatBar
|
||||
private val itemListChest: UITemplateHalfInventory
|
||||
|
||||
@@ -14,10 +14,10 @@ import net.torvald.unicode.getKeycapPC
|
||||
/**
|
||||
* Created by minjaesong on 2024-02-18.
|
||||
*/
|
||||
class UITechView(val full: UIInventoryFull?, private val colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme,
|
||||
class UITechView(val inventoryUI: UIInventoryFull?, val parentContainer: UICrafting, private val colourTheme: InventoryCellColourTheme = UIItemInventoryCellCommonRes.defaultInventoryCellTheme,
|
||||
) : UICanvas(
|
||||
toggleKeyLiteral = if (full == null) "control_key_inventory" else null,
|
||||
toggleButtonLiteral = if (full == null) "control_gamepad_start" else null
|
||||
toggleKeyLiteral = if (inventoryUI == null) "control_key_inventory" else null,
|
||||
toggleButtonLiteral = if (inventoryUI == null) "control_gamepad_start" else null
|
||||
) {
|
||||
|
||||
override var width = Toolkit.drawWidth
|
||||
@@ -34,10 +34,10 @@ class UITechView(val full: UIInventoryFull?, private val colourTheme: InventoryC
|
||||
|
||||
// private val navbarX = posX1 + UIItemListNavBarVertical.LIST_TO_CONTROL_GAP
|
||||
// private val navbarY = posY1
|
||||
private val navbarX = full!!.transitionalCraftingUI.itemListCraftable.navRemoCon.posX + 12
|
||||
private val navbarY = full!!.transitionalCraftingUI.itemListCraftable.navRemoCon.posY - 8
|
||||
private val navbarX = parentContainer.transitionalCraftingUI.itemListCraftable.navRemoCon.posX + 12
|
||||
private val navbarY = parentContainer.transitionalCraftingUI.itemListCraftable.navRemoCon.posY - 8
|
||||
private val navbarWidth = UIItemListNavBarVertical.WIDTH
|
||||
private val navbarHeight = full!!.transitionalCraftingUI.itemListCraftable.height
|
||||
private val navbarHeight = parentContainer.transitionalCraftingUI.itemListCraftable.height
|
||||
|
||||
private val panelX = 32 + navbarX
|
||||
private val panelY = navbarY
|
||||
@@ -61,8 +61,7 @@ class UITechView(val full: UIInventoryFull?, private val colourTheme: InventoryC
|
||||
highlightable = true
|
||||
).also {
|
||||
it.clickOnceListener = { _, _ ->
|
||||
full?.transitionPanel?.setLeftUIto(0)
|
||||
full?.transitionPanel?.uis?.get(0)?.show()
|
||||
parentContainer.showCraftingUI()
|
||||
it.highlighted = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package net.torvald.terrarum.modulebasegame.ui
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
||||
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.CreditSingleton
|
||||
import net.torvald.terrarum.ceilToInt
|
||||
import net.torvald.terrarum.ui.*
|
||||
import java.util.TreeMap
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.ui.UIItemTextArea
|
||||
import net.torvald.terrarum.ui.UIItemVertSlider
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class UITitleWallOfText(private val text: List<String>) : UICanvas() {
|
||||
init {
|
||||
@@ -90,11 +94,16 @@ class UISystemInfo(val remoCon: UIRemoCon) : UICanvas() {
|
||||
private var uptime: Long = 0L
|
||||
|
||||
init {
|
||||
|
||||
// auto resize for fullscreen
|
||||
val disp = Lwjgl3ApplicationConfiguration.getDisplayMode(Lwjgl3ApplicationConfiguration.getPrimaryMonitor())
|
||||
|
||||
v.add("${App.GAME_NAME}" to App.getVERSION_STRING())
|
||||
v.add("JRE" to System.getProperty("java.version"))
|
||||
v.add("Gdx" to com.badlogic.gdx.Version.VERSION)
|
||||
v.add("LWJGL" to "${org.lwjgl.Version.VERSION_MAJOR}.${org.lwjgl.Version.VERSION_MINOR}.${org.lwjgl.Version.VERSION_REVISION}")
|
||||
v.add("OS" to "${App.OSName} ${App.OSVersion}")
|
||||
v.add("Display" to "${App.scr.windowW}\u00D7${App.scr.windowH}@${App.scr.magn.times(100).roundToInt()}%, ${disp.bitsPerPixel}bpp (internally ${App.scr.width}\u00D7${App.scr.height})")
|
||||
v.add("Processor" to "${App.THREAD_COUNT}\u2009\u00D7\u2009${App.processor}")
|
||||
v.add("Architecture" to App.systemArch)
|
||||
v.add("CPUID" to App.processorVendor.let { if (it == "null" || it == null) "n/a" else it })
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
||||
import net.torvald.terrarum.ui.*
|
||||
@@ -36,7 +37,7 @@ class UIWorldPortalCargo(val full: UIWorldPortal) : UICanvas(), HasInventory {
|
||||
|
||||
override fun getNegotiator() = negotiator
|
||||
override fun getFixtureInventory(): FixtureInventory = chestInventory
|
||||
override fun getPlayerInventory(): FixtureInventory = INGAME.actorNowPlaying!!.inventory
|
||||
override fun getPlayerInventory(): ActorInventory = INGAME.actorNowPlaying!!.inventory
|
||||
|
||||
private val catBar: UIItemCatBar
|
||||
private val itemListChest: UIItemInventoryItemGrid
|
||||
@@ -155,7 +156,7 @@ class UIWorldPortalCargo(val full: UIWorldPortal) : UICanvas(), HasInventory {
|
||||
itemListChest.rebuild(catBar.catIconsMeaning[catBar.selectedIndex])
|
||||
itemListPlayer.rebuild(catBar.catIconsMeaning[catBar.selectedIndex])
|
||||
|
||||
encumbrancePerc = getPlayerInventory().capacity.toFloat() / getPlayerInventory().maxCapacity
|
||||
encumbrancePerc = (getPlayerInventory().capacity / getPlayerInventory().maxCapacityByActor).toFloat()
|
||||
isEncumbered = getPlayerInventory().isEncumbered
|
||||
}
|
||||
|
||||
|
||||
@@ -332,16 +332,16 @@ internal object TerragenTest : NoiseMaker {
|
||||
Block.STONE_MARBLE to Color(0.8f, 0.8f, 0.8f, 1f)
|
||||
)
|
||||
|
||||
private val COPPER_ORE = 0//x00e9c8ff.toInt()
|
||||
private val IRON_ORE = 0//xff7e74ff.toInt()
|
||||
private val COAL_ORE = 0//x383314ff.toInt()
|
||||
private val ZINC_ORE = 0//xefde76ff.toInt()
|
||||
private val TIN_ORE = 0//xcd8b62ff.toInt()
|
||||
private val GOLD_ORE = 0//xffcc00ff.toInt()
|
||||
private val SILVER_ORE = 0//xd5d9f9ff.toInt()
|
||||
private val LEAD_ORE = 0//xff9300ff.toInt()
|
||||
private val QUARTZ = 0//x55ff33ff.toInt()
|
||||
private val AMETHYST = 0//xee77ffff.toInt()
|
||||
private val COPPER_ORE = 0x00e9c8ff.toInt()
|
||||
private val IRON_ORE = 0xff7e74ff.toInt()
|
||||
private val COAL_ORE = 0x383314ff.toInt()
|
||||
private val ZINC_ORE = 0xefde76ff.toInt()
|
||||
private val TIN_ORE = 0xcd8b62ff.toInt()
|
||||
private val GOLD_ORE = 0xffcc00ff.toInt()
|
||||
private val SILVER_ORE = 0xd5d9f9ff.toInt()
|
||||
private val LEAD_ORE = 0xff9300ff.toInt()
|
||||
private val QUARTZ = 0x55ff33ff.toInt()
|
||||
private val AMETHYST = 0xee77ffff.toInt()
|
||||
private val ROCKSALT = 0xff00ffff.toInt()
|
||||
private val NITRE = 0xdbd6a1ff.toInt()
|
||||
|
||||
@@ -684,7 +684,7 @@ internal object TerragenTest : NoiseMaker {
|
||||
Joise(groundScalingCached),
|
||||
Joise(caveScaling),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:1", 0.026, 0.010, 0.517, 1.0)),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:2", 0.045, 0.011, 0.517, 1.0)),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:2", 0.031, 0.011, 0.521, 1.0)),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:3", 0.017, 0.070, 0.511, 3.8)),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:4", 0.019, 0.011, 0.511, 1.0)),
|
||||
Joise(generateOreVeinModule(caveAttenuateBiasScaledCache, seed shake "ores@basegame:5", 0.017, 0.017, 0.511, 1.0)),
|
||||
|
||||
@@ -3,11 +3,8 @@ package net.torvald.terrarum.utils
|
||||
import com.badlogic.gdx.Gdx
|
||||
import net.torvald.terrarum.App
|
||||
import java.awt.Desktop
|
||||
import java.awt.Toolkit
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
import java.awt.datatransfer.StringSelection
|
||||
import java.awt.datatransfer.UnsupportedFlavorException
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-07-31.
|
||||
@@ -15,7 +12,7 @@ import java.io.File
|
||||
object Clipboard {
|
||||
private val IS_MACOS = App.operationSystem == "OSX"
|
||||
|
||||
fun fetch(): String = Gdx.app.clipboard.contents
|
||||
fun fetch(): String = Gdx.app.clipboard.contents ?: ""
|
||||
|
||||
fun copy(s: String) {
|
||||
Gdx.app.clipboard.contents = s
|
||||
@@ -31,4 +28,11 @@ object OpenFile {
|
||||
if (IS_MACOS) return // at this point macOS might as well be a bane of existence for "some" devs Apple fanboys think they are not worthy of existence
|
||||
Desktop.getDesktop().open(file)
|
||||
}
|
||||
}
|
||||
|
||||
object OpenURL {
|
||||
private val IS_MACOS = App.operationSystem == "OSX"
|
||||
operator fun invoke(url: URL) {
|
||||
Gdx.net.openURI(url.toURI().toString())
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,10 @@ object WorldCamera {
|
||||
// zoomed coords. Currently only being used by the lightmaprenderer.
|
||||
// What about others? We just waste 3/4 of the framebuffer
|
||||
val zoomedX: Int
|
||||
get() = x + (width * zoomSamplePoint).toInt()
|
||||
get() {
|
||||
val t = (if (App.getConfigBoolean("fx_streamerslayout")) App.scr.chatWidth / 2 else 0).toFloat()
|
||||
return x + (width * zoomSamplePoint - (t * (zoom - 1f)) / 2f).toInt()
|
||||
}
|
||||
val zoomedY: Int
|
||||
get() = y + (height * zoomSamplePoint).toInt()
|
||||
|
||||
|
||||
Binary file not shown.
BIN
work_files/graphics/sprites/fixtures/copper_bulb.kra
LFS
Normal file
BIN
work_files/graphics/sprites/fixtures/copper_bulb.kra
LFS
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user