Skip to content

Commit 1594671

Browse files
Allow creating a floor from "raw" (images in the same orientation/size/etc) images
1 parent 65a4fed commit 1594671

2 files changed

Lines changed: 72 additions & 28 deletions

File tree

  • floormaker-cli/src/main/kotlin/net/sneakysims/floormaker/cli
  • floormaker-common/src/commonMain/kotlin/net/sneakysims/floormaker

floormaker-cli/src/main/kotlin/net/sneakysims/floormaker/cli/FloorMakerCLI.kt

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import net.perfectdreams.slippyimage.PaletteCreator
1212
import net.perfectdreams.slippyimage.SlippyImage
1313
import net.perfectdreams.slippyimage.convertToSlippyImage
1414
import net.sneakysims.floormaker.FloorMaker
15+
import net.sneakysims.floormaker.FloorMaker.convertToSPR2Sprite
1516
import net.sneakysims.floormaker.FloorSound
1617
import java.io.File
1718
import javax.imageio.ImageIO
@@ -21,7 +22,10 @@ class FloorMakerCLI : CliktCommand() {
2122
return "The Sims 1 Floor Maker made by MrPowerGamerBR (https://sneakysims.net)"
2223
}
2324

24-
val inputImage by option("--input", help = "The image that will be converted to a floor").required()
25+
val inputImage by option("--input", help = "The image that will be converted to a floor")
26+
val inputRawFarZoomImage by option("--input-raw-far-zoom", help = "The image that will be converted to a floor (far zoom), raw in this context means the image in the same position/rotation as a floor")
27+
val inputRawMediumZoomImage by option("--input-raw-medium-zoom", help = "The image that will be converted to a floor (medium zoom), raw in this context means the image in the same position/rotation as a floor")
28+
val inputRawNearZoomImage by option("--input-raw-near-zoom", help = "The image that will be converted to a floor (near zoom), raw in this context means the image in the same position/rotation as a floor")
2529
val name by option("--name", help = "The name of the item in game")
2630
val description by option("--description", help = "The description of the item in game")
2731
val price by option("--price", help = "The price of the item in game").int()
@@ -31,24 +35,48 @@ class FloorMakerCLI : CliktCommand() {
3135
val output by argument("output", help = "The output flr file")
3236

3337
override fun run() {
34-
val inputImage = ImageIO.read(File(inputImage))
35-
val slippyImage = SlippyImage.convertToSlippyImage(inputImage)
36-
val floorSprite = FloorMaker.createFloorSprite(slippyImage)
37-
val stepSound = stepSound ?: FloorSound.HARD_FLOOR
38-
39-
val colors = PaletteCreator.extractColors(floorSprite)
40-
val palette = PaletteCreator.kMeansQuantization(colors, 256)
41-
42-
val iff = FloorMaker.createFloorIFF(
43-
name ?: "",
44-
price ?: 1,
45-
description ?: "",
46-
stepSound,
47-
floorSprite,
48-
palette
49-
)
50-
51-
File(output).writeBytes(iff.write())
38+
if (inputImage != null) {
39+
val inputImage = ImageIO.read(File(inputImage))
40+
val slippyImage = SlippyImage.convertToSlippyImage(inputImage)
41+
val floorSprite = FloorMaker.createFloorSprite(slippyImage)
42+
val stepSound = stepSound ?: FloorSound.HARD_FLOOR
43+
44+
val colors = PaletteCreator.extractColors(floorSprite)
45+
val palette = PaletteCreator.kMeansQuantization(colors, 256)
46+
47+
val iff = FloorMaker.createFloorIFF(
48+
name ?: "",
49+
price ?: 1,
50+
description ?: "",
51+
stepSound,
52+
floorSprite,
53+
palette
54+
)
55+
56+
File(output).writeBytes(iff.write())
57+
} else if (inputRawFarZoomImage != null && inputRawMediumZoomImage != null && inputRawNearZoomImage != null) {
58+
val farZoomImage = SlippyImage.convertToSlippyImage(ImageIO.read(File(inputRawFarZoomImage)))
59+
val mediumZoomImage = SlippyImage.convertToSlippyImage(ImageIO.read(File(inputRawMediumZoomImage)))
60+
val nearZoomImage = SlippyImage.convertToSlippyImage(ImageIO.read(File(inputRawNearZoomImage)))
61+
62+
val stepSound = stepSound ?: FloorSound.HARD_FLOOR
63+
64+
val colors = PaletteCreator.extractColors(farZoomImage) + PaletteCreator.extractColors(mediumZoomImage) + PaletteCreator.extractColors(nearZoomImage)
65+
val palette = PaletteCreator.kMeansQuantization(colors, 256)
66+
67+
val iff = FloorMaker.createFloorIFF(
68+
name ?: "",
69+
price ?: 1,
70+
description ?: "",
71+
stepSound,
72+
convertToSPR2Sprite(farZoomImage, 31, 16, palette),
73+
convertToSPR2Sprite(mediumZoomImage, 63, 32, palette),
74+
convertToSPR2Sprite(nearZoomImage, 127, 64, palette),
75+
palette
76+
)
77+
78+
File(output).writeBytes(iff.write())
79+
} else error("Missing image input parameter!")
5280
}
5381
}
5482

floormaker-common/src/commonMain/kotlin/net/sneakysims/floormaker/FloorMaker.kt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@ object FloorMaker {
1111
stepSound: FloorSound,
1212
sprite: SlippyImage,
1313
palette: List<Color>
14+
): IFF {
15+
return createFloorIFF(
16+
name,
17+
price,
18+
description,
19+
stepSound,
20+
convertToSPR2Sprite(sprite, 31, 16, palette),
21+
convertToSPR2Sprite(sprite, 63, 32, palette),
22+
convertToSPR2Sprite(sprite, 127, 64, palette),
23+
palette
24+
)
25+
}
26+
27+
fun createFloorIFF(
28+
name: String,
29+
price: Int,
30+
description: String,
31+
stepSound: FloorSound,
32+
spriteFar: SPR2ChunkData.SPRSprite,
33+
spriteMedium: SPR2ChunkData.SPRSprite,
34+
spriteNear: SPR2ChunkData.SPRSprite,
35+
palette: List<Color>
1436
): IFF {
1537
val iff = IFF.empty()
1638

@@ -65,9 +87,7 @@ object FloorMaker {
6587
SPR2ChunkData(
6688
1000,
6789
1537,
68-
mutableListOf(
69-
convertToSPR2Sprite(sprite, 31, 16, palette)
70-
)
90+
mutableListOf(spriteFar)
7191
)
7292
)
7393

@@ -79,9 +99,7 @@ object FloorMaker {
7999
SPR2ChunkData(
80100
1000,
81101
1537,
82-
mutableListOf(
83-
convertToSPR2Sprite(sprite, 63, 32, palette)
84-
)
102+
mutableListOf(spriteMedium)
85103
)
86104
)
87105

@@ -93,9 +111,7 @@ object FloorMaker {
93111
SPR2ChunkData(
94112
1000,
95113
1537,
96-
mutableListOf(
97-
convertToSPR2Sprite(sprite, 127, 64, palette)
98-
)
114+
mutableListOf(spriteNear)
99115
)
100116
)
101117

0 commit comments

Comments
 (0)