From 4e3a9c236ec0fe4deae14301470a2bca4c22d568 Mon Sep 17 00:00:00 2001 From: LimePotato Date: Mon, 6 Nov 2023 03:36:10 -0700 Subject: [PATCH] The Creature SPREADS --- .../potrogue/builders/EntityFactory.kt | 15 +++++-- .../ouroboros/potrogue/data/config/Config.kt | 9 +++- .../entity/attributes/CreatureSpread.kt | 9 ++++ .../potrogue/entity/systems/CreatureGrowth.kt | 42 +++++++++++++++++++ 4 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/group/ouroboros/potrogue/entity/attributes/CreatureSpread.kt create mode 100644 src/main/kotlin/group/ouroboros/potrogue/entity/systems/CreatureGrowth.kt diff --git a/src/main/kotlin/group/ouroboros/potrogue/builders/EntityFactory.kt b/src/main/kotlin/group/ouroboros/potrogue/builders/EntityFactory.kt index ce595e8..2c43482 100644 --- a/src/main/kotlin/group/ouroboros/potrogue/builders/EntityFactory.kt +++ b/src/main/kotlin/group/ouroboros/potrogue/builders/EntityFactory.kt @@ -1,5 +1,6 @@ package group.ouroboros.potrogue.builders +import group.ouroboros.potrogue.entity.attributes.CreatureSpread import group.ouroboros.potrogue.entity.attributes.EntityActions import group.ouroboros.potrogue.entity.attributes.EntityPosition import group.ouroboros.potrogue.entity.attributes.EntityTile @@ -47,11 +48,17 @@ object EntityFactory { facets(Movable, CameraMover) } - fun newCreature() = newGameEntityOfType(Creature) { - attributes(BlockOccupier, + // We added the creatureSpread as a parameter to newCreature and it also has a default value. + // This enables us to call it with a CreatureSpread object when The Creature grows and use the default when we create the first one in the builder + fun newCreature(creatureSpread: CreatureSpread = CreatureSpread()) = newGameEntityOfType(Creature) { + attributes( + BlockOccupier, EntityPosition(), - EntityTile(GameTileRepository.CREATURE)) + EntityTile(GameTileRepository.CREATURE), + // We pass the creatureSPread parameter to our builder so it will use whatever we supplied instead of creating one by hand + creatureSpread + ) facets(Attackable) - behaviors() + behaviors(CreatureGrowth) } } \ No newline at end of file diff --git a/src/main/kotlin/group/ouroboros/potrogue/data/config/Config.kt b/src/main/kotlin/group/ouroboros/potrogue/data/config/Config.kt index 9e661ec..a787423 100644 --- a/src/main/kotlin/group/ouroboros/potrogue/data/config/Config.kt +++ b/src/main/kotlin/group/ouroboros/potrogue/data/config/Config.kt @@ -24,7 +24,8 @@ class Config { else{ Files.createDirectories(Paths.get("./run")) Files.createDirectories(Paths.get("./run/tiles")) - Files.createDirectories(Paths.get("./run/data")) + //TODO: DataPacks and Advanced configuration system (see values.conf in jar) + //Files.createDirectories(Paths.get("./run/data")) Files.createFile(Path.of("./run/potrogue.conf")) FileInputStream(file).use { prop.load(it) @@ -35,6 +36,7 @@ class Config { prop.setProperty("logAreaHeight", "12") prop.setProperty("helpTipHeight", "3") prop.setProperty("creaturesPerLevel", "15") + prop.setProperty("creatureMaxSpread", "20") } val out: OutputStream = FileOutputStream(file) prop.store(out, "PotRogue Configuration File, restart game if changed value. HERE BE DRAGONS.") @@ -53,5 +55,8 @@ class Config { val logAreaHeight: Int = (prop.getProperty("logAreaHeight")).toInt() val helpTipHeight: Int = (prop.getProperty("helpTipHeight")).toInt() - val creaturesPerLevel: Int = (prop.getProperty("creaturesPerLevel", "15")).toInt() + + val creaturesPerLevel: Int = (prop.getProperty("creaturesPerLevel")).toInt() + + val creatureMaxSpread: Int = (prop.getProperty("creatureMaxSpread")).toInt() } \ No newline at end of file diff --git a/src/main/kotlin/group/ouroboros/potrogue/entity/attributes/CreatureSpread.kt b/src/main/kotlin/group/ouroboros/potrogue/entity/attributes/CreatureSpread.kt new file mode 100644 index 0000000..a1ae661 --- /dev/null +++ b/src/main/kotlin/group/ouroboros/potrogue/entity/attributes/CreatureSpread.kt @@ -0,0 +1,9 @@ +package group.ouroboros.potrogue.entity.attributes + +import group.ouroboros.potrogue.data.config.Config +import org.hexworks.amethyst.api.base.BaseAttribute + +data class CreatureSpread( + var spreadCount: Int = 0, + val maximumSpread: Int = Config().creatureMaxSpread +) : BaseAttribute() diff --git a/src/main/kotlin/group/ouroboros/potrogue/entity/systems/CreatureGrowth.kt b/src/main/kotlin/group/ouroboros/potrogue/entity/systems/CreatureGrowth.kt new file mode 100644 index 0000000..8c30555 --- /dev/null +++ b/src/main/kotlin/group/ouroboros/potrogue/entity/systems/CreatureGrowth.kt @@ -0,0 +1,42 @@ +package group.ouroboros.potrogue.entity.systems + +import group.ouroboros.potrogue.builders.EntityFactory +import group.ouroboros.potrogue.entity.attributes.CreatureSpread +import group.ouroboros.potrogue.extensions.position +import group.ouroboros.potrogue.extensions.tryToFindAttribute +import group.ouroboros.potrogue.world.GameContext +import org.hexworks.amethyst.api.base.BaseBehavior +import org.hexworks.amethyst.api.entity.Entity +import org.hexworks.amethyst.api.entity.EntityType +import org.hexworks.zircon.api.data.Size3D + +// We create a Behavior and supply CreatureSpread as a mandatory Attribute to it +object CreatureGrowth : BaseBehavior(CreatureSpread::class) { + + override suspend fun update(entity: Entity, context: GameContext): Boolean { + val world = context.world + // When update is called with an entity we try to find its CreatureSpread Attribute. + // We know that it is there so we don’t have to use the findAttribute method. + val creatureSpread = entity.tryToFindAttribute(CreatureSpread::class) + // Destructuring works for CreatureSpread because it is a data class + val (spreadCount, maxSpread) = creatureSpread + // You can specify any probability here. + // It will have a direct effect on how often The Creature spreads. + // Feel free to tinker with this number but don’t be surprised if you find yourself in a creaturesplosion! + return if (spreadCount < maxSpread && Math.random() < 0.015) { + world.findEmptyLocationWithin( + offset = entity.position + .withRelativeX(-1) + .withRelativeY(-1), + size = Size3D.create(3, 3, 0) + ).map { emptyLocation -> + // Note that we pass creatureSpread as a parameter to newCreature + // so that all Creatures in the same Creature colony can share this Attribute. + // This makes sure that Creatures won’t spread all over the place and the size of a colony is controlled + world.addEntity(EntityFactory.newCreature(creatureSpread), emptyLocation) + creatureSpread.spreadCount++ + } + true + } else false + } +} \ No newline at end of file