Continues #2: Artifacts

- Adds sparkle effect on artifacts
- Implements TRAP_AVOIDANCE, IMPROVED_HEARING
This commit is contained in:
Linus Probert 2018-08-08 14:46:59 +02:00
parent 095c93e5b2
commit 736eb79996
9 changed files with 83 additions and 44 deletions

View File

@ -19,46 +19,70 @@
#include "artifact.h" #include "artifact.h"
#include "util.h" #include "util.h"
#include "texturecache.h" #include "texturecache.h"
#include "particle_engine.h"
static void static void
artifact_set_effect(Artifact *a, MagicalEffect effect) artifact_set_effect(Artifact *a, MagicalEffect effect)
{ {
Texture *t;
a->effect = effect; a->effect = effect;
switch (effect) { switch (effect) {
case IMPROVED_HEARING: case IMPROVED_HEARING:
a->info.name = "Potion of ear juice"; a->info.name = "Potion of ear juice";
a->info.desc = "Your hearing is slightly improved"; a->info.desc = "Your hearing is slightly improved";
t = texturecache_add("Items/Potion.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(7*16, 4*16);
break; break;
case TRAP_AVOIDANCE: case TRAP_AVOIDANCE:
a->info.name = "Boot with nails inside"; a->info.name = "Boot with nails inside";
a->info.desc = "You are lighter on your feet"; a->info.desc = "You are lighter on your feet";
t = texturecache_add("Items/Boot.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(5*16, 0);
break; break;
case PIERCING_DAGGERS: case PIERCING_DAGGERS:
a->info.name = "Whetstone"; a->info.name = "Whetstone";
a->info.desc = "Your daggers are sharper"; a->info.desc = "Your daggers are sharper";
Texture *t = texturecache_add("Items/Rock.png"); t = texturecache_add("Items/Rock.png");
sprite_set_texture(a->sprite, t, 0); sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(0, 0); a->sprite->clip = CLIP16(0, 0);
break; break;
case CHARGE_THROUGH: case CHARGE_THROUGH:
a->info.name = "Greasy shield"; a->info.name = "Greasy shield";
a->info.desc = "You glide through obstructions"; a->info.desc = "You glide through obstructions";
t = texturecache_add("Items/Shield.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(16, 0);
break; break;
case PUSH_BACK: case PUSH_BACK:
a->info.name = "Glove of strength"; a->info.name = "Glove of strength";
a->info.desc = "Your arm is stronger"; a->info.desc = "Your arm is stronger";
t = texturecache_add("Items/Glove.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(0, 0);
break; break;
case DAGGER_RECOVERY: case DAGGER_RECOVERY:
a->info.name = "Forging hammer"; a->info.name = "Forging hammer";
a->info.desc = "Your daggers are more durable"; a->info.desc = "Your daggers are more durable";
t = texturecache_add("Items/LongWep.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(0, 6*16);
break; break;
case INCREASED_STUN: case INCREASED_STUN:
a->info.name = "Solid shield"; a->info.name = "Solid shield";
a->info.desc = "Your shield is harder"; a->info.desc = "Your shield is harder";
t = texturecache_add("Items/Shield.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(4*16, 0);
break; break;
case FEAR_INDUCING: case FEAR_INDUCING:
a->info.name = "Ugly shirt"; a->info.name = "Ugly shirt";
a->info.desc = "You look disgusting"; a->info.desc = "You look disgusting";
t = texturecache_add("Items/Armor.png");
sprite_set_texture(a->sprite, t, 0);
a->sprite->clip = CLIP16(6*16, 8*16);
break; break;
default: default:
break; break;
@ -89,6 +113,10 @@ void
artifact_render(Artifact *a, Camera *cam) artifact_render(Artifact *a, Camera *cam)
{ {
sprite_render(a->sprite, cam); sprite_render(a->sprite, cam);
Position pos = a->sprite->pos;
pos.x += 4;
pos.y += 4;
particle_engine_sparkle(pos, (Dimension) { 24, 24 }, C_PURPLE, false);
} }
void void

View File

@ -67,6 +67,7 @@
#define C_BLUE (SDL_Color) { 0, 0, 255, 255 } #define C_BLUE (SDL_Color) { 0, 0, 255, 255 }
#define C_YELLOW (SDL_Color) { 255, 255, 0, 255 } #define C_YELLOW (SDL_Color) { 255, 255, 0, 255 }
#define C_BLACK (SDL_Color) { 0, 0, 0, 255 } #define C_BLACK (SDL_Color) { 0, 0, 0, 255 }
#define C_PURPLE (SDL_Color) { 137, 16, 229, 255 }
// MSVC seems to have min/max defined. // MSVC seems to have min/max defined.
// Haven't looked into it further. // Haven't looked into it further.

View File

@ -619,6 +619,7 @@ run_menu(void)
SDL_RenderClear(gRenderer); SDL_RenderClear(gRenderer);
SDL_RenderSetViewport(gRenderer, &menuViewport); SDL_RenderSetViewport(gRenderer, &menuViewport);
map_render(gMap, gCamera); map_render(gMap, gCamera);
map_render_top_layer(gMap, gCamera);
roommatrix_render_lightmap(gRoomMatrix, gCamera); roommatrix_render_lightmap(gRoomMatrix, gCamera);
SDL_RenderSetViewport(gRenderer, NULL); SDL_RenderSetViewport(gRenderer, NULL);

View File

@ -376,7 +376,6 @@ monster_coward_walk(Monster *m, RoomMatrix *rm)
bool bool
monster_move(Monster *m, RoomMatrix *rm) monster_move(Monster *m, RoomMatrix *rm)
{ {
Position monsterRoomPos;
if (m->state.current == STUNNED) { if (m->state.current == STUNNED) {
if (m->state.stepsSinceChange < 3) { if (m->state.stepsSinceChange < 3) {
@ -390,9 +389,10 @@ monster_move(Monster *m, RoomMatrix *rm)
monster_behaviour_check(m, rm); monster_behaviour_check(m, rm);
monsterRoomPos = position_to_matrix_coords(&m->sprite->pos); Position originalPosition =
rm->spaces[monsterRoomPos.x][monsterRoomPos.y].occupied = false; position_to_matrix_coords(&m->sprite->pos);
rm->spaces[monsterRoomPos.x][monsterRoomPos.y].monster = NULL; rm->spaces[originalPosition.x][originalPosition.y].occupied = false;
rm->spaces[originalPosition.x][originalPosition.y].monster = NULL;
switch (m->state.current) { switch (m->state.current) {
case PASSIVE: case PASSIVE:
@ -413,9 +413,25 @@ monster_move(Monster *m, RoomMatrix *rm)
monster_update_pos(m, m->sprite->pos); monster_update_pos(m, m->sprite->pos);
monsterRoomPos = position_to_matrix_coords(&m->sprite->pos); Position newPos = position_to_matrix_coords(&m->sprite->pos);
rm->spaces[monsterRoomPos.x][monsterRoomPos.y].occupied = true; rm->spaces[newPos.x][newPos.y].occupied = true;
rm->spaces[monsterRoomPos.x][monsterRoomPos.y].monster = m; rm->spaces[newPos.x][newPos.y].monster = m;
if (!position_equals(&originalPosition, &newPos)) {
Player *p = rm->spaces[rm->playerRoomPos.x][rm->playerRoomPos.y].player;
if (p) {
Uint32 range = 3 + player_has_artifact(p, IMPROVED_HEARING) * 2;
bool withinHearingDist =
range > 3 && position_proximity(range,
&newPos,
&rm->playerRoomPos);
RoomSpace *space = &rm->spaces[newPos.x][newPos.y];
if (space->light < 100 && withinHearingDist) {
actiontextbuilder_create_text("!", C_WHITE, &m->sprite->pos);
}
}
}
m->steps++; m->steps++;
if (m->steps >= m->stats.speed) { if (m->steps >= m->stats.speed) {
@ -538,7 +554,9 @@ 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); // TODO: This should not occur every time
// Debug code.
Artifact *a = artifact_create(TRAP_AVOIDANCE);
a->sprite->pos = monster->sprite->pos; a->sprite->pos = monster->sprite->pos;
linkedlist_append(&map->artifacts, a); linkedlist_append(&map->artifacts, a);
} }

View File

@ -82,27 +82,6 @@ create_rect_particle(void)
return p; return p;
} }
/*
* Not used right now, hide for now
static Particle *
create_line_particle(void)
{
Particle *p = ec_malloc(sizeof(Particle));
p->type = LINE;
p->velocity = VECTOR2D_NODIR;
p->movetime = 100;
p->lifetime = 100;
p->fixed = false;
p->blend_mode = SDL_BLENDMODE_MOD;
p->color = C_WHITE;
p->particle.line.startPos = (Position) { 0, 0 };
p->particle.line.endPos = (Position) { 32, 32 };
return p;
}
*/
static void static void
check_engine(void) check_engine(void)
{ {
@ -243,7 +222,7 @@ particle_engine_speed_lines(Position pos, Dimension dim, bool horizontal)
} }
void void
particle_engine_sparkle(Position pos, Dimension dim) particle_engine_sparkle(Position pos, Dimension dim, SDL_Color color, bool global)
{ {
for (unsigned int i = 0; i < 10; ++i) { for (unsigned int i = 0; i < 10; ++i) {
int x, y, yv, alpha; int x, y, yv, alpha;
@ -266,10 +245,13 @@ particle_engine_sparkle(Position pos, Dimension dim)
p->movetime = lt; p->movetime = lt;
p->lifetime = lt; p->lifetime = lt;
p->blend_mode = SDL_BLENDMODE_BLEND; p->blend_mode = SDL_BLENDMODE_BLEND;
p->color = C_WHITE; p->color = color;
p->color.a = (Uint8) alpha; p->color.a = (Uint8) alpha;
p->fixed = true; p->fixed = global;
linkedlist_append(&engine->global_particles, p); if (global)
linkedlist_append(&engine->global_particles, p);
else
linkedlist_append(&engine->game_particles, p);
} }
} }

View File

@ -41,7 +41,7 @@ void
particle_engine_speed_lines(Position, Dimension, bool horizontal); particle_engine_speed_lines(Position, Dimension, bool horizontal);
void void
particle_engine_sparkle(Position, Dimension); particle_engine_sparkle(Position, Dimension, SDL_Color, bool global);
void void
particle_engine_wind(Vector2d direction); particle_engine_wind(Vector2d direction);

View File

@ -108,17 +108,18 @@ projectile_update(Projectile *p, UpdateData *data)
if (dmg > 0) { if (dmg > 0) {
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;
} else {
gui_log("%s dodged your dagger", space->monster->label);
} }
if (get_random(5) == 0 monster_hit(space->monster, dmg);
|| get_random(5) < player_has_artifact(data->player, DAGGER_RECOVERY)) { player_monster_kill_check(data->player, space->monster);
alive = player_has_artifact(data->player, PIERCING_DAGGERS) > p->collisionCount;
if (!alive && (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);
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 = alive; p->alive = alive;

View File

@ -235,7 +235,7 @@ render_skill_sparkles(SkillBar *bar, Player *player)
continue; continue;
pos.x += 32 * i; pos.x += 32 * i;
particle_engine_sparkle(pos, dim); particle_engine_sparkle(pos, dim, C_WHITE, true);
} }
} }

View File

@ -20,6 +20,8 @@
#include "trap.h" #include "trap.h"
#include "util.h" #include "util.h"
#include "gui.h" #include "gui.h"
#include "random.h"
#include "actiontextbuilder.h"
Trap * Trap *
trap_create() trap_create()
@ -35,14 +37,20 @@ trap_create()
void void
trap_activate(Trap *trap, Player *player) trap_activate(Trap *trap, Player *player)
{ {
player->stats.hp -= trap->damage;
player_hit(player, trap->damage);
if (!trap->sprite->animate) { if (!trap->sprite->animate) {
gui_log("A trap is sprung!"); gui_log("A trap is sprung!");
trap->sprite->animate = true; trap->sprite->animate = true;
} else { } else {
gui_log("You step in a trap!"); gui_log("You step in a trap!");
} }
if (get_random(10) > 2 * player_has_artifact(player, TRAP_AVOIDANCE)) {
player->stats.hp -= trap->damage;
player_hit(player, trap->damage);
} else {
actiontextbuilder_create_text("Dodged", C_YELLOW, &player->sprite->pos);
gui_log("You nimbly avoid getting hurt by the trap");
}
} }
void void