Spawn MT_LOOPENDPOINT and MT_LOOPCENTERPOINT mapthings

This commit is contained in:
James R 2022-11-21 16:29:39 -08:00
parent 7738d6bb7c
commit 8bd83b69c3
5 changed files with 174 additions and 1 deletions

View file

@ -2,6 +2,8 @@
#ifndef k_objects_H
#define k_objects_H
#include "taglist.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -93,7 +95,10 @@ void Obj_ItemSpotAssignMonitor(mobj_t *spot, mobj_t *monitor);
void Obj_ItemSpotUpdate(mobj_t *spot);
/* Loops */
mobj_t *Obj_FindLoopCenter(const mtag_t tag);
void Obj_InitLoopEndpoint(mobj_t *end, mobj_t *anchor);
void Obj_InitLoopCenter(mobj_t *center);
void Obj_LinkLoopAnchor(mobj_t *anchor, mobj_t *center, UINT8 type);
void Obj_LoopEndpointCollide(mobj_t *special, mobj_t *toucher);
#ifdef __cplusplus

View file

@ -91,6 +91,21 @@ measure_clock
*radius = FixedHypot(xy, dz);
}
static void
crisscross
( mobj_t * anchor,
mobj_t ** target_p,
mobj_t ** other_p)
{
P_SetTarget(target_p, anchor);
if (!P_MobjWasRemoved(*other_p))
{
P_SetTarget(&anchor_other(anchor), *other_p);
P_SetTarget(&anchor_other(*other_p), anchor);
}
}
static boolean
moving_toward_gate
( const player_t * player,
@ -134,6 +149,32 @@ get_binary_direction
}
}
mobj_t *
Obj_FindLoopCenter (const mtag_t tag)
{
INT32 i;
TAG_ITER_THINGS(tag, i)
{
mapthing_t *mt = &mapthings[i];
if (mt->type == mobjinfo[MT_LOOPCENTERPOINT].doomednum)
{
return mt->mobj;
}
}
return NULL;
}
void
Obj_InitLoopEndpoint
( mobj_t * end,
mobj_t * anchor)
{
P_SetTarget(&end_anchor(end), anchor);
}
void
Obj_InitLoopCenter (mobj_t *center)
{
@ -143,6 +184,35 @@ Obj_InitLoopCenter (mobj_t *center)
center_set_flip(center, mt->args[0]);
}
void
Obj_LinkLoopAnchor
( mobj_t * anchor,
mobj_t * center,
UINT8 type)
{
P_SetTarget(&anchor_center(anchor), center);
anchor_type(anchor) = type;
if (!P_MobjWasRemoved(center))
{
switch (type)
{
case TMLOOP_ALPHA:
crisscross(anchor,
&center_alpha(center),
&center_beta(center));
break;
case TMLOOP_BETA:
crisscross(anchor,
&center_beta(center),
&center_alpha(center));
break;
}
}
}
void
Obj_LoopEndpointCollide
( mobj_t * end,

View file

@ -13552,6 +13552,11 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi
angle_t angle = FixedAngle(fixedangle << FRACBITS);
angle_t fineangle = (angle >> ANGLETOFINESHIFT) & FINEMASK;
boolean isloopend = (mthing->type == mobjinfo[MT_LOOPENDPOINT].doomednum);
mobj_t *loopanchor;
boolean inclusive = isloopend;
for (r = 0; r < numitemtypes; r++)
{
dummything = *mthing;
@ -13570,6 +13575,21 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi
}
z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale);
if (isloopend)
{
const fixed_t length = (numitems - 1) * horizontalspacing / 2;
mobj_t *loopcenter = Obj_FindLoopCenter(Tag_FGet(&mthing->tags));
// Spawn the anchor at the middle point of the line
loopanchor = P_SpawnMobjFromMapThing(&dummything,
x + FixedMul(length, FINECOSINE(fineangle)),
y + FixedMul(length, FINESINE(fineangle)),
z, MT_LOOPCENTERPOINT);
Obj_LinkLoopAnchor(loopanchor, loopcenter, mthing->args[0]);
}
for (r = 0; r < numitems; r++)
{
mobjtype_t itemtype = itemtypes[r % numitemtypes];
@ -13577,15 +13597,24 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi
continue;
dummything.type = mobjinfo[itemtype].doomednum;
if (inclusive)
mobj = P_SpawnMobjFromMapThing(&dummything, x, y, z, itemtype);
x += FixedMul(horizontalspacing, FINECOSINE(fineangle));
y += FixedMul(horizontalspacing, FINESINE(fineangle));
z += (mthing->options & MTF_OBJECTFLIP) ? -verticalspacing : verticalspacing;
mobj = P_SpawnMobjFromMapThing(&dummything, x, y, z, itemtype);
if (!inclusive)
mobj = P_SpawnMobjFromMapThing(&dummything, x, y, z, itemtype);
if (!mobj)
continue;
if (isloopend)
{
Obj_InitLoopEndpoint(mobj, loopanchor);
}
mobj->spawnpoint = NULL;
}
}

