A bunch of stuff again.

* Lock on targets bob now, and are used for CA_HOMINGTHOK and SH_ATTRACT as well.
* Flag stuff is now animated like it was designed to be but which was kinda messed up.
* Cork sounds.
* P_SpawnLockOn(player_t player, mobj_t lockon, statenum_t state) for Lua.
* Added homing/firing CA2_GUNSLINGER stuff at egg guard shields.
* Fixed homing stuff wrt egg guard shields and sea egg balloons.
* Fixed attract orb goin' gold when doing a CA_HOMINGTHOK homing ability.
* Fixed positioning of player during homing attack.
* Cleaned up lockon spawn code.
This commit is contained in:
toasterbabe 2017-03-23 19:11:22 +00:00
parent ddf8db12af
commit fa29f7deca
10 changed files with 106 additions and 81 deletions

View file

@ -5910,16 +5910,16 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FOUR2",
"S_FIVE2",
"S_LOCKON",
"S_LOCKON1",
"S_LOCKON2",
// Tag Sign
"S_TTAG",
// Got Flag Sign
"S_GOTREDFLAG1",
"S_GOTREDFLAG2",
"S_GOTBLUEFLAG1",
"S_GOTBLUEFLAG2",
"S_GOTFLAG",
"S_GOTREDFLAG",
"S_GOTBLUEFLAG",
"S_CORK",
@ -6714,8 +6714,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_GOTEMERALD", // Chaos Emerald (intangible)
"MT_LOCKON", // Target
"MT_TAG", // Tag Sign
"MT_GOTREDFLAG", // Got Flag sign
"MT_GOTBLUEFLAG", // Got Flag sign
"MT_GOTFLAG", // Got Flag sign
// Ambient Sounds
"MT_AWATERA", // Ambient Water Sound 1

View file

