Makes critical hits cause bleeding

This commit is contained in:
Linus Probert 2019-05-14 10:26:28 +02:00
parent 8f21e8bfb2
commit dd3e84d70d
8 changed files with 66 additions and 59 deletions

View File

@ -135,13 +135,13 @@ damage_surroundings(Monster *m, RoomMatrix *rm)
RoomSpace *r = &rm->spaces[matrixPos.x][matrixPos.y];
if (r->monster) {
int dmg = stats_fight(&m->stats, &r->monster->stats);
monster_hit(r->monster, dmg);
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
CombatResult result = stats_fight(&m->stats, &r->monster->stats);
monster_hit(r->monster, result.dmg, result.critical);
gui_log("%s takes %d damage from the explosion", r->monster->label, result.dmg);
} else if (r->player) {
int dmg = stats_fight(&m->stats, &r->player->stats);
player_hit(r->player, dmg);
gui_log("You take %d damage from the explosion", dmg);
CombatResult result = stats_fight(&m->stats, &r->player->stats);
player_hit(r->player, result.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);
if (space->player && monster->state.current == AGRESSIVE) {
unsigned int dmg = stats_fight(&monster->stats,
&space->player->stats);
CombatResult result = stats_fight(&monster->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",
monster->label, dmg);
monster->label, result.dmg);
camera_shake(direction, 300);
} else {
gui_log("%s missed you", monster->label);
@ -563,7 +563,7 @@ apply_bleed_damage(Player *p, Monster *m)
return;
uint32_t dmg = m->stats.lvl * 2;
monster_hit(m, dmg);
monster_hit(m, dmg, false);
m->stats.hp -= dmg;
player_monster_kill_check(p, m);
}
@ -685,7 +685,7 @@ monster_update(Monster *m, UpdateData *data)
}
void
monster_hit(Monster *monster, unsigned int dmg)
monster_hit(Monster *monster, unsigned int dmg, bool critical)
{
if (dmg > 0) {
Position p = monster->sprite->pos;
@ -703,6 +703,9 @@ monster_hit(Monster *monster, unsigned int dmg)
C_YELLOW,
&monster->sprite->pos);
}
if (critical)
monster_set_bleeding(monster);
monster_behaviour_check_post_hit(monster);
}
@ -878,7 +881,7 @@ monster_push(Monster *m, Player *p, RoomMatrix *rm, Vector2d direction)
if (space->trap) {
int dmg = space->trap->damage * 3;
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);
} else if (space->damaging) {
LinkedList *objects = space->objects;
@ -888,7 +891,7 @@ monster_push(Monster *m, Player *p, RoomMatrix *rm, Vector2d direction)
if (!o->damage)
return;
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)) {
m->sprite->pos.x -= TILE_DIMENSION * (int) direction.x;

View File

@ -103,7 +103,7 @@ void
monster_render_top_layer(Monster*, RoomMatrix*, Camera*);
void
monster_hit(Monster*, unsigned int dmg);
monster_hit(Monster*, unsigned int dmg, bool critical);
void
monster_update_stats_for_level(Monster*, unsigned int level);

View File

@ -103,7 +103,7 @@ particle_engine_init(void)
void
particle_engine_bleed(Position pos, Dimension dim)
{
particle_engine_bloodspray(pos, dim, 5);
particle_engine_bloodspray(pos, dim, 10);
}
void

View File

@ -133,16 +133,16 @@ on_monster_collision(Player *player,
RoomMatrix *matrix,
Vector2d direction)
{
unsigned int hit = stats_fight(&player->stats,
&monster->stats);
CombatResult result = stats_fight(&player->stats,
&monster->stats);
mixer_play_effect(SWING0 + get_random(2));
monster_hit(monster, hit);
monster_hit(monster, result.dmg, result.critical);
animation_run(player->swordAnimation);
if (hit > 0) {
if (result.dmg > 0) {
gui_log("You hit %s for %u damage",
monster->lclabel, hit);
monster->lclabel, result.dmg);
player->stat_data.hits += 1;
mixer_play_effect(SWORD_HIT);
} else {

View File

@ -119,14 +119,14 @@ projectile_update(Projectile *p, UpdateData *data)
if (space->monster) {
Stats tmpStats = data->player->stats;
tmpStats.dmg *= 2;
Uint32 dmg = stats_fight(&tmpStats, &space->monster->stats);
if (dmg > 0) {
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg);
CombatResult result = stats_fight(&tmpStats, &space->monster->stats);
if (result.dmg > 0) {
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, result.dmg);
data->player->stat_data.hits += 1;
} else {
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);
alive = player_has_artifact(data->player, PIERCING_DAGGERS) > p->collisionCount;
projectilePos = space->monster->sprite->pos;

View File

@ -319,12 +319,12 @@ skill_use_flurry(Skill *skill, SkillData *data)
unsigned int hitCount = 0;
for (size_t i = 0; i < 3; ++i) {
unsigned int originalHp = monster->stats.hp;
unsigned int dmg = stats_fight(&data->player->stats, &monster->stats);
if (dmg > 0 && originalHp > 0) {
gui_log("You hit for %u damage", dmg);
CombatResult result = stats_fight(&data->player->stats, &monster->stats);
if (result.dmg > 0 && originalHp > 0) {
gui_log("You hit for %u damage", result.dmg);
hitCount++;
}
monster_hit(monster, dmg);
monster_hit(monster, result.dmg, result.critical);
}
if (hitCount == 1) {
mixer_play_effect(SWORD_HIT);
@ -436,9 +436,9 @@ skill_bash(Skill *skill, SkillData *data)
mixer_play_effect(SWING0);
if (monster) {
gui_log("You bash %s with your shield", monster->lclabel);
unsigned int dmg = stats_fight(&data->player->stats, &monster->stats);
if (dmg > 0) {
gui_log("You hit for %u damage", dmg);
CombatResult result = stats_fight(&data->player->stats, &monster->stats);
if (result.dmg > 0) {
gui_log("You hit for %u damage", result.dmg);
if (monster->stats.hp > 0) {
gui_log("%s seems dazed and confused", monster->label);
monster_set_state(monster, STUNNED,
@ -449,7 +449,7 @@ skill_bash(Skill *skill, SkillData *data)
} else {
gui_log("You missed %s", monster->lclabel);
}
monster_hit(monster, dmg);
monster_hit(monster, result.dmg, result.critical);
} else {
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));
animation_run(data->player->swordAnimation);
if (space->monster) {
int dmg = stats_fight(&data->player->stats, &space->monster->stats);
if (dmg)
CombatResult result = stats_fight(&data->player->stats, &space->monster->stats);
if (result.dmg)
mixer_play_effect(SWORD_HIT);
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);
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);
for (Uint32 i = 0; i < pushCount; ++i) {
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);
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;
monster_hit(m, dmg);
monster_hit(m, result.dmg, result.critical);
player_monster_kill_check(data->player, m);
if (dmg) {
if (result.dmg) {
mixer_play_effect(SWORD_HIT);
monster_set_state(m, STUNNED, (Uint8)(2 + player_has_artifact(data->player, INCREASED_STUN)));
monster_set_bleeding(m);
@ -680,13 +680,13 @@ skill_charge_check_path(SkillData *data,
Stats tmpStats = player->stats;
tmpStats.dmg *= steps > 0 ? steps : 1;
mixer_play_effect(SWING0 + get_random(2));
unsigned int dmg = stats_fight(&tmpStats, &monster->stats);
if (dmg > 0) {
gui_log("You charged %s for %u damage", monster->lclabel, dmg);
CombatResult result = stats_fight(&tmpStats, &monster->stats);
if (result.dmg > 0) {
gui_log("You charged %s for %u damage", monster->lclabel, result.dmg);
mixer_play_effect(SWORD_HIT);
data->player->stat_data.hits += 1;
}
monster_hit(monster, dmg);
monster_hit(monster, result.dmg, result.critical);
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];
if (r->monster) {
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;
monster_hit(r->monster, dmg);
gui_log("%s takes %d damage from the explosion", r->monster->label, dmg);
monster_hit(r->monster, result.dmg, result.critical);
gui_log("%s takes %d damage from the explosion", r->monster->label, result.dmg);
monster_set_bleeding(r->monster);
int lvl = 1 + player_has_artifact(player, PUSH_BACK);

View File

@ -61,31 +61,30 @@ get_defence_roll(Stats *defender)
return roll + defender->def;
}
unsigned int
CombatResult
stats_fight(Stats *attacker, Stats *defender)
{
bool critical = false;
CombatResult result = { 0, false };
int atkRoll = get_attack_roll(attacker);
int defRoll = get_defence_roll(defender);
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 (attacker->dmg > 0)
dmgRoll = get_random(attacker->dmg - 1) + 1;
result.dmg = get_random(attacker->dmg - 1) + 1;
else
dmgRoll = 1;
result.dmg = 1;
if (critical) {
dmgRoll = dmgRoll * 2;
if (result.critical) {
result.dmg = result.dmg * 2;
gui_log("CRITICAL HIT!");
}
defender->hp -= dmgRoll;
defender->hp -= result.dmg;
}
return dmgRoll;
return result;
}

View File

@ -31,7 +31,12 @@ typedef struct Stats_t {
bool disadvantage;
} Stats;
unsigned int
typedef struct CombatResult {
unsigned int dmg;
bool critical;
} CombatResult;
CombatResult
stats_fight(Stats *attacker, Stats *defender);
#endif // STATS_H_