Makes critical hits cause bleeding
This commit is contained in:
parent
8f21e8bfb2
commit
dd3e84d70d
|
@ -135,13 +135,13 @@ damage_surroundings(Monster *m, RoomMatrix *rm)
|
||||||
|
|
||||||
RoomSpace *r = &rm->spaces[matrixPos.x][matrixPos.y];
|
RoomSpace *r = &rm->spaces[matrixPos.x][matrixPos.y];
|
||||||
if (r->monster) {
|
if (r->monster) {
|
||||||
int dmg = stats_fight(&m->stats, &r->monster->stats);
|
CombatResult result = stats_fight(&m->stats, &r->monster->stats);
|
||||||
monster_hit(r->monster, dmg);
|
monster_hit(r->monster, result.dmg, result.critical);
|
||||||
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
|
gui_log("%s takes %d damage from the explosion", r->monster->label, result.dmg);
|
||||||
} else if (r->player) {
|
} else if (r->player) {
|
||||||
int dmg = stats_fight(&m->stats, &r->player->stats);
|
CombatResult result = stats_fight(&m->stats, &r->player->stats);
|
||||||
player_hit(r->player, dmg);
|
player_hit(r->player, result.dmg);
|
||||||
gui_log("You take %d damage from the explosion", dmg);
|
gui_log("You take %d damage from the explosion", result.dmg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,14 +314,14 @@ has_collided(Monster *monster, RoomMatrix *matrix, Vector2d direction)
|
||||||
RoomSpace *space = roommatrix_get_space_for(matrix, &monster->sprite->pos);
|
RoomSpace *space = roommatrix_get_space_for(matrix, &monster->sprite->pos);
|
||||||
|
|
||||||
if (space->player && monster->state.current == AGRESSIVE) {
|
if (space->player && monster->state.current == AGRESSIVE) {
|
||||||
unsigned int dmg = stats_fight(&monster->stats,
|
CombatResult result = stats_fight(&monster->stats,
|
||||||
&space->player->stats);
|
&space->player->stats);
|
||||||
|
|
||||||
player_hit(space->player, dmg);
|
player_hit(space->player, result.dmg);
|
||||||
|
|
||||||
if (dmg > 0) {
|
if (result.dmg > 0) {
|
||||||
gui_log("%s hit you for %u damage",
|
gui_log("%s hit you for %u damage",
|
||||||
monster->label, dmg);
|
monster->label, result.dmg);
|
||||||
camera_shake(direction, 300);
|
camera_shake(direction, 300);
|
||||||
} else {
|
} else {
|
||||||
gui_log("%s missed you", monster->label);
|
gui_log("%s missed you", monster->label);
|
||||||
|
@ -563,7 +563,7 @@ apply_bleed_damage(Player *p, Monster *m)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t dmg = m->stats.lvl * 2;
|
uint32_t dmg = m->stats.lvl * 2;
|
||||||
monster_hit(m, dmg);
|
monster_hit(m, dmg, false);
|
||||||
m->stats.hp -= dmg;
|
m->stats.hp -= dmg;
|
||||||
player_monster_kill_check(p, m);
|
player_monster_kill_check(p, m);
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ monster_update(Monster *m, UpdateData *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
monster_hit(Monster *monster, unsigned int dmg)
|
monster_hit(Monster *monster, unsigned int dmg, bool critical)
|
||||||
{
|
{
|
||||||
if (dmg > 0) {
|
if (dmg > 0) {
|
||||||
Position p = monster->sprite->pos;
|
Position p = monster->sprite->pos;
|
||||||
|
@ -703,6 +703,9 @@ monster_hit(Monster *monster, unsigned int dmg)
|
||||||
C_YELLOW,
|
C_YELLOW,
|
||||||
&monster->sprite->pos);
|
&monster->sprite->pos);
|
||||||
}
|
}
|
||||||
|
if (critical)
|
||||||
|
monster_set_bleeding(monster);
|
||||||
|
|
||||||
monster_behaviour_check_post_hit(monster);
|
monster_behaviour_check_post_hit(monster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,7 +881,7 @@ monster_push(Monster *m, Player *p, RoomMatrix *rm, Vector2d direction)
|
||||||
if (space->trap) {
|
if (space->trap) {
|
||||||
int dmg = space->trap->damage * 3;
|
int dmg = space->trap->damage * 3;
|
||||||
m->stats.hp -= dmg;
|
m->stats.hp -= dmg;
|
||||||
monster_hit(m, dmg);
|
monster_hit(m, dmg, false);
|
||||||
gui_log("%s takes %d damage from a trap", m->label, dmg);
|
gui_log("%s takes %d damage from a trap", m->label, dmg);
|
||||||
} else if (space->damaging) {
|
} else if (space->damaging) {
|
||||||
LinkedList *objects = space->objects;
|
LinkedList *objects = space->objects;
|
||||||
|
@ -888,7 +891,7 @@ monster_push(Monster *m, Player *p, RoomMatrix *rm, Vector2d direction)
|
||||||
if (!o->damage)
|
if (!o->damage)
|
||||||
return;
|
return;
|
||||||
m->stats.hp -= o->damage * 3;
|
m->stats.hp -= o->damage * 3;
|
||||||
monster_hit(m, o->damage * 3);
|
monster_hit(m, o->damage * 3, false);
|
||||||
}
|
}
|
||||||
} else if (has_collided(m, rm, direction)) {
|
} else if (has_collided(m, rm, direction)) {
|
||||||
m->sprite->pos.x -= TILE_DIMENSION * (int) direction.x;
|
m->sprite->pos.x -= TILE_DIMENSION * (int) direction.x;
|
||||||
|
|
|
@ -103,7 +103,7 @@ void
|
||||||
monster_render_top_layer(Monster*, RoomMatrix*, Camera*);
|
monster_render_top_layer(Monster*, RoomMatrix*, Camera*);
|
||||||
|
|
||||||
void
|
void
|
||||||
monster_hit(Monster*, unsigned int dmg);
|
monster_hit(Monster*, unsigned int dmg, bool critical);
|
||||||
|
|
||||||
void
|
void
|
||||||
monster_update_stats_for_level(Monster*, unsigned int level);
|
monster_update_stats_for_level(Monster*, unsigned int level);
|
||||||
|
|
|
@ -103,7 +103,7 @@ particle_engine_init(void)
|
||||||
void
|
void
|
||||||
particle_engine_bleed(Position pos, Dimension dim)
|
particle_engine_bleed(Position pos, Dimension dim)
|
||||||
{
|
{
|
||||||
particle_engine_bloodspray(pos, dim, 5);
|
particle_engine_bloodspray(pos, dim, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -133,16 +133,16 @@ on_monster_collision(Player *player,
|
||||||
RoomMatrix *matrix,
|
RoomMatrix *matrix,
|
||||||
Vector2d direction)
|
Vector2d direction)
|
||||||
{
|
{
|
||||||
unsigned int hit = stats_fight(&player->stats,
|
CombatResult result = stats_fight(&player->stats,
|
||||||
&monster->stats);
|
&monster->stats);
|
||||||
|
|
||||||
mixer_play_effect(SWING0 + get_random(2));
|
mixer_play_effect(SWING0 + get_random(2));
|
||||||
monster_hit(monster, hit);
|
monster_hit(monster, result.dmg, result.critical);
|
||||||
animation_run(player->swordAnimation);
|
animation_run(player->swordAnimation);
|
||||||
|
|
||||||
if (hit > 0) {
|
if (result.dmg > 0) {
|
||||||
gui_log("You hit %s for %u damage",
|
gui_log("You hit %s for %u damage",
|
||||||
monster->lclabel, hit);
|
monster->lclabel, result.dmg);
|
||||||
player->stat_data.hits += 1;
|
player->stat_data.hits += 1;
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -119,14 +119,14 @@ projectile_update(Projectile *p, UpdateData *data)
|
||||||
if (space->monster) {
|
if (space->monster) {
|
||||||
Stats tmpStats = data->player->stats;
|
Stats tmpStats = data->player->stats;
|
||||||
tmpStats.dmg *= 2;
|
tmpStats.dmg *= 2;
|
||||||
Uint32 dmg = stats_fight(&tmpStats, &space->monster->stats);
|
CombatResult result = stats_fight(&tmpStats, &space->monster->stats);
|
||||||
if (dmg > 0) {
|
if (result.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, result.dmg);
|
||||||
data->player->stat_data.hits += 1;
|
data->player->stat_data.hits += 1;
|
||||||
} else {
|
} else {
|
||||||
gui_log("%s dodged your dagger", space->monster->label);
|
gui_log("%s dodged your dagger", space->monster->label);
|
||||||
}
|
}
|
||||||
monster_hit(space->monster, dmg);
|
monster_hit(space->monster, result.dmg, result.critical);
|
||||||
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;
|
alive = player_has_artifact(data->player, PIERCING_DAGGERS) > p->collisionCount;
|
||||||
projectilePos = space->monster->sprite->pos;
|
projectilePos = space->monster->sprite->pos;
|
||||||
|
|
44
src/skill.c
44
src/skill.c
|
@ -319,12 +319,12 @@ skill_use_flurry(Skill *skill, SkillData *data)
|
||||||
unsigned int hitCount = 0;
|
unsigned int hitCount = 0;
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
unsigned int originalHp = monster->stats.hp;
|
unsigned int originalHp = monster->stats.hp;
|
||||||
unsigned int dmg = stats_fight(&data->player->stats, &monster->stats);
|
CombatResult result = stats_fight(&data->player->stats, &monster->stats);
|
||||||
if (dmg > 0 && originalHp > 0) {
|
if (result.dmg > 0 && originalHp > 0) {
|
||||||
gui_log("You hit for %u damage", dmg);
|
gui_log("You hit for %u damage", result.dmg);
|
||||||
hitCount++;
|
hitCount++;
|
||||||
}
|
}
|
||||||
monster_hit(monster, dmg);
|
monster_hit(monster, result.dmg, result.critical);
|
||||||
}
|
}
|
||||||
if (hitCount == 1) {
|
if (hitCount == 1) {
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
|
@ -436,9 +436,9 @@ skill_bash(Skill *skill, SkillData *data)
|
||||||
mixer_play_effect(SWING0);
|
mixer_play_effect(SWING0);
|
||||||
if (monster) {
|
if (monster) {
|
||||||
gui_log("You bash %s with your shield", monster->lclabel);
|
gui_log("You bash %s with your shield", monster->lclabel);
|
||||||
unsigned int dmg = stats_fight(&data->player->stats, &monster->stats);
|
CombatResult result = stats_fight(&data->player->stats, &monster->stats);
|
||||||
if (dmg > 0) {
|
if (result.dmg > 0) {
|
||||||
gui_log("You hit for %u damage", dmg);
|
gui_log("You hit for %u damage", result.dmg);
|
||||||
if (monster->stats.hp > 0) {
|
if (monster->stats.hp > 0) {
|
||||||
gui_log("%s seems dazed and confused", monster->label);
|
gui_log("%s seems dazed and confused", monster->label);
|
||||||
monster_set_state(monster, STUNNED,
|
monster_set_state(monster, STUNNED,
|
||||||
|
@ -449,7 +449,7 @@ skill_bash(Skill *skill, SkillData *data)
|
||||||
} else {
|
} else {
|
||||||
gui_log("You missed %s", monster->lclabel);
|
gui_log("You missed %s", monster->lclabel);
|
||||||
}
|
}
|
||||||
monster_hit(monster, dmg);
|
monster_hit(monster, result.dmg, result.critical);
|
||||||
} else {
|
} else {
|
||||||
gui_log("You bash your shield at nothing");
|
gui_log("You bash your shield at nothing");
|
||||||
}
|
}
|
||||||
|
@ -491,13 +491,13 @@ skill_trip(Skill *skill, SkillData *data)
|
||||||
mixer_play_effect(SWING0 + get_random(2));
|
mixer_play_effect(SWING0 + get_random(2));
|
||||||
animation_run(data->player->swordAnimation);
|
animation_run(data->player->swordAnimation);
|
||||||
if (space->monster) {
|
if (space->monster) {
|
||||||
int dmg = stats_fight(&data->player->stats, &space->monster->stats);
|
CombatResult result = stats_fight(&data->player->stats, &space->monster->stats);
|
||||||
if (dmg)
|
if (result.dmg)
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
gui_log("You trip %s causing it to fall away from you", space->monster->lclabel);
|
gui_log("You trip %s causing it to fall away from you", space->monster->lclabel);
|
||||||
monster_hit(space->monster, dmg);
|
monster_hit(space->monster, result.dmg, result.critical);
|
||||||
player_monster_kill_check(data->player, space->monster);
|
player_monster_kill_check(data->player, space->monster);
|
||||||
if (dmg && space->monster->stats.hp > 0) {
|
if (result.dmg && space->monster->stats.hp > 0) {
|
||||||
Uint32 pushCount = 1 + player_has_artifact(data->player, PUSH_BACK);
|
Uint32 pushCount = 1 + player_has_artifact(data->player, PUSH_BACK);
|
||||||
for (Uint32 i = 0; i < pushCount; ++i) {
|
for (Uint32 i = 0; i < pushCount; ++i) {
|
||||||
monster_push(space->monster, data->player, data->matrix, data->direction);
|
monster_push(space->monster, data->player, data->matrix, data->direction);
|
||||||
|
@ -564,11 +564,11 @@ skill_backstab(Skill *skill, SkillData *data)
|
||||||
monster_push(m, data->player, data->matrix, reverseDirection);
|
monster_push(m, data->player, data->matrix, reverseDirection);
|
||||||
|
|
||||||
m->stats.disadvantage = true;
|
m->stats.disadvantage = true;
|
||||||
int dmg = stats_fight(&data->player->stats, &m->stats);
|
CombatResult result = stats_fight(&data->player->stats, &m->stats);
|
||||||
m->stats.disadvantage = false;
|
m->stats.disadvantage = false;
|
||||||
monster_hit(m, dmg);
|
monster_hit(m, result.dmg, result.critical);
|
||||||
player_monster_kill_check(data->player, m);
|
player_monster_kill_check(data->player, m);
|
||||||
if (dmg) {
|
if (result.dmg) {
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
monster_set_state(m, STUNNED, (Uint8)(2 + player_has_artifact(data->player, INCREASED_STUN)));
|
monster_set_state(m, STUNNED, (Uint8)(2 + player_has_artifact(data->player, INCREASED_STUN)));
|
||||||
monster_set_bleeding(m);
|
monster_set_bleeding(m);
|
||||||
|
@ -680,13 +680,13 @@ skill_charge_check_path(SkillData *data,
|
||||||
Stats tmpStats = player->stats;
|
Stats tmpStats = player->stats;
|
||||||
tmpStats.dmg *= steps > 0 ? steps : 1;
|
tmpStats.dmg *= steps > 0 ? steps : 1;
|
||||||
mixer_play_effect(SWING0 + get_random(2));
|
mixer_play_effect(SWING0 + get_random(2));
|
||||||
unsigned int dmg = stats_fight(&tmpStats, &monster->stats);
|
CombatResult result = stats_fight(&tmpStats, &monster->stats);
|
||||||
if (dmg > 0) {
|
if (result.dmg > 0) {
|
||||||
gui_log("You charged %s for %u damage", monster->lclabel, dmg);
|
gui_log("You charged %s for %u damage", monster->lclabel, result.dmg);
|
||||||
mixer_play_effect(SWORD_HIT);
|
mixer_play_effect(SWORD_HIT);
|
||||||
data->player->stat_data.hits += 1;
|
data->player->stat_data.hits += 1;
|
||||||
}
|
}
|
||||||
monster_hit(monster, dmg);
|
monster_hit(monster, result.dmg, result.critical);
|
||||||
player_monster_kill_check(data->player, monster);
|
player_monster_kill_check(data->player, monster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,10 +886,10 @@ skill_erupt(Skill *skill, SkillData *data)
|
||||||
RoomSpace *r = &rm->spaces[matrixPos.x][matrixPos.y];
|
RoomSpace *r = &rm->spaces[matrixPos.x][matrixPos.y];
|
||||||
if (r->monster) {
|
if (r->monster) {
|
||||||
player->stats.advantage = true;
|
player->stats.advantage = true;
|
||||||
int dmg = stats_fight(&player->stats, &r->monster->stats);
|
CombatResult result = stats_fight(&player->stats, &r->monster->stats);
|
||||||
player->stats.advantage = false;
|
player->stats.advantage = false;
|
||||||
monster_hit(r->monster, dmg);
|
monster_hit(r->monster, result.dmg, result.critical);
|
||||||
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
|
gui_log("%s takes %d damage from the explosion", r->monster->label, result.dmg);
|
||||||
monster_set_bleeding(r->monster);
|
monster_set_bleeding(r->monster);
|
||||||
|
|
||||||
int lvl = 1 + player_has_artifact(player, PUSH_BACK);
|
int lvl = 1 + player_has_artifact(player, PUSH_BACK);
|
||||||
|
|
19
src/stats.c
19
src/stats.c
|
@ -61,31 +61,30 @@ get_defence_roll(Stats *defender)
|
||||||
return roll + defender->def;
|
return roll + defender->def;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
CombatResult
|
||||||
stats_fight(Stats *attacker, Stats *defender)
|
stats_fight(Stats *attacker, Stats *defender)
|
||||||
{
|
{
|
||||||
bool critical = false;
|
CombatResult result = { 0, false };
|
||||||
|
|
||||||
int atkRoll = get_attack_roll(attacker);
|
int atkRoll = get_attack_roll(attacker);
|
||||||
int defRoll = get_defence_roll(defender);
|
int defRoll = get_defence_roll(defender);
|
||||||
|
|
||||||
if (atkRoll - attacker->atk == 20)
|
if (atkRoll - attacker->atk == 20)
|
||||||
critical = get_attack_roll(attacker) > defRoll;
|
result.critical = get_attack_roll(attacker) > defRoll;
|
||||||
|
|
||||||
int dmgRoll = 0;
|
|
||||||
if (atkRoll >= defRoll) {
|
if (atkRoll >= defRoll) {
|
||||||
if (attacker->dmg > 0)
|
if (attacker->dmg > 0)
|
||||||
dmgRoll = get_random(attacker->dmg - 1) + 1;
|
result.dmg = get_random(attacker->dmg - 1) + 1;
|
||||||
else
|
else
|
||||||
dmgRoll = 1;
|
result.dmg = 1;
|
||||||
|
|
||||||
if (critical) {
|
if (result.critical) {
|
||||||
dmgRoll = dmgRoll * 2;
|
result.dmg = result.dmg * 2;
|
||||||
gui_log("CRITICAL HIT!");
|
gui_log("CRITICAL HIT!");
|
||||||
}
|
}
|
||||||
|
|
||||||
defender->hp -= dmgRoll;
|
defender->hp -= result.dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dmgRoll;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,12 @@ typedef struct Stats_t {
|
||||||
bool disadvantage;
|
bool disadvantage;
|
||||||
} Stats;
|
} Stats;
|
||||||
|
|
||||||
unsigned int
|
typedef struct CombatResult {
|
||||||
|
unsigned int dmg;
|
||||||
|
bool critical;
|
||||||
|
} CombatResult;
|
||||||
|
|
||||||
|
CombatResult
|
||||||
stats_fight(Stats *attacker, Stats *defender);
|
stats_fight(Stats *attacker, Stats *defender);
|
||||||
|
|
||||||
#endif // STATS_H_
|
#endif // STATS_H_
|
||||||
|
|
Loading…
Reference in New Issue