Trailling items

Needs redone with a linked list and remove mobjtable; it doesn't like netgames atm
This commit is contained in:
TehRealSalt 2018-06-16 17:54:12 -04:00
parent 98c6d0f6d9
commit da83809d44
7 changed files with 272 additions and 86 deletions

View file

@ -14510,7 +14510,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_BANANA_SHIELD
-1, // doomednum
S_BANANA, // spawnstate
S_BANANA, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
@ -14521,12 +14521,12 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_BANANA_DEAD, // deathstate
S_BANANA_DEAD, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
12*FRACUNIT, // radius
20*FRACUNIT, // height
0, // display offset
100, // mass
1, // damage

View file

@ -2008,6 +2008,37 @@ void K_DriftDustHandling(mobj_t *spawner)
}
}
static mobj_t *K_FindLastTrailMobj(player_t *player)
{
thinker_t *th;
mobj_t *mo;
mobj_t *trail = NULL;
if (!player)
return NULL;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
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;
}
return trail;
}
static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, boolean minethrow)
{
mobj_t *mo;
@ -2124,13 +2155,23 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
}
else
{
fixed_t dropradius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(mobjinfo[mapthing].radius, mobjinfo[mapthing].radius);
mobj_t *lasttrail = K_FindLastTrailMobj(player);
// Drop it directly behind you.
newangle = player->mo->angle;
if (lasttrail)
{
newx = lasttrail->x;
newy = lasttrail->y;
}
else
{
// Drop it directly behind you.
fixed_t dropradius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(mobjinfo[mapthing].radius, mobjinfo[mapthing].radius);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, dropradius);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, dropradius);
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, dropradius);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, dropradius);
}
mo = P_SpawnMobj(newx, newy, player->mo->z, mapthing);
@ -2986,48 +3027,49 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_BANANA:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{
if (player->kartstuff[k_itemamount] == 1) // Banana x1 held
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *mo;
player->kartstuff[k_itemheld] = 1;
player->pflags |= PF_ATTACKDOWN;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANA_SHIELD);
mo->threshold = 10;
if (mo)
P_SetTarget(&mo->target, player->mo);
}
else if (player->kartstuff[k_itemamount] > 1) // Banana x3 held
{
INT32 moloop;
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *master;
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 2;
player->pflags |= PF_ATTACKDOWN;
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;
for (moloop = 0; moloop < player->kartstuff[k_itemamount]; moloop++)
if (master)
{
P_SetTarget(&master->target, player->mo);
if (master->movecount > 0) // Banana x3/x10 held
{
angle_t newangle;
fixed_t newx;
fixed_t newy;
mobj_t *mo;
newangle = player->mo->angle;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
mo = P_SpawnMobj(newx, newy, player->mo->z, MT_BANANA_SHIELD);
INT32 moloop;
K_PlayTauntSound(player->mo);
player->kartstuff[k_itemheld] = 2;
if (mo)
for (moloop = 0; moloop < master->movecount; moloop++)
{
mo->threshold = 10;
mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
mo->angle = FixedAngle(((90/player->kartstuff[k_itemamount])*moloop)*FRACUNIT);
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;
}
}
}
}
@ -3041,7 +3083,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else if (ATTACK_IS_DOWN && player->kartstuff[k_itemheld] == 2) // Banana x3 thrown
{
K_ThrowKartItem(player, false, MT_BANANA, -1,false );
K_ThrowKartItem(player, false, MT_BANANA, -1, false);
K_PlayTauntSound(player->mo);
player->pflags |= PF_ATTACKDOWN;
player->kartstuff[k_itemamount]--;

View file

@ -81,7 +81,8 @@ enum mobj_e {
mobj_extravalue2,
mobj_cusval,
mobj_cvmem,
mobj_colorized
mobj_colorized,
mobj_mobjtable
};
static const char *const mobj_opt[] = {
@ -142,6 +143,7 @@ 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])
@ -348,6 +350,9 @@ 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));
@ -646,6 +651,8 @@ 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

