* Crushtacean!

* Behaves a bit differently to the one in DSZres.pk3.
   * Can now punch DSZ mines!
   * Also has mapthingnum 126 instead of 610.
* Some other mapthingnum changes.
   * DSZ2 stalagmite is now 1009, formerly 999.
   * Big DSZ gargoyle is now 1011, formerly 1009.
This commit is contained in:
toasterbabe 2018-05-14 01:19:24 +01:00
parent 5c11131230
commit 26d13db548
9 changed files with 534 additions and 77 deletions

View file

@ -1705,6 +1705,10 @@ static actionpointer_t actionpointers[] =
{{A_SharpChase}, "A_SHARPCHASE"},
{{A_SharpSpin}, "A_SHARPSPIN"},
{{A_SharpDecel}, "A_SHARPDECEL"},
{{A_CrushstaceanWalk}, "A_CRUSHSTACEANWALK"},
{{A_CrushstaceanPunch}, "A_CRUSHSTACEANPUNCH"},
{{A_CrushclawAim}, "A_CRUSHCLAWAIM"},
{{A_CrushclawLaunch}, "A_CRUSHCLAWLAUNCH"},
{{A_VultureVtol}, "A_VULTUREVTOL"},
{{A_VultureCheck}, "A_VULTURECHECK"},
{{A_SkimChase}, "A_SKIMCHASE"},
@ -3686,6 +3690,21 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_SPINCUSHION_STOP3",
"S_SPINCUSHION_STOP4",
// Crushstacean
"S_CRUSHSTACEAN_ROAM1",
"S_CRUSHSTACEAN_ROAM2",
"S_CRUSHSTACEAN_ROAM3",
"S_CRUSHSTACEAN_ROAM4",
"S_CRUSHSTACEAN_ROAMPAUSE",
"S_CRUSHSTACEAN_PUNCH1",
"S_CRUSHSTACEAN_PUNCH2",
"S_CRUSHCLAW_AIM",
"S_CRUSHCLAW_OUT",
"S_CRUSHCLAW_STAY",
"S_CRUSHCLAW_IN",
"S_CRUSHCLAW_WAIT",
"S_CRUSHCHAIN",
// Jet Jaw
"S_JETJAW_ROAM1",
"S_JETJAW_ROAM2",
@ -6160,31 +6179,34 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_TAILSOVERLAY", // c:
// Enemies
"MT_BLUECRAWLA",
"MT_REDCRAWLA",
"MT_GFZFISH", // Greenflower Fish
"MT_GOLDBUZZ",
"MT_REDBUZZ",
"MT_BLUECRAWLA", // Crawla (Blue)
"MT_REDCRAWLA", // Crawla (Red)
"MT_GFZFISH", // SDURF
"MT_GOLDBUZZ", // Buzz (Gold)
"MT_REDBUZZ", // Buzz (Red)
"MT_JETTBOMBER", // Jetty-Syn Bomber
"MT_JETTGUNNER", // Jetty-Syn Gunner
"MT_CRAWLACOMMANDER", // Crawla Commander
"MT_DETON", // Deton
"MT_SKIM", // Skim mine dropper
"MT_TURRET",
"MT_POPUPTURRET",
"MT_TURRET", // Industrial Turret
"MT_POPUPTURRET", // Pop-Up Turret
"MT_SPINCUSHION", // Spincushion
"MT_CRUSHSTACEAN", // Crushstacean
"MT_CRUSHCLAW", // Big meaty claw
"MT_CRUSHCHAIN", // Chain
"MT_JETJAW", // Jet Jaw
"MT_SNAILER", // Snailer
"MT_VULTURE", // Vulture
"MT_VULTURE", // BASH
"MT_POINTY", // Pointy
"MT_POINTYBALL", // Pointy Ball
"MT_ROBOHOOD", // Robo-Hood
"MT_FACESTABBER", // CastleBot FaceStabber
"MT_EGGGUARD", // Egg Guard
"MT_EGGSHIELD", // Egg Shield for Egg Guard
"MT_EGGSHIELD", // Egg Guard's shield
"MT_GSNAPPER", // Green Snapper
"MT_MINUS", // Minus
"MT_SPRINGSHELL", // Spring Shell (no drop)
"MT_SPRINGSHELL", // Spring Shell
"MT_YELLOWSHELL", // Spring Shell (yellow)
"MT_UNIDUS", // Unidus
"MT_UNIBALL", // Unidus Ball

