Moved forced skills into creature
This commit is contained in:
parent
f496abee18
commit
2683ce69a9
@ -1,12 +1,10 @@
|
||||
package me.msoucy.ptures.controller
|
||||
|
||||
import me.msoucy.ptures.model.Creature
|
||||
import me.msoucy.ptures.model.KnockedOut
|
||||
import me.msoucy.ptures.model.Skill
|
||||
import me.msoucy.ptures.model.*
|
||||
import me.msoucy.ptures.model.Target
|
||||
import me.msoucy.ptures.model.Team
|
||||
import me.msoucy.ptures.view.BattleView
|
||||
import me.msoucy.ptures.view.SkillChoice
|
||||
import me.msoucy.ptures.view.CreatureView
|
||||
import me.msoucy.ptures.model.SkillChoice
|
||||
|
||||
sealed class BattleType(vararg val teams: Team) {
|
||||
init {
|
||||
@ -33,16 +31,19 @@ class RaidBattle(val boss: Creature, vararg teams: Team) : BattleType(*teams) {
|
||||
|
||||
class Engine(private val battle: BattleType) {
|
||||
|
||||
private var currentCreature = 0
|
||||
private lateinit var currentCreature: CreatureView
|
||||
|
||||
// List of all creatures that are involved in the battle
|
||||
private val creatures get() = battle.teams.flatMap { it.activeCreatures }
|
||||
|
||||
val attacker: Creature
|
||||
// The current attacking creature
|
||||
private var attacker: CreatureView
|
||||
get() {
|
||||
return creatures[currentCreature].creature
|
||||
return currentCreature
|
||||
}
|
||||
private set(value) {
|
||||
currentCreature = value
|
||||
}
|
||||
|
||||
private val forcedSkills = mutableMapOf<Creature, Skill>()
|
||||
|
||||
private val activeCreatures
|
||||
get() = creatures
|
||||
@ -50,70 +51,54 @@ class Engine(private val battle: BattleType) {
|
||||
.sortedBy { it.creature.spd }
|
||||
|
||||
fun resolveTurn(view: BattleView) {
|
||||
forcedSkills.clear()
|
||||
|
||||
// All preconditions
|
||||
for (i in activeCreatures.indices) {
|
||||
val creature = creatures[i]
|
||||
for (creature in activeCreatures) {
|
||||
for (status in creature.creature.statuses) {
|
||||
status.onTurnStart(this, creature.creature)
|
||||
status.onTurnStart(creature.creature)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the moves each creature will use this turn
|
||||
val moves = activeCreatures.indices.map { i ->
|
||||
val forcedSkill = forcedSkills[creatures[i].creature]
|
||||
if (forcedSkill != null) {
|
||||
SkillChoice(forcedSkill, creatures[nextOpponent(i)].creature)
|
||||
} else {
|
||||
creatures[i].chooseSkill(activeCreatures.map { it.creature })
|
||||
}
|
||||
activeCreatures.forEach {
|
||||
it.chooseSkill(activeCreatures.map { c -> c.creature })
|
||||
}
|
||||
|
||||
// Resolve each move
|
||||
for (i in activeCreatures.indices) {
|
||||
for (c in activeCreatures) {
|
||||
// Resolve move
|
||||
val (skill, target) = moves[i]
|
||||
currentCreature = i
|
||||
val (skill, targets) = c.creature.activeSkill!!
|
||||
currentCreature = c
|
||||
val attackingCreature = currentCreature
|
||||
for (step in skill.damageSteps) {
|
||||
for (targetCreature in getTargetList(step.target, target)) {
|
||||
if (attacker.hits(targetCreature, step)) {
|
||||
targetCreature.apply(step, attacker)
|
||||
for (targetCreature in targets) {
|
||||
if (attackingCreature.creature.hits(targetCreature, step)) {
|
||||
targetCreature.apply(step, attackingCreature.creature)
|
||||
step.applyStatus(targetCreature)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (step in skill.postSteps) {
|
||||
for (targetCreature in getTargetList(step.target, target)) {
|
||||
for (targetCreature in targets) {
|
||||
step.apply(targetCreature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All post conditions
|
||||
for (creatureView in activeCreatures) {
|
||||
val creature = creatureView.creature
|
||||
for (status in creature.statuses) {
|
||||
status.onTurnEnd(this)
|
||||
status.onTurnEnd(creature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTargetList(target: Target, selected: Creature): List<Creature> {
|
||||
return when (target) {
|
||||
Target.Self -> listOf(attacker)
|
||||
private fun getTargetList(target: Target, selected: Creature): List<Creature> = when (target) {
|
||||
Target.Self -> listOf(attacker.creature)
|
||||
Target.Selected -> listOf(selected)
|
||||
Target.Others -> creatures.filter { it.creature != attacker }.map { it.creature }
|
||||
Target.Opponents -> creatures.filter { it.playerId != creatures[currentCreature].playerId }.map { it.creature }
|
||||
Target.Others -> creatures.filter { it.creature != attacker.creature }.map { it.creature }
|
||||
Target.Opponents -> creatures.filter { it.playerId != attacker.playerId }.map { it.creature }
|
||||
Target.All -> creatures.map { it.creature }
|
||||
}
|
||||
}
|
||||
|
||||
private fun nextOpponent(idx: Int): Int {
|
||||
var nextIdx = idx + 1
|
||||
while (nextIdx != idx) {
|
||||
if (creatures[nextIdx].playerId != creatures[idx].playerId) {
|
||||
return nextIdx
|
||||
}
|
||||
nextIdx = (nextIdx + 1) % creatures.size
|
||||
}
|
||||
// There are no opponents... so use the "none" index
|
||||
return -1
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ class Creature {
|
||||
val skills = mutableListOf<Skill>()
|
||||
val statuses = mutableListOf<Status>()
|
||||
|
||||
var activeSkill : SkillChoice? = null
|
||||
|
||||
val atk : Int get() = statFormula(genes.atk, growth.atk)
|
||||
val def : Int get() = statFormula(genes.def, growth.def)
|
||||
val spd : Int get() = statFormula(genes.spd, growth.spd)
|
||||
|
@ -2,6 +2,8 @@ package me.msoucy.ptures.model
|
||||
|
||||
import com.badlogic.gdx.math.MathUtils.random
|
||||
|
||||
data class SkillChoice (val skill : Skill, val target : List<Creature>)
|
||||
|
||||
@DslMarker
|
||||
annotation class SkillMarker
|
||||
|
||||
@ -105,6 +107,9 @@ object Skills {
|
||||
val Fly = skill("Fly") {
|
||||
addStatus(Flying(), Target.Self)
|
||||
}
|
||||
val Fly2 = skill("Fly", Attribute.Air) {
|
||||
damage(60)
|
||||
}
|
||||
|
||||
val Ember = skill("Ember", Attribute.Fire) {
|
||||
damage(40) {
|
||||
|
@ -4,48 +4,49 @@ import me.msoucy.ptures.controller.Engine
|
||||
|
||||
sealed class Status {
|
||||
|
||||
open fun onTurnStart(engine : Engine, creature : Creature) {
|
||||
open fun onTurnStart(creature: Creature) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
open fun onAdd(creature : Creature) {
|
||||
open fun onAdd(creature: Creature) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
open fun onTurnEnd(engine : Engine) {
|
||||
open fun onTurnEnd(creature: Creature) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
open fun attackMod(creature : Creature) = 1.0
|
||||
open fun defenseMod(creature : Creature) = 1.0
|
||||
open fun attackMod(creature: Creature) = 1.0
|
||||
open fun defenseMod(creature: Creature) = 1.0
|
||||
}
|
||||
|
||||
sealed class VisibleStatus(val label : String = "") : Status()
|
||||
sealed class VisibleStatus(val label: String = "") : Status()
|
||||
|
||||
sealed class CountdownStatus(private var turns : Int) : Status()
|
||||
{
|
||||
override fun onTurnEnd(engine : Engine) {
|
||||
sealed class CountdownStatus(private var turns: Int) : Status() {
|
||||
override fun onTurnEnd(creature: Creature) {
|
||||
turns--
|
||||
if(turns == 0) {
|
||||
onCountdownReached(engine)
|
||||
engine.attacker.removeStatus(this)
|
||||
if (turns == 0) {
|
||||
onCountdownReached(creature)
|
||||
creature.removeStatus(this)
|
||||
}
|
||||
}
|
||||
|
||||
open fun onCountdownReached(engine : Engine) {
|
||||
open fun onCountdownReached(creature: Creature) {
|
||||
}
|
||||
}
|
||||
|
||||
object KnockedOut : VisibleStatus("ko")
|
||||
object Burned : VisibleStatus("burned") {
|
||||
override fun onTurnEnd(engine : Engine) {
|
||||
override fun onTurnEnd(creature : Creature) {
|
||||
// Deal a small amount of damage
|
||||
}
|
||||
}
|
||||
|
||||
object Stunned : VisibleStatus("stunned")
|
||||
object Poisoned : VisibleStatus("poisoned")
|
||||
class Flying : CountdownStatus(1) {
|
||||
override fun onCountdownReached(engine: Engine) {
|
||||
super.onCountdownReached(engine)
|
||||
class Flying(private vararg val targets : Creature) : CountdownStatus(1) {
|
||||
override fun onCountdownReached(creature: Creature) {
|
||||
super.onCountdownReached(creature)
|
||||
creature.activeSkill = SkillChoice(Skills.Fly2, targets.toList())
|
||||
}
|
||||
}
|
||||
|
@ -2,50 +2,51 @@ package me.msoucy.ptures.view
|
||||
|
||||
import me.msoucy.ptures.model.Creature
|
||||
import me.msoucy.ptures.model.Skill
|
||||
import me.msoucy.ptures.model.SkillChoice
|
||||
import me.msoucy.ptures.model.VisibleStatus
|
||||
|
||||
class SkillViewText(skill : Skill) : SkillView(skill) {
|
||||
class SkillViewText(skill: Skill) : SkillView(skill) {
|
||||
override fun display() {
|
||||
println(skill.name)
|
||||
}
|
||||
|
||||
override fun displayEnumerated(idx: Int) {
|
||||
println("${idx+1}: ${skill.name}")
|
||||
println("${idx + 1}: ${skill.name}")
|
||||
}
|
||||
}
|
||||
|
||||
class CreatureViewText(playerId : Int, creature : Creature) : CreatureView(playerId, creature) {
|
||||
class CreatureViewText(playerId: Int, creature: Creature) : CreatureView(playerId, creature) {
|
||||
|
||||
private val skillViews = creature.skills.map { SkillViewText(it) }
|
||||
|
||||
private fun chooseSkillName() : Skill {
|
||||
private fun chooseSkillName(): Skill {
|
||||
println("Skills:")
|
||||
println("=======")
|
||||
skillViews.forEachIndexed { index, skillView ->
|
||||
skillView.displayEnumerated(index)
|
||||
}
|
||||
var idx = -1
|
||||
while(idx != -1) {
|
||||
while (idx != -1) {
|
||||
print("> ")
|
||||
val tmpIdx = readLine()?.toIntOrNull() ?: -1
|
||||
if (tmpIdx in creature.skills.indices)
|
||||
{
|
||||
if (tmpIdx in creature.skills.indices) {
|
||||
idx = tmpIdx
|
||||
}
|
||||
}
|
||||
return creature.skills[idx]
|
||||
}
|
||||
|
||||
private fun chooseTarget(skill : Skill, possibleTargets : List<Creature>) : Creature {
|
||||
return creature
|
||||
private fun chooseTarget(skill: Skill, possibleTargets: List<Creature>): List<Creature> {
|
||||
return possibleTargets
|
||||
}
|
||||
|
||||
override fun chooseSkill(possibleTargets : List<Creature>) : SkillChoice {
|
||||
override fun chooseSkill(possibleTargets: List<Creature>) {
|
||||
|
||||
if (creature.activeSkill == null) {
|
||||
val skill = chooseSkillName()
|
||||
val target = chooseTarget(skill, possibleTargets)
|
||||
|
||||
return SkillChoice(skill, target)
|
||||
val targets = chooseTarget(skill, possibleTargets)
|
||||
creature.activeSkill = SkillChoice(skill, targets)
|
||||
}
|
||||
}
|
||||
|
||||
override fun displayName() {
|
||||
@ -65,6 +66,6 @@ class CreatureViewText(playerId : Int, creature : Creature) : CreatureView(playe
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerViewText(playerId : Int) : PlayerView(playerId) {
|
||||
class PlayerViewText(playerId: Int) : PlayerView(playerId) {
|
||||
override fun creatureViewFor(creature: Creature) = CreatureViewText(playerId, creature)
|
||||
}
|
@ -2,8 +2,7 @@ package me.msoucy.ptures.view
|
||||
|
||||
import me.msoucy.ptures.model.Creature
|
||||
import me.msoucy.ptures.model.Skill
|
||||
|
||||
data class SkillChoice (val skill : Skill, val target : Creature)
|
||||
import me.msoucy.ptures.model.SkillChoice
|
||||
|
||||
abstract class SkillView(val skill : Skill) {
|
||||
abstract fun display()
|
||||
@ -12,7 +11,7 @@ abstract class SkillView(val skill : Skill) {
|
||||
|
||||
abstract class CreatureView(val playerId : Int, val creature: Creature) {
|
||||
|
||||
abstract fun chooseSkill(possibleTargets : List<Creature>) : SkillChoice
|
||||
abstract fun chooseSkill(possibleTargets : List<Creature>)
|
||||
|
||||
abstract fun displayName()
|
||||
abstract fun displaySkills()
|
||||
|
Loading…
Reference in New Issue
Block a user