Testing: Damage animations on damaged units

This commit is contained in:
Yair Morgenstern
2023-04-24 17:07:55 +03:00
parent 2f7fa6ba5c
commit 95ee35d301
2 changed files with 65 additions and 1 deletions

View File

@ -9,11 +9,14 @@ import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.badlogic.gdx.scenes.scene2d.actions.FloatAction import com.badlogic.gdx.scenes.scene2d.actions.FloatAction
import com.badlogic.gdx.scenes.scene2d.actions.RelativeTemporalAction import com.badlogic.gdx.scenes.scene2d.actions.RelativeTemporalAction
import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction
import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction
import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.battle.ICombatant import com.unciv.logic.battle.ICombatant
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.map.HexMath import com.unciv.logic.map.HexMath
import com.unciv.ui.components.tilegroups.TileSetStrings
import com.unciv.ui.images.ImageGetter import com.unciv.ui.images.ImageGetter
import com.unciv.ui.screens.worldscreen.WorldScreen import com.unciv.ui.screens.worldscreen.WorldScreen
@ -41,6 +44,49 @@ object BattleTableHelpers {
} }
} }
class AttackAnimationAction(
val attacker: ICombatant,
val defenderActors: List<Actor>,
val currentTileSetStrings: TileSetStrings
): SequenceAction(){
init {
if (defenderActors.any()) {
val attackAnimationLocation = getAttackAnimationLocation()
if (attackAnimationLocation != null){
var i = 1
while (ImageGetter.imageExists(attackAnimationLocation+i)){
val image = ImageGetter.getImage(attackAnimationLocation+i)
addAction(Actions.run {
defenderActors.first().parent.addActor(image)
})
addAction(Actions.delay(0.1f))
addAction(Actions.removeActor(image))
i++
}
}
}
}
private fun getAttackAnimationLocation(): String?{
if (attacker is MapUnitCombatant) {
val unitSpecificAttackAnimationLocation =
currentTileSetStrings.getString(
currentTileSetStrings.unitsLocation,
attacker.getUnitType().name,
"-attack-"
)
if (ImageGetter.imageExists(unitSpecificAttackAnimationLocation+"1")) return unitSpecificAttackAnimationLocation
}
val unitTypeAttackAnimationLocation =
currentTileSetStrings.getString(currentTileSetStrings.unitsLocation, attacker.getUnitType().name, "-attack-")
if (ImageGetter.imageExists(unitTypeAttackAnimationLocation+"1")) return unitTypeAttackAnimationLocation
return null
}
}
fun WorldScreen.battleAnimation( fun WorldScreen.battleAnimation(
attacker: ICombatant, damageToAttacker: Int, attacker: ICombatant, damageToAttacker: Int,
defender: ICombatant, damageToDefender: Int defender: ICombatant, damageToDefender: Int
@ -50,7 +96,7 @@ object BattleTableHelpers {
val tileGroup = mapHolder.tileGroups[combatant.getTile()]!! val tileGroup = mapHolder.tileGroups[combatant.getTile()]!!
if (combatant.isCity()) { if (combatant.isCity()) {
val icon = tileGroup.layerMisc.improvementIcon val icon = tileGroup.layerMisc.improvementIcon
if (icon != null) yield(icon) if (icon != null) yield (icon)
} }
else { else {
val slot = if (combatant.isCivilian()) 0 else 1 val slot = if (combatant.isCivilian()) 0 else 1
@ -76,6 +122,15 @@ object BattleTableHelpers {
MoveActorsAction(actorsToMove, attackVectorWorldCoords), MoveActorsAction(actorsToMove, attackVectorWorldCoords),
Actions.parallel( // While the unit is moving back to its normal position, we flash the damages on both units Actions.parallel( // While the unit is moving back to its normal position, we flash the damages on both units
MoveActorsAction(actorsToMove, attackVectorWorldCoords.cpy().scl(-1f)), MoveActorsAction(actorsToMove, attackVectorWorldCoords.cpy().scl(-1f)),
AttackAnimationAction(attacker,
if (damageToDefender != 0) getMapActorsForCombatant(defender).toList() else listOf(),
mapHolder.currentTileSetStrings
),
AttackAnimationAction(
defender,
if (damageToAttacker != 0) getMapActorsForCombatant(attacker).toList() else listOf(),
mapHolder.currentTileSetStrings
),
Actions.sequence( Actions.sequence(
FlashRedAction(0f,1f, actorsToFlashRed), FlashRedAction(0f,1f, actorsToFlashRed),
FlashRedAction(1f,0f, actorsToFlashRed) FlashRedAction(1f,0f, actorsToFlashRed)

View File

@ -137,3 +137,12 @@ This is used by providing multiple images per unit, each representing a coloured
| Archer-2.png | Colour layer | Nation outer colour | | Archer-2.png | Colour layer | Nation outer colour |
The [Civ Army Color Style Sheet](https://github.com/AdityaMH/Civ-Army-Color-Style-Sheet/tree/main/Images/TileSets/FantasyHex/Units) mod by @AdityaMH and the [5Hex Tileset](https://github.com/ravignir/5Hex-Tileset/tree/master/Images/TileSets/5Hex/Units) by @ravignir are very good practical examples of how this can be used. The [Civ Army Color Style Sheet](https://github.com/AdityaMH/Civ-Army-Color-Style-Sheet/tree/main/Images/TileSets/FantasyHex/Units) mod by @AdityaMH and the [5Hex Tileset](https://github.com/ravignir/5Hex-Tileset/tree/master/Images/TileSets/5Hex/Units) by @ravignir are very good practical examples of how this can be used.
## Attack animations
These are small animations that play on units when they receive damage.
They can be for unit types (Archery, Seige, Cavalry) or for specific unit names
The files should be in the format of `<unit type/unit name>-attack-<frame number>`.
For example, a 3 frame animation for Sword units would have the files `Sword-attack-1.png`, `Sword-attack-3.png`, `Sword-attack-3.png`