Merge public master

This commit is contained in:
Eidolon 2025-08-20 20:53:36 -05:00
commit 43b93daaad
7 changed files with 537 additions and 73 deletions

View file

@ -4574,6 +4574,22 @@ static void K_drawKartAccessibilityIcons(boolean gametypeinfoshown, INT32 fx)
mirror = true;
}
}
// Adjust for Lua disabling things underneath or to the left of the speedometer.
if (!LUA_HudEnabled(hud_rings))
{
if (r_splitscreen < 2)
{
fy += 14;
}
// For 4P race, only check if it's a race.
// For 4P battle/capsules, check if it's either prisons or battle, AND check if that element isn't disabled.
else if ((gametyperules & GTR_CIRCUIT) == GTR_CIRCUIT ||
((battleprisons || (gametyperules & GTR_BUMPERS) == GTR_BUMPERS) && !LUA_HudEnabled(hud_gametypeinfo)))
{
fx -= 44;
}
}
// Kickstart Accel
if (stplyr->pflags & PF_KICKSTARTACCEL)
@ -4700,6 +4716,12 @@ static void K_drawKartSpeedometer(boolean gametypeinfoshown)
{
fy += 9;
}
// Adjust for Lua disabling things underneath the speedometer.
if (!LUA_HudEnabled(hud_rings))
{
fy += 14;
}
using srb2::Draw;
Draw(LAPS_X+7, fy+1).flags(V_HUDTRANS|V_SLIDEIN|splitflags).align(Draw::Align::kCenter).width(42).small_sticker();
@ -8062,13 +8084,16 @@ void K_drawKartHUD(void)
K_drawKartAccessibilityIcons(gametypeinfoshown, 0);
}
if (gametyperules & GTR_SPHERES)
if (LUA_HudEnabled(hud_rings))
{
K_drawBlueSphereMeter(gametypeinfoshown);
}
else
{
K_drawRingCounter(gametypeinfoshown);
if (gametyperules & GTR_SPHERES)
{
K_drawBlueSphereMeter(gametypeinfoshown);
}
else
{
K_drawRingCounter(gametypeinfoshown);
}
}
// This sucks, but we need to draw rings before EXP because 4P amps

View file

@ -6707,7 +6707,7 @@ void K_SpawnSparkleTrail(mobj_t *mo)
if (leveltime & 2)
index = 1;
invtime = mo->player->invincibilitytimer/TICRATE+1;
invtime = mo->player ? mo->player->invincibilitytimer/TICRATE+1 : 11;
//CONS_Printf("%d\n", index);
@ -6737,7 +6737,7 @@ void K_SpawnSparkleTrail(mobj_t *mo)
P_SetMobjState(sparkle, K_SparkleTrailStartStates[invanimnum][index]);
if (mo->player->invincibilitytimer > itemtime+(2*TICRATE))
if (mo->player && mo->player->invincibilitytimer > itemtime+(2*TICRATE))
{
sparkle->color = mo->color;
sparkle->colorized = true;
@ -8634,7 +8634,7 @@ static void K_MoveHeldObjects(player_t *player)
mobj_t *curnext;
mobj_t *targ = player->mo;
if (P_IsObjectOnGround(player->mo) && player->speed > 0)
if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->bananadrag < 255)
player->bananadrag++;
while (cur && !P_MobjWasRemoved(cur))

View file

