Improve enemy AI cliff detection, add level-bottom kill, and charger knockback
Some checks failed
Deploy / deploy (push) Failing after 1m14s

Enemies that fall past the bottom of the level are now instantly destroyed,
preventing them from accumulating off-screen. Cliff detection uses a
speed-scaled lookahead so faster enemies reverse earlier. Charger deals
double damage during charge and knockback scales with the attacker's speed.
This commit was merged in pull request #23.
This commit is contained in:
2026-03-16 14:52:36 +00:00
committed by tas
parent 84a257f9b9
commit f65e8dd9ea
2 changed files with 71 additions and 26 deletions

View File

@@ -228,11 +228,14 @@ static void damage_player(Entity *player, int damage, Entity *source) {
ppd->inv_timer = PLAYER_INV_TIME;
player->flags |= ENTITY_INVINCIBLE;
/* Knockback away from source */
/* Knockback away from source, scaled by source speed */
if (source) {
float knock_dir = (player->body.pos.x < source->body.pos.x) ?
-1.0f : 1.0f;
player->body.vel.x = knock_dir * 150.0f;
float src_speed = fabsf(source->body.vel.x);
float knock_str = 150.0f;
if (src_speed > knock_str) knock_str = src_speed;
player->body.vel.x = knock_dir * knock_str;
player->body.vel.y = -150.0f;
}
}
@@ -308,7 +311,15 @@ static void handle_collisions(EntityManager *em) {
if (a->flags & ENTITY_DEAD) stats_record_kill();
player->body.vel.y = -PLAYER_JUMP_FORCE * 0.7f;
} else {
damage_player(player, a->damage, a);
/* Charger deals extra damage and knockback while charging */
int dmg = a->damage;
if (a->type == ENT_ENEMY_CHARGER) {
ChargerData *cd = (ChargerData *)a->data;
if (cd && cd->state == CHARGER_CHARGE) {
dmg = 2;
}
}
damage_player(player, dmg, a);
}
}
}