diff --git a/src/dehacked.c b/src/dehacked.c index 1279d7bd0..3db12d4c0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4681,6 +4681,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WALLSPIKE5", "S_WALLSPIKE6", "S_WALLSPIKEBASE", + "S_WALLSPIKED1", + "S_WALLSPIKED2", // Starpost "S_STARPOST_IDLE", diff --git a/src/info.c b/src/info.c index 66e1b64cf..191c8ae91 100644 --- a/src/info.c +++ b/src/info.c @@ -1563,13 +1563,13 @@ state_t states[NUMSTATES] = // Floor Spike {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended - {SPR_USPK, 5, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 - {SPR_USPK, 4, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 + {SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 + {SPR_USPK, 2, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 {SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted - {SPR_USPK, 4, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 - {SPR_USPK, 5, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 - {SPR_USPK, 1,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles - {SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 + {SPR_USPK, 2, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 + {SPR_USPK, 1, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 + {SPR_USPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles + {SPR_USPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 // Wall Spike {SPR_WSPK, 0|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 1, 0, S_WALLSPIKE2}, // S_WALLSPIKE1 -- Fully extended @@ -1579,6 +1579,8 @@ state_t states[NUMSTATES] = {SPR_WSPK, 2|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE6}, // S_WALLSPIKE5 {SPR_WSPK, 1|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE1}, // S_WALLSPIKE6 {SPR_WSPB, 0|FF_PAPERSPRITE,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKEBASE -- Base + {SPR_WSPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED1 -- Busted spike particles + {SPR_WSPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED2 // Starpost {SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE @@ -6003,9 +6005,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_s3k64, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound + S_WALLSPIKED1, // deathstate + S_WALLSPIKED2, // xdeathstate + sfx_mspogo, // deathsound 2*TICRATE, // speed 16*FRACUNIT, // radius 14*FRACUNIT, // height diff --git a/src/info.h b/src/info.h index 42fd63dff..735530667 100644 --- a/src/info.h +++ b/src/info.h @@ -1784,6 +1784,8 @@ typedef enum state S_WALLSPIKE5, S_WALLSPIKE6, S_WALLSPIKEBASE, + S_WALLSPIKED1, + S_WALLSPIKED2, // Starpost S_STARPOST_IDLE, diff --git a/src/p_inter.c b/src/p_inter.c index 33ca1eeb5..730fd207b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1665,7 +1665,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield str = M_GetText("%s%s's armageddon blast %s %s.\n"); else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY)) - str = M_GetText("%s%s's flame stomp %s %s.\n"); + str = M_GetText("%s%s's elemental stomp %s %s.\n"); else if (inflictor->player->powers[pw_invulnerability]) str = M_GetText("%s%s's invincibility aura %s %s.\n"); else if (inflictor->player->powers[pw_super]) @@ -1719,6 +1719,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n"); break; case MT_SPIKE: + case MT_WALLSPIKE: str = M_GetText("%s was %s by spikes.\n"); break; default: @@ -2395,7 +2396,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget else { P_SetObjectMomZ(target, 14*FRACUNIT, false); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes + if (damagetype == DMG_SPIKE) // Spikes S_StartSound(target, sfx_spkdth); else P_PlayDeathSound(target); @@ -2457,90 +2458,159 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } - if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) + if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { - const fixed_t x=target->x,y=target->y,z=target->z; - const fixed_t scale=target->scale; - const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP; - S_StartSound(target,target->info->deathsound); + const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + fixed_t momz; - P_SetMobjState(target, target->info->deathstate); - target->health = 0; - target->angle = inflictor->angle + ANGLE_90; - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - if (flip) - target->z -= FixedMul(12*FRACUNIT, target->scale); - else - target->z += FixedMul(12*FRACUNIT, target->scale); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; - - if (flip) - { - target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); - target->eflags |= MFE_VERTICALFLIP; - } - else - target = P_SpawnMobj(x,y,z+FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); - P_SetMobjState(target, target->info->deathstate); - target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + S_StartSound(target, target->info->deathsound); if (target->info->xdeathstate != S_NULL) { - target = P_SpawnMobj(x,y,z,MT_SPIKE); + momz = 6*scale; if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle + ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + momz *= -1; +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = angtweak;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov;\ + chunk->y += ymov;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk,chunk->angle, 4*scale);\ + chunk->momz = momz - target = P_SpawnMobj(x,y,z,MT_SPIKE); - if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + makechunk(ang, xoffs, yoffs); + +#undef makechunk } + + momz = 7*scale; + if (flip) + momz *= -1; + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = ang + ANGLE_180; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x -= xoffs; + chunk->y -= yoffs; + if (flip) + chunk->z -= 12*scale; + else + chunk->z += 12*scale; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, chunk->angle, 2*scale); + chunk->momz = momz; + + P_SetMobjState(target, target->info->deathstate); + target->health = 0; + target->angle = ang; + P_UnsetThingPosition(target); + target->flags = MF_NOCLIP; + target->x += xoffs; + target->y += yoffs; + target->z = chunk->z; + P_SetThingPosition(target); + P_InstaThrust(target, target->angle, 2*scale); + target->momz = momz; + } + else if (target->type == MT_WALLSPIKE && target->info->deathstate != S_NULL) + { + const angle_t ang = (/*(inflictor) ? inflictor->angle : */target->angle) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale), forwardxoffs = P_ReturnThrustX(target, target->angle, 7*scale), forwardyoffs = P_ReturnThrustY(target, target->angle, 7*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + boolean sprflip; + + S_StartSound(target, target->info->deathsound); + if (!P_MobjWasRemoved(target->tracer)) + P_RemoveMobj(target->tracer); + + if (target->info->xdeathstate != S_NULL) + { + sprflip = P_RandomChance(FRACUNIT/2); + +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = target->angle;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov - forwardxoffs;\ + chunk->y += ymov - forwardyoffs;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk, angtweak, 4*scale);\ + chunk->momz = P_RandomRange(5, 7)*scale;\ + if (flip)\ + chunk->momz *= -1;\ + if (sprflip)\ + chunk->frame |= FF_VERTICALFLIP + + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + sprflip = !sprflip; + makechunk(ang, xoffs, yoffs); + +#undef makechunk + } + + sprflip = P_RandomChance(FRACUNIT/2); + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = target->angle; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x += forwardxoffs - xoffs; + chunk->y += forwardyoffs - yoffs; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); + chunk->momz = P_RandomRange(5, 7)*scale; + if (flip) + chunk->momz *= -1; + if (sprflip) + chunk->frame |= FF_VERTICALFLIP; + + P_SetMobjState(target, target->info->deathstate); + target->health = 0; + P_UnsetThingPosition(target); + target->flags = MF_NOCLIP; + target->x += forwardxoffs + xoffs; + target->y += forwardyoffs + yoffs; + P_SetThingPosition(target); + P_InstaThrust(target, ang, 2*scale); + target->momz = P_RandomRange(5, 7)*scale; + if (flip) + target->momz *= -1; + if (!sprflip) + target->frame |= FF_VERTICALFLIP; } else if (target->player) { @@ -2876,7 +2946,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + if (damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -2905,7 +2975,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + if (damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); if (source && source->player && !player->powers[pw_super]) //don't score points against super players diff --git a/src/p_map.c b/src/p_map.c index 7ea19a249..665ebd204 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -439,7 +439,9 @@ static boolean PIT_CheckThing(mobj_t *thing) // Metal Sonic destroys tiny baby objects. if (tmthing->type == MT_METALSONIC_RACE - && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE)) + && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) { if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; @@ -451,12 +453,14 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->type == MT_SPIKE) + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) { + mobjtype_t type = thing->type; if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) - if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); } else @@ -470,10 +474,13 @@ static boolean PIT_CheckThing(mobj_t *thing) // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. if ((tmthing->player) && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) - && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) + && (thing->flags & (MF_MONITOR) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) - && (thing->type == MT_SPIKE)))) + && (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE)))) { if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; @@ -485,12 +492,14 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->type == MT_SPIKE) + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) { + mobjtype_t type = thing->type; if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) - if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); } else @@ -937,12 +946,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?! { @@ -951,12 +960,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale) && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(tmthing, thing, thing, 1, 0); + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(tmthing, thing, thing, 1, 0); + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player diff --git a/src/p_mobj.c b/src/p_mobj.c index 1bb6a2f01..f01cd4383 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2739,8 +2739,9 @@ static boolean P_ZMovement(mobj_t *mo) return true; break; case MT_SPIKE: + case MT_WALLSPIKE: // Dead spike particles disappear upon ground contact - if ((mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) && mo->health <= 0) + if (!mo->health && (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz)) { P_RemoveMobj(mo); return false; @@ -10148,7 +10149,7 @@ ML_NOCLIMB : Direction not controllable // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so... - const fixed_t baseradius = mobj->radius - (mobj->scale/2); //FixedMul(FRACUNIT/2, mobj->scale); + const fixed_t baseradius = mobj->radius - mobj->scale; mobj_t *base = P_SpawnMobj( mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),