Skip to content

Commit

Permalink
Merge pull request #188 from Poeschl/map-editor-locations
Browse files Browse the repository at this point in the history
Implement Map location edit function
  • Loading branch information
Poeschl authored Aug 29, 2024
2 parents 40e02e5 + 05b6042 commit ee7ed4e
Show file tree
Hide file tree
Showing 17 changed files with 609 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import xyz.poeschl.roborush.models.settings.ClientSettings
import xyz.poeschl.roborush.models.settings.SaveSettingDto
import xyz.poeschl.roborush.models.settings.Setting
import xyz.poeschl.roborush.models.settings.SettingKey
import xyz.poeschl.roborush.repositories.Tile
import xyz.poeschl.roborush.security.repository.User
import xyz.poeschl.roborush.service.ConfigService
import xyz.poeschl.roborush.service.MapService
Expand Down Expand Up @@ -102,6 +103,20 @@ class ConfigRestController(private val configService: ConfigService, private val
}
}

@SecurityRequirement(name = "Bearer Authentication")
@PreAuthorize("hasRole('${User.ROLE_ADMIN}')")
@PostMapping("/map/{id}/tile", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
fun setMapTile(@PathVariable id: Long, @RequestBody tile: Tile): PlaygroundMap {
val map = mapService.getMap(id)

if (map != null) {
val minMax = Pair(map.mapData.minOf { it.height }, map.mapData.maxOf { it.height })
return PlaygroundMap(mapService.setMapTile(map, tile), minMax)
} else {
throw MapNotFound("No matching map found for given id.")
}
}

@SecurityRequirement(name = "Bearer Authentication")
@PreAuthorize("hasRole('${User.ROLE_ADMIN}')")
@DeleteMapping("/map/{id}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package xyz.poeschl.roborush.controller.restmodels

import net.karneim.pojobuilder.GeneratePojoBuilder
import xyz.poeschl.roborush.configuration.Builder
import xyz.poeschl.roborush.models.Position
import xyz.poeschl.roborush.models.Size
import xyz.poeschl.roborush.repositories.Map
Expand All @@ -9,6 +11,7 @@ data class MapGenerationResult(val warnings: List<String>)

data class MapActiveDto(val active: Boolean)

@GeneratePojoBuilder(withBuilderInterface = Builder::class)
data class MapAttributeSaveDto(val mapName: String, val maxRobotFuel: Int, val solarChargeRate: Double)

data class PlaygroundMap(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlin.math.ceil

@GameLogic
class MapHandler {
private var currentMap = Map(0, "init", Size(0, 0), listOf(), Position(0, 0), 0)
private var currentMap = Map(0, "init", Size(0, 0), mutableListOf(), Position(0, 0), 0)

// Use a 2D array for faster tile data access
private var currentMapTiles = arrayOf(emptyArray<Tile>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ data class Map(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(insertable = false) val id: Long?,
@Column var mapName: String,
@Column val size: Size,
@Column val possibleStartPositions: List<Position>,
@Column val targetPosition: Position,
@Column val possibleStartPositions: MutableList<Position>,
@Column var targetPosition: Position,
@Column var maxRobotFuel: Int = 300,
@Column var solarChargeRate: Double = 0.0,
@Column var active: Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ data class Tile(
val id: Long?,
@Column val position: Position,
@Column val height: Int = 0,
@Column @Enumerated(EnumType.STRING) val type: TileType = TileType.DEFAULT_TILE
@Column @Enumerated(EnumType.STRING) var type: TileType = TileType.DEFAULT_TILE
) {

@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import xyz.poeschl.roborush.models.*
import xyz.poeschl.roborush.repositories.Map
import xyz.poeschl.roborush.repositories.MapRepository
import xyz.poeschl.roborush.repositories.Tile
import xyz.poeschl.roborush.repositories.TileRepository
import java.io.InputStream
import javax.imageio.ImageIO
import kotlin.time.measureTime

@Service
class MapService(private val mapRepository: MapRepository) {
class MapService(private val mapRepository: MapRepository, private val tileRepository: TileRepository) {

companion object {
private val LOGGER = LoggerFactory.getLogger(MapService::class.java)
Expand Down Expand Up @@ -68,6 +69,49 @@ class MapService(private val mapRepository: MapRepository) {
return mapRepository.save(map)
}

@Transactional
fun setMapTile(map: Map, tile: Tile): Map {
val stored = map.mapData.find { it.position == tile.position }
stored?.let { storedTile ->
when {
tile.type == TileType.START_TILE && storedTile.type == TileType.DEFAULT_TILE -> {
// A start tile is added
map.possibleStartPositions.add(storedTile.position)
storedTile.type = TileType.START_TILE
}

tile.type == TileType.DEFAULT_TILE && storedTile.type == TileType.START_TILE -> {
// A start tile is removed
if (map.possibleStartPositions.size > 1) {
// Keep at least one start position
map.possibleStartPositions.remove(storedTile.position)
storedTile.type = TileType.DEFAULT_TILE
}
}

tile.type == TileType.TARGET_TILE && storedTile.type == TileType.DEFAULT_TILE -> {
// A new target tile is stored
val oldTarget = map.mapData.find { it.position == map.targetPosition }
oldTarget?.let { old ->
old.type = TileType.DEFAULT_TILE
tileRepository.save(old)
}
map.targetPosition = storedTile.position
storedTile.type = TileType.TARGET_TILE
}

tile.type == TileType.DEFAULT_TILE && storedTile.type == TileType.TARGET_TILE -> {
// The target is removed, which is not possible
}
else -> {
storedTile.type = tile.type
}
}
tileRepository.save(storedTile)
}
return mapRepository.save(map)
}

fun deleteMap(map: Map) {
val deleteMap = measureTime {
mapRepository.delete(map)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,15 @@ class MapHandlerTest {
private fun createNewRandomMap(size: Size): Map {
val randomHeights = IntStream.range(0, size.width * size.height)
.map { Random.nextInt(0, 8) }.toList()
val startPositions = listOf(Position(0, 0), Position(0, 1), Position(1, 0), Position(1, 1))
val startPositions = mutableListOf(Position(0, 0), Position(0, 1), Position(1, 0), Position(1, 1))
val targetPosition = Position(size.width - 2, size.height - 2)
val map = Map(null, "gen", size, startPositions, targetPosition, 100)
createHeightMap(size, randomHeights, startPositions, targetPosition).forEach { map.addTile(it) }
return map
}

private fun createNewPresetMap(size: Size, heights: List<Int>, start: Position, target: Position = Position(size.width - 1, size.height - 1)): Map {
val map = Map(1L, "gen", size, listOf(start), target, 100)
val map = Map(1L, "gen", size, mutableListOf(start), target, 100)
createHeightMap(size, heights, listOf(start), target).forEach { map.addTile(it) }
return map
}
Expand Down
Loading

0 comments on commit ee7ed4e

Please sign in to comment.