Skip to content

Commit

Permalink
Generation for FS25
Browse files Browse the repository at this point in the history
* Preview update and custom size.

* Version update.

* README update.

* README update.

* Integrated FS25 template.

* FS25 schema update.

* Finished integration of FS25.

* pylint updates.

* README update.
  • Loading branch information
iwatkot authored Nov 22, 2024
1 parent d8b8058 commit b5b08fc
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 49 deletions.
2 changes: 1 addition & 1 deletion README-steam.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ So, if you're new to map making, here's a quick overview of the process:
You'll find detailed instructions on how to run the project below. But if you prefer video tutorials, here's one for you.
https://www.youtube.com/watch?v=ujwWKHVKsw8

[b]🗺️ Supported map sizes:** 2x2, 4x4, 8x8, 16x16 km.[/b]
[b]🗺️ Supported map sizes: 2x2, 4x4, 8x8, 16x16 km.[/b]

[h3]Option 1: Use the web application[/h3]
In this case you don't need to install anything, just open the link and in a coiple of clicks your map template will be ready.
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@
🌍 Based on real-world data from OpenStreetMap<br>
🏞️ Generates height using SRTM dataset<br>
📦 Provides a ready-to-use map template for the Giants Editor<br>
🚜 Supports Farming Simulator 22 and 25*<br>

\* changes in the library are ready, waiting for the Giants to release the Giants Editor v10. Meanwhile the option to generate a map for FS25 is disabled.<br>
UPD: Giants Editor v10 is released, but it contains critical bugs, which prevent modders from creating maps. Waiting for the bugfix, until then the option to generate a map for FS25 will remain disabled.<br>
🚜 Supports Farming Simulator 22 and 25<br>

## Quick Start
There are several ways to use the tool. You obviously need the **first one**, but you can choose any of the others depending on your needs.<br>
Expand Down
Binary file added data/fs25-map-template.zip
Binary file not shown.
197 changes: 197 additions & 0 deletions data/fs25-texture-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
[
{
"name": "asphalt",
"count": 2
},
{
"name": "asphaltCracks",
"count": 2
},
{
"name": "asphaltDirt",
"count": 2
},
{
"name": "asphaltDusty",
"count": 2,
"tags": { "highway": ["motorway", "trunk", "primary"] },
"width": 8,
"color": [70, 70, 70]
},
{
"name": "asphaltGravel",
"count": 2
},
{
"name": "asphaltTwigs",
"count": 2
},
{
"name": "concrete",
"count": 2,
"tags": { "building": true },
"width": 8,
"color": [130, 130, 130]
},
{
"name": "concreteGravelSand",
"count": 2
},
{
"name": "concretePebbles",
"count": 2
},
{
"name": "concreteShattered",
"count": 2
},
{
"name": "forestGrass",
"count": 2
},
{
"name": "forestLeaves",
"count": 2
},
{
"name": "forestNeedels",
"count": 2
},
{
"name": "forestRockRoots",
"count": 2,
"exclude_weight": true
},
{
"name": "grass",
"count": 2,
"tags": { "natural": "grassland" },
"color": [34, 255, 34]
},
{
"name": "grassClovers",
"count": 2
},
{
"name": "grassCut",
"count": 2
},
{
"name": "grassDirtPatchy",
"count": 2,
"tags": { "natural": ["wood", "tree_row"] },
"width": 2,
"color": [0, 252, 124]
},
{
"name": "grassDirtPatchyDry",
"count": 2
},
{
"name": "grassDirtStones",
"count": 2
},
{
"name": "grassFreshMiddle",
"count": 2
},
{
"name": "grassFreshShort",
"count": 2
},
{
"name": "grassMoss",
"count": 2
},
{
"name": "gravel",
"count": 2
},
{
"name": "gravelDirtMoss",
"count": 2
},
{
"name": "gravelPebblesMoss",
"count": 2
},
{
"name": "gravelPebblesMossPatchy",
"count": 2
},
{
"name": "gravelSmall",
"count": 2
},
{
"name": "mudDark",
"count": 2,
"tags": { "highway": ["unclassified", "residential", "track"] },
"width": 2,
"color": [33, 67, 101]
},
{
"name": "mudDarkGrassPatchy",
"count": 2
},
{
"name": "mudDarkMossPatchy",
"count": 2
},
{
"name": "mudLeaves",
"count": 2
},
{
"name": "mudLight",
"count": 2,
"tags": { "highway": ["secondary", "tertiary", "road"] },
"width": 4,
"color": [140, 180, 210]
},
{
"name": "mudPebbles",
"count": 2
},
{
"name": "mudPebblesLight",
"count": 2
},
{
"name": "mudTracks",
"count": 2
},
{
"name": "pebblesForestGround",
"count": 2
},
{
"name": "rock",
"count": 2
},
{
"name": "rockFloorTiles",
"count": 2
},
{
"name": "rockFloorTilesPattern",
"count": 2
},
{
"name": "rockForest",
"count": 2
},
{
"name": "rockyForestGround",
"count": 2,
"tags": { "landuse": "farmland" },
"color": [47, 107, 85]
},
{
"name": "sand",
"count": 2,
"tags": { "natural": "water", "waterway": true },
"width": 10,
"color": [255, 20, 20]
}
]
21 changes: 17 additions & 4 deletions maps4fs/generator/dem.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def preprocess(self) -> None:
self.multiplier = self.kwargs.get("multiplier", DEFAULT_MULTIPLIER)
self.blur_radius = self.kwargs.get("blur_radius", DEFAULT_BLUR_RADIUS)
self.logger.debug(
"DEM multiplier is %s, blur radius is %s.", self.multiplier, self.blur_radius
"DEM value multiplier is %s, blur radius is %s.", self.multiplier, self.blur_radius
)

