Add TD shadows to Kart

Disclaimer: I haven't tested this and therefore am not sure whether or not it actually works. I think it does. Probably.
This commit is contained in:
Wolfy 2017-10-11 20:54:35 -05:00
parent faf886885e
commit 366fe9fa91
5 changed files with 154 additions and 1 deletions

View file

@ -6389,6 +6389,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_POKEY8",
"S_POKEYIDLE",
"S_SHADOW",
"S_WHITESHADOW",
#ifdef SEENAMES
"S_NAMECHECK",
#endif
@ -6950,6 +6953,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_POKEY", // Huh, thought this was a default asset for some reason, guess not.
"MT_ENEMYFLIP",
"MT_WAYPOINT",
"MT_SHADOW",
#ifdef SEENAMES
"MT_NAMECHECK",

View file

@ -58,7 +58,7 @@ char sprnames[NUMSPRITES + 1][5] =
"SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA",
"DBAN","GSHE","GSTR","DGSH","RSHE","RSTR","DRSH","BOMB","BLIG","LIGH",
"SINK","SITR","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS",
"BUZB","CHOM","SACO","CRAB"
"BUZB","CHOM","SACO","CRAB", "SHAD"
};
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -2847,6 +2847,10 @@ state_t states[NUMSTATES] =
{SPR_CRAB, 10, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST
{SPR_CRAB, 11, -1, {NULL}, 0, 0, S_NULL}, // S_MOSSYTREE
// Fake Shadow
{SPR_SHAD, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_SHADOW
{SPR_SHAD, FF_FULLBRIGHT|FF_TRANS50|1, -1, {NULL}, 0, 0, S_NULL}, // S_WHITESHADOW
#ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif
@ -16479,6 +16483,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_SHADOW
-1, // doomednum
S_SHADOW, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // 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
60*FRACUNIT, // speed
50*FRACUNIT, // radius
1*FRACUNIT, // height
-1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
// ============================================================================================================================//
#ifdef SEENAMES

View file

@ -615,6 +615,7 @@ typedef enum sprite
SPR_CHOM, // Sapphire Coast Chomper
SPR_SACO, // Sapphire Coast Fauna
SPR_CRAB, // Crystal Abyss mobs
SPR_SHAD, // TD shadows
SPR_FIRSTFREESLOT,
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
@ -3360,6 +3361,8 @@ typedef enum state
S_FLYINGGARG8,
S_LAMPPOST,
S_MOSSYTREE,
S_SHADOW,
S_WHITESHADOW,
#ifdef SEENAMES
S_NAMECHECK,
@ -3996,6 +3999,7 @@ typedef enum mobj_type
MT_FLYINGGARG,
MT_LAMPPOST,
MT_MOSSYTREE,
MT_SHADOW,
#ifdef SEENAMES
MT_NAMECHECK,

View file

@ -204,6 +204,8 @@ void P_RespawnSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
mobj_t *P_SpawnShadowMobj(mobj_t * caster);
void P_RecalcPrecipInSector(sector_t *sector);
void P_PrecipitationEffects(void);

View file

@ -8274,6 +8274,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
}
if (mobj->type == MT_PLAYER)
P_SpawnShadowMobj(mobj);
if (!(mobj->flags & MF_NOTHINK))
P_AddThinker(&mobj->thinker);
@ -8309,6 +8312,115 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
return mobj;
}
//
// P_SpawnShadowMobj
// warning: Do not send a shadow mobj as a caster into here, or try to spawn spawn shadows for shadows in P_SpawnMobj, we do not want recursive shadows
//
mobj_t *P_SpawnShadowMobj(mobj_t * caster)
{
const mobjinfo_t *info = &mobjinfo[MT_SHADOW];
state_t *st;
mobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
// this is officially a mobj, declared as soon as possible.
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
mobj->type = MT_SHADOW;
mobj->info = info;
mobj->x = caster->x;
mobj->y = caster->y;
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
mobj->health = info->spawnhealth;
mobj->reactiontime = info->reactiontime;
mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer
// do not set the state with P_SetMobjState,
// because action routines can not be called yet
if (caster->frame & FF_FULLBRIGHT)
st = &states[S_WHITESHADOW];
else
st = &states[info->spawnstate];
mobj->state = st;
mobj->tics = st->tics;
mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->friction = ORIG_FRICTION;
mobj->movefactor = ORIG_FRICTION_FACTOR;
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
// TODO: Make this a special map header
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
mobj->destscale = FRACUNIT/2;
// set subsector and/or block links
P_SetThingPosition(mobj);
I_Assert(mobj->subsector != NULL);
// Make sure scale matches destscale immediately when spawned
P_SetScale(mobj, mobj->destscale);
mobj->floorz = mobj->subsector->sector->floorheight;
mobj->ceilingz = mobj->subsector->sector->ceilingheight;
// Tells MobjCheckWater that the water height was not set.
mobj->watertop = INT32_MAX;
mobj->z = mobj->floorz;
// defaults onground
if (mobj->z == mobj->floorz)
mobj->eflags |= MFE_ONGROUND;
if (!(mobj->flags & MF_NOTHINK))
P_AddThinker(&mobj->thinker);
// Call action functions when the state is set
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
{
if (levelloading)
{
// Cache actions in a linked list
// with function pointer, and
// var1 & var2, which will be executed
// when the level finishes loading.
P_AddCachedAction(mobj, mobj->info->spawnstate);
}
else
{
var1 = st->var1;
var2 = st->var2;
#ifdef HAVE_BLUA
astate = st;
#endif
st->action.acp1(mobj);
// DANGER! This is the ONLY way for P_SpawnMobj to return NULL!
// Avoid using MF_RUNSPAWNFUNC on mobjs whose spawn state expects target or tracer to already be set!
if (P_MobjWasRemoved(mobj))
return NULL;
}
}
if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP))
P_CheckGravity(mobj, false);
P_SetTarget(&mobj->target, caster); // set the shadow's caster as the target
return mobj;
}
static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{
state_t *st;