@ -2530,15 +2530,15 @@ state_t states[NUMSTATES] =
{SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
{SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
{SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON
{SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON1
{SPR_LCKN, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON2
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG
// CTF Sign
{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTREDFLAG2}, // S_GOTREDFLAG1
{SPR_GFLG, 1, 1, {NULL}, 0, 0, S_NULL}, // S_GOTREDFLAG2
{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTBLUEFLAG2}, // S_GOTBLUEFLAG1
{SPR_GFLG, 2, 1, {NULL}, 0, 0, S_NULL}, // S_GOTBLUEFLAG2
{SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG
{SPR_GFLG, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTREDFLAG
{SPR_GFLG, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTBLUEFLAG
{SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK
@ -12068,7 +12068,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_LOCKON
-1, // doomednum
S_LOCKON, // spawnstate
S_LOCKON1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -12089,7 +12089,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
@ -12120,36 +12120,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_GOTREDFLAG
{ // MT_GOTFLAG
-1, // doomednum
S_GOTREDFLAG1, // 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
8, // speed
64*FRACUNIT, // radius
32*FRACUNIT, // height
111, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_GOTBLUEFLAG2
-1, // doomednum
S_GOTBLUEFLAG1, // spawnstate
S_GOTFLAG, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -12457,7 +12430,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_CORK, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_itemup, // seesound
sfx_corkp, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -12467,7 +12440,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // missilestate
S_SMOKE1, // deathstate
S_NULL, // xdeathstate
sfx_itemup, // deathsound
sfx_corkh, // deathsound
60*FRACUNIT, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height

View file

@ -2720,16 +2720,16 @@ typedef enum state
S_FOUR2,
S_FIVE2,
S_LOCKON,
S_LOCKON1,
S_LOCKON2,
// Tag Sign
S_TTAG,
// Got Flag Sign
S_GOTREDFLAG1,
S_GOTREDFLAG2,
S_GOTBLUEFLAG1,
S_GOTBLUEFLAG2,
S_GOTFLAG,
S_GOTREDFLAG,
S_GOTBLUEFLAG,
S_CORK,
@ -3543,8 +3543,7 @@ typedef enum mobj_type
MT_GOTEMERALD, // Chaos Emerald (intangible)
MT_LOCKON, // Target
MT_TAG, // Tag Sign
MT_GOTREDFLAG, // Got Flag sign
MT_GOTBLUEFLAG, // Got Flag sign
MT_GOTFLAG, // Got Flag sign
// Ambient Sounds
MT_AWATERA, // Ambient Water Sound 1

View file

@ -449,6 +449,28 @@ static int lib_pIsValidSprite2(lua_State *L)
return 1;
}
// P_SpawnLockOn doesn't exist either, but we want to expose making a local mobj without encouraging hacks.
static int lib_pSpawnLockOn(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobj_t *lockon = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
statenum_t state = luaL_checkinteger(L, 3);
NOHUD
INLEVEL
if (!lockon)
return LUA_ErrInvalid(L, "mobj_t");
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
P_SetMobjStateNF(visual, state);
}
return 0;
}
static int lib_pSpawnMissile(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2328,6 +2350,7 @@ static luaL_Reg lib[] = {
{"P_SpawnMobj",lib_pSpawnMobj},
{"P_RemoveMobj",lib_pRemoveMobj},
{"P_IsValidSprite2", lib_pIsValidSprite2},
{"P_SpawnLockOn", lib_pSpawnLockOn},
{"P_SpawnMissile",lib_pSpawnMissile},
{"P_SpawnXYZMissile",lib_pSpawnXYZMissile},
{"P_SpawnPointMissile",lib_pSpawnPointMissile},

View file

@ -1778,8 +1778,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
case MT_GOTEMERALD:
case MT_LOCKON:
case MT_TAG:
case MT_GOTREDFLAG:
case MT_GOTBLUEFLAG:
case MT_GOTFLAG:
case MT_HOOP:
case MT_HOOPCOLLIDE:
case MT_NIGHTSCORE:

View file

@ -1348,6 +1348,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
}
player->homing = 0;
// Play a bounce sound?
S_StartSound(toucher, special->info->painsound);
@ -1408,6 +1409,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE);
P_SetPlayerMobjState(toucher, S_PLAY_FALL);
}
player->homing = 0;
// Play a bounce sound?
S_StartSound(toucher, special->info->painsound);

View file

@ -6868,7 +6868,7 @@ void P_MobjThinker(mobj_t *mobj)
return;
if (/*(mobj->target) -- the following is implicit by P_AddShield
&& (mobj->target->player)
&& */ (mobj->target->player->homing))
&& */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY))
{
P_SetMobjState(mobj, mobj->info->painstate);
mobj->tics++;
@ -7012,13 +7012,15 @@ void P_MobjThinker(mobj_t *mobj)
mobj->x = mobj->target->x;
mobj->y = mobj->target->y;
mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP);
mobj->destscale = mobj->target->destscale;
P_SetScale(mobj, mobj->target->scale);
if (!(mobj->target->eflags & MFE_VERTICALFLIP))
mobj->z = mobj->target->z + mobj->target->height + FixedMul(16*FRACUNIT, mobj->target->scale);
if (!(mobj->eflags & MFE_VERTICALFLIP))
mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale);
else
mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height;
mobj->z = mobj->target->z - FixedMul((16 + abs((leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height;
break;
case MT_DROWNNUMBERS:
if (!mobj->target)

View file

@ -2349,12 +2349,17 @@ static void P_DoPlayerHeadSigns(player_t *player)
// has it (but not on your own screen if you have the flag).
if (splitscreen || player != &players[consoleplayer])
{
if (!(player->mo->eflags & MFE_VERTICALFLIP))
P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, ((player->gotflag & GF_REDFLAG) ? MT_GOTREDFLAG : MT_GOTBLUEFLAG));
mobj_t *sign = P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
player->mo->z+player->mo->momz, MT_GOTFLAG);
if (player->mo->eflags & MFE_VERTICALFLIP)
{
sign->z += player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale);
sign->eflags |= MFE_VERTICALFLIP;
}
else
P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTREDFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, ((player->gotflag & GF_REDFLAG) ? MT_GOTREDFLAG : MT_GOTBLUEFLAG))->eflags |= MFE_VERTICALFLIP; // yes, MT_GOTREDFLAG's height is used for both of them. Doesn't really matter - they should both always be the same height.
sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale);
if (leveltime & 1)
P_SetMobjStateNF(sign, (player->gotflag & GF_REDFLAG) ? S_GOTREDFLAG : S_GOTBLUEFLAG);
}
}
}
@ -3843,8 +3848,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON);
visual->eflags |= (lockon->eflags & MFE_VERTICALFLIP);
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
}
}
@ -4102,9 +4106,20 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
//
static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
mobj_t *lockon = NULL;
if (player->pflags & PF_JUMPSTASIS)
return;
if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY)) && (lockon = P_LookForEnemies(player, true, false)) && !((leveltime & 1) && (lockon->flags & (MF_ENEMY|MF_BOSS)) && player->powers[pw_shield] == SH_ATTRACT))
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
}
}
if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPDOWN) && !player->exiting && !P_PlayerInPain(player))
{
if (player->mo->tracer && player->powers[pw_carry] == CR_MACESPIN)
@ -4255,9 +4270,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
P_SpawnThokMobj(player);
if (player->charability == CA_HOMINGTHOK && !player->homing)
if (player->charability == CA_HOMINGTHOK)
{
mobj_t *lockon = P_LookForEnemies(player, true, false);
if (lockon)
{
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
@ -7161,6 +7175,19 @@ static void P_MovePlayer(player_t *player)
if (player->pflags & PF_JUMPED && !player->exiting && player->mo->health)
{
mobj_t *lockon = NULL;
if (!player->powers[pw_super] && player->powers[pw_shield] == SH_ATTRACT && !(player->pflags & PF_THOKKED))
{
if ((lockon = P_LookForEnemies(player, false, false)) && !(!(leveltime & 1) && player->charability == CA_HOMINGTHOK))
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
P_SetMobjStateNF(visual, visual->info->spawnstate+1);
}
}
}
if (cmd->buttons & BT_USE) // Spin button effects
{
if (player->powers[pw_super]) // Super can't use shield actives, only passives
@ -7214,20 +7241,16 @@ static void P_MovePlayer(player_t *player)
case SH_ATTRACT:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->homing = 2;
{
mobj_t *lockon = P_LookForEnemies(player, false, false);
if (lockon)
{
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
player->pflags &= ~PF_NOJUMPDAMAGE;
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_s3k40);
player->homing = 3*TICRATE;
}
else
S_StartSound(player->mo, sfx_s3ka6);
}
break;
// Elemental/Bubblewrap shield activation
case SH_ELEMENTAL:
@ -7886,7 +7909,8 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
mo = (mobj_t *)think;
if (!(mo->flags & targetmask
|| mo->type == MT_FAKEMOBILE)) // hehehehe
|| mo->type == MT_FAKEMOBILE // hehehehe
|| mo->type == MT_EGGSHIELD))
continue; // not a valid target
if (mo->health <= 0) // dead
@ -7974,7 +7998,7 @@ void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
}
// change slope
zdist = (P_MobjFlip(source) ? (enemy->z + enemy->height) - (source->z + source->height) : (enemy->z - source->z));
zdist = ((P_MobjFlip(source) == -1) ? (enemy->z + enemy->height) - (source->z + source->height) : (enemy->z - source->z));
dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), zdist);
if (dist < 1)

View file

@ -189,6 +189,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR},
{"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
// Menu, interface
{"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR},

View file

@ -252,6 +252,8 @@ typedef enum
sfx_mswarp,
sfx_mspogo,
sfx_boingf,
sfx_corkp,
sfx_corkh,
// Menu, interface
sfx_chchng,