Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
88ce18f
feat: enemies are capitalized
caspersg Jan 4, 2025
b33baf8
feat: add targeting and enemy uses view_distance
caspersg Jan 4, 2025
c75cc42
feat: lighter highlighting
caspersg Jan 4, 2025
c6d20cb
fix: nil attribute error
caspersg Jan 4, 2025
086dee6
fix: enemies moving onto player
caspersg Jan 4, 2025
ceff88c
chore: remove debug
caspersg Jan 4, 2025
c58be95
refactor: choose_move moved to Decision, enemies and friends have sam…
caspersg Jan 4, 2025
8a0e817
feat: enemies pickup items if they're in the way
caspersg Jan 4, 2025
7d681f8
feat: enemies pickup all close by items and wear them
caspersg Jan 4, 2025
a730326
feat: show weapon's damage too
caspersg Jan 4, 2025
4df79af
feat: attack player and nearby enemies
caspersg Jan 4, 2025
01dda10
refactor: generalize choose_action
caspersg Jan 5, 2025
fc84756
feat: bigger message window
caspersg Jan 5, 2025
94554bd
feat: enemies can kick, and they don't pickup corpses
caspersg Jan 5, 2025
6d112b0
feat: tweak combat attributes so player can actually hit enemies
caspersg Jan 5, 2025
bac9d66
feat: show enemy slots on yank
caspersg Jan 5, 2025
80bcdfb
feat: enemies can cast spells
caspersg Jan 5, 2025
9ab6a66
fix: health spells, and remove non-attributes from Movement
caspersg Jan 5, 2025
172d0f2
feat: add turn message
caspersg Jan 5, 2025
e71d1b5
feat: add rename and drop actions to npcs, refactor decisions
caspersg Jan 5, 2025
988862b
feat: add weighted choice for actions
caspersg Jan 5, 2025
5ce7361
fix: enemies drop bug which made the enemy disappear
caspersg Jan 5, 2025
85150bc
fix: spells now check for attribute not defined
caspersg Jan 5, 2025
6c4280f
fix: nil entity
caspersg Jan 5, 2025
92ac64e
docs: log crash bug
caspersg Jan 5, 2025
8bbd1a3
fix: handle nil attributes in inspect
caspersg Jan 6, 2025
a1d947a
feat: tweak decisions
caspersg Jan 6, 2025
5569b28
feat: tweak dodge
caspersg Jan 6, 2025
a02a9ec
feat: handle player being kicked
caspersg Jan 6, 2025
0fee3c6
docs: add todos
caspersg Jan 6, 2025
8f61936
chore: add back targeting debug
caspersg Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,23 @@ Actions
- [ ] slippery floor?
- [ ] entity component system
- [ ] refactor
- [ ] extract all features into components
- [ ] all player actions can be performed by entities
- [ ] ai for entities to choose action
- [ ] control player movement with a spell
- [x] extract all features into components
- [x] all player actions can be performed by entities
- [ ] enemy sneak makes them not visible
- [ ] use the same move logic for everything
- [x] ai for entities to choose action
- [x] choose target
- [x] choose other actions
- [x] kick player
- [ ] control player movement with a spell
- [x] enemies have inventory
- [x] player and enemies drop inventory the same way
- [ ] enemies have view_distance
- [ ] target for enemies and friends
- [ ] enemies pickup items
- [ ] enemies use weapons
- [x] enemies have view_distance
- [x] target for enemies
- [ ] target for friends
- [x] enemies pickup items
- [ ] but don't pickup everything
- [x] enemies use weapons
- [ ] npcs
- [ ] friends
- [x] enchant enemies into friends
Expand All @@ -143,13 +150,17 @@ Actions
- [ ] dot repeat
- doesn't seem possible, as game loop sets the last change
- [ ] macros
- [ ] marks not working
- [ ] undo?
- [x] varied entities
- [x] item and enemy generation from dictionary
- [x] item and enemy variations with different colours
- [ ] map generation
- [x] generate random map progressively
- [x] have some structure to generated maps
- [x] new buffer for down
- [ ] add enemies and items in a later stage
- [ ] pick a selection, not fully random
- [ ] performance
- [x] write buffer once per tick
- [x] store map as 2D array
Expand Down
6 changes: 3 additions & 3 deletions lua/neohack/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ M.actions = {

---comment
drop = function(request)
state.player.inventory:drop({ request.object })
state.player.inventory:drop(request.object)
M.tick()
end,

---comment
say = function(request)
state.player.speak:say({ request.object, request.target })
state.player.speak:say(request.object, request.target)
M.tick()
end,

Expand Down Expand Up @@ -265,7 +265,7 @@ M.prompt_wait = function()
local str = M.prompt_one_word("Wait how long?")
if str then
-- M.insert_action("wait " .. str)
M.actions.wait({ object = str })
M.actions.wait({ action = "wait", object = str })
end
end, 50)
end
Expand Down
22 changes: 16 additions & 6 deletions lua/neohack/buffer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
---

