Improve skills
This commit is contained in:
		@@ -1,14 +1,17 @@
 | 
			
		||||
package me.msoucy.ptures.model
 | 
			
		||||
 | 
			
		||||
import com.badlogic.gdx.math.MathUtils.clamp
 | 
			
		||||
import com.badlogic.gdx.math.MathUtils.random
 | 
			
		||||
 | 
			
		||||
class Stats(var atk : Int, var def : Int, var spd : Int, var hp : Int)
 | 
			
		||||
 | 
			
		||||
class Creature {
 | 
			
		||||
    var genes = Stats(5,5,5,5)
 | 
			
		||||
    var growth = Stats(5,5,5,5)
 | 
			
		||||
    val genes = Stats(5,5,5,5)
 | 
			
		||||
    val growth = Stats(5,5,5,5)
 | 
			
		||||
    val attributes = mutableMapOf<Attribute, Int>()
 | 
			
		||||
    var level = 1
 | 
			
		||||
    var currentHp = 1
 | 
			
		||||
    val skills = mutableListOf<Skill>()
 | 
			
		||||
    val statuses = mutableListOf<Status>()
 | 
			
		||||
 | 
			
		||||
    val atk : Int get() = statFormula(genes.atk, growth.atk)
 | 
			
		||||
@@ -16,8 +19,19 @@ class Creature {
 | 
			
		||||
    val spd : Int get() = statFormula(genes.atk, growth.atk)
 | 
			
		||||
    val maxHp : Int get() = statFormula(genes.atk, growth.atk)
 | 
			
		||||
 | 
			
		||||
    fun apply(dmg : Damage) {
 | 
			
		||||
        currentHp = clamp(currentHp - dmg.power, 0, maxHp)
 | 
			
		||||
    fun apply(dmg : Damage, attacker : Creature) {
 | 
			
		||||
        val critical = if (random(32) < attacker.genes.spd) { 1.5 } else { 1.0 }
 | 
			
		||||
        val randVal = random(0.85f, 1.0f)
 | 
			
		||||
        val effectiveness = 1.0
 | 
			
		||||
        val modifier = critical * randVal * effectiveness
 | 
			
		||||
        val power = (((0.4 * attacker.level) + 2) * dmg.power * (attacker.atk / def)) / 50 + 2
 | 
			
		||||
        val total : Int = (power * modifier).toInt()
 | 
			
		||||
        currentHp = clamp(currentHp - total, 0, maxHp)
 | 
			
		||||
 | 
			
		||||
        if(currentHp == 0) {
 | 
			
		||||
            statuses.clear()
 | 
			
		||||
            addStatus(KnockedOut)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addStatus(status : Status) {
 | 
			
		||||
@@ -37,5 +51,10 @@ class Creature {
 | 
			
		||||
        statuses.clear()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun hits(creature : Creature, damage : Damage) =
 | 
			
		||||
            random(100) < damage.accuracy + spd - creature.spd
 | 
			
		||||
 | 
			
		||||
    inline fun <reified S : Status> hasStatus() = statuses.filter { it is S }.isNotEmpty()
 | 
			
		||||
 | 
			
		||||
    private fun statFormula(gene : Int, growth : Int) = (2 * gene + growth) * level / 100 + 5
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
package me.msoucy.ptures.model
 | 
			
		||||
 | 
			
		||||
class Engine(vararg val creatures : Creature) {
 | 
			
		||||
class Engine(vararg val creatures : Pair<Creature, Int>) {
 | 
			
		||||
    init {
 | 
			
		||||
        assert(creatures.isNotEmpty())
 | 
			
		||||
    }
 | 
			
		||||
@@ -8,6 +8,45 @@ class Engine(vararg val creatures : Creature) {
 | 
			
		||||
    var currentCreature = 0
 | 
			
		||||
 | 
			
		||||
    val attacker : Creature get() {
 | 
			
		||||
        return creatures[currentCreature]
 | 
			
		||||
        return creatures[currentCreature].first
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun resolveTurn() {
 | 
			
		||||
        val activeCreatures = creatures.withIndex()
 | 
			
		||||
                .filter { (_, c) -> !c.first.hasStatus<KnockedOut>() }
 | 
			
		||||
                .sortedBy { (_, c) -> c.first.spd }
 | 
			
		||||
        // Get the moves each creature will use this turn
 | 
			
		||||
        val moves = activeCreatures.map { (_, c) -> Pair(c.first.skills[0], 0) }
 | 
			
		||||
        val wasHit = mutableListOf<Creature>()
 | 
			
		||||
        for ((i, c) in activeCreatures) {
 | 
			
		||||
            // Resolve move
 | 
			
		||||
            val (skill, target) = moves[i]
 | 
			
		||||
            currentCreature = i
 | 
			
		||||
            for (step in skill.damageSteps) {
 | 
			
		||||
                val targets = getTargetList(step.target, currentCreature, target)
 | 
			
		||||
                for (t in targets) {
 | 
			
		||||
                    val (targetCreature, _) = creatures[t]
 | 
			
		||||
                    if (attacker.hits(targetCreature, step)) {
 | 
			
		||||
                        targetCreature.apply(step, c.first)
 | 
			
		||||
                        wasHit.add(targetCreature)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for(creature in wasHit) {
 | 
			
		||||
                for(step in skill.statusSteps) {
 | 
			
		||||
                    step(creature)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun getTargetList(target : Target, active : Int, selected : Int) : List<Int> {
 | 
			
		||||
        return when(target) {
 | 
			
		||||
            Target.Self -> listOf(active)
 | 
			
		||||
            Target.Selected -> listOf(selected)
 | 
			
		||||
            Target.Others -> creatures.indices.filter { it != active }
 | 
			
		||||
            Target.Opponents -> creatures.indices.filter { creatures[it].second != creatures[active].second }
 | 
			
		||||
            Target.All -> creatures.indices.toList()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,13 +23,16 @@ enum class Attribute {
 | 
			
		||||
class Damage(val power : Int) {
 | 
			
		||||
    var target = Target.Selected
 | 
			
		||||
    var accuracy = 100
 | 
			
		||||
 | 
			
		||||
    infix fun hits (target : Creature) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@SkillMarker
 | 
			
		||||
class Skill(val name : String, val attribute : Attribute) {
 | 
			
		||||
    val preSteps = mutableListOf<Pair<Status, Target>>()
 | 
			
		||||
    val damageSteps = mutableListOf<Damage>()
 | 
			
		||||
    val postSteps = mutableListOf<Pair<Status, Target>>()
 | 
			
		||||
    val statusSteps = mutableListOf<(Creature) -> Unit>()
 | 
			
		||||
 | 
			
		||||
    fun damage(power : Int, block : Damage.() -> Unit = {}) {
 | 
			
		||||
        val d = Damage(power)
 | 
			
		||||
@@ -38,7 +41,11 @@ class Skill(val name : String, val attribute : Attribute) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addStatus(status : Status, target : Target = Target.Selected) {
 | 
			
		||||
        postSteps.add(Pair(status, target))
 | 
			
		||||
        statusSteps.add { c -> c.addStatus(status) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeStatus(status : Status, target : Target = Target.Selected) {
 | 
			
		||||
        statusSteps.add { c -> c.removeStatus(status) }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -48,6 +55,9 @@ fun skill(name : String, attribute : Attribute = Attribute.Neutral, block : Skil
 | 
			
		||||
    return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
val Ignore = skill("Ignore") {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
val Tackle = skill("Tackle") {
 | 
			
		||||
    damage(20)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,16 @@ package me.msoucy.ptures.model
 | 
			
		||||
 | 
			
		||||
sealed class Status {
 | 
			
		||||
 | 
			
		||||
    open fun onTurnStart(engine : Engine) {
 | 
			
		||||
        // Do nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open fun onAdd(creature : Creature) {
 | 
			
		||||
        // Do nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    open fun onTurnEnd(engine : Engine) {
 | 
			
		||||
        // Do nothing by default
 | 
			
		||||
        // Do nothing
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user