From 94363a2e95554a848edcfcefef2a6163b07b70b6 Mon Sep 17 00:00:00 2001 From: Linus_Probert Date: Tue, 20 Feb 2018 14:22:26 +0100 Subject: [PATCH] Added monster stats generation to lua. --- data/monstergen.lua | 168 +++++++++++++++++++++++++++++++------------- src/map_lua.c | 50 +++++++++++-- src/monster.c | 12 +++- src/player.c | 13 ++-- src/stats.c | 14 +++- 5 files changed, 194 insertions(+), 63 deletions(-) diff --git a/data/monstergen.lua b/data/monstergen.lua index 8a5744a..29b1e7f 100644 --- a/data/monstergen.lua +++ b/data/monstergen.lua @@ -43,41 +43,79 @@ local state = { scared = 2, } +local stats = { + default = { + hp = 12, + dmg = 2, + atk = 0, + def = 0, + speed = 1 + }, + pest = { + hp = 6, + dmg = 1, + atk = 0, + def = 0, + speed = 1 + }, + dog = { + hp = 12, + dmg = 2, + atk = 0, + def = 0, + speed = 1 + }, + undead = { + hp = 24, + dmg = 1, + atk = 0, + def = 0, + speed = 1 + }, + platino = { + hp = 60, + dmg = 60, + atk = 60, + def = 60, + speed = 3 + } +} + local pests = { -- PESTS - { texturePaths.pest0, texturePaths.pest1, 0, 0, "A Beetle" }, - { texturePaths.pest0, texturePaths.pest1, 16, 0, "A Beetle" }, - { texturePaths.pest0, texturePaths.pest1, 32, 0, "A Beetle" }, - { texturePaths.pest0, texturePaths.pest1, 48, 0, "A Beetle" }, - { texturePaths.pest0, texturePaths.pest1, 64, 0, "A Large Grub" }, - { texturePaths.pest0, texturePaths.pest1, 80, 0, "A Small Grub" }, - { texturePaths.pest0, texturePaths.pest1, 96, 0, "A Slim Worm" }, - { texturePaths.pest0, texturePaths.pest1, 112, 0, "A Fat Worm" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 0, 0, "A Beetle" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 16, 0, "A Beetle" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 32, 0, "A Beetle" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 48, 0, "A Beetle" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 64, 0, "A Large Grub" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 80, 0, "A Small Grub" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 96, 0, "A Slim Worm" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 112, 0, "A Fat Worm" }, --{ texturePaths.pest0, texturePaths.pest1, 0, 16, "Female Dragonfly" }, - { texturePaths.pest0, texturePaths.pest1, 16, 16, "A Fly" }, - { texturePaths.pest0, texturePaths.pest1, 32, 16, "A Larva" }, - { texturePaths.pest0, texturePaths.pest1, 48, 16, "A Moth" }, - --{ texturePaths.pest0, texturePaths.pest1, 64, 16 }, - { texturePaths.pest0, texturePaths.pest1, 80, 16, "A Gnat" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 16, 16, "A Fly" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 32, 16, "A Larva" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 48, 16, "A Moth" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 64, 16 }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 80, 16, "A Gnat" }, - { texturePaths.pest0, texturePaths.pest1, 0, 32, "A Small Spider" }, - { texturePaths.pest0, texturePaths.pest1, 16, 32, "A Medium Spider" }, - { texturePaths.pest0, texturePaths.pest1, 32, 32, "A Large Spider" }, - { texturePaths.pest0, texturePaths.pest1, 48, 32, "A Small Scorpion" }, - { texturePaths.pest0, texturePaths.pest1, 64, 32, "A Medium Scorpion" }, - { texturePaths.pest0, texturePaths.pest1, 80, 32, "A Large Scorpion" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 0, 32, "A Small Spider" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 16, 32, "A Medium Spider" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 32, 32, "A Large Spider" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 48, 32, "A Small Scorpion" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 64, 32, "A Medium Scorpion" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 80, 32, "A Large Scorpion" }, - { texturePaths.pest0, texturePaths.pest1, 0, 48, "A Slug" }, - { texturePaths.pest0, texturePaths.pest1, 16, 48, "A Large Slug" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 0, 48, "A Slug" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 16, 48, "A Large Slug" }, --{ texturePaths.pest0, texturePaths.pest1, 32, 48 }, - { texturePaths.pest0, texturePaths.pest1, 48, 48, "A Red Slug" }, - { texturePaths.pest0, texturePaths.pest1, 64, 48, "A Large Red Slug" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 48, 48, "A Red Slug" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 64, 48, "A Large Red Slug" }, - { texturePaths.pest0, texturePaths.pest1, 0, 64, "A Giant Brown Ant" }, - { texturePaths.pest0, texturePaths.pest1, 16, 64, "A Giant Black Ant" }, - { texturePaths.pest0, texturePaths.pest1, 32, 64, "A Giant Gold Ant" }, - { texturePaths.pest0, texturePaths.pest1, 48, 64, "A Giant Silver Ant" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 0, 64, "A Giant Brown Ant" }, + { texturePaths.pest0, texturePaths.pest1, stats.pest, 16, 64, "A Giant Black Ant" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 32, 64, "A Giant Gold Ant" }, + --{ texturePaths.pest0, texturePaths.pest1, stats.pest, 48, 64, "A Giant Silver Ant" }, --{ texturePaths.pest0, texturePaths.pest1, 0, 80 }, --{ texturePaths.pest0, texturePaths.pest1, 16, 80 }, @@ -114,25 +152,43 @@ local undead = { --{ texturePaths.undead0, texturePaths.undead1, 96, 16, "", state.passive, state.agressive }; --{ texturePaths.undead0, texturePaths.undead1, 112, 16, "", state.passive, state.agressive }; - { texturePaths.undead0, texturePaths.undead1, 0, 32, "A Skeleton", state.passive, state.agressive }; - { texturePaths.undead0, texturePaths.undead1, 16, 32, "An Umber Skeleton", state.passive, state.agressive }; - { texturePaths.undead0, texturePaths.undead1, 32, 32, "A Caustic Skeleton", state.passive, state.agressive }; - { texturePaths.undead0, texturePaths.undead1, 48, 32, "A Black Skeleton", state.passive, state.agressive }; - --{ texturePaths.undead0, texturePaths.undead1, 64, 32, "", state.passive, state.agressive }; - --{ texturePaths.undead0, texturePaths.undead1, 80, 32, "", state.passive, state.agressive }; + { texturePaths.undead0, texturePaths.undead1, stats.undead, 0, 32, "A Skeleton", state.passive, state.agressive }; + --{ texturePaths.undead0, texturePaths.undead1, 16, 32, "An Umber Skeleton", state.passive, state.agressive }; + --{ texturePaths.undead0, texturePaths.undead1, 32, 32, "A Caustic Skeleton", state.passive, state.agressive }; + { texturePaths.undead0, texturePaths.undead1, stats.undead, 48, 32, "A Black Skeleton", state.passive, state.agressive }; + { texturePaths.undead0, texturePaths.undead1, stats.undead, 64, 32, "A Zombie", state.passive, state.agressive }; + { texturePaths.undead0, texturePaths.undead1, stats.undead, 80, 32, "A Zombie", state.passive, state.agressive }; --{ texturePaths.undead0, texturePaths.undead1, 96, 32, "", state.passive, state.agressive }; --{ texturePaths.undead0, texturePaths.undead1, 112, 32, "", state.passive, state.scared }; } +local dogs = { + { texturePaths.dog0, texturePaths.dog1, stats.dog, 0, 16, "A Rabid Dog", state.passive, state.agressive }; + { texturePaths.dog0, texturePaths.dog1, stats.dog, 0, 16, "An Angry Rabid Dog", state.agressive, state.agressive }; +} + +local reptile = { + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 0, 64, "A Small Brown Snake", state.passive, state.agressive }; + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 16, 64, "A Medium Brown Snake", state.passive, state.agressive }; + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 32, 64, "A Large Brown Snake", state.passive, state.agressive }; + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 48, 64, "A Small Black Snake", state.agressive, state.agressive }; + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 64, 64, "A Medium Black Snake", state.agressive, state.agressive }; + { texturePaths.reptile0, texturePaths.reptile1, stats.default, 80, 64, "A Large Black Snake", state.agressive, state.agressive }; +} + +local platino = { + { texturePaths.reptile0, texturePaths.reptile1, stats.platino, 48, 12*16, "Platino", state.agressive, state.agressive }; +} + local demon = { - { texturePaths.demon0, texturePaths.demon1, 0, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 16, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 32, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 48, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 64, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 80, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 96, 0, "A Demon", state.agressive, state.agressive }; - { texturePaths.demon0, texturePaths.demon1, 112, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 0, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 16, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 32, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 48, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 64, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 80, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 96, 0, "A Demon", state.agressive, state.agressive }; + { texturePaths.demon0, texturePaths.demon1, stats.default, 112, 0, "A Demon", state.agressive, state.agressive }; } local function concat(table1, table2) @@ -146,11 +202,12 @@ local function repack(data) return { texturePath1 = data[1], texturePath2 = data[2], - clipX = data[3], - clipY = data[4], - label = data[5] or "", - nstate = data[6] or state.passive, - cstate = data[7] or state.scared, + stats = data[3], + clipX = data[4], + clipY = data[5], + label = data[6] or "", + nstate = data[7] or state.passive, + cstate = data[8] or state.scared, } end @@ -159,17 +216,34 @@ local enemies = {} if(CURRENT_LEVEL > 0 and CURRENT_LEVEL < 10) then if (CURRENT_LEVEL == 1) then enemies = concat(enemies, pests) + enemies = concat(enemies, dogs) + elseif (CURRENT_LEVEL > 5) then + enemies = {} + enemies = concat(enemies, demon) enemies = concat(enemies, undead) + enemies = concat(enemies, reptile) + elseif (CURRENT_LEVEL > 3) then + enemies = {} + enemies = concat(enemies, undead) + enemies = concat(enemies, reptile) + enemies = concat(enemies, dogs) elseif (CURRENT_LEVEL > 2) then enemies = {} enemies = concat(enemies, undead) - enemies = concat(enemies, demon) + enemies = concat(enemies, reptile) + enemies = concat(enemies, dogs) elseif (CURRENT_LEVEL > 1) then enemies = {} enemies = concat(enemies, undead) + enemies = concat(enemies, reptile) + enemies = concat(enemies, dogs) end end +if random(100) == 1 then + enemies = concat(enemies, platino); +end + function module.add_monster_to_room(map, roomx, roomy) local count = random(3) for i=0,count do diff --git a/src/map_lua.c b/src/map_lua.c index abe5d06..0043120 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -27,6 +27,7 @@ #include "map_lua.h" #include "util.h" +#include "stats.h" static lua_State* load_lua_state(void) @@ -150,7 +151,7 @@ extract_tile_data(lua_State *L, levelExit = lua_toboolean(L, -1); // Clear the stack - lua_pop(L, 6); + lua_pop(L, 7); Position tilePos = (Position) { tile_x, tile_y }; SDL_Rect clip = (SDL_Rect) { tile_clip_x, tile_clip_y, 16, 16 }; @@ -166,6 +167,40 @@ extract_tile_data(lua_State *L, f_add_tile(map, &tilePos, tile); } +static Stats +lua_checkstats(lua_State *L, int index) +{ + debug("Reading stats: %d", index); + + // Confirm table + luaL_checktype(L, index, LUA_TTABLE); + + // Push to top of stack + lua_pushvalue(L, index); + // Stack: -1 => table + + int tableIndex = lua_gettop(L); + debug("Table index: %d", tableIndex); + + lua_getfield(L, tableIndex, "hp"); + lua_getfield(L, tableIndex, "dmg"); + lua_getfield(L, tableIndex, "atk"); + lua_getfield(L, tableIndex, "def"); + lua_getfield(L, tableIndex, "speed"); + + int hp = luaL_checkinteger(L, -5); + int dmg = luaL_checkinteger(L, -4); + int atk = luaL_checkinteger(L, -3); + int def = luaL_checkinteger(L, -2); + int speed = luaL_checkinteger(L, -1); + + // Reset the stack + lua_pop(L, 6); + + Stats stats = { hp, hp, dmg, atk, def, speed, 1 }; + return stats; +} + static int l_tile_occupied(lua_State *L) { @@ -217,6 +252,7 @@ l_add_monster(lua_State *L) char *label; Texture *texture1, *texture2; SDL_Renderer *renderer; + Stats stats; renderer = luaL_checksdlrenderer(L); map = luaL_checkmap(L, 1); @@ -230,14 +266,16 @@ l_add_monster(lua_State *L) lua_getfield(L, 4, "label"); lua_getfield(L, 4, "texturePath1"); lua_getfield(L, 4, "texturePath2"); + lua_getfield(L, 4, "stats"); lua_getfield(L, 4, "clipX"); lua_getfield(L, 4, "clipY"); lua_getfield(L, 4, "nstate"); lua_getfield(L, 4, "cstate"); - tmp_label = luaL_checkstring(L, -7); - texture_path_1 = luaL_checkstring(L, -6); - texture_path_2 = luaL_checkstring(L, -5); + tmp_label = luaL_checkstring(L, -8); + texture_path_1 = luaL_checkstring(L, -7); + texture_path_2 = luaL_checkstring(L, -6); + stats = lua_checkstats(L, -5); clip_x = (int) luaL_checkinteger(L, -4); clip_y = (int) luaL_checkinteger(L, -3); nstate = (int) luaL_checkinteger(L, -2); @@ -251,7 +289,7 @@ l_add_monster(lua_State *L) texture1->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; texture2->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; - lua_pop(L, 6); + lua_pop(L, 8); monster = monster_create(renderer); monster->sprite->clip = (SDL_Rect) { clip_x, clip_y, 16, 16 }; @@ -266,6 +304,8 @@ l_add_monster(lua_State *L) monster->lclabel = to_lower(label); } + monster->stats = stats; + map_add_monster(map, monster); return 0; diff --git a/src/monster.c b/src/monster.c index b9007d7..58953f3 100644 --- a/src/monster.c +++ b/src/monster.c @@ -54,7 +54,17 @@ monster_create(SDL_Renderer *renderer) Monster *m = ec_malloc(sizeof(Monster)); m->sprite = sprite_create(); m->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; - m->stats = (Stats) { 12, 12, 1, 0, 0, 1, 1 }; + + m->stats = (Stats) { + 12, // Max HP + 12, // hp + 2, // dmg + 0, // atk + 0, // def + 1, // speed + 1 // lvl + }; + m->state.normal = PASSIVE; m->state.challenge = AGRESSIVE; m->state.current = m->state.normal; diff --git a/src/player.c b/src/player.c index 7673f35..2e3a058 100644 --- a/src/player.c +++ b/src/player.c @@ -30,11 +30,11 @@ #include "mixer.h" #include "random.h" -#define ENGINEER_STATS { 12, 12, 5, 7, 2, 1, 1 } -#define MAGE_STATS { 12, 12, 5, 7, 2, 1, 1 } -#define PALADIN_STATS { 12, 12, 8, 9, 2, 1, 1 } -#define ROGUE_STATS { 12, 12, 5, 7, 3, 2, 1 } -#define WARRIOR_STATS { 12, 12, 8, 9, 2, 1, 1 } +#define ENGINEER_STATS { 12, 12, 5, 7, 2, 2, 1 } +#define MAGE_STATS { 12, 12, 5, 7, 1, 2, 1 } +#define PALADIN_STATS { 12, 12, 8, 9, 3, 1, 1 } +#define ROGUE_STATS { 12, 12, 5, 7, 1, 2, 1 } +#define WARRIOR_STATS { 12, 12, 8, 9, 3, 1, 1 } static void player_levelup(Player *player) @@ -42,10 +42,9 @@ player_levelup(Player *player) mixer_play_effect(LEVEL_UP); player->stats.lvl += 1; - player->stats.maxhp += 3; + player->stats.maxhp += 9; player->stats.dmg += 5; player->stats.atk += 1; - player->stats.def += 1; // Limit health to 3 rows of hearts if (player->stats.maxhp > 72) diff --git a/src/stats.c b/src/stats.c index 6260b97..f52b1c0 100644 --- a/src/stats.c +++ b/src/stats.c @@ -21,6 +21,7 @@ #include #include +#include "gui.h" #include "stats.h" #include "random.h" #include "util.h" @@ -42,10 +43,17 @@ stats_fight(Stats *attacker, Stats *defender) debug("-----------[ FIGHT ]---------"); debug("Attacking: %d Defending: %d", atkRoll, defRoll); - if (atkRoll > defRoll) { - dmgRoll = get_random(attacker->dmg - 1) + 1; - if (critical) + if (atkRoll >= defRoll) { + if (attacker->dmg > 0) + dmgRoll = get_random(attacker->dmg) + 1; + else + dmgRoll = get_random(attacker->dmg - 1) + 1; + + if (critical) { dmgRoll = dmgRoll * 2; + gui_log("You have scored a critical hit"); + } + defender->hp -= dmgRoll; }