local view_buffer = require("neohack.view_buffer")
local Def = require("neohack.def")

---@class Buffer
--- @field bufnr integer
Expand Down Expand Up @@ -125,11 +126,17 @@ M.tick = function(callback)
M.write_buf(nil)
end

--- Get the entity at a specific position in a specific buffer
--- Get the entity at a specific position in a specific buffer, including player
---@param row integer
---@param col integer
---@param skip_player boolean?
---@return Entity
M.get_entity_at_pos = function(row, col)
M.get_entity_at_pos = function(row, col, skip_player)
if not skip_player then
if state.player.movement.row == row and state.player.movement.col == col then
return state.player
end
end
local bufnr = state.current_bufnr
local line = M.buffers[bufnr].cells[row]
if not line then
Expand All @@ -156,7 +163,7 @@ end
M.get_under_cursor = function()
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
col = col + 1
local entity = M.get_entity_at_pos(row, col)
local entity = M.get_entity_at_pos(row, col, true)
-- message.notify("under cursor " .. row .. " " .. col .. " " .. entity.movement.char)
return row, col, entity
end
Expand All @@ -174,9 +181,12 @@ M.set_entity_at_cell = function(row, col, entity)
if not buf then
error("no buffer")
end
-- error("set entity at " .. row .. " " .. col)
-- message.notify(vim.inspect(buf.cells[row][col]))
buf.cells[row][col] = entity
-- don't set the player char
if entity.type ~= Def.DefType.player then
-- error("set entity at " .. row .. " " .. col)
-- message.notify(vim.inspect(buf.cells[row][col]))
buf.cells[row][col] = entity
end
end

--- Insert an entity at a specific position in a specific buffer
Expand Down
1 change: 1 addition & 0 deletions lua/neohack/components/attributes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
---@field hit_highlight string
---Decision
---@field randomness number
---@field target Entity?
---Eat
---@field eat_attribute number
---Fuse
Expand Down
38 changes: 26 additions & 12 deletions lua/neohack/components/combat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ function Combat.new(parent, damage, durability, hit_rate, default_weapon)
--other
default_weapon = default_weapon,
}
--attributes
parent.attributes.dodge_attribute = 0.5
--as an attacker attributes
--TODO: generate these for enemies
parent.attributes.dodge_attribute = 0.1
parent.attributes.deflect_attribute = 0.01
parent.attributes.weapon_attribute = 0.5
parent.attributes.weapon_attribute = 0.1
--as a weapon attribute
parent.attributes.hit_rate = hit_rate
parent.attributes.damage = damage
parent.attributes.durability = durability
parent.attributes.hit_rate = hit_rate

--status
parent.attributes.hit_highlight = nil

Expand All @@ -48,11 +51,13 @@ end

function Combat:inspect()
return "durability="
.. self.parent.attributes.durability
.. (self.parent.attributes.durability or "")
.. " damage="
.. self.parent.attributes.damage
.. (self.parent.attributes.damage or "")
.. " weapon_damage="
.. (self:get_weapon().attributes.damage or "")
.. " hit_rate="
.. self.parent.attributes.hit_rate
.. (self.parent.attributes.hit_rate or "")
.. " dodge_skill="
.. self:dodge_skill()
.. " weapon_skill="
Expand Down Expand Up @@ -87,14 +92,14 @@ end
---@return number
function Combat:dodge_skill()
return self.parent.attributes.dodge_attribute
+ self.parent.inventory:wear_effect(state.slot_types.feet, attributes.randomness, 0.3)
+ self.parent.inventory:wear_effect(state.slot_types.feet, attributes.hit_rate, 0.2)
+ self.parent.inventory:wear_effect(state.slot_types.feet, attributes.randomness, 0.15)
+ self.parent.inventory:wear_effect(state.slot_types.feet, attributes.hit_rate, 0.15)
end

function Combat:deflect_skill()
return self.parent.attributes.deflect_attribute
+ self.parent.inventory:wear_effect(state.slot_types.body, attributes.durability, 0.4)
+ self.parent.inventory:wear_effect(state.slot_types.left_hand, attributes.durability, 0.3)
+ self.parent.inventory:wear_effect(state.slot_types.body, attributes.durability, 0.08)
+ self.parent.inventory:wear_effect(state.slot_types.left_hand, attributes.durability, 0.05)
end

function Combat:weapon_skill()
Expand Down Expand Up @@ -207,10 +212,19 @@ function Combat:apply_damage(damage, target, weapon)
end
end

---comment
---@return Entity
function Combat:get_weapon()
return self.parent.inventory:get_weapon() or self.default_weapon()
end

---comment
---@param target Combat
---@return boolean if damage was dealth
function Combat:attack(target)
local weapon = self.parent.inventory:get_weapon() or self.default_weapon()
--the target will target the attacker
target.parent.attributes.target = self.parent
local weapon = self:get_weapon()

local damage, dealt = self:try_damage_dealt(target, weapon)
if not dealt then
Expand Down
Loading