# pylint: disable=no-member
Expand All @@ -50,10 +50,10 @@ def process(self) -> None:
saves to map directory."""
north, south, east, west = self.bbox

dem_height = self.map_height * self.game.dem_multipliyer + 1
dem_width = self.map_width * self.game.dem_multipliyer + 1
dem_height = int((self.map_height / 2) * self.game.dem_multipliyer + 1)
dem_width = int((self.map_width / 2) * self.game.dem_multipliyer + 1)
self.logger.debug(
"DEM multiplier is %s, DEM height is %s, DEM width is %s.",
"DEM size multiplier is %s, DEM height is %s, DEM width is %s.",
self.game.dem_multipliyer,
dem_height,
dem_width,
Expand Down Expand Up @@ -129,6 +129,12 @@ def process(self) -> None:
cv2.imwrite(self._dem_path, resampled_data)
self.logger.debug("DEM data was saved to %s.", self._dem_path)

if self.game.additional_dem_name is not None:
dem_directory = os.path.dirname(self._dem_path)
additional_dem_path = os.path.join(dem_directory, self.game.additional_dem_name)
shutil.copyfile(self._dem_path, additional_dem_path)
self.logger.debug("Additional DEM data was copied to %s.", additional_dem_path)

def _tile_info(self, lat: float, lon: float) -> tuple[str, str]:
"""Returns latitude band and tile name for SRTM tile from coordinates.
Expand Down Expand Up @@ -218,6 +224,9 @@ def grayscale_preview(self) -> str:
str: Path to the preview image.
"""
rgb_dem_path = self._dem_path.replace(".png", "_grayscale.png")

self.logger.debug("Creating grayscale preview of DEM data in %s.", rgb_dem_path)

dem_data = cv2.imread(self._dem_path, cv2.IMREAD_GRAYSCALE)
dem_data_rgb = cv2.cvtColor(dem_data, cv2.COLOR_GRAY2RGB)
cv2.imwrite(rgb_dem_path, dem_data_rgb)
Expand All @@ -232,6 +241,9 @@ def colored_preview(self) -> str:
"""

colored_dem_path = self._dem_path.replace(".png", "_colored.png")

self.logger.debug("Creating colored preview of DEM data in %s.", colored_dem_path)

dem_data = cv2.imread(self._dem_path, cv2.IMREAD_GRAYSCALE)

# Create an empty array with the same shape and type as dem_data
Expand All @@ -250,4 +262,5 @@ def previews(self) -> list[str]:
Returns:
list[str]: List of preview images.
"""
self.logger.debug("Starting DEM previews generation.")
return [self.grayscale_preview(), self.colored_preview()]
53 changes: 52 additions & 1 deletion maps4fs/generator/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Game:

code: str | None = None
dem_multipliyer: int = 1
_additional_dem_name: str | None = None
_map_template_path: str | None = None
_texture_schema: str | None = None

Expand Down Expand Up @@ -102,6 +103,24 @@ def dem_file_path(self, map_directory: str) -> str:
"""
raise NotImplementedError

def weights_dir_path(self, map_directory: str) -> str:
"""Returns the path to the weights directory.
Arguments:
map_directory (str): The path to the map directory.
Returns:
str: The path to the weights directory."""
raise NotImplementedError

@property
def additional_dem_name(self) -> str | None:
"""Returns the name of the additional DEM file.
Returns:
str | None: The name of the additional DEM file."""
return self._additional_dem_name


class FS22(Game):
"""Class used to define the game version FS22."""
Expand All @@ -120,12 +139,23 @@ def dem_file_path(self, map_directory: str) -> str:
str: The path to the DEM file."""
return os.path.join(map_directory, "maps", "map", "data", "map_dem.png")

def weights_dir_path(self, map_directory: str) -> str:
"""Returns the path to the weights directory.
Arguments:
map_directory (str): The path to the map directory.
Returns:
str: The path to the weights directory."""
return os.path.join(map_directory, "maps", "map", "data")


class FS25(Game):
"""Class used to define the game version FS25."""

code = "FS25"
dem_multipliyer: int = 2
_additional_dem_name = "unprocessedHeightMap.png"
_map_template_path = os.path.join(working_directory, "data", "fs25-map-template.zip")
_texture_schema = os.path.join(working_directory, "data", "fs25-texture-schema.json")

Expand All @@ -137,4 +167,25 @@ def dem_file_path(self, map_directory: str) -> str:
Returns:
str: The path to the DEM file."""
return os.path.join(map_directory, "maps", "map", "data", "dem.png")
return os.path.join(map_directory, "mapUS", "data", "dem.png")

def map_xml_path(self, map_directory: str) -> str:
"""Returns the path to the map.xml file.
Arguments:
map_directory (str): The path to the map directory.
Returns:
str: The path to the map.xml file.
"""
return os.path.join(map_directory, "mapUS", "mapUS.xml")

def weights_dir_path(self, map_directory: str) -> str:
"""Returns the path to the weights directory.
Arguments:
map_directory (str): The path to the map directory.
Returns:
str: The path to the weights directory."""
return os.path.join(map_directory, "mapUS", "data")
9 changes: 8 additions & 1 deletion maps4fs/generator/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@ def previews(self) -> list[str]:
"""
previews = []
for component in self.components:
previews.extend(component.previews())
try:
previews.extend(component.previews())
except Exception as e: # pylint: disable=W0718
self.logger.error(
"Error getting previews for component %s: %s",
component.__class__.__name__,
e,
)
return previews

def pack(self, archive_name: str) -> str:
Expand Down
Loading

0 comments on commit b5b08fc

Please sign in to comment.