diff --git a/engine/engine_util.go b/engine/engine_util.go index 03371a3..bf1ddad 100644 --- a/engine/engine_util.go +++ b/engine/engine_util.go @@ -62,6 +62,32 @@ func (p Position) WithOffset(xOffset int, yOffset int) Position { return p } +func (p Position) Diff(other Position) Position { + p.x = p.x - other.x + p.y = p.y - other.y + + return p +} + +func (p Position) Sign() Position { + p.x = IntSign(p.x) + p.y = IntSign(p.y) + + return p +} + +func IntSign(i int) int { + if i < 0 { + return -1 + } + + if i > 0 { + return 1 + } + + return 0 +} + type Sized struct { size Size } diff --git a/game/model/entity_behavior.go b/game/model/entity_behavior.go index e402013..69bb85b 100644 --- a/game/model/entity_behavior.go +++ b/game/model/entity_behavior.go @@ -5,7 +5,7 @@ import ( "mvvasilev/last_light/engine" ) -type ProjectileSprite rune +type ArrowSprite rune // // \ | / @@ -15,10 +15,10 @@ type ProjectileSprite rune // / | \ const ( - ProjectileSprite_NorthSouth ProjectileSprite = '|' - ProjectileSprite_EastWest = '─' - ProjectileSprite_NorthEastSouthWest = '/' - ProjectileSprite_NorthWestSouthEast = '\\' + ProjectileSprite_NorthSouth ArrowSprite = '|' + ProjectileSprite_EastWest ArrowSprite = '─' + ProjectileSprite_NorthEastSouthWest ArrowSprite = '/' + ProjectileSprite_NorthWestSouthEast ArrowSprite = '\\' ) func ProjectileBehavior(eventLog *engine.GameEventLog, dungeon *Dungeon) func(npc Entity) (complete bool, requeue bool) { diff --git a/game/model/entity_npcs.go b/game/model/entity_npcs.go index 528a5ac..a0ac81f 100644 --- a/game/model/entity_npcs.go +++ b/game/model/entity_npcs.go @@ -12,11 +12,11 @@ const ( ImpClaws specialItemType = 100_000 + iota ) -func Entity_ArrowProjectile(source Entity, path *engine.Path, eventLog *engine.GameEventLog, dungeon *Dungeon) Entity { +func Entity_Projectile(name string, symbol rune, style tcell.Style, source Entity, path *engine.Path, eventLog *engine.GameEventLog, dungeon *Dungeon) Entity { return CreateEntity( - WithName("Arrow"), + WithName(name), WithPosition(path.From()), - WithPresentation('?', tcell.StyleDefault), + WithPresentation(symbol, style), WithProjectileData(source, path), WithBehavior(1, ProjectileBehavior(eventLog, dungeon)), ) diff --git a/game/state/look_state.go b/game/state/look_state.go index 6e30b9b..49ca998 100644 --- a/game/state/look_state.go +++ b/game/state/look_state.go @@ -103,10 +103,11 @@ func (ls *LookState) ShootEquippedWeapon() { // TODO: Projectiles dX, dY := ls.lookCursorCoordsToDungeonCoords() + cursorPos := engine.PositionAt(dX, dY) - distance := engine.PositionAt(dX, dY).Distance(ls.player.Position()) + distance := cursorPos.Distance(ls.player.Position()) - if distance >= 12 { + if distance > 12 { ls.eventLog.Log("Can't see in the dark that far") return @@ -122,7 +123,22 @@ func (ls *LookState) ShootEquippedWeapon() { return } - projectile := model.Entity_ArrowProjectile(ls.player, path, ls.eventLog, ls.dungeon) + 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,