@ -232,10 +232,13 @@ static const struct {
{META_LUABANKS, "luabanks[]"},
{META_ACTIVATOR, "activator_t"},
{META_FOLLOWER, "follower_t"},
{META_ITEMROULETTE, "itemroulette_t"},
{META_ITEMROULETTE_ITEMLIST, "itemroulette_t.itemlist_t"},
{META_SONICLOOPVARS, "sonicloopvars_t"},
{META_SONICLOOPCAMVARS, "sonicloopcamvars_t"},
{NULL, NULL}
};
@ -3554,6 +3557,16 @@ static int lib_kIsPlayerLosing(lua_State *L)
return 1;
}
static int lib_kGetPlayerDontDrawFlag(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_GetPlayerDontDrawFlag(player));
return 1;
}
static int lib_kIsPlayerWanted(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -3577,6 +3590,18 @@ static int lib_kKartBouncing(lua_State *L)
return 0;
}
static int lib_kKartPainEnergyFling(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_KartPainEnergyFling(player);
return 0;
}
static int lib_kMatchGenericExtraFlags(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -3590,10 +3615,88 @@ static int lib_kMatchGenericExtraFlags(lua_State *L)
return 0;
}
static int lib_kSpawnDashDustRelease(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnDashDustRelease(player);
return 0;
}
static int lib_kSpawnDriftBoostClip(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnDriftBoostClip(player);
return 0;
}
static int lib_kSpawnDriftBoostClipSpark(lua_State *L)
{
mobj_t *clip = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!clip)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnDriftBoostClipSpark(clip);
return 0;
}
static int lib_kSpawnNormalSpeedLines(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnNormalSpeedLines(player);
return 0;
}
static int lib_kSpawnGardenTopSpeedLines(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnGardenTopSpeedLines(player);
return 0;
}
static int lib_kSpawnInvincibilitySpeedLines(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnInvincibilitySpeedLines(mo);
return 0;
}
static int lib_kSpawnBumpEffect(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnBumpEffect(mo);
return 0;
}
static int lib_kDoInstashield(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_DoInstashield(player);
@ -3689,10 +3792,21 @@ static int lib_kTakeBumpersFromPlayer(lua_State *L)
return 0;
}
static int lib_kMineFlashScreen(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
INLEVEL
NOHUD
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_MineFlashScreen(source);
return 0;
}
static int lib_kSpawnMineExplosion(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
UINT8 color = (UINT8)luaL_optinteger(L, 2, SKINCOLOR_KETCHUP);
skincolornum_t color = luaL_optinteger(L, 2, SKINCOLOR_KETCHUP);
tic_t delay = (tic_t)luaL_optinteger(L, 3, 0);
NOHUD
if (!source)
@ -3701,6 +3815,30 @@ static int lib_kSpawnMineExplosion(lua_State *L)
return 0;
}
static int lib_kSpawnLandMineExplosion(lua_State *L)
{
mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
skincolornum_t color = luaL_optinteger(L, 2, SKINCOLOR_KETCHUP);
tic_t delay = (tic_t)luaL_optinteger(L, 3, 0);
NOHUD
INLEVEL
if (!source)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnLandMineExplosion(source, color, delay);
return 0;
}
static int lib_kDriftSparkColor(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
INT32 charge = luaL_checkinteger(L, 2);
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_DriftSparkColor(player, charge));
return 1;
}
static int lib_kSpawnBoostTrail(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -3731,6 +3869,29 @@ static int lib_kSpawnWipeoutTrail(lua_State *L)
return 0;
}
static int lib_kSpawnDraftDust(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnDraftDust(mo);
return 0;
}
static int lib_kSpawnMagicianParticles(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
INT32 spread = luaL_optinteger(L, 2, 5);
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnMagicianParticles(mo, spread);
return 0;
}
static int lib_kDriftDustHandling(lua_State *L)
{
mobj_t *spawner = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -3741,6 +3902,17 @@ static int lib_kDriftDustHandling(lua_State *L)
return 0;
}
static int lib_kSquish(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
K_Squish(mo);
return 0;
}
static int lib_kDoSneaker(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -3813,6 +3985,39 @@ static int lib_kGetKartDriftSparkValue(lua_State *L)
return 1;
}
static int lib_kStairJankFlip(lua_State *L)
{
INT32 value = luaL_checkinteger(L, 1);
INLEVEL
lua_pushinteger(L, K_StairJankFlip(value));
return 1;
}
static int lib_kSpawnDriftBoostExplosion(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
UINT8 stage = luaL_checkinteger(L, 2);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnDriftBoostExplosion(player, stage);
return 0;
}
static int lib_kSpawnDriftElectricSparks(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
skincolornum_t color = luaL_checkinteger(L, 2);
boolean shockwave = lua_optboolean(L, 3);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_SpawnDriftElectricSparks(player, color, shockwave);
return 0;
}
static int lib_kKartUpdatePosition(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -3883,6 +4088,17 @@ static int lib_kMomentumToFacing(lua_State *L)
return 0;
}
static int lib_kSpawnWaterRunParticles(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
NOHUD
INLEVEL
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
K_SpawnWaterRunParticles(mobj);
return 0;
}
static int lib_kGetKartSpeed(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -3951,10 +4167,10 @@ static int lib_kItemResultToAmount(lua_State *L)
static int lib_kGetItemCooldown(lua_State *L)
{
kartitems_t item = luaL_checkinteger(L, 1);
NOHUD
INLEVEL
lua_pushinteger(L, K_GetItemCooldown(item));
return 1;
}
@ -3963,10 +4179,10 @@ static int lib_kSetItemCooldown(lua_State *L)
{
kartitems_t item = luaL_checkinteger(L, 1);
tic_t time = luaL_checkinteger(L, 2);
NOHUD
INLEVEL
K_SetItemCooldown(item, time);
return 0;
}
@ -3985,6 +4201,32 @@ static int lib_kCapsuleTimeAttackRules(lua_State *L)
return 1;
}
static int lib_kGetInvincibilityItemFrame(lua_State *L)
{
INLEVEL
lua_pushinteger(L, K_GetInvincibilityItemFrame());
return 1;
}
static int lib_kGetOrbinautItemFrame(lua_State *L)
{
UINT8 count = luaL_optinteger(L, 1, 1);
lua_pushinteger(L, K_GetOrbinautItemFrame(count));
return 1;
}
static int lib_kUpdateMobjItemOverlay(lua_State *L)
{
mobj_t *part = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
SINT8 itemType = luaL_optinteger(L, 2, 0);
UINT8 itemCount = luaL_optinteger(L, 3, 0);
NOHUD
INLEVEL
if (!part)
return LUA_ErrInvalid(L, "mobj_t");
K_UpdateMobjItemOverlay(part, itemType, itemCount);
return 0;
}
static int lib_kGetCollideAngle(lua_State *L)
{
@ -4154,13 +4396,13 @@ static int lib_kAddItemToReel(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
if (lua_isnumber(L, 2))
{
kartitems_t item = luaL_checkinteger(L, 2);
@ -4170,7 +4412,7 @@ static int lib_kAddItemToReel(lua_State *L)
{
luaL_checktype(L, 2, LUA_TTABLE);
size_t size = luaL_getn(L, 2);
for (size_t i = 1; i <= size; i++)
{
lua_rawgeti(L, 2, i);
@ -4183,7 +4425,7 @@ static int lib_kAddItemToReel(lua_State *L)
{
lua_pop(L, 1);
return luaL_error(L, "Non-integer value in table in index %d.", i);
}
}
lua_pop(L, 1);
}
}
@ -4195,13 +4437,13 @@ static int lib_kAddItemToReel(lua_State *L)
static int lib_kPushToRouletteItemList(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
itemroulette_t *itemRoulette = NULL;
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
if (lua_isnumber(L, 2))
{
kartitems_t item = luaL_checkinteger(L, 2);
@ -4211,7 +4453,7 @@ static int lib_kPushToRouletteItemList(lua_State *L)
{
luaL_checktype(L, 2, LUA_TTABLE);
size_t size = luaL_getn(L, 2);
for (size_t i = 1; i <= size; i++)
{
lua_rawgeti(L, 2, i);
@ -4224,12 +4466,12 @@ static int lib_kPushToRouletteItemList(lua_State *L)
{
lua_pop(L, 1);
return luaL_error(L, "Non-integer value in table in index %d.", i);
}
}
lua_pop(L, 1);
}
}
else return LUA_ErrInvalid(L, "integer/table");
return 0;
}
@ -4237,12 +4479,12 @@ static int lib_kStartItemRoulette(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean ringbox = lua_optboolean(L, 2);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_StartItemRoulette(player, ringbox);
return 0;
}
@ -4250,12 +4492,12 @@ static int lib_kStartItemRoulette(lua_State *L)
static int lib_kStartEggmanRoulette(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_StartEggmanRoulette(player);
return 0;
}
@ -4263,12 +4505,12 @@ static int lib_kStartEggmanRoulette(lua_State *L)
static int lib_kStopRoulette(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_StopRoulette(&player->itemRoulette);
return 0;
}
@ -4277,12 +4519,12 @@ static int lib_kKartGetItemResult(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
kartitems_t item = luaL_checkinteger(L, 2);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_KartGetItemResult(player, item);
return 0;
}
@ -4292,10 +4534,10 @@ static int lib_kGetItemRouletteDistance(lua_State *L)
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
UINT8 numPlayers = luaL_checkinteger(L, 2);
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushinteger(L, K_GetItemRouletteDistance(player, numPlayers));
return 1;
}
@ -4304,9 +4546,9 @@ static int lib_kFillItemRouletteData(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
boolean ringbox = lua_optboolean(L, 2);
NOHUD
INLEVEL
if (!player)
@ -4321,10 +4563,10 @@ static int lib_kForcedSPB(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, K_ForcedSPB(player, &player->itemRoulette));
return 1;
}
@ -4343,10 +4585,10 @@ static int lib_kGetRouletteOffset(lua_State *L)
fixed_t renderDelta = luaL_optnumber(L, 2, FRACUNIT);
UINT8 fudge = luaL_optnumber(L, 3, player ? player->cmd.latency : 0);
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushfixed(L, K_GetRouletteOffset(&player->itemRoulette, renderDelta, fudge));
return 1;
}
@ -4357,10 +4599,10 @@ static int lib_kGetSlotOffset(lua_State *L)
fixed_t renderDelta = luaL_optnumber(L, 2, FRACUNIT);
UINT8 fudge = luaL_optnumber(L, 3, player ? player->cmd.latency : 0);
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
lua_pushfixed(L, K_GetSlotOffset(&player->itemRoulette, renderDelta, fudge));
return 1;
}
@ -4368,12 +4610,12 @@ static int lib_kGetSlotOffset(lua_State *L)
static int lib_kCalculateRouletteSpeed(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
K_CalculateRouletteSpeed(&player->itemRoulette);
return 0;
}
@ -4403,7 +4645,7 @@ static int lib_kWipeItemsInReel(lua_State *L)
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
itemRoulette->itemList.len = 0;
return 0;
}
@ -4412,22 +4654,22 @@ static int lib_kSetItemInReelByIndex(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
size_t index = luaL_checkinteger(L, 2) - 1;
kartitems_t item = luaL_checkinteger(L, 3);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
if (itemRoulette->itemList.len == 0)
return luaL_error(L, "There are no items in the roulette to set.");
if (index > itemRoulette->itemList.len - 1)
return luaL_error(L, "Roulette index %d out of bounds (should be between %d and %d).", index + 1, 1, itemRoulette->itemList.len);
itemRoulette->itemList.items[index] = item;
return 0;
}
@ -4444,51 +4686,51 @@ static int lib_kAddItemToReelByIndex(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
size_t index = luaL_checkinteger(L, 2) - 1;
kartitems_t item = luaL_checkinteger(L, 3);
boolean addRings = lua_optboolean(L, 4);
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
// If the list is empty, just add the item silently and leave.
if (itemRoulette->itemList.len == 0) {
AddOrPushToItemReel(player, itemRoulette, item, addRings);
return 0;
}
if (index > itemRoulette->itemList.len - 1)
return luaL_error(L, "Roulette index %d out of bounds (should be between %d and %d).", index + 1, 1, itemRoulette->itemList.len);
size_t latterItemList = itemRoulette->itemList.len - index;
kartitems_t *latterItems = Z_Calloc(
sizeof(kartitems_t) * latterItemList,
PU_STATIC,
NULL
);
if (!latterItems)
I_Error("Out of memory during calloc for lib_kAddItemToReelByIndex.");
for (size_t i = 0; i < latterItemList; i++)
{
latterItems[i] = itemRoulette->itemList.items[index + i];
}
itemRoulette->itemList.len = index;
AddOrPushToItemReel(player, itemRoulette, item, addRings);
for (size_t i = 0; i < latterItemList; i++)
{
AddOrPushToItemReel(player, itemRoulette, latterItems[i], addRings);
}
Z_Free(latterItems);
return 0;
}
@ -4496,43 +4738,43 @@ static int lib_kRemoveItemFromReelByIndex(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
itemroulette_t *itemRoulette = NULL;
size_t index = luaL_checkinteger(L, 2) - 1;
NOHUD
INLEVEL
if (!player)
return LUA_ErrInvalid(L, "player_t");
itemRoulette = &player->itemRoulette;
if (itemRoulette->itemList.len == 0)
return luaL_error(L, "There are no items in the roulette to delete.");
if (index > itemRoulette->itemList.len - 1)
return luaL_error(L, "Roulette index %d out of bounds (should be between %d and %d).", index + 1, 1, itemRoulette->itemList.len);
size_t latterItemList = itemRoulette->itemList.len - index - 1;
kartitems_t *latterItems = Z_Calloc(
sizeof(kartitems_t) * latterItemList,
PU_STATIC,
NULL
);
if (!latterItems)
I_Error("Out of memory during calloc for lib_kRemoveItemFromReelByIndex.");
for (size_t i = 0; i < latterItemList; i++)
{
latterItems[i] = itemRoulette->itemList.items[index + 1 + i];
}
itemRoulette->itemList.len = index;
for (size_t i = 0; i < latterItemList; i++)
K_PushToRouletteItemList(itemRoulette, latterItems[i]);
Z_Free(latterItems);
return 0;
}
@ -4778,10 +5020,19 @@ static luaL_Reg lib[] = {
{"K_PlayPainSound", lib_kPainSound},
{"K_PlayHitEmSound", lib_kHitEmSound},
{"K_TryHurtSoundExchange", lib_kTryHurtSoundExchange},
{"K_GetPlayerDontDrawFlag", lib_kGetPlayerDontDrawFlag},
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
{"K_KartBouncing",lib_kKartBouncing},
{"K_KartPainEnergyFling",lib_kKartPainEnergyFling},
{"K_MatchGenericExtraFlags",lib_kMatchGenericExtraFlags},
{"K_SpawnDashDustRelease",lib_kSpawnDashDustRelease},
{"K_SpawnDriftBoostClip",lib_kSpawnDriftBoostClip},
{"K_SpawnDriftBoostClipSpark",lib_kSpawnDriftBoostClipSpark},
{"K_SpawnNormalSpeedLines",lib_kSpawnNormalSpeedLines},
{"K_SpawnGardenTopSpeedLines",lib_kSpawnGardenTopSpeedLines},
{"K_SpawnInvincibilitySpeedLines",lib_kSpawnInvincibilitySpeedLines},
{"K_SpawnBumpEffect",lib_kSpawnBumpEffect},
{"K_DoInstashield",lib_kDoInstashield},
{"K_SpawnBattlePoints",lib_kSpawnBattlePoints},
{"K_SpinPlayer",lib_kSpinPlayer},
@ -4789,17 +5040,26 @@ static luaL_Reg lib[] = {
{"K_StumblePlayer",lib_kStumblePlayer},
{"K_ExplodePlayer",lib_kExplodePlayer},
{"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer},
{"K_MineFlashScreen",lib_kMineFlashScreen},
{"K_SpawnMineExplosion",lib_kSpawnMineExplosion},
{"K_SpawnLandMineExplosion",lib_kSpawnLandMineExplosion},
{"K_DriftSparkColor",lib_kDriftSparkColor},
{"K_SpawnBoostTrail",lib_kSpawnBoostTrail},
{"K_SpawnSparkleTrail",lib_kSpawnSparkleTrail},
{"K_SpawnWipeoutTrail",lib_kSpawnWipeoutTrail},
{"K_SpawnDraftDust",lib_kSpawnDraftDust},
{"K_SpawnMagicianParticles",lib_kSpawnMagicianParticles},
{"K_DriftDustHandling",lib_kDriftDustHandling},
{"K_Squish",lib_kSquish},
{"K_DoSneaker",lib_kDoSneaker},
{"K_DoPogoSpring",lib_kDoPogoSpring},
{"K_KillBananaChain",lib_kKillBananaChain},
{"K_RepairOrbitChain",lib_kRepairOrbitChain},
{"K_FindJawzTarget",lib_kFindJawzTarget},
{"K_GetKartDriftSparkValue",lib_kGetKartDriftSparkValue},
{"K_StairJankFlip",lib_kStairJankFlip},
{"K_SpawnDriftBoostExplosion",lib_kSpawnDriftBoostExplosion},
{"K_SpawnDriftElectricSparks",lib_kSpawnDriftElectricSparks},
{"K_KartUpdatePosition",lib_kKartUpdatePosition},
{"K_PopPlayerShield",lib_kPopPlayerShield},
{"K_DropHnextList",lib_kDropHnextList},
@ -4807,10 +5067,14 @@ static luaL_Reg lib[] = {
{"K_StripItems",lib_kStripItems},
{"K_StripOther",lib_kStripOther},
{"K_MomentumToFacing",lib_kMomentumToFacing},
{"K_SpawnWaterRunParticles",lib_kSpawnWaterRunParticles},
{"K_GetKartSpeed",lib_kGetKartSpeed},
{"K_GetKartAccel",lib_kGetKartAccel},
{"K_GetKartFlashing",lib_kGetKartFlashing},
{"K_GetItemPatch",lib_kGetItemPatch},
{"K_GetInvincibilityItemFrame",lib_kGetInvincibilityItemFrame},
{"K_GetOrbinautItemFrame",lib_kGetOrbinautItemFrame},
{"K_UpdateMobjItemOverlay",lib_kUpdateMobjItemOverlay},
{"K_GetCollideAngle",lib_kGetCollideAngle},
{"K_AddHitLag",lib_kAddHitLag},
{"K_GetShieldFromItem",lib_kGetShieldFromItem},
@ -4834,7 +5098,7 @@ static luaL_Reg lib[] = {
{"VS_GetArena", lib_vsGetArena},
{"VS_PredictAroundArena", lib_vsPredictAroundArena},
{"VS_RandomPointOnArena", lib_vsRandomPointOnArena},
// k_roulette
{"K_ItemEnabled", lib_kItemEnabled},
{"K_ItemSingularity", lib_kItemSingularity},
@ -4853,7 +5117,7 @@ static luaL_Reg lib[] = {
{"K_GetSlotOffset", lib_kGetSlotOffset},
{"K_CalculateRouletteSpeed", lib_kCalculateRouletteSpeed},
{"K_ScaleItemDistance", lib_kScaleItemDistance},
{"K_ItemOddsScale", lib_kItemOddsScale},
{"K_ItemOddsScale", lib_kItemOddsScale},
// These are not real functions in k_roulette, but they allow
// encapsulation on how the scripter interacts with the item reel.
{"K_WipeItemsInReel", lib_kWipeItemsInReel},

View file

@ -39,6 +39,7 @@ enum hud {
hud_speedometer,
hud_freeplay,
hud_rankings, // Tab rankings
hud_rings, // Rings and Spheres HUD element
// Intermission
hud_intermissiontally,

View file

@ -59,6 +59,7 @@ static const char *const hud_disable_options[] = {
"speedometer",
"freeplay",
"rankings",
"rings",
"intermissiontally",
"intermissionmessages",

View file

@ -106,6 +106,9 @@ extern lua_State *gL;
#define META_ITEMROULETTE "ITEMROULETTE_T"
#define META_ITEMROULETTE_ITEMLIST "ITEMROULETTE_T.ITEMLIST"
#define META_SONICLOOPVARS "SONICLOOPVARS_T*"
#define META_SONICLOOPCAMVARS "SONICLOOPCAMVARS_T*"
boolean luaL_checkboolean(lua_State *L, int narg);
int LUA_EnumLib(lua_State *L);

View file

@ -757,6 +757,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, playerpingtable[( plr - players )]);
else if (fastcmp(field, "publickey"))
lua_pushstring(L, GetPrettyRRID(plr->public_key, false));
else if (fastcmp(field, "loop"))
LUA_PushUserdata(L, &plr->loop, META_SONICLOOPVARS);
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
@ -1396,6 +1398,8 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"fovadd"))
plr->fovadd = luaL_checkfixed(L, 3);
#endif
else if (fastcmp(field, "loop"))
return NOSET;
else {
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(L, -1));
@ -1601,6 +1605,162 @@ static int respawn_set(lua_State *L)
#undef RNOFIELD
#undef RUNIMPLEMENTED
enum sonicloopvars {
sonicloopvars_radius = 0,
sonicloopvars_revolution,
sonicloopvars_min_revolution,
sonicloopvars_max_revolution,
sonicloopvars_yaw,
sonicloopvars_origin_x,
sonicloopvars_origin_y,
sonicloopvars_origin_z,
sonicloopvars_origin_shift_x,
sonicloopvars_origin_shift_y,
sonicloopvars_shift_x,
sonicloopvars_shift_y,
sonicloopvars_flip,
sonicloopvars_camera,
};
static const char *const sonicloopvars_opt[] = {
"radius",
"revolution",
"min_revolution",
"max_revolution",
"yaw",
"origin_x",
"origin_y",
"origin_z",
"origin_shift_x",
"origin_shift_y",
"shift_x",
"shift_y",
"flip",
"camera",
NULL
};
static int sonicloopvars_get(lua_State *L)
{
sonicloopvars_t *sonicloopvars = *((sonicloopvars_t **)luaL_checkudata(L, 1, META_SONICLOOPVARS));
enum sonicloopvars field = luaL_checkoption(L, 2, NULL, sonicloopvars_opt);
// This should always be valid.
I_Assert(sonicloopvars != NULL);
switch (field)
{
case sonicloopvars_radius:
lua_pushfixed(L, sonicloopvars->radius);
break;
case sonicloopvars_revolution:
lua_pushfixed(L, sonicloopvars->revolution);
break;
case sonicloopvars_min_revolution:
lua_pushfixed(L, sonicloopvars->min_revolution);
break;
case sonicloopvars_max_revolution:
lua_pushfixed(L, sonicloopvars->max_revolution);
break;
case sonicloopvars_yaw:
lua_pushangle(L, sonicloopvars->yaw);
break;
case sonicloopvars_origin_x:
lua_pushfixed(L, sonicloopvars->origin.x);
break;
case sonicloopvars_origin_y:
lua_pushfixed(L, sonicloopvars->origin.y);
break;
case sonicloopvars_origin_z:
lua_pushfixed(L, sonicloopvars->origin.z);
break;
case sonicloopvars_origin_shift_x:
lua_pushfixed(L, sonicloopvars->origin_shift.x);
break;
case sonicloopvars_origin_shift_y:
lua_pushfixed(L, sonicloopvars->origin_shift.y);
break;
case sonicloopvars_shift_x:
lua_pushfixed(L, sonicloopvars->shift.x);
break;
case sonicloopvars_shift_y:
lua_pushfixed(L, sonicloopvars->shift.y);
break;
case sonicloopvars_flip:
lua_pushboolean(L, sonicloopvars->flip);
break;
case sonicloopvars_camera:
LUA_PushUserdata(L, &sonicloopvars->camera, META_SONICLOOPCAMVARS);
break;
}
return 1;
}
enum sonicloopcamvars {
sonicloopcamvars_enter_tic = 0,
sonicloopcamvars_exit_tic,
sonicloopcamvars_zoom_in_speed,
sonicloopcamvars_zoom_out_speed,
sonicloopcamvars_dist,
sonicloopcamvars_pan,
sonicloopcamvars_pan_speed,
sonicloopcamvars_pan_accel,
sonicloopcamvars_pan_back,
};
static const char *const sonicloopcamvars_opt[] = {
"enter_tic",
"exit_tic",
"zoom_in_speed",
"zoom_out_speed",
"dist",
"pan",
"pan_speed",
"pan_accel",
"pan_back",
NULL
};
static int sonicloopcamvars_get(lua_State *L)
{
sonicloopcamvars_t *sonicloopcamvars = *((sonicloopcamvars_t **)luaL_checkudata(L, 1, META_SONICLOOPCAMVARS));
enum sonicloopcamvars field = luaL_checkoption(L, 2, NULL, sonicloopcamvars_opt);
// This should always be valid.
I_Assert(sonicloopcamvars != NULL);
switch (field)
{
case sonicloopcamvars_enter_tic:
lua_pushinteger(L, sonicloopcamvars->enter_tic);
break;
case sonicloopcamvars_exit_tic:
lua_pushinteger(L, sonicloopcamvars->exit_tic);
break;
case sonicloopcamvars_zoom_in_speed:
lua_pushinteger(L, sonicloopcamvars->zoom_in_speed);
break;
case sonicloopcamvars_zoom_out_speed:
lua_pushinteger(L, sonicloopcamvars->zoom_out_speed);
break;
case sonicloopcamvars_dist:
lua_pushfixed(L, sonicloopcamvars->dist);
break;
case sonicloopcamvars_pan:
lua_pushangle(L, sonicloopcamvars->pan);
break;
case sonicloopcamvars_pan_speed:
lua_pushfixed(L, sonicloopcamvars->pan_speed);
break;
case sonicloopcamvars_pan_accel:
lua_pushinteger(L, sonicloopcamvars->pan_accel);
break;
case sonicloopcamvars_pan_back:
lua_pushinteger(L, sonicloopcamvars->pan_back);
break;
}
return 1;
}
int LUA_PlayerLib(lua_State *L)
{
@ -1641,6 +1801,16 @@ int LUA_PlayerLib(lua_State *L)
lua_pushcfunction(L, ticcmd_set);
lua_setfield(L, -2, "__newindex");
lua_pop(L,1);
luaL_newmetatable(L, META_SONICLOOPVARS);
lua_pushcfunction(L, sonicloopvars_get);
lua_setfield(L, -2, "__index");
lua_pop(L,1);
luaL_newmetatable(L, META_SONICLOOPCAMVARS);
lua_pushcfunction(L, sonicloopcamvars_get);
lua_setfield(L, -2, "__index");
lua_pop(L,1);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);