View file

@ -161,6 +161,7 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_TRET
&lspr[NOLIGHT], // SPR_TURR
&lspr[NOLIGHT], // SPR_SHRP
&lspr[NOLIGHT], // SPR_CRAB
&lspr[NOLIGHT], // SPR_JJAW
&lspr[NOLIGHT], // SPR_SNLR
&lspr[NOLIGHT], // SPR_VLTR

View file

@ -49,14 +49,15 @@ char sprnames[NUMSPRITES + 1][5] =
"TRET", // Industrial Turret
"TURR", // Pop-Up Turret
"SHRP", // Sharp
"CRAB", // Crushstacean
"JJAW", // Jet Jaw
"SNLR", // Snailer
"VLTR", // Vulture
"VLTR", // BASH
"PNTY", // Pointy
"ARCH", // Robo-Hood
"CBFS", // Castlebot Facestabber
"SPSH", // Egg Guard
"ESHI", // Egg Shield for Egg Guard
"ESHI", // Egg Guard's shield
"GSNP", // Green Snapper
"MNUS", // Minus
"SSHL", // Spring Shell
@ -904,6 +905,21 @@ state_t states[NUMSTATES] =
{SPR_SHRP, 5, 4, {A_FaceTarget}, 0, 0, S_SPINCUSHION_STOP4}, // S_SPINCUSHION_STOP3
{SPR_SHRP, 4, 4, {A_SetObjectFlags}, MF_PAIN, 1, S_SPINCUSHION_LOOK}, // S_SPINCUSHION_STOP4
// Crushstacean
{SPR_CRAB, 0, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM2}, // S_CRUSHSTACEAN_ROAM1
{SPR_CRAB, 1, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM3}, // S_CRUSHSTACEAN_ROAM2
{SPR_CRAB, 0, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM4}, // S_CRUSHSTACEAN_ROAM3
{SPR_CRAB, 2, 3, {A_CrushstaceanWalk}, 0, S_CRUSHSTACEAN_ROAMPAUSE, S_CRUSHSTACEAN_ROAM1}, // S_CRUSHSTACEAN_ROAM4
{SPR_CRAB, 0, 40, {NULL}, 0, 0, S_CRUSHSTACEAN_ROAM1}, // S_CRUSHSTACEAN_ROAMPAUSE
{SPR_CRAB, 0, 10, {NULL}, 0, 0, S_CRUSHSTACEAN_PUNCH2}, // S_CRUSHSTACEAN_PUNCH1
{SPR_CRAB, 0, -1, {A_CrushstaceanPunch}, 0, 0, S_CRUSHSTACEAN_ROAMPAUSE}, // S_CRUSHSTACEAN_PUNCH2
{SPR_CRAB, 3, 1, {A_CrushclawAim}, 0, 0, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_AIM
{SPR_CRAB, 3, 1, {A_CrushclawLaunch}, 0, S_CRUSHCLAW_STAY, S_CRUSHCLAW_OUT}, // S_CRUSHCLAW_OUT
{SPR_CRAB, 3, 10, {NULL}, 0, 0, S_CRUSHCLAW_IN}, // S_CRUSHCLAW_STAY
{SPR_CRAB, 3, 1, {A_CrushclawLaunch}, 1, S_CRUSHCLAW_WAIT, S_CRUSHCLAW_IN}, // S_CRUSHCLAW_IN
{SPR_CRAB, 3, 37, {NULL}, 0, 0, S_CRUSHCLAW_AIM}, // S_CRUSHCLAW_WAIT
{SPR_CRAB, 4, -1, {NULL}, 0, 0, S_NULL}, // S_CRUSHCHAIN
// Jet Jaw
{SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1
{SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM3}, // S_JETJAW_ROAM2
@ -3455,7 +3471,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
0, // speed
0, // radius
0, // height
0, // display offset
@ -3544,7 +3560,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // damage
sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE, // flags
(statenum_t)MT_NULL // raisestate
MT_NULL // raisestate
},
{ // MT_TAILSOVERLAY
@ -3925,6 +3941,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_CRUSHSTACEAN
126, // doomednum
S_CRUSHSTACEAN_ROAM1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
32, // reactiontime
sfx_s3k6b, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_CRUSHSTACEAN_PUNCH1, // missilestate
S_XPLD_FLICKY, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
8, // speed
24*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags
S_NULL // raisestate
},
{ // MT_CRUSHCLAW
-1, // doomednum
S_CRUSHCLAW_AIM, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
16, // reactiontime
sfx_s3k6b, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_CRUSHCLAW_OUT,// missilestate
S_XPLD1, // deathstate
S_NULL, // xdeathstate
sfx_pop, // deathsound
1, // speed
32*FRACUNIT, // radius
24*FRACUNIT, // height
0, // display offset
(sfx_s3k49<<8), // mass
0, // damage
sfx_s3kd2l, // activesound
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
MT_CRUSHCHAIN // raisestate
},
{ // MT_CRUSHCHAIN
-1, // doomednum
S_CRUSHCHAIN, // spawnstate
0, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
0, // radius
0, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_JETJAW
113, // doomednum
S_JETJAW_ROAM1, // spawnstate
@ -8997,7 +9094,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_BIGGARGOYLE
1009, // doomednum
1011, // doomednum
S_BIGGARGOYLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -9267,7 +9364,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_DSZ2STALAGMITE
999, // doomednum
1009, // doomednum
S_DSZ2STALAGMITE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate

View file

@ -104,6 +104,10 @@ void A_SnailerThink();
void A_SharpChase();
void A_SharpSpin();
void A_SharpDecel();
void A_CrushstaceanWalk();
void A_CrushstaceanPunch();
void A_CrushclawAim();
void A_CrushclawLaunch();
void A_VultureVtol();
void A_VultureCheck();
void A_SkimChase();
@ -257,14 +261,15 @@ typedef enum sprite
SPR_TRET, // Industrial Turret
SPR_TURR, // Pop-Up Turret
SPR_SHRP, // Sharp
SPR_CRAB, // Crushstacean
SPR_JJAW, // Jet Jaw
SPR_SNLR, // Snailer
SPR_VLTR, // Vulture
SPR_VLTR, // BASH
SPR_PNTY, // Pointy
SPR_ARCH, // Robo-Hood
SPR_CBFS, // Castlebot Facestabber
SPR_SPSH, // Egg Guard
SPR_ESHI, // Egg Shield for Egg Guard
SPR_ESHI, // Egg Guard's shield
SPR_GSNP, // Green Snapper
SPR_MNUS, // Minus
SPR_SSHL, // Spring Shell
@ -1022,6 +1027,21 @@ typedef enum state
S_SPINCUSHION_STOP3,
S_SPINCUSHION_STOP4,
// Crushstacean
S_CRUSHSTACEAN_ROAM1,
S_CRUSHSTACEAN_ROAM2,
S_CRUSHSTACEAN_ROAM3,
S_CRUSHSTACEAN_ROAM4,
S_CRUSHSTACEAN_ROAMPAUSE,
S_CRUSHSTACEAN_PUNCH1,
S_CRUSHSTACEAN_PUNCH2,
S_CRUSHCLAW_AIM,
S_CRUSHCLAW_OUT,
S_CRUSHCLAW_STAY,
S_CRUSHCLAW_IN,
S_CRUSHCLAW_WAIT,
S_CRUSHCHAIN,
// Jet Jaw
S_JETJAW_ROAM1,
S_JETJAW_ROAM2,
@ -3518,28 +3538,31 @@ typedef enum mobj_type
MT_TAILSOVERLAY, // c:
// Enemies
MT_BLUECRAWLA,
MT_REDCRAWLA,
MT_GFZFISH, // Greenflower Fish
MT_GOLDBUZZ,
MT_REDBUZZ,
MT_BLUECRAWLA, // Crawla (Blue)
MT_REDCRAWLA, // Crawla (Red)
MT_GFZFISH, // SDURF
MT_GOLDBUZZ, // Buzz (Gold)
MT_REDBUZZ, // Buzz (Red)
MT_JETTBOMBER, // Jetty-Syn Bomber
MT_JETTGUNNER, // Jetty-Syn Gunner
MT_CRAWLACOMMANDER, // Crawla Commander
MT_DETON, // Deton
MT_SKIM, // Skim mine dropper
MT_TURRET,
MT_POPUPTURRET,
MT_TURRET, // Industrial Turret
MT_POPUPTURRET, // Pop-Up Turret
MT_SPINCUSHION, // Spincushion
MT_CRUSHSTACEAN, // Crushstacean
MT_CRUSHCLAW, // Big meaty claw
MT_CRUSHCHAIN, // Chain
MT_JETJAW, // Jet Jaw
MT_SNAILER, // Snailer
MT_VULTURE, // Vulture
MT_VULTURE, // BASH
MT_POINTY, // Pointy
MT_POINTYBALL, // Pointy Ball
MT_ROBOHOOD, // Robo-Hood
MT_FACESTABBER, // CastleBot FaceStabber
MT_FACESTABBER, // Castlebot Facestabber
MT_EGGGUARD, // Egg Guard
MT_EGGSHIELD, // Egg Shield for Egg Guard
MT_EGGSHIELD, // Egg Guard's shield
MT_GSNAPPER, // Green Snapper
MT_MINUS, // Minus
MT_SPRINGSHELL, // Spring Shell

View file

@ -65,6 +65,10 @@ void A_SnailerThink(mobj_t *actor);
void A_SharpChase(mobj_t *actor);
void A_SharpSpin(mobj_t *actor);
void A_SharpDecel(mobj_t *actor);
void A_CrushstaceanWalk(mobj_t *actor);
void A_CrushstaceanPunch(mobj_t *actor);
void A_CrushclawAim(mobj_t *actor);
void A_CrushclawLaunch(mobj_t *actor);
void A_VultureVtol(mobj_t *actor);
void A_VultureCheck(mobj_t *actor);
void A_SkimChase(mobj_t *actor);
@ -1615,6 +1619,264 @@ void A_SharpDecel(mobj_t *actor)
P_SetMobjState(actor, actor->info->xdeathstate);
}
// Function: A_CrushstaceanWalk
//
// Description: Crushstacean movement
//
// var1 = speed (actor info's speed if 0)
// var2 = state to switch to when blocked (spawnstate if 0)
//
void A_CrushstaceanWalk(mobj_t *actor)
{
INT32 locvar1 = (var1 ? var1 : (INT32)actor->info->speed);
INT32 locvar2 = (var2 ? var2 : (INT32)actor->info->spawnstate);
angle_t ang = actor->angle + ((actor->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_CrushstaceanWalk", actor))
return;
#endif
actor->reactiontime--;
if (!P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, ang, locvar1*actor->scale),
actor->y + P_ReturnThrustY(actor, ang, locvar1*actor->scale),
false)
|| (actor->reactiontime-- <= 0))
{
actor->flags2 ^= MF2_AMBUSH;
P_SetMobjState(actor, locvar2);
actor->reactiontime = actor->info->reactiontime;
}
}
// Function: A_CrushstaceanPunch
//
// Description: Crushstacean attack
//
// var1 = unused
// var2 = state to go to if unsuccessful (spawnstate if 0)
//
void A_CrushstaceanPunch(mobj_t *actor)
{
//INT32 locvar1 = var1;
INT32 locvar2 = (var2 ? var2 : (INT32)actor->info->spawnstate);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_CrushstaceanPunch", actor))
return;
#endif
if (!actor->tracer)
return;
if (!actor->target)
{
P_SetMobjState(actor, locvar2);
return;
}
actor->tracer->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
P_SetMobjState(actor->tracer, actor->tracer->info->missilestate);
actor->tracer->extravalue1 = actor->tracer->extravalue2 = 0;
S_StartSound(actor, actor->info->attacksound);
}
// Function: A_CrushclawAim
//
// Description: Crushstacean claw aiming
//
// var1 = unused
// var2 = unused
//
void A_CrushclawAim(mobj_t *actor)
{
//INT32 locvar1 = var1;
//INT32 locvar2 = var2;
mobj_t *crab = actor->tracer;
angle_t ang;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_CrushclawAim", actor))
return;
#endif
if (!crab)
{
P_RemoveMobj(actor);
return; // there is only one step and it is crab
}
if (crab->target || P_LookForPlayers(crab, true, false, 600*crab->scale))
ang = R_PointToAngle2(crab->x, crab->y, crab->target->x, crab->target->y);
else
ang = crab->angle + ((crab->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);
ang -= actor->angle;
#define anglimit ANGLE_22h
#define angfactor 5
if (ang < ANGLE_180)
{
if (ang > anglimit)
ang = anglimit;
ang /= angfactor;
}
else
{
ang = InvAngle(ang);
if (ang > anglimit)
ang = anglimit;
ang = InvAngle(ang/angfactor);
}
actor->angle += ang;
#undef anglimit
#undef angfactor
P_TeleportMove(actor,
crab->x + P_ReturnThrustX(actor, actor->angle, 40*crab->scale),
crab->y + P_ReturnThrustY(actor, actor->angle, 40*crab->scale),
crab->z + 20*crab->scale);
if (!crab->target || (statenum_t)(crab->state-states) == crab->info->missilestate)
return;
if (((ang + ANG1) < ANG2) || P_AproxDistance(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale)
P_SetMobjState(crab, crab->info->missilestate);
}
// Function: A_CrushclawLaunch
//
// Description: Crushstacean claw launching
//
// var1:
// 0 - forwards
// anything else - backwards
// var2 = state to change to when done
//
void A_CrushclawLaunch(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *crab = actor->tracer;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_CrushclawLaunch", actor))
return;
#endif
if (!crab)
{
mobj_t *chainnext;
while (actor)
{
chainnext = actor->target;
P_RemoveMobj(actor);
actor = chainnext;
}
return; // there is only one step and it is crab
}
if (!actor->extravalue1)
{
S_StartSound(actor, actor->info->activesound);
actor->extravalue1 = ((locvar1) ? -1 : 32);
}
else if (actor->extravalue1 != 1)
actor->extravalue1 -= 1;
#define CSEGS 5
if (!actor->target)
{
mobj_t *prevchain = actor;
UINT8 i = 0;
for (i = 0; (i < CSEGS); i++)
{
mobj_t *newchain = P_SpawnMobjFromMobj(actor, 0, 0, 0, actor->info->raisestate);
prevchain->target = newchain;
prevchain = newchain;
}
actor->target->angle = R_PointToAngle2(actor->target->x, actor->target->y, crab->target->x, crab->target->y);
}
if ((!locvar1) && crab->target)
{
#define anglimit ANGLE_22h
#define angfactor 7
angle_t ang = R_PointToAngle2(actor->target->x, actor->target->y, crab->target->x, crab->target->y) - actor->target->angle;
if (ang < ANGLE_180)
{
if (ang > anglimit)
ang = anglimit;
ang /= angfactor;
}
else
{
ang = InvAngle(ang);
if (ang > anglimit)
ang = anglimit;
ang /= angfactor;
ang = InvAngle(ang);
}
actor->target->angle += ang;
actor->angle = actor->target->angle;
}
actor->extravalue2 += actor->extravalue1;
if (!P_TryMove(actor,
actor->target->x + P_ReturnThrustX(actor, actor->target->angle, actor->extravalue2*actor->scale),
actor->target->y + P_ReturnThrustY(actor, actor->target->angle, actor->extravalue2*actor->scale),
true)
&& !locvar1)
{
actor->extravalue1 = 0;
actor->extravalue2 = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y)>>FRACBITS;
P_SetMobjState(actor, locvar2);
S_StopSound(actor);
S_StartSound(actor, sfx_s3k49);
}
else
{
actor->z = actor->target->z;
if ((!locvar1 && (actor->extravalue2 > 256)) || (locvar1 && (actor->extravalue2 < 16)))
{
if (locvar1) // In case of retracting, resume crab and remove the chain.
{
mobj_t *chain = actor->target, *chainnext;
while (chain)
{
chainnext = chain->target;
P_RemoveMobj(chain);
chain = chainnext;
}
actor->extravalue2 = 0;
actor->angle = R_PointToAngle2(crab->x, crab->y, actor->x, actor->y);
P_SetTarget(&actor->target, NULL);
P_SetTarget(&crab->target, NULL);
P_SetMobjState(crab, crab->state->nextstate);
}
actor->extravalue1 = 0;
P_SetMobjState(actor, locvar2);
S_StopSound(actor);
}
}
if (!actor->target)
return;
{
mobj_t *chain = actor->target->target;
fixed_t dx = (actor->x - actor->target->x)/CSEGS, dy = (actor->y - actor->target->y)/CSEGS, dz = (actor->z - actor->target->z)/CSEGS;
fixed_t idx = dx, idy = dy, idz = dz;
while (chain)
{
P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz);
idx += dx;
idy += dy;
idz += dz;
chain = chain->target;
}
}
#undef CSEGS
}
// Function: A_VultureVtol
//
// Description: Vulture rising up to match target's height

View file

@ -2354,6 +2354,20 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->momx = target->momy = target->momz = 0;
break;
case MT_CRUSHSTACEAN:
if (target->tracer)
{
mobj_t *chain = target->tracer->target, *chainnext;
while (chain)
{
chainnext = chain->target;
P_RemoveMobj(chain);
chain = chainnext;
}
P_KillMobj(target->tracer, inflictor, source, damagetype);
}
break;
case MT_EGGMOBILE3:
{
thinker_t *th;

View file

@ -633,28 +633,51 @@ static boolean PIT_CheckThing(mobj_t *thing)
#endif
// Billiards mines!
if (thing->type == MT_BIGMINE && tmthing->type == MT_BIGMINE)
if (thing->type == MT_BIGMINE)
{
if (!tmthing->momx && !tmthing->momy)
return true;
if ((statenum_t)(thing->state-states) != thing->info->spawnstate)
return true;
if (thing->z > tmthing->z + tmthing->height)
return true; // overhead
if (thing->z + thing->height < tmthing->z)
return true; // underneath
if (tmthing->type == MT_BIGMINE)
{
if (!tmthing->momx && !tmthing->momy)
return true;
if ((statenum_t)(thing->state-states) >= thing->info->meleestate)
return true;
if (thing->z > tmthing->z + tmthing->height)
return true; // overhead
if (thing->z + thing->height < tmthing->z)
return true; // underneath
thing->momx = tmthing->momx/3;
thing->momy = tmthing->momy/3;
thing->momz = tmthing->momz/3;
tmthing->momx /= -8;
tmthing->momy /= -8;
tmthing->momz /= -8;
if (thing->info->activesound)
S_StartSound(thing, thing->info->activesound);
P_SetMobjState(thing, thing->info->meleestate);
P_SetTarget(&thing->tracer, tmthing->tracer);
return true;
thing->momx = tmthing->momx/3;
thing->momy = tmthing->momy/3;
thing->momz = tmthing->momz/3;
tmthing->momx /= -8;
tmthing->momy /= -8;
tmthing->momz /= -8;
if (thing->info->activesound)
S_StartSound(thing, thing->info->activesound);
P_SetMobjState(thing, thing->info->meleestate);
P_SetTarget(&thing->tracer, tmthing->tracer);
return true;
}
else if (tmthing->type == MT_CRUSHCLAW)
{
if (tmthing->extravalue1 <= 0)
return true;
if ((statenum_t)(thing->state-states) >= thing->info->meleestate)
return true;
if (thing->z > tmthing->z + tmthing->height)
return true; // overhead
if (thing->z + thing->height < tmthing->z)
return true; // underneath
thing->momx = P_ReturnThrustX(tmthing, tmthing->angle, 2*tmthing->extravalue1*tmthing->scale/3);
thing->momy = P_ReturnThrustY(tmthing, tmthing->angle, 2*tmthing->extravalue1*tmthing->scale/3);
if (thing->info->activesound)
S_StartSound(thing, thing->info->activesound);
P_SetMobjState(thing, thing->info->meleestate);
if (tmthing->tracer)
P_SetTarget(&thing->tracer, tmthing->tracer->target);
return false;
}
}
// When solid spikes move, assume they just popped up and teleport things on top of them to hurt.

View file

@ -8514,41 +8514,56 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
}
break;
case MT_UNIDUS:
{
INT32 i;
mobj_t *ball;
// Spawn "damage" number of "painchance" spikeball mobjs
// threshold is the distance they should keep from the MT_UNIDUS (touching radius + ball painchance)
for (i = 0; i < mobj->info->damage; i++)
{
ball = P_SpawnMobj(x, y, z, mobj->info->painchance);
ball->destscale = mobj->scale;
P_SetScale(ball, mobj->scale);
P_SetTarget(&ball->target, mobj);
ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS));
ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale);
INT32 i;
mobj_t *ball;
// Spawn "damage" number of "painchance" spikeball mobjs
// threshold is the distance they should keep from the MT_UNIDUS (touching radius + ball painchance)
for (i = 0; i < mobj->info->damage; i++)
{
ball = P_SpawnMobj(x, y, z, mobj->info->painchance);
ball->destscale = mobj->scale;
P_SetScale(ball, mobj->scale);
P_SetTarget(&ball->target, mobj);
ball->movedir = FixedAngle(FixedMul(FixedDiv(i<<FRACBITS, mobj->info->damage<<FRACBITS), 360<<FRACBITS));
ball->threshold = ball->radius + mobj->radius + FixedMul(ball->info->painchance, ball->scale);
var1 = ball->state->var1, var2 = ball->state->var2;
ball->state->action.acp1(ball);
var1 = ball->state->var1, var2 = ball->state->var2;
ball->state->action.acp1(ball);
}
}
break;
}
case MT_POINTY:
{
INT32 q;
mobj_t *ball, *lastball = mobj;
for (q = 0; q < mobj->info->painchance; q++)
{
ball = P_SpawnMobj(x, y, z, mobj->info->mass);
ball->destscale = mobj->scale;
P_SetScale(ball, mobj->scale);
P_SetTarget(&lastball->tracer, ball);
P_SetTarget(&ball->target, mobj);
lastball = ball;
INT32 q;
mobj_t *ball, *lastball = mobj;
for (q = 0; q < mobj->info->painchance; q++)
{
ball = P_SpawnMobj(x, y, z, mobj->info->mass);
ball->destscale = mobj->scale;
P_SetScale(ball, mobj->scale);
P_SetTarget(&lastball->tracer, ball);
P_SetTarget(&ball->target, mobj);
lastball = ball;
}
}
break;
case MT_CRUSHSTACEAN:
{
mobj_t *bigmeatyclaw;
angle_t ang = mobj->angle + ((mobj->flags2 & MF2_AMBUSH) ? ANGLE_90 : ANGLE_270);
bigmeatyclaw = P_SpawnMobjFromMobj(mobj,
P_ReturnThrustX(mobj, ang, 40<<FRACBITS),
P_ReturnThrustY(mobj, ang, 40<<FRACBITS),
20*FRACUNIT,
MT_CRUSHCLAW);
bigmeatyclaw->angle = ang;
P_SetTarget(&mobj->tracer, bigmeatyclaw);
P_SetTarget(&bigmeatyclaw->tracer, mobj);
mobj->reactiontime >>= 1;
}
break;
}
case MT_BIGMINE:
mobj->extravalue1 = FixedHypot(mobj->x, mobj->y)>>FRACBITS;
break;

View file

@ -340,7 +340,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Unknown possibilities"},
{"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Punch"},
{"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
{"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical damage"},
@ -465,7 +465,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3kd1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"},
{"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"}, // ditto
{"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving chain"}, // ditto
{"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"},