Skip to content
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
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,6 @@ class Agent(

override fun seeMarker(): Boolean = mothership.teamMarker.seeMarker(this)

@Suppress("OVERRIDE_DEPRECATION")
override fun seeTower(): Boolean = mothership.tower.seeTower(this)

@Suppress("OVERRIDE_DEPRECATION")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ interface AgentLegacyInterface : AgentSpecialInterface<AgentSpecialInterfaceGerm
*
* @return true oder false
*/
@Deprecated("NOT YET SUPPORTED")
fun seeTower(): Boolean

/**
* Überprüft, ob dieser Agent einen Turm aufbauen könnte.
* Bedenke das nur Commander einen Turm trägt!
* @return
*/
@Deprecated("NOT YET SUPPORTED")
val hasTower: Boolean

/**
Expand All @@ -30,14 +28,12 @@ interface AgentLegacyInterface : AgentSpecialInterface<AgentSpecialInterfaceGerm
*
* @param type Hier rüber kannst du den Turmtypen auswählen welcher errichtet werden soll.
*/
@Deprecated("NOT YET SUPPORTED")
fun constructTower(type: Tower.TowerType)

/**
* Baut einen Turm wieder ab der zuvor aufgestellt wurde.
* Diese Aktion kann nur vom Commander durchgeführt werden, und zwar nur dann, wenn er in unmittelbarer Nähe des Turms ist.
*/
@Deprecated("NOT YET SUPPORTED")
fun deconstructTower()

/**
Expand Down
49 changes: 35 additions & 14 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 @@ -127,7 +139,7 @@ class Tower(id: Int, level: AbstractLevel, @JvmField val mothership: Mothership)
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 || levelSize != LevelSize.UNKNOWN) {
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,98 @@
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)

/**
* 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