From 3aaf2e80a9cec05c19a181562fb88b84e63b8318 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 22 Oct 2020 20:21:21 +0200 Subject: [PATCH] - moveweapons. --- source/games/duke/src/actors_d.cpp | 120 ++++++++++++++--------------- source/games/duke/src/actors_r.cpp | 111 +++++++++++++------------- source/games/duke/src/player_d.cpp | 2 +- source/games/duke/src/player_r.cpp | 2 +- source/games/duke/src/savegame.cpp | 1 + source/games/duke/src/types.h | 1 + 6 files changed, 116 insertions(+), 121 deletions(-) diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 9dc2d3d67..153d4eab3 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1764,17 +1764,16 @@ static bool weaponhitsector(DDukeActor* proj, const vec3_t& oldpos, bool firebal // //--------------------------------------------------------------------------- -static void weaponcommon_d(int i) +static void weaponcommon_d(DDukeActor* proj) { - auto s = &sprite[i]; - + auto s = &proj->s; if (s->picnum == COOLEXPLOSION1) - if (!S_CheckSoundPlaying(i, WIERDSHOT_FLY)) - S_PlayActorSound(WIERDSHOT_FLY, i); + if (!S_CheckSoundPlaying(proj->GetIndex(), WIERDSHOT_FLY)) + S_PlayActorSound(WIERDSHOT_FLY, proj); int p = -1; int k, ll; - auto oldpos = s->pos; + vec3_t oldpos = s->pos; if (s->picnum == RPG && sector[s->sectnum].lotag == 2) { @@ -1787,47 +1786,47 @@ static void weaponcommon_d(int i) ll = s->zvel; } - getglobalz(i); + getglobalz(proj); switch (s->picnum) { case RPG: - if (hittype[i].picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (proj->picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) { - int j = fi.spawn(i, SMALLSMOKE); - sprite[j].z += (1 << 8); + auto spawned = spawn(proj, SMALLSMOKE); + spawned->s.z += (1 << 8); } break; case FIREBALL: - if (movefireball(&hittype[i])) return; + if (movefireball(proj)) return; break; } - int j = fi.movesprite(i, + int j = fi.movesprite(proj->GetIndex(), (k * (sintable[(s->ang + 512) & 2047])) >> 14, (k * (sintable[s->ang & 2047])) >> 14, ll, CLIPMASK1); - if (s->picnum == RPG && s->yvel >= 0) - if (FindDistance2D(s->x - sprite[s->yvel].x, s->y - sprite[s->yvel].y) < 256) + if (s->picnum == RPG && proj->temp_actor != nullptr) + if (FindDistance2D(s->x - proj->temp_actor->s.x, s->y - proj->temp_actor->s.y) < 256) j = kHitSprite | s->yvel; if (s->sectnum < 0) { - deletesprite(i); + deletesprite(proj); return; } if ((j & kHitTypeMask) != kHitSprite && s->picnum != FREEZEBLAST) { - if (s->z < hittype[i].ceilingz) + if (s->z < proj->ceilingz) { j = kHitSector | (s->sectnum); s->zvel = -1; } else - if ((s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1) || - (s->z > hittype[i].floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) + if ((s->z > proj->floorz && sector[s->sectnum].lotag != 1) || + (s->z > proj->floorz + (16 << 8) && sector[s->sectnum].lotag == 1)) { j = kHitSector | (s->sectnum); if (sector[s->sectnum].lotag != 1) @@ -1839,14 +1838,14 @@ static void weaponcommon_d(int i) { for (k = -3; k < 2; k++) { - int x = EGS(s->sectnum, + auto spawned = EGS(s->sectnum, s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), s->y + ((k * sintable[s->ang & 2047]) >> 9), s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 24)), FIRELASER, -40 + (k << 2), - s->xrepeat, s->yrepeat, 0, 0, 0, s->owner, 5); + s->xrepeat, s->yrepeat, 0, 0, 0, proj->GetOwner(), 5); - sprite[x].cstat = 128; - sprite[x].pal = s->pal; + spawned->s.cstat = 128; + spawned->s.pal = s->pal; } } else if (s->picnum == SPIT) if (s->zvel < 6144) @@ -1856,7 +1855,7 @@ static void weaponcommon_d(int i) { if (s->picnum == COOLEXPLOSION1) { - if ((j & kHitTypeMask) == kHitSprite && sprite[j & kHitIndexMask].picnum != APLAYER) + if ((j & kHitTypeMask) == kHitSprite && hittype[j & kHitIndexMask].s.picnum != APLAYER) { return; } @@ -1864,21 +1863,21 @@ static void weaponcommon_d(int i) s->zvel = 0; } - bool fireball = (isWorldTour() && s->picnum == FIREBALL && sprite[s->owner].picnum != FIREBALL); + bool fireball = (isWorldTour() && s->picnum == FIREBALL && (!proj->GetOwner() || proj->GetOwner()->s.picnum != FIREBALL)); if ((j & kHitTypeMask) == kHitSprite) { j &= kHitIndexMask; - if (weaponhitsprite(&hittype[i], &hittype[j], fireball)) return; + if (weaponhitsprite(proj, &hittype[j], fireball)) return; } else if ((j & kHitTypeMask) == kHitWall) { j &= kHitIndexMask; - if (weaponhitwall(&hittype[i], j, oldpos)) return; + if (weaponhitwall(proj, j, oldpos)) return; } else if ((j & kHitTypeMask) == kHitSector) { - if (weaponhitsector(&hittype[i], oldpos, fireball)) return; + if (weaponhitsector(proj, oldpos, fireball)) return; } if (s->picnum != SPIT) @@ -1886,35 +1885,35 @@ static void weaponcommon_d(int i) if (s->picnum == RPG) { // j is only needed for the hit type mask. - rpgexplode(&hittype[i], j, oldpos, EXPLOSION2, EXPLOSION2BOT, -1, RPG_EXPLODE); + rpgexplode(proj, j, oldpos, EXPLOSION2, EXPLOSION2BOT, -1, RPG_EXPLODE); } else if (s->picnum == SHRINKSPARK) { - fi.spawn(i, SHRINKEREXPLOSION); - S_PlayActorSound(SHRINKER_HIT, i); - fi.hitradius(&hittype[i], shrinkerblastradius, 0, 0, 0, 0); + spawn(proj, SHRINKEREXPLOSION); + S_PlayActorSound(SHRINKER_HIT, proj); + fi.hitradius(proj, shrinkerblastradius, 0, 0, 0, 0); } else if (s->picnum != COOLEXPLOSION1 && s->picnum != FREEZEBLAST && s->picnum != FIRELASER && (!isWorldTour() || s->picnum != FIREBALL)) { - k = fi.spawn(i, EXPLOSION2); - sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat >> 1; + auto k = spawn(proj, EXPLOSION2); + k->s.xrepeat = k->s.yrepeat = s->xrepeat >> 1; if ((j & kHitTypeMask) == kHitSector) { if (s->zvel < 0) { - sprite[k].cstat |= 8; sprite[k].z += (72 << 8); + k->s.cstat |= 8; k->s.z += (72 << 8); } } } if (fireball) { - j = fi.spawn(i, EXPLOSION2); - sprite[j].xrepeat = sprite[j].yrepeat = (short)(s->xrepeat >> 1); + auto spawned = spawn(proj, EXPLOSION2); + spawned->s.xrepeat = spawned->s.yrepeat = (short)(s->xrepeat >> 1); } } if (s->picnum != COOLEXPLOSION1) { - deletesprite(i); + deletesprite(proj); return; } } @@ -1923,12 +1922,12 @@ static void weaponcommon_d(int i) s->shade++; if (s->shade >= 40) { - deletesprite(i); + deletesprite(proj); return; } } else if (s->picnum == RPG && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140)) - fi.spawn(i, WATERBUBBLE); + spawn(proj, WATERBUBBLE); } //--------------------------------------------------------------------------- @@ -1939,58 +1938,55 @@ static void weaponcommon_d(int i) void moveweapons_d(void) { - StatIterator it(STAT_PROJECTILE); - int i; - while ((i = it.NextIndex()) >= 0) + DukeStatIterator it(STAT_PROJECTILE); + while (auto act = it.Next()) { - auto s = &sprite[i]; - - if (s->sectnum < 0) + if (act->s.sectnum < 0) { - deletesprite(i); + deletesprite(act); continue; } - hittype[i].bposx = s->x; - hittype[i].bposy = s->y; - hittype[i].bposz = s->z; + act->bposx = act->s.x; + act->bposy = act->s.y; + act->bposz = act->s.z; - switch(s->picnum) + switch(act->s.picnum) { case RADIUSEXPLOSION: case KNEE: - deletesprite(i); + deletesprite(act); continue; case TONGUE: - movetongue(&hittype[i], TONGUE, INNERJAW); + movetongue(act, TONGUE, INNERJAW); continue; case FREEZEBLAST: - if (s->yvel < 1 || s->extra < 2 || (s->xvel|s->zvel) == 0) + if (act->s.yvel < 1 || act->s.extra < 2 || (act->s.xvel|act->s.zvel) == 0) { - int j = fi.spawn(i,TRANSPORTERSTAR); - sprite[j].pal = 1; - sprite[j].xrepeat = 32; - sprite[j].yrepeat = 32; - deletesprite(i); + auto spawned = spawn(act,TRANSPORTERSTAR); + spawned->s.pal = 1; + spawned->s.xrepeat = 32; + spawned->s.yrepeat = 32; + deletesprite(act); continue; } case FIREBALL: // Twentieth Anniversary World Tour - if (s->picnum == FIREBALL && !isWorldTour()) break; + if (act->s.picnum == FIREBALL && !isWorldTour()) break; case SHRINKSPARK: case RPG: case FIRELASER: case SPIT: case COOLEXPLOSION1: - weaponcommon_d(i); + weaponcommon_d(act); break; case SHOTSPARK1: { int x; - int p = findplayer(s, &x); - execute(i, p, x); + int p = findplayer(&act->s, &x); + execute(act, p, x); break; } } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index f9af98b44..db3900ed1 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1359,12 +1359,12 @@ bool weaponhitsector(DDukeActor *proj, const vec3_t& oldpos) // //--------------------------------------------------------------------------- -static void weaponcommon_r(int i) +static void weaponcommon_r(DDukeActor *proj) { - int j, k, p; - int x, ll; + auto s = &proj->s; + int k, p; + int ll; - auto s = &sprite[i]; p = -1; if (s->picnum == RPG && sector[s->sectnum].lotag == 2) @@ -1385,20 +1385,19 @@ static void weaponcommon_r(int i) auto oldpos = s->pos; - getglobalz(i); + getglobalz(proj); switch (s->picnum) { case RPG: - if (hittype[i].picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) + if (proj->picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) { - j = fi.spawn(i, SMALLSMOKE); - sprite[j].z += (1 << 8); + spawn(proj, SMALLSMOKE)->s.z += (1 << 8); } break; case RPG2: if (!isRRRA()) break; - chickenarrow(&hittype[i]); + chickenarrow(proj); break; case RRTILE1790: @@ -1409,38 +1408,37 @@ static void weaponcommon_r(int i) s->extra--; } else - makeitfall(i); + makeitfall(proj); if (s->xrepeat >= 10 && sector[s->sectnum].lotag != 2) { - j = fi.spawn(i, SMALLSMOKE); - sprite[j].z += (1 << 8); + spawn(proj, SMALLSMOKE)->s.z += (1 << 8); } break; } - j = movesprite_r(i, + int j = fi.movesprite(proj->GetIndex(), (k * (sintable[(s->ang + 512) & 2047])) >> 14, (k * (sintable[s->ang & 2047])) >> 14, ll, CLIPMASK1); - if ((s->picnum == RPG || (isRRRA() && isIn(s->picnum, RPG2, RRTILE1790))) && s->yvel >= 0) - if (FindDistance2D(s->x - sprite[s->yvel].x, s->y - sprite[s->yvel].y) < 256) - j = 49152 | s->yvel; + if ((s->picnum == RPG || (isRRRA() && isIn(s->picnum, RPG2, RRTILE1790))) && proj->temp_actor != nullptr) + if (FindDistance2D(s->x - proj->temp_actor->s.x, s->y - proj->temp_actor->s.y) < 256) + j = kHitSprite | s->yvel; if (s->sectnum < 0) // || (isRR() && sector[s->sectnum].filler == 800)) { - deletesprite(i); + deletesprite(proj); return; } if ((j & kHitTypeMask) != kHitSprite && s->picnum != FREEZEBLAST) { - if (s->z < hittype[i].ceilingz) + if (s->z < proj->ceilingz) { j = kHitSector | (s->sectnum); s->zvel = -1; } else - if (s->z > hittype[i].floorz) + if (s->z > proj->floorz) { j = kHitSector | (s->sectnum); if (sector[s->sectnum].lotag != 1) @@ -1452,14 +1450,14 @@ static void weaponcommon_r(int i) { for (k = -3; k < 2; k++) { - x = EGS(s->sectnum, + auto x = EGS(s->sectnum, s->x + ((k * sintable[(s->ang + 512) & 2047]) >> 9), s->y + ((k * sintable[s->ang & 2047]) >> 9), s->z + ((k * ksgn(s->zvel)) * abs(s->zvel / 24)), FIRELASER, -40 + (k << 2), - s->xrepeat, s->yrepeat, 0, 0, 0, s->owner, 5); + s->xrepeat, s->yrepeat, 0, 0, 0, proj->GetOwner(), 5); - sprite[x].cstat = 128; - sprite[x].pal = s->pal; + x->s.cstat = 128; + x->s.pal = s->pal; } } else if (s->picnum == SPIT) if (s->zvel < 6144) @@ -1470,41 +1468,43 @@ static void weaponcommon_r(int i) if ((j & kHitTypeMask) == kHitSprite) { j &= kHitIndexMask; - if (weaponhitsprite(&hittype[i], &hittype[j], oldpos)) return; + if (weaponhitsprite(proj, &hittype[j], oldpos)) return; } else if ((j & kHitTypeMask) == kHitWall) { j &= kHitIndexMask; - if (weaponhitwall(&hittype[i], j, oldpos)) return; + if (weaponhitwall(proj, j, oldpos)) return; } - else if ((j & 49152) == 16384) + else if ((j & kHitTypeMask) == kHitSector) { - if (weaponhitsector(&hittype[i], oldpos)) return; + if (weaponhitsector(proj, oldpos)) return; } if (s->picnum != SPIT) { - if (s->picnum == RPG) rpgexplode(&hittype[i], j, oldpos, EXPLOSION2, -1, -1, RPG_EXPLODE); - else if (isRRRA() && s->picnum == RPG2) rpgexplode(&hittype[i], j, oldpos, EXPLOSION2, -1, 150, 247); - else if (isRRRA() && s->picnum == RRTILE1790) rpgexplode(&hittype[i], j, oldpos, EXPLOSION2, -1, 160, RPG_EXPLODE); + if (s->picnum == RPG) rpgexplode(proj, j, oldpos, EXPLOSION2, -1, -1, RPG_EXPLODE); + else if (isRRRA() && s->picnum == RPG2) rpgexplode(proj, j, oldpos, EXPLOSION2, -1, 150, 247); + else if (isRRRA() && s->picnum == RRTILE1790) rpgexplode(proj, j, oldpos, EXPLOSION2, -1, 160, RPG_EXPLODE); else if (s->picnum != FREEZEBLAST && s->picnum != FIRELASER && s->picnum != SHRINKSPARK) { - k = fi.spawn(i, 1441); - sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat >> 1; + auto k = spawn(proj, 1441); + k->s.xrepeat = k->s.yrepeat = s->xrepeat >> 1; if ((j & kHitTypeMask) == kHitSector) { if (s->zvel < 0) { - sprite[k].cstat |= 8; sprite[k].z += (72 << 8); + k->s.cstat |= 8; + k->s.z += (72 << 8); } } } } - deletesprite(i); + deletesprite(proj); return; } if ((s->picnum == RPG || (isRRRA() && s->picnum == RPG2)) && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(184)) - fi.spawn(i, WATERBUBBLE); + spawn(proj, WATERBUBBLE); + } //--------------------------------------------------------------------------- @@ -1515,39 +1515,36 @@ static void weaponcommon_r(int i) void moveweapons_r(void) { - StatIterator it(STAT_PROJECTILE); - int i; - while ((i = it.NextIndex()) >= 0) + DukeStatIterator it(STAT_PROJECTILE); + while (auto proj = it.Next()) { - auto s = &sprite[i]; - - if (s->sectnum < 0) + if (proj->s.sectnum < 0) { - deletesprite(i); + deletesprite(proj); continue; } - hittype[i].bposx = s->x; - hittype[i].bposy = s->y; - hittype[i].bposz = s->z; + proj->bposx = proj->s.x; + proj->bposy = proj->s.y; + proj->bposz = proj->s.z; - switch (s->picnum) + switch (proj->s.picnum) { case RADIUSEXPLOSION: - deletesprite(i); + deletesprite(proj); continue; case TONGUE: - movetongue(&hittype[i], TONGUE, INNERJAW); + movetongue(proj, TONGUE, INNERJAW); continue; case FREEZEBLAST: - if (s->yvel < 1 || s->extra < 2 || (s->xvel | s->zvel) == 0) + if (proj->s.yvel < 1 || proj->s.extra < 2 || (proj->s.xvel | proj->s.zvel) == 0) { - int j = fi.spawn(i, TRANSPORTERSTAR); - sprite[j].pal = 1; - sprite[j].xrepeat = 32; - sprite[j].yrepeat = 32; - deletesprite(i); + auto star = spawn(proj, TRANSPORTERSTAR); + star->s.pal = 1; + star->s.xrepeat = 32; + star->s.yrepeat = 32; + deletesprite(proj); continue; } case RPG2: @@ -1560,15 +1557,15 @@ void moveweapons_r(void) case COOLEXPLOSION1: case OWHIP: case UWHIP: - weaponcommon_r(i); + weaponcommon_r(proj); continue; case SHOTSPARK1: { int x; - int p = findplayer(s, &x); - execute(i, p, x); + int p = findplayer(&proj->s, &x); + execute(proj, p, x); continue; } } diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 2ccf2eb6d..cdeff037c 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -733,7 +733,7 @@ static void shootrpg(int i, int p, int sx, int sy, int sz, int sa, int atwith) auto spj = &sprite[j]; spj->extra += (krand() & 7); if (atwith != FREEZEBLAST) - spj->yvel = l; + hittype[j].temp_actor = l >= 0? &hittype[l] : nullptr;// sprite[j].yvel = l; else { spj->yvel = numfreezebounces; diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index fa9bbb77e..8424b0def 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -702,7 +702,7 @@ static void shootrpg(int i, int p, int sx, int sy, int sz, int sa, int atwith) sprite[j].extra += (krand() & 7); if (atwith != FREEZEBLAST) - sprite[j].yvel = l; + hittype[j].temp_actor = l >= 0? &hittype[l] : nullptr;// sprite[j].yvel = l; else { sprite[j].yvel = numfreezebounces; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 284e190a4..6a822f730 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -335,6 +335,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, weaponhit& w, weap ("bposy", w.bposy, def->bposy) ("bposz", w.bposz, def->bposz) ("aflags", w.aflags, def->aflags) + ("temp_actor", w.temp_actor, def->temp_actor) .Array("temp_data", w.temp_data, def->temp_data, 6) .EndObject(); } diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index dc909f4bc..bb4d5f214 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -30,6 +30,7 @@ struct weaponhit short timetosleep; int floorz, ceilingz, lastvx, lastvy, bposx, bposy, bposz, aflags; int temp_data[6]; + weaponhit* temp_actor; spritetype& s; // direct reference to the corresponding sprite. static weaponhit* array(); // this is necessary to allow define inline functions referencing the global array inside the definition itself.