Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ abstract class AbstractStrategy<LEVEL : GlobalAgentInterface<*>>(val agent: Agen

private val strategyOwner: Agent by lazy { agent as Agent }
val mothership: MothershipInterface by lazy { strategyOwner.mothership }

val tower: TowerInterface by lazy { strategyOwner.mothership.tower }
val enemyAgent get() = strategyOwner.enemyAgent
val teamAgent get() = strategyOwner.teamAgent
private val mothershipInternal: Mothership by lazy { strategyOwner.mothership }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.openbase.planetsudo.game.strategy

import org.openbase.planetsudo.game.SwatTeam
import org.openbase.planetsudo.level.LevelSize
import org.openbase.planetsudo.level.levelobjects.AgentInterface
import org.openbase.planetsudo.level.levelobjects.Resource.ResourceType
import org.openbase.planetsudo.level.levelobjects.Tower
Expand Down Expand Up @@ -37,18 +38,17 @@ class DivineStrategy(agent: AgentInterface) : StrategyLevelLegacy(agent) {
}
},
)
// -------------------------------------------->
createRule(
object : Rule("Discover", SwatTeam.COMMANDER) {
override fun constraint(): Boolean {
return true
}

override fun action() {
agent.goRight(4)
}
},
)
"Discover" commander inCase { true } then { agent.goRight(4) }

"Scan" commander inCase { tower.type == Tower.TowerType.ObservationTower && tower.levelSize == LevelSize.UNKNOWN } then {
tower.scanLevelSize()
}

"Place Observation Tower" commander inCase { agent.hasTower } then {
agent.constructTower(Tower.TowerType.ObservationTower)
}