View file

@ -677,11 +677,26 @@ void P_ReloadRings(void)
}
}
static int cmp_loopends(const void *a, const void *b)
{
const mapthing_t
*mt1 = *(const mapthing_t*const*)a,
*mt2 = *(const mapthing_t*const*)b;
// weighted sorting; tag takes precedence over type
return
intsign(Tag_FGet(&mt1->tags) - Tag_FGet(&mt2->tags)) * 2 +
intsign(mt1->args[0] - mt2->args[0]);
}
static void P_SpawnMapThings(boolean spawnemblems)
{
size_t i;
mapthing_t *mt;
mapthing_t **loopends;
size_t num_loopends = 0;
// Spawn axis points first so they are at the front of the list for fast searching.
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
@ -690,14 +705,22 @@ static void P_SpawnMapThings(boolean spawnemblems)
case 1700: // MT_AXIS
case 1701: // MT_AXISTRANSFER
case 1702: // MT_AXISTRANSFERLINE
case 2021: // MT_LOOPCENTERPOINT
mt->mobj = NULL;
P_SpawnMapThing(mt);
break;
case 2020: // MT_LOOPENDPOINT
num_loopends++;
break;
default:
break;
}
}
Z_Malloc(num_loopends * sizeof *loopends, PU_STATIC,
&loopends);
num_loopends = 0;
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
switch (mt->type)
@ -705,6 +728,7 @@ static void P_SpawnMapThings(boolean spawnemblems)
case 1700: // MT_AXIS
case 1701: // MT_AXISTRANSFER
case 1702: // MT_AXISTRANSFERLINE
case 2021: // MT_LOOPCENTERPOINT
continue; // These were already spawned
}
@ -716,6 +740,13 @@ static void P_SpawnMapThings(boolean spawnemblems)
mt->mobj = NULL;
if (mt->type == mobjinfo[MT_LOOPENDPOINT].doomednum)
{
loopends[num_loopends] = mt;
num_loopends++;
continue;
}
if (mt->type >= 600 && mt->type <= 611) // item patterns
P_SpawnItemPattern(mt);
else if (mt->type == 1713) // hoops
@ -723,6 +754,25 @@ static void P_SpawnMapThings(boolean spawnemblems)
else // Everything else
P_SpawnMapThing(mt);
}
qsort(loopends, num_loopends, sizeof *loopends,
cmp_loopends);
for (i = 1; i < num_loopends; ++i)
{
mapthing_t
*mt1 = loopends[i - 1],
*mt2 = loopends[i];
if (Tag_FGet(&mt1->tags) == Tag_FGet(&mt2->tags) &&
mt1->args[0] == mt2->args[0])
{
P_SpawnItemLine(mt1, mt2);
i++;
}
}
Z_Free(loopends);
}
// Experimental groovy write function!
@ -3931,6 +3981,8 @@ static void P_AddBinaryMapTags(void)
case 292:
case 294:
case 780:
case 2020: // MT_LOOPENDPOINT
case 2021: // MT_LOOPCENTERPOINT
Tag_FSet(&mapthings[i].tags, mapthings[i].extrainfo);
break;
default:
@ -6736,6 +6788,17 @@ static void P_ConvertBinaryThingTypes(void)
mapthings[i].args[2] |= TMICF_INVERTSIZE;
}
break;
case 2020: // MT_LOOPENDPOINT
{
mapthings[i].args[0] =
mapthings[i].options & MTF_AMBUSH ?
TMLOOP_BETA : TMLOOP_ALPHA;
break;
}
case 2021: // MT_LOOPCENTERPOINT
mapthings[i].args[0] = (mapthings[i].options & MTF_AMBUSH) == MTF_AMBUSH;
mapthings[i].args[1] = mapthings[i].angle;
break;
case 2050: // MT_DUELBOMB
mapthings[i].args[1] = !!(mapthings[i].options & MTF_AMBUSH);
break;

View file

@ -513,6 +513,12 @@ typedef enum
TMBOT_FORCEDIR = 1<<2,
} textmapbotcontroller_t;
typedef enum
{
TMLOOP_ALPHA = 0,
TMLOOP_BETA = 1,
} textmaploopendpointtype_t;
// GETSECSPECIAL (specialval, section)
//
// Pulls out the special # from a particular section.