From 844416855f86244ce46e0fc3ff920f4b5bf5559b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Oct 2017 14:08:58 +0100 Subject: [PATCH] Smiles follow-mobj initial support! Still using a Lua hook to follow closely behind, but now it doesn't need to be a generic thinkframe. Woo! --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 2 ++ src/g_game.c | 3 +++ src/lua_hook.h | 2 ++ src/lua_hooklib.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/lua_playerlib.c | 8 ++++++++ src/lua_skinlib.c | 5 +++++ src/p_saveg.c | 19 +++++++++++++++++++ src/p_user.c | 34 ++++++++++++++++++++++++++++++++++ src/r_things.c | 10 ++++++++++ src/r_things.h | 1 + 12 files changed, 127 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6685cd5ee..4ec9cdb20 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -544,6 +544,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->thokitem = (UINT32)LONG(players[i].thokitem); //mobjtype_t rsp->spinitem = (UINT32)LONG(players[i].spinitem); //mobjtype_t rsp->revitem = (UINT32)LONG(players[i].revitem); //mobjtype_t + rsp->followitem = (UINT32)LONG(players[i].followitem); //mobjtype_t rsp->actionspd = (fixed_t)LONG(players[i].actionspd); rsp->mindash = (fixed_t)LONG(players[i].mindash); rsp->maxdash = (fixed_t)LONG(players[i].maxdash); @@ -673,6 +674,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].thokitem = (UINT32)LONG(rsp->thokitem); //mobjtype_t players[i].spinitem = (UINT32)LONG(rsp->spinitem); //mobjtype_t players[i].revitem = (UINT32)LONG(rsp->revitem); //mobjtype_t + players[i].followitem = (UINT32)LONG(rsp->followitem); //mobjtype_t players[i].actionspd = (fixed_t)LONG(rsp->actionspd); players[i].mindash = (fixed_t)LONG(rsp->mindash); players[i].maxdash = (fixed_t)LONG(rsp->maxdash); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index b9a4eec3e..bdf332665 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -189,6 +189,7 @@ typedef struct UINT32 thokitem; // mobjtype_t UINT32 spinitem; // mobjtype_t UINT32 revitem; // mobjtype_t + UINT32 followitem; // mobjtype_t fixed_t actionspd; fixed_t mindash; fixed_t maxdash; diff --git a/src/d_player.h b/src/d_player.h index bf0b303b8..e1350fe67 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -369,6 +369,8 @@ typedef struct player_s mobjtype_t thokitem; // Object # to spawn for the thok mobjtype_t spinitem; // Object # to spawn for spindash/spinning mobjtype_t revitem; // Object # to spawn for spindash/spinning + mobjtype_t followitem; // Object # to spawn for Smiles + mobj_t *followmobj; // Smiles all around fixed_t actionspd; // Speed of thok/glide/fly fixed_t mindash; // Minimum spindash speed diff --git a/src/g_game.c b/src/g_game.c index 19abd516b..df933c4cb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2144,6 +2144,7 @@ void G_PlayerReborn(INT32 player) UINT32 thokitem; UINT32 spinitem; UINT32 revitem; + UINT32 followitem; fixed_t actionspd; fixed_t mindash; fixed_t maxdash; @@ -2215,6 +2216,7 @@ void G_PlayerReborn(INT32 player) thokitem = players[player].thokitem; spinitem = players[player].spinitem; revitem = players[player].revitem; + followitem = players[player].followitem; actionspd = players[player].actionspd; mindash = players[player].mindash; maxdash = players[player].maxdash; @@ -2252,6 +2254,7 @@ void G_PlayerReborn(INT32 player) p->thokitem = thokitem; p->spinitem = spinitem; p->revitem = revitem; + p->followitem = followitem; p->actionspd = actionspd; p->mindash = mindash; p->maxdash = maxdash; diff --git a/src/lua_hook.h b/src/lua_hook.h index fe5706f56..822edf79f 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -47,6 +47,7 @@ enum hook { hook_ShieldSpecial, hook_MobjMoveBlocked, hook_MapThingSpawn, + hook_FollowMobj, hook_MAX // last hook }; @@ -85,5 +86,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 #define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities #define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type +boolean LUAh_FollowMobj(player_t *player, mobj_t *mo); // Hook for P_PlayerAfterThink Smiles mobj-following #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 3dd3f932f..0a7ef801e 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -58,6 +58,7 @@ const char *const hookNames[hook_MAX+1] = { "ShieldSpecial", "MobjMoveBlocked", "MapThingSpawn", + "FollowMobj", NULL }; @@ -197,6 +198,7 @@ static int lib_addHook(lua_State *L) case hook_SpinSpecial: case hook_JumpSpinSpecial: case hook_PlayerSpawn: + case hook_FollowMobj: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1138,4 +1140,42 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) return hooked; } +// Hook for P_PlayerAfterThink Smiles mobj-following +boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_FollowMobj/8] & (1<<(hook_FollowMobj%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + if (hookp->type == hook_FollowMobj) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, mobj, META_MOBJ); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + #endif diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 7c55012d2..12b2646d0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -174,6 +174,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->spinitem); else if (fastcmp(field,"revitem")) lua_pushinteger(L, plr->revitem); + else if (fastcmp(field,"followitem")) + lua_pushinteger(L, plr->followitem); + else if (fastcmp(field,"followmobj")) + LUA_PushUserdata(L, plr->followmobj, META_MOBJ); else if (fastcmp(field,"actionspd")) lua_pushfixed(L, plr->actionspd); else if (fastcmp(field,"mindash")) @@ -441,6 +445,10 @@ static int player_set(lua_State *L) plr->spinitem = luaL_checkinteger(L, 3); else if (fastcmp(field,"revitem")) plr->revitem = luaL_checkinteger(L, 3); + else if (fastcmp(field,"followitem")) + plr->followitem = luaL_checkinteger(L, 3); + else if (fastcmp(field,"followmobj")) + plr->followmobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); else if (fastcmp(field,"actionspd")) plr->actionspd = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"mindash")) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index f93513c49..1a70a82d9 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -35,6 +35,7 @@ enum skin { skin_thokitem, skin_spinitem, skin_revitem, + skin_followitem, skin_actionspd, skin_mindash, skin_maxdash, @@ -73,6 +74,7 @@ static const char *const skin_opt[] = { "thokitem", "spinitem", "revitem", + "followitem", "actionspd", "mindash", "maxdash", @@ -162,6 +164,9 @@ static int skin_get(lua_State *L) case skin_revitem: lua_pushinteger(L, skin->revitem); break; + case skin_followitem: + lua_pushinteger(L, skin->followitem); + break; case skin_actionspd: lua_pushfixed(L, skin->actionspd); break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 8efe7027b..bb89b643a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -56,6 +56,7 @@ typedef enum AWAYVIEW = 0x08, FIRSTAXIS = 0x10, SECONDAXIS = 0x20, + FOLLOW = 0x40, } player_saveflags; // @@ -220,6 +221,9 @@ static void P_NetArchivePlayers(void) if (players[i].axis2) flags |= SECONDAXIS; + if (players[i].followmobj) + flags |= FOLLOW; + WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); @@ -245,6 +249,9 @@ static void P_NetArchivePlayers(void) if (flags & AWAYVIEW) WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); + if (flags & FOLLOW) + WRITEUINT32(save_p, players[i].followmobj->mobjnum); + WRITEFIXED(save_p, players[i].camerascale); WRITEFIXED(save_p, players[i].shieldscale); @@ -254,6 +261,7 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, (UINT32)players[i].thokitem); WRITEUINT32(save_p, (UINT32)players[i].spinitem); WRITEUINT32(save_p, (UINT32)players[i].revitem); + WRITEUINT32(save_p, (UINT32)players[i].followitem); WRITEFIXED(save_p, players[i].actionspd); WRITEFIXED(save_p, players[i].mindash); WRITEFIXED(save_p, players[i].maxdash); @@ -413,6 +421,9 @@ static void P_NetUnArchivePlayers(void) if (flags & AWAYVIEW) players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p); + if (flags & FOLLOW) + players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p); + players[i].viewheight = cv_viewheight.value<player->awayviewmobj, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); } + if (mobj->player && mobj->player->followmobj) + { + temp = (UINT32)(size_t)mobj->player->followmobj; + mobj->player->followmobj = NULL; + if (!P_SetTarget(&mobj->player->followmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "followmobj not found on %d\n", mobj->type); + } } } } diff --git a/src/p_user.c b/src/p_user.c index cfe9b334b..86d58b663 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -591,6 +591,7 @@ static void P_DeNightserizePlayer(player_t *player) player->mo->flags &= ~MF_NOGRAVITY; player->mo->skin = &skins[player->skin]; + player->followitem = skins[player->skin].followitem; player->mo->color = player->skincolor; // Restore aiming angle @@ -666,6 +667,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { player->mo->skin = &skins[DEFAULTNIGHTSSKIN]; player->mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; + player->followitem = skins[DEFAULTNIGHTSSKIN].followitem; } player->nightstime = player->startedtime = nighttime*TICRATE; @@ -10165,6 +10167,11 @@ void P_PlayerAfterThink(player_t *player) if (thiscam && thiscam->chase) P_MoveChaseCamera(player, thiscam, false); } + if (player->followmobj) + { + P_RemoveMobj(player->followmobj); + player->followmobj = NULL; + } return; } @@ -10456,4 +10463,31 @@ void P_PlayerAfterThink(player_t *player) if (P_IsObjectOnGround(player->mo)) player->mo->pmomz = 0; + + if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem)) + { + P_RemoveMobj(player->followmobj); + player->followmobj = NULL; + } + + if (!player->spectator && player->mo->health && player->followitem) + { + if (!player->followmobj || P_MobjWasRemoved(player->followmobj)) + player->followmobj = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, player->followitem); + + if (player->followmobj) + { +#ifdef HAVE_BLUA + if (LUAh_FollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) + {;} + //else +#endif + /*switch (player->followmobj->type) + { + case MT_ALTVIEWMAN: + break; + ; + }*/ + } + } } diff --git a/src/r_things.c b/src/r_things.c index 116782c3c..49b3dbcf5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2525,6 +2525,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->thokitem = -1; skin->spinitem = -1; skin->revitem = -1; + skin->followitem = 0; skin->highresscale = FRACUNIT; @@ -2638,6 +2639,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + player->followitem = skin->followitem; player->actionspd = skin->actionspd; player->mindash = skin->mindash; @@ -2663,6 +2665,12 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->skincolor = newcolor = skin->prefcolor; } + if (player->followmobj) + { + P_RemoveMobj(player->followmobj); + player->followmobj = NULL; + } + if (player->mo) { fixed_t radius = FixedMul(skin->radius, player->mo->scale); @@ -2670,6 +2678,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { skin = &skins[DEFAULTNIGHTSSKIN]; newcolor = skin->prefcolor; // will be updated in thinker to flashing + player->followitem = skin->followitem; } player->mo->skin = skin; if (newcolor) @@ -2803,6 +2812,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) FULLPROCESS(thokitem) FULLPROCESS(spinitem) FULLPROCESS(revitem) + FULLPROCESS(followitem) #undef FULLPROCESS #define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<