Skip to content

Commit

Permalink
Fix positioning of map elements
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraq committed May 28, 2024
1 parent 7188c61 commit 10903d6
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CoordinateExtensions {
*/
static Vector2f asCellCoords(Integer self) {

return new Vector2f(self % TILES_Y, Math.ceil(self / TILES_Y) as float)
return new Vector2f(self % TILES_Y, Math.floor(self / TILES_Y) as float)
}

/**
Expand All @@ -66,7 +66,7 @@ class CoordinateExtensions {
*
* @param self
* @param objectHeightInCells
* Optional, height of the object whose coordinates are being translated.
* Vertical space occupied by the objheheight of the object whose coordinates are being translated.
* @return
*/
static Vector2f asWorldCoords(Vector2f self, int objectHeightInCells = 0) {
Expand All @@ -76,6 +76,15 @@ class CoordinateExtensions {
.add(WORLD_OFFSET)
}

/**
* Adjust a vector enough so that an arbitrary-sized sprite is centered in a
* map cell.
*/
static Vector2f centerInCell(Vector2f self, float spriteWidth, float spriteHeight) {

return self.sub((spriteWidth - TILE_WIDTH) / 2 as float, (spriteHeight - TILE_HEIGHT) / 2 as float)
}

/**
* Update the rectangle so that min/max values are valid, ie: if minX > maxX
* then minX <-> maxX, and same for the Y axis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class Unit extends Node<Unit> implements FactionColours, Rotatable, Temporal {
this.palette = palette
this.unitData = unitData

bounds.setMax(imagesFile.width, imagesFile.height)

body = new UnitBody(imagesFile.width, imagesFile.height, imagesFile.numImages, palette, { _ ->
return CompletableFuture.completedFuture(spriteSheet)
}, unitData)
Expand Down Expand Up @@ -105,6 +107,14 @@ class Unit extends Node<Unit> implements FactionColours, Rotatable, Temporal {
return 360f / unitData.shpFile.states[stateIndex].headings
}

/**
* Return the height of the unit, often determined by the sprite used for it.
*/
int getHeight() {

return bounds.lengthY()
}

/**
* Return the name of the current state of the unit.
*/
Expand All @@ -113,6 +123,14 @@ class Unit extends Node<Unit> implements FactionColours, Rotatable, Temporal {
return unitData.shpFile.states[stateIndex].name
}

/**
* Return the width of the unit, often determined by the sprite used for it.
*/
int getWidth() {

return bounds.lengthX()
}

@Override
CompletableFuture<Void> onSceneAdded(Scene scene) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ package nz.net.ultraq.redhorizon.explorer
*/
class MixDatabase {

private static final String[] sources = ['ra-conquer.csv', 'ra-missions.csv', 'ra-videos.csv']
private static final String[] sources = ['ra-config.csv', 'ra-conquer.csv', 'ra-missions.csv', 'ra-videos.csv']

private final List<MixData> data = []

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ID,Name
0xb1c3b238,rules.ini
0x1f223123,tutorial.ini
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import org.joml.Vector2f
*/
class GridLines extends Node<GridLines> {

private static final int COORD_MIN = -2400
private static final int COORD_MAX = 2400
private static final int COORD_MIN = -1536 // The max area a Red Alert map can be
private static final int COORD_MAX = 1536

GridLines() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package nz.net.ultraq.redhorizon.explorer.objects

import nz.net.ultraq.redhorizon.classic.Faction
import nz.net.ultraq.redhorizon.classic.filetypes.IniFile
import nz.net.ultraq.redhorizon.classic.filetypes.MapFile
import nz.net.ultraq.redhorizon.classic.filetypes.PalFile
import nz.net.ultraq.redhorizon.classic.filetypes.RulesFile
import nz.net.ultraq.redhorizon.classic.filetypes.ShpFile
import nz.net.ultraq.redhorizon.classic.filetypes.TmpFileRA
import nz.net.ultraq.redhorizon.classic.maps.InfantryLine
Expand Down Expand Up @@ -80,14 +82,15 @@ class Map extends Node<Map> {
private static final int TILE_HEIGHT = 24

final MapFile mapFile
final String name = "Map - ${mapFile.name}"
final String name = "Map - ${mapFile.basicSection.name()}"
final Theater theater
final Rectanglef boundary
final Vector2f initialPosition

private final Palette palette
private final TileSet tileSet
private final ResourceManager resourceManager
private final RulesFile rules

private CompletableFuture<Texture> paletteAsTextureFuture
private Texture paletteAsTexture
Expand Down Expand Up @@ -115,22 +118,26 @@ class Map extends Node<Map> {

var waypoints = mapFile.waypointsData
var waypoint98 = waypoints[98]
initialPosition = waypoint98.asCellCoords().asWorldCoords()
initialPosition = waypoint98.asCellCoords().asWorldCoords(1)

var halfMapWidth = (TILES_X * TILE_WIDTH) / 2 as float
var halfMapHeight = (TILES_Y * TILE_HEIGHT) / 2 as float
bounds.set(-halfMapWidth, -halfMapHeight, halfMapWidth, halfMapHeight)

tileSet = new TileSet()

// Rules file needed for some object configuration
var rulesIni = resourceManager.loadFile('rules.ini', IniFile)
rules = rulesIni as RulesFile

addChild(new MapBackground())
addChild(new MapPack())
addChild(new OverlayPack())
addChild(new Terrain())
addChild(new MapLines())
addChild(new Units())
addChild(new Infantry())
addChild(new Structures())
addChild(new MapLines())
}

@Override
Expand Down Expand Up @@ -217,17 +224,17 @@ class Map extends Node<Map> {
*/
private class MapLines extends Node<MapLines> {

private static final Vector2f X_AXIS_MIN = new Vector2f(-3600, 0)
private static final Vector2f X_AXIS_MAX = new Vector2f(3600, 0)
private static final Vector2f Y_AXIS_MIN = new Vector2f(0, -3600)
private static final Vector2f Y_AXIS_MAX = new Vector2f(0, 3600)
private static final Vector2f X_AXIS_MIN = new Vector2f(-3072, 0)
private static final Vector2f X_AXIS_MAX = new Vector2f(3072, 0)
private static final Vector2f Y_AXIS_MIN = new Vector2f(0, -3072)
private static final Vector2f Y_AXIS_MAX = new Vector2f(0, 3072)

MapLines() {

addChild(new Primitive(MeshType.LINES, Colour.RED.withAlpha(0.5), X_AXIS_MIN, X_AXIS_MAX, Y_AXIS_MIN, Y_AXIS_MAX).tap {
addChild(new Primitive(MeshType.LINES, Colour.RED.withAlpha(0.8), X_AXIS_MIN, X_AXIS_MAX, Y_AXIS_MIN, Y_AXIS_MAX).tap {
name = "XY axis (red)"
})
addChild(new Primitive(MeshType.LINE_LOOP, Colour.YELLOW.withAlpha(0.5), boundary as Vector2f[]).tap {
addChild(new Primitive(MeshType.LINE_LOOP, Colour.YELLOW.withAlpha(0.8), boundary as Vector2f[]).tap {
name = "Map boundary (yellow)"
})
}
Expand Down Expand Up @@ -509,7 +516,7 @@ class Map extends Node<Map> {
var terrainData = mapFile.terrainData
terrainData.each { cell, terrainType ->
var terrainFile = resourceManager.loadFile(terrainType + theater.ext, ShpFile)
var cellPosXY = (cell as int).asCellCoords().asWorldCoords(terrainFile.height / TILE_HEIGHT - 1 as int)
var cellPosXY = (cell as int).asCellCoords().asWorldCoords(terrainFile.height / TILE_HEIGHT as int)
tileSet.addTiles(terrainFile)

// TODO: Get TileSets to work with any sized sprites, then terrain can
Expand Down Expand Up @@ -553,7 +560,6 @@ class Map extends Node<Map> {
var unitData = new JsonSlurper().parseText(unitJson) as UnitData

return new Unit(unitImages, palette, unitData).tap {

configure(it, unitData)

// TODO: Country to faction map
Expand All @@ -562,9 +568,7 @@ class Map extends Node<Map> {
case "USSR" -> Faction.RED
default -> Faction.GOLD
}

heading = objectLine.heading
transform.translate((objectLine.coords as Vector2f).asWorldCoords())
}
}
}
Expand All @@ -580,6 +584,9 @@ class Map extends Node<Map> {
try {
var unit = createObject(unitLine) { unit, unitData ->
unit.name = "Vehicle - ${unitLine.faction}, ${unitLine.type}"
unit.transform.translate((unitLine.coords as Vector2f)
.asWorldCoords(1)
.centerInCell(unit.width, unit.height))
}
addChild(unit)
}
Expand All @@ -601,13 +608,16 @@ class Map extends Node<Map> {
mapFile.infantryData.eachWithIndex { infantryLine, index ->
try {
var infantry = createObject(infantryLine) { infantry, infantryData ->
infantry.name = "Infantry - ${infantryLine.faction}, ${infantryLine.type}"
infantry.transform.translate((infantryLine.coords as Vector2f)
.asWorldCoords(1)
.centerInCell(infantry.width, infantry.height))
switch (infantryLine.cellPos) {
case 1 -> infantry.transform.translate(-8, 8)
case 2 -> infantry.transform.translate(8, 8)
case 3 -> infantry.transform.translate(-8, -8)
case 4 -> infantry.transform.translate(8, -8)
}
infantry.name = "Infantry - ${infantryLine.faction}, ${infantryLine.type}"
}
addChild(infantry)
}
Expand All @@ -630,10 +640,14 @@ class Map extends Node<Map> {
try {
var structure = createObject(structureLine) { structure, structureData ->
structure.name = "Structure - ${structureLine.faction}, ${structureLine.type}"
var translate = (structureLine.coords as Vector2f).asWorldCoords(Math.ceil(structure.height / TILE_HEIGHT) as int)
if (structure.width < TILE_WIDTH || structure.height < TILE_HEIGHT) {
translate.centerInCell(structure.width, structure.height)
}
structure.transform.translate(translate)

// Push down 1 cell to account for bib placement
// structure.transform.translate(0, -TILE_HEIGHT)

// A special case for structures with secondary parts, namely the
// weapons factory for its garage door
var combineWith = structureData.shpFile.parts.body.combineWith
if (combineWith) {
var combinedImages = resourceManager.loadFile("${combineWith}.shp", ShpFile)
Expand Down

0 comments on commit 10903d6

Please sign in to comment.