diff --git a/source/games/sw/src/actor.cpp b/source/games/sw/src/actor.cpp index 2a9a40615..8718d1177 100644 --- a/source/games/sw/src/actor.cpp +++ b/source/games/sw/src/actor.cpp @@ -303,9 +303,7 @@ void DoDebrisCurrent(DSWActor* actor) nx = MulScale(DIV4(sectu->speed), bcos(sectu->ang), 14); ny = MulScale(DIV4(sectu->speed), bsin(sectu->ang), 14); - // faster than move_sprite - //move_missile(sp-sprite, nx, ny, 0, Z(2), Z(0), 0, ACTORMOVETICS); - ret = move_sprite(int(sp-sprite), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS); + ret = move_sprite(actor->GetSpriteIndex(), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS); // attempt to move away from wall if (ret) @@ -315,7 +313,7 @@ void DoDebrisCurrent(DSWActor* actor) nx = MulScale(DIV4(sectu->speed), bcos(sectu->ang + rang), 14); nx = MulScale(DIV4(sectu->speed), bsin(sectu->ang + rang), 14); - move_sprite(int(sp-sprite), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS); + move_sprite(actor->GetSpriteIndex(), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS); } sp->z = u->loz; diff --git a/source/games/sw/src/ai.cpp b/source/games/sw/src/ai.cpp index dd4aebfba..46c367870 100644 --- a/source/games/sw/src/ai.cpp +++ b/source/games/sw/src/ai.cpp @@ -108,15 +108,13 @@ bool ActorFlaming(DSWActor* actor) USERp u = actor->u(); SPRITEp sp = &actor->s(); - if (u->flame >= 0) + if (u->flameActor != nullptr) { int size; - SPRITEp fp = &sprite[u->flame]; + SPRITEp fp = &u->flameActor->s(); size = SPRITEp_SIZE_Z(sp) - DIV4(SPRITEp_SIZE_Z(sp)); - //DSPRINTF(ds,"enemy size %d, flame size %d",size>>8,SPRITEp_SIZE_Z(fp)>>8); - if (SPRITEp_SIZE_Z(fp) > size) return true; } diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index b948c8d94..7b02def82 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -1104,6 +1104,11 @@ struct USER SECTOR_OBJECTp sop_parent; // denotes that this sprite is a part of the // sector object - contains info for the SO + // referenced actors + DSWActor* lowActor, * highActor; + DSWActor* targetActor; // target player for the enemy - can only handle one player at at time + DSWActor* flameActor; + int Flags; int Flags2; int Tics; @@ -1131,7 +1136,6 @@ struct USER int hiz,loz; int zclip; // z height to move up for clipmove SECTORp hi_sectp, lo_sectp; - DSWActor* lowActor, *highActor; int active_range; @@ -1173,12 +1177,7 @@ struct USER // Only have a place for actors // - // For actors on fire - short flame; - - // target player for the enemy - can only handle one player at at time - //PLAYERp tgt_player; - DSWActor* targetActor; + // scaling short scale_speed; @@ -1343,61 +1342,64 @@ struct USERSAVE #define TEST_BOOL11(sp) TEST((sp)->extra, SPRX_BOOL11) // User->Flags flags -#define SPR_MOVED BIT(0) // Did actor move -#define SPR_ATTACKED BIT(1) // Is sprite being attacked? -#define SPR_TARGETED BIT(2) // Is sprite a target of a weapon? -#define SPR_ACTIVE BIT(3) // Is sprite aware of the player? -#define SPR_ELECTRO_TOLERANT BIT(4) // Electro spell does not slow actor -#define SPR_JUMPING BIT(5) // Actor is jumping -#define SPR_FALLING BIT(6) // Actor is falling -#define SPR_CLIMBING BIT(7) // Actor is falling -#define SPR_DEAD BIT(8) // Actor is dying - -#define SPR_ZDIFF_MODE BIT(10) // For following tracks at different z heights -#define SPR_SPEED_UP BIT(11) // For following tracks at different speeds -#define SPR_SLOW_DOWN BIT(12) // For following tracks at different speeds -#define SPR_DONT_UPDATE_ANG BIT(13) // For tracks - don't update the angle for a while - -#define SPR_SO_ATTACHED BIT(14) // sprite is part of a sector object -#define SPR_SUICIDE BIT(15) // sprite is set to kill itself - -#define SPR_RUN_AWAY BIT(16) // sprite is in "Run Away" track mode. -#define SPR_FIND_PLAYER BIT(17) // sprite is in "Find Player" track mode. - -#define SPR_SWIMMING BIT(18) // Actor is swimming -#define SPR_WAIT_FOR_PLAYER BIT(19) // Track Mode - Actor is waiting for player to come close -#define SPR_WAIT_FOR_TRIGGER BIT(20) // Track Mode - Actor is waiting for player to trigger -#define SPR_SLIDING BIT(21) // Actor is sliding -#define SPR_ON_SO_SECTOR BIT(22) // sprite is on a sector object sector - -#define SPR_SHADE_DIR BIT(23) // sprite is on a sector object sector -#define SPR_XFLIP_TOGGLE BIT(24) // sprite rotation xflip bit -#define SPR_NO_SCAREDZ BIT(25) // not afraid of falling - -#define SPR_SET_POS_DONT_KILL BIT(26) // Don't kill sprites in MissileSetPos -#define SPR_SKIP2 BIT(27) // 20 moves ps -#define SPR_SKIP4 BIT(28) // 10 moves ps - -#define SPR_BOUNCE BIT(29) // For shrapnel types that can bounce once -#define SPR_UNDERWATER BIT(30) // For missiles etc - -#define SPR_SHADOW BIT(31) // Sprites that have shadows - -// User->Flags2 flags -#define SPR2_BLUR_TAPER (BIT(13)|BIT(14)) // taper type -#define SPR2_BLUR_TAPER_FAST (BIT(13)) // taper fast -#define SPR2_BLUR_TAPER_SLOW (BIT(14)) // taper slow -#define SPR2_SPRITE_FAKE_BLOCK (BIT(15)) // fake blocking bit for damage -#define SPR2_NEVER_RESPAWN (BIT(16)) // for item respawning -#define SPR2_ATTACH_WALL (BIT(17)) -#define SPR2_ATTACH_FLOOR (BIT(18)) -#define SPR2_ATTACH_CEILING (BIT(19)) -#define SPR2_CHILDREN (BIT(20)) // sprite OWNS children -#define SPR2_SO_MISSILE (BIT(21)) // this is a missile from a SO -#define SPR2_DYING (BIT(22)) // Sprite is currently dying -#define SPR2_VIS_SHADING (BIT(23)) // Sprite shading to go along with vis adjustments -#define SPR2_DONT_TARGET_OWNER (BIT(24)) +enum +{ + SPR_MOVED = BIT(0), // Did actor move + SPR_ATTACKED = BIT(1), // Is sprite being attacked? + SPR_TARGETED = BIT(2), // Is sprite a target of a weapon? + SPR_ACTIVE = BIT(3), // Is sprite aware of the player? + SPR_ELECTRO_TOLERANT = BIT(4), // Electro spell does not slow actor + SPR_JUMPING = BIT(5), // Actor is jumping + SPR_FALLING = BIT(6), // Actor is falling + SPR_CLIMBING = BIT(7), // Actor is falling + SPR_DEAD = BIT(8), // Actor is dying + + SPR_ZDIFF_MODE = BIT(10), // For following tracks at different z heights + SPR_SPEED_UP = BIT(11), // For following tracks at different speeds + SPR_SLOW_DOWN = BIT(12), // For following tracks at different speeds + SPR_DONT_UPDATE_ANG = BIT(13), // For tracks - don't update the angle for a while + + SPR_SO_ATTACHED = BIT(14), // sprite is part of a sector object + SPR_SUICIDE = BIT(15), // sprite is set to kill itself + + SPR_RUN_AWAY = BIT(16), // sprite is in "Run Away" track mode. + SPR_FIND_PLAYER = BIT(17), // sprite is in "Find Player" track mode. + + SPR_SWIMMING = BIT(18), // Actor is swimming + SPR_WAIT_FOR_PLAYER = BIT(19), // Track Mode - Actor is waiting for player to come close + SPR_WAIT_FOR_TRIGGER = BIT(20), // Track Mode - Actor is waiting for player to trigger + SPR_SLIDING = BIT(21), // Actor is sliding + SPR_ON_SO_SECTOR = BIT(22), // sprite is on a sector object sector + + SPR_SHADE_DIR = BIT(23), // sprite is on a sector object sector + SPR_XFLIP_TOGGLE = BIT(24), // sprite rotation xflip bit + SPR_NO_SCAREDZ = BIT(25), // not afraid of falling + + SPR_SET_POS_DONT_KILL = BIT(26), // Don't kill sprites in MissileSetPos + SPR_SKIP2 = BIT(27), // 20 moves ps + SPR_SKIP4 = BIT(28), // 10 moves ps + + SPR_BOUNCE = BIT(29), // For shrapnel types that can bounce once + SPR_UNDERWATER = BIT(30), // For missiles etc + + SPR_SHADOW = BIT(31), // Sprites that have shadows + // User->Flags2 flags + SPR2_BLUR_TAPER = BIT(13)|BIT(14), // taper type + SPR2_BLUR_TAPER_FAST = BIT(13), // taper fast + SPR2_BLUR_TAPER_SLOW = BIT(14), // taper slow + SPR2_SPRITE_FAKE_BLOCK = BIT(15), // fake blocking bit for damage + SPR2_NEVER_RESPAWN = BIT(16), // for item respawning + SPR2_ATTACH_WALL = BIT(17), + SPR2_ATTACH_FLOOR = BIT(18), + SPR2_ATTACH_CEILING = BIT(19), + SPR2_CHILDREN = BIT(20), // sprite OWNS children + SPR2_SO_MISSILE = BIT(21), // this is a missile from a SO + SPR2_DYING = BIT(22), // Sprite is currently dying + SPR2_VIS_SHADING = BIT(23), // Sprite shading to go along with vis adjustments + SPR2_DONT_TARGET_OWNER = BIT(24), + SPR2_FLAMEDIE = BIT(25), // was previously 'flame == -2' +}; extern TPointer User[MAXSPRITES]; diff --git a/source/games/sw/src/jweapon.cpp b/source/games/sw/src/jweapon.cpp index 3de8a7efe..ef7fa124d 100644 --- a/source/games/sw/src/jweapon.cpp +++ b/source/games/sw/src/jweapon.cpp @@ -45,7 +45,7 @@ BEGIN_SW_NS ANIMATOR DoSuicide; ANIMATOR DoBloodSpray; -int SpawnFlashBombOnActor(int16_t enemy); +void SpawnFlashBombOnActor(DSWActor* actor); ANIMATOR DoPuff, BloodSprayFall; extern STATE s_Puff[]; @@ -1596,6 +1596,7 @@ PlayerInitFlashBomb(PLAYERp pp) StatIterator it(StatDamageList[stat]); while ((i = it.NextIndex()) >= 0) { + auto itActor = &swActors[i]; hp = &sprite[i]; hu = User[i].Data(); @@ -1638,7 +1639,7 @@ PlayerInitFlashBomb(PLAYERp pp) else { ActorPain(i); - SpawnFlashBombOnActor(i); + SpawnFlashBombOnActor(itActor); } } } @@ -1667,6 +1668,7 @@ InitFlashBomb(DSWActor* actor) StatIterator it(StatDamageList[stat]); while ((i = it.NextIndex()) >= 0) { + auto itActor = &swActors[i]; hp = &sprite[i]; hu = User[i].Data(); @@ -1703,7 +1705,7 @@ InitFlashBomb(DSWActor* actor) if (i != SpriteNum) { ActorPain(i); - SpawnFlashBombOnActor(i); + SpawnFlashBombOnActor(itActor); } } } @@ -1714,34 +1716,25 @@ InitFlashBomb(DSWActor* actor) // This is a sneaky function to make actors look blinded by flashbomb while using flaming code -int -SpawnFlashBombOnActor(int16_t enemy) +void SpawnFlashBombOnActor(DSWActor* actor) { - SPRITEp ep = &sprite[enemy]; - USERp eu = User[enemy].Data(); - SPRITEp np; - USERp nu; - short New; + if (!actor->hasU()) return; + SPRITEp sp = &actor->s(); + USERp u = actor->u(); // Forget about burnable sprites - if (TEST(ep->extra, SPRX_BURNABLE)) - return eu->flame; + if (TEST(sp->extra, SPRX_BURNABLE)) + return; - - if (enemy >= 0) + if (actor != nullptr) { - if (!eu) + if (u->flameActor != nullptr) { - ASSERT(true == false); - } + int sizez = (SPRITEp_SIZE_Z(sp) * 5) >> 2; - if (eu->flame >= 0) - { - int sizez = SPRITEp_SIZE_Z(ep) + DIV4(SPRITEp_SIZE_Z(ep)); - - np = &sprite[eu->flame]; - nu = User[eu->flame].Data(); + auto np = &u->flameActor->s(); + auto nu = u->flameActor->u(); if (nu->Counter >= SPRITEp_SIZE_Z_2_YREPEAT(np, sizez)) @@ -1765,24 +1758,24 @@ SpawnFlashBombOnActor(int16_t enemy) if (nu->WaitTics < 2 * 120) nu->WaitTics = 2 * 120; // allow it to grow again - return eu->flame; + return; } } - New = SpawnSprite(STAT_MISSILE, FIREBALL_FLAMES, s_FireballFlames, ep->sectnum, - ep->x, ep->y, ep->z, ep->ang, 0); - np = &sprite[New]; - nu = User[New].Data(); + auto actorNew = SpawnActor(STAT_MISSILE, FIREBALL_FLAMES, s_FireballFlames, sp->sectnum, + sp->x, sp->y, sp->z, sp->ang, 0); + auto np = &actorNew->s(); + auto nu = actor->u(); - if (enemy >= 0) - eu->flame = New; + if (u->flameActor != nullptr) + u->flameActor = actorNew; np->xrepeat = 16; np->yrepeat = 16; - if (enemy >= 0) + if (u->flameActor != nullptr) { - nu->Counter = SPRITEp_SIZE_Z_2_YREPEAT(np, SPRITEp_SIZE_Z(ep) >> 1) * 4; + nu->Counter = SPRITEp_SIZE_Z_2_YREPEAT(np, SPRITEp_SIZE_Z(sp) >> 1) * 4; } else nu->Counter = 0; // max flame size @@ -1793,12 +1786,12 @@ SpawnFlashBombOnActor(int16_t enemy) nu->Radius = 200; - if (enemy >= 0) + if (u->flameActor != nullptr) { - SetAttach(enemy, New); + SetAttach(actor->GetSpriteIndex(), actorNew->GetSpriteIndex()); } - return New; + return; } ////////////////////////////////////////////// diff --git a/source/games/sw/src/panel.cpp b/source/games/sw/src/panel.cpp index e787db0fc..1bbf109d5 100644 --- a/source/games/sw/src/panel.cpp +++ b/source/games/sw/src/panel.cpp @@ -3863,8 +3863,10 @@ SpawnOnFire(PLAYERp pp) void pOnFire(PANEL_SPRITEp psp) { + auto actor = psp->PlayerP->Actor(); + auto u = actor->u(); // Kill immediately - in case of death/water - if (User[psp->PlayerP->PlayerSprite]->flame <= -2) + if (u->flameActor == nullptr && u->Flags2 & SPR2_FLAMEDIE) { pKillSprite(psp); return; @@ -3872,7 +3874,7 @@ pOnFire(PANEL_SPRITEp psp) psp->backupy(); - if (User[psp->PlayerP->PlayerSprite]->flame == -1) + if (u->flameActor == nullptr) { // take flames down and kill them psp->y += 1; diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp index d83927c76..fd34a80b2 100644 --- a/source/games/sw/src/player.cpp +++ b/source/games/sw/src/player.cpp @@ -4915,9 +4915,10 @@ DoPlayerFireOutWater(PLAYERp pp) if (pp->WadeDepth > 20) { - if (u->flame >= 0) - SetSuicide(&swActors[u->flame]); - u->flame = -2; + if (u->flameActor != nullptr) + SetSuicide(u->flameActor); + u->flameActor = nullptr; + u->Flags2 |= SPR2_FLAMEDIE; } } @@ -4929,10 +4930,11 @@ DoPlayerFireOutDeath(PLAYERp pp) if (Prediction) return; - if (u->flame >= 0) - SetSuicide(&swActors[u->flame]); + if (u->flameActor != nullptr) + SetSuicide(u->flameActor); - u->flame = -2; + u->flameActor = nullptr; + u->Flags2 |= SPR2_FLAMEDIE; } void diff --git a/source/games/sw/src/save.cpp b/source/games/sw/src/save.cpp index b2534b553..ae30f1a65 100644 --- a/source/games/sw/src/save.cpp +++ b/source/games/sw/src/save.cpp @@ -889,7 +889,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, USER& w, USER* def ("WpnGoal", w.WpnGoal, def->WpnGoal) ("Radius", w.Radius, def->Radius) ("OverlapZ", w.OverlapZ, def->OverlapZ) - ("flame", w.flame, def->flame) + ("flame", w.flameActor, def->flameActor) ("tgt_sp", w.targetActor, def->targetActor) ("scale_speed", w.scale_speed, def->scale_speed) ("scale_value", w.scale_value, def->scale_value) diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index 0d97703d5..0754cb5eb 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -781,9 +781,9 @@ void KillSprite(int16_t SpriteNum) } } - if (u->flame >= 0) + if (u->flameActor != nullptr) { - SetSuicide(&swActors[u->flame]); + SetSuicide(u->flameActor); } User[SpriteNum].Clear(); } @@ -908,7 +908,6 @@ SpawnUser(short SpriteNum, short id, STATEp state) u->targetActor = Player[0].Actor(); u->Radius = 220; u->Sibling = -1; - u->flame = -1; u->SpriteP = &sprite[SpriteNum]; u->SpriteNum = SpriteNum; u->WaitTics = 0; diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp index 09c56f0f1..4946bdbda 100644 --- a/source/games/sw/src/weapon.cpp +++ b/source/games/sw/src/weapon.cpp @@ -4789,7 +4789,10 @@ DoFireballFlames(DSWActor* actor) if (((signed char)sp->xrepeat) == 0) { if (u->Attach >= 0) - User[u->Attach]->flame = -1; + { + User[u->Attach]->flameActor = nullptr; + User[u->Attach]->Flags2 &= ~SPR2_FLAMEDIE; + } KillActor(actor); return 0; } @@ -4862,7 +4865,10 @@ DoBreakFlames(DSWActor* actor) if (((signed char)sp->xrepeat) == 0) { if (u->Attach >= 0) - User[u->Attach]->flame = -1; + { + User[u->Attach]->flameActor = nullptr; + User[u->Attach]->Flags2 &= ~SPR2_FLAMEDIE; + } KillActor(actor); return 0; } @@ -10697,19 +10703,13 @@ SpawnBasicExp(int16_t Weapon) return explosion; } -int -SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) +void SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) { - SPRITEp sp = &sprite[SpriteNum]; - USERp u = User[SpriteNum].Data(); - SPRITEp ep; - USERp eu; - SPRITEp np; - USERp nu; - short New; + SPRITEp sp = &sprite[SpriteNum], ep; + USERp u = User[SpriteNum].Data(), eu; if (TEST(u->Flags, SPR_UNDERWATER)) - return -1; + return; if (enemy >= 0) { @@ -10718,22 +10718,22 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) // test for already burned if (TEST(ep->extra, SPRX_BURNABLE) && ep->shade > 40) - return -1; + return; if (!eu) { ASSERT(true == false); - return -1; + return; } - if (eu->flame >= 0) + if (eu->flameActor != nullptr) { int sizez = SPRITEp_SIZE_Z(ep) + DIV4(SPRITEp_SIZE_Z(ep)); - np = &sprite[eu->flame]; - nu = User[eu->flame].Data(); + auto np = &eu->flameActor->s(); + auto nu = eu->flameActor->u(); if (TEST(ep->extra, SPRX_BURNABLE)) - return eu->flame; + return; if (nu->Counter >= SPRITEp_SIZE_Z_2_YREPEAT(np, sizez)) { @@ -10756,28 +10756,19 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) if (nu->WaitTics < 2*120) nu->WaitTics = 2*120; // allow it to grow again - return eu->flame; - } - else - { - if (eu->PlayerP) - { - void SpawnOnFire(PLAYERp pp); - //SpawnOnFire(eu->PlayerP); //Nobody likes the panel fire - } + return; } } - New = SpawnSprite(STAT_MISSILE, FIREBALL_FLAMES, s_FireballFlames, sp->sectnum, + auto actorNew = SpawnActor(STAT_MISSILE, FIREBALL_FLAMES, s_FireballFlames, sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 0); - auto actorNew = &swActors[New]; - np = &actorNew->s(); - nu = actorNew->u(); + auto np = &actorNew->s(); + auto nu = actorNew->u(); np->hitag = LUMINOUS; //Always full brightness if (enemy >= 0) - eu->flame = New; + eu->flameActor = actorNew; np->xrepeat = 16; np->yrepeat = 16; @@ -10799,7 +10790,7 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) nu->Counter = 48; // max flame size } - SetOwner(sp->owner, New); + SetOwner(sp->owner, actorNew->GetSpriteIndex()); np->shade = -40; np->pal = nu->spal = u->spal; SET(np->cstat, CSTAT_SPRITE_YCENTER); @@ -10810,27 +10801,25 @@ SpawnFireballFlames(int16_t SpriteNum, int16_t enemy) if (enemy >= 0) { - SetAttach(enemy, New); + SetAttach(enemy, actorNew->GetSpriteIndex()); } else { if (TestDontStickSector(np->sectnum)) { KillActor(actorNew); - return -1; + return; } nu->floor_dist = nu->ceiling_dist = 0; - DoFindGround(New); + DoFindGround(actorNew->GetSpriteIndex()); nu->jump_speed = 0; DoBeginJump(actorNew); } PlaySound(DIGI_FIRE1,np,v3df_dontpan|v3df_doppler); - Set3DSoundOwner(New); - - return New; + Set3DSoundOwner(actorNew->GetSpriteIndex()); } @@ -14359,7 +14348,7 @@ InitStar(PLAYERp pp) nu->Radius = wu->Radius; nu->ceiling_dist = wu->ceiling_dist; nu->floor_dist = wu->floor_dist; - nu->Flags2 = wu->Flags2; + nu->Flags2 = wu->Flags2 & ~(SPR2_FLAMEDIE); // mask out any new flags here for safety. if (TEST(pp->Flags, PF_DIVING) || SpriteInUnderwaterArea(np)) SET(nu->Flags, SPR_UNDERWATER); diff --git a/source/games/sw/src/weapon.h b/source/games/sw/src/weapon.h index efa5beb21..2a2900c21 100644 --- a/source/games/sw/src/weapon.h +++ b/source/games/sw/src/weapon.h @@ -77,7 +77,7 @@ bool HitscanSpriteAdjust(short SpriteNum, short hit_wall); int SpawnSwordSparks(PLAYERp pp, short hit_sect, short hit_wall, int hit_x, int hit_y, int hit_z, short hit_ang); int SpawnBubble(short SpriteNum); int SpawnFireballExp(int16_t Weapon); -int SpawnFireballFlames(int16_t SpriteNum,int16_t enemy); +void SpawnFireballFlames(int16_t SpriteNum,int16_t enemy); int SpawnRadiationCloud(short SpriteNum); int SpawnGrenadeExp(int16_t Weapon); int SpawnSectorExp(int16_t Weapon);