From 2b05f5d490b9830b7b87ec3d7c0244aca59c795c Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 5 Oct 2024 10:00:11 +0200 Subject: [PATCH] shmup:: improved collision radius system, collision debug --- graph.cpp | 2 ++ shmup.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/graph.cpp b/graph.cpp index aae50c97..a53b8ddf 100644 --- a/graph.cpp +++ b/graph.cpp @@ -4784,6 +4784,8 @@ EX bool should_draw_mouse_cursor() { EX void drawMarkers() { + shmup::draw_collision_debug(); + if(!(cmode & sm::NORMAL)) return; if(should_draw_mouse_cursor()) { diff --git a/shmup.cpp b/shmup.cpp index 3a9fc79c..261444d4 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -257,6 +257,25 @@ bool isMonster(monster *m) { return m->type != moPlayer && m->type != moBullet; EX hookset hooks_kill; +struct collision_info { + shiftpoint p1, p2; + color_t col; + }; + +vector collisions; +int collision_debug_level = 2; + +ld collision_radius(monster *m) { + if(m->type == moAsteroid) + return cgi.asteroid_size[m->hitpoints & 7]; + else + return SCALE * 0.15; + } + +ld collision_distance(monster *bullet, monster *target) { + return collision_radius(bullet) + collision_radius(target); + } + void killMonster(monster* m, eMonster who_kills, flagtype flags = 0) { int tk = tkills(); if(callhandlers(false, hooks_kill, m)) return; @@ -452,6 +471,7 @@ monster *playerCrash(monster *who, shiftpoint where) { if(pc[j]->isVirtual) continue; if(!gmatrix.count(pc[j]->base)) continue; double d = sqdist(pc[j]->pat*C0, where); + if(collision_debug_level >= 2) collisions.emplace_back(collision_info{pc[j]->pat*C0, where, 0x0000FFFF}); /* crash into another player -- not taken into account in racing */ if(d < 0.1 * SCALE2 && !racing::on) return pc[j]; /* too far away -- irrelevant in split_screen */ @@ -1089,6 +1109,7 @@ void movePlayer(monster *m, int delta) { crashintomon = playerCrash(m, nat*C0); for(monster *m2: nonvirtual) if(m2!=m && m2->type == passive_switch) { double d = sqdist(m2->pat*C0, nat*C0); + if(collision_debug_level >= 2) collisions.emplace_back(collision_info{m->pat*C0, m2->pat*C0, 0x00FF00FF}); if(d < SCALE2 * 0.2) crashintomon = m2; } } @@ -1635,12 +1656,6 @@ hyperpoint fronttangent(ld x) { else return ztangent(x); } -ld collision_distance(monster *bullet, monster *target) { - if(target->type == moAsteroid) - return SCALE * 0.15 + cgi.asteroid_size[target->hitpoints & 7]; - return SCALE * 0.3; - } - void spawn_asteroids(monster *bullet, monster *target) { if(target->hitpoints <= 1) return; hyperpoint rnd = random_spin() * point2(SCALE/3000., 0); @@ -1802,6 +1817,7 @@ void moveBullet(monster *m, int delta) { if(m->type == moFireball && m2->type == moFireball) continue; if(m->type == moAirball && m2->type == moAirball) continue; double d = hdist(m2->pat*C0, m->pat*C0); + if(collision_debug_level >= 2) collisions.emplace_back(collision_info{m2->pat*C0, m->pat*C0, 0xFF0000FF}); if(d < collision_distance(m, m2)) { @@ -2022,6 +2038,8 @@ void moveMonster(monster *m, int delta) { else if(m->type == moAltDemon || m->type == moHexDemon || m->type == moCrusher || m->type == moMonk) step *= 1.4; + if(collision_debug_level >= 2) collisions.emplace_back(collision_info{goal*C0, m->pat*C0, 0xC04040FF}); + if(m->type == passive_switch) step = 0; if(items[itOrbBeauty] && !m->isVirtual) { @@ -2260,8 +2278,12 @@ void moveMonster(monster *m, int delta) { if(d < SCALE2 * 0.1) crashintomon = m2; } - if(inertia_based) for(int i=0; ipat), tC0(m->pat)) < collision_distance(pc[i], m)) - crashintomon = pc[i]; + if(inertia_based) for(int i=0; i= 2) collisions.emplace_back(collision_info{pc[i]->pat*C0, m->pat*C0, 0x00FFFFFF}); + if(hdist(tC0(pc[i]->pat), tC0(m->pat)) < collision_distance(pc[i], m)) + crashintomon = pc[i]; + } if(!peace::on) for(int i=0; i 200) { turn(200); delta -= 200; if(!delta) return; } + collisions.clear(); + curtime += delta; handleInput(delta); @@ -2918,6 +2942,7 @@ EX void clearMemory() { nextdragon = 0; visibleAt = 0; for(int i=0; ipat = ggmatrix(m->base) * m->at; shiftmatrix view = V * m->at; + if(collision_debug_level) { + ld r = collision_radius(m); + for(int i=0; i<=10; i++) curvepoint(xspinpush0(i * 36._deg, r)); + queuecurve(view, 0xFFFFFFFF, 0, PPR::SUPERLINE); + } + bool half_elliptic = elliptic && GDIM == 3 && WDIM == 2; bool mirrored = det(view.T) > 0; if(half_elliptic && mirrored) continue;