Linked list bananas, hnext/hprev fixes

This commit is contained in:
TehRealSalt 2018-06-16 19:57:08 -04:00
parent da83809d44
commit d1929d3a37
9 changed files with 132 additions and 167 deletions

View file

@ -14525,8 +14525,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
12*FRACUNIT, // radius
20*FRACUNIT, // height
10*FRACUNIT, // radius
21*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage

View file

@ -2008,32 +2008,16 @@ void K_DriftDustHandling(mobj_t *spawner)
}
}
static mobj_t *K_FindLastTrailMobj(player_t *player)
static mobj_t *K_FindLastTrailMobj(player_t *player) // YUCK, i hate this!
{
thinker_t *th;
mobj_t *mo;
mobj_t *trail = NULL;
mobj_t *trail = player->mo->hnext;
if (!player)
if (!player || !trail)
return NULL;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
while (trail->hnext && !P_MobjWasRemoved(trail->hnext))
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
continue;
mo = (mobj_t *)th;
if (mo->type != MT_BANANA_SHIELD
&& mo->type != MT_FAKESHIELD
&& mo->type != MT_SSMINE_SHIELD)
continue;
if (!mo->target || !mo->target->player || mo->target->player != player)
continue;
if (trail == NULL || (mo->lastlook > trail->lastlook))
trail = mo;
trail = trail->hnext;
}
return trail;
@ -2381,6 +2365,27 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed)
S_StartSound(mo, sfx_kc2f);
}
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
{
if (banana->hnext)
K_KillBananaChain(banana->hnext, inflictor, source);
if (banana->health)
{
if (banana->eflags & MFE_VERTICALFLIP)
banana->z -= banana->height;
else
banana->z += banana->height;
S_StartSound(banana, banana->info->deathsound);
P_KillMobj(banana, inflictor, source);
P_SetObjectMomZ(banana, 8*FRACUNIT, false);
if (inflictor)
P_InstaThrust(banana, R_PointToAngle2(inflictor->x, inflictor->y, banana->x, banana->y)+ANGLE_90, 16*FRACUNIT);
}
}
/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c
\param player player object passed from P_PlayerThink
@ -3030,48 +3035,38 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *master;
INT32 moloop;
mobj_t *mo;
mobj_t *prev = NULL;
player->kartstuff[k_itemheld] = 1;
player->pflags |= PF_ATTACKDOWN;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
master = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANA_SHIELD);
master->threshold = 10;
master->movecount = player->kartstuff[k_itemamount]-1;
master->lastlook = 1;
if (master)
if (player->kartstuff[k_itemamount] > 1)
{
P_SetTarget(&master->target, player->mo);
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 2;
}
else
player->kartstuff[k_itemheld] = 1;
player->pflags |= PF_ATTACKDOWN;
if (master->movecount > 0) // Banana x3/x10 held
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
{
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANA_SHIELD);
mo->threshold = 10;
mo->movecount = player->kartstuff[k_itemamount];
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
if (moloop > 0)
{
INT32 moloop;
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 2;
for (moloop = 0; moloop < master->movecount; moloop++)
{
if (moloop >= 10) // maxed out mobjtable
break;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, mobjinfo[MT_BANANA_SHIELD].radius);
master->mobjtable[moloop] = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANA_SHIELD);
if (master->mobjtable[moloop])
{
master->mobjtable[moloop]->threshold = 10;
master->mobjtable[moloop]->lastlook = moloop+2;
P_SetTarget(&master->mobjtable[moloop]->target, player->mo);
P_SetTarget(&master->mobjtable[moloop]->tracer, master);
master->mobjtable[moloop]->angle = newangle;
}
}
P_SetTarget(&mo->hprev, prev);
if (prev != NULL)
P_SetTarget(&prev->hnext, mo);
}
else
P_SetTarget(&player->mo->hnext, mo);
prev = mo;
}
}
else if (!(cmd->buttons & BT_ATTACK) && player->kartstuff[k_itemheld] == 1)
@ -3111,6 +3106,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo->scale = FRACUNIT/2;
mo->threshold = 10;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
}
break;
@ -3269,7 +3265,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_SSMINE_SHIELD);
mo->threshold = 10;
if (mo)
{
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
}
else if (!(cmd->buttons & BT_ATTACK) && HOLDING_ITEM)
{

View file

@ -34,6 +34,7 @@ void K_SpawnSparkleTrail(mobj_t *mo);
void K_DriftDustHandling(mobj_t *spawner);
void K_DoSneaker(player_t *player, boolean doPFlag);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
void K_StripItems(player_t *player);

View file

@ -2132,6 +2132,22 @@ static int lib_kDoPogoSpring(lua_State *L)
return 0;
}
static int lib_kKillBananaChain(lua_State *L)
{
mobj_t *banana = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
if (!banana)
return LUA_ErrInvalid(L, "mobj_t");
if (!inflictor)
return LUA_ErrInvalid(L, "mobj_t");
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_KillBananaChain(banana, inflictor, source);
return 0;
}
static int lib_kMomentumToFacing(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2359,6 +2375,7 @@ static luaL_Reg lib[] = {
{"K_DriftDustHandling",lib_kDriftDustHandling},
{"K_DoSneaker",lib_kDoSneaker},
{"K_DoPogoSpring",lib_kDoPogoSpring},
{"K_KillBananaChain",lib_kKillBananaChain},
{"K_MomentumToFacing",lib_kMomentumToFacing},
{"K_GetKartSpeed",lib_kGetKartSpeed},
{"K_GetKartAccel",lib_kGetKartAccel},

View file

@ -81,8 +81,7 @@ enum mobj_e {
mobj_extravalue2,
mobj_cusval,
mobj_cvmem,
mobj_colorized,
mobj_mobjtable
mobj_colorized
};
static const char *const mobj_opt[] = {
@ -143,7 +142,6 @@ static const char *const mobj_opt[] = {
"cusval",
"cvmem",
"colorized",
"mobjtable",
NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
@ -350,9 +348,6 @@ static int mobj_get(lua_State *L)
case mobj_colorized:
lua_pushboolean(L, mo->colorized);
break;
case mobj_mobjtable:
// No idea how to do a table like this :V
return UNIMPLEMENTED;
default: // extra custom variables in Lua memory
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
@ -535,10 +530,22 @@ static int mobj_set(lua_State *L)
case mobj_bprev:
return UNIMPLEMENTED;
case mobj_hnext:
mo->hnext = luaL_checkudata(L, 3, META_MOBJ);
if (lua_isnil(L, 3))
P_SetTarget(&mo->hnext, NULL);
else
{
mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_SetTarget(&mo->hnext, hnext);
}
break;
case mobj_hprev:
mo->hprev = luaL_checkudata(L, 3, META_MOBJ);
if (lua_isnil(L, 3))
P_SetTarget(&mo->hprev, NULL);
else
{
mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
P_SetTarget(&mo->hprev, hprev);
}
break;
case mobj_type: // yeah sure, we'll let you change the mobj's type.
{
@ -651,8 +658,6 @@ static int mobj_set(lua_State *L)
case mobj_colorized:
mo->colorized = luaL_checkboolean(L, 3);
break;
case mobj_mobjtable:
return UNIMPLEMENTED;
default:
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));

View file

@ -2109,27 +2109,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
if ((target->type == MT_BANANA_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_BANANA)
|| (target->type == MT_SSMINE_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_MINE))
{
if (target->lastlook == 1)
if (target->lastlook != 0 && target->lastlook < target->target->player->kartstuff[k_itemamount])
{
INT32 i;
for (i = 0; i < 10; i++)
{
if (target->mobjtable[i] && target->mobjtable[i]->health)
P_KillMobj(target->mobjtable[i], inflictor, source);
}
if (target->target->hnext)
K_KillBananaChain(target->target->hnext, inflictor, source);
target->target->player->kartstuff[k_itemamount] = 0;
}
else if (target->lastlook > 1)
{
if (target->lastlook < target->target->player->kartstuff[k_itemamount])
{
if (target->tracer && target->tracer->health)
P_KillMobj(target->tracer, inflictor, source);
target->target->player->kartstuff[k_itemamount] = 0;
}
else
target->target->player->kartstuff[k_itemamount]--;
}
else
target->target->player->kartstuff[k_itemamount]--;
}

View file

@ -6431,6 +6431,11 @@ void P_MobjThinker(mobj_t *mobj)
P_SetTarget(&mobj->target, NULL);
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL);
// hnext/hprev changes suggested by toaster
if (mobj->hnext && P_MobjWasRemoved(mobj->hnext))
P_SetTarget(&mobj->hnext, NULL);
if (mobj->hprev && P_MobjWasRemoved(mobj->hprev))
P_SetTarget(&mobj->hprev, NULL);
mobj->flags2 &= ~MF2_PUSHED;
mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
@ -6774,55 +6779,42 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->lastlook == 1)
{
const fixed_t spacing = FixedMul(mobj->info->radius, mobj->target->scale);
angle_t ang = mobj->target->angle;
fixed_t targx = mobj->target->x + P_ReturnThrustX(mobj, ang + ANGLE_180, spacing);
fixed_t targy = mobj->target->y + P_ReturnThrustY(mobj, ang + ANGLE_180, spacing);
fixed_t targz = mobj->target->z;
fixed_t speed = FixedMul(R_PointToDist2(mobj->x, mobj->y, targx, targy), FRACUNIT/2);
INT32 i;
INT32 previ = -1;
mobj_t *cur = mobj;
mobj_t *targ = mobj->target;
if (P_IsObjectOnGround(mobj->target))
targz = mobj->floorz;
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, targx, targy);
if (speed > spacing/2)
P_InstaThrust(mobj, mobj->angle, speed-spacing/2);
P_SetObjectMomZ(mobj, FixedMul(targz - mobj->z, FRACUNIT/2), false);
if (R_PointToDist2(mobj->x, mobj->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(mobj, targx, targy, mobj->z);
if (mobj->movecount > 0) // Now, for chaser bananas.
while (cur && !P_MobjWasRemoved(cur))
{
for (i = 0; i < mobj->movecount; i++)
{
mobj_t *targ;
angle_t ang;
fixed_t targx;
fixed_t targy;
fixed_t targz;
fixed_t speed;
if (!mobj->mobjtable[i])
continue;
if (cur != mobj)
targ = cur->hprev;
targ = mobj;
if (previ >= 0 && mobj->mobjtable[previ])
targ = mobj->mobjtable[previ];
if (!targ || P_MobjWasRemoved(targ))
continue;
ang = targ->angle;
targx = targ->x + P_ReturnThrustX(mobj->mobjtable[i], ang + ANGLE_180, spacing);
targy = targ->y + P_ReturnThrustY(mobj->mobjtable[i], ang + ANGLE_180, spacing);
targz = targ->z;
speed = FixedMul(R_PointToDist2(mobj->mobjtable[i]->x, mobj->mobjtable[i]->y, targx, targy), FRACUNIT/2);
if (P_IsObjectOnGround(targ))
targz = mobj->mobjtable[i]->floorz;
ang = targ->angle;
targx = targ->x + P_ReturnThrustX(cur, ang + ANGLE_180, spacing);
targy = targ->y + P_ReturnThrustY(cur, ang + ANGLE_180, spacing);
targz = targ->z;
speed = FixedMul(R_PointToDist2(cur->x, cur->y, targx, targy), FRACUNIT/2);
if (P_IsObjectOnGround(targ))
targz = cur->floorz;
mobj->mobjtable[i]->angle = R_PointToAngle2(mobj->mobjtable[i]->x, mobj->mobjtable[i]->y, targx, targy);
cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy);
if (speed > spacing/2)
P_InstaThrust(mobj->mobjtable[i], mobj->mobjtable[i]->angle, speed-(spacing/2));
P_SetObjectMomZ(mobj->mobjtable[i], FixedMul(targz - mobj->mobjtable[i]->z, FRACUNIT/2), false);
if (R_PointToDist2(mobj->mobjtable[i]->x, mobj->mobjtable[i]->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(mobj->mobjtable[i], targx, targy, mobj->mobjtable[i]->z);
if (speed > spacing/2)
P_InstaThrust(cur, cur->angle, speed-(spacing/2));
previ = i;
}
P_SetObjectMomZ(cur, FixedMul(targz - cur->z, FRACUNIT/2), false);
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
P_TeleportMove(cur, targx, targy, cur->z);
cur = cur->hnext;
}
}
@ -9308,6 +9300,7 @@ void P_RemoveMobj(mobj_t *mobj)
//
// Remove any references to other mobjs.
P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL));
P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL));
// free block
// DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error.

