Skip to content

Commit

Permalink
[Close #20] Dead entities can not act
Browse files Browse the repository at this point in the history
  • Loading branch information
Orchaldir committed Apr 22, 2020
1 parent fea2a81 commit a3e3227
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 7 deletions.
4 changes: 3 additions & 1 deletion src/main/kotlin/app/demo/MeleeCombatDemo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import game.map.GameMapBuilder
import game.map.Terrain
import game.reducer.action.*
import game.reducer.event.ON_DAMAGE_REDUCER
import game.reducer.event.ON_DEATH_REDUCER
import game.rpg.Damage
import game.rpg.character.Defense
import game.rpg.character.ability.DamageEffect
Expand Down Expand Up @@ -95,7 +96,7 @@ class MeleeCombatDemo : TileApplication(60, 45, 20, 20) {
buildEntity()
add(SimpleBody(gameMap.size.getIndex(15, 10)) as Body)
add(Combat(listOf(meleeAttack), defense))
add(Player as Controller)
add(AI as Controller)
add(Graphic(UnicodeTile("O", Color.GREEN)))
add(Health())
add(Statistics(mapOf(fighting to 6, speed to 6, toughness to 8)))
Expand All @@ -110,6 +111,7 @@ class MeleeCombatDemo : TileApplication(60, 45, 20, 20) {
is Init -> INIT_REDUCER(state, action)
is Move -> MOVE_REDUCER(state, action)
is OnDamage -> ON_DAMAGE_REDUCER(state, action)
is OnDeath -> ON_DEATH_REDUCER(state, action)
is UseAbility -> USE_ABILITY_REDUCER(state, action)
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/game/action/Action.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ data class Move(val entity: Int, val direction: Direction) : Action()
data class UseAbility(val entity: Int, val ability: Int, val position: Int) : Action()

// events
data class OnDamage(val entity: Int, val damage: Damage) : Action()
data class OnDamage(val entity: Int, val damage: Damage) : Action()
data class OnDeath(val entity: Int) : Action()
16 changes: 12 additions & 4 deletions src/main/kotlin/game/reducer/event/OnDamageReducer.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package game.reducer.event

import game.action.Action
import game.action.OnDamage
import game.action.OnDeath
import game.component.Health
import game.component.HealthState
import game.component.HealthState.DEAD
import game.component.Statistics
import game.rpg.character.skill.SkillUsage
import game.rpg.check.*
Expand All @@ -19,13 +21,14 @@ import util.redux.random.RandomNumberState

private val logger = KotlinLogging.logger {}

val ON_DAMAGE_REDUCER: Reducer<OnDamage, EcsState> = a@{ state, action ->
val ON_DAMAGE_REDUCER: Reducer<Action, EcsState> = a@{ state, action ->
if (action !is OnDamage) throw IllegalArgumentException("Action must be OnDamage!")
val id = action.entity

val healthStorage = state.getStorage<Health>()
val health = healthStorage.getOrThrow(id)

if (health.state == HealthState.DEAD) {
if (health.state == DEAD) {
return@a noFollowUps(addMessage(state, Message("Entity $id is already dead!", Color.YELLOW)))
}

Expand All @@ -44,21 +47,26 @@ val ON_DAMAGE_REDUCER: Reducer<OnDamage, EcsState> = a@{ state, action ->

val updatedStorage = mutableListOf<ComponentStorage<*>>()
val updatedData = mutableListOf<Any>(rng.createState())
val events = mutableListOf<Action>()

val newHealth = updateHealth(health, result)

if (health != newHealth) {
logger.info("Change to $newHealth")
updatedStorage += healthStorage.updateAndRemove(mapOf(id to newHealth))

if (newHealth.state == DEAD) {
events.add(OnDeath(id))
}

updateMessageLog(state, health, newHealth, id, updatedData)
} else {
val messageLog = state.getData<MessageLog>()
val message = Message("Entity $id suffers no damage", Color.WHITE)
updatedData += messageLog.add(message)
}

noFollowUps(state.copy(updatedStorage, updatedData))
Pair(state.copy(updatedStorage, updatedData), events)
}

private fun updateMessageLog(
Expand Down
23 changes: 23 additions & 0 deletions src/main/kotlin/game/reducer/event/OnDeathReducer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package game.reducer.event

import game.action.OnDeath
import game.component.Controller
import game.rpg.time.TimeSystem
import mu.KotlinLogging
import util.ecs.EcsState
import util.redux.Reducer
import util.redux.noFollowUps

private val logger = KotlinLogging.logger {}

val ON_DEATH_REDUCER: Reducer<OnDeath, EcsState> = a@{ state, action ->
val storage = state.getStorage<Controller>()
val newStorage = storage.updateAndRemove(removed = setOf(action.entity))

val system = state.getData<TimeSystem>()
val newSystem = system.remove(action.entity)

logger.info("Entity ${action.entity} died. storage={} time={}", newStorage, newSystem)
noFollowUps(state.copy(listOf(newStorage), listOf(newSystem)))
}

2 changes: 1 addition & 1 deletion src/main/kotlin/util/ecs/storage/ComponentStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ interface ComponentStorage<T> {
fun getList(vararg entities: Int): List<T>
fun getAll(): Collection<T>
fun getIds(): Set<Int>
fun updateAndRemove(updated: Map<Int, T>, removed: Set<Int> = emptySet()): ComponentStorage<T>
fun updateAndRemove(updated: Map<Int, T> = emptyMap(), removed: Set<Int> = emptySet()): ComponentStorage<T>
}

0 comments on commit a3e3227

Please sign in to comment.