Skip to content

Commit 31d36b5

Browse files
author
adam-arold
committed
Add equipment handling
1 parent b625207 commit 31d36b5

19 files changed

Lines changed: 501 additions & 26 deletions

src/main/kotlin/org/hexworks/cavesofzircon/GameConfig.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ object GameConfig {
2727
const val BATS_PER_LEVEL = 10
2828
const val ZIRCONS_PER_LEVEL = 20
2929
const val MAXIMUM_FUNGUS_SPREAD = 20
30+
const val WEAPONS_PER_LEVEL = 3
31+
const val ARMOR_PER_LEVEL = 3
3032

3133
fun buildAppConfig() = AppConfigs.newConfig()
3234
.enableBetaFeatures()

src/main/kotlin/org/hexworks/cavesofzircon/attributes/CombatStats.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ data class CombatStats(val maxHpProperty: Property<Int>,
4040

4141
addComponent(Components.textBox()
4242
.withContentWidth(width)
43-
.addHeader("Combat Stats"))
43+
.addHeader("Combat Stats", false))
4444
addComponent(hpLabel)
4545
addComponent(attackLabel)
4646
addComponent(defenseLabel)

src/main/kotlin/org/hexworks/cavesofzircon/attributes/EnergyLevel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class EnergyLevel(initialEnergy: Int,
1717
private val currentValueProperty = createPropertyFrom(initialEnergy)
1818

1919
override fun toComponent(width: Int) = Components.vbox()
20-
.withSize(width, 5)
20+
.withSize(width, 2)
2121
.build().apply {
2222
val hungerLabel = Components.label()
2323
.withSize(width, 1)
@@ -28,7 +28,7 @@ class EnergyLevel(initialEnergy: Int,
2828

2929
addComponent(Components.textBox()
3030
.withContentWidth(width)
31-
.addHeader("Hunger"))
31+
.addHeader("Hunger", false))
3232
addComponent(hungerLabel)
3333

3434
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package org.hexworks.cavesofzircon.attributes
2+
3+
import org.hexworks.cavesofzircon.attributes.types.Armor
4+
import org.hexworks.cavesofzircon.attributes.types.Weapon
5+
import org.hexworks.cavesofzircon.attributes.types.attackValue
6+
import org.hexworks.cavesofzircon.attributes.types.defenseValue
7+
import org.hexworks.cavesofzircon.attributes.types.iconTile
8+
import org.hexworks.cavesofzircon.extensions.GameCombatItem
9+
import org.hexworks.cavesofzircon.extensions.GameEntity
10+
import org.hexworks.cavesofzircon.extensions.whenTypeIs
11+
import org.hexworks.cobalt.databinding.api.createPropertyFrom
12+
import org.hexworks.cobalt.databinding.api.property.Property
13+
import org.hexworks.zircon.api.Components
14+
import org.hexworks.zircon.api.component.Component
15+
16+
class Equipment(initialWeapon: GameEntity<Weapon>,
17+
initialArmor: GameEntity<Armor>) : DisplayableAttribute {
18+
19+
private val weaponProperty: Property<GameEntity<Weapon>> = createPropertyFrom(initialWeapon)
20+
private val armorProperty: Property<GameEntity<Armor>> = createPropertyFrom(initialArmor)
21+
22+
val attackValue: Int
23+
get() = weaponProperty.value.attackValue + armorProperty.value.attackValue
24+
25+
val defenseValue: Int
26+
get() = weaponProperty.value.defenseValue + armorProperty.value.defenseValue
27+
28+
val armorName: String
29+
get() = armorProperty.value.name
30+
31+
val weaponName: String
32+
get() = weaponProperty.value.name
33+
34+
private val weapon: GameEntity<Weapon> by weaponProperty.asDelegate()
35+
private val armor: GameEntity<Armor> by armorProperty.asDelegate()
36+
37+
private val weaponStats: String
38+
get() = " A: ${weapon.attackValue} D: ${weapon.defenseValue}"
39+
40+
private val armorStats: String
41+
get() = " A: ${armor.attackValue} D: ${armor.defenseValue}"
42+
43+
fun equip(inventory: Inventory, combatItem: GameCombatItem): GameCombatItem {
44+
combatItem.whenTypeIs<Weapon> {
45+
return equipWeapon(inventory, it)
46+
}
47+
combatItem.whenTypeIs<Armor> {
48+
return equipArmor(inventory, it)
49+
}
50+
throw IllegalStateException("Combat item is not Weapon or Armor.")
51+
}
52+
53+
private fun equipWeapon(inventory: Inventory, newWeapon: GameEntity<Weapon>): GameCombatItem {
54+
val oldWeapon = weapon
55+
inventory.removeItem(newWeapon)
56+
inventory.addItem(oldWeapon)
57+
weaponProperty.value = newWeapon
58+
return oldWeapon
59+
}
60+
61+
private fun equipArmor(inventory: Inventory, newArmor: GameEntity<Armor>): GameCombatItem {
62+
val oldArmor = armor
63+
inventory.removeItem(newArmor)
64+
inventory.addItem(oldArmor)
65+
armorProperty.value = newArmor
66+
return oldArmor
67+
}
68+
69+
override fun toComponent(width: Int): Component {
70+
val weaponIcon = Components.icon().withIcon(weaponProperty.value.iconTile).build()
71+
val weaponNameLabel = Components.label()
72+
.withText(weaponName)
73+
.withSize(width - 2, 1)
74+
.build()
75+
val weaponStatsLabel = Components.label()
76+
.withText(weaponStats)
77+
.withSize(width - 1, 1)
78+
.build()
79+
80+
val armorIcon = Components.icon().withIcon(armorProperty.value.iconTile).build()
81+
val armorNameLabel = Components.label()
82+
.withText(armorName)
83+
.withSize(width - 2, 1)
84+
.build()
85+
val armorStatsLabel = Components.label()
86+
.withText(armorStats)
87+
.withSize(width - 1, 1)
88+
.build()
89+
90+
weaponProperty.onChange {
91+
weaponIcon.iconProperty.value = weapon.iconTile
92+
weaponNameLabel.textProperty.value = weapon.name
93+
weaponStatsLabel.textProperty.value = weaponStats
94+
}
95+
96+
armorProperty.onChange {
97+
armorIcon.iconProperty.value = armor.iconTile
98+
armorNameLabel.textProperty.value = armor.name
99+
armorStatsLabel.textProperty.value = armorStats
100+
}
101+
102+
return Components.textBox()
103+
.withContentWidth(width)
104+
.addHeader("Weapon", withNewLine = false)
105+
.addInlineComponent(weaponIcon)
106+
.addInlineComponent(weaponNameLabel)
107+
.commitInlineElements()
108+
.addInlineComponent(weaponStatsLabel)
109+
.commitInlineElements()
110+
.addNewLine()
111+
.addHeader("Armor", withNewLine = false)
112+
.addInlineComponent(armorIcon)
113+
.addInlineComponent(armorNameLabel)
114+
.commitInlineElements()
115+
.addInlineComponent(armorStatsLabel)
116+
.commitInlineElements()
117+
.build()
118+
}
119+
120+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.hexworks.cavesofzircon.attributes
2+
3+
import org.hexworks.zircon.api.Components
4+
import org.hexworks.zircon.api.component.Component
5+
6+
data class ItemCombatStats(val attackValue: Int = 0,
7+
val defenseValue: Int = 0,
8+
val combatItemType: String) : DisplayableAttribute {
9+
10+
override fun toComponent(width: Int): Component {
11+
return Components.textBox()
12+
.withContentWidth(width)
13+
.addParagraph("Type: $combatItemType", withNewLine = false)
14+
.addParagraph("Attack: $attackValue", withNewLine = false)
15+
.addParagraph("Defense: $defenseValue", withNewLine = false)
16+
.build()
17+
}
18+
19+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.hexworks.cavesofzircon.attributes.types
2+
3+
import org.hexworks.amethyst.api.entity.Entity
4+
import org.hexworks.cavesofzircon.attributes.ItemCombatStats
5+
import org.hexworks.cavesofzircon.world.GameContext
6+
7+
interface Armor : CombatItem
8+
9+
val Entity<Armor, GameContext>.attackValue: Int
10+
get() = findAttribute(ItemCombatStats::class).get().attackValue
11+
12+
val Entity<Armor, GameContext>.defenseValue: Int
13+
get() = findAttribute(ItemCombatStats::class).get().defenseValue
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package org.hexworks.cavesofzircon.attributes.types
2+
3+
interface CombatItem : Item

src/main/kotlin/org/hexworks/cavesofzircon/attributes/types/EntityTypes.kt

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.hexworks.cavesofzircon.attributes.types
33
import org.hexworks.amethyst.api.base.BaseEntityType
44

55
object Player : BaseEntityType(
6-
name = "player"), Combatant, ItemHolder, EnergyUser
6+
name = "player"), Combatant, ItemHolder, EnergyUser, EquipmentHolder
77

88
object Wall : BaseEntityType(
99
name = "wall")
@@ -29,3 +29,35 @@ object Zircon : BaseEntityType(
2929
description = "A small piece of Zircon. Its value is unfathomable."), Item
3030

3131
object FogOfWarType : BaseEntityType()
32+
33+
object Dagger : BaseEntityType(
34+
name = "Rusty Dagger",
35+
description = "A small, rusty dagger made of some metal alloy."), Weapon
36+
37+
object Sword : BaseEntityType(
38+
name = "Iron Sword",
39+
description = "A shiny sword made of iron. It is a two-hand weapon"), Weapon
40+
41+
object Staff : BaseEntityType(
42+
name = "Wooden Staff",
43+
description = "A wooden staff made of birch. It has seen some use"), Weapon
44+
45+
object LightArmor : BaseEntityType(
46+
name = "Leather Tunic",
47+
description = "A tunic made of rugged leather. It is very comfortable."), Armor
48+
49+
object MediumArmor : BaseEntityType(
50+
name = "Chainmail",
51+
description = "A sturdy chainmail armor made of interlocking iron chains."), Armor
52+
53+
object HeavyArmor : BaseEntityType(
54+
name = "Platemail",
55+
description = "A heavy and shiny platemail armor made of bronze."), Armor
56+
57+
object Club : BaseEntityType(
58+
name = "Club",
59+
description = "A wooden club. It doesn't give you an edge over your opponent (haha)."), Weapon
60+
61+
object Jacket : BaseEntityType(
62+
name = "Leather jacket",
63+
description = "Dirty and rugged jacket made of leather."), Armor
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.hexworks.cavesofzircon.attributes.types
2+
3+
import org.hexworks.amethyst.api.entity.EntityType
4+
import org.hexworks.cavesofzircon.attributes.Equipment
5+
import org.hexworks.cavesofzircon.attributes.Inventory
6+
import org.hexworks.cavesofzircon.extensions.GameCombatItem
7+
import org.hexworks.cavesofzircon.extensions.GameEquipmentHolder
8+
9+
interface EquipmentHolder : EntityType
10+
11+
fun GameEquipmentHolder.equip(inventory: Inventory, item: GameCombatItem): GameCombatItem {
12+
return equipment.equip(inventory, item)
13+
}
14+
15+
val GameEquipmentHolder.equipment: Equipment
16+
get() = findAttribute(Equipment::class).get()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.hexworks.cavesofzircon.attributes.types
2+
3+
import org.hexworks.cavesofzircon.attributes.ItemCombatStats
4+
import org.hexworks.cavesofzircon.extensions.GameEntity
5+
6+
interface Weapon : CombatItem
7+
8+
val GameEntity<Weapon>.attackValue: Int
9+
get() = findAttribute(ItemCombatStats::class).get().attackValue
10+
11+
val GameEntity<Weapon>.defenseValue: Int
12+
get() = findAttribute(ItemCombatStats::class).get().defenseValue

0 commit comments

Comments
 (0)