Merge branch 'amycameo' into 'master'

Amy for Frozen Hillside (full pitch in description)

See merge request STJr/SRB2Internal!356
This commit is contained in:
MascaraSnake 2019-10-12 07:16:26 -04:00
commit 68a82c3849
5 changed files with 371 additions and 1 deletions

View File

@ -5945,6 +5945,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_LAMPPOST1", // normal
"S_LAMPPOST2", // with snow
"S_HANGSTAR",
"S_MISTLETOE",
// Xmas GFZ bushes
"S_XMASBLUEBERRYBUSH",
"S_XMASBERRYBUSH",
@ -5952,6 +5953,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// FHZ
"S_FHZICE1",
"S_FHZICE2",
"S_ROSY_IDLE1",
"S_ROSY_IDLE2",
"S_ROSY_IDLE3",
"S_ROSY_IDLE4",
"S_ROSY_JUMP",
"S_ROSY_WALK",
"S_ROSY_HUG",
"S_ROSY_PAIN",
"S_ROSY_STND",
"S_ROSY_UNHAPPY",
// Halloween Scenery
// Pumpkins
@ -7649,6 +7660,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_LAMPPOST1", // normal
"MT_LAMPPOST2", // with snow
"MT_HANGSTAR",
"MT_MISTLETOE",
// Xmas GFZ bushes
"MT_XMASBLUEBERRYBUSH",
"MT_XMASBERRYBUSH",
@ -7656,6 +7668,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// FHZ
"MT_FHZICE1",
"MT_FHZICE2",
"MT_ROSY",
"MT_CDLHRT",
// Halloween Scenery
// Pumpkins

View File

@ -388,7 +388,9 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_XMS3
&lspr[NOLIGHT], // SPR_XMS4
&lspr[NOLIGHT], // SPR_XMS5
&lspr[NOLIGHT], // SPR_XMS6
&lspr[NOLIGHT], // SPR_FHZI
&lspr[NOLIGHT], // SPR_ROSY
// Halloween Scenery
&lspr[RINGLIGHT_L], // SPR_PUMK

View File