@ -2062,29 +2062,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
//if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
// P_SetTarget(&target->tracer, inflictor);
// SRB2kart
// I wish I knew a better way to do this
if (target->target && target->target->player && target->target->player->mo)
{
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_FAKESHIELD)
target->target->player->kartstuff[k_eggmanheld] = 0;
if ((target->target->player->kartstuff[k_itemheld])
&& ((target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT)
|| (target->type == MT_JAWZ_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_JAWZ)
|| (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 > 0)
target->target->player->kartstuff[k_itemamount] = target->lastlook-1;
else
target->target->player->kartstuff[k_itemamount]--;
if (!target->target->player->kartstuff[k_itemamount])
target->target->player->kartstuff[k_itemheld] = 0;
}
}
//
if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6)
sstimer = 6; // Just let P_Ticker take care of the rest.
@ -2116,6 +2093,60 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
return;
#endif
// SRB2kart
// I wish I knew a better way to do this
if (target->target && target->target->player && target->target->player->mo)
{
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_FAKESHIELD)
target->target->player->kartstuff[k_eggmanheld] = 0;
if ((target->target->player->kartstuff[k_itemheld])
&& ((target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT)
|| (target->type == MT_JAWZ_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_JAWZ)
|| (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->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)
{
INT32 i;
for (i = 0; i < 10; i++)
{
if (target->mobjtable[i] && target->mobjtable[i]->health)
P_KillMobj(target->mobjtable[i], 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]--;
}
else
{
if (target->lastlook > 0)
target->target->player->kartstuff[k_itemamount] = target->lastlook-1;
else
target->target->player->kartstuff[k_itemamount]--;
}
if (!target->target->player->kartstuff[k_itemamount])
target->target->player->kartstuff[k_itemheld] = 0;
}
}
//
// Let EVERYONE know what happened to a player! 01-29-2002 Tails
if (target->player && !target->player->spectator)
{

View file

@ -6682,11 +6682,8 @@ void P_MobjThinker(mobj_t *mobj)
}
break;
}
case MT_GREENSHIELD:
case MT_GREENSHIELD: // Kart orbit items
case MT_JAWZ_SHIELD:
case MT_BANANA_SHIELD:
case MT_FAKESHIELD:
case MT_SSMINE_SHIELD:
if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
@ -6694,12 +6691,8 @@ void P_MobjThinker(mobj_t *mobj)
const fixed_t radius = FixedHypot(mobj->target->radius, mobj->target->radius) + FixedHypot(mobj->radius, mobj->radius); // mobj's distance from its Target, or Radius.
//mobj->angle += FixedAngle(12*FRACUNIT); // mobj's actual speed.
if ((mobj->type == MT_GREENSHIELD || mobj->type == MT_JAWZ_SHIELD) && mobj->lastlook > 0)
if (mobj->lastlook > 0)
mobj->angle += FixedAngle(mobj->info->speed);
else if (mobj->type == MT_BANANA_SHIELD && mobj->lastlook == 2)
mobj->angle = (mobj->target->angle + ANGLE_135);
else if (mobj->type == MT_BANANA_SHIELD && mobj->lastlook == 3)
mobj->angle = (mobj->target->angle + ANGLE_225);
else
mobj->angle = (mobj->target->angle + ANGLE_180);
@ -6756,7 +6749,85 @@ void P_MobjThinker(mobj_t *mobj)
// Was this so hard?
if ((mobj->type == MT_GREENSHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
|| (mobj->type == MT_BANANA_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_BANANA)
|| (mobj->lastlook > 0 && mobj->target->player->kartstuff[k_itemamount] < mobj->lastlook)
|| (!mobj->target->player->kartstuff[k_itemheld]))
{
P_RemoveMobj(mobj);
return;
}
}
else if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
|| P_CheckDeathPitCollide(mobj)) // When in death state
{
P_RemoveMobj(mobj);
return;
}
break;
case MT_BANANA_SHIELD: // Kart trailing items
case MT_SSMINE_SHIELD:
case MT_FAKESHIELD:
if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
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;
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.
{
for (i = 0; i < mobj->movecount; i++)
{
mobj_t *targ;
if (!mobj->mobjtable[i])
continue;
targ = mobj;
if (previ >= 0 && mobj->mobjtable[previ])
targ = mobj->mobjtable[previ];
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;
mobj->mobjtable[i]->angle = R_PointToAngle2(mobj->mobjtable[i]->x, mobj->mobjtable[i]->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);
previ = i;
}
}
}
// Was this so hard?
if ((mobj->type == MT_BANANA_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_BANANA)
|| (mobj->type == MT_SSMINE_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_MINE)
|| (mobj->type == MT_FAKESHIELD && !mobj->target->player->kartstuff[k_eggmanheld])
|| (mobj->type != MT_FAKESHIELD && !mobj->target->player->kartstuff[k_itemheld])

View file

@ -367,6 +367,7 @@ 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

@ -944,13 +944,14 @@ typedef enum
MD2_EXTVAL1 = 1<<5,
MD2_EXTVAL2 = 1<<6,
MD2_HNEXT = 1<<7,
MD2_HPREV = 1<<8,
#ifdef ESLOPE
MD2_HPREV = 1<<8,
MD2_SLOPE = 1<<9,
MD2_COLORIZED = 1<<10
MD2_COLORIZED = 1<<10,
MD2_MOBJTABLE = 1<<11
#else
MD2_HPREV = 1<<8,
MD2_COLORIZED = 1<<9
MD2_COLORIZED = 1<<9,
MD2_MOBJTABLE = 1<<10
#endif
} mobj_diff2_t;
@ -1030,6 +1031,8 @@ 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.
if (mobj->type == MT_HOOP)
@ -1059,7 +1062,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 = 0;
diff2 = difft = 0;
// not the default but the most probable
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
@ -1147,6 +1150,14 @@ 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;
@ -1158,6 +1169,8 @@ 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);
@ -1268,6 +1281,14 @@ 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);
}
@ -1938,6 +1959,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj_t *mobj;
UINT32 diff;
UINT16 diff2;
UINT16 difft;
INT32 i;
fixed_t z, floorz, ceilingz;
@ -1946,6 +1968,10 @@ 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);
@ -2139,6 +2165,14 @@ 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)
{