Fix Saloon doors.

* Make the center be the object stuff collides with, so that if the door is open people can't slip through.
* Add an MF_AMBUSH enhancement to allow non-minecart players to travel through.
* Make A_SaloonDoorSpawn more customisable. (var1 = object type, var2 = distance sides should be placed apart)
This commit is contained in:
toaster 2019-10-05 13:21:35 +01:00
parent ff8c43664a
commit 0235d9e7ec
5 changed files with 49 additions and 51 deletions

View file

@ -5861,7 +5861,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Saloon door
"S_SALOONDOOR",
"S_SALOONDOORTHINKER",
"S_SALOONDOORCENTER",
// Train cameo
"S_TRAINCAMEOSPAWNER_1",
@ -7601,7 +7601,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_MINECARTSIDEMARK",
"MT_MINECARTSPARK",
"MT_SALOONDOOR",
"MT_SALOONDOORTHINKER",
"MT_SALOONDOORCENTER",
"MT_TRAINCAMEOSPAWNER",
"MT_TRAINSEG",
"MT_TRAINDUSTSPAWNER",

View file

@ -263,7 +263,6 @@ char sprnames[NUMSPRITES + 1][5] =
"ADST", // Arid dust
"MCRT", // Minecart
"MCSP", // Minecart spark
"NON2", // Saloon door thinker
"SALD", // Saloon door
"TRAE", // Train cameo locomotive
"TRAI", // Train cameo wagon
@ -2462,8 +2461,8 @@ state_t states[NUMSTATES] =
{SPR_MCSP, FF_FULLBRIGHT, 1, {A_MinecartSparkThink}, 0, 0, S_MINECARTSPARK}, // S_MINECARTSPARK
// Saloon door
{SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR
{SPR_NON2, 0, -1, {A_SaloonDoorSpawn}, 0, 0, S_NULL}, // S_SALONDOORTHINKER
{SPR_SALD, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_SALOONDOOR
{SPR_NULL, 0, -1, {A_SaloonDoorSpawn}, MT_SALOONDOOR, 48, S_NULL}, // S_SALOONDOORCENTER
// Train cameo
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_TRAINCAMEOSPAWNER_2}, // S_TRAINCAMEOSPAWNER_1
@ -12527,9 +12526,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SALOONDOORTHINKER
{ // MT_SALOONDOORCENTER
1221, // doomednum
S_SALOONDOORTHINKER, // spawnstate
S_SALOONDOORCENTER, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -12550,7 +12549,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags
MF_SOLID|MF_NOGRAVITY|MF_RUNSPAWNFUNC|MF_PAPERCOLLISION|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},

View file

@ -511,7 +511,6 @@ typedef enum sprite
SPR_ADST, // Arid dust
SPR_MCRT, // Minecart
SPR_MCSP, // Minecart spark
SPR_NON2, // Saloon door thinker
SPR_SALD, // Saloon door
SPR_TRAE, // Train cameo locomotive
SPR_TRAI, // Train cameo wagon
@ -2576,7 +2575,7 @@ typedef enum state
// Saloon door
S_SALOONDOOR,
S_SALOONDOORTHINKER,
S_SALOONDOORCENTER,
// Train cameo
S_TRAINCAMEOSPAWNER_1,
@ -4338,7 +4337,7 @@ typedef enum mobj_type
MT_MINECARTSIDEMARK,
MT_MINECARTSPARK,
MT_SALOONDOOR,
MT_SALOONDOORTHINKER,
MT_SALOONDOORCENTER,
MT_TRAINCAMEOSPAWNER,
MT_TRAINSEG,
MT_TRAINDUSTSPAWNER,

View file

@ -13893,51 +13893,43 @@ void A_SnapperThinker(mobj_t *actor)
//
// Description: Spawns a saloon door.
//
// var1 = unused
// var2 = unused
// var1 = mobjtype for sides
// var2 = distance sides should be placed apart
//
void A_SaloonDoorSpawn(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
angle_t ang = actor->angle;
angle_t fa = (ang >> ANGLETOFINESHIFT) & FINEMASK;
fixed_t c = FINECOSINE(fa);
fixed_t s = FINESINE(fa);
INT32 d = 48;
fixed_t x = actor->x;
fixed_t y = actor->y;
fixed_t z = actor->z;
fixed_t c = FINECOSINE(fa)*locvar2;
fixed_t s = FINESINE(fa)*locvar2;
mobj_t *door;
mobjflag2_t ambush = (actor->flags & MF2_AMBUSH);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SaloonDoorSpawn", actor))
return;
#endif
//Front
door = P_SpawnMobj(x + c*d, y + s*d, z, MT_SALOONDOOR);
if (!locvar1)
return;
// One door...
if (!(door = P_SpawnMobjFromMobj(actor, c, s, 0, locvar1))) return;
door->angle = ang + ANGLE_180;
door->extravalue1 = AngleFixed(door->angle); // Origin angle
door->extravalue2 = 0; // Angular speed
P_SetTarget(&door->tracer, actor); // Origin door
door->flags2 |= ambush; // Can be opened by normal players?
// Origin angle
door->extravalue1 = AngleFixed(door->angle);
// Angular speed
door->extravalue2 = 0;
// Origin door
P_SetTarget(&door->tracer, actor);
//Back
door = P_SpawnMobj(x - c*d, y - s*d, z, MT_SALOONDOOR);
// ...two door!
if (!(door = P_SpawnMobjFromMobj(actor, -c, -s, 0, locvar1))) return;
door->angle = ang;
// Origin angle
door->extravalue1 = AngleFixed(door->angle);
// Angular speed
door->extravalue2 = 0;
// Origin door
P_SetTarget(&door->tracer, actor);
door->extravalue1 = AngleFixed(door->angle); // Origin angle
door->extravalue2 = 0; // Angular speed
P_SetTarget(&door->tracer, actor); // Origin door
door->flags2 |= ambush; // Can be opened by normal players?
}
// Function: A_MinecartSparkThink

View file

@ -870,19 +870,27 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
}
if (thing->type == MT_SALOONDOOR && tmthing->player)
if (thing->type == MT_SALOONDOOR)
{
if (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer) && tmthing->tracer->health)
if (tmthing->player)
{
fixed_t dx = tmthing->tracer->momx;
fixed_t dy = tmthing->tracer->momy;
fixed_t dm = min(FixedHypot(dx, dy), 16*FRACUNIT);
angle_t ang = R_PointToAngle2(0, 0, dx, dy) - thing->angle;
fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK);
S_StartSound(tmthing, thing->info->activesound);
thing->extravalue2 += 2*FixedMul(s, dm)/3;
return true;
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
if ((thing->flags & MF2_AMBUSH) || ref != tmthing)
{
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
fixed_t s = FINESINE((ang >> ANGLETOFINESHIFT) & FINEMASK);
S_StartSound(tmthing, thing->info->activesound);
thing->extravalue2 += 2*FixedMul(s, dm)/3;
}
}
return true;
}
if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
{
if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
return true;
}
if (thing->type == MT_TNTBARREL && tmthing->player)