P_SpawnMapThing(): Separated the giant post-Lua hook switch-case statement into its own function, and separated some of the larger cases into their own function as well
This commit is contained in:
parent
8ddd078b20
commit
e382c2e094
705
src/p_mobj.c
705
src/p_mobj.c
|
@ -11890,63 +11890,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
|
|||
return i;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpawnMapThing
|
||||
// The fields of the mapthing should
|
||||
// already be in host byte order.
|
||||
//
|
||||
void P_SpawnMapThing(mapthing_t *mthing)
|
||||
{
|
||||
mobjtype_t i;
|
||||
mobj_t *mobj;
|
||||
fixed_t x, y, z;
|
||||
boolean doangle = true;
|
||||
|
||||
if (!mthing->type)
|
||||
return; // Ignore type-0 things as NOPs
|
||||
|
||||
if (mthing->type == 3328) // 3D Mode start Thing
|
||||
return;
|
||||
|
||||
if (!objectplacing && P_SpawnNonMobjMapThing(mthing))
|
||||
return;
|
||||
|
||||
i = P_GetMobjtype(mthing->type);
|
||||
if (i == MT_UNKNOWN)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
|
||||
|
||||
// Skip all returning/substitution code in objectplace.
|
||||
if (!objectplacing)
|
||||
{
|
||||
if (!P_AllowMobjSpawn(mthing, i))
|
||||
return;
|
||||
|
||||
i = P_GetMobjtypeSubstitute(mthing, i);
|
||||
if (i == MT_NULL) // Don't spawn mobj
|
||||
return;
|
||||
}
|
||||
|
||||
// spawn it
|
||||
x = mthing->x << FRACBITS;
|
||||
y = mthing->y << FRACBITS;
|
||||
z = P_GetMobjSpawnHeight(i, mthing, x, y);
|
||||
|
||||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
mobj->spawnpoint = mthing;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUAh_MapThingSpawn(mobj, mthing))
|
||||
{
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
}
|
||||
else if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
else
|
||||
#endif
|
||||
switch(mobj->type)
|
||||
{
|
||||
case MT_EMBLEM:
|
||||
static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
|
||||
{
|
||||
INT32 j;
|
||||
emblem_t* emblem = M_GetLevelEmblems(gamemap);
|
||||
|
@ -11963,7 +11907,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
if (!emblem)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle);
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
j = emblem - emblemlocations;
|
||||
|
@ -12000,126 +11944,10 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
case MT_SKYBOX:
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
skyboxcenterpnts[mthing->extrainfo] = mobj;
|
||||
else
|
||||
skyboxviewpnts[mthing->extrainfo] = mobj;
|
||||
break;
|
||||
case MT_EGGSTATUE:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj->color = SKINCOLOR_GOLD;
|
||||
mobj->colorized = true;
|
||||
}
|
||||
break;
|
||||
case MT_EGGMOBILE3:
|
||||
mobj->cusval = mthing->extrainfo;
|
||||
break;
|
||||
case MT_FAN:
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
if (sector_list)
|
||||
{
|
||||
P_DelSeclist(sector_list);
|
||||
sector_list = NULL;
|
||||
}
|
||||
mobj->flags |= MF_NOSECTOR; // this flag basically turns it invisible
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
if (mthing->angle)
|
||||
mobj->health = mthing->angle;
|
||||
else
|
||||
mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
|
||||
break;
|
||||
case MT_METALSONIC_RACE:
|
||||
case MT_METALSONIC_BATTLE:
|
||||
case MT_FANG:
|
||||
case MT_ROSY:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj->color = SKINCOLOR_SILVER;
|
||||
mobj->colorized = true;
|
||||
mobj->flags2 |= MF2_SLIDEPUSH;
|
||||
}
|
||||
break;
|
||||
case MT_BALLOON:
|
||||
if (mthing->angle > 0)
|
||||
mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1;
|
||||
break;
|
||||
#define makesoftwarecorona(mo, h) \
|
||||
corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\
|
||||
corona->sprite = SPR_FLAM;\
|
||||
corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);\
|
||||
corona->tics = -1
|
||||
case MT_FLAME:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(mobj, 20);
|
||||
P_SetScale(corona, (corona->destscale = mobj->scale*3));
|
||||
P_SetTarget(&mobj->tracer, corona);
|
||||
}
|
||||
break;
|
||||
case MT_FLAMEHOLDER:
|
||||
if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire
|
||||
{
|
||||
mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME);
|
||||
P_SetTarget(&flame->target, mobj);
|
||||
flame->flags2 |= MF2_BOSSNOTRAP;
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(flame, 20);
|
||||
P_SetScale(corona, (corona->destscale = flame->scale*3));
|
||||
P_SetTarget(&flame->tracer, corona);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_CANDLE:
|
||||
case MT_CANDLEPRICKET:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176));
|
||||
}
|
||||
break;
|
||||
#undef makesoftwarecorona
|
||||
case MT_JACKO1:
|
||||
case MT_JACKO2:
|
||||
case MT_JACKO3:
|
||||
if (!(mthing->options & MTF_EXTRA)) // take the torch out of the crafting recipe
|
||||
{
|
||||
mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY);
|
||||
P_SetTarget(&overlay->target, mobj);
|
||||
P_SetMobjState(overlay, mobj->info->raisestate);
|
||||
}
|
||||
break;
|
||||
case MT_WATERDRIP:
|
||||
if (mthing->angle)
|
||||
mobj->tics = 3*TICRATE + mthing->angle;
|
||||
else
|
||||
mobj->tics = 3*TICRATE;
|
||||
break;
|
||||
case MT_FLAMEJET:
|
||||
case MT_VERTICALFLAMEJET:
|
||||
mobj->threshold = (mthing->angle >> 10) & 7;
|
||||
mobj->movecount = (mthing->angle >> 13);
|
||||
|
||||
mobj->threshold *= (TICRATE/2);
|
||||
mobj->movecount *= (TICRATE/2);
|
||||
|
||||
mobj->movedir = mthing->extrainfo;
|
||||
break;
|
||||
case MT_MACEPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
case MT_SPRINGBALLPOINT:
|
||||
case MT_CHAINPOINT:
|
||||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
||||
{
|
||||
fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor;
|
||||
angle_t mspokeangle;
|
||||
|
@ -12139,7 +11967,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
|||
if (line == -1)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
mapthing -
|
||||
|
@ -12203,9 +12031,9 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
|
||||
mobj->lastlook = mspeed;
|
||||
mobj->movecount = mobj->lastlook;
|
||||
mobj->angle = FixedAngle(myaw*FRACUNIT);
|
||||
doangle = false;
|
||||
mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mobj->angle = FixedAngle(myaw << FRACBITS);
|
||||
*doangle = false;
|
||||
mobj->threshold = (FixedAngle(mpitch << FRACBITS) >> ANGLETOFINESHIFT);
|
||||
mobj->movefactor = mpinch;
|
||||
mobj->movedir = 0;
|
||||
|
||||
|
@ -12259,12 +12087,12 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
}
|
||||
|
||||
if (!macetype && !chainlink)
|
||||
break;
|
||||
return true;
|
||||
|
||||
if (mobj->type == MT_CHAINPOINT)
|
||||
{
|
||||
if (!mlength)
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
mlength++;
|
||||
|
@ -12308,8 +12136,8 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
msound = (mchainlike ? 0 : (mwidth & 1));
|
||||
|
||||
// Quick and easy preparatory variable setting
|
||||
mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||
mphase = (FixedAngle(mphase << FRACBITS) >> ANGLETOFINESHIFT);
|
||||
mroll = (FixedAngle(mroll << FRACBITS) >> ANGLETOFINESHIFT);
|
||||
|
||||
#define makemace(mobjtype, dist, moreflags2) {\
|
||||
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\
|
||||
|
@ -12431,12 +12259,11 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
makemace(linktype, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#undef makemace
|
||||
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
case MT_PARTICLEGEN:
|
||||
|
||||
static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj)
|
||||
{
|
||||
fixed_t radius, speed;
|
||||
INT32 type, numdivisions, anglespeed, ticcount;
|
||||
|
@ -12450,7 +12277,7 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
if (line == -1)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sides[lines[line].sidenum[0]].toptexture)
|
||||
|
@ -12502,40 +12329,10 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
mobj->reactiontime = ticcount;
|
||||
mobj->cvmem = line;
|
||||
mobj->watertop = mobj->waterbottom = 0;
|
||||
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
case MT_ROCKSPAWNER:
|
||||
mobj->threshold = mthing->angle;
|
||||
mobj->movecount = mthing->extrainfo;
|
||||
break;
|
||||
case MT_POPUPTURRET:
|
||||
if (mthing->angle)
|
||||
mobj->threshold = mthing->angle;
|
||||
else
|
||||
mobj->threshold = (TICRATE*2)-1;
|
||||
break;
|
||||
case MT_NIGHTSBUMPER:
|
||||
// Lower 4 bits specify the angle of
|
||||
// the bumper in 30 degree increments.
|
||||
mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold);
|
||||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
if (mthing->angle <= 0)
|
||||
mthing->angle = 20; // prevent 0 health
|
||||
|
||||
mobj->health = mthing->angle;
|
||||
mobj->threshold = min(mthing->extrainfo, 7);
|
||||
break;
|
||||
case MT_TUBEWAYPOINT:
|
||||
mobj->health = mthing->angle & 255;
|
||||
mobj->threshold = mthing->angle >> 8;
|
||||
break;
|
||||
case MT_IDEYAANCHOR:
|
||||
mobj->health = mthing->extrainfo;
|
||||
break;
|
||||
case MT_NIGHTSDRONE:
|
||||
static boolean P_SetupNiGHTSDrone(mapthing_t* mthing, mobj_t* mobj)
|
||||
{
|
||||
boolean flip = mthing->options & MTF_OBJECTFLIP;
|
||||
boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA);
|
||||
|
@ -12651,7 +12448,225 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
goalpost->friction = mobj->height;
|
||||
goalpost->threshold = mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong)
|
||||
{
|
||||
angle_t angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t x2 = FINECOSINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y2 = FINESINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
statenum_t facestate = strong ? S_REDBOOSTERSEG_FACE : S_YELLOWBOOSTERSEG_FACE;
|
||||
statenum_t leftstate = strong ? S_REDBOOSTERSEG_LEFT : S_YELLOWBOOSTERSEG_LEFT;
|
||||
statenum_t rightstate = strong ? S_REDBOOSTERSEG_RIGHT : S_YELLOWBOOSTERSEG_RIGHT;
|
||||
statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER;
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle - ANGLE_90;
|
||||
P_SetMobjState(seg, facestate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle + ANGLE_90;
|
||||
P_SetMobjState(seg, facestate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, leftstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, rightstate);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, rollerstate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
boolean override = LUAh_MapThingSpawn(mobj, mthing);
|
||||
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return false;
|
||||
|
||||
if (override)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_EMBLEM:
|
||||
{
|
||||
if (!P_SetupEmblem(mthing, mobj))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case MT_SKYBOX:
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
skyboxcenterpnts[mthing->extrainfo] = mobj;
|
||||
else
|
||||
skyboxviewpnts[mthing->extrainfo] = mobj;
|
||||
break;
|
||||
case MT_EGGSTATUE:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj->color = SKINCOLOR_GOLD;
|
||||
mobj->colorized = true;
|
||||
}
|
||||
break;
|
||||
case MT_EGGMOBILE3:
|
||||
mobj->cusval = mthing->extrainfo;
|
||||
break;
|
||||
case MT_FAN:
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
P_UnsetThingPosition(mobj);
|
||||
if (sector_list)
|
||||
{
|
||||
P_DelSeclist(sector_list);
|
||||
sector_list = NULL;
|
||||
}
|
||||
mobj->flags |= MF_NOSECTOR; // this flag basically turns it invisible
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
if (mthing->angle)
|
||||
mobj->health = mthing->angle;
|
||||
else
|
||||
mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4)) >> FRACBITS;
|
||||
break;
|
||||
case MT_METALSONIC_RACE:
|
||||
case MT_METALSONIC_BATTLE:
|
||||
case MT_FANG:
|
||||
case MT_ROSY:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj->color = SKINCOLOR_SILVER;
|
||||
mobj->colorized = true;
|
||||
mobj->flags2 |= MF2_SLIDEPUSH;
|
||||
}
|
||||
break;
|
||||
case MT_BALLOON:
|
||||
if (mthing->angle > 0)
|
||||
mobj->color = ((mthing->angle - 1) % (MAXSKINCOLORS - 1)) + 1;
|
||||
break;
|
||||
#define makesoftwarecorona(mo, h) \
|
||||
corona = P_SpawnMobjFromMobj(mo, 0, 0, h<<FRACBITS, MT_PARTICLE);\
|
||||
corona->sprite = SPR_FLAM;\
|
||||
corona->frame = (FF_FULLBRIGHT|FF_TRANS90|12);\
|
||||
corona->tics = -1
|
||||
case MT_FLAME:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(mobj, 20);
|
||||
P_SetScale(corona, (corona->destscale = mobj->scale*3));
|
||||
P_SetTarget(&mobj->tracer, corona);
|
||||
}
|
||||
break;
|
||||
case MT_FLAMEHOLDER:
|
||||
if (!(mthing->options & MTF_OBJECTSPECIAL)) // Spawn the fire
|
||||
{
|
||||
mobj_t *flame = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_FLAME);
|
||||
P_SetTarget(&flame->target, mobj);
|
||||
flame->flags2 |= MF2_BOSSNOTRAP;
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(flame, 20);
|
||||
P_SetScale(corona, (corona->destscale = flame->scale*3));
|
||||
P_SetTarget(&flame->tracer, corona);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_CANDLE:
|
||||
case MT_CANDLEPRICKET:
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
mobj_t *corona;
|
||||
makesoftwarecorona(mobj, ((mobj->type == MT_CANDLE) ? 42 : 176));
|
||||
}
|
||||
break;
|
||||
#undef makesoftwarecorona
|
||||
case MT_JACKO1:
|
||||
case MT_JACKO2:
|
||||
case MT_JACKO3:
|
||||
if (!(mthing->options & MTF_EXTRA)) // take the torch out of the crafting recipe
|
||||
{
|
||||
mobj_t *overlay = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY);
|
||||
P_SetTarget(&overlay->target, mobj);
|
||||
P_SetMobjState(overlay, mobj->info->raisestate);
|
||||
}
|
||||
break;
|
||||
case MT_WATERDRIP:
|
||||
mobj->tics = 3*TICRATE + mthing->angle;
|
||||
break;
|
||||
case MT_FLAMEJET:
|
||||
case MT_VERTICALFLAMEJET:
|
||||
mobj->threshold = (mthing->angle >> 10) & 7;
|
||||
mobj->movecount = (mthing->angle >> 13);
|
||||
|
||||
mobj->threshold *= (TICRATE/2);
|
||||
mobj->movecount *= (TICRATE/2);
|
||||
|
||||
mobj->movedir = mthing->extrainfo;
|
||||
break;
|
||||
case MT_MACEPOINT:
|
||||
case MT_CHAINMACEPOINT:
|
||||
case MT_SPRINGBALLPOINT:
|
||||
case MT_CHAINPOINT:
|
||||
case MT_FIREBARPOINT:
|
||||
case MT_CUSTOMMACEPOINT:
|
||||
if (!P_SetupMace(mthing, mobj, doangle))
|
||||
return false;
|
||||
break;
|
||||
case MT_PARTICLEGEN:
|
||||
if (!P_SetupParticleGen(mthing, mobj))
|
||||
return false;
|
||||
break;
|
||||
case MT_ROCKSPAWNER:
|
||||
mobj->threshold = mthing->angle;
|
||||
mobj->movecount = mthing->extrainfo;
|
||||
break;
|
||||
case MT_POPUPTURRET:
|
||||
if (mthing->angle)
|
||||
mobj->threshold = mthing->angle;
|
||||
else
|
||||
mobj->threshold = (TICRATE*2)-1;
|
||||
break;
|
||||
case MT_NIGHTSBUMPER:
|
||||
// Lower 4 bits specify the angle of
|
||||
// the bumper in 30 degree increments.
|
||||
mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc
|
||||
P_SetMobjState(mobj, mobj->info->spawnstate + mobj->threshold);
|
||||
break;
|
||||
case MT_EGGCAPSULE:
|
||||
if (mthing->angle <= 0)
|
||||
mthing->angle = 20; // prevent 0 health
|
||||
|
||||
mobj->health = mthing->angle;
|
||||
mobj->threshold = min(mthing->extrainfo, 7);
|
||||
break;
|
||||
case MT_TUBEWAYPOINT:
|
||||
mobj->health = mthing->angle & 255;
|
||||
mobj->threshold = mthing->angle >> 8;
|
||||
break;
|
||||
case MT_IDEYAANCHOR:
|
||||
mobj->health = mthing->extrainfo;
|
||||
break;
|
||||
case MT_NIGHTSDRONE:
|
||||
if (!P_SetupNiGHTSDrone(mthing, mobj))
|
||||
return false;
|
||||
break;
|
||||
case MT_HIVEELEMENTAL:
|
||||
if (mthing->extrainfo)
|
||||
|
@ -12675,9 +12690,9 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
case MT_THZTREE:
|
||||
{ // Spawn the branches
|
||||
angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS);
|
||||
P_SpawnMobjFromMobj(mobj, 1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h;
|
||||
P_SpawnMobjFromMobj(mobj, 0, 1*FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h;
|
||||
P_SpawnMobjFromMobj(mobj, -1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270;
|
||||
P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h;
|
||||
P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h;
|
||||
P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270;
|
||||
}
|
||||
break;
|
||||
case MT_CEZPOLE1:
|
||||
|
@ -12699,10 +12714,10 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
leaf->angle = mobjangle;\
|
||||
P_SetMobjState(leaf, leaf->info->seestate);\
|
||||
mobjangle += ANGLE_90
|
||||
doleaf(1*FRACUNIT, 0);
|
||||
doleaf(0, 1*FRACUNIT);
|
||||
doleaf(-1*FRACUNIT, 0);
|
||||
doleaf(0, -1*FRACUNIT);
|
||||
doleaf(FRACUNIT, 0);
|
||||
doleaf(0, FRACUNIT);
|
||||
doleaf(-FRACUNIT, 0);
|
||||
doleaf(0, -FRACUNIT);
|
||||
#undef doleaf
|
||||
}
|
||||
break;
|
||||
|
@ -12743,87 +12758,20 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
break;
|
||||
}
|
||||
case MT_REDBOOSTER:
|
||||
{
|
||||
angle_t angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle-ANGLE_90;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle+ANGLE_90;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_LEFT);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERSEG_RIGHT);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_REDBOOSTERROLLER);
|
||||
break;
|
||||
}
|
||||
case MT_YELLOWBOOSTER:
|
||||
{
|
||||
angle_t angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
|
||||
mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle-ANGLE_90;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle+ANGLE_90;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_LEFT);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERSEG_RIGHT);
|
||||
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER);
|
||||
seg->angle = angle;
|
||||
P_SetMobjState(seg, S_YELLOWBOOSTERROLLER);
|
||||
if (!P_SetupBooster(mthing, mobj, mobj->type == MT_REDBOOSTER))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case MT_AXIS:
|
||||
// Inverted if uppermost bit is set
|
||||
if (mthing->angle & 16384)
|
||||
mobj->flags2 |= MF2_AMBUSH;
|
||||
|
||||
if (mobj->flags & MF_BOSS)
|
||||
{
|
||||
if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss
|
||||
mobj->flags2 |= MF2_BOSSNOTRAP;
|
||||
}
|
||||
|
||||
if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) // Axis Points
|
||||
{
|
||||
if (mthing->angle > 0)
|
||||
mobj->radius = (mthing->angle & 16383) << FRACBITS;
|
||||
// FALLTHRU
|
||||
case MT_AXISTRANSFER:
|
||||
case MT_AXISTRANSFERLINE:
|
||||
// Mare it belongs to
|
||||
mobj->threshold = min(mthing->extrainfo, 7);
|
||||
|
||||
|
@ -12831,33 +12779,24 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
mobj->health = mthing->options;
|
||||
|
||||
mobj->flags2 |= MF2_AXIS;
|
||||
|
||||
if (i == MT_AXIS)
|
||||
{
|
||||
// Inverted if uppermost bit is set
|
||||
if (mthing->angle & 16384)
|
||||
mobj->flags2 |= MF2_AMBUSH;
|
||||
|
||||
if (mthing->angle > 0)
|
||||
mobj->radius = (mthing->angle & 16383)*FRACUNIT;
|
||||
}
|
||||
}
|
||||
else if (i == MT_TOKEN)
|
||||
{
|
||||
break;
|
||||
case MT_TOKEN:
|
||||
// We advanced tokenbits earlier due to the return check.
|
||||
// Subtract 1 here for the correct value.
|
||||
mobj->health = 1 << (tokenbits - 1);
|
||||
}
|
||||
else if (i == MT_CYBRAKDEMON && mthing->options & MTF_AMBUSH)
|
||||
break;
|
||||
case MT_CYBRAKDEMON:
|
||||
if (mthing->options & MTF_AMBUSH)
|
||||
{
|
||||
mobj_t* elecmobj;
|
||||
elecmobj = P_SpawnMobj(x, y, z, MT_CYBRAKDEMON_ELECTRIC_BARRIER);
|
||||
elecmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_CYBRAKDEMON_ELECTRIC_BARRIER);
|
||||
P_SetTarget(&elecmobj->target, mobj);
|
||||
elecmobj->angle = FixedAngle(mthing->angle<<FRACBITS);;
|
||||
elecmobj->angle = FixedAngle(mthing->angle << FRACBITS);
|
||||
elecmobj->destscale = mobj->scale*2;
|
||||
P_SetScale(elecmobj, elecmobj->destscale);
|
||||
}
|
||||
else if (i == MT_STARPOST)
|
||||
break;
|
||||
case MT_STARPOST:
|
||||
{
|
||||
thinker_t* th;
|
||||
mobj_t* mo2;
|
||||
|
@ -12884,9 +12823,9 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
|
||||
if (!foundanother)
|
||||
numstarposts++;
|
||||
break;
|
||||
}
|
||||
else if (i == MT_SPIKE)
|
||||
{
|
||||
case MT_SPIKE:
|
||||
// Pop up spikes!
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
|
@ -12903,9 +12842,8 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
mobj->flags |= MF_SOLID;
|
||||
P_SetThingPosition(mobj);
|
||||
}
|
||||
}
|
||||
else if (i == MT_WALLSPIKE)
|
||||
{
|
||||
break;
|
||||
case MT_WALLSPIKE:
|
||||
// Pop up spikes!
|
||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||
{
|
||||
|
@ -12937,45 +12875,32 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
P_SetTarget(&base->target, mobj);
|
||||
P_SetTarget(&mobj->tracer, base);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case MT_RING_BOX:
|
||||
//count 10 ring boxes into the number of rings equation too.
|
||||
if (i == MT_RING_BOX && nummaprings >= 0)
|
||||
if (nummaprings >= 0)
|
||||
nummaprings += 10;
|
||||
|
||||
if (i == MT_BIGTUMBLEWEED || i == MT_LITTLETUMBLEWEED)
|
||||
{
|
||||
break;
|
||||
case MT_BIGTUMBLEWEED:
|
||||
case MT_LITTLETUMBLEWEED:
|
||||
if (mthing->options & MTF_AMBUSH)
|
||||
{
|
||||
mobj->momz += FixedMul(16*FRACUNIT, mobj->scale);
|
||||
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
mobj->momx += FixedMul(16*FRACUNIT, mobj->scale);
|
||||
else
|
||||
mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale);
|
||||
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
mobj->momy += FixedMul(16*FRACUNIT, mobj->scale);
|
||||
else
|
||||
mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale);
|
||||
fixed_t offset = FixedMul(16*FRACUNIT, mobj->scale);
|
||||
mobj->momx += P_RandomChance(FRACUNIT/2) ? offset : -offset;
|
||||
mobj->momy += P_RandomChance(FRACUNIT/2) ? offset : -offset;
|
||||
mobj->momz += offset;
|
||||
}
|
||||
}
|
||||
|
||||
// CTF flag pointers
|
||||
if (i == MT_REDFLAG)
|
||||
{
|
||||
break;
|
||||
case MT_REDFLAG:
|
||||
redflag = mobj;
|
||||
rflagpoint = mobj->spawnpoint;
|
||||
}
|
||||
if (i == MT_BLUEFLAG)
|
||||
{
|
||||
break;
|
||||
case MT_BLUEFLAG:
|
||||
blueflag = mobj;
|
||||
bflagpoint = mobj->spawnpoint;
|
||||
}
|
||||
|
||||
// special push/pull stuff
|
||||
if (i == MT_PUSH || i == MT_PULL)
|
||||
{
|
||||
break;
|
||||
case MT_PUSH:
|
||||
case MT_PULL:
|
||||
mobj->health = 0; // Default behaviour: pushing uses XY, fading uses XYZ
|
||||
|
||||
if (mthing->options & MTF_AMBUSH)
|
||||
|
@ -12984,14 +12909,68 @@ ML_EFFECT5 : Don't stop thinking when too far away
|
|||
mobj->health |= 2; // If object special is set, fade using XY
|
||||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
P_SetMobjState(mobj, (mobj->type == MT_PUSH) ? S_GRAVWELLGREEN : S_GRAVWELLRED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mobj->flags & MF_BOSS)
|
||||
{
|
||||
if (i == MT_PUSH)
|
||||
P_SetMobjState(mobj, S_GRAVWELLGREEN);
|
||||
if (i == MT_PULL)
|
||||
P_SetMobjState(mobj, S_GRAVWELLRED);
|
||||
if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss
|
||||
mobj->flags2 |= MF2_BOSSNOTRAP;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpawnMapThing
|
||||
// The fields of the mapthing should
|
||||
// already be in host byte order.
|
||||
//
|
||||
void P_SpawnMapThing(mapthing_t *mthing)
|
||||
{
|
||||
mobjtype_t i;
|
||||
mobj_t *mobj;
|
||||
fixed_t x, y, z;
|
||||
boolean doangle = true;
|
||||
|
||||
if (!mthing->type)
|
||||
return; // Ignore type-0 things as NOPs
|
||||
|
||||
if (mthing->type == 3328) // 3D Mode start Thing
|
||||
return;
|
||||
|
||||
if (!objectplacing && P_SpawnNonMobjMapThing(mthing))
|
||||
return;
|
||||
|
||||
i = P_GetMobjtype(mthing->type);
|
||||
if (i == MT_UNKNOWN)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
|
||||
|
||||
// Skip all returning/substitution code in objectplace.
|
||||
if (!objectplacing)
|
||||
{
|
||||
if (!P_AllowMobjSpawn(mthing, i))
|
||||
return;
|
||||
|
||||
i = P_GetMobjtypeSubstitute(mthing, i);
|
||||
if (i == MT_NULL) // Don't spawn mobj
|
||||
return;
|
||||
}
|
||||
|
||||
// spawn it
|
||||
x = mthing->x << FRACBITS;
|
||||
y = mthing->y << FRACBITS;
|
||||
z = P_GetMobjSpawnHeight(i, mthing, x, y);
|
||||
|
||||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
mobj->spawnpoint = mthing;
|
||||
|
||||
if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle))
|
||||
return;
|
||||
|
||||
if (doangle)
|
||||
mobj->angle = FixedAngle(mthing->angle<<FRACBITS);
|
||||
|
||||
|
|
Loading…
Reference in New Issue