@ -282,7 +282,9 @@ char sprnames[NUMSPRITES + 1][5] =
"XMS3", // Snowman
"XMS4", // Lamppost
"XMS5", // Hanging Star
"XMS6", // Mistletoe
"FHZI", // FHZ ice
"ROSY",
// Halloween Scenery
"PUMK", // Pumpkins
@ -2551,6 +2553,7 @@ state_t states[NUMSTATES] =
{SPR_XMS4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST1
{SPR_XMS4, 1, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST2
{SPR_XMS5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HANGSTAR
{SPR_XMS6, 0, -1, {NULL}, 0, 0, S_NULL}, // S_MISTLETOE
// Xmas GFZ bushes
{SPR_BUS3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBLUEBERRYBUSH
{SPR_BUS1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_XMASBERRYBUSH
@ -2558,6 +2561,16 @@ state_t states[NUMSTATES] =
// FHZ
{SPR_FHZI, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE1
{SPR_FHZI, 1, -1, {NULL}, 0, 0, S_NULL}, // S_FHZICE2
{SPR_ROSY, 16, 8, {NULL}, 0, 0, S_ROSY_IDLE2}, // S_ROSY_IDLE1
{SPR_ROSY, 17, 4, {NULL}, 0, 0, S_ROSY_IDLE3}, // S_ROSY_IDLE2
{SPR_ROSY, 18, 8, {NULL}, 0, 0, S_ROSY_IDLE4}, // S_ROSY_IDLE3
{SPR_ROSY, 17, 4, {NULL}, 0, 0, S_ROSY_IDLE1}, // S_ROSY_IDLE4
{SPR_ROSY, 14, -1, {NULL}, 1, 0, S_NULL}, // S_ROSY_JUMP
{SPR_ROSY, 5, -1, {NULL}, 7, 0, S_NULL}, // S_ROSY_WALK
{SPR_ROSY, 19, -1, {NULL}, 0, 0, S_NULL}, // S_ROSY_HUG
{SPR_ROSY, 13, -1, {NULL}, 0, 0, S_NULL}, // S_ROSY_PAIN
{SPR_ROSY, 1|FF_ANIMATE, -1, {NULL}, 3, 16, S_NULL}, // S_ROSY_STND
{SPR_ROSY, 20|FF_ANIMATE, TICRATE, {NULL}, 3, 4, S_ROSY_WALK}, // S_ROSY_UNHAPPY
// Halloween Scenery
// Pumpkins
@ -13444,6 +13457,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_MISTLETOE
2105, // doomednum
S_MISTLETOE, // 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
0, // speed
52*FRACUNIT, // radius
106*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_XMASBLUEBERRYBUSH
1859, // doomednum
S_XMASBLUEBERRYBUSH, // spawnstate
@ -13579,6 +13619,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_ROSY
2104, // doomednum
S_ROSY_IDLE1, // 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
0, // speed
16*FRACUNIT, // radius
48*FRACUNIT, // height
0, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_SCENERY|MF_ENEMY|MF_SLIDEME, // flags -- "enemy" may seem weird but it doesn't have any unintended consequences in context because no MF_SHOOTABLE|MF_SPECIAL
S_NULL // raisestate
},
{ // MT_CDLHRT
-1, // doomednum
S_LHRT, // 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
4*FRACUNIT, // speed
4*FRACUNIT, // radius
4*FRACUNIT, // height
1, // display offset
4, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_JACKO1
2006, // doomednum
S_JACKO1, // spawnstate

View File

@ -530,7 +530,9 @@ typedef enum sprite
SPR_XMS3, // Snowman
SPR_XMS4, // Lamppost
SPR_XMS5, // Hanging Star
SPR_XMS6, // Mistletoe
SPR_FHZI, // FHZ Ice
SPR_ROSY,
// Halloween Scenery
SPR_PUMK, // Pumpkins
@ -2659,6 +2661,7 @@ typedef enum state
S_LAMPPOST1, // normal
S_LAMPPOST2, // with snow
S_HANGSTAR,
S_MISTLETOE,
// Xmas GFZ bushes
S_XMASBLUEBERRYBUSH,
S_XMASBERRYBUSH,
@ -2666,6 +2669,16 @@ typedef enum state
// FHZ
S_FHZICE1,
S_FHZICE2,
S_ROSY_IDLE1,
S_ROSY_IDLE2,
S_ROSY_IDLE3,
S_ROSY_IDLE4,
S_ROSY_JUMP,
S_ROSY_WALK,
S_ROSY_HUG,
S_ROSY_PAIN,
S_ROSY_STND,
S_ROSY_UNHAPPY,
// Halloween Scenery
// Pumpkins
@ -4385,6 +4398,7 @@ typedef enum mobj_type
MT_LAMPPOST1, // normal
MT_LAMPPOST2, // with snow
MT_HANGSTAR,
MT_MISTLETOE,
// Xmas GFZ bushes
MT_XMASBLUEBERRYBUSH,
MT_XMASBERRYBUSH,
@ -4392,6 +4406,8 @@ typedef enum mobj_type
// FHZ
MT_FHZICE1,
MT_FHZICE2,
MT_ROSY,
MT_CDLHRT,
// Halloween Scenery
// Pumpkins

View File

@ -7628,6 +7628,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_ROCKCRUMBLE16:
case MT_WOODDEBRIS:
case MT_BRICKDEBRIS:
case MT_BROKENROBOT:
if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height)
&& mobj->state != &states[mobj->info->deathstate])
{
@ -7692,6 +7693,237 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->movedir)
mobj->angle += mobj->movedir;
break;
case MT_ROSY:
{
UINT8 i;
fixed_t pdist = 1700*mobj->scale, work, actualwork;
player_t *player = NULL;
statenum_t stat = (mobj->state-states);
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (!players[i].mo)
continue;
if (players[i].bot)
continue;
if (!players[i].mo->health)
continue;
actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y);
if (player)
{
if (players[i].skin == 0 || players[i].skin == 3)
work = (2*work)/3;
if (work >= pdist)
continue;
}
pdist = actualwork;
player = &players[i];
}
if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN)
{
if (P_IsObjectOnGround(mobj))
{
mobj->momx = mobj->momy = 0;
if (player && mobj->cvmem < (-2*TICRATE))
stat = S_ROSY_UNHAPPY;
else
stat = S_ROSY_WALK;
P_SetMobjState(mobj, stat);
}
else if (P_MobjFlip(mobj)*mobj->momz < 0)
mobj->frame = mobj->state->frame+mobj->state->var1;
}
if (!player)
{
if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP)
{
mobj->momx = mobj->momy = 0;
P_SetMobjState(mobj, S_ROSY_IDLE1);
}
}
else
{
boolean dojump = false, targonground, love, makeheart = false;
if (mobj->target != player->mo)
P_SetTarget(&mobj->target, player->mo);
targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN));
love = (player->skin == 0 || player->skin == 3);
switch (stat)
{
case S_ROSY_IDLE1:
case S_ROSY_IDLE2:
case S_ROSY_IDLE3:
case S_ROSY_IDLE4:
dojump = true;
break;
case S_ROSY_JUMP:
case S_ROSY_PAIN:
// handled above
break;
case S_ROSY_WALK:
{
fixed_t x = mobj->x, y = mobj->y, z = mobj->z;
angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y);
boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false);
P_UnsetThingPosition(mobj);
mobj->x = x;
mobj->y = y;
mobj->z = z;
P_SetThingPosition(mobj);
if (allowed)
{
fixed_t mom, max;
P_Thrust(mobj, angletoplayer, (3*FRACUNIT)>>1);
mom = FixedHypot(mobj->momx, mobj->momy);
max = pdist;
if ((--mobj->extravalue1) <= 0)
{
if (++mobj->frame > mobj->state->frame+mobj->state->var1)
mobj->frame = mobj->state->frame;
if (mom > 12*mobj->scale)
mobj->extravalue1 = 2;
else if (mom > 6*mobj->scale)
mobj->extravalue1 = 3;
else
mobj->extravalue1 = 4;
}
if (max < (mobj->radius + mobj->target->radius))
{
mobj->momx = mobj->target->player->cmomx;
mobj->momy = mobj->target->player->cmomy;
if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground)
P_SetMobjState(mobj, (stat = S_ROSY_STND));
else
{
mobj->target->momx = mobj->momx;
mobj->target->momy = mobj->momy;
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
S_StartSound(mobj, sfx_cdpcm6);
mobj->angle = angletoplayer;
}
}
else
{
max /= 3;
if (max > 30*mobj->scale)
max = 30*mobj->scale;
if (mom > max && max > mobj->scale)
{
max = FixedDiv(max, mom);
mobj->momx = FixedMul(mobj->momx, max);
mobj->momy = FixedMul(mobj->momy, max);
}
if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale)
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
}
}
else
dojump = true;
}
break;
case S_ROSY_HUG:
if (targonground)
{
player->pflags |= PF_STASIS;
if (mobj->cvmem < 5*TICRATE)
mobj->cvmem++;
if (love && !(leveltime & 7))
makeheart = true;
}
else
{
if (mobj->cvmem < (love ? 5*TICRATE : 0))
{
P_SetMobjState(mobj, (stat = S_ROSY_PAIN));
S_StartSound(mobj, sfx_cdpcm7);
}
else
P_SetMobjState(mobj, (stat = S_ROSY_JUMP));
var1 = var2 = 0;
A_DoNPCPain(mobj);
mobj->cvmem -= TICRATE;
}
break;
case S_ROSY_STND:
if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale))))
P_SetMobjState(mobj, (stat = S_ROSY_WALK));
else if (!targonground)
;
else
{
if (love && !(leveltime & 15))
makeheart = true;
if (player->exiting || --mobj->cvmem < TICRATE)
{
P_SetMobjState(mobj, (stat = S_ROSY_HUG));
S_StartSound(mobj, sfx_cdpcm6);
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y);
mobj->target->momx = mobj->momx;
mobj->target->momy = mobj->momy;
}
}
break;
case S_ROSY_UNHAPPY:
default:
break;
}
if (stat == S_ROSY_HUG)
{
if (player->panim != PA_IDLE)
P_SetPlayerMobjState(mobj->target, S_PLAY_STND);
player->pflags |= PF_STASIS;
}
if (dojump)
{
P_SetMobjState(mobj, S_ROSY_JUMP);
mobj->z += P_MobjFlip(mobj);
mobj->momx = mobj->momy = 0;
P_SetObjectMomZ(mobj, 6<<FRACBITS, false);
S_StartSound(mobj, sfx_cdfm02);
}
if (makeheart)
{
mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT);
cdlhrt->destscale = (5*mobj->scale)>>4;
P_SetScale(cdlhrt, cdlhrt->destscale);
cdlhrt->fuse = (5*TICRATE)>>1;
cdlhrt->momz = mobj->scale;
P_SetTarget(&cdlhrt->target, mobj);
cdlhrt->extravalue1 = mobj->x;
cdlhrt->extravalue2 = mobj->y;
}
}
}
break;
case MT_CDLHRT:
{
if (mobj->cvmem < 24)
mobj->cvmem++;
mobj->movedir += ANG10;
P_UnsetThingPosition(mobj);
mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale);
P_SetThingPosition(mobj);
if ((--mobj->fuse) < 6)
{
if (!mobj->fuse)
{
P_RemoveMobj(mobj);
return;
}
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|((10-(mobj->fuse*2))<<(FF_TRANSSHIFT));
}
}
break;
case MT_VWREF:
case MT_VWREB:
{
@ -9909,6 +10141,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_FANG:
sc = 4;
break;
case MT_ROSY:
sc = 5;
break;
case MT_CORK:
mobj->flags2 |= MF2_SUPERFIRE;
break;
@ -11080,6 +11315,14 @@ You should think about modifying the deathmatch starts to take full advantage of
// They're likely facets of the level's design and therefore required to progress.
}
if (i == MT_ROSY)
{
if (mariomode)
i = MT_TOAD; // don't remove on penalty of death
else if (!(netgame || multiplayer) && players[consoleplayer].skin == 5)
return; // no doubles
}
if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
return; // you already got this token, or there are too many, or the gametype's not right
@ -11293,9 +11536,10 @@ You should think about modifying the deathmatch starts to take full advantage of
else
mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
break;
case MT_FANG:
case MT_METALSONIC_RACE:
case MT_METALSONIC_BATTLE:
case MT_FANG:
case MT_ROSY:
if (mthing->options & MTF_EXTRA)
{
mobj->color = SKINCOLOR_SILVER;