// -------------------------------------------->
// createRule(
// object : Rule("Avoid Agents", SwatTeam.COMMANDER) {
Expand Down Expand Up @@ -498,19 +498,6 @@ class DivineStrategy(agent: AgentInterface) : StrategyLevelLegacy(agent) {
}
},
)
// -------------------------------------------->
createRule(
object : Rule("Construct Tower", SwatTeam.COMMANDER) {
override fun constraint(): Boolean {
return agent.hasTower && agent.seeResource
}

override fun action() {
agent.constructTower(Tower.TowerType.DefenceTower)
}
},
)
// -------------------------------------------->
createRule(
object : Rule("Follow Wall", SwatTeam.ALPHA) {
override fun constraint(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ abstract class AbstractLevel : AbstractGameObject, Runnable {
private val RESOURCES_LOCK: Any = SyncObject("ResourcesLock")
private val TOWER_LOCK: Any = SyncObject("TowerLock")
private val base: Point2D
val size: LevelSize by lazy { LevelSize.fromLevel(this) }

@JvmField
val levelBorderPolygon: Polygon
Expand Down Expand Up @@ -102,11 +103,11 @@ abstract class AbstractLevel : AbstractGameObject, Runnable {
this.base = calculateBasePosition(levelBorderPolygon)

levelBorderPolygon.translate(-base.x.toInt(), -base.y.toInt())
if (levelWallPolygons != null) {
for (p in levelWallPolygons) {
p.translate(-base.x.toInt(), -base.y.toInt())
}

for (p in levelWallPolygons) {
p.translate(-base.x.toInt(), -base.y.toInt())
}

for (homepos in homePositions) {
homepos.translateIntoBase(base)
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/kotlin/org/openbase/planetsudo/level/LevelSize.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.openbase.planetsudo.level

import kotlin.math.max

enum class LevelSize(val label: String) {
SMALL("Klein"),
MEDIUM("Mittel"),
LARGE("Groß"),
UNKNOWN("?"),
;

companion object {
fun fromLevel(level: AbstractLevel): LevelSize {
val size = max(level.levelBorderPolygon.bounds2D.width, level.levelBorderPolygon.bounds2D.height)
return when {
size <= 1000 -> SMALL
size <= 1500 -> MEDIUM
else -> LARGE
}
}
}
}
53 changes: 37 additions & 16 deletions src/main/kotlin/org/openbase/planetsudo/level/levelobjects/Tower.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.openbase.planetsudo.game.GameSound
import org.openbase.planetsudo.geometry.Direction2D
import org.openbase.planetsudo.geometry.Point2D
import org.openbase.planetsudo.level.AbstractLevel
import org.openbase.planetsudo.level.LevelSize
import org.openbase.planetsudo.level.ResourcePlacement
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand All @@ -34,23 +35,34 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
SIZE.toDouble(),
ObjectShape.Rec,
),
ActionListener {
ActionListener,
TowerInterface {
enum class TowerType {
DefenceTower, ObservationTower
Unknown, DefenceTower, ObservationTower
}

var type: TowerType? = null
override var type: TowerType = TowerType.Unknown
private set

private val lock = ReentrantLock()
private val condition = lock.newCondition()
private val placement: ResourcePlacement? = null
private val timer: Timer

override var levelSize: LevelSize = LevelSize.UNKNOWN

var shieldForce: Int = 0
private set
var fuel: Int = 0

override var fuel: Int = 0
private set

override val fuelVolume: Int
get() = TOWER_FUEL_VOLUME

override val fuelInPercent: Int
get() = (fuel * 100) / fuelVolume

@JvmField
val direction: Direction2D = Direction2D(0)
val isAttacked: Boolean = false
Expand All @@ -70,7 +82,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
Thread.sleep(1000)
continue
}
direction.angle = direction.angle + 10
direction.angle += 10
Thread.sleep(100)
}
} catch (ex: InterruptedException) {
Expand All @@ -82,7 +94,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
}

@Throws(CouldNotPerformException::class)
fun construct(type: TowerType?, commander: Agent) {
fun construct(type: TowerType, commander: Agent) {
if (!commander.isCommander) {
commander.kill()
throw CouldNotPerformException("Only the commander can construct a tower!")
Expand Down Expand Up @@ -114,20 +126,20 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
isConstructed = false
}

fun seeTower(agent: Agent): Boolean {
override fun seeTower(agent: Agent): Boolean {
if (!isConstructed) {
return false
}

return bounds.intersects(agent.bounds)
}

fun orderFuel(fuel: Int, agent: Agent?): Int {
override fun orderFuel(fuel: Int, agent: Agent?): Int {
var fuel = fuel
if (agent == null || bounds.contains(agent.bounds)) {
try {
val oldFuel = this.fuel
if (fuel <= 0) { // fuel emty
if (fuel <= 0) { // fuel empty
fuel = 0
} else if (this.fuel < fuel) { // use last fuel
fuel = this.fuel
Expand All @@ -148,7 +160,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
return fuel
}

fun hasFuel(): Boolean {
override fun hasFuel(): Boolean {
return fuel > 0
}

Expand All @@ -162,7 +174,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
}

@Synchronized
fun attack() {
override fun attack() {
logger.debug("Attack Mothership")
if (shieldForce > 0) {
shieldForce--
Expand All @@ -177,7 +189,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
}

@Synchronized
fun repair() {
override fun repair() {
if (shieldForce < 100) {
shieldForce++
if (shieldForce > Mothership.Companion.BURNING_TOWER && timer.isRunning) {
Expand All @@ -187,16 +199,24 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
}
}

val isBurning: Boolean
override fun scanLevelSize() {
if (!isConstructed) {
return
}
levelSize = level.size
changes.firePropertyChange(TOWER_SCAN_LEVEL, null, null)
}

override val isBurning: Boolean
get() = shieldForce < Mothership.BURNING_TOWER && hasFuel()

val shieldPoints: Int
override val shieldPoints: Int
get() = shieldForce / 2

val isMaxDamaged: Boolean
override val isMaxDamaged: Boolean
get() = shieldForce == 0

val isDamaged: Boolean
override val isDamaged: Boolean
get() = shieldForce < 100

override fun actionPerformed(ex: ActionEvent) {
Expand All @@ -210,6 +230,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
const val TOWER_FUEL_VOLUME: Int = 500
const val TOWER_FUEL_STATE_CHANGE: String = "FuelStateChange"
const val TOWER_SHIELD_STATE_CHANGE: String = "ShieldStateChange"
const val TOWER_SCAN_LEVEL: String = "ScanLevel"
const val TOWER_CONSTRUCT: String = "construct tower"
const val TOWER_DECONSTRUCT: String = "deconstruct tower"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.openbase.planetsudo.level.levelobjects

import org.openbase.planetsudo.level.LevelSize

/*-
* #%L
* PlanetSudo GameEngine
* %%
* Copyright (C) 2009 - 2024 openbase.org
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
/**
*
* @author Divine Threepwood
*/
interface TowerInterface {

val de get() = TowerInterfaceGermanWrapper(this)

/**
* Checks whether the given agent can see the tower.
*/
fun seeTower(agent: Agent): Boolean

/**
* Orders fuel from the tower. Returns the amount actually provided.
*/
fun orderFuel(fuel: Int, agent: Agent?): Int

/**
* Returns whether the tower has any fuel left.
*/
fun hasFuel(): Boolean

/**
* Current fuel amount of the tower.
*/
val fuel: Int

/**
* Maximum fuel capacity of the tower.
*/
val fuelVolume: Int

/**
* Current fuel level as percentage.
*/
val fuelInPercent: Int

/**
* Makes the tower perform an attack.
*/
fun attack()

/**
* Repairs the tower (increases shield strength).
*/
fun repair()

/**
* Returns whether the tower is burning (losing fuel).
*/
val isBurning: Boolean

/**
* Shield points of the tower.
*/
val shieldPoints: Int

/**
* Returns whether the tower is completely destroyed (no shield left).
*/
val isMaxDamaged: Boolean

/**
* Returns whether the tower is damaged (shield not full).
*/
val isDamaged: Boolean

/**
* Current tower type (DefenceTower or ObservationTower). Unknown if no tower is constructed.
*/
val type: Tower.TowerType

/**
* Scans and updates the currently detected level size.
*/
fun scanLevelSize()

/**
* The last scanned level size.
*/
val levelSize: LevelSize
}
Loading