View file

@ -367,7 +367,6 @@ typedef struct mobj_s
#endif
boolean colorized; // Whether the mobj uses the rainbow colormap
struct mobj_s *mobjtable[10]; // Table of 10 mobj pointers
// WARNING: New fields must be added separately to savegame and Lua.
} mobj_t;

View file

@ -947,11 +947,9 @@ typedef enum
MD2_HPREV = 1<<8,
#ifdef ESLOPE
MD2_SLOPE = 1<<9,
MD2_COLORIZED = 1<<10,
MD2_MOBJTABLE = 1<<11
MD2_COLORIZED = 1<<10
#else
MD2_COLORIZED = 1<<9,
MD2_MOBJTABLE = 1<<10
MD2_COLORIZED = 1<<9
#endif
} mobj_diff2_t;
@ -1031,7 +1029,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff;
UINT16 diff2;
UINT16 difft;
UINT8 i;
// Ignore stationary hoops - these will be respawned from mapthings.
@ -1062,7 +1059,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
else
diff = MD_POS | MD_TYPE; // not a map spawned thing so make it from scratch
diff2 = difft = 0;
diff2 = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
@ -1150,14 +1147,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
#endif
if (mobj->colorized)
diff2 |= MD2_COLORIZED;
for (i = 0; i < 10; i++)
{
if (mobj->mobjtable[i])
{
diff2 |= MD2_MOBJTABLE;
difft |= ((i > 0) ? (1<<i) : 1);
}
}
if (diff2 != 0)
diff |= MD_MORE;
@ -1169,8 +1158,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, diff);
if (diff & MD_MORE)
WRITEUINT16(save_p, diff2);
if (diff2 & MD2_MOBJTABLE)
WRITEUINT16(save_p, difft);
// save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj);
@ -1281,14 +1268,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
#endif
if (diff2 & MD2_COLORIZED)
WRITEUINT8(save_p, mobj->colorized);
if (diff2 & MD2_MOBJTABLE)
{
for (i = 0; i < 10; i++)
{
if (difft & ((i > 0) ? (1<<i) : 1))
WRITEUINT32(save_p, mobj->mobjtable[i]->mobjnum);
}
}
WRITEUINT32(save_p, mobj->mobjnum);
}
@ -1959,7 +1938,6 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
UINT16 difft;
INT32 i;
fixed_t z, floorz, ceilingz;
@ -1968,10 +1946,6 @@ static void LoadMobjThinker(actionf_p1 thinker)
diff2 = READUINT16(save_p);
else
diff2 = 0;
if (diff2 & MD2_MOBJTABLE)
difft = READUINT16(save_p);
else
difft = 0;
next = (void *)(size_t)READUINT32(save_p);
@ -2165,14 +2139,6 @@ static void LoadMobjThinker(actionf_p1 thinker)
#endif
if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p);
if (diff2 & MD2_MOBJTABLE)
{
for (i = 0; i < 10; i++)
{
if (difft & ((i > 0) ? (1<<i) : 1))
mobj->mobjtable[i] = (mobj_t *)(size_t)READUINT32(save_p);
}
}
if (diff & MD_REDFLAG)
{