engine-c: vehicle tread/wheel roll via Unit.anim

This commit is contained in:
local-model/engine-L2-grok-4.5 2026-09-19 12:50:15 +02:00
parent 48960b11fa
commit 8b55fa687a
No known key found for this signature in database
3 changed files with 149 additions and 4 deletions

View file

@ -6,6 +6,23 @@
static int unit_alloc_id(Game *g) { return g->unit_next_id++; }
/* Wheeled / tracked chassis: Unit.anim is continuous tyre phase (rad), not a pulse. */
static int unit_wheeled(UnitType t) {
return t == UT_BUGGY || t == UT_JEEP || t == UT_HARVESTER
|| t == UT_BEAST || t == UT_MISSILE || t == UT_MEDIC;
}
static int unit_tracked(UnitType t) {
return t == UT_TANK || t == UT_RAVAGER;
}
static int unit_rolling(UnitType t) {
return unit_wheeled(t) || unit_tracked(t);
}
static void unit_roll_phase(Unit *u, float sp) {
/* ~1 revolution per ~40 world px */
u->anim = fmodf(u->anim + (sp / 40.0f) * (float)(2.0 * M_PI), (float)(2.0 * M_PI));
if (u->anim < 0.0f) u->anim += (float)(2.0 * M_PI);
}
Unit *unit_by_id(Game *g, int id) {
for (int i = 0; i < g->unit_count; i++)
if (!g->units[i].dead && g->units[i].id == id)
@ -336,7 +353,8 @@ static void unit_combat_step(Game *g, Unit *u, float dt) {
particle_burst(g, mx, my, 3, 1, 255, 160, 50);
u->atk_cd = ((u->type == UT_ARTILLERY) ? 2.2f
: (u->type == UT_INFANTRY ? 0.8f : 1.0f)) / u->reload_mul;
u->anim = 1.0f;
/* rolling chassis keep continuous tyre phase — no fire pulse */
if (!unit_rolling(u->type)) u->anim = 1.0f;
audio_sfx(1);
}
return;
@ -405,7 +423,7 @@ static void unit_harvester_step(Game *g, Unit *u, float dt) {
int add = (d->cargo - u->cargo > take) ? take : (int)(d->cargo - u->cargo);
u->cargo += add;
map_deplete_scrap(&g->map, tx, ty, add);
u->anim = 1.0f;
if (!unit_rolling(u->type)) u->anim = 1.0f;
}
if (u->cargo >= d->cargo) {
int rid = harvester_find_refinery(g, u);
@ -505,7 +523,8 @@ void unit_update(Game *g, float dt) {
for (int i = 0; i < g->unit_count; i++) {
Unit *u = &g->units[i];
if (u->dead) continue;
if (u->anim > 0) u->anim -= dt * 3;
/* infantry/pulse anim decays; wheeled/tracked keep phase radians */
if (!unit_rolling(u->type) && u->anim > 0) u->anim -= dt * 3;
if (u->repath_timer > 0) u->repath_timer -= dt;
if (u->ability_cd > 0) u->ability_cd -= dt;
@ -576,7 +595,8 @@ void unit_update(Game *g, float dt) {
u->heading = (float)atan2(wy - u->y, wx - u->x);
u->x += (wx - u->x) / d * sp;
u->y += (wy - u->y) / d * sp;
u->anim = 1.0f;
if (unit_rolling(u->type)) unit_roll_phase(u, sp);
else u->anim = 1.0f;
}
}
} else if (u->state == STATE_MOVING) {
@ -585,8 +605,11 @@ void unit_update(Game *g, float dt) {
if (d < 4) { u->state = STATE_IDLE; }
else {
float sp = u->speed * dt;
u->heading = (float)atan2(u->dest_y - u->y, u->dest_x - u->x);
u->x += (u->dest_x - u->x)/d * sp;
u->y += (u->dest_y - u->y)/d * sp;
if (unit_rolling(u->type)) unit_roll_phase(u, sp);
else u->anim = 1.0f;
}
}
}