diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index c2a949f0f..e4841f9c6 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -885,14 +885,12 @@ post_analyzesprites(spritetype* tsprite, int& spritesortcnt) if (tu) { - if (tu->ID == FIREBALL_FLAMES && tu->Attach >= 0) + if (tu->ID == FIREBALL_FLAMES && tu->attachActor != nullptr) { - tspriteptr_t const atsp = get_tsprite(tsprite, spritesortcnt, tu->Attach); + tspriteptr_t const atsp = get_tsprite(tsprite, spritesortcnt, tu->attachActor->GetSpriteIndex()); if (!atsp) { - //DSPRINTF(ds,"Attach not found"); - MONO_PRINT(ds); continue; } diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index fba009932..f64e89c18 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -1127,6 +1127,7 @@ struct USER DSWActor* lowActor, * highActor; DSWActor* targetActor; // target player for the enemy - can only handle one player at at time DSWActor* flameActor; + DSWActor* attachActor; // attach to sprite if needed - electro snake int Flags; int Flags2; @@ -1159,7 +1160,6 @@ struct USER int active_range; short SpriteNum; - short Attach; // attach to sprite if needed - electro snake SPRITEp SpriteP; SPRITEp s() { return SpriteP;} @@ -1970,7 +1970,7 @@ void change_actor_stat(DSWActor* actor, int stat); void SetOwner(DSWActor*, DSWActor*); void SetOwner(int a, int b); // we still need this... void ClearOwner(DSWActor* ownr); -void SetAttach(short, short); +void SetAttach(DSWActor*, DSWActor*); void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, int camang); void ChangeSpriteState(short SpriteNum, STATEp statep); void CollectPortals(); diff --git a/source/games/sw/src/jweapon.cpp b/source/games/sw/src/jweapon.cpp index 198f2817d..1a73b2fe1 100644 --- a/source/games/sw/src/jweapon.cpp +++ b/source/games/sw/src/jweapon.cpp @@ -1788,7 +1788,7 @@ void SpawnFlashBombOnActor(DSWActor* actor) if (u->flameActor != nullptr) { - SetAttach(actor->GetSpriteIndex(), actorNew->GetSpriteIndex()); + SetAttach(actor, actorNew); } return; @@ -2186,9 +2186,9 @@ DoCarryFlag(DSWActor* actor) // if no owner then die - if (u->Attach >= 0) + if (u->attachActor != nullptr) { - SPRITEp ap = &sprite[u->Attach]; + SPRITEp ap = &u->attachActor->s(); setspritez_old(Weapon, ap->x, ap->y, SPRITEp_MID(ap)); sp->ang = NORM_ANGLE(ap->ang + 1536); @@ -2217,8 +2217,8 @@ DoCarryFlag(DSWActor* actor) // not already in detonate state if (u->Counter2 < FLAG_DETONATE_STATE) { - SPRITEp ap = &sprite[u->Attach]; - USERp au = User[u->Attach].Data(); + SPRITEp ap = &u->attachActor->s(); + USERp au = u->attachActor->u(); if (!au || au->Health <= 0) { @@ -2336,8 +2336,8 @@ DoCarryFlagNoDet(DSWActor* actor) int Weapon = u->SpriteNum; SPRITEp sp = &sprite[Weapon]; - SPRITEp ap = &sprite[u->Attach]; - USERp au = User[u->Attach].Data(); + SPRITEp ap = &u->attachActor->s(); + USERp au = u->attachActor->u(); SPRITEp fp = &sprite[u->FlagOwner]; USERp fu = User[u->FlagOwner].Data(); @@ -2347,9 +2347,9 @@ DoCarryFlagNoDet(DSWActor* actor) // won't respawn // if no owner then die - if (u->Attach >= 0) + if (u->attachActor != nullptr) { - SPRITEp ap = &sprite[u->Attach]; + SPRITEp ap = &u->attachActor->s(); setspritez_old(Weapon, ap->x, ap->y, SPRITEp_MID(ap)); sp->ang = NORM_ANGLE(ap->ang + 1536); @@ -2433,6 +2433,7 @@ DoFlag(DSWActor* actor) if (hit_sprite != -1) { + auto hitActor = &swActors[hit_sprite]; SPRITEp hsp = &sprite[hit_sprite]; SetCarryFlag(Weapon); @@ -2442,7 +2443,7 @@ DoFlag(DSWActor* actor) { // attach weapon to sprite RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); - SetAttach(hit_sprite, Weapon); + SetAttach(hitActor, actor); u->sz = hsp->z - DIV2(SPRITEp_SIZE_Z(hsp)); //u->sz = hsp->z - SPRITEp_MID(hsp); // Set mid way up who it hit } diff --git a/source/games/sw/src/light.cpp b/source/games/sw/src/light.cpp index c16ef837a..2d18bab74 100644 --- a/source/games/sw/src/light.cpp +++ b/source/games/sw/src/light.cpp @@ -149,6 +149,7 @@ void DoLightingMatch(short match, short state) StatIterator it(STAT_LIGHTING); while ((i = it.NextIndex()) >= 0) { + auto u = User[i].Data(); sp = &sprite[i]; if (LIGHT_Match(sp) != match) @@ -169,7 +170,7 @@ void DoLightingMatch(short match, short state) { SET_BOOL1(sp); sp->shade = -LIGHT_MaxBright(sp); - sp->pal = User[sp-sprite]->spal; // on + sp->pal = u->spal; // on SectorLightShade(sp, sp->shade); DiffuseLighting(sp); } @@ -291,6 +292,7 @@ void DoLighting(void) StatIterator it(STAT_LIGHTING); while ((i = it.NextIndex()) >= 0) { + auto u = User[i].Data(); sp = &sprite[i]; // on/off test @@ -378,7 +380,7 @@ void DoLighting(void) else { sp->shade -= LIGHT_ShadeInc(sp); - sp->pal = User[sp-sprite]->spal; // on + sp->pal = u->spal; // on if (sp->shade <= -LIGHT_MaxBright(sp)) { LIGHT_DirChange(sp); diff --git a/source/games/sw/src/save.cpp b/source/games/sw/src/save.cpp index 32cbeccaa..5b9cfea66 100644 --- a/source/games/sw/src/save.cpp +++ b/source/games/sw/src/save.cpp @@ -870,7 +870,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, USER& w, USER* def ("lo_sp", w.lowActor, def->lowActor) ("active_range", w.active_range, def->active_range) ("SpriteNum", w.SpriteNum, def->SpriteNum) - ("Attach", w.Attach, def->Attach) + ("Attach", w.attachActor, def->attachActor) ("SpriteP", w.SpriteP, def->SpriteP) ("PlayerP", w.PlayerP, def->PlayerP) ("Sibling", w.Sibling, def->Sibling) diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index 2a4dd0c26..e3d5d3825 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -607,16 +607,14 @@ void SetOwner(int a, int b) else if (b >= 0) ClearOwner(&swActors[b]); } -void -SetAttach(short owner, short child) +void SetAttach(DSWActor* ownr, DSWActor* child) { - USERp cu = User[child].Data(); - - ASSERT(cu); - - ASSERT(User[owner].Data()); - SET(User[owner]->Flags2, SPR2_CHILDREN); - cu->Attach = owner; + if (child && child->hasU() && ownr->hasU()) + { + USERp cu = child->u(); + SET(ownr->u()->Flags2, SPR2_CHILDREN); + cu->attachActor = ownr; + } } void KillActor(DSWActor* actor) @@ -760,9 +758,9 @@ void KillSprite(int16_t SpriteNum) sprite[i].owner = -1; } - if (User[i].Data() && User[i]->Attach == SpriteNum) + if (User[i].Data() && User[i]->attachActor == actor) { - User[i]->Attach = -1; + User[i]->attachActor = nullptr; } } } @@ -903,7 +901,7 @@ SpawnUser(short SpriteNum, short id, STATEp state) u->ID = id; u->Health = 100; u->WpnGoal = -1; // for weapons - u->Attach = -1; + u->attachActor = nullptr; u->track = -1; u->targetActor = Player[0].Actor(); u->Radius = 220; @@ -6430,6 +6428,7 @@ KeyMain: break; case ICON_FLAG: + { if (sp->pal == sprite[pp->PlayerSprite].pal) break; // Can't pick up your own flag! PlaySound(DIGI_ITEM, sp, v3df_dontpan); @@ -6441,6 +6440,7 @@ KeyMain: New = SpawnSprite(STAT_ITEM, ICON_FLAG, s_CarryFlag, sp->sectnum, sp->x, sp->y, sp->z, 0, 0); + auto actorNew = &swActors[New]; np = &sprite[New]; nu = User[New].Data(); np->shade = -20; @@ -6449,7 +6449,7 @@ KeyMain: nu->Counter = 0; RESET(np->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); SET(np->cstat, CSTAT_SPRITE_ALIGNMENT_WALL); - SetAttach(pp->PlayerSprite, New); + SetAttach(pp->Actor(), actorNew); nu->sz = SPRITEp_MID(&sprite[pp->PlayerSprite]); // Set mid way up who it hit nu->spal = np->pal = sp->pal; // Set the palette of the flag @@ -6457,7 +6457,7 @@ KeyMain: nu->FlagOwner = SpriteNum; // Tell carried flag who owns it KillGet(SpriteNum); // Set up for flag respawning break; - + } default: KillActor(actor); } diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index 273ade33b..fb9597a0c 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -4529,12 +4529,6 @@ WeaponMoveHit(short SpriteNum) hsp = &sprite[hit_sprite]; hu = User[hit_sprite].Data(); - if (hsp->statnum == STAT_ENEMY) - { - ////DSPRINTF(ds, "Bullet Hit Monster %d, stat %d ", hsp-sprite, (short)hsp->statnum); - //MONO_PRINT(ds); - } - ASSERT(hsp->extra != -1); if (TEST(hsp->extra, SPRX_BREAKABLE)) @@ -4726,9 +4720,9 @@ DoFireballFlames(DSWActor* actor) bool jumping = false; // if no owner then stay where you are - if (u->Attach >= 0) + if (u->attachActor != nullptr) { - ap = &sprite[u->Attach]; + ap = &u->attachActor->s(); sp->x = ap->x; sp->y = ap->y; @@ -4786,10 +4780,10 @@ DoFireballFlames(DSWActor* actor) if (((signed char)sp->xrepeat) == 0) { - if (u->Attach >= 0) + if (u->attachActor != nullptr) { - User[u->Attach]->flameActor = nullptr; - User[u->Attach]->Flags2 &= ~SPR2_FLAMEDIE; + u->attachActor->u()->flameActor = nullptr; + u->attachActor->u()->Flags2 &= ~SPR2_FLAMEDIE; } KillActor(actor); return 0; @@ -4862,10 +4856,10 @@ DoBreakFlames(DSWActor* actor) if (((signed char)sp->xrepeat) == 0) { - if (u->Attach >= 0) + if (u->attachActor != nullptr) { - User[u->Attach]->flameActor = nullptr; - User[u->Attach]->Flags2 &= ~SPR2_FLAMEDIE; + u->attachActor->u()->flameActor = nullptr; + u->attachActor->u()->Flags2 &= ~SPR2_FLAMEDIE; } KillActor(actor); return 0; @@ -8564,17 +8558,19 @@ InitPlasmaFountain(SPRITEp wp, SPRITEp sp) SPRITEp np; USERp nu; short SpriteNum; + auto sActor = &swActors[sp - sprite]; SpriteNum = SpawnSprite(STAT_MISSILE, PLASMA_FOUNTAIN, s_PlasmaFountain, sp->sectnum, sp->x, sp->y, SPRITEp_BOS(sp), sp->ang, 0); + auto actorNew = &swActors[SpriteNum]; np = &sprite[SpriteNum]; nu = User[SpriteNum].Data(); np->shade = -40; if (wp) SetOwner(wp->owner, SpriteNum); - SetAttach(short(sp - sprite), SpriteNum); + SetAttach(sActor, actorNew); np->yrepeat = 0; np->clipdist = 8>>2; @@ -8595,15 +8591,15 @@ DoPlasmaFountain(DSWActor* actor) short bak_cstat; // if no owner then die - if (u->Attach < 0) + if (u->attachActor == nullptr) { KillActor(actor); return 0; } else { - auto attachActor = &swActors[u->Attach]; - ap = &sprite[u->Attach]; + auto attachActor = u->attachActor; + ap = &attachActor->s(); // move with sprite setspritez(Weapon, &ap->pos); @@ -8617,7 +8613,7 @@ DoPlasmaFountain(DSWActor* actor) { SpawnBlood(attachActor, actor, 0, 0, 0, 0); if (RandomRange(1000) > 600) - InitBloodSpray(short(ap-sprite), false, 105); + InitBloodSpray(attachActor->GetSpriteIndex(), false, 105); } } @@ -9370,10 +9366,11 @@ DoMineStuck(DSWActor* actor) #define MINE_DETONATE_STATE 99 // if no owner then die - if (u->Attach >= 0) + auto attachActor = u->attachActor; + if (attachActor != nullptr) { - SPRITEp ap = &sprite[u->Attach]; - USERp au = User[u->Attach].Data(); + SPRITEp ap = &attachActor->s(); + USERp au = attachActor->u(); ASSERT(au); @@ -9585,6 +9582,7 @@ DoMine(DSWActor* actor) case HIT_SPRITE: { short hit_sprite = NORM_SPRITE(u->ret); + auto hitActor = &swActors[hit_sprite]; SPRITEp hsp = &sprite[hit_sprite]; USERp hu = User[hit_sprite].Data(); @@ -9602,7 +9600,7 @@ DoMine(DSWActor* actor) PLAYERp pp; // attach weapon to sprite - SetAttach(hit_sprite, Weapon); + SetAttach(hitActor, actor); u->sz = sprite[hit_sprite].z - sp->z; if (sp->owner >= 0) @@ -9849,14 +9847,12 @@ DoEMPBurst(DSWActor* actor) { USER* u = actor->u(); int Weapon = u->SpriteNum; - SPRITEp sp = &sprite[Weapon]; + SPRITEp sp = &actor->s(); - if (u->Attach >= 0) + auto attachActor = u->attachActor; + if (attachActor != nullptr) { - SPRITEp ap = &sprite[u->Attach]; - USERp au = User[u->Attach].Data(); - - ASSERT(au); + SPRITEp ap = &attachActor->s(); setspritez_old(Weapon, ap->x, ap->y, ap->z - u->sz); sp->ang = NORM_ANGLE(ap->ang+1024); @@ -10798,7 +10794,7 @@ void SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) if (enemy >= 0) { - SetAttach(enemy, actorNew->GetSpriteIndex()); + SetAttach(&swActors[enemy], actorNew); } else { @@ -17651,6 +17647,7 @@ InitEMP(PLAYERp pp) j = SpawnSprite(STAT_MISSILE, EMP, s_EMPBurst, hitinfo.sect, hitinfo.pos.x, hitinfo.pos.y, hitinfo.pos.z, daang, 0); + auto missileActor = &swActors[j]; wp = &sprite[j]; wu = User[j].Data(); @@ -17750,7 +17747,7 @@ InitEMP(PLAYERp pp) if (TEST(hsp->extra, SPRX_PLAYER_OR_ENEMY)) { // attach weapon to sprite - SetAttach(hitinfo.sprite, j); + SetAttach(&swActors[hitinfo.sprite], missileActor); wu->sz = sprite[hitinfo.sprite].z - wp->z; if (RandomRange(1000) > 500) PlayerSound(DIGI_YOULOOKSTUPID, v3df_follow|v3df_dontpan,pp);