Add mo.rollsum and player.sliproll fields. Rendering and frame interp… #69

Merged
alufolie91 merged 1 commits from lua-more-rotation-fields into Saturn 2023-09-18 15:51:34 +02:00
5 changed files with 103 additions and 0 deletions

No files matched your search

+31
View File
@@ -16,6 +16,7 @@
#ifdef HAVE_BLUA
#include "fastcmp.h"
#include "r_things.h"
#include "r_main.h"
#include "p_local.h"
#include "g_game.h"
#include "p_setup.h"
@@ -65,6 +66,8 @@ int mobj_mobjnum_unimplemented(lua_State *L);
int mobj_scale_setter(lua_State *L);
int mobj_destscale_setter(lua_State *L);
int mobj_standingslope_noset(lua_State *L);
int mobj_rollsum_getter(lua_State *L);
int mobj_rollsum_noset(lua_State *L);
static const char *const array_opt[] ={"iterate",NULL};
@@ -78,6 +81,8 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, angle, udatalib_getter_angle, mobj_angle_setter),
FIELD(mobj_t, rollangle, udatalib_getter_angle, udatalib_setter_angle),
FIELD(mobj_t, sloperoll, udatalib_getter_angle, mobj_sloperoll_noop),
// Macro fails here
{ "rollsum", 0, mobj_rollsum_getter, mobj_rollsum_noset },
FIELD(mobj_t, sprite, udatalib_getter_spritenum, udatalib_setter_spritenum),
FIELD(mobj_t, frame, udatalib_getter_uint32, udatalib_setter_uint32),
FIELD(mobj_t, anim_duration, udatalib_getter_uint16, udatalib_setter_uint16),
@@ -174,13 +179,21 @@ int mobj_ ## field ## _noset(lua_State *L) \
return luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", #field); \
}
#define NOSET_USE(field, use) \
int mobj_ ## field ## _noset(lua_State *L) \
{ \
return luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL(use) " instead.", #field); \
}
NOSET(snext)
NOSET(bnext)
NOSET(info)
NOSET(player)
NOSET(standingslope)
NOSET_USE(rollsum, "rollangle")
#undef NOSET
#undef NOSET_USE
// Unimplemented fields (why would you need to set them like that explicitly?
// No idea, i'm keeping it for synch reasons)
@@ -539,6 +552,24 @@ int mobj_destscale_setter(lua_State *L)
return 0;
}
// WARNING: Not synch safe!
// Don't use this field in game logic code!
int mobj_rollsum_getter(lua_State *L)
{
mobj_t *mo = GETMO();
angle_t rollsum = mo->rollangle + cv_sloperoll.value ? mo->sloperoll : 0;
if (mo->player)
{
rollsum += R_PlayerSliptideAngle(mo->player);
}
lua_pushangle(L, rollsum);
return 1;
}
static int mobj_get(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+16
View File
@@ -13,6 +13,7 @@
#include "doomdef.h"
#ifdef HAVE_BLUA
#include "fastcmp.h"
#include "r_main.h"
#include "p_mobj.h"
#include "d_player.h"
#include "g_game.h"
@@ -44,6 +45,10 @@ int player_splitscreenindex_noset(lua_State *L);
int player_ping_getter(lua_State *L);
int player_ping_noset(lua_State *L);
// Non synch safe!
int player_sliproll_getter(lua_State *L);
int player_sliproll_noset(lua_State *L);
#define FIELD(type, field_name, getter, setter) { #field_name, offsetof(type, field_name), getter, setter }
static const udata_field_t player_fields[] = {
// Player doesn't actually have field "name" so macro fails. Need to declare field manually.
@@ -150,6 +155,7 @@ static const udata_field_t player_fields[] = {
FIELD(player_t, fovadd, udatalib_getter_fixed, udatalib_setter_fixed), // Mmm yeah thats definitely synch safe
#endif
// Same as player.name
{ "sliproll", 0, player_sliproll_getter, player_sliproll_noset },
{ "ping", 0, player_ping_getter, player_ping_noset }, // Hmm originally setter doesn't exist so data is written as unreachable custom field...
{ NULL },
};
@@ -207,6 +213,7 @@ NOSET(kartstuff)
NOSET(bot)
NOSET(splitscreenindex)
NOSET(ping)
NOSET(sliproll)
#undef NOSET
@@ -331,6 +338,15 @@ int player_ping_getter(lua_State *L)
return 1;
}
int player_sliproll_getter(lua_State *L)
{
player_t *plr = GETPLAYER();
lua_pushangle(L, R_PlayerSliptideAngle(plr));
return 1;
}
static int lib_iteratePlayers(lua_State *L)
{
INT32 i = -1;
+1
View File
@@ -19,6 +19,7 @@
// We rely on the thinker data struct to handle sound origins in sectors.
#include "d_think.h"
// SECTORS do store MObjs anyway.
#include "p_mobj.h"
+54
View File
@@ -439,6 +439,60 @@ fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1)
return FixedHypot(px1 - px2, py1 - py2);
}
angle_t R_PlayerSliptideAngle(player_t *player)
{
mobj_t *mo = player->mo;
if (!cv_sliptideroll.value || !mo || P_MobjWasRemoved(mo)) return 0;
size_t rot = mo->frame&FF_FRAMEMASK;
boolean papersprite = (mo->frame & FF_PAPERSPRITE);
spritedef_t *sprdef;
spriteframe_t *sprframe;
angle_t ang = 0;
interpmobjstate_t interp = {0};
// Yes.
if (R_UsingFrameInterpolation() && !paused)
{
R_InterpolateMobjState(mo, rendertimefrac, &interp);
}
else
{
R_InterpolateMobjState(mo, FRACUNIT, &interp);
}
if (mo->skin && mo->sprite == SPR_PLAY)
{
sprdef = &((skin_t *)mo->skin)->spritedef;
if (rot >= sprdef->numframes)
sprdef = &sprites[mo->sprite];
}
else
{
sprdef = &sprites[mo->sprite];
}
if (rot >= sprdef->numframes)
{
sprdef = &sprites[states[S_UNKNOWN].sprite];
rot = states[S_UNKNOWN].frame&FF_FRAMEMASK;
}
sprframe = &sprdef->spriteframes[rot];
// No sprite frame? I guess it is possible
if (!sprframe) return 0;
if (sprframe->rotate != SRF_SINGLE || papersprite)
ang = R_PointToAngle(interp.x, interp.y) - interp.angle;
return FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mo->player->sliproll*(mo->player->sliptidemem));
}
// Little extra utility. Works in the same way as R_PointToAngle2
fixed_t R_PointToDist(fixed_t x, fixed_t y)
{
+1
View File
@@ -73,6 +73,7 @@ angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1);
fixed_t R_PointToDist(fixed_t x, fixed_t y);
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
angle_t R_PlayerSliptideAngle(player_t *player);
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);