diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 2088b3a50..a34da0b9f 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -107,6 +107,14 @@ struct HitInfoBase return kHitSector; } + int setSector(sectortype* num) + { + *this = {}; + type = kHitSector; + hitSector = num; + return kHitSector; + } + int setWall(int num) { *this = {}; @@ -115,6 +123,14 @@ struct HitInfoBase return kHitWall; } + int setWall(walltype* num) + { + *this = {}; + type = kHitWall; + hitWall = num; + return kHitWall; + } + int setSprite(int num) { *this = {}; diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index d9b5174c1..49a018afc 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -903,9 +903,8 @@ post_analyzesprites(spritetype* tsprite, int& spritesortcnt) void CircleCamera(int *nx, int *ny, int *nz, sectortype** vsect, binangle *nang, fixed_t q16horiz) { - vec3_t n = { *nx, *ny, *nz }; SPRITEp sp; - hitdata_t hit_info; + HitInfo hit; int i, vx, vy, vz, hx, hy; int bakcstat, daang; PLAYERp pp = &Player[screenpeek]; @@ -932,23 +931,22 @@ CircleCamera(int *nx, int *ny, int *nz, sectortype** vsect, binangle *nang, fixe // Make sure sector passed to hitscan is correct //updatesector(*nx, *ny, vsect); - hitscan(&n, sectnum(*vsect), vx, vy, vz, &hit_info, CLIPMASK_MISSILE); - HITINFO hitinfo; hitinfo.set(&hit_info); + hitscan({ *nx, *ny, *nz }, *vsect, { vx, vy, vz }, hit, CLIPMASK_MISSILE); sp->cstat = bakcstat; // Restore cstat //ASSERT(hitinfo.sect >= 0); - hx = hitinfo.pos.x - (*nx); - hy = hitinfo.pos.y - (*ny); + hx = hit.hitpos.x - (*nx); + hy = hit.hitpos.y - (*ny); // If something is in the way, make pp->circle_camera_dist lower if necessary if (abs(vx) + abs(vy) > abs(hx) + abs(hy)) { - if (hitinfo.wall()) // Push you a little bit off the wall + if (hit.hitWall) // Push you a little bit off the wall { - *vsect = hitinfo.sector(); + *vsect = hit.hitSector; - daang = getangle(hitinfo.wall()->delta()); + daang = getangle(hit.hitWall->delta()); i = vx * bsin(daang) + vy * -bcos(daang); if (abs(vx) > abs(vy)) @@ -956,9 +954,9 @@ CircleCamera(int *nx, int *ny, int *nz, sectortype** vsect, binangle *nang, fixe else hy -= MulScale(vy, i, 28); } - else if (hitinfo.hitactor == nullptr) // Push you off the ceiling/floor + else if (hit.actor() == nullptr) // Push you off the ceiling/floor { - *vsect = hitinfo.sector(); + *vsect = hit.hitSector; if (abs(vx) > abs(vy)) hx -= (vx >> 5); @@ -967,7 +965,7 @@ CircleCamera(int *nx, int *ny, int *nz, sectortype** vsect, binangle *nang, fixe } else { - SPRITEp hsp = &hitinfo.hitactor->s(); + SPRITEp hsp = &hit.actor()->s(); int flag_backup; // if you hit a sprite that's not a wall sprite - try again diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp index abfacdbe9..b6527178d 100644 --- a/source/games/sw/src/player.cpp +++ b/source/games/sw/src/player.cpp @@ -2651,7 +2651,7 @@ void DoPlayerMoveVehicle(PLAYERp pp) if (RectClip) { - hitdata_t hitinfo; + HitInfo hit; int vel; int ret; @@ -2671,17 +2671,16 @@ void DoPlayerMoveVehicle(PLAYERp pp) { vec3_t hit_pos = { DIV2(x[0] + x[1]), DIV2(y[0] + y[1]), pp->cursector()->floorz - Z(10) }; - hitscan(&hit_pos, pp->cursectnum, - //pp->xvect, pp->yvect, 0, - MOVEx(256, pp->angle.ang.asbuild()), MOVEy(256, pp->angle.ang.asbuild()), 0, - &hitinfo, CLIPMASK_PLAYER); + hitscan(hit_pos, pp->cursector(), + { MOVEx(256, pp->angle.ang.asbuild()), MOVEy(256, pp->angle.ang.asbuild()), 0 }, + hit, CLIPMASK_PLAYER); - if (FindDistance2D(hitinfo.pos.x - hit_pos.x, hitinfo.pos.y - hit_pos.y) < 800) + if (FindDistance2D(hit.hitpos.x - hit_pos.x, hit.hitpos.y - hit_pos.y) < 800) { - if (hitinfo.wall >= 0) - u->coll.setWall(hitinfo.wall); - else if (hitinfo.sprite >= 0) - u->coll.setSprite(&swActors[hitinfo.sprite]); + if (hit.hitWall) + u->coll.setWall(wallnum(hit.hitWall)); + else if (hit.actor()) + u->coll.setSprite(hit.actor()); else u->coll.setNone(); diff --git a/source/games/sw/src/rooms.cpp b/source/games/sw/src/rooms.cpp index 0dc74d01d..3ea52d808 100644 --- a/source/games/sw/src/rooms.cpp +++ b/source/games/sw/src/rooms.cpp @@ -294,31 +294,29 @@ bool FAFcansee(int32_t xs, int32_t ys, int32_t zs, sectortype* sects, else zvect = 0; - hitdata_t e_hitinfo; - hitscan(&s, sectnum(sects), xvect, yvect, zvect, &e_hitinfo, CLIPMASK_MISSILE); - HITINFO hitinfo; - hitinfo.set(&e_hitinfo); + HitInfo hit; + hitscan(s, sects, { xvect, yvect, zvect }, hit, CLIPMASK_MISSILE); - if (hitinfo.sector() == nullptr) + if (hit.hitSector == nullptr) return false; // make sure it hit JUST a sector before doing a check - if (hitinfo.wall() == nullptr && hitinfo.hitactor == nullptr) + if (hit.hitWall == nullptr && hit.actor() == nullptr) { - getzsofslopeptr(hitinfo.sector(), hitinfo.pos.x, hitinfo.pos.y, &hiz, &loz); - if (labs(hitinfo.pos.z - loz) < Z(4)) + getzsofslopeptr(hit.hitSector, hit.hitpos.x, hit.hitpos.y, &hiz, &loz); + if (labs(hit.hitpos.z - loz) < Z(4)) { - if (FAF_ConnectFloor(hitinfo.sector())) + if (FAF_ConnectFloor(hit.hitSector)) { - updatesectorz(hitinfo.pos.x, hitinfo.pos.y, hitinfo.pos.z + Z(12), &newsect); + updatesectorz(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z + Z(12), &newsect); plax_found = true; } } - else if (labs(hitinfo.pos.z - hiz) < Z(4)) + else if (labs(hit.hitpos.z - hiz) < Z(4)) { - if (FAF_ConnectCeiling(hitinfo.sector())) + if (FAF_ConnectCeiling(hit.hitSector)) { - updatesectorz(hitinfo.pos.x, hitinfo.pos.y, hitinfo.pos.z - Z(12), &newsect); + updatesectorz(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z - Z(12), &newsect); plax_found = true; } } @@ -329,7 +327,7 @@ bool FAFcansee(int32_t xs, int32_t ys, int32_t zs, sectortype* sects, } if (plax_found) - return !!cansee(hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z,newsect,xe,ye,ze,secte); + return !!cansee(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, newsect, xe, ye, ze, secte); return false; } diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index ce0f5987b..f81d307e0 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -1940,21 +1940,18 @@ void SpriteSetup(void) case SECT_WALL_PAN_SPEED: { vec3_t hit_pos = { sp->x, sp->y, sp->z - Z(8) }; - hitdata_t hitinfo; + HitInfo hit; - hitscan(&hit_pos, sp->sectnum, // Start position - bcos(sp->ang), // X vector of 3D ang - bsin(sp->ang), // Y vector of 3D ang - 0, // Z vector of 3D ang - &hitinfo, CLIPMASK_MISSILE); + hitscan(hit_pos, sp->sector(), // Start position + { bcos(sp->ang), bsin(sp->ang), 0 }, hit, CLIPMASK_MISSILE); - if (hitinfo.wall == -1) + if (hit.hitWall == nullptr) { KillActor(actor); break; } - actor->tempwall = &wall[hitinfo.wall]; + actor->tempwall = hit.hitWall; // if moves with SO if (TEST_BOOL1(sp)) sp->xvel = 0; @@ -1962,9 +1959,9 @@ void SpriteSetup(void) sp->xvel = sp->lotag; sp->ang = SP_TAG6(sp); // attach to the sector that contains the wall - ChangeActorSect(actor, hitinfo.sect); - StartInterpolation(hitinfo.wall, Interp_Wall_PanX); - StartInterpolation(hitinfo.wall, Interp_Wall_PanY); + ChangeActorSect(actor, hit.hitSector); + StartInterpolation(hit.hitWall, Interp_Wall_PanX); + StartInterpolation(hit.hitWall, Interp_Wall_PanY); change_actor_stat(actor, STAT_WALL_PAN); break; } @@ -1972,21 +1969,18 @@ void SpriteSetup(void) case WALL_DONT_STICK: { vec3_t hit_pos = { sp->x, sp->y, sp->z - Z(8) }; - hitdata_t hitinfo; + HitInfo hit; - hitscan(&hit_pos, sp->sectnum, // Start position - bcos(sp->ang), // X vector of 3D ang - bcos(sp->ang), // Y vector of 3D ang - 0, // Z vector of 3D ang - &hitinfo, CLIPMASK_MISSILE); + hitscan(hit_pos, sp->sector(), // Start position + { bcos(sp->ang), bsin(sp->ang), 0 }, hit, CLIPMASK_MISSILE); - if (hitinfo.wall == -1) + if (hit.hitWall == nullptr) { KillActor(actor); break; } - SET(wall[hitinfo.wall].extra, WALLFX_DONT_STICK); + SET(hit.hitWall->extra, WALLFX_DONT_STICK); KillActor(actor); break; } diff --git a/source/games/sw/src/swactor.h b/source/games/sw/src/swactor.h index 9c1540d8e..edf1f9426 100644 --- a/source/games/sw/src/swactor.h +++ b/source/games/sw/src/swactor.h @@ -46,6 +46,15 @@ extern DSWActor swActors[MAXSPRITES]; inline DSWActor* DSWActor::base() { return swActors; } +// subclassed to add a game specific actor() method +struct HitInfo : public HitInfoBase +{ + DSWActor* actor() const + { + return static_cast(hitActor); + } +}; + // Iterator wrappers that return an actor pointer, not an index. class SWStatIterator : public StatIterator { diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index 72200d281..86c554ad7 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -4478,21 +4478,17 @@ bool WeaponMoveHit(DSWActor* actor) // clipmove does not correctly return the sprite for WALL sprites // on walls, so look with hitscan - hitdata_t hitinfo; - hitscan(&sp->pos, sp->sectnum, // Start position - bcos(sp->ang), // X vector of 3D ang - bsin(sp->ang), // Y vector of 3D ang - sp->zvel, // Z vector of 3D ang - &hitinfo, CLIPMASK_MISSILE); + HitInfo hit; + hitscan(sp->pos, sp->sector(), { bcos(sp->ang), bsin(sp->ang), sp->zvel }, hit, CLIPMASK_MISSILE); - if (hitinfo.sect < 0) + if (!hit.hitSector) { return false; } - if (hitinfo.sprite >= 0) + if (hit.actor()) { - auto hitActor = &swActors[hitinfo.sprite]; + auto hitActor = hit.actor(); SPRITEp hsp = &hitActor->s(); if (hsp->lotag == TAG_SPRITE_HIT_MATCH)