mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-20 20:41:10 +00:00
Merge public master
This commit is contained in:
commit
7febf53ec0
31 changed files with 1485 additions and 121 deletions
|
|
@ -126,6 +126,8 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
lua_hudlib_drawlist.c
|
||||
lua_followerlib.c
|
||||
lua_itemroulettelib.c
|
||||
lua_respawnvarslib.c
|
||||
lua_waypointslib.c
|
||||
lua_profile.cpp
|
||||
k_kart.c
|
||||
k_respawn.c
|
||||
|
|
@ -213,7 +215,7 @@ if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND
|
|||
target_link_options(SRB2SDL2 PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE Threads::Threads)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE Threads::Threads)
|
||||
endif()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
target_link_options(SRB2SDL2 PRIVATE "-Wl,--large-address-aware")
|
||||
|
|
|
|||
|
|
@ -3368,6 +3368,12 @@ enum
|
|||
THING_PROP_HNEXT,
|
||||
THING_PROP_HPREV,
|
||||
THING_PROP_ITNEXT,
|
||||
THING_PROP_BAKEDXOFFSET,
|
||||
THING_PROP_BAKEDYOFFSET,
|
||||
THING_PROP_BAKEDZOFFSET,
|
||||
THING_PROP_BAKEDXPIVOT,
|
||||
THING_PROP_BAKEDYPIVOT,
|
||||
THING_PROP_BAKEDZPIVOT,
|
||||
THING_PROP__MAX
|
||||
};
|
||||
|
||||
|
|
@ -3553,6 +3559,12 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
|
|||
PROP_MOBJ(THING_PROP_HNEXT, hnext)
|
||||
PROP_MOBJ(THING_PROP_HPREV, hprev)
|
||||
PROP_MOBJ(THING_PROP_ITNEXT, itnext)
|
||||
PROP_INT(THING_PROP_BAKEDXOFFSET, bakexoff)
|
||||
PROP_INT(THING_PROP_BAKEDYOFFSET, bakeyoff)
|
||||
PROP_INT(THING_PROP_BAKEDZOFFSET, bakezoff)
|
||||
PROP_INT(THING_PROP_BAKEDXPIVOT, bakexpiv)
|
||||
PROP_INT(THING_PROP_BAKEDYPIVOT, bakeypiv)
|
||||
PROP_INT(THING_PROP_BAKEDZPIVOT, bakezpiv)
|
||||
default:
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "GetThingProperty type %d out of range (expected 0 - %d).\n", property, THING_PROP__MAX-1);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include "k_boss.h" // spottype_t (for lua)
|
||||
#include "k_follower.h" // followermode_t (for lua)
|
||||
#include "music.h" // tune flags (for lua)
|
||||
#include "k_respawn.h" // respawn values (for lua)
|
||||
#include "k_waypoint.h" // waypoint values (for lua)
|
||||
|
||||
#include "deh_tables.h"
|
||||
|
||||
|
|
@ -4857,6 +4859,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"OV_DONT3DOFFSET", OV_DONT3DOFFSET},
|
||||
{"OV_DONTXYSCALE", OV_DONTXYSCALE},
|
||||
{"OV_DONTROLL", OV_DONTROLL},
|
||||
{"OV_DONTBAKEOFFSET", OV_DONTBAKEOFFSET},
|
||||
|
||||
// Player state (playerstate_t)
|
||||
{"PST_LIVE",PST_LIVE}, // Playing or camping.
|
||||
|
|
@ -5339,6 +5342,16 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"TN_NIGHTCOREABLE",TN_NIGHTCOREABLE},
|
||||
{"TN_CHANGEPITCH",TN_CHANGEPITCH},
|
||||
{"TN_LOOPING",TN_LOOPING},
|
||||
|
||||
// k_respawn.h values
|
||||
{"RESPAWN_DIST",RESPAWN_DIST},
|
||||
{"RESPAWN_TIME",RESPAWN_TIME},
|
||||
{"RESPAWNST_NONE",RESPAWNST_NONE},
|
||||
{"RESPAWNST_MOVE",RESPAWNST_MOVE},
|
||||
{"RESPAWNST_DROP",RESPAWNST_DROP},
|
||||
|
||||
// k_waypoint.h values
|
||||
{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},
|
||||
|
||||
{"PICKUP_RINGORSPHERE", PICKUP_RINGORSPHERE},
|
||||
{"PICKUP_ITEMBOX", PICKUP_ITEMBOX},
|
||||
|
|
|
|||
|
|
@ -3115,11 +3115,15 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
R_InterpolateMobjState(thing, FRACUNIT, &interp);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * HITLAGJITTERS;
|
||||
fixed_t jitters = HITLAGJITTERS;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
jitters += (rendertimefrac / HITLAGDIV);
|
||||
fixed_t mul = thing->hitlag * jitters;
|
||||
|
||||
// perhaps there could be a way to interp this too?
|
||||
if (leveltime & 1)
|
||||
{
|
||||
mul = -mul;
|
||||
|
|
@ -4666,6 +4670,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
patch_t *rotsprite = NULL;
|
||||
INT32 rollangle = 0;
|
||||
angle_t spriterotangle = 0;
|
||||
vector2_t visoffs;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
|
|
@ -4685,10 +4690,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
dispoffset = thing->dispoffset;
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * HITLAGJITTERS;
|
||||
fixed_t jitters = HITLAGJITTERS;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
jitters += (rendertimefrac / HITLAGDIV);
|
||||
|
||||
fixed_t mul = thing->hitlag * jitters;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
|
|
@ -4861,12 +4870,31 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
flip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize and rotate pitch/roll vector
|
||||
visoffs.x = 0;
|
||||
visoffs.y = 0;
|
||||
|
||||
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
|
||||
|
||||
if (R_ThingIsUsingBakedOffsets(thing))
|
||||
{
|
||||
R_RotateSpriteOffsetsByPitchRoll(thing,
|
||||
vflip,
|
||||
hflip,
|
||||
&visoffs);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = interp.spritexoffset;
|
||||
#ifdef ROTSPRITE
|
||||
spr_topoffset = (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
|
||||
mapobjectscale));
|
||||
#else
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -4876,7 +4904,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
flipoffset = -1;
|
||||
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
#ifdef ROTSPRITE
|
||||
spr_topoffset += (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
|
||||
mapobjectscale))
|
||||
* flipoffset;
|
||||
#else
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (papersprite)
|
||||
|
|
@ -4934,17 +4968,28 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef ROTSPRITE
|
||||
if (visoffs.x)
|
||||
{
|
||||
visoffs.x = (FixedDiv((visoffs.x * FRACUNIT), mapobjectscale));
|
||||
}
|
||||
#endif
|
||||
if (flip)
|
||||
{
|
||||
x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale);
|
||||
#ifdef ROTSPRITE
|
||||
spr_offset -= visoffs.x;
|
||||
#endif
|
||||
x1 = (FIXED_TO_FLOAT((spr_width - spr_offset)) * this_xscale);
|
||||
x2 = (FIXED_TO_FLOAT(spr_offset) * this_xscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ROTSPRITE
|
||||
spr_offset += visoffs.x;
|
||||
#endif
|
||||
x1 = (FIXED_TO_FLOAT(spr_offset) * this_xscale);
|
||||
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale);
|
||||
}
|
||||
|
||||
// test if too close
|
||||
/*
|
||||
if (papersprite)
|
||||
|
|
|
|||
|
|
@ -1404,7 +1404,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
// hitlag vibrating
|
||||
if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = spr->mobj->hitlag * HITLAGJITTERS;
|
||||
fixed_t jitters = HITLAGJITTERS;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
jitters += (rendertimefrac / HITLAGDIV);
|
||||
fixed_t mul = spr->mobj->hitlag * jitters;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
|
|
@ -1670,14 +1673,23 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
|
||||
angle_t pitchR, rollR, fixedAngY;
|
||||
|
||||
pitchR = 0;
|
||||
rollR = 0;
|
||||
fixedAngY = 0;
|
||||
|
||||
{
|
||||
fixed_t anglef = AngleFixed(R_ModelRotationAngle(spr->mobj, NULL));
|
||||
|
||||
p.rollangle = 0.0f;
|
||||
|
||||
// make fixedAngY a disguised fixed_t first
|
||||
fixedAngY = FLOAT_TO_FIXED(p.angley);
|
||||
|
||||
if (anglef)
|
||||
{
|
||||
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
|
||||
fixed_t camAngleDiff = AngleFixed(viewangle) - (fixed_t)(fixedAngY); // dumb reconversion back, I know
|
||||
|
||||
p.rollangle = FIXED_TO_FLOAT(anglef);
|
||||
p.roll = true;
|
||||
|
|
@ -1687,9 +1699,19 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
|
||||
|
||||
// rotation axes relative to camera
|
||||
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
|
||||
pitchR = FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT);
|
||||
rollR = FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT);
|
||||
|
||||
p.rollx = FIXED_TO_FLOAT((fixed_t)rollR);
|
||||
p.rollz = FIXED_TO_FLOAT((fixed_t)pitchR);
|
||||
|
||||
// convert to angles
|
||||
pitchR = FixedAngle((fixed_t)pitchR);
|
||||
rollR = FixedAngle((fixed_t)rollR);
|
||||
}
|
||||
|
||||
// make this a proper angle now
|
||||
fixedAngY = FixedAngle(fixedAngY);
|
||||
}
|
||||
|
||||
p.anglez = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_pitch, spr->mobj->pitch)));
|
||||
|
|
@ -1713,6 +1735,88 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
p.y += ox * gl_viewcos;
|
||||
p.z += oy;
|
||||
|
||||
if (R_ThingIsUsingBakedOffsets(spr->mobj))
|
||||
{
|
||||
// visoffset stuff
|
||||
float xx, xy, yx, yy;
|
||||
float zx, zy, zz;
|
||||
float xpiv, ypiv, zpiv;
|
||||
fixed_t zh;
|
||||
fixed_t xoffs, yoffs;
|
||||
|
||||
// xoffs = (cos(xoff) + sin(yoff))
|
||||
xoffs =
|
||||
FixedMul(spr->mobj->bakeyoff, -FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(spr->mobj->bakexoff, FINESINE(fixedAngY >> ANGLETOFINESHIFT));
|
||||
|
||||
// yoffs = (-sin(xoff) + cos(yoff))
|
||||
yoffs =
|
||||
FixedMul(spr->mobj->bakeyoff, -FINESINE(fixedAngY >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(spr->mobj->bakexoff, FINECOSINE(fixedAngY >> ANGLETOFINESHIFT));
|
||||
|
||||
const fixed_t hflipmul = hflip ? -FRACUNIT : FRACUNIT;
|
||||
|
||||
xpiv = FIXED_TO_FLOAT(
|
||||
FixedMul(
|
||||
FixedMul(spr->mobj->bakeypiv,
|
||||
-FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(spr->mobj->bakexpiv,
|
||||
FINESINE(fixedAngY >> ANGLETOFINESHIFT)),
|
||||
hflipmul));
|
||||
ypiv = FIXED_TO_FLOAT(
|
||||
FixedMul(
|
||||
FixedMul(spr->mobj->bakeypiv,
|
||||
-FINESINE(fixedAngY >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(spr->mobj->bakexpiv,
|
||||
FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)),
|
||||
hflipmul));
|
||||
zpiv = FIXED_TO_FLOAT(spr->mobj->bakezpiv * ((flip) ? -1 : 1));
|
||||
|
||||
pitchR = ((pitchR + spr->mobj->pitch) * ((flip) ? -1 : 1));
|
||||
rollR = ((rollR + spr->mobj->roll) * ((flip) ? -1 : 1));
|
||||
|
||||
// x offset
|
||||
xx = FIXED_TO_FLOAT(FixedMul(FixedMul(
|
||||
FixedMul(xoffs,spr->mobj->spritexscale),
|
||||
hflipmul),
|
||||
FINECOSINE(pitchR >> ANGLETOFINESHIFT)
|
||||
));
|
||||
xy = FIXED_TO_FLOAT(FixedMul(FixedMul(
|
||||
FixedMul(xoffs,spr->mobj->spritexscale),
|
||||
hflipmul),
|
||||
-FINESINE(pitchR >> ANGLETOFINESHIFT)
|
||||
));
|
||||
|
||||
// y offset
|
||||
yx = FIXED_TO_FLOAT(FixedMul(FixedMul(
|
||||
FixedMul(yoffs,spr->mobj->spritexscale),
|
||||
hflipmul),
|
||||
FINECOSINE(rollR >> ANGLETOFINESHIFT)
|
||||
));
|
||||
|
||||
yy = FIXED_TO_FLOAT(FixedMul(FixedMul(
|
||||
FixedMul(yoffs,spr->mobj->spritexscale),
|
||||
hflipmul),
|
||||
-FINESINE(rollR >> ANGLETOFINESHIFT)
|
||||
));
|
||||
|
||||
// z offset
|
||||
zh = FixedMul(FixedMul(spr->mobj->bakezoff,spr->mobj->spriteyscale),
|
||||
FINECOSINE(rollR >> ANGLETOFINESHIFT));
|
||||
|
||||
zz = FIXED_TO_FLOAT(FixedMul(zh,
|
||||
FINECOSINE(pitchR >> ANGLETOFINESHIFT)));
|
||||
zx = FIXED_TO_FLOAT(FixedMul(zh,
|
||||
FINESINE(pitchR >> ANGLETOFINESHIFT)));
|
||||
zy = FIXED_TO_FLOAT(FixedMul(zh,
|
||||
FINESINE(rollR >> ANGLETOFINESHIFT)));
|
||||
|
||||
// do these namings even make sense at this point?
|
||||
p.x += xx + zx + xpiv;
|
||||
p.z += (xy + yy + zz * (flip ? -1 : 1)) + zpiv;
|
||||
p.y += yx + zy + ypiv;
|
||||
}
|
||||
|
||||
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ extern boolean actionsoverridden[NUMACTIONS];
|
|||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
|
||||
#define NUMSPRITEFREESLOTS (NUMMOBJFREESLOTS*2)
|
||||
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
|
||||
|
||||
// Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c!
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#define MAXHITLAGTICS (30)
|
||||
#define HITLAGJITTERS (FRACUNIT / 20)
|
||||
#define HITLAGDIV (20) // define this so we arent using a magic number
|
||||
#define HITLAGJITTERS (FRACUNIT / HITLAGDIV)
|
||||
#define NUM_HITLAG_STATES (9)
|
||||
#define NUM_HITLAG_SOUNDS (4)
|
||||
|
||||
|
|
|
|||
|
|
@ -6866,7 +6866,11 @@ static void K_drawKartFirstPerson(void)
|
|||
// hitlag vibrating
|
||||
if (stplyr->mo->hitlag > 0 && (stplyr->mo->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = stplyr->mo->hitlag * HITLAGJITTERS;
|
||||
fixed_t jitters = HITLAGJITTERS;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
jitters += (rendertimefrac / HITLAGDIV);
|
||||
|
||||
fixed_t mul = stplyr->mo->hitlag * jitters;
|
||||
if (r_splitscreen && mul > FRACUNIT)
|
||||
mul = FRACUNIT;
|
||||
|
||||
|
|
|
|||
|
|
@ -9537,6 +9537,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->mo->spritexoffset = 0;
|
||||
player->mo->spriteyoffset = 0;
|
||||
|
||||
player->mo->bakexoff = 0;
|
||||
player->mo->bakeyoff = 0;
|
||||
player->mo->bakezoff = 0;
|
||||
player->mo->bakexpiv = 0;
|
||||
player->mo->bakeypiv = 0;
|
||||
player->mo->bakezpiv = 0;
|
||||
|
||||
player->cameraOffset = 0;
|
||||
|
||||
player->pflags &= ~(PF_CASTSHADOW);
|
||||
|
|
|
|||
|
|
@ -2119,6 +2119,9 @@ static void M_DrawCharSelectPreview(UINT8 num)
|
|||
{
|
||||
INT32 randomskin = 0;
|
||||
INT32 doping = 0;
|
||||
char variadicInfoBuffer[(MAXCOLORNAME*2) + 1 + 2 + 1];//+1 for spacing, +2 for brackets, +1 for null terminator
|
||||
UINT16 folcol;
|
||||
|
||||
switch (p->mdepth)
|
||||
{
|
||||
case CSSTEP_ALTS: // Select clone
|
||||
|
|
@ -2149,7 +2152,12 @@ static void M_DrawCharSelectPreview(UINT8 num)
|
|||
case CSSTEP_COLORS: // Select color
|
||||
if (p->color < numskincolors)
|
||||
{
|
||||
V_DrawThinString(x-3, y+2, 0, skincolors[p->color].name);
|
||||
if(p->color == SKINCOLOR_NONE) //'default' handling
|
||||
sprintf(variadicInfoBuffer, "%s (%s)", skincolors[p->color].name, skincolors[skins[p->skin]->prefcolor].name);
|
||||
else
|
||||
sprintf(variadicInfoBuffer, "%s", skincolors[p->color].name);
|
||||
|
||||
V_DrawThinString(x-3, y+2, 0, variadicInfoBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2179,17 +2187,26 @@ static void M_DrawCharSelectPreview(UINT8 num)
|
|||
}
|
||||
break;
|
||||
case CSSTEP_FOLLOWERCOLORS:
|
||||
folcol = K_GetEffectiveFollowerColor(p->followercolor, &followers[p->followern], p->color, skins[p->skin]);
|
||||
|
||||
if (p->followercolor == FOLLOWERCOLOR_MATCH)
|
||||
{
|
||||
V_DrawThinString(x-3, y+2, 0, "Match");
|
||||
sprintf(variadicInfoBuffer, "Match (%s)", skincolors[folcol].name);
|
||||
V_DrawThinString(x-3, y+2, 0, variadicInfoBuffer);
|
||||
}
|
||||
else if (p->followercolor == FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
V_DrawThinString(x-3, y+2, 0, "Opposite");
|
||||
sprintf(variadicInfoBuffer, "Opposite (%s)", skincolors[folcol].name);
|
||||
V_DrawThinString(x-3, y+2, 0, variadicInfoBuffer);
|
||||
}
|
||||
else if (p->followercolor < numskincolors)
|
||||
{
|
||||
V_DrawThinString(x-3, y+2, 0, skincolors[p->followercolor].name);
|
||||
if(p->followercolor == SKINCOLOR_NONE) //'default' handling
|
||||
sprintf(variadicInfoBuffer, "%s (%s)", skincolors[p->followercolor].name, skincolors[folcol].name);
|
||||
else
|
||||
sprintf(variadicInfoBuffer, "%s", skincolors[p->followercolor].name);
|
||||
|
||||
V_DrawThinString(x-3, y+2, 0, variadicInfoBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5889,7 +5906,7 @@ void M_DrawItemToggles(void)
|
|||
|
||||
// Button prompts
|
||||
K_DrawGameControl(
|
||||
(BASEVIDWIDTH/2) - cv_kartfrantic.value, BASEVIDHEIGHT-20, 0,
|
||||
(BASEVIDWIDTH/2) - cv_kartfrantic.value, BASEVIDHEIGHT-20, 0,
|
||||
va(
|
||||
"<c_animated> Toggle All %s<white> <r_animated> Frantic Mode: %s",
|
||||
cv_thunderdome.value ? "<yellow>(Ring Box Mode) " : "<gold>(Item Box Mode)",
|
||||
|
|
|
|||
|
|
@ -61,18 +61,11 @@ static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
|
||||
Updates a player's respawn variables to go to the provided waypoint.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
waypoint - Waypoint to respawn to.
|
||||
|
||||
Return:-
|
||||
None
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
{
|
||||
if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,6 +42,19 @@ extern "C" {
|
|||
|
||||
fixed_t K_RespawnOffset(player_t *player, boolean flip);
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
|
||||
Updates a player's respawn variables to go to the provided waypoint.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
waypoint - Waypoint to respawn to.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint);
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoFault(player_t *player);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,27 @@ boolean K_GetWaypointIsEnabled(waypoint_t *waypoint)
|
|||
return waypointisenabled;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
{
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_SetWaypointIsEnabled.\n");
|
||||
}
|
||||
else if ((waypoint->mobj == NULL) || (P_MobjWasRemoved(waypoint->mobj) == true))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_SetWaypointIsEnabled.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
waypoint->mobj->extravalue1 = enabled ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -162,11 +183,11 @@ boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
|||
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointIsEnabled.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointIsSpawnpoint.\n");
|
||||
}
|
||||
else if ((waypoint->mobj == NULL) || (P_MobjWasRemoved(waypoint->mobj) == true))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_GetWaypointIsEnabled.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_GetWaypointIsSpawnpoint.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -516,7 +537,7 @@ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
|||
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointID.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointHeapIndex.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -115,6 +115,18 @@ boolean K_GetWaypointIsShortcut(waypoint_t *waypoint);
|
|||
boolean K_GetWaypointIsEnabled(waypoint_t *waypoint);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
|
||||
Sets whether the waypoint is enabled or not.
|
||||
|
||||
Input Arguments:-
|
||||
waypoint - The waypoint to set its enabled status to.
|
||||
enabled - Boolean that sets the waypoint's enabled status.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled);
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "k_endcam.h"
|
||||
#include "k_hud.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_waypoint.h"
|
||||
#include "k_respawn.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "k_menu.h" // Player Setup menu color stuff
|
||||
|
|
@ -5965,6 +5967,392 @@ static int lib_kRemoveBot(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kRespawnOffset(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
boolean flip = lua_optboolean(L, 2);
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushfixed(L, K_RespawnOffset(player, flip));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kRespawnAtWaypoint(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
waypoint_t *wp = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
|
||||
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (!wp)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
K_RespawnAtWaypoint(player, wp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kDoFault(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
K_DoFault(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kDoIngameRespawn(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
K_DoIngameRespawn(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kNextRespawnWaypointIndex(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
|
||||
INLEVEL
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushinteger(L, K_NextRespawnWaypointIndex(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetFinishLineWaypoint(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
LUA_PushUserdata(L, K_GetFinishLineWaypoint(), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetStartingWaypoint(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
LUA_PushUserdata(L, K_GetStartingWaypoint(), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointIsFinishline(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushboolean(L, K_GetWaypointIsFinishline(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointIsShortcut(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushboolean(L, K_GetWaypointIsShortcut(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointIsEnabled(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushboolean(L, K_GetWaypointIsEnabled(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kSetWaypointIsEnabled(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
boolean enabled = luaL_checkboolean(L, 2);
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
K_SetWaypointIsEnabled(waypoint, enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointIsSpawnpoint(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushboolean(L, K_GetWaypointIsSpawnpoint(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointNextID(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushinteger(L, K_GetWaypointNextID(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointID(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushinteger(L, K_GetWaypointID(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetWaypointFromID(lua_State *L)
|
||||
{
|
||||
INT32 waypointId = luaL_checkinteger(L, 1);
|
||||
INLEVEL
|
||||
|
||||
LUA_PushUserdata(L, K_GetWaypointFromID(waypointId), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetCircuitLength(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
lua_pushinteger(L, K_GetCircuitLength());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetTrackComplexity(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
lua_pushinteger(L, K_GetTrackComplexity());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetClosestWaypointToMobj(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
LUA_PushUserdata(L, K_GetClosestWaypointToMobj(mobj), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetBestWaypointForMobj(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
waypoint_t *hint = NULL;
|
||||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
// Optional waypoint parameter:
|
||||
if (lua_isuserdata(L, 2) && lua_getmetatable(L, 2))
|
||||
{
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, META_WAYPOINT);
|
||||
int result = lua_rawequal(L, -1, -2);
|
||||
lua_pop(L, 2);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
}
|
||||
else
|
||||
hint = *((waypoint_t **)lua_touserdata(L, 2));
|
||||
}
|
||||
else if (!lua_isnoneornil(L, 2))
|
||||
{
|
||||
// If we reach this point and it isn't an userdata,
|
||||
// the scripter used a basic data type. Let them know
|
||||
// they messed up. (Just use nil or nothing, please.)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
}
|
||||
|
||||
LUA_PushUserdata(L, K_GetBestWaypointForMobj(mobj, hint), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
JugadorXEI @ 01/11/2025 (MM/DD/AAAA)
|
||||
This was my way to work around giving path_t and pathfindnode_t objects
|
||||
to Lua, as usually these are dynamically allocated. We give them a deep
|
||||
copy of the values and then we free this memory after the fact.
|
||||
Lua can manage its own copy itself.
|
||||
*/
|
||||
static void pushDeepCopyOfPathTypeAsTable(lua_State *L, path_t *const path)
|
||||
{
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
lua_pushinteger(L, path->numnodes);
|
||||
lua_setfield(L, -2, "numnodes");
|
||||
|
||||
lua_createtable(L, path->numnodes, 0);
|
||||
for (size_t i = 0; i < path->numnodes; i++)
|
||||
{
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
// It doesn't make sense for heap-related stuff to be exposed to Lua.
|
||||
// lua_pushinteger(L, path->array[i].heapindex);
|
||||
// lua_setfield(L, -2, "heapindex");
|
||||
|
||||
LUA_PushUserdata(L, (waypoint_t *)path->array[i].nodedata, META_WAYPOINT);
|
||||
lua_setfield(L, -2, "nodedata");
|
||||
|
||||
lua_pushinteger(L, path->array[i].gscore);
|
||||
lua_setfield(L, -2, "gscore");
|
||||
|
||||
lua_pushinteger(L, path->array[i].hscore);
|
||||
lua_setfield(L, -2, "hscore");
|
||||
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
lua_setfield(L, -2, "array");
|
||||
|
||||
lua_pushinteger(L, path->totaldist);
|
||||
lua_setfield(L, -2, "totaldist");
|
||||
}
|
||||
|
||||
static int lib_kPathfindToWaypoint(lua_State *L)
|
||||
{
|
||||
waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
waypoint_t *destinationwaypoint = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
|
||||
boolean useshortcuts = lua_optboolean(L, 3);
|
||||
boolean huntbackwards = lua_optboolean(L, 4);
|
||||
|
||||
INLEVEL
|
||||
if (!sourcewaypoint || !destinationwaypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
path_t returnpath = {0};
|
||||
boolean success = K_PathfindToWaypoint(sourcewaypoint, destinationwaypoint, &returnpath, useshortcuts, huntbackwards);
|
||||
|
||||
lua_pushboolean(L, success);
|
||||
if (success)
|
||||
{
|
||||
pushDeepCopyOfPathTypeAsTable(L, &returnpath);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
Z_Free(returnpath.array);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_kPathfindThruCircuit(lua_State *L)
|
||||
{
|
||||
waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
fixed_t traveldistance = luaL_checkfixed(L, 2);
|
||||
boolean useshortcuts = lua_optboolean(L, 3);
|
||||
boolean huntbackwards = lua_optboolean(L, 4);
|
||||
|
||||
INLEVEL
|
||||
if (!sourcewaypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
path_t returnpath = {0};
|
||||
boolean success = K_PathfindThruCircuit(sourcewaypoint, traveldistance, &returnpath, useshortcuts, huntbackwards);
|
||||
|
||||
lua_pushboolean(L, success);
|
||||
if (success)
|
||||
{
|
||||
pushDeepCopyOfPathTypeAsTable(L, &returnpath);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
Z_Free(returnpath.array);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_kPathfindThruCircuitSpawnable(lua_State *L)
|
||||
{
|
||||
waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
fixed_t traveldistance = luaL_checkfixed(L, 2);
|
||||
boolean useshortcuts = lua_optboolean(L, 3);
|
||||
boolean huntbackwards = lua_optboolean(L, 4);
|
||||
|
||||
INLEVEL
|
||||
if (!sourcewaypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
path_t returnpath = {0};
|
||||
boolean success = K_PathfindThruCircuitSpawnable(sourcewaypoint, traveldistance, &returnpath, useshortcuts, huntbackwards);
|
||||
|
||||
lua_pushboolean(L, success);
|
||||
if (success)
|
||||
{
|
||||
pushDeepCopyOfPathTypeAsTable(L, &returnpath);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
Z_Free(returnpath.array);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_kGetNextWaypointToDestination(lua_State *L)
|
||||
{
|
||||
waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
waypoint_t *destinationwaypoint = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
|
||||
boolean useshortcuts = lua_optboolean(L, 3);
|
||||
boolean huntbackwards = lua_optboolean(L, 4);
|
||||
|
||||
INLEVEL
|
||||
if (!sourcewaypoint || !destinationwaypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
LUA_PushUserdata(L, K_GetNextWaypointToDestination(sourcewaypoint, destinationwaypoint, useshortcuts, huntbackwards), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kSearchWaypointGraphForMobj(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
||||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
LUA_PushUserdata(L, K_SearchWaypointGraphForMobj(mobj), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kSearchWaypointHeapForMobj(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
||||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
LUA_PushUserdata(L, K_SearchWaypointHeapForMobj(mobj), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_getTimeMicros(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
|
||||
|
|
@ -6515,6 +6903,27 @@ static luaL_Reg lib[] = {
|
|||
// k_grandprix
|
||||
{"K_CanChangeRules", lib_kCanChangeRules},
|
||||
|
||||
// k_respawn
|
||||
{"K_RespawnOffset", lib_kRespawnOffset},
|
||||
{"K_RespawnAtWaypoint", lib_kRespawnAtWaypoint},
|
||||
{"K_DoFault", lib_kDoFault},
|
||||
{"K_DoIngameRespawn", lib_kDoIngameRespawn},
|
||||
{"K_NextRespawnWaypointIndex", lib_kNextRespawnWaypointIndex},
|
||||
|
||||
// k_waypoint
|
||||
{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
|
||||
{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
|
||||
{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
|
||||
{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
|
||||
{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
|
||||
{"K_SetWaypointIsEnabled", lib_kSetWaypointIsEnabled},
|
||||
{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
|
||||
{"K_GetWaypointNextID", lib_kGetWaypointNextID},
|
||||
{"K_GetWaypointID", lib_kGetWaypointID},
|
||||
{"K_GetWaypointFromID", lib_kGetWaypointFromID},
|
||||
{"K_GetCircuitLength", lib_kGetCircuitLength},
|
||||
{"K_GetTrackComplexity", lib_kGetTrackComplexity},
|
||||
|
||||
// k_bot
|
||||
{"K_PlayerUsesBotMovement", lib_kPlayerUsesBotMovement},
|
||||
{"K_BotCanTakeCut", lib_kBotCanTakeCut},
|
||||
|
|
@ -6527,6 +6936,14 @@ static luaL_Reg lib[] = {
|
|||
{"K_SetNameForBot", lib_kSetNameForBot},
|
||||
// Lua-only function to allow safely removing bots.
|
||||
{"K_RemoveBot", lib_kRemoveBot},
|
||||
{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
|
||||
{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
|
||||
{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
|
||||
{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
|
||||
{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
|
||||
{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
|
||||
{"K_SearchWaypointGraphForMobj", lib_kSearchWaypointGraphForMobj},
|
||||
{"K_SearchWaypointHeapForMobj", lib_kSearchWaypointHeapForMobj},
|
||||
|
||||
// hu_stuff technically?
|
||||
{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ extern lua_State *gL;
|
|||
#define META_FOLLOWER "FOLLOWER_T*"
|
||||
#define META_ITEMROULETTE "ITEMROULETTE_T"
|
||||
#define META_ITEMROULETTE_ITEMLIST "ITEMROULETTE_T.ITEMLIST"
|
||||
#define META_WAYPOINT "WAYPOINT_T*"
|
||||
|
||||
#define META_SONICLOOPVARS "SONICLOOPVARS_T*"
|
||||
#define META_SONICLOOPCAMVARS "SONICLOOPCAMVARS_T*"
|
||||
|
|
@ -139,6 +140,8 @@ int LUA_FollowerLib(lua_State *L);
|
|||
int LUA_ItemRouletteLib(lua_State *L);
|
||||
int LUA_BotVarsLib(lua_State *L);
|
||||
int LUA_TerrainLib(lua_State *L);
|
||||
int LUA_RespawnVarsLib(lua_State *L);
|
||||
int LUA_WaypointLib(lua_State *L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -101,6 +101,12 @@ enum mobj_e {
|
|||
mobj_sprxoff,
|
||||
mobj_spryoff,
|
||||
mobj_sprzoff,
|
||||
mobj_bakexoff,
|
||||
mobj_bakeyoff,
|
||||
mobj_bakezoff,
|
||||
mobj_bakexpiv,
|
||||
mobj_bakeypiv,
|
||||
mobj_bakezpiv,
|
||||
mobj_terrain,
|
||||
mobj_hitlag,
|
||||
mobj_waterskip,
|
||||
|
|
@ -192,6 +198,12 @@ static const char *const mobj_opt[] = {
|
|||
"sprxoff",
|
||||
"spryoff",
|
||||
"sprzoff",
|
||||
"bakexoff",
|
||||
"bakeyoff",
|
||||
"bakezoff",
|
||||
"bakexpiv",
|
||||
"bakeypiv",
|
||||
"bakezpiv",
|
||||
"terrain",
|
||||
"hitlag",
|
||||
"waterskip",
|
||||
|
|
@ -481,6 +493,24 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_sprzoff:
|
||||
lua_pushfixed(L, mo->sprzoff);
|
||||
break;
|
||||
case mobj_bakexoff:
|
||||
lua_pushfixed(L, mo->bakexoff);
|
||||
break;
|
||||
case mobj_bakeyoff:
|
||||
lua_pushfixed(L, mo->bakeyoff);
|
||||
break;
|
||||
case mobj_bakezoff:
|
||||
lua_pushfixed(L, mo->bakezoff);
|
||||
break;
|
||||
case mobj_bakexpiv:
|
||||
lua_pushfixed(L, mo->bakexpiv);
|
||||
break;
|
||||
case mobj_bakeypiv:
|
||||
lua_pushfixed(L, mo->bakeypiv);
|
||||
break;
|
||||
case mobj_bakezpiv:
|
||||
lua_pushfixed(L, mo->bakezpiv);
|
||||
break;
|
||||
case mobj_terrain:
|
||||
LUA_PushUserdata(L, mo->terrain, META_TERRAIN);
|
||||
break;
|
||||
|
|
@ -899,6 +929,24 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_sprzoff:
|
||||
mo->sprzoff = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakexoff:
|
||||
mo->bakexoff = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakeyoff:
|
||||
mo->bakeyoff = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakezoff:
|
||||
mo->bakezoff = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakexpiv:
|
||||
mo->bakexpiv = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakeypiv:
|
||||
mo->bakeypiv = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_bakezpiv:
|
||||
mo->bakezpiv = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case mobj_terrain:
|
||||
mo->terrain = *((terrain_t **)luaL_checkudata(L, 3, META_TERRAIN));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -225,10 +225,16 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->lastpickupdistance);
|
||||
else if (fastcmp(field,"lastpickuptype"))
|
||||
lua_pushinteger(L, plr->lastpickuptype);
|
||||
else if (fastcmp(field,"currentwaypoint"))
|
||||
LUA_PushUserdata(L, plr->currentwaypoint, META_WAYPOINT);
|
||||
else if (fastcmp(field,"nextwaypoint"))
|
||||
LUA_PushUserdata(L, plr->nextwaypoint, META_WAYPOINT);
|
||||
else if (fastcmp(field,"airtime"))
|
||||
lua_pushinteger(L, plr->airtime);
|
||||
else if (fastcmp(field,"lastairtime"))
|
||||
lua_pushinteger(L, plr->lastairtime);
|
||||
else if (fastcmp(field,"bigwaypointgap"))
|
||||
lua_pushinteger(L, plr->bigwaypointgap);
|
||||
else if (fastcmp(field,"flashing"))
|
||||
lua_pushinteger(L, plr->flashing);
|
||||
else if (fastcmp(field,"spinouttimer"))
|
||||
|
|
@ -311,6 +317,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->gateSound);
|
||||
else if (fastcmp(field,"startboost"))
|
||||
lua_pushinteger(L, plr->startboost);
|
||||
else if (fastcmp(field,"dropdashboost"))
|
||||
lua_pushinteger(L, plr->dropdashboost);
|
||||
else if (fastcmp(field,"aizdriftstrat"))
|
||||
lua_pushinteger(L, plr->aizdriftstrat);
|
||||
else if (fastcmp(field,"aizdriftextend"))
|
||||
|
|
@ -872,15 +880,17 @@ static int player_set(lua_State *L)
|
|||
else if (fastcmp(field,"teamimportance"))
|
||||
plr->teamimportance = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"distancetofinish"))
|
||||
return NOSET;
|
||||
plr->distancetofinish = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"distancetofinishprev"))
|
||||
return NOSET;
|
||||
plr->distancetofinishprev = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"lastpickupdistance"))
|
||||
plr->lastpickupdistance = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"airtime"))
|
||||
plr->airtime = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"lastairtime"))
|
||||
plr->lastairtime = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"bigwaypointgap"))
|
||||
plr->bigwaypointgap = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"flashing"))
|
||||
plr->flashing = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"spinouttimer"))
|
||||
|
|
@ -968,6 +978,8 @@ static int player_set(lua_State *L)
|
|||
plr->gateSound = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"startboost"))
|
||||
plr->startboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"dropdashboost"))
|
||||
plr->dropdashboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aizdriftstrat"))
|
||||
plr->aizdriftstrat = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"aizdrifttilt"))
|
||||
|
|
@ -1542,81 +1554,6 @@ static int ticcmd_set(lua_State *L)
|
|||
|
||||
#undef NOFIELD
|
||||
|
||||
// Same shit for player.respawn variable... Why is everything in different sub-variables again now???
|
||||
#define RNOFIELD luaL_error(L, LUA_QL("respawnvars_t") " has no field named " LUA_QS, field)
|
||||
#define RUNIMPLEMENTED luaL_error(L, LUA_QL("respawnvars_t") " unimplemented field " LUA_QS " cannot be read or set.", field)
|
||||
// @TODO: Waypoints in Lua possibly maybe? No don't count on me to do it...
|
||||
|
||||
static int respawn_get(lua_State *L)
|
||||
{
|
||||
respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
if (!rsp)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (fastcmp(field,"state"))
|
||||
lua_pushinteger(L, rsp->state);
|
||||
else if (fastcmp(field,"waypoint"))
|
||||
return RUNIMPLEMENTED;
|
||||
else if (fastcmp(field,"pointx"))
|
||||
lua_pushfixed(L, rsp->pointx);
|
||||
else if (fastcmp(field,"pointy"))
|
||||
lua_pushfixed(L, rsp->pointy);
|
||||
else if (fastcmp(field,"pointz"))
|
||||
lua_pushfixed(L, rsp->pointz);
|
||||
else if (fastcmp(field,"flip"))
|
||||
lua_pushboolean(L, rsp->flip);
|
||||
else if (fastcmp(field,"timer"))
|
||||
lua_pushinteger(L, rsp->timer);
|
||||
else if (fastcmp(field,"distanceleft"))
|
||||
lua_pushinteger(L, rsp->distanceleft); // Can't possibly foresee any problem when pushing UINT32 to Lua's INT32 hahahahaha, get ready for dumb hacky shit on high distances.
|
||||
else if (fastcmp(field,"dropdash"))
|
||||
lua_pushinteger(L, rsp->dropdash);
|
||||
else
|
||||
return RNOFIELD;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int respawn_set(lua_State *L)
|
||||
{
|
||||
respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
if (!rsp)
|
||||
return LUA_ErrInvalid(L, "respawnvars_t");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
||||
|
||||
if (fastcmp(field,"state"))
|
||||
rsp->state = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"waypoint"))
|
||||
return RUNIMPLEMENTED;
|
||||
else if (fastcmp(field,"pointx"))
|
||||
rsp->pointx = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"pointy"))
|
||||
rsp->pointy = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"pointz"))
|
||||
rsp->pointz = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"flip"))
|
||||
rsp->flip = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"timer"))
|
||||
rsp->timer = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"distanceleft"))
|
||||
rsp->distanceleft = (UINT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"dropdash"))
|
||||
rsp->dropdash = (tic_t)luaL_checkinteger(L, 3);
|
||||
else
|
||||
return RNOFIELD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef RNOFIELD
|
||||
#undef RUNIMPLEMENTED
|
||||
|
||||
enum sonicloopvars {
|
||||
sonicloopvars_radius = 0,
|
||||
sonicloopvars_revolution,
|
||||
|
|
@ -1798,14 +1735,6 @@ int LUA_PlayerLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L,1);
|
||||
|
||||
luaL_newmetatable(L, META_RESPAWN);
|
||||
lua_pushcfunction(L, respawn_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, respawn_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
luaL_newmetatable(L, META_TICCMD);
|
||||
lua_pushcfunction(L, ticcmd_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
|||
221
src/lua_respawnvarslib.c
Normal file
221
src/lua_respawnvarslib.c
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Kart Krew.
|
||||
// Copyright (C) 2020 by Sonic Team Junior.
|
||||
// Copyright (C) 2016 by John "JTE" Muniz.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_respawnvarslib.c
|
||||
/// \brief player respawn variables library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "fastcmp.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
|
||||
enum respawnvars {
|
||||
respawnvars_state = 0,
|
||||
respawnvars_waypoint,
|
||||
respawnvars_pointx,
|
||||
respawnvars_pointy,
|
||||
respawnvars_pointz,
|
||||
respawnvars_pointangle,
|
||||
respawnvars_flip,
|
||||
respawnvars_timer,
|
||||
respawnvars_airtimer,
|
||||
respawnvars_distanceleft,
|
||||
respawnvars_dropdash,
|
||||
respawnvars_truedeath,
|
||||
respawnvars_manual,
|
||||
respawnvars_fromringshooter,
|
||||
respawnvars_init,
|
||||
respawnvars_fast,
|
||||
respawnvars_returnspeed,
|
||||
};
|
||||
|
||||
static const char *const respawnvars_opt[] = {
|
||||
"state",
|
||||
"waypoint",
|
||||
"pointx",
|
||||
"pointy",
|
||||
"pointz",
|
||||
"pointangle",
|
||||
"flip",
|
||||
"timer",
|
||||
"airtimer",
|
||||
"distanceleft",
|
||||
"dropdash",
|
||||
"truedeath",
|
||||
"manual",
|
||||
"fromringshooter",
|
||||
"init",
|
||||
"fast",
|
||||
"returnspeed",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define RNOFIELD luaL_error(L, LUA_QL("respawnvars_t") " has no field named " LUA_QS, field)
|
||||
#define RUNIMPLEMENTED luaL_error(L, LUA_QL("respawnvars_t") " unimplemented field " LUA_QS " cannot be read or set.", field)
|
||||
|
||||
static int respawn_get(lua_State *L)
|
||||
{
|
||||
respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
|
||||
enum respawnvars field = luaL_checkoption(L, 2, NULL, respawnvars_opt);
|
||||
|
||||
if (!rsp)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case respawnvars_state:
|
||||
lua_pushinteger(L, rsp->state);
|
||||
break;
|
||||
case respawnvars_waypoint:
|
||||
LUA_PushUserdata(L, rsp->wp, META_WAYPOINT);
|
||||
break;
|
||||
case respawnvars_pointx:
|
||||
lua_pushfixed(L, rsp->pointx);
|
||||
break;
|
||||
case respawnvars_pointy:
|
||||
lua_pushfixed(L, rsp->pointy);
|
||||
break;
|
||||
case respawnvars_pointz:
|
||||
lua_pushfixed(L, rsp->pointz);
|
||||
break;
|
||||
case respawnvars_pointangle:
|
||||
lua_pushangle(L, rsp->pointangle);
|
||||
break;
|
||||
case respawnvars_flip:
|
||||
lua_pushboolean(L, rsp->flip);
|
||||
break;
|
||||
case respawnvars_timer:
|
||||
lua_pushinteger(L, rsp->timer);
|
||||
break;
|
||||
case respawnvars_airtimer:
|
||||
lua_pushinteger(L, rsp->airtimer);
|
||||
break;
|
||||
case respawnvars_distanceleft:
|
||||
lua_pushinteger(L, rsp->distanceleft);
|
||||
break;
|
||||
case respawnvars_dropdash:
|
||||
lua_pushinteger(L, rsp->dropdash);
|
||||
break;
|
||||
case respawnvars_truedeath:
|
||||
lua_pushboolean(L, rsp->truedeath);
|
||||
break;
|
||||
case respawnvars_manual:
|
||||
lua_pushboolean(L, rsp->manual);
|
||||
break;
|
||||
case respawnvars_fromringshooter:
|
||||
lua_pushboolean(L, rsp->fromRingShooter);
|
||||
break;
|
||||
case respawnvars_init:
|
||||
lua_pushboolean(L, rsp->init);
|
||||
break;
|
||||
case respawnvars_fast:
|
||||
lua_pushboolean(L, rsp->fast);
|
||||
break;
|
||||
case respawnvars_returnspeed:
|
||||
lua_pushfixed(L, rsp->returnspeed);
|
||||
break;
|
||||
default:
|
||||
return RNOFIELD;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int respawn_set(lua_State *L)
|
||||
{
|
||||
respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
|
||||
enum respawnvars field = luaL_checkoption(L, 2, respawnvars_opt[0], respawnvars_opt);
|
||||
|
||||
if (!rsp)
|
||||
return LUA_ErrInvalid(L, "respawnvars_t");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case respawnvars_state:
|
||||
rsp->state = (UINT8)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case respawnvars_waypoint:
|
||||
rsp->wp = *((waypoint_t **)luaL_checkudata(L, 3, META_WAYPOINT));
|
||||
break;
|
||||
case respawnvars_pointx:
|
||||
rsp->pointx = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case respawnvars_pointy:
|
||||
rsp->pointy = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case respawnvars_pointz:
|
||||
rsp->pointz = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case respawnvars_pointangle:
|
||||
rsp->pointangle = luaL_checkangle(L, 3);
|
||||
break;
|
||||
case respawnvars_flip:
|
||||
rsp->flip = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_timer:
|
||||
rsp->timer = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case respawnvars_airtimer:
|
||||
rsp->airtimer = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case respawnvars_distanceleft:
|
||||
rsp->distanceleft = (UINT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case respawnvars_dropdash:
|
||||
rsp->dropdash = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case respawnvars_truedeath:
|
||||
rsp->truedeath = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_manual:
|
||||
rsp->manual = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_fromringshooter:
|
||||
rsp->fromRingShooter = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_init:
|
||||
rsp->init = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_fast:
|
||||
rsp->fast = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case respawnvars_returnspeed:
|
||||
rsp->returnspeed = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
default:
|
||||
return RNOFIELD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef RNOFIELD
|
||||
#undef RUNIMPLEMENTED
|
||||
|
||||
int LUA_RespawnVarsLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_RESPAWN);
|
||||
lua_pushcfunction(L, respawn_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, respawn_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -64,6 +64,8 @@ static lua_CFunction liblist[] = {
|
|||
LUA_ItemRouletteLib, // itemroulette_t
|
||||
LUA_BotVarsLib, // botvars_t
|
||||
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
||||
LUA_RespawnVarsLib, // respawnvars_t
|
||||
LUA_WaypointLib, // waypoint_t
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -874,6 +876,10 @@ void LUA_InvalidateLevel(void)
|
|||
LUA_InvalidateUserdata(nodes[i].children);
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < K_GetNumWaypoints(); i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(K_GetWaypointFromIndex(i));
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_InvalidateMapthings(void)
|
||||
|
|
|
|||
293
src/lua_waypointslib.c
Normal file
293
src/lua_waypointslib.c
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Kart Krew.
|
||||
// Copyright (C) 2020 by Sonic Team Junior.
|
||||
// Copyright (C) 2016 by John "JTE" Muniz.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_waypointslib.c
|
||||
/// \brief wapoint structure library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "fastcmp.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
enum waypointvars {
|
||||
waypointvars_valid = 0,
|
||||
waypointvars_mobj,
|
||||
waypointvars_x,
|
||||
waypointvars_y,
|
||||
waypointvars_z,
|
||||
waypointvars_onaline,
|
||||
waypointvars_nextwaypoints,
|
||||
waypointvars_prevwaypoints,
|
||||
waypointvars_nextwaypointdistances,
|
||||
waypointvars_prevwaypointdistances,
|
||||
waypointvars_numnextwaypoints,
|
||||
waypointvars_numprevwaypoints,
|
||||
};
|
||||
|
||||
static const char *const waypointvars_opt[] = {
|
||||
"valid",
|
||||
"mobj",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"onaline",
|
||||
"nextwaypoints",
|
||||
"prevwaypoints",
|
||||
"nextwaypointdistances",
|
||||
"prevwaypointdistances",
|
||||
"numnextwaypoints",
|
||||
"numprevwaypoints",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define RNOFIELD luaL_error(L, LUA_QL("waypoint_t") " has no field named " LUA_QS, field)
|
||||
#define RNOSET luaL_error(L, LUA_QL("waypoint_t") " field " LUA_QS " cannot be set.", field)
|
||||
#define RNOGET luaL_error(L, LUA_QL("waypoint_t") " field " LUA_QS " cannot be get.", field)
|
||||
|
||||
static int waypoint_get(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
enum waypointvars field = luaL_checkoption(L, 2, NULL, waypointvars_opt);
|
||||
|
||||
if (!waypoint)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case waypointvars_valid:
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
default:
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
}
|
||||
}
|
||||
|
||||
// It could totally happen that some scripter just deletes the mobj,
|
||||
// which would have us check a null pointer, so we're checking against that
|
||||
// just in case.
|
||||
mobj_t *waypointMobj = NULL;
|
||||
if (waypoint->mobj != NULL && P_MobjWasRemoved(waypoint->mobj) == false)
|
||||
waypointMobj = waypoint->mobj;
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case waypointvars_valid:
|
||||
lua_pushboolean(L, true);
|
||||
break;
|
||||
case waypointvars_mobj:
|
||||
return RNOGET;
|
||||
case waypointvars_x:
|
||||
if (waypointMobj)
|
||||
lua_pushfixed(L, waypointMobj->x);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case waypointvars_y:
|
||||
if (waypointMobj)
|
||||
lua_pushinteger(L, waypointMobj->y);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case waypointvars_z:
|
||||
if (waypointMobj)
|
||||
lua_pushinteger(L, waypointMobj->z);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case waypointvars_onaline:
|
||||
lua_pushboolean(L, waypoint->onaline);
|
||||
break;
|
||||
case waypointvars_nextwaypoints:
|
||||
lua_createtable(L, waypoint->numnextwaypoints, 0);
|
||||
for (size_t i = 0; i < waypoint->numnextwaypoints; i++)
|
||||
{
|
||||
LUA_PushUserdata(L, waypoint->nextwaypoints[i], META_WAYPOINT);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
break;
|
||||
case waypointvars_prevwaypoints:
|
||||
lua_createtable(L, waypoint->numprevwaypoints, 0);
|
||||
for (size_t i = 0; i < waypoint->numprevwaypoints; i++)
|
||||
{
|
||||
LUA_PushUserdata(L, waypoint->prevwaypoints[i], META_WAYPOINT);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
break;
|
||||
case waypointvars_nextwaypointdistances:
|
||||
lua_createtable(L, waypoint->numnextwaypoints, 0);
|
||||
for (size_t i = 0; i < waypoint->numnextwaypoints; i++)
|
||||
{
|
||||
lua_pushinteger(L, waypoint->nextwaypointdistances[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
break;
|
||||
case waypointvars_prevwaypointdistances:
|
||||
lua_createtable(L, waypoint->numprevwaypoints, 0);
|
||||
for (size_t i = 0; i < waypoint->numprevwaypoints; i++)
|
||||
{
|
||||
lua_pushinteger(L, waypoint->prevwaypointdistances[i]);
|
||||
lua_rawseti(L, -2, 1 + i);
|
||||
}
|
||||
break;
|
||||
case waypointvars_numnextwaypoints:
|
||||
lua_pushinteger(L, waypoint->numnextwaypoints);
|
||||
break;
|
||||
case waypointvars_numprevwaypoints:
|
||||
lua_pushinteger(L, waypoint->numprevwaypoints);
|
||||
break;
|
||||
default:
|
||||
return RNOFIELD;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int waypoint_set(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
enum waypointvars field = luaL_checkoption(L, 2, waypointvars_opt[0], waypointvars_opt);
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
INLEVEL
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case waypointvars_mobj:
|
||||
return RNOSET;
|
||||
case waypointvars_x:
|
||||
return RNOSET;
|
||||
case waypointvars_y:
|
||||
return RNOSET;
|
||||
case waypointvars_z:
|
||||
return RNOSET;
|
||||
case waypointvars_onaline:
|
||||
return RNOSET;
|
||||
// A function should be used to set these instead.
|
||||
case waypointvars_nextwaypoints:
|
||||
return RNOSET;
|
||||
case waypointvars_prevwaypoints:
|
||||
return RNOSET;
|
||||
case waypointvars_nextwaypointdistances:
|
||||
return RNOSET;
|
||||
case waypointvars_prevwaypointdistances:
|
||||
return RNOSET;
|
||||
case waypointvars_numnextwaypoints:
|
||||
return RNOSET;
|
||||
case waypointvars_numprevwaypoints:
|
||||
return RNOSET;
|
||||
default:
|
||||
return RNOFIELD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef RNOSET
|
||||
#undef RNOFIELD
|
||||
|
||||
static int waypoint_num(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
lua_pushinteger(L, K_GetWaypointHeapIndex(waypoint));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateWaypoints(lua_State *L)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
lua_pushcfunction(L, lib_iterateWaypoints);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // state is unused.
|
||||
|
||||
if (!lua_isnil(L, 1))
|
||||
i = K_GetWaypointHeapIndex(*(waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT)) + 1;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
if (i < K_GetNumWaypoints())
|
||||
{
|
||||
LUA_PushUserdata(L, K_GetWaypointFromIndex(i), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getWaypoint(lua_State *L)
|
||||
{
|
||||
const char *field;
|
||||
size_t i;
|
||||
|
||||
// find waypoint by number
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
i = luaL_checkinteger(L, 2);
|
||||
if (i >= K_GetNumWaypoints())
|
||||
return luaL_error(L, "waypoints[] index %d out of range (0 - %d)", i, K_GetNumWaypoints()-1);
|
||||
LUA_PushUserdata(L, K_GetWaypointFromIndex(i), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
field = luaL_checkstring(L, 2);
|
||||
|
||||
// special function iterate
|
||||
if (fastcmp(field,"iterate"))
|
||||
{
|
||||
lua_pushcfunction(L, lib_iterateWaypoints);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_numWaypoints(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, K_GetNumWaypoints());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LUA_WaypointLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_WAYPOINT);
|
||||
lua_pushcfunction(L, waypoint_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, waypoint_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, waypoint_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L,1);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getWaypoint);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numWaypoints);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "waypoints");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -207,6 +207,13 @@ struct Mobj : mobj_t
|
|||
FIXED_METHOD(spryoff)
|
||||
FIXED_METHOD(sprzoff)
|
||||
|
||||
FIXED_METHOD(bakexoff)
|
||||
FIXED_METHOD(bakeyoff)
|
||||
FIXED_METHOD(bakezoff)
|
||||
FIXED_METHOD(bakexpiv)
|
||||
FIXED_METHOD(bakeypiv)
|
||||
FIXED_METHOD(bakezpiv)
|
||||
|
||||
vec2 spritescale() const { return {spritexscale(), spriteyscale()}; }
|
||||
void spritescale(const vec2& v)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ void P_RunOverlays(void);
|
|||
#define OV_DONT3DOFFSET 1<<1
|
||||
#define OV_DONTXYSCALE 1<<2
|
||||
#define OV_DONTROLL 1<<3
|
||||
#define OV_DONTBAKEOFFSET 1<<4
|
||||
|
||||
void P_HandleMinecartSegments(mobj_t *mobj);
|
||||
void P_MobjThinker(mobj_t *mobj);
|
||||
|
|
|
|||
12
src/p_mobj.c
12
src/p_mobj.c
|
|
@ -5581,6 +5581,18 @@ void P_RunOverlays(void)
|
|||
mo->roll = mo->target->roll;
|
||||
}
|
||||
|
||||
if (!(mo->threshold & OV_DONTBAKEOFFSET))
|
||||
{
|
||||
// offsets
|
||||
mo->bakexoff = mo->target->bakexoff;
|
||||
mo->bakeyoff = mo->target->bakeyoff;
|
||||
mo->bakezoff = mo->target->bakezoff;
|
||||
// pivots
|
||||
mo->bakexpiv = mo->target->bakexpiv;
|
||||
mo->bakeypiv = mo->target->bakeypiv;
|
||||
mo->bakezpiv = mo->target->bakezpiv;
|
||||
}
|
||||
|
||||
mo->hitlag = mo->target->hitlag;
|
||||
mo->eflags = (mo->eflags & ~MFE_DAMAGEHITLAG) | (mo->target->eflags & MFE_DAMAGEHITLAG);
|
||||
|
||||
|
|
|
|||
|
|
@ -422,6 +422,8 @@ struct mobj_t
|
|||
UINT8 shadowcolor; // Palette index to use for rendering the shadow
|
||||
|
||||
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
|
||||
fixed_t bakexoff, bakeyoff, bakezoff; // BAKED sprite offsets. Simulates visuals in real space, and rotates along the object's sprite
|
||||
fixed_t bakexpiv, bakeypiv, bakezpiv; // Pivot points for baked offsets. These are *not* rotated with a sprite
|
||||
|
||||
terrain_t *terrain; // Terrain definition of the floor this object last hit. NULL when in the air.
|
||||
mobj_t *terrainOverlay; // Overlay sprite object for terrain
|
||||
|
|
|
|||
|
|
@ -3063,6 +3063,7 @@ typedef enum
|
|||
MD3_REAPPEAR = 1<<1,
|
||||
MD3_PUNT_REF = 1<<2,
|
||||
MD3_OWNER = 1<<3,
|
||||
MD3_BAKEDOFFSET = 1<<4,
|
||||
} mobj_diff3_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -3386,6 +3387,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
|||
diff3 |= MD3_PUNT_REF;
|
||||
if (mobj->owner)
|
||||
diff3 |= MD3_OWNER;
|
||||
if (mobj->bakexoff || mobj->bakeyoff || mobj->bakezoff || mobj->bakexpiv ||
|
||||
mobj->bakeypiv || mobj->bakezpiv)
|
||||
diff3 |= MD3_BAKEDOFFSET;
|
||||
|
||||
if (diff3 != 0)
|
||||
diff2 |= MD2_MORE;
|
||||
|
|
@ -3676,6 +3680,15 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
|||
{
|
||||
WRITEUINT32(save->p, mobj->owner->mobjnum);
|
||||
}
|
||||
if (diff3 & MD3_BAKEDOFFSET)
|
||||
{
|
||||
WRITEFIXED(save->p, mobj->bakexoff);
|
||||
WRITEFIXED(save->p, mobj->bakeyoff);
|
||||
WRITEFIXED(save->p, mobj->bakezoff);
|
||||
WRITEFIXED(save->p, mobj->bakexpiv);
|
||||
WRITEFIXED(save->p, mobj->bakeypiv);
|
||||
WRITEFIXED(save->p, mobj->bakezpiv);
|
||||
}
|
||||
|
||||
WRITEUINT32(save->p, mobj->mobjnum);
|
||||
}
|
||||
|
|
@ -4989,6 +5002,20 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
|||
{
|
||||
mobj->owner = (mobj_t *)(size_t)READUINT32(save->p);
|
||||
}
|
||||
if (diff3 & MD3_BAKEDOFFSET)
|
||||
{
|
||||
mobj->bakexoff = READFIXED(save->p);
|
||||
mobj->bakeyoff = READFIXED(save->p);
|
||||
mobj->bakezoff = READFIXED(save->p);
|
||||
mobj->bakexpiv = READFIXED(save->p);
|
||||
mobj->bakeypiv = READFIXED(save->p);
|
||||
mobj->bakezpiv = READFIXED(save->p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->bakexoff = mobj->bakeyoff = mobj->bakezoff = 0;
|
||||
mobj->bakexpiv = mobj->bakeypiv = mobj->bakezpiv = 0;
|
||||
}
|
||||
|
||||
// link tid set earlier
|
||||
P_AddThingTID(mobj);
|
||||
|
|
|
|||
|
|
@ -1120,6 +1120,15 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost->sprxoff = mobj->sprxoff;
|
||||
ghost->spryoff = mobj->spryoff;
|
||||
ghost->sprzoff = mobj->sprzoff;
|
||||
|
||||
// baked offsets
|
||||
ghost->bakexoff = mobj->bakexoff;
|
||||
ghost->bakeyoff = mobj->bakeyoff;
|
||||
ghost->bakezoff = mobj->bakezoff;
|
||||
ghost->bakexpiv = mobj->bakexpiv;
|
||||
ghost->bakeypiv = mobj->bakeypiv;
|
||||
ghost->bakezpiv = mobj->bakezpiv;
|
||||
|
||||
ghost->rollangle = mobj->rollangle;
|
||||
|
||||
ghost->spritexscale = mobj->spritexscale;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ INT32 R_GetRollAngle(angle_t rollangle);
|
|||
angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer);
|
||||
angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer);
|
||||
angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer);
|
||||
vector2_t* R_RotateSpriteOffsetsByPitchRoll(
|
||||
mobj_t* mobj,
|
||||
boolean vflip,
|
||||
boolean hflip,
|
||||
vector2_t* out);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -105,6 +105,98 @@ INT32 R_GetRollAngle(angle_t rollangle)
|
|||
return ra;
|
||||
}
|
||||
|
||||
#define VISROTMUL (ANG1 * ROTANGDIFF)
|
||||
|
||||
vector2_t* R_RotateSpriteOffsetsByPitchRoll(
|
||||
mobj_t* mobj,
|
||||
boolean vflip,
|
||||
boolean hflip,
|
||||
vector2_t* out)
|
||||
{
|
||||
fixed_t rotcos, rotsin, finx, finy;
|
||||
vector2_t xvec, yvec;
|
||||
|
||||
// input offsets
|
||||
fixed_t xoffs, yoffs, xpiv, ypiv;
|
||||
|
||||
// final offsets
|
||||
INT16 visx, visy, visz;
|
||||
INT16 vxpiv, vypiv;
|
||||
|
||||
// visual rotation
|
||||
angle_t visrollang;
|
||||
|
||||
// camera angle
|
||||
angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y);
|
||||
|
||||
// rotate ourselves entirely by the sprite's own rotation angle
|
||||
angle_t visrot = R_SpriteRotationAngle(mobj, NULL);
|
||||
|
||||
// xoffs = (-cos(xoff) + sin(yoff))
|
||||
xoffs =
|
||||
FixedMul(mobj->bakeyoff, -FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(mobj->bakexoff, FINESINE(mobj->angle >> ANGLETOFINESHIFT));
|
||||
xpiv =
|
||||
FixedMul(mobj->bakeypiv, -FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(mobj->bakexpiv, FINESINE(mobj->angle >> ANGLETOFINESHIFT));
|
||||
|
||||
// yoffs = (-sin(yoff) + cos(xoff))
|
||||
yoffs =
|
||||
FixedMul(mobj->bakeyoff, -FINESINE(mobj->angle >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(mobj->bakexoff, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT));
|
||||
ypiv =
|
||||
FixedMul(mobj->bakeypiv, -FINESINE(mobj->angle >> ANGLETOFINESHIFT)) +
|
||||
FixedMul(mobj->bakexpiv, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT));
|
||||
|
||||
visrollang = (R_GetRollAngle(visrot) * VISROTMUL) * (hflip ? -1 : 1);
|
||||
|
||||
// get pitch and roll multipliers, mainly used to align the
|
||||
// viewpoint with the camera
|
||||
fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
|
||||
fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT);
|
||||
|
||||
// get visual positions
|
||||
visz = visy = visx = 0;
|
||||
visz = (INT16)(-(mobj->bakezoff / FRACUNIT));
|
||||
visx = (INT16)(FixedMul((yoffs / FRACUNIT), rollMul));
|
||||
visy = (INT16)(FixedMul((xoffs / FRACUNIT), pitchMul));
|
||||
|
||||
vxpiv = (INT16)(FixedMul((ypiv / FRACUNIT), rollMul));
|
||||
vypiv = (INT16)(FixedMul((xpiv / FRACUNIT), pitchMul));
|
||||
|
||||
// rotate by rollangle
|
||||
finx = (visx + visy);
|
||||
finy = -visz;
|
||||
|
||||
rotcos = FINECOSINE(visrollang >> ANGLETOFINESHIFT);
|
||||
rotsin = FINESINE(visrollang >> ANGLETOFINESHIFT);
|
||||
|
||||
xvec.x = FixedMul(finx, rotcos);
|
||||
xvec.y = FixedMul(finx, -rotsin);
|
||||
|
||||
yvec.x = FixedMul(finy, rotsin);
|
||||
yvec.y = FixedMul(finy, -rotcos);
|
||||
|
||||
// set finalized offsets
|
||||
out->x = (fixed_t)(xvec.x + yvec.x + vxpiv + vypiv);
|
||||
out->y = (fixed_t)(xvec.y - yvec.y) + (mobj->bakezpiv / FRACUNIT);
|
||||
|
||||
// flip based on vflip and hflip
|
||||
// flip the view angle if we're horizontally flipped
|
||||
if (hflip)
|
||||
{
|
||||
out->x *= -1;
|
||||
}
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
out->y *= -1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
#undef VISROTMUL
|
||||
|
||||
patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip)
|
||||
{
|
||||
rotsprite_t *rotsprite = patch->rotated;
|
||||
|
|
|
|||
|
|
@ -834,6 +834,12 @@ boolean R_ThingIsFlashing(mobj_t *thing)
|
|||
baddie_is_flashing(thing);
|
||||
}
|
||||
|
||||
boolean R_ThingIsUsingBakedOffsets(mobj_t* thing)
|
||||
{
|
||||
return ((thing->bakexoff) || (thing->bakeyoff) || (thing->bakezoff) ||
|
||||
(thing->bakexpiv) || (thing->bakeypiv) || (thing->bakezpiv));
|
||||
}
|
||||
|
||||
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
|
||||
{
|
||||
if (vis->cut & SC_PRECIP)
|
||||
|
|
@ -1777,6 +1783,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
patch_t *rotsprite = NULL;
|
||||
INT32 rollangle = 0;
|
||||
angle_t spriterotangle = 0;
|
||||
vector2_t visoffs;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
|
|
@ -1794,7 +1801,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
this_scale = interp.scale;
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * HITLAGJITTERS;
|
||||
|
|
@ -1987,10 +1994,31 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (spritexscale < 1 || spriteyscale < 1)
|
||||
return;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
// initialize and rotate pitch/roll vector
|
||||
visoffs.x = 0;
|
||||
visoffs.y = 0;
|
||||
|
||||
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
|
||||
|
||||
if (R_ThingIsUsingBakedOffsets(thing))
|
||||
{
|
||||
R_RotateSpriteOffsetsByPitchRoll(thing,
|
||||
vflip,
|
||||
hflip,
|
||||
&visoffs);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = interp.spritexoffset;
|
||||
#ifdef ROTSPRITE
|
||||
spr_topoffset = (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
|
||||
mapobjectscale));
|
||||
#else
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1999,8 +2027,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
|
||||
flipoffset = -1;
|
||||
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
spr_offset += (interp.spritexoffset) * flipoffset;
|
||||
#ifdef ROTSPRITE
|
||||
spr_topoffset += (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
|
||||
mapobjectscale))
|
||||
* flipoffset;
|
||||
#else
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (flip)
|
||||
|
|
@ -2008,6 +2042,13 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
offset = -spr_offset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (visoffs.x)
|
||||
{
|
||||
offset -= FixedDiv((visoffs.x * FRACUNIT), mapobjectscale);
|
||||
}
|
||||
#endif
|
||||
|
||||
offset = FixedMul(offset, FixedMul(spritexscale, this_scale));
|
||||
offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale));
|
||||
|
||||
|
|
@ -2172,10 +2213,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
R_InterpolateMobjState(thing, FRACUNIT, &tracer_interp);
|
||||
}
|
||||
|
||||
// hitlag vibrating (todo: interp somehow?)
|
||||
// hitlag vibrating
|
||||
if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG))
|
||||
{
|
||||
fixed_t mul = thing->hitlag * (FRACUNIT / 10);
|
||||
// previous code multiplied by (FRACUNIT / 10) instead of HITLAGJITTERS, um wadaflip
|
||||
fixed_t jitters = HITLAGJITTERS;
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
jitters += (rendertimefrac / HITLAGDIV);
|
||||
|
||||
fixed_t mul = thing->hitlag * jitters;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ boolean R_ThingModelUsesDirectionalLighting(mobj_t *thing);
|
|||
|
||||
boolean R_ThingIsFlashing(mobj_t *thing);
|
||||
|
||||
boolean R_ThingIsUsingBakedOffsets(mobj_t *thing);
|
||||
|
||||
INT32 R_ThingLightLevel(mobj_t *thing);
|
||||
boolean R_SplatSlope(mobj_t *thing, vector3_t position, pslope_t *slope);
|
||||
boolean R_CustomShadowZ(mobj_t *thing, fixed_t *return_z, pslope_t **return_slope);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue