mirror of
https://github.com/mvvasilev/last_light.git
synced 2025-04-19 12:49:52 +03:00
Character stats menu start, key bindings menu start, add tophat item
This commit is contained in:
parent
9445958338
commit
8e6309c824
13 changed files with 289 additions and 92 deletions
|
@ -3,22 +3,9 @@ package model
|
|||
import (
|
||||
"fmt"
|
||||
"mvvasilev/last_light/engine"
|
||||
)
|
||||
"mvvasilev/last_light/game/systems"
|
||||
|
||||
type ArrowSprite rune
|
||||
|
||||
//
|
||||
// \ | /
|
||||
//
|
||||
// ─ + ─
|
||||
//
|
||||
// / | \
|
||||
|
||||
const (
|
||||
ProjectileSprite_NorthSouth ArrowSprite = '|'
|
||||
ProjectileSprite_EastWest ArrowSprite = '─'
|
||||
ProjectileSprite_NorthEastSouthWest ArrowSprite = '/'
|
||||
ProjectileSprite_NorthWestSouthEast ArrowSprite = '\\'
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
|
||||
func ProjectileBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon) func(npc Entity) (complete bool, requeue bool) {
|
||||
|
@ -76,7 +63,8 @@ func ProjectileFollowPathNext(npc Entity, eventLog *engine.GameEventLog, dungeon
|
|||
return false
|
||||
}
|
||||
|
||||
ExecuteAttack(eventLog, projectileData.Source, nextTileEntityData.Entity)
|
||||
// TODO: calculate additional projectile damage
|
||||
ExecuteAttack(eventLog, projectileData.Source, nextTileEntityData.Entity, true)
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -86,7 +74,7 @@ func ProjectileFollowPathNext(npc Entity, eventLog *engine.GameEventLog, dungeon
|
|||
return
|
||||
}
|
||||
|
||||
func HostileNPCBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon, player *Player) func(npc Entity) (complete bool, requeue bool) {
|
||||
func HostileMeleeNPCBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon, player *Player) func(npc Entity) (complete bool, requeue bool) {
|
||||
return func(npc Entity) (complete bool, requeue bool) {
|
||||
CalcPathToPlayerAndMove(25, eventLog, dungeon, npc, player)
|
||||
|
||||
|
@ -94,6 +82,16 @@ func HostileNPCBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon, player
|
|||
}
|
||||
}
|
||||
|
||||
func HostileRangedNPCBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon, player *Player) func(npc Entity) (complete bool, requeue bool) {
|
||||
return func(npc Entity) (complete bool, requeue bool) {
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
|
||||
func CalcPathToPlayerAndKeepDistance(simulationDistance int, eventLog *engine.GameEventLog, dungeon *Dungeon, npc Entity, player *Player) {
|
||||
|
||||
}
|
||||
|
||||
func CalcPathToPlayerAndMove(simulationDistance int, eventLog *engine.GameEventLog, dungeon *Dungeon, npc Entity, player *Player) {
|
||||
if npc.Positioned().Position.DistanceSquared(player.Position()) > simulationDistance*simulationDistance {
|
||||
return
|
||||
|
@ -141,7 +139,7 @@ func CalcPathToPlayerAndMove(simulationDistance int, eventLog *engine.GameEventL
|
|||
}
|
||||
|
||||
if WithinHitRange(npc.Positioned().Position, player.Position()) {
|
||||
ExecuteAttack(eventLog, npc, player)
|
||||
ExecuteAttack(eventLog, npc, player, false)
|
||||
}
|
||||
|
||||
pathToPlayer := engine.FindPath(
|
||||
|
@ -193,8 +191,8 @@ func WithinHitRange(pos engine.Position, otherPos engine.Position) bool {
|
|||
return pos.WithOffset(-1, 0) == otherPos || pos.WithOffset(+1, 0) == otherPos || pos.WithOffset(0, -1) == otherPos || pos.WithOffset(0, +1) == otherPos
|
||||
}
|
||||
|
||||
func ExecuteAttack(eventLog *engine.GameEventLog, attacker, victim Entity) {
|
||||
hit, precision, evasion, dmg, dmgType := CalculateAttack(attacker, victim)
|
||||
func ExecuteAttack(eventLog *engine.GameEventLog, attacker, victim Entity, isRanged bool) {
|
||||
hit, precision, evasion, dmg, dmgType := CalculateAttack(attacker, victim, isRanged)
|
||||
|
||||
if attacker.Projectile() != nil {
|
||||
attacker = attacker.Projectile().Source
|
||||
|
@ -232,12 +230,140 @@ func ExecuteAttack(eventLog *engine.GameEventLog, attacker, victim Entity) {
|
|||
eventLog.Log(fmt.Sprintf("%s attacked %s, and hit for %v %v damage", attackerName, victimName, dmg, DamageTypeName(dmgType)))
|
||||
}
|
||||
|
||||
func CalculateAttack(attacker, victim Entity) (hit bool, precisionRoll, evasionRoll int, damage int, damageType DamageType) {
|
||||
func CalculateAttack(attacker, victim Entity, isRanged bool) (hit bool, precisionRoll, evasionRoll int, damage int, damageType DamageType) {
|
||||
if attacker.Equipped() != nil && attacker.Equipped().Inventory.AtSlot(EquippedSlotDominantHand) != nil {
|
||||
weapon := attacker.Equipped().Inventory.AtSlot(EquippedSlotDominantHand)
|
||||
|
||||
if weapon.Damaging() != nil {
|
||||
// If the weapon is ranged, but the combat isn't, do unarmed
|
||||
if isRanged && !weapon.Damaging().IsRanged {
|
||||
return UnarmedAttack(attacker, victim)
|
||||
}
|
||||
|
||||
// Doing melee damage from ranged? Don't think so.
|
||||
if !isRanged && weapon.Damaging().IsRanged {
|
||||
return false, 0, 0, 0, DamageType_Physical_Unarmed
|
||||
}
|
||||
}
|
||||
|
||||
return PhysicalWeaponAttack(attacker, weapon, victim)
|
||||
} else {
|
||||
return UnarmedAttack(attacker, victim)
|
||||
}
|
||||
}
|
||||
|
||||
func ShootProjectile(shooter Entity, target engine.Position, eventLog *engine.GameEventLog, dungeon *Dungeon, turnSystem *systems.TurnSystem) (success bool) {
|
||||
success = false
|
||||
|
||||
logMessage := func(msg string) {
|
||||
if eventLog != nil {
|
||||
eventLog.Log(msg)
|
||||
}
|
||||
}
|
||||
|
||||
if shooter.Equipped() == nil || shooter.Positioned() == nil {
|
||||
return
|
||||
}
|
||||
|
||||
shooterName := "Unknown"
|
||||
|
||||
if shooter.Named() != nil {
|
||||
shooterName = shooter.Named().Name
|
||||
}
|
||||
|
||||
weapon := shooter.Equipped().Inventory.AtSlot(EquippedSlotDominantHand)
|
||||
|
||||
if weapon == nil {
|
||||
logMessage(fmt.Sprintf("%s wants to shoot, but doesn't have anything equipped!", shooterName))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if weapon.Damaging() == nil || !weapon.Damaging().IsRanged {
|
||||
itemName := "dominant hand"
|
||||
|
||||
if weapon.Named() != nil {
|
||||
itemName = weapon.Named().Name
|
||||
}
|
||||
|
||||
logMessage(fmt.Sprintf("%s wants to use %s for this, but can't!", shooterName, itemName))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
projectileItem := shooter.Equipped().Inventory.AtSlot(EquippedSlotOffhand)
|
||||
|
||||
if projectileItem == nil {
|
||||
logMessage(fmt.Sprintf("%s doesn't have any projectiles equipped!", shooterName))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if projectileItem.ProjectileData() == nil {
|
||||
projectileItemName := "off hand"
|
||||
|
||||
if projectileItem.Named() != nil {
|
||||
projectileItemName = projectileItem.Named().Name
|
||||
}
|
||||
|
||||
logMessage(fmt.Sprintf("%s can't use %s as ammo", shooterName, projectileItemName))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
distance := target.Distance(shooter.Positioned().Position)
|
||||
|
||||
if distance > 12 {
|
||||
// logMessage("Can't see in the dark that far")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
path := engine.LinePath(
|
||||
shooter.Positioned().Position,
|
||||
target,
|
||||
)
|
||||
|
||||
if path == nil {
|
||||
// logMessage("Can't shoot there, something is in the way")
|
||||
return
|
||||
}
|
||||
|
||||
direction := map[engine.Position]ProjectileDirection{
|
||||
engine.PositionAt(-1, -1): ProjectileDirection_NorthWestSouthEast,
|
||||
engine.PositionAt(+1, +1): ProjectileDirection_NorthWestSouthEast,
|
||||
engine.PositionAt(-1, +1): ProjectileDirection_NorthEastSouthWest,
|
||||
engine.PositionAt(+1, -1): ProjectileDirection_NorthEastSouthWest,
|
||||
engine.PositionAt(0, +1): ProjectileDirection_NorthSouth,
|
||||
engine.PositionAt(0, -1): ProjectileDirection_NorthSouth,
|
||||
engine.PositionAt(-1, 0): ProjectileDirection_EastWest,
|
||||
engine.PositionAt(+1, 0): ProjectileDirection_EastWest,
|
||||
}[shooter.Positioned().Position.Diff(target).Sign()]
|
||||
|
||||
projectile := Entity_Projectile(
|
||||
"Projectile",
|
||||
projectileItem.ProjectileData().Sprites[direction],
|
||||
tcell.StyleDefault,
|
||||
shooter,
|
||||
path,
|
||||
eventLog,
|
||||
dungeon,
|
||||
)
|
||||
|
||||
turnSystem.Schedule(
|
||||
projectile.Behavior().Speed,
|
||||
projectile.Behavior().Behavior,
|
||||
)
|
||||
|
||||
if projectileItem.Quantifiable() == nil {
|
||||
shooter.Equipped().Inventory.Equip(nil, EquippedSlotOffhand)
|
||||
} else {
|
||||
projectileItem.Quantifiable().CurrentQuantity--
|
||||
|
||||
if projectileItem.Quantifiable().CurrentQuantity <= 0 {
|
||||
shooter.Equipped().Inventory.Equip(nil, EquippedSlotOffhand)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ func CreatePlayer(x, y int, playerBaseStats map[Stat]int) *Player {
|
|||
}
|
||||
|
||||
p.Inventory().Push(Item_Bow())
|
||||
p.Inventory().Push(Item_Arrow(8))
|
||||
|
||||
p.HealthData().MaxHealth = BaseMaxHealth(p)
|
||||
p.HealthData().Health = p.HealthData().MaxHealth
|
||||
|
|
|
@ -144,3 +144,13 @@ func (i *BasicInventory) ItemAt(x, y int) (item Item) {
|
|||
|
||||
return i.contents[index]
|
||||
}
|
||||
|
||||
func (i *BasicInventory) Find(filter func(i Item) bool) Item {
|
||||
for _, c := range i.contents {
|
||||
if filter(c) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -16,9 +16,19 @@ const (
|
|||
MetaItemType_Magic_Armour
|
||||
MetaItemType_Armour
|
||||
MetaItemType_Consumable
|
||||
MetaItemType_Projectile
|
||||
MetaItemType_Potion
|
||||
)
|
||||
|
||||
type ProjectileDirection int
|
||||
|
||||
const (
|
||||
ProjectileDirection_NorthSouth ProjectileDirection = iota
|
||||
ProjectileDirection_EastWest
|
||||
ProjectileDirection_NorthEastSouthWest
|
||||
ProjectileDirection_NorthWestSouthEast
|
||||
)
|
||||
|
||||
type Item interface {
|
||||
TileIcon() rune
|
||||
Icon() string
|
||||
|
@ -33,6 +43,12 @@ type Item interface {
|
|||
Damaging() *Item_DamagingComponent
|
||||
StatModifier() *Item_StatModifierComponent
|
||||
MetaTypes() *Item_MetaTypesComponent
|
||||
ProjectileData() *Item_ProjectileComponent
|
||||
}
|
||||
|
||||
type Item_ProjectileComponent struct {
|
||||
Sprites map[ProjectileDirection]rune
|
||||
AdditionalDamageRoll func() (dmg int, dmgType DamageType)
|
||||
}
|
||||
|
||||
type Item_QuantifiableComponent struct {
|
||||
|
@ -86,6 +102,7 @@ type BaseItem struct {
|
|||
damaging *Item_DamagingComponent
|
||||
statModifier *Item_StatModifierComponent
|
||||
metaTypes *Item_MetaTypesComponent
|
||||
projectileData *Item_ProjectileComponent
|
||||
}
|
||||
|
||||
func (i *BaseItem) TileIcon() rune {
|
||||
|
@ -136,6 +153,10 @@ func (i *BaseItem) MetaTypes() *Item_MetaTypesComponent {
|
|||
return i.metaTypes
|
||||
}
|
||||
|
||||
func (i *BaseItem) ProjectileData() *Item_ProjectileComponent {
|
||||
return i.projectileData
|
||||
}
|
||||
|
||||
func createBaseItem(itemType ItemType, tileIcon rune, icon string, style tcell.Style, components ...func(*BaseItem)) *BaseItem {
|
||||
i := &BaseItem{
|
||||
itemType: itemType,
|
||||
|
@ -219,3 +240,12 @@ func item_WithMetaTypes(metaTypes []ItemMetaType) func(*BaseItem) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func item_WithProjectileData(sprites map[ProjectileDirection]rune, additionalDamageRoll func() (dmg int, dmgType DamageType)) func(*BaseItem) {
|
||||
return func(bi *BaseItem) {
|
||||
bi.projectileData = &Item_ProjectileComponent{
|
||||
Sprites: sprites,
|
||||
AdditionalDamageRoll: additionalDamageRoll,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ const (
|
|||
ItemType_SmallHealthPotion
|
||||
ItemType_HealthPotion
|
||||
ItemType_LargeHealthPotion
|
||||
ItemType_Arrow
|
||||
|
||||
// Weapons
|
||||
ItemType_Bow
|
||||
|
@ -30,6 +31,7 @@ const (
|
|||
ItemType_Quarterstaff
|
||||
|
||||
// Armour
|
||||
ItemType_TopHat
|
||||
|
||||
// Special
|
||||
)
|
||||
|
@ -353,6 +355,41 @@ func Item_Spear() Item {
|
|||
)
|
||||
}
|
||||
|
||||
func Item_Arrow(amount int) Item {
|
||||
return createBaseItem(
|
||||
ItemType_Arrow,
|
||||
'-',
|
||||
"»->",
|
||||
tcell.StyleDefault.Foreground(tcell.ColorBurlyWood),
|
||||
item_WithQuantity(amount, 32),
|
||||
item_WithName("Arrow", tcell.StyleDefault),
|
||||
item_WithProjectileData(
|
||||
map[ProjectileDirection]rune{
|
||||
ProjectileDirection_NorthSouth: '|',
|
||||
ProjectileDirection_EastWest: '─',
|
||||
ProjectileDirection_NorthEastSouthWest: '/',
|
||||
ProjectileDirection_NorthWestSouthEast: '\\',
|
||||
},
|
||||
nil,
|
||||
),
|
||||
item_WithMetaTypes([]ItemMetaType{MetaItemType_Consumable, MetaItemType_Projectile}),
|
||||
item_WithEquippable(EquippedSlotOffhand),
|
||||
)
|
||||
}
|
||||
|
||||
func Item_TopHat() Item {
|
||||
return createBaseItem(
|
||||
ItemType_TopHat,
|
||||
'■',
|
||||
"_█_",
|
||||
tcell.StyleDefault.Foreground(tcell.ColorLightYellow),
|
||||
item_WithName("Top Hat", tcell.StyleDefault),
|
||||
item_WithDescription("Smells fishy...", tcell.StyleDefault),
|
||||
item_WithMetaTypes([]ItemMetaType{MetaItemType_Physical_Armour, MetaItemType_Armour}),
|
||||
item_WithEquippable(EquippedSlotHead),
|
||||
)
|
||||
}
|
||||
|
||||
// func ItemTypeGold() ItemType {
|
||||
// return &BasicItemType{
|
||||
// id: 1,
|
||||
|
|
|
@ -102,6 +102,10 @@ func CreateDungeonLevel(width, height int, dungeonType DungeonType) (dLevel *Dun
|
|||
return Item_HealthPotion()
|
||||
})
|
||||
|
||||
genTable.Add(3, func() Item {
|
||||
return Item_Arrow(engine.RandInt(1, 5))
|
||||
})
|
||||
|
||||
itemPool := []Item{
|
||||
Item_Bow(),
|
||||
Item_Longsword(),
|
||||
|
|
26
game/state/character_stats_state.go
Normal file
26
game/state/character_stats_state.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package state
|
||||
|
||||
import (
|
||||
"mvvasilev/last_light/engine"
|
||||
"mvvasilev/last_light/game/model"
|
||||
"mvvasilev/last_light/game/systems"
|
||||
"mvvasilev/last_light/game/ui"
|
||||
)
|
||||
|
||||
type CharacterStatsState struct {
|
||||
window *ui.UIWindow
|
||||
|
||||
player *model.Player
|
||||
}
|
||||
|
||||
func (css *CharacterStatsState) InputContext() systems.InputContext {
|
||||
return systems.InputContext_Menu
|
||||
}
|
||||
|
||||
func (css *CharacterStatsState) OnTick(dt int64) GameState {
|
||||
return css
|
||||
}
|
||||
|
||||
func (css *CharacterStatsState) CollectDrawables() []engine.Drawable {
|
||||
return []engine.Drawable{}
|
||||
}
|
|
@ -60,6 +60,9 @@ func (iss *InventoryScreenState) OnTick(dt int64) (nextState GameState) {
|
|||
|
||||
if item.Usable() != nil {
|
||||
item.Usable().Use(iss.eventLog, iss.dungeon, iss.player)
|
||||
|
||||
iss.player.Inventory().ReduceQuantityAt(iss.selectedInventorySlot.X(), iss.selectedInventorySlot.Y(), 1)
|
||||
return
|
||||
}
|
||||
|
||||
if item.Equippable() != nil {
|
||||
|
@ -70,7 +73,7 @@ func (iss *InventoryScreenState) OnTick(dt int64) (nextState GameState) {
|
|||
iss.player.Inventory().Equip(item, item.Equippable().Slot)
|
||||
}
|
||||
|
||||
iss.player.Inventory().ReduceQuantityAt(iss.selectedInventorySlot.X(), iss.selectedInventorySlot.Y(), 1)
|
||||
iss.player.Inventory().Drop(iss.selectedInventorySlot.X(), iss.selectedInventorySlot.Y())
|
||||
|
||||
case systems.InputAction_DropItem:
|
||||
iss.player.Inventory().Drop(iss.selectedInventorySlot.XY())
|
||||
|
|
|
@ -79,72 +79,21 @@ func (ls *LookState) OnTick(dt int64) GameState {
|
|||
}
|
||||
|
||||
func (ls *LookState) ShootEquippedWeapon() {
|
||||
weapon := ls.player.Inventory().AtSlot(model.EquippedSlotDominantHand)
|
||||
|
||||
if weapon == nil {
|
||||
ls.eventLog.Log("You don't have anything equipped!")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if weapon.Damaging() == nil {
|
||||
ls.eventLog.Log("Item unusable")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
damaging := weapon.Damaging()
|
||||
|
||||
if !damaging.IsRanged {
|
||||
ls.eventLog.Log("Equipped weapon is not ranged!")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: Projectiles
|
||||
dX, dY := ls.lookCursorCoordsToDungeonCoords()
|
||||
cursorPos := engine.PositionAt(dX, dY)
|
||||
|
||||
distance := cursorPos.Distance(ls.player.Position())
|
||||
|
||||
if distance > 12 {
|
||||
ls.eventLog.Log("Can't see in the dark that far")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
path := engine.LinePath(
|
||||
ls.player.Position(),
|
||||
engine.PositionAt(dX, dY),
|
||||
success := model.ShootProjectile(
|
||||
ls.player,
|
||||
cursorPos,
|
||||
ls.eventLog,
|
||||
ls.dungeon,
|
||||
ls.turnSystem,
|
||||
)
|
||||
|
||||
if path == nil {
|
||||
ls.eventLog.Log("Can't shoot there, something is in the way")
|
||||
if !success {
|
||||
return
|
||||
}
|
||||
|
||||
direction := ls.player.Position().Diff(cursorPos).Sign()
|
||||
|
||||
sprites := map[engine.Position]model.ArrowSprite{
|
||||
engine.PositionAt(-1, -1): model.ProjectileSprite_NorthWestSouthEast,
|
||||
engine.PositionAt(+1, -1): model.ProjectileSprite_NorthWestSouthEast,
|
||||
engine.PositionAt(-1, +1): model.ProjectileSprite_NorthEastSouthWest,
|
||||
engine.PositionAt(+1, +1): model.ProjectileSprite_NorthEastSouthWest,
|
||||
engine.PositionAt(0, +1): model.ProjectileSprite_NorthSouth,
|
||||
engine.PositionAt(0, -1): model.ProjectileSprite_NorthSouth,
|
||||
engine.PositionAt(-1, 0): model.ProjectileSprite_EastWest,
|
||||
engine.PositionAt(+1, 0): model.ProjectileSprite_EastWest,
|
||||
}
|
||||
|
||||
sprite := sprites[direction]
|
||||
|
||||
projectile := model.Entity_Projectile("Arrow", rune(sprite), tcell.StyleDefault, ls.player, path, ls.eventLog, ls.dungeon)
|
||||
|
||||
ls.turnSystem.Schedule(
|
||||
projectile.Behavior().Speed,
|
||||
projectile.Behavior().Behavior,
|
||||
)
|
||||
|
||||
ls.player.SkipNextTurn(true)
|
||||
|
||||
ls.nextGameState = ls.prevState
|
||||
|
|
|
@ -101,13 +101,13 @@ func CreatePlayingState(turnSystem *systems.TurnSystem, inputSystem *systems.Inp
|
|||
entityTable := model.CreateEntityTable()
|
||||
|
||||
entityTable.Add(1, func(x, y int) model.Entity {
|
||||
return model.Entity_Imp(x, y, model.HostileNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
return model.Entity_Imp(x, y, model.HostileMeleeNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
})
|
||||
entityTable.Add(1, func(x, y int) model.Entity {
|
||||
return model.Entity_SkeletalKnight(x, y, model.HostileNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
return model.Entity_SkeletalKnight(x, y, model.HostileMeleeNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
})
|
||||
entityTable.Add(1, func(x, y int) model.Entity {
|
||||
return model.Entity_SkeletalWarrior(x, y, model.HostileNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
return model.Entity_SkeletalWarrior(x, y, model.HostileMeleeNPCBehavior(s.eventLog, s.dungeon, s.player))
|
||||
})
|
||||
|
||||
s.npcs = SpawnNPCs(s.dungeon, 7, entityTable)
|
||||
|
@ -171,7 +171,7 @@ func (ps *PlayingState) MovePlayer(direction model.Direction) (success bool) {
|
|||
return false
|
||||
}
|
||||
|
||||
model.ExecuteAttack(ps.eventLog, ps.player, ent)
|
||||
model.ExecuteAttack(ps.eventLog, ps.player, ent, false)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
1
game/ui/menu/menu_character_stats.go
Normal file
1
game/ui/menu/menu_character_stats.go
Normal file
|
@ -0,0 +1 @@
|
|||
package menu
|
1
game/ui/menu/menu_key_bindings.go
Normal file
1
game/ui/menu/menu_key_bindings.go
Normal file
|
@ -0,0 +1 @@
|
|||
package menu
|
|
@ -148,6 +148,15 @@ func drawEquipmentSlot(screenX, screenY int, item model.Item, highlighted bool,
|
|||
style = highlightStyle
|
||||
}
|
||||
|
||||
if item.Quantifiable() != nil {
|
||||
ui.CreateSingleLineUILabel(
|
||||
screenX,
|
||||
screenY,
|
||||
fmt.Sprintf("%03d", item.Quantifiable().CurrentQuantity),
|
||||
style,
|
||||
).Draw(v)
|
||||
}
|
||||
|
||||
ui.CreateSingleLineUILabel(
|
||||
screenX,
|
||||
screenY+1,
|
||||
|
|
Loading…
Add table
Reference in a new issue