Merge branch 'master' into dev

This commit is contained in:
Linus Probert 2018-08-03 10:41:21 +02:00
commit 2aee3600e6
27 changed files with 733 additions and 317 deletions

2
.vimrc
View File

@ -1,7 +1,7 @@
nnoremap <F1> :Make<cr>
nnoremap <F2> :Make lint test<cr>
nnoremap <F3> :Termdebug _build/breakhack<cr>
nnoremap <F4> :ter _build/breakhack<cr>
nnoremap <F4> :ter ++close ./_build/breakhack<cr>
packadd termdebug
let g:termdebug_wide = 1

View File

@ -7,7 +7,7 @@ project(breakhack C)
set(breakhack_GAME_TITLE "BreakHack")
set(breakhack_MAJOR_VERSION 0)
set(breakhack_MINOR_VERSION 1)
set(breakhack_PATCH_VERSION 6)
set(breakhack_PATCH_VERSION 7)
set(breakhack_RELEASE_TYPE "(early access)")
include(FindLua)
@ -171,6 +171,7 @@ add_executable(breakhack
src/db
src/settings
src/actiontextbuilder
src/animation
)
# Sqlite has some warnings that I we don't need to see

View File

@ -1,6 +1,7 @@
[![Build Status](https://travis-ci.org/LiquidityC/breakhack.svg?branch=master)](https://travis-ci.org/LiquidityC/breakhack)
[![Build Status](https://ci.appveyor.com/api/projects/status/2nvna97cmm4cf535?svg=true)](https://ci.appveyor.com/project/LiquidityC/breakhack)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/fc02d56fa7194e61b2c7d260fd2e4186)](https://www.codacy.com/app/LiquidityC/breakhack?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=LiquidityC/breakhack&amp;utm_campaign=Badge_Grade)
[![CodeFactor](https://www.codefactor.io/repository/github/liquidityc/breakhack/badge/master)](https://www.codefactor.io/repository/github/liquidityc/breakhack/overview/master)
<!--[![Coverity Scan](https://scan.coverity.com/projects/15218/badge.svg)](https://scan.coverity.com/projects/liquidityc-breakhack)-->
Something in the ways of NETHACK

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

View File

@ -0,0 +1,18 @@
f36a9dd Sleeping state indicator is always visible.
53dc7e2 Possibly more accurate scaling.
dff55a1 Fixes some buggs
6a9a3bd Removed some old debug output from pitlayouts.
cc229c8 Prepares pengine for more particle types.
bbe4526 Fixes colors to use defines.
2462e4c Adds sentinel monster behaviour.
a66f16d Reintroduces the pointer and mouse menu operation.
123ae90 Better mod key logic in input and mouse motion check.
821cac2 Completely separates input handling and game logic.
186cc7b Replaced state logic with behaviours instead.
b905232 ....and once again...
8573bad ...and include the SDL dll
8c58c6e And once again for windows!
6788e3c Another trywq
60114ed Hopefully fixes the build issues
e222e51 Don't test on clang and fix include problem in appveyor
138cba1 Mock test for keyboardinput and fixed the found issues

View File

@ -17,7 +17,7 @@ local function matrix_coverage (matrix)
local cov = 0
for i=1,10 do
for j=1,10 do
if matrix[i][j].active then cov = cov + 1 end
if matrix[i][j] then cov = cov + 1 end
end
end
return cov
@ -36,7 +36,7 @@ local function generate_path ()
for i=1,10 do
map_matrix[i] = {}
for j=1,10 do
map_matrix[i][j] = room_builder.create_room()
map_matrix[i][j] = nil
end
end
@ -47,7 +47,10 @@ local function generate_path ()
local direction = 0
local lastDirection = 0
local coridoor_count = 0
local coverage = 10
local coverage = 9 + CURRENT_LEVEL
-- Create the first room
map_matrix[cx][cy] = room_builder.create_empty_room()
while matrix_coverage(map_matrix) < coverage do
local direction = random(4)
@ -60,8 +63,6 @@ local function generate_path ()
direction = random(4)
end
map_matrix[cx][cy].active = true
if coridoor_count < coverage/3 then
if random(3) == 1 and (cx > 1 or cy > 1) then
map_matrix[cx][cy].type = "coridoor"
@ -69,49 +70,56 @@ local function generate_path ()
end
end
valid_direction = false
if direction == UP and cy > 1 then -- UP
table.insert(map_matrix[cx][cy].exits, direction)
room_builder.add_exit(map_matrix[cx][cy], direction)
map_matrix[cx][cy].path_dir = direction
cy = cy - 1;
table.insert(map_matrix[cx][cy].exits, reverse_direction(direction))
cy = cy - 1
valid_direction = true
elseif direction == LEFT and cx > 1 then -- LEFT
table.insert(map_matrix[cx][cy].exits, direction)
room_builder.add_exit(map_matrix[cx][cy], direction)
map_matrix[cx][cy].path_dir = direction
cx = cx - 1;
table.insert(map_matrix[cx][cy].exits, reverse_direction(direction))
cx = cx - 1
valid_direction = true
elseif direction == RIGHT and cx < 10 then -- RIGHT
table.insert(map_matrix[cx][cy].exits, direction)
room_builder.add_exit(map_matrix[cx][cy], direction)
map_matrix[cx][cy].path_dir = direction
cx = cx + 1;
table.insert(map_matrix[cx][cy].exits, reverse_direction(direction))
cx = cx + 1
valid_direction = true
elseif direction == DOWN and cy < 10 then -- DOWN
table.insert(map_matrix[cx][cy].exits, direction)
room_builder.add_exit(map_matrix[cx][cy], direction)
map_matrix[cx][cy].path_dir = direction
cy = cy + 1;
table.insert(map_matrix[cx][cy].exits, reverse_direction(direction))
cy = cy + 1
valid_direction = true
end
-- Create the next room and add the reverse exit
-- if a valid direction was found
if valid_direction then
if not map_matrix[cx][cy] then
map_matrix[cx][cy] = room_builder.create_empty_room()
end
room_builder.add_exit(map_matrix[cx][cy], reverse_direction(direction))
end
lastDirection = direction
end
-- Last room rules
map_matrix[cx][cy].active = true
map_matrix[cx][cy].goal = true
map_matrix[cx][cy].type = "room"
return map_matrix;
end
local function print_matrix(matrix)
-- Build all the rooms
for i=1,10 do
for j=1,10 do
if not map_matrix[j][i].goal then
io.write(map_matrix[j][i].path_dir .. " ")
else
io.write("G ")
room = map_matrix[i][j]
if room then
room_builder.build_room(room)
monster_gen.add_monsters_to_room(room, i-1, j-1)
end
end
io.write("\n")
end
return map_matrix;
end
-- END FUNCTIONS
@ -126,14 +134,10 @@ local map_matrix = generate_path()
for i=1,10 do
for j=1,10 do
local room = map_matrix[i][j]
if room.active then
if room then
set_current_room(map, i-1, j-1);
if room.type == "room" then
room_builder.build_square_room(map, room)
monster_gen.add_monster_to_room(map, i-1, j-1);
elseif room.type == "coridoor" then
room_builder.build_coridoor_room(map, room)
end
room_builder.load_room(map, room)
monster_gen.load_monsters(map, room.monsters)
end
end
end

View File

@ -61,23 +61,23 @@ local function load_decor_textures()
table.insert(floorDecor, { td0, td1, 48, 13 * 16, false, false })
-- Urns
table.insert(floorDecor, { td0, td1, 0 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 1 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 2 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 3 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 4 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 5 * 16, 48, true, false })
table.insert(floorDecor, { td0, td1, 6 * 16, 48, false, false })
table.insert(floorDecor, { td0, td1, 7 * 16, 48, false, false })
--table.insert(floorDecor, { td0, td1, 0 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 1 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 2 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 3 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 4 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 5 * 16, 48, true, false })
--table.insert(floorDecor, { td0, td1, 6 * 16, 48, false, false })
--table.insert(floorDecor, { td0, td1, 7 * 16, 48, false, false })
-- Racks
table.insert(floorDecor, { td0, td1, 0 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 1 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 2 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 3 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 4 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 5 * 16, 11 * 16, true, false })
table.insert(floorDecor, { td0, td1, 6 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 0 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 1 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 2 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 3 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 4 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 5 * 16, 11 * 16, true, false })
--table.insert(floorDecor, { td0, td1, 6 * 16, 11 * 16, true, false })
-- Headstones
table.insert(floorDecor, { td0, td1, 0 * 16, 17 * 16, true, false })
@ -138,22 +138,31 @@ local function check_add_decoration(map, x, y, data)
return true
end
local function check_add_tile(map, x, y, data)
if tile_occupied(map, x, y) then
return false
end
add_tile(map, x, y, repack(data))
return true
end
local function add_random_decor_to_room(map)
local function add_random_decor_to_room(room)
local decor_count = random(4) - 1
for i=1,decor_count do
check_add_decoration(map, random(11)+1, random(8)+1, floorDecor[random(#floorDecor)])
x = random(11) + 1
y = random(8) + 1
if not room.decor[x][y] then
room.decor[x][y] = floorDecor[random(#floorDecor)]
end
end
if random(2) == 1 then
room.decor[4][3] = lightDecor.candle2
end
if random(2) == 1 then
room.decor[11][3] = lightDecor.candle2
end
if random(2) == 1 then
room.decor[4][9] = lightDecor.candle2
end
if random(2) == 1 then
room.decor[11][9] = lightDecor.candle2
end
end
local function add_pits_to_room(map)
local function add_pits_to_room(room)
if CURRENT_LEVEL < 3 then
return
@ -189,210 +198,177 @@ local function add_pits_to_room(map)
-- Chose a random layout
matrix = matrix[random(#matrix)]
for i=2,13 do
for j=2,10 do
if not tile_occupied(map, (i), (j)) and matrix[i][j] then
if matrix[i][j] then
room.decor[i][j] = nil
if not matrix[i-1][j-1] and not matrix[i+1][j-1] and matrix[i-1][j] and matrix[i+1][j] and matrix[i][j-1] then
add_tile(map, i, j, repack(pits.innermid))
room.tiles[i][j] = pits.innermid
elseif not matrix[i-1][j-1] and matrix[i-1][j] and matrix[i][j-1] then
add_tile(map, i, j, repack(pits.innerleft))
room.tiles[i][j] = pits.innerleft
elseif not matrix[i+1][j-1] and matrix[i+1][j] and matrix[i][j-1] then
add_tile(map, i, j, repack(pits.innerright))
room.tiles[i][j] = pits.innerright
elseif not matrix[i-1][j] and not matrix[i][j-1] and not matrix[i+1][j] then
add_tile(map, i, j, repack(pits.topcrevice))
room.tiles[i][j] = pits.topcrevice
elseif not matrix[i-1][j] and not matrix[i+1][j] then
add_tile(map, i, j, repack(pits.bottomcrevice))
room.tiles[i][j] = pits.bottomcrevice
elseif not matrix[i-1][j] and not matrix[i][j-1] then
add_tile(map, i, j, repack(pits.topleft))
room.tiles[i][j] = pits.topleft
elseif not matrix[i+1][j] and not matrix[i][j-1] then
add_tile(map, i, j, repack(pits.topright))
room.tiles[i][j] = pits.topright
elseif not matrix[i-1][j] then
add_tile(map, i, j, repack(pits.left))
room.tiles[i][j] = pits.left
elseif not matrix[i+1][j] then
add_tile(map, i, j, repack(pits.right))
room.tiles[i][j] = pits.right
elseif not matrix[i][j-1] then
add_tile(map, i, j, repack(pits.top))
room.tiles[i][j] = pits.top
else
add_tile(map, i, j, repack(pits.center))
room.tiles[i][j] = pits.center
end
end
end
end
end
local function add_tiles_to_room (map)
local function add_tiles_to_room (room)
for i=0,15 do
for j=0,11 do
if (i >= 1 and i <= 14 and j >= 1 and j <= 10) then
if (i == 1 and j == 1) then
add_tile(map, i, j, repack(floor.topleft))
room.tiles[i][j] = floor.topleft
elseif (i == 14 and j == 1) then
add_tile(map, i, j, repack(floor.topright))
room.tiles[i][j] = floor.topright
elseif (i == 1 and j == 10) then
add_tile(map, i, j, repack(floor.bottomleft))
room.tiles[i][j] = floor.bottomleft
elseif (i == 14 and j == 10) then
add_tile(map, i, j, repack(floor.bottomright))
room.tiles[i][j] = floor.bottomright
elseif (i == 1) then
add_tile(map, i, j, repack(floor.left))
room.tiles[i][j] = floor.left
elseif (i == 14) then
add_tile(map, i, j, repack(floor.right))
room.tiles[i][j] = floor.right
elseif (j == 1) then
add_tile(map, i, j, repack(floor.top))
room.tiles[i][j] = floor.top
elseif (j == 10) then
add_tile(map, i, j, repack(floor.bottom))
room.tiles[i][j] = floor.bottom
else
add_tile(map, i, j, repack(floor.center))
room.tiles[i][j] = floor.center
end
end
end
end
add_random_decor_to_room(map)
add_pits_to_room(map)
end
local function add_walls_to_room (map)
local function add_walls_to_room (room)
for i=0,15 do
for j=0,11 do
if (i == 0 and j == 0) then
add_tile(map, i, j, repack(wall.topleft))
room.tiles[i][j] = wall.topleft
elseif (i == 15 and j == 0) then
add_tile(map, i, j, repack(wall.topright))
room.tiles[i][j] = wall.topright
elseif (i == 0 and j == 11) then
add_tile(map, i, j, repack(wall.bottomleft))
room.tiles[i][j] = wall.bottomleft
elseif (i == 15 and j == 11) then
add_tile(map, i, j, repack(wall.bottomright))
room.tiles[i][j] = wall.bottomright
elseif (i == 0 or i == 15) then
add_tile(map, i, j, repack(wall.vertical))
room.tiles[i][j] = wall.vertical
elseif (j == 0 or j == 11) then
add_tile(map, i, j, repack(wall.horizontal))
room.tiles[i][j] = wall.horizontal
end
end
end
if random(2) == 1 then
check_add_decoration(map, 4, 3, lightDecor.candle2)
end
if random(2) == 1 then
check_add_decoration(map, 11, 3, lightDecor.candle2)
end
if random(2) == 1 then
check_add_decoration(map, 4, 9, lightDecor.candle2)
end
if random(2) == 1 then
check_add_decoration(map, 11, 9, lightDecor.candle2)
end
end
local function add_exit(map, direction)
if direction > 4 then return end
if direction == UP then
add_tile(map, 6, 0, repack(wall.bottomright))
add_tile(map, 7, 0, repack(floor.singleleft))
add_tile(map, 8, 0, repack(floor.singleright))
add_tile(map, 9, 0, repack(wall.bottomleft))
elseif direction == LEFT then
add_tile(map, 0, 4, repack(wall.bottomright))
add_tile(map, 0, 5, repack(floor.singletop))
add_tile(map, 0, 6, repack(floor.singlebottom))
add_tile(map, 0, 7, repack(wall.topright))
elseif direction == RIGHT then
add_tile(map, 15, 4, repack(wall.bottomleft))
add_tile(map, 15, 5, repack(floor.singletop))
add_tile(map, 15, 6, repack(floor.singlebottom))
add_tile(map, 15, 7, repack(wall.topleft))
elseif direction == DOWN then
add_tile(map, 6, 11, repack(wall.topright))
add_tile(map, 7, 11, repack(floor.singleleft))
add_tile(map, 8, 11, repack(floor.singleright))
add_tile(map, 9, 11, repack(wall.topleft))
end
end
local function add_level_exit(map)
success = false
while not success do
x = random(14)
y = random(10)
success = check_add_tile(map, x, y, special.level_exit)
end
end
local function build_vert_center_coridoor(map, offset)
for j=0,4 do
add_tile(map, 6, offset+j, repack(wall.vertical));
add_tile(map, 7, offset+j, repack(floor.center));
add_tile(map, 8, offset+j, repack(floor.center));
add_tile(map, 9, offset+j, repack(wall.vertical));
local function build_vert_center_coridoor(room, offset)
for i=0,4 do
room.tiles[6][offset+i] = wall.vertical
room.tiles[7][offset+i] = floor.center
room.tiles[8][offset+i] = floor.center
room.tiles[9][offset+i] = wall.vertical
end
if random(2) == 1 then
add_decoration(map, 6, offset + 2, repack(lightDecor.candle1))
room.decor[6][offset+2] = lightDecor.candle1
end
if random(2) == 1 then
add_decoration(map, 9, offset + 2, repack(lightDecor.candle1))
room.decor[6][offset+2] = lightDecor.candle1
end
end
local function build_horiz_center_coridoor(map, offset)
local function build_horiz_center_coridoor(room, offset)
info("Building horizontal corrdior: " .. offset)
for i=0,6 do
add_tile(map, offset+i, 4, repack(wall.horizontal));
add_tile(map, offset+i, 5, repack(floor.center));
add_tile(map, offset+i, 6, repack(floor.center));
add_tile(map, offset+i, 7, repack(wall.horizontal));
room.tiles[offset+i][4] = wall.horizontal
room.tiles[offset+i][5] = floor.center
room.tiles[offset+i][6] = floor.center
room.tiles[offset+i][7] = wall.horizontal
end
if random(2) == 1 then
check_add_decoration(map, offset+3, 4, lightDecor.candle1)
room.decor[offset+3][4] = lightDecor.candle1
end
if random(2) == 1 then
check_add_decoration(map, offset+3, 7, lightDecor.candle1)
room.decor[offset+3][7] = lightDecor.candle1
end
end
local function build_center_corner_walls(map, exits)
local function build_center_corner_walls(room, exits)
if exits.down then
if exits.left then
add_tile(map, 6, 7, repack(wall.topright))
room.tiles[6][7] = wall.topright
end
if exits.right then
add_tile(map, 9, 7, repack(wall.topleft))
room.tiles[9][7] = wall.topleft
end
else
if not exits.left then
add_tile(map, 6, 7, repack(wall.bottomleft))
room.tiles[6][7] = wall.bottomleft
end
if not exits.right then
add_tile(map, 9, 7, repack(wall.bottomright))
room.tiles[9][7] = wall.bottomright
end
end
if exits.up then
if exits.left then
add_tile(map, 6, 4, repack(wall.bottomright))
room.tiles[6][4] = wall.bottomright
end
if exits.right then
add_tile(map, 9, 4, repack(wall.bottomleft))
room.tiles[9][4] = wall.bottomleft
end
else
if not exits.left then
add_tile(map, 6, 4, repack(wall.topleft))
room.tiles[6][4] = wall.topleft
end
if not exits.right then
add_tile(map, 9, 4, repack(wall.topright))
room.tiles[9][4] = wall.topright
end
end
end
local module = {}
function module.add_full_lighting(map)
check_add_decoration(map, 4, 3, lightDecor.candle2)
check_add_decoration(map, 11, 3, lightDecor.candle2)
check_add_decoration(map, 4, 9, lightDecor.candle2)
check_add_decoration(map, 11, 9, lightDecor.candle2)
local function add_exits_to_room(room)
for _,direction in ipairs(room.exits) do
if direction == UP then
room.tiles[6][0] = wall.bottomright
room.tiles[7][0] = floor.singleleft
room.tiles[8][0] = floor.singleright
room.tiles[9][0] = wall.bottomleft
elseif direction == LEFT then
room.tiles[0][4] = wall.bottomright
room.tiles[0][5] = floor.singletop
room.tiles[0][6] = floor.singlebottom
room.tiles[0][7] = wall.topright
elseif direction == RIGHT then
room.tiles[15][4] = wall.bottomleft
room.tiles[15][5] = floor.singletop
room.tiles[15][6] = floor.singlebottom
room.tiles[15][7] = wall.topleft
elseif direction == DOWN then
room.tiles[6][11] = wall.topright
room.tiles[7][11] = floor.singleleft
room.tiles[8][11] = floor.singleright
room.tiles[9][11] = wall.topleft
end
end
end
function module.build_coridoor_room(map, room)
local function build_coridoor_room(room)
local exits = {
up = false,
down = false,
@ -409,51 +385,126 @@ function module.build_coridoor_room(map, room)
end
-- Fill the center
add_tile(map, 6, 5, repack(wall.vertical))
add_tile(map, 6, 6, repack(wall.vertical))
add_tile(map, 7, 4, repack(wall.horizontal))
add_tile(map, 7, 5, repack(floor.center))
add_tile(map, 7, 6, repack(floor.center))
add_tile(map, 7, 7, repack(wall.horizontal))
add_tile(map, 8, 4, repack(wall.horizontal))
add_tile(map, 8, 5, repack(floor.center))
add_tile(map, 8, 6, repack(floor.center))
add_tile(map, 8, 7, repack(wall.horizontal))
add_tile(map, 9, 5, repack(wall.vertical))
add_tile(map, 9, 6, repack(wall.vertical))
room.tiles[6][5] = wall.vertical
room.tiles[6][6] = wall.vertical
room.tiles[7][4] = wall.horizontal
room.tiles[7][5] = floor.center
room.tiles[7][6] = floor.center
room.tiles[7][7] = wall.horizontal
room.tiles[8][4] = wall.horizontal
room.tiles[8][5] = floor.center
room.tiles[8][6] = floor.center
room.tiles[8][7] = wall.horizontal
room.tiles[9][5] = wall.vertical
room.tiles[9][6] = wall.vertical
-- Build the coridoors
if exits.down then build_vert_center_coridoor(map, 7) end
if exits.up then build_vert_center_coridoor(map, 0) end
if exits.left then build_horiz_center_coridoor(map, 0) end
if exits.right then build_horiz_center_coridoor(map, 9) end
if exits.down then build_vert_center_coridoor(room, 7) end
if exits.up then build_vert_center_coridoor(room, 0) end
if exits.left then build_horiz_center_coridoor(room, 0) end
if exits.right then build_horiz_center_coridoor(room, 9) end
build_center_corner_walls(map, exits)
build_center_corner_walls(room, exits)
end
function module.create_room ()
return {
exits = {},
active = false,
goal = false,
path_dir = 0,
type = "room"
}
end
function module.build_square_room(map, room)
add_tiles_to_room(map);
add_walls_to_room(map);
for exit=1, #room.exits do
add_exit(map, room.exits[exit]);
local function add_level_exit(room)
success = false
while not success do
x = random(14)
y = random(10)
if not room.decor[x][y] then
success = true
room.tiles[x][y] = special.level_exit
end
end
end
local function build_normal_room(room)
add_tiles_to_room(room)
add_random_decor_to_room(room)
add_walls_to_room(room)
add_exits_to_room(room)
add_pits_to_room(room)
if room.goal then
add_level_exit(map);
add_level_exit(room)
end
if CURRENT_LEVEL > 3 and random(10) == 1 then
directions = { "LEFT", "RIGHT", "UP", "DOWN" }
set_modifier(map, "WINDY", directions[random(#directions)]);
room.modifier.type = "WINDY"
room.modifier.arg = directions[random(#directions)]
end
return room
end
local module = {}
function module.add_exit(room, direction)
if direction > 4 then
return
end
table.insert(room.exits, direction)
end
function module.add_full_lighting(room)
room.decor[4][3] = lightDecor.candle2
room.decor[11][3] = lightDecor.candle2
room.decor[4][9] = lightDecor.candle2
room.decor[11][9] = lightDecor.candle2
end
function module.create_empty_room()
room = {
exits = {},
active = false,
goal = false,
path_dir = 0,
type = "room",
tiles = {},
decor = {},
modifier = {
type = nil,
arg = nil
},
monsters = {}
}
for i=0,15 do
room.tiles[i] = {}
room.decor[i] = {}
room.monsters[i] = {}
for j=0,11 do
room.tiles[i][j] = nil
room.decor[i][j] = nil
room.monsters[i][j] = nil
end
end
return room
end
function module.build_room(room)
if room.type == "coridoor" then
build_coridoor_room(room)
else
build_normal_room(room)
end
end
function module.load_room(map, room)
for i=0, 15 do
for j=0, 11 do
if room.tiles[i][j] then
add_tile(map, i, j, repack(room.tiles[i][j]))
end
if room.decor[i][j] then
add_decoration(map, i, j, repack(room.decor[i][j]))
end
end
end
if room.modifier.type then
set_modifier(map, room.modifier.type, room.modifier.arg)
end
end

View File

@ -4,9 +4,11 @@ local monster_gen = require "monstergen"
map = create_map(CURRENT_LEVEL) -- 'map' needs to be global
room_builder.load_textures(map)
local room = room_builder.create_room()
set_current_room(map, 0, 0)
room_builder.build_square_room(map, room)
monster_gen.add_monster_to_room(map, 0, 0);
room_builder.add_full_lighting(map);
local room = room_builder.create_empty_room()
room_builder.build_room(room)
room_builder.add_full_lighting(room)
monster_gen.add_monsters_to_room(room, 0, 0)
room_builder.load_room(map, room)
monster_gen.load_monsters(map, room.monsters)

View File

@ -241,15 +241,42 @@ if random(100) == 1 then
enemies = concat(enemies, platino);
end
function module.add_monster_to_room(map, roomx, roomy)
function module.add_monsters_to_room(room, roomx, roomy)
local count = random(3)
if (CURRENT_LEVEL > 3) then
count = random(4)
end
for i=0,count do
local x = (roomx * 512) + (random(13) + 1) * 32
local y = (roomy * 384) + (random(9) + 1) * 32
add_monster(map, x, y, repack(enemies[random(#enemies)]));
local i = 0
while i < count do
local rx = random(13) + 1
local ry = random(9) + 1
if not room.decor[rx][ry]
and not room.monsters[rx][ry]
and (room.tiles[rx][ry]
and not room.tiles[rx][ry][5]
and not room.tiles[rx][ry][8])
then
local x = (roomx * 512) + rx * 32
local y = (roomy * 384) + ry * 32
room.monsters[rx][ry] = {
x,
y,
enemies[random(#enemies)]
}
i = i + 1
end
end
end
function module.load_monsters(map, monsters)
for i=0,15 do
for j=0,11 do
monster = monsters[i][j]
if monster then
add_monster(map, monster[1], monster[2], repack(monster[3]))
end
end
end
end

117
src/animation.c Normal file
View File

@ -0,0 +1,117 @@
/*
* BreakHack - A dungeone crawler RPG
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "animation.h"
#include "timer.h"
#include "camera.h"
#include "sprite.h"
#include "util.h"
Animation *
animation_create(unsigned int clipCount)
{
Animation *animation = ec_malloc(sizeof(Animation)
+ clipCount * sizeof(AnimationClip));
animation->clipTimer = timer_create();
animation->clipCount = clipCount;
animation->currentClip = 0;
animation->loop = true;
animation->running = false;
animation->sprite = sprite_create();
return animation;
}
void
animation_load_texture(Animation *animation, const char *path, SDL_Renderer *renderer)
{
sprite_load_texture(animation->sprite, path, 0, renderer);
}
void
animation_update(Animation *animation)
{
if (!animation->running) {
return;
}
if (!timer_started(animation->clipTimer)) {
timer_start(animation->clipTimer);
}
if (timer_get_ticks(animation->clipTimer)
> animation->clips[animation->currentClip].renderTime)
{
animation->currentClip++;
if (animation->currentClip >= animation->clipCount) {
animation->currentClip = 0;
if (!animation->loop) {
animation_stop(animation);
return;
}
timer_start(animation->clipTimer);
}
}
animation->sprite->clip = (SDL_Rect) {
animation->clips[animation->currentClip].x,
animation->clips[animation->currentClip].y,
animation->clips[animation->currentClip].w,
animation->clips[animation->currentClip].h
};
}
void
animation_render(Animation *animation, Camera *camera)
{
if (!animation->running) {
return;
}
sprite_render(animation->sprite, camera);
}
void
animation_set_frames(Animation *animation, AnimationClip clips[])
{
for (size_t i = 0; i < animation->clipCount; i++) {
animation->clips[i] = clips[i];
}
}
void
animation_run(Animation *a)
{
a->running = true;
}
void
animation_stop(Animation *a)
{
a->running = false;
a->currentClip = 0;
timer_stop(a->clipTimer);
}
void
animation_destroy(Animation *animation)
{
timer_destroy(animation->clipTimer);
sprite_destroy(animation->sprite);
free(animation);
}

75
src/animation.h Normal file
View File

@ -0,0 +1,75 @@
/*
* BreakHack - A dungeone crawler RPG
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ANIMATION_H
#define _ANIMATION_H
#include <SDL.h>
#include <stdbool.h>
typedef struct Timer Timer;
typedef struct Camera Camera;
typedef struct Sprite Sprite;
typedef struct AnimationClip
{
unsigned int x;
unsigned int y;
unsigned int w;
unsigned int h;
unsigned int renderTime;
} AnimationClip;
typedef struct Animation
{
Sprite *sprite;
Timer *clipTimer;
unsigned int currentClip;
bool loop;
unsigned int clipCount;
bool running;
AnimationClip clips[];
} Animation;
Animation*
animation_create(unsigned int clipCount);
void
animation_load_texture(Animation *, const char *path, SDL_Renderer*);
void
animation_set_frames(Animation*, AnimationClip clips[]);
void
animation_run(Animation*);
void
animation_update(Animation*);
void
animation_render(Animation*, Camera*);
void
animation_stop(Animation*);
void
animation_destroy(Animation*);
#endif // _ANIMATION_H

View File

@ -25,7 +25,7 @@
#include "timer.h"
#include "vector2d.h"
typedef struct {
typedef struct Camera {
Position pos;
Position basePos;
Vector2d velocity;

View File

@ -42,6 +42,5 @@ void linkedlist_each(LinkedList **head, void (*fun)(void*));
void linkedlist_destroy(LinkedList **head);
unsigned int linkedlist_size(LinkedList *head);
#endif // LINKEDLIST_H_

View File

@ -108,10 +108,6 @@ bool initSDL(void)
if (dim.height > 1080) {
info("Hi resolution screen detected (%u x %u)", dim.width, dim.height);
renderScale = ((double) dim.height)/1080;
if (renderScale > 2)
renderScale = 3;
else if (renderScale > 1)
renderScale = 2;
info("Scaling by %f", renderScale);
}
@ -250,6 +246,7 @@ goToMainMenu(void *unused)
inGameMenu = NULL;
initMainMenu();
Position p = { 0, 0 };
gPlayer->sprite->pos = (Position) { 32, 32 };
map_set_current_room(gMap, &p);
camera_follow_position(gCamera, &p);
}
@ -298,6 +295,22 @@ initInGameMenu(void)
createMenu(&inGameMenu, menu_items, 3);
}
static void
createInGameGameOverMenu(void)
{
struct MENU_ITEM menu_items[] = {
{ "NEW GAME", startGame },
{ "MAIN MENU", goToMainMenu },
{ "QUIT", exitGame },
};
if (inGameMenu) {
menu_destroy(inGameMenu);
inGameMenu = NULL;
}
createMenu(&inGameMenu, menu_items, 3);
}
static void
initMainMenu(void)
{
@ -315,6 +328,15 @@ initMainMenu(void)
mixer_play_music(MENU_MUSIC);
}
static void
repopulate_roommatrix(void)
{
roommatrix_populate_from_map(gRoomMatrix, gMap);
roommatrix_add_lightsource(gRoomMatrix,
&gPlayer->sprite->pos);
roommatrix_build_lightmap(gRoomMatrix);
}
static void
resetGame(void)
{
@ -341,6 +363,7 @@ resetGame(void)
map_set_current_room(gMap, &gPlayer->sprite->pos);
camera_follow_position(gCamera, &gPlayer->sprite->pos);
repopulate_roommatrix();
}
static bool
@ -461,7 +484,7 @@ populateUpdateData(UpdateData *data, float deltatime)
}
static void
run_game(void)
run_game_update(void)
{
static UpdateData updateData;
static unsigned int playerLevel = 1;
@ -471,11 +494,6 @@ run_game(void)
map_clear_dead_monsters(gMap, gPlayer);
map_clear_collected_items(gMap);
roommatrix_populate_from_map(gRoomMatrix, gMap);
roommatrix_add_lightsource(gRoomMatrix,
&gPlayer->sprite->pos);
roommatrix_build_lightmap(gRoomMatrix);
populateUpdateData(&updateData, deltaTime);
if (playerLevel != gPlayer->stats.lvl) {
@ -500,13 +518,19 @@ run_game(void)
if (player_turn_over(gPlayer)) {
currentTurn = MONSTER;
player_reset_steps(gPlayer);
repopulate_roommatrix();
}
} else if (currentTurn == MONSTER) {
if (map_move_monsters(gMap, gRoomMatrix)) {
currentTurn = PLAYER;
repopulate_roommatrix();
}
}
}
static void
run_game_render(void)
{
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0);
SDL_RenderClear(gRenderer);
@ -519,6 +543,9 @@ run_game(void)
map_render_top_layer(gMap, gCamera);
if (!is_player_dead())
player_render_toplayer(gPlayer, gCamera);
if (gPlayer->class == MAGE || gPlayer->class == PALADIN)
roommatrix_render_mouse_square(gRoomMatrix, gCamera);
@ -547,6 +574,14 @@ run_game(void)
pointer_render(gPointer, gCamera);
SDL_RenderPresent(gRenderer);
}
static void
run_game(void)
{
run_game_update();
run_game_render();
if (gGameState == PLAYING && is_player_dead()) {
camera_shake(VECTOR2D_RIGHT, 800);
@ -554,6 +589,8 @@ run_game(void)
gui_event_message("You died!");
mixer_play_effect(SPLAT);
gGameState = GAME_OVER;
createInGameGameOverMenu();
toggleInGameMenu(NULL);
} else {
check_next_level();
}

View File

@ -27,7 +27,7 @@
#include "mixer.h"
#include "collisions.h"
typedef struct MenuItems_t {
typedef struct MenuItems {
Sprite *sprite;
Sprite *hsprite;
GuiButton *button;

View File

@ -66,7 +66,11 @@ monster_state_change(Monster *m, StateType newState)
m->state.current = newState;
m->state.stepsSinceChange = 0;
m->stateIndicator.displayCount = 5;
if (newState == SLEEPING)
m->stateIndicator.displayCount = -1;
else
m->stateIndicator.displayCount = 5;
monster_set_sprite_clip_for_current_state(m);
}
@ -241,8 +245,8 @@ monster_drunk_walk(Monster *m, RoomMatrix *rm)
}
}
static void
monster_agressive_walk(Monster *m, RoomMatrix *rm)
static Direction
get_optimal_move_towards(Monster *m, RoomMatrix *rm, const Position *dest)
{
int x_dist, y_dist;
Position mPos;
@ -257,21 +261,21 @@ monster_agressive_walk(Monster *m, RoomMatrix *rm)
unsigned int nextScore = 0;
switch (i) {
case UP:
next.y -= 1;
break;
case DOWN:
next.y += 1;
break;
case LEFT:
next.x -= 1;
break;
case RIGHT:
next.x += 1;
break;
case UP:
next.y -= 1;
break;
case DOWN:
next.y += 1;
break;
case LEFT:
next.x -= 1;
break;
case RIGHT:
next.x += 1;
break;
}
if (position_equals(&next, &rm->playerRoomPos)) {
if (position_equals(&next, dest)) {
chosenDirection = (Direction) i;
break;
}
@ -279,8 +283,8 @@ monster_agressive_walk(Monster *m, RoomMatrix *rm)
if (!position_in_roommatrix(&next))
continue;
x_dist = abs(next.x - rm->playerRoomPos.x);
y_dist = abs(next.y - rm->playerRoomPos.y);
x_dist = abs(next.x - dest->x);
y_dist = abs(next.y - dest->y);
if (rm->spaces[next.x][next.y].occupied || rm->spaces[next.x][next.y].lethal) {
nextScore += 50;
@ -289,23 +293,31 @@ monster_agressive_walk(Monster *m, RoomMatrix *rm)
nextScore += x_dist > y_dist ? x_dist : y_dist;
if (nextScore < currentScore) {
currentScore = nextScore;
chosenDirection = (Direction)i;
chosenDirection = (Direction) i;
}
}
return chosenDirection;
}
static void
monster_agressive_walk(Monster *m, RoomMatrix *rm)
{
unsigned int chosenDirection = get_optimal_move_towards(m, rm, &rm->playerRoomPos);
switch (chosenDirection) {
case UP:
move(m, rm, VECTOR2D_UP);
break;
case DOWN:
move(m, rm, VECTOR2D_DOWN);
break;
case LEFT:
move(m, rm, VECTOR2D_LEFT);
break;
case RIGHT:
move(m, rm, VECTOR2D_RIGHT);
break;
case UP:
move(m, rm, VECTOR2D_UP);
break;
case DOWN:
move(m, rm, VECTOR2D_DOWN);
break;
case LEFT:
move(m, rm, VECTOR2D_LEFT);
break;
case RIGHT:
move(m, rm, VECTOR2D_RIGHT);
break;
}
}
@ -320,7 +332,6 @@ monster_coward_walk(Monster *m, RoomMatrix *rm)
x_dist = mPos.x - rm->playerRoomPos.x;
y_dist = mPos.y - rm->playerRoomPos.y;
if (abs(x_dist) > abs(y_dist)) {
if (x_dist > 0)
move(m, rm, VECTOR2D_RIGHT);
@ -389,7 +400,9 @@ monster_update(Monster *m, UpdateData *data)
return;
m->stateIndicator.shownOnPlayerRoomEnter = true;
if (m->state.current != PASSIVE && m->state.current != STATIONARY)
if (m->state.current == SLEEPING)
m->stateIndicator.displayCount = -1; // Sleeping state is always shown
else if (m->state.current != PASSIVE && m->state.current != STATIONARY)
m->stateIndicator.displayCount = 5;
} else {
m->stateIndicator.shownOnPlayerRoomEnter = false;
@ -486,7 +499,7 @@ monster_render(Monster *m, Camera *cam)
return;
sprite_render(m->sprite, cam);
if (m->stateIndicator.displayCount > 0)
if (m->stateIndicator.displayCount != 0)
sprite_render(m->stateIndicator.sprite, cam);
}

View File

@ -252,7 +252,7 @@ particle_engine_sparkle(Position pos, Dimension dim)
alpha = get_random(155) + 100;
yv = (get_random(100) + 100) * -1;
yv = -(get_random(100) + 100);
lt = get_random(20);

View File

@ -33,6 +33,7 @@
#include "texturecache.h"
#include "vector2d.h"
#include "actiontextbuilder.h"
#include "animation.h"
#define ENGINEER_STATS { 12, 12, 5, 7, 2, 2, 1 }
#define MAGE_STATS { 12, 12, 5, 7, 1, 2, 1 }
@ -133,6 +134,8 @@ has_collided(Player *player, RoomMatrix *matrix, Vector2d direction)
monster_hit(space->monster, hit);
animation_run(player->swordAnimation);
if (hit > 0) {
gui_log("You hit %s for %u damage",
space->monster->lclabel, hit);
@ -190,12 +193,41 @@ set_clip_for_direction(Player *player, Vector2d *direction)
player->sprite->clip.y = 0;
}
void
player_turn(Player *player, Vector2d *direction)
{
set_clip_for_direction(player, direction);
if (!vector2d_equals(*direction, VECTOR2D_NODIR))
player->swordAnimation->sprite->pos = player->sprite->pos;
if (vector2d_equals(*direction, VECTOR2D_UP)) {
player->swordAnimation->sprite->pos.y -= 32;
player->swordAnimation->sprite->angle = -90;
player->swordAnimation->sprite->flip = SDL_FLIP_NONE;
} else if (vector2d_equals(*direction, VECTOR2D_DOWN)) {
player->swordAnimation->sprite->pos.y += 32;
player->swordAnimation->sprite->angle = 90;
player->swordAnimation->sprite->flip = SDL_FLIP_NONE;
} else if (vector2d_equals(*direction, VECTOR2D_LEFT)) {
player->swordAnimation->sprite->pos.x -= 32;
player->swordAnimation->sprite->angle = 0;
player->swordAnimation->sprite->flip = SDL_FLIP_HORIZONTAL;
} else if (vector2d_equals(*direction, VECTOR2D_RIGHT)) {
player->swordAnimation->sprite->pos.x += 32;
player->swordAnimation->sprite->angle = 0;
player->swordAnimation->sprite->flip = SDL_FLIP_NONE;
}
}
static void
move(Player *player, RoomMatrix *matrix, Vector2d direction)
{
set_clip_for_direction(player, &direction);
player_turn(player, &direction);
player->sprite->pos.x += TILE_DIMENSION * (int) direction.x;
player->sprite->pos.y += TILE_DIMENSION * (int) direction.y;
if (!has_collided(player, matrix, direction)) {
player_step(player);
}
@ -236,6 +268,11 @@ handle_next_move(UpdateData *data)
static unsigned int step = 1;
Player *player = data->player;
// Don't move when projectiles are still moving
if (linkedlist_size(player->projectiles) > 0)
return;
RoomMatrix *matrix = data->matrix;
Vector2d nextDir = read_direction_from(data->input);
if (!vector2d_equals(nextDir, VECTOR2D_NODIR))
@ -329,12 +366,34 @@ check_skill_trigger(UpdateData *data)
return true;
}
static void
build_sword_animation(Player *p, SDL_Renderer *renderer)
{
animation_load_texture(p->swordAnimation, "Extras/SwordSwing.png", renderer);
animation_set_frames(p->swordAnimation, (AnimationClip[]) {
{ 0, 0, 16, 16, 20 },
{ 16, 0, 16, 16, 20 },
{ 32, 0, 16, 16, 20 },
{ 48, 0, 16, 16, 20 },
{ 64, 0, 16, 16, 20 }
});
p->swordAnimation->loop = false;
p->swordAnimation->sprite->dim = GAME_DIMENSION;
p->swordAnimation->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
p->swordAnimation->sprite->rotationPoint = (SDL_Point) { 16, 16 };
}
Player*
player_create(class_t class, SDL_Renderer *renderer)
{
Player *player = malloc(sizeof(Player));
player->sprite = sprite_create();
#ifdef DEBUG
player->daggers = 10;
#else
player->daggers = 0;
#endif
player->stat_data.total_steps = 0;
player->stat_data.steps = 0;
player->stat_data.hits = 0;
@ -347,6 +406,9 @@ player_create(class_t class, SDL_Renderer *renderer)
player->state = ALIVE;
player->projectiles = linkedlist_create();
player->animationTimer = timer_create();
player->swordAnimation = animation_create(5);
build_sword_animation(player, renderer);
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
player->skills[i] = NULL;
@ -447,7 +509,12 @@ player_render(Player *player, Camera *cam)
projectile_render(projectile->data, cam);
projectile = projectile->next;
}
}
void
player_render_toplayer(Player *player, Camera *camera)
{
animation_render(player->swordAnimation, camera);
}
void
@ -502,6 +569,8 @@ void player_update(UpdateData *data)
linkedlist_destroy(&player->projectiles);
player->projectiles = remaining;
animation_update(player->swordAnimation);
}
void
@ -510,6 +579,7 @@ player_destroy(Player *player)
if (player->sprite)
sprite_destroy(player->sprite);
animation_destroy(player->swordAnimation);
timer_destroy(player->animationTimer);
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {

View File

@ -31,7 +31,8 @@
#define PLAYER_SKILL_COUNT 5
// Foward declare
struct UpdateData;
typedef struct UpdateData UpdateData;
typedef struct Animation Animation;
typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
typedef enum PlayerState { ALIVE, DEAD, FALLING } state_t;
@ -64,6 +65,7 @@ typedef struct Player_t {
state_t state;
Skill *skills[PLAYER_SKILL_COUNT];
Timer *animationTimer;
Animation *swordAnimation;
} Player;
Player*
@ -90,6 +92,12 @@ player_update(struct UpdateData *);
void
player_render(Player*, Camera*);
void
player_render_toplayer(Player*, Camera*);
void
player_turn(Player*, Vector2d *dir);
void
player_destroy(Player*);

View File

@ -100,6 +100,7 @@ projectile_update(Projectile *p, UpdateData *data)
linkedlist_append(&data->map->items, item);
}
monster_hit(space->monster, dmg);
player_monster_kill_check(data->player, space->monster);
}
mixer_play_effect(SWORD_HIT);
p->alive = false;

View File

@ -25,6 +25,29 @@
#include "item.h"
#include "update_data.h"
static void
roommatrix_reset(RoomMatrix *m)
{
RoomSpace *space;
int i, j;
for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
space = &m->spaces[i][j];
space->occupied = false;
space->lethal = false;
space->lightsource = false;
space->light = 0;
space->monster = NULL;
space->player = NULL;
while (space->items != NULL)
linkedlist_pop(&space->items);
}
}
m->roomPos = (Position) { 0, 0 };
m->playerRoomPos = (Position) { 1, 1 };
}
RoomMatrix* roommatrix_create(void)
{
int i, j;
@ -242,29 +265,6 @@ roommatrix_render_lightmap(RoomMatrix *matrix, Camera *cam)
}
}
void
roommatrix_reset(RoomMatrix *m)
{
RoomSpace *space;
int i, j;
for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
space = &m->spaces[i][j];
space->occupied = false;
space->lethal = false;
space->lightsource = false;
space->light = 0;
space->monster = NULL;
space->player = NULL;
while (space->items != NULL)
linkedlist_pop(&space->items);
}
}
m->roomPos = (Position) { 0, 0 };
m->playerRoomPos = (Position) { 1, 1 };
}
void roommatrix_destroy(RoomMatrix *m)
{
// Clear the list but don't destroy the items

View File

@ -26,7 +26,7 @@
#include "map_room_modifiers.h"
#include "input.h"
typedef struct Sprite_t Sprite;
typedef struct Sprite Sprite;
typedef struct Map_t Map;
typedef struct Monster_t Monster;
typedef struct Player_t Player;
@ -67,8 +67,6 @@ void roommatrix_render_mouse_square(RoomMatrix*, Camera*);
void roommatrix_render_lightmap(RoomMatrix*, Camera*);
void roommatrix_reset(RoomMatrix*);
void roommatrix_destroy(RoomMatrix*);
#endif // ROOMMATRIX_H_

View File

@ -32,19 +32,7 @@
#include "projectile.h"
#include "linkedlist.h"
#include "item.h"
static void
set_player_clip_for_direction(Player *player, Vector2d *direction)
{
if (direction->y > 0) // Down
player->sprite->clip.y = 0;
else if (direction->y < 0) // Up
player->sprite->clip.y = 48;
else if (direction->x < 0) // Left
player->sprite->clip.y = 16;
else if (direction->x > 0) // Right
player->sprite->clip.y = 32;
}
#include "animation.h"
static Skill *
create_default(const char *s_label, Sprite *s)
@ -73,12 +61,13 @@ skill_use_flurry(Skill *skill, SkillData *data)
targetPos.x += (int) data->direction.x;
targetPos.y += (int) data->direction.y;
set_player_clip_for_direction(data->player, &data->direction);
player_turn(data->player, &data->direction);
if (!position_in_roommatrix(&targetPos)) {
return false;
}
animation_run(data->player->swordAnimation);
Monster *monster = data->matrix->spaces[targetPos.x][targetPos.y].monster;
mixer_play_effect(TRIPPLE_SWING);
if (monster) {
@ -160,7 +149,7 @@ skill_throw_dagger(Skill *skill, SkillData *data)
p->sprite->angle = -270;
}
set_player_clip_for_direction(data->player, &data->direction);
player_turn(data->player, &data->direction);
mixer_play_effect(SWOOSH);
p->sprite->pos = data->player->sprite->pos;
@ -263,7 +252,7 @@ skill_charge(Skill *skill, SkillData *data)
player->sprite->pos.x += (steps * TILE_DIMENSION) * (int) data->direction.x;
player->sprite->pos.y += (steps * TILE_DIMENSION) * (int) data->direction.y;
Position playerDestinationPos = player->sprite->pos;
set_player_clip_for_direction(data->player, &data->direction);
player_turn(data->player, &data->direction);
// Add motion particles
bool horizontal = data->direction.x != 0;
@ -294,6 +283,7 @@ skill_charge(Skill *skill, SkillData *data)
data->player->stat_data.hits += 1;
}
monster_hit(monster, dmg);
player_monster_kill_check(data->player, monster);
}
return true;

View File

@ -222,6 +222,10 @@ render_skill_sparkles(SkillBar *bar, Player *player)
return;
}
if (player->stats.lvl == 1) {
return;
}
Position pos = { 0, GAME_VIEW_HEIGHT };
Dimension dim = { 32, 32 };
for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) {

View File

@ -51,7 +51,7 @@ sprite_create(void)
void
sprite_load_texture(Sprite *sprite,
char *path,
const char *path,
int index,
SDL_Renderer *renderer)
{
@ -68,7 +68,7 @@ sprite_load_texture(Sprite *sprite,
sprite->destroyTextures = true;
}
void sprite_load_text_texture(Sprite *sprite, char * path, int index, int size, int outline)
void sprite_load_text_texture(Sprite *sprite, const char * path, int index, int size, int outline)
{
if (index > 1)
fatal("in sprite_load_texture() index out of bounds");
@ -122,7 +122,7 @@ sprite_render(Sprite *s, Camera *cam)
cameraPos.x, cameraPos.y, s->dim.width, s->dim.height
};
if ((s->clip.w && s->clip.h) || s->angle != 0 || s->flip != SDL_FLIP_NONE) {
if (s->angle != 0 || s->flip != SDL_FLIP_NONE) {
texture_render_clip_ex(s->textures[s->texture_index],
&box,
&s->clip,

View File

@ -27,7 +27,7 @@
#include "roommatrix.h"
#include "timer.h"
typedef struct Sprite_t {
typedef struct Sprite {
Texture* textures[2];
SDL_Rect clip;
bool destroyTextures;
@ -46,9 +46,9 @@ typedef struct Sprite_t {
Sprite* sprite_create(void);
void sprite_load_texture(Sprite *, char *path, int index, SDL_Renderer *);
void sprite_load_texture(Sprite *, const char *path, int index, SDL_Renderer *);
void sprite_load_text_texture(Sprite *, char *path, int index, int size, int outline);
void sprite_load_text_texture(Sprite *, const char *path, int index, int size, int outline);
void sprite_set_texture(Sprite *, Texture *, int index);

View File

@ -21,7 +21,7 @@
#include <stdbool.h>
typedef struct {
typedef struct Timer {
unsigned int startTime;
} Timer;