Began #2: Added artifacts and the PIERCING_DAGGERS modifier
Still need to add the rest of the artifact effects but that should be simpler from this point.
This commit is contained in:
parent
611d8ef4d6
commit
095c93e5b2
|
@ -173,6 +173,7 @@ add_executable(breakhack
|
||||||
src/actiontextbuilder
|
src/actiontextbuilder
|
||||||
src/animation
|
src/animation
|
||||||
src/trap
|
src/trap
|
||||||
|
src/artifact
|
||||||
)
|
)
|
||||||
|
|
||||||
# Sqlite has some warnings that I we don't need to see
|
# Sqlite has some warnings that I we don't need to see
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* 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 "artifact.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "texturecache.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
artifact_set_effect(Artifact *a, MagicalEffect effect)
|
||||||
|
{
|
||||||
|
a->effect = effect;
|
||||||
|
switch (effect) {
|
||||||
|
case IMPROVED_HEARING:
|
||||||
|
a->info.name = "Potion of ear juice";
|
||||||
|
a->info.desc = "Your hearing is slightly improved";
|
||||||
|
break;
|
||||||
|
case TRAP_AVOIDANCE:
|
||||||
|
a->info.name = "Boot with nails inside";
|
||||||
|
a->info.desc = "You are lighter on your feet";
|
||||||
|
break;
|
||||||
|
case PIERCING_DAGGERS:
|
||||||
|
a->info.name = "Whetstone";
|
||||||
|
a->info.desc = "Your daggers are sharper";
|
||||||
|
Texture *t = texturecache_add("Items/Rock.png");
|
||||||
|
sprite_set_texture(a->sprite, t, 0);
|
||||||
|
a->sprite->clip = CLIP16(0, 0);
|
||||||
|
break;
|
||||||
|
case CHARGE_THROUGH:
|
||||||
|
a->info.name = "Greasy shield";
|
||||||
|
a->info.desc = "You glide through obstructions";
|
||||||
|
break;
|
||||||
|
case PUSH_BACK:
|
||||||
|
a->info.name = "Glove of strength";
|
||||||
|
a->info.desc = "Your arm is stronger";
|
||||||
|
break;
|
||||||
|
case DAGGER_RECOVERY:
|
||||||
|
a->info.name = "Forging hammer";
|
||||||
|
a->info.desc = "Your daggers are more durable";
|
||||||
|
break;
|
||||||
|
case INCREASED_STUN:
|
||||||
|
a->info.name = "Solid shield";
|
||||||
|
a->info.desc = "Your shield is harder";
|
||||||
|
break;
|
||||||
|
case FEAR_INDUCING:
|
||||||
|
a->info.name = "Ugly shirt";
|
||||||
|
a->info.desc = "You look disgusting";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Artifact *
|
||||||
|
artifact_create(MagicalEffect effect)
|
||||||
|
{
|
||||||
|
Artifact *a = ec_malloc(sizeof(Artifact));
|
||||||
|
a->sprite = sprite_create();
|
||||||
|
a->sprite->dim = GAME_DIMENSION;
|
||||||
|
a->collected = false;
|
||||||
|
a->level = 1;
|
||||||
|
artifact_set_effect(a, effect);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Artifact *
|
||||||
|
artifact_copy(Artifact *a)
|
||||||
|
{
|
||||||
|
Artifact *new = ec_malloc(sizeof(Artifact));
|
||||||
|
*new = *a;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
artifact_render(Artifact *a, Camera *cam)
|
||||||
|
{
|
||||||
|
sprite_render(a->sprite, cam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
artifact_destroy(Artifact *a)
|
||||||
|
{
|
||||||
|
sprite_destroy(a->sprite);
|
||||||
|
free(a);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sprite.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
typedef enum MagicalEffect {
|
||||||
|
IMPROVED_HEARING,
|
||||||
|
TRAP_AVOIDANCE,
|
||||||
|
PIERCING_DAGGERS,
|
||||||
|
CHARGE_THROUGH,
|
||||||
|
PUSH_BACK,
|
||||||
|
DAGGER_RECOVERY,
|
||||||
|
INCREASED_STUN,
|
||||||
|
FEAR_INDUCING,
|
||||||
|
LAST_ARTIFACT_EFFECT // Sentinel
|
||||||
|
} MagicalEffect;
|
||||||
|
|
||||||
|
typedef struct ArtifactInfo {
|
||||||
|
const char *name;
|
||||||
|
const char *desc;
|
||||||
|
} ArtifactInfo;
|
||||||
|
|
||||||
|
typedef struct Artifact {
|
||||||
|
Sprite *sprite;
|
||||||
|
MagicalEffect effect;
|
||||||
|
ArtifactInfo info;
|
||||||
|
bool collected;
|
||||||
|
int level;
|
||||||
|
} Artifact;
|
||||||
|
|
||||||
|
Artifact *
|
||||||
|
artifact_create(MagicalEffect);
|
||||||
|
|
||||||
|
Artifact *
|
||||||
|
artifact_copy(Artifact*);
|
||||||
|
|
||||||
|
void
|
||||||
|
artifact_render(Artifact*, Camera*);
|
||||||
|
|
||||||
|
void
|
||||||
|
artifact_destroy(Artifact*);
|
|
@ -494,6 +494,7 @@ run_game_update(void)
|
||||||
|
|
||||||
map_clear_dead_monsters(gMap, gPlayer);
|
map_clear_dead_monsters(gMap, gPlayer);
|
||||||
map_clear_collected_items(gMap);
|
map_clear_collected_items(gMap);
|
||||||
|
map_clear_collected_artifacts(gMap);
|
||||||
|
|
||||||
populateUpdateData(&updateData, deltaTime);
|
populateUpdateData(&updateData, deltaTime);
|
||||||
if (playerLevel != gPlayer->stats.lvl) {
|
if (playerLevel != gPlayer->stats.lvl) {
|
||||||
|
|
27
src/map.c
27
src/map.c
|
@ -54,6 +54,7 @@ map_create(void)
|
||||||
map->textures = linkedlist_create();
|
map->textures = linkedlist_create();
|
||||||
map->monsters = linkedlist_create();
|
map->monsters = linkedlist_create();
|
||||||
map->items = linkedlist_create();
|
map->items = linkedlist_create();
|
||||||
|
map->artifacts = linkedlist_create();
|
||||||
map->currentRoom = (Position) { 0, 0 };
|
map->currentRoom = (Position) { 0, 0 };
|
||||||
map->renderTimer = timer_create();
|
map->renderTimer = timer_create();
|
||||||
map->monsterMoveTimer = timer_create();
|
map->monsterMoveTimer = timer_create();
|
||||||
|
@ -158,6 +159,20 @@ map_clear_collected_items(Map *map)
|
||||||
map->items = filtered;
|
map->items = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
map_clear_collected_artifacts(Map *map)
|
||||||
|
{
|
||||||
|
LinkedList *filtered = linkedlist_create();
|
||||||
|
while (map->artifacts) {
|
||||||
|
Artifact *a = linkedlist_pop(&map->artifacts);
|
||||||
|
if (!a->collected)
|
||||||
|
linkedlist_append(&filtered, a);
|
||||||
|
else
|
||||||
|
artifact_destroy(a);
|
||||||
|
}
|
||||||
|
map->artifacts = filtered;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
map_add_monster(Map *map, Monster *m)
|
map_add_monster(Map *map, Monster *m)
|
||||||
{
|
{
|
||||||
|
@ -305,9 +320,14 @@ map_render_top_layer(Map *map, Camera *cam)
|
||||||
|
|
||||||
LinkedList *items = map->items;
|
LinkedList *items = map->items;
|
||||||
while (items != NULL) {
|
while (items != NULL) {
|
||||||
Item *item = items->data;
|
item_render(items->data, cam);
|
||||||
items = items->next;
|
items = items->next;
|
||||||
item_render(item, cam);
|
}
|
||||||
|
|
||||||
|
LinkedList *artifacts = map->artifacts;
|
||||||
|
while (artifacts != NULL) {
|
||||||
|
artifact_render(artifacts->data, cam);
|
||||||
|
artifacts = artifacts->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +396,9 @@ void map_destroy(Map *map)
|
||||||
while (map->items != NULL)
|
while (map->items != NULL)
|
||||||
item_destroy(linkedlist_pop(&map->items));
|
item_destroy(linkedlist_pop(&map->items));
|
||||||
|
|
||||||
|
while (map->artifacts != NULL)
|
||||||
|
artifact_destroy(linkedlist_pop(&map->artifacts));
|
||||||
|
|
||||||
timer_destroy(map->renderTimer);
|
timer_destroy(map->renderTimer);
|
||||||
timer_destroy(map->monsterMoveTimer);
|
timer_destroy(map->monsterMoveTimer);
|
||||||
free(map);
|
free(map);
|
||||||
|
|
|
@ -57,6 +57,7 @@ typedef struct Map_t {
|
||||||
LinkedList *textures;
|
LinkedList *textures;
|
||||||
LinkedList *monsters;
|
LinkedList *monsters;
|
||||||
LinkedList *items;
|
LinkedList *items;
|
||||||
|
LinkedList *artifacts;
|
||||||
Position currentRoom;
|
Position currentRoom;
|
||||||
Timer *renderTimer;
|
Timer *renderTimer;
|
||||||
Timer *monsterMoveTimer;
|
Timer *monsterMoveTimer;
|
||||||
|
@ -93,6 +94,9 @@ map_clear_dead_monsters(Map*, Player*);
|
||||||
void
|
void
|
||||||
map_clear_collected_items(Map*);
|
map_clear_collected_items(Map*);
|
||||||
|
|
||||||
|
void
|
||||||
|
map_clear_collected_artifacts(Map*);
|
||||||
|
|
||||||
void
|
void
|
||||||
map_update(UpdateData*);
|
map_update(UpdateData*);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "vector2d.h"
|
#include "vector2d.h"
|
||||||
|
|
||||||
// Forward declares
|
// Forward declares
|
||||||
typedef struct Player_t Player;
|
typedef struct Player Player;
|
||||||
typedef struct RoomMatrix_t RoomMatrix;
|
typedef struct RoomMatrix_t RoomMatrix;
|
||||||
|
|
||||||
typedef enum RoomModifierType_e {
|
typedef enum RoomModifierType_e {
|
||||||
|
|
|
@ -493,8 +493,8 @@ void
|
||||||
monster_drop_loot(Monster *monster, Map *map, Player *player)
|
monster_drop_loot(Monster *monster, Map *map, Player *player)
|
||||||
{
|
{
|
||||||
static unsigned int treasure_drop_chance = 1;
|
static unsigned int treasure_drop_chance = 1;
|
||||||
|
|
||||||
unsigned int item_drop_chance = 1;
|
unsigned int item_drop_chance = 1;
|
||||||
|
|
||||||
Item *item;
|
Item *item;
|
||||||
Item *items[3];
|
Item *items[3];
|
||||||
unsigned int item_count = 0;
|
unsigned int item_count = 0;
|
||||||
|
@ -537,6 +537,10 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
|
||||||
}
|
}
|
||||||
linkedlist_append(&map->items, container);
|
linkedlist_append(&map->items, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Artifact *a = artifact_create(PIERCING_DAGGERS);
|
||||||
|
a->sprite->pos = monster->sprite->pos;
|
||||||
|
linkedlist_append(&map->artifacts, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
54
src/player.c
54
src/player.c
|
@ -165,6 +165,14 @@ has_collided(Player *player, RoomMatrix *matrix, Vector2d direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (space->artifacts != NULL && !collided) {
|
||||||
|
LinkedList *artifacts = space->artifacts;
|
||||||
|
while (artifacts) {
|
||||||
|
player_add_artifact(player, artifacts->data);
|
||||||
|
artifacts = artifacts->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (space->lethal && !collided) {
|
if (space->lethal && !collided) {
|
||||||
mixer_play_effect(FALL0 + get_random(2) - 1);
|
mixer_play_effect(FALL0 + get_random(2) - 1);
|
||||||
player->state = FALLING;
|
player->state = FALLING;
|
||||||
|
@ -407,9 +415,11 @@ player_create(class_t class, SDL_Renderer *renderer)
|
||||||
|
|
||||||
build_sword_animation(player, renderer);
|
build_sword_animation(player, renderer);
|
||||||
|
|
||||||
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
|
memset(&player->skills,
|
||||||
player->skills[i] = NULL;
|
0, PLAYER_SKILL_COUNT * sizeof(Skill*));
|
||||||
}
|
|
||||||
|
for (size_t i = 0; i < LAST_ARTIFACT_EFFECT; ++i)
|
||||||
|
player->equipment.artifacts[i].level = 0;
|
||||||
|
|
||||||
char asset[100];
|
char asset[100];
|
||||||
switch (class) {
|
switch (class) {
|
||||||
|
@ -571,9 +581,21 @@ void player_update(UpdateData *data)
|
||||||
animation_update(player->swordAnimation);
|
animation_update(player->swordAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
player_reset(Player *player)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < LAST_ARTIFACT_EFFECT; ++i)
|
||||||
|
player->equipment.artifacts[i].level = 0;
|
||||||
|
|
||||||
|
while (player->projectiles)
|
||||||
|
projectile_destroy(linkedlist_pop(&player->projectiles));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
player_destroy(Player *player)
|
player_destroy(Player *player)
|
||||||
{
|
{
|
||||||
|
player_reset(player);
|
||||||
|
|
||||||
if (player->sprite)
|
if (player->sprite)
|
||||||
sprite_destroy(player->sprite);
|
sprite_destroy(player->sprite);
|
||||||
|
|
||||||
|
@ -586,9 +608,6 @@ player_destroy(Player *player)
|
||||||
player->skills[i] = NULL;
|
player->skills[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (player->projectiles)
|
|
||||||
projectile_destroy(linkedlist_pop(&player->projectiles));
|
|
||||||
|
|
||||||
free(player);
|
free(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,3 +616,26 @@ player_turn_over(Player *player)
|
||||||
{
|
{
|
||||||
return player->stat_data.steps >= player->stats.speed;
|
return player->stat_data.steps >= player->stats.speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uint32
|
||||||
|
player_has_artifact(Player *p, MagicalEffect effect)
|
||||||
|
{
|
||||||
|
return p->equipment.artifacts[effect].level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
player_add_artifact(Player *p, Artifact *a)
|
||||||
|
{
|
||||||
|
if (a->collected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
a->collected = true;
|
||||||
|
|
||||||
|
ArtifactData *ad = &p->equipment.artifacts[a->effect];
|
||||||
|
ad->name = a->info.name;
|
||||||
|
ad->desc = a->info.desc;
|
||||||
|
ad->level += a->level;
|
||||||
|
|
||||||
|
gui_log("You pick an ancient %s", ad->name);
|
||||||
|
gui_log("%s (%u)", ad->desc, ad->level);
|
||||||
|
}
|
||||||
|
|
28
src/player.h
28
src/player.h
|
@ -15,9 +15,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef PLAYER_H_
|
|
||||||
#define PLAYER_H_
|
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
|
@ -27,6 +25,7 @@
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "artifact.h"
|
||||||
|
|
||||||
#define PLAYER_SKILL_COUNT 5
|
#define PLAYER_SKILL_COUNT 5
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ typedef struct Animation Animation;
|
||||||
typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
|
typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
|
||||||
typedef enum PlayerState { ALIVE, DEAD, FALLING } state_t;
|
typedef enum PlayerState { ALIVE, DEAD, FALLING } state_t;
|
||||||
|
|
||||||
typedef struct PlayerStatData_t {
|
typedef struct PlayerStatData {
|
||||||
unsigned int total_steps;
|
unsigned int total_steps;
|
||||||
unsigned int steps;
|
unsigned int steps;
|
||||||
unsigned int hits;
|
unsigned int hits;
|
||||||
|
@ -45,14 +44,24 @@ typedef struct PlayerStatData_t {
|
||||||
unsigned int misses;
|
unsigned int misses;
|
||||||
} PlayerStatData;
|
} PlayerStatData;
|
||||||
|
|
||||||
typedef struct ExperienceData_t {
|
typedef struct ExperienceDatat {
|
||||||
unsigned int previousLevel;
|
unsigned int previousLevel;
|
||||||
unsigned int current;
|
unsigned int current;
|
||||||
unsigned int nextLevel;
|
unsigned int nextLevel;
|
||||||
unsigned int level;
|
unsigned int level;
|
||||||
} ExperienceData;
|
} ExperienceData;
|
||||||
|
|
||||||
typedef struct Player_t {
|
typedef struct ArtifactData {
|
||||||
|
const char *name;
|
||||||
|
const char *desc;
|
||||||
|
Uint32 level;
|
||||||
|
} ArtifactData;
|
||||||
|
|
||||||
|
typedef struct PlayerEquipment {
|
||||||
|
ArtifactData artifacts[LAST_ARTIFACT_EFFECT];
|
||||||
|
} PlayerEquipment;
|
||||||
|
|
||||||
|
typedef struct Player {
|
||||||
Sprite *sprite;
|
Sprite *sprite;
|
||||||
Stats stats;
|
Stats stats;
|
||||||
unsigned int daggers;
|
unsigned int daggers;
|
||||||
|
@ -66,6 +75,7 @@ typedef struct Player_t {
|
||||||
Skill *skills[PLAYER_SKILL_COUNT];
|
Skill *skills[PLAYER_SKILL_COUNT];
|
||||||
Timer *animationTimer;
|
Timer *animationTimer;
|
||||||
Animation *swordAnimation;
|
Animation *swordAnimation;
|
||||||
|
PlayerEquipment equipment;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
Player*
|
Player*
|
||||||
|
@ -104,4 +114,8 @@ player_destroy(Player*);
|
||||||
bool
|
bool
|
||||||
player_turn_over(Player*);
|
player_turn_over(Player*);
|
||||||
|
|
||||||
#endif // PLAYER_H_
|
Uint32
|
||||||
|
player_has_artifact(Player *, MagicalEffect);
|
||||||
|
|
||||||
|
void
|
||||||
|
player_add_artifact(Player*, Artifact*);
|
||||||
|
|
|
@ -47,6 +47,10 @@ projectile_dagger_create(void)
|
||||||
p->sprite->clip = CLIP16(0, 0);
|
p->sprite->clip = CLIP16(0, 0);
|
||||||
p->sprite->dim = (Dimension) { 32, 32 };
|
p->sprite->dim = (Dimension) { 32, 32 };
|
||||||
p->sprite->rotationPoint = (SDL_Point) { 16, 16 };
|
p->sprite->rotationPoint = (SDL_Point) { 16, 16 };
|
||||||
|
p->collisionCount = 0;
|
||||||
|
memset(&p->processedSpaces,
|
||||||
|
false,
|
||||||
|
sizeof(p->processedSpaces[0][0]) * MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +70,8 @@ projectile_create(void)
|
||||||
void
|
void
|
||||||
projectile_update(Projectile *p, UpdateData *data)
|
projectile_update(Projectile *p, UpdateData *data)
|
||||||
{
|
{
|
||||||
|
bool alive = false;
|
||||||
|
|
||||||
p->sprite->pos.x += (int) (p->velocity.x * data->deltatime);
|
p->sprite->pos.x += (int) (p->velocity.x * data->deltatime);
|
||||||
p->sprite->pos.y += (int) (p->velocity.y * data->deltatime);
|
p->sprite->pos.y += (int) (p->velocity.y * data->deltatime);
|
||||||
|
|
||||||
|
@ -78,7 +84,16 @@ projectile_update(Projectile *p, UpdateData *data)
|
||||||
if(p->velocity.y > 0)
|
if(p->velocity.y > 0)
|
||||||
collisionPos.y += TILE_DIMENSION;
|
collisionPos.y += TILE_DIMENSION;
|
||||||
|
|
||||||
|
if (!position_in_room(&collisionPos, &data->map->currentRoom)) {
|
||||||
|
p->alive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Position roomPos = position_to_matrix_coords(&collisionPos);
|
Position roomPos = position_to_matrix_coords(&collisionPos);
|
||||||
|
if (p->processedSpaces[roomPos.x][roomPos.y])
|
||||||
|
return;
|
||||||
|
p->processedSpaces[roomPos.x][roomPos.y] = true;
|
||||||
|
|
||||||
RoomSpace *space = &data->matrix->spaces[roomPos.x][roomPos.y];
|
RoomSpace *space = &data->matrix->spaces[roomPos.x][roomPos.y];
|
||||||
if (!space->occupied)
|
if (!space->occupied)
|
||||||
return;
|
return;
|
||||||
|
@ -94,16 +109,20 @@ projectile_update(Projectile *p, UpdateData *data)
|
||||||
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg);
|
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg);
|
||||||
data->player->stat_data.hits += 1;
|
data->player->stat_data.hits += 1;
|
||||||
}
|
}
|
||||||
if (get_random(2) >= 1) {
|
if (get_random(5) == 0
|
||||||
|
|| get_random(5) < player_has_artifact(data->player, DAGGER_RECOVERY)) {
|
||||||
Item *item = item_builder_build_item(DAGGER, 1);
|
Item *item = item_builder_build_item(DAGGER, 1);
|
||||||
item->sprite->pos = space->monster->sprite->pos;
|
item->sprite->pos = space->monster->sprite->pos;
|
||||||
linkedlist_append(&data->map->items, item);
|
linkedlist_append(&data->map->items, item);
|
||||||
}
|
}
|
||||||
monster_hit(space->monster, dmg);
|
monster_hit(space->monster, dmg);
|
||||||
player_monster_kill_check(data->player, space->monster);
|
player_monster_kill_check(data->player, space->monster);
|
||||||
|
|
||||||
|
alive = player_has_artifact(data->player, PIERCING_DAGGERS) > p->collisionCount;
|
||||||
}
|
}
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
p->alive = false;
|
p->alive = alive;
|
||||||
|
p->collisionCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -26,18 +26,18 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "roommatrix.h"
|
#include "roommatrix.h"
|
||||||
#include "update_data.h"
|
#include "update_data.h"
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
#define DAGGER_VELOCITY 500
|
#define DAGGER_VELOCITY 500
|
||||||
|
|
||||||
// Forward declare
|
typedef struct Projectile {
|
||||||
struct Player_t;
|
|
||||||
|
|
||||||
typedef struct Projectile_t {
|
|
||||||
Sprite *sprite;
|
Sprite *sprite;
|
||||||
Vector2d velocity;
|
Vector2d velocity;
|
||||||
Timer *lifetime;
|
Timer *lifetime;
|
||||||
bool alive;
|
bool alive;
|
||||||
void (*onRender)(struct Projectile_t*);
|
Uint32 collisionCount;
|
||||||
|
bool processedSpaces[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT];
|
||||||
|
void (*onRender)(struct Projectile*);
|
||||||
} Projectile;
|
} Projectile;
|
||||||
|
|
||||||
Projectile *
|
Projectile *
|
||||||
|
|
|
@ -46,6 +46,8 @@ roommatrix_reset(RoomMatrix *m)
|
||||||
space->trap = NULL;
|
space->trap = NULL;
|
||||||
while (space->items != NULL)
|
while (space->items != NULL)
|
||||||
linkedlist_pop(&space->items);
|
linkedlist_pop(&space->items);
|
||||||
|
while (space->artifacts != NULL)
|
||||||
|
linkedlist_pop(&space->artifacts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->roomPos = (Position) { 0, 0 };
|
m->roomPos = (Position) { 0, 0 };
|
||||||
|
@ -58,7 +60,8 @@ RoomMatrix* roommatrix_create(void)
|
||||||
RoomMatrix *m = ec_malloc(sizeof(RoomMatrix));
|
RoomMatrix *m = ec_malloc(sizeof(RoomMatrix));
|
||||||
for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
|
for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
|
||||||
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
|
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
|
||||||
m->spaces[i][j].items = NULL;
|
m->spaces[i][j].items = linkedlist_create();;
|
||||||
|
m->spaces[i][j].artifacts = linkedlist_create();;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
roommatrix_reset(m);
|
roommatrix_reset(m);
|
||||||
|
@ -97,7 +100,6 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
|
||||||
Monster *monster;
|
Monster *monster;
|
||||||
LinkedList *monsterItem;
|
LinkedList *monsterItem;
|
||||||
Item *item;
|
Item *item;
|
||||||
LinkedList *items;
|
|
||||||
|
|
||||||
roommatrix_reset(rm);
|
roommatrix_reset(rm);
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
|
||||||
.monster = monster;
|
.monster = monster;
|
||||||
}
|
}
|
||||||
|
|
||||||
items = m->items;
|
LinkedList *items = m->items;
|
||||||
while (items) {
|
while (items) {
|
||||||
item = items->data;
|
item = items->data;
|
||||||
items = items->next;
|
items = items->next;
|
||||||
|
@ -154,6 +156,18 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
|
||||||
position = position_to_matrix_coords(&item->sprite->pos);
|
position = position_to_matrix_coords(&item->sprite->pos);
|
||||||
linkedlist_push(&rm->spaces[position.x][position.y].items, item);
|
linkedlist_push(&rm->spaces[position.x][position.y].items, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkedList *artifacts = m->artifacts;
|
||||||
|
while (artifacts) {
|
||||||
|
Artifact *a = artifacts->data;
|
||||||
|
artifacts = artifacts->next;
|
||||||
|
|
||||||
|
if (!position_in_room(&a->sprite->pos, &m->currentRoom))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
position = position_to_matrix_coords(&a->sprite->pos);
|
||||||
|
linkedlist_push(&rm->spaces[position.x][position.y].artifacts, a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -259,6 +273,8 @@ void roommatrix_destroy(RoomMatrix *m)
|
||||||
RoomSpace *space = &m->spaces[i][j];
|
RoomSpace *space = &m->spaces[i][j];
|
||||||
while (space->items)
|
while (space->items)
|
||||||
linkedlist_pop(&space->items);
|
linkedlist_pop(&space->items);
|
||||||
|
while (space->artifacts)
|
||||||
|
linkedlist_pop(&space->artifacts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
typedef struct Sprite Sprite;
|
typedef struct Sprite Sprite;
|
||||||
typedef struct Map_t Map;
|
typedef struct Map_t Map;
|
||||||
typedef struct Monster_t Monster;
|
typedef struct Monster_t Monster;
|
||||||
typedef struct Player_t Player;
|
typedef struct Player Player;
|
||||||
typedef struct Item_t Item;
|
typedef struct Item_t Item;
|
||||||
typedef struct Node LinkedList;
|
typedef struct Node LinkedList;
|
||||||
typedef struct Trap Trap;
|
typedef struct Trap Trap;
|
||||||
|
@ -45,6 +45,7 @@ typedef struct {
|
||||||
Player *player;
|
Player *player;
|
||||||
Trap *trap;
|
Trap *trap;
|
||||||
LinkedList *items;
|
LinkedList *items;
|
||||||
|
LinkedList *artifacts;
|
||||||
} RoomSpace;
|
} RoomSpace;
|
||||||
|
|
||||||
typedef struct RoomMatrix_t {
|
typedef struct RoomMatrix_t {
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "animation.h"
|
#include "animation.h"
|
||||||
|
#include "artifact.h"
|
||||||
|
|
||||||
static Skill *
|
static Skill *
|
||||||
create_default(const char *s_label, Sprite *s)
|
create_default(const char *s_label, Sprite *s)
|
||||||
|
@ -298,6 +299,12 @@ skill_charge(Skill *skill, SkillData *data)
|
||||||
items = items->next;
|
items = items->next;
|
||||||
item_collected(item, player);
|
item_collected(item, player);
|
||||||
}
|
}
|
||||||
|
LinkedList *artifacts = space->artifacts;
|
||||||
|
while (artifacts != NULL) {
|
||||||
|
Artifact *artifact = artifacts->data;
|
||||||
|
artifacts = artifacts->next;
|
||||||
|
player_add_artifact(player, artifact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
space = &matrix->spaces[destination.x][destination.y];
|
space = &matrix->spaces[destination.x][destination.y];
|
||||||
steps++;
|
steps++;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "vector2d.h"
|
#include "vector2d.h"
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
struct Player_t;
|
struct Player;
|
||||||
|
|
||||||
enum SkillType {
|
enum SkillType {
|
||||||
FLURRY,
|
FLURRY,
|
||||||
|
@ -36,7 +36,7 @@ enum SkillType {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SkillData_t {
|
typedef struct SkillData_t {
|
||||||
struct Player_t *player;
|
struct Player *player;
|
||||||
RoomMatrix *matrix;
|
RoomMatrix *matrix;
|
||||||
Vector2d direction;
|
Vector2d direction;
|
||||||
} SkillData;
|
} SkillData;
|
||||||
|
|
18
src/sprite.h
18
src/sprite.h
|
@ -44,16 +44,22 @@ typedef struct Sprite {
|
||||||
void (*onRender)(Sprite*);
|
void (*onRender)(Sprite*);
|
||||||
} Sprite;
|
} Sprite;
|
||||||
|
|
||||||
Sprite* sprite_create(void);
|
Sprite*
|
||||||
|
sprite_create(void);
|
||||||
|
|
||||||
void sprite_load_texture(Sprite *, const char *path, int index, SDL_Renderer *);
|
void
|
||||||
|
sprite_load_texture(Sprite *, const char *path, int index, SDL_Renderer *);
|
||||||
|
|
||||||
void sprite_load_text_texture(Sprite *, const 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);
|
void
|
||||||
|
sprite_set_texture(Sprite *, Texture *, int index);
|
||||||
|
|
||||||
void sprite_render(Sprite*, Camera*);
|
void
|
||||||
|
sprite_render(Sprite*, Camera*);
|
||||||
|
|
||||||
void sprite_destroy(Sprite *);
|
void
|
||||||
|
sprite_destroy(Sprite *);
|
||||||
|
|
||||||
#endif // SPRITE_H_
|
#endif // SPRITE_H_
|
||||||
|
|
14
src/util.c
14
src/util.c
|
@ -127,8 +127,8 @@ log_print(FILE *out,
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void *
|
||||||
*ec_malloc(unsigned long size)
|
ec_malloc(unsigned long size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ptr = malloc(size);
|
ptr = malloc(size);
|
||||||
|
@ -137,6 +137,16 @@ void
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ec_calloc(size_t count, unsigned long size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
ptr = calloc(count, size);
|
||||||
|
if (ptr == NULL)
|
||||||
|
fatal("in ec_calloc() on memory allocation");
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
timestamp(char *tstamp, size_t sz)
|
timestamp(char *tstamp, size_t sz)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,9 @@ log_print(FILE *out,
|
||||||
void *
|
void *
|
||||||
ec_malloc(unsigned long size);
|
ec_malloc(unsigned long size);
|
||||||
|
|
||||||
|
void *
|
||||||
|
ec_calloc(size_t count, unsigned long size);
|
||||||
|
|
||||||
void
|
void
|
||||||
m_strcpy(char *dest, size_t destsz, const char *src);
|
m_strcpy(char *dest, size_t destsz, const char *src);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue