Deterministic roulette

The roulette contains NO (non-seeded) RNG anymore. You manually stop it at any time.

Still needs the visual of the items scrolling, to make it not blind.
This commit is contained in:
Sally Coolatta 2022-12-11 23:58:11 -05:00
parent 32f747fd5a
commit a481e4b34b
20 changed files with 1199 additions and 1107 deletions

View file

@ -125,3 +125,4 @@ k_director.c
k_follower.c
k_profiles.c
k_specialstage.c
k_roulette.c

View file

@ -360,35 +360,36 @@ consvar_t cv_joyscale[MAXSPLITSCREENPLAYERS] = { //Alam: Dummy for save
#endif
// SRB2kart
consvar_t cv_sneaker = CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_rocketsneaker = CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_invincibility = CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_banana = CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_eggmanmonitor = CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_orbinaut = CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_jawz = CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_mine = CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_landmine = CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_ballhog = CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_selfpropelledbomb = CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_grow = CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_shrink = CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_lightningshield = CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_bubbleshield = CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_flameshield = CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_hyudoro = CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_pogospring = CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_superring = CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_kitchensink = CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_droptarget = CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_gardentop = CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualsneaker = CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplesneaker = CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_triplebanana = CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_tripleorbinaut = CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_quadorbinaut = CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_dualjawz = CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_items[NUMKARTRESULTS-1] = {
CVAR_INIT ("sneaker", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("rocketsneaker", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("invincibility", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("banana", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("eggmanmonitor", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("orbinaut", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("jawz", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("mine", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("landmine", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("ballhog", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("selfpropelledbomb", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("grow", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("shrink", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("lightningshield", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("bubbleshield", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("flameshield", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("hyudoro", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("pogospring", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("superring", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("kitchensink", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("droptarget", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("gardentop", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("dualsneaker", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("triplesneaker", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("triplebanana", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("tripleorbinaut", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("quadorbinaut", "On", CV_NETVAR, CV_OnOff, NULL),
CVAR_INIT ("dualjawz", "On", CV_NETVAR, CV_OnOff, NULL)
};
consvar_t cv_kartspeed = CVAR_INIT ("gamespeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange);
static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}};
@ -5659,7 +5660,7 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
K_StripItems(player);
// Cancel roulette if rolling
player->itemroulette = 0;
player->itemRoulette.active = false;
player->itemtype = item;
player->itemamount = amt;

View file

@ -16,6 +16,7 @@
#define __D_NETCMD__
#include "command.h"
#include "d_player.h"
// console vars
extern consvar_t cv_playername[MAXSPLITSCREENPLAYERS];
@ -72,37 +73,7 @@ extern consvar_t cv_pause;
extern consvar_t cv_restrictskinchange, cv_allowteamchange, cv_maxplayers, cv_respawntime;
// SRB2kart items
extern consvar_t
cv_sneaker,
cv_rocketsneaker,
cv_invincibility,
cv_banana,
cv_eggmanmonitor,
cv_orbinaut,
cv_jawz,
cv_mine,
cv_landmine,
cv_ballhog,
cv_selfpropelledbomb,
cv_grow,
cv_shrink,
cv_lightningshield,
cv_bubbleshield,
cv_flameshield,
cv_hyudoro,
cv_pogospring,
cv_superring,
cv_kitchensink,
cv_droptarget,
cv_gardentop;
extern consvar_t
cv_dualsneaker,
cv_triplesneaker,
cv_triplebanana,
cv_tripleorbinaut,
cv_quadorbinaut,
cv_dualjawz;
extern consvar_t cv_items[NUMKARTRESULTS-1];
extern consvar_t cv_kartspeed;
extern consvar_t cv_kartbumpers;

View file

@ -131,6 +131,7 @@ Do with it whatever you want.
Run this macro, then #undef FOREACH afterward
*/
#define KART_ITEM_ITERATOR \
FOREACH (EGGEXPLODE, -2),\
FOREACH (SAD, -1),\
FOREACH (NONE, 0),\
FOREACH (SNEAKER, 1),\
@ -329,6 +330,25 @@ struct skybox_t {
mobj_t * centerpoint;
};
// player_t struct for item roulette variables
struct itemroulette_t
{
boolean active;
size_t itemListCap;
size_t itemListLen;
SINT8 *itemList;
size_t index;
UINT8 sound;
tic_t speed;
tic_t tics;
tic_t elapsed;
boolean eggman;
};
// ========================================================================
// PLAYER STRUCTURE
// ========================================================================
@ -477,8 +497,7 @@ struct player_t
UINT8 tripwirePass; // see tripwirepass_t
UINT16 tripwireLeniency; // When reaching a state that lets you go thru tripwire, you get an extra second leniency after it ends to still go through it.
UINT16 itemroulette; // Used for the roulette when deciding what item to give you (was "pw_kartitem")
UINT8 roulettetype; // Used for the roulette, for deciding type (0 = normal, 1 = better, 2 = eggman mark)
itemroulette_t itemRoulette; // Item roulette data
// Item held stuff
SINT8 itemtype; // KITEM_ constant for item number

View file

@ -2260,11 +2260,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
SINT8 xtralife;
// SRB2kart
itemroulette_t itemRoulette;
respawnvars_t respawn;
INT32 itemtype;
INT32 itemamount;
INT32 itemroulette;
INT32 roulettetype;
INT32 growshrinktimer;
INT32 bumper;
boolean songcredit = false;
@ -2325,8 +2324,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
// SRB2kart
if (betweenmaps || leveltime < introtime)
{
itemroulette = 0;
roulettetype = 0;
itemtype = 0;
itemamount = 0;
growshrinktimer = 0;
@ -2348,9 +2345,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
}
else
{
itemroulette = (players[player].itemroulette > 0 ? 1 : 0);
roulettetype = players[player].roulettetype;
if (players[player].pflags & PF_ITEMOUT)
{
itemtype = 0;
@ -2406,6 +2400,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
P_SetTarget(&players[player].follower, NULL);
}
memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette));
memcpy(&respawn, &players[player].respawn, sizeof (respawn));
p = &players[player];
@ -2453,8 +2448,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->xtralife = xtralife;
// SRB2kart
p->itemroulette = itemroulette;
p->roulettetype = roulettetype;
p->itemtype = itemtype;
p->itemamount = itemamount;
p->growshrinktimer = growshrinktimer;
@ -2470,6 +2463,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->botvars.rubberband = FRACUNIT;
p->botvars.controller = UINT16_MAX;
memcpy(&p->itemRoulette, &itemRoulette, sizeof (p->itemRoulette));
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
if (follower)
@ -2481,7 +2475,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
//p->follower = NULL; // respawn a new one with you, it looks better.
// ^ Not necessary anyway since it will be respawned regardless considering it doesn't exist anymore.
p->playerstate = PST_LIVE;
p->panim = PA_STILL; // standing animation

View file

@ -26,6 +26,7 @@
#include "d_ticcmd.h"
#include "m_random.h"
#include "r_things.h" // numskins
#include "k_roulette.h"
/*--------------------------------------------------
static inline boolean K_ItemButtonWasDown(player_t *player)
@ -739,7 +740,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd)
tryLookback = true;
}
if (stealth > 1 || player->itemroulette > 0)
if (stealth > 1 || player->itemRoulette.active == true)
{
player->botvars.itemconfirm += player->botvars.difficulty * 4;
throwdir = -1;
@ -1400,7 +1401,7 @@ static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd)
return;
}
if (player->rings < 0 && cv_superring.value)
if (player->rings < 0 && K_ItemEnabled(KITEM_SUPERRING) == true)
{
// Uh oh, we need a loan!
// It'll be better in the long run for bots to lose an item set for 10 free rings.
@ -1441,7 +1442,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
return;
}
if (player->itemroulette)
if (player->itemRoulette.active == true)
{
// Mashing behaviors
K_BotItemRouletteMash(player, cmd);

View file

@ -12,6 +12,7 @@
#include "doomdef.h" // Sink snipe print
#include "g_game.h" // Sink snipe print
#include "k_objects.h"
#include "k_roulette.h"
angle_t K_GetCollideAngle(mobj_t *t1, mobj_t *t2)
{
@ -158,10 +159,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
}
else
{
K_DropItems(t2->player); //K_StripItems(t2->player);
//K_StripOther(t2->player);
t2->player->itemroulette = 1;
t2->player->roulettetype = 2;
K_StartEggmanRoulette(t2->player);
}
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)

View file

@ -36,6 +36,7 @@
#include "r_things.h"
#include "r_fps.h"
#include "m_random.h"
#include "k_roulette.h"
//{ Patch Definitions
static patch_t *kp_nodraw;
@ -1146,12 +1147,14 @@ static void K_drawKartItem(void)
UINT8 *colmap = NULL;
boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff
if (stplyr->itemroulette)
if (stplyr->itemRoulette.active == true)
{
const INT32 item = K_GetRollingRouletteItem(stplyr);
const SINT8 item = K_ItemResultToType(stplyr->itemRoulette.itemList[ stplyr->itemRoulette.index ]);
if (stplyr->skincolor)
{
localcolor = stplyr->skincolor;
}
switch (item)
{
@ -1165,6 +1168,7 @@ static void K_drawKartItem(void)
default:
localpatch = K_GetCachedItemPatch(item, offset);
break;
}
}
else
@ -1223,7 +1227,7 @@ static void K_drawKartItem(void)
if (stplyr->itemamount <= 0)
return;
switch(stplyr->itemtype)
switch (stplyr->itemtype)
{
case KITEM_INVINCIBILITY:
localpatch = localinv;
@ -1302,7 +1306,7 @@ static void K_drawKartItem(void)
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
// Then, the numbers:
if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette)
if (stplyr->itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false)
{
V_DrawScaledPatch(fx + (flipamount ? 48 : 0), fy, V_HUDTRANS|V_SLIDEIN|fflags|(flipamount ? V_FLIP : 0), kp_itemmulsticker[offset]); // flip this graphic for p2 and p4 in split and shift it.
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags, localpatch, colmap);
@ -4541,6 +4545,12 @@ K_drawMiniPing (void)
static void K_drawDistributionDebugger(void)
{
#if 1
// TODO: Create a roulette struct and initialize it,
// and use that to draw the data, instead of recalculating
// most of it.
return;
#else
patch_t *items[NUMKARTRESULTS] = {
kp_sadface[1],
kp_sneaker[1],
@ -4619,7 +4629,7 @@ static void K_drawDistributionDebugger(void)
pdis = (15 * pdis) / 14;
}
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper);
useodds = K_FindUseodds(stplyr, pdis);
for (i = 1; i < NUMKARTRESULTS; i++)
{
@ -4653,6 +4663,7 @@ static void K_drawDistributionDebugger(void)
}
V_DrawString(0, 0, V_SNAPTOTOP, va("USEODDS %d", useodds));
#endif
}
static void K_DrawWaypointDebugger(void)

File diff suppressed because it is too large Load diff

View file

@ -50,14 +50,6 @@ void K_ReduceVFX(mobj_t *mo, player_t *owner);
boolean K_IsPlayerLosing(player_t *player);
fixed_t K_GetKartGameSpeedScalar(SINT8 value);
extern consvar_t *KartItemCVars[NUMKARTRESULTS-1];
UINT8 K_FindUseodds(player_t *player, fixed_t mashed, UINT32 pdis, UINT8 bestbumper);
fixed_t K_ItemOddsScale(UINT8 numPlayers);
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers);
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, fixed_t mashed, boolean bot, boolean rival);
INT32 K_GetRollingRouletteItem(player_t *player);
boolean K_ForcedSPB(player_t *player);
INT32 K_GetShieldFromItem(INT32 item);
SINT8 K_ItemResultToType(SINT8 getitem);
UINT8 K_ItemResultToAmount(SINT8 getitem);

View file

@ -3455,7 +3455,7 @@ void M_DrawItemToggles(void)
continue;
}
cv = KartItemCVars[currentMenu->menuitems[thisitem].mvar1-1];
cv = &cv_items[currentMenu->menuitems[thisitem].mvar1-1];
translucent = (cv->value ? 0 : V_TRANSLUCENT);
drawnum = K_ItemResultToAmount(currentMenu->menuitems[thisitem].mvar1);
@ -3502,7 +3502,7 @@ void M_DrawItemToggles(void)
}
else
{
cv = KartItemCVars[currentMenu->menuitems[itemOn].mvar1-1];
cv = &cv_items[currentMenu->menuitems[itemOn].mvar1-1];
translucent = (cv->value ? 0 : V_TRANSLUCENT);
drawnum = K_ItemResultToAmount(currentMenu->menuitems[itemOn].mvar1);

View file

@ -5632,12 +5632,12 @@ void M_HandleItemToggles(INT32 choice)
else
if (currentMenu->menuitems[itemOn].mvar1 == 0)
{
INT32 v = cv_sneaker.value;
INT32 v = cv_items[0].value;
S_StartSound(NULL, sfx_s1b4);
for (i = 0; i < NUMKARTRESULTS-1; i++)
{
if (KartItemCVars[i]->value == v)
CV_AddValue(KartItemCVars[i], 1);
if (cv_items[i].value == v)
CV_AddValue(&cv_items[i], 1);
}
}
else
@ -5650,7 +5650,7 @@ void M_HandleItemToggles(INT32 choice)
{
S_StartSound(NULL, sfx_s1ba);
}
CV_AddValue(KartItemCVars[currentMenu->menuitems[itemOn].mvar1-1], 1);
CV_AddValue(&cv_items[currentMenu->menuitems[itemOn].mvar1-1], 1);
}
}

1001
src/k_roulette.c Normal file

File diff suppressed because it is too large Load diff

35
src/k_roulette.h Normal file
View file

@ -0,0 +1,35 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2022 by Kart Krew
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
//
// 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 k_roulette.h
/// \brief Item roulette code.
#ifndef __K_ROULETTE_H__
#define __K_ROULETTE_H__
#include "doomtype.h"
#include "d_player.h"
boolean K_ItemEnabled(SINT8 item);
fixed_t K_ItemOddsScale(UINT8 playerCount);
UINT32 K_ScaleItemDistance(UINT32 distance, UINT8 numPlayers);
UINT32 K_GetItemRouletteDistance(player_t *const player, UINT8 pingame);
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, UINT32 ourDist, boolean bot, boolean rival);
UINT8 K_FindUseodds(player_t *const player, UINT32 playerDist);
boolean K_ForcedSPB(player_t *const player);
void K_StartItemRoulette(player_t *const player, itemroulette_t *const roulette);
void K_StartEggmanRoulette(player_t *const player);
void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd);
#endif // __K_ROULETTE_H__

View file

@ -304,10 +304,10 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->tripwirePass);
else if (fastcmp(field,"tripwireLeniency"))
lua_pushinteger(L, plr->tripwireLeniency);
/*
else if (fastcmp(field,"itemroulette"))
lua_pushinteger(L, plr->itemroulette);
else if (fastcmp(field,"roulettetype"))
lua_pushinteger(L, plr->roulettetype);
*/
else if (fastcmp(field,"itemtype"))
lua_pushinteger(L, plr->itemtype);
else if (fastcmp(field,"itemamount"))
@ -680,10 +680,10 @@ static int player_set(lua_State *L)
plr->tripwirePass = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tripwireLeniency"))
plr->tripwireLeniency = luaL_checkinteger(L, 3);
/*
else if (fastcmp(field,"itemroulette"))
plr->itemroulette = luaL_checkinteger(L, 3);
else if (fastcmp(field,"roulettetype"))
plr->roulettetype = luaL_checkinteger(L, 3);
*/
else if (fastcmp(field,"itemtype"))
plr->itemtype = luaL_checkinteger(L, 3);
else if (fastcmp(field,"itemamount"))

View file

@ -34,6 +34,7 @@
#include "k_respawn.h"
#include "k_collide.h"
#include "k_objects.h"
#include "k_roulette.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
@ -13042,9 +13043,13 @@ void A_ItemPop(mobj_t *actor)
Obj_SpawnItemDebrisEffects(actor, actor->target);
if (locvar1 == 1)
{
P_GivePlayerSpheres(actor->target->player, actor->extravalue1);
}
else if (locvar1 == 0)
actor->target->player->itemroulette = 1;
{
K_StartItemRoulette(actor->target->player, &actor->target->player->itemRoulette);
}
// Here at mapload in battle?
if ((gametyperules & GTR_BUMPERS) && (actor->flags2 & MF2_BOSSNOTRAP))

View file

@ -38,6 +38,7 @@
#include "k_respawn.h"
#include "p_spec.h"
#include "k_objects.h"
#include "k_roulette.h"
// CTF player names
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
@ -130,7 +131,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
return false;
// Already have fake
if (player->roulettetype == 2
if (player->itemRoulette.eggman == true
|| player->eggmanexplode)
return false;
}
@ -143,7 +144,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
return false;
// Item slot already taken up
if (player->itemroulette
if (player->itemRoulette.active == true
|| (weapon != 3 && player->itemamount)
|| (player->pflags & PF_ITEMOUT))
return false;
@ -411,8 +412,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0))
return;
player->itemroulette = 1;
player->roulettetype = 1;
K_StartItemRoulette(player, &player->itemRoulette);
// Karma fireworks
for (i = 0; i < 5; i++)
@ -1449,8 +1449,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
}
player->karthud[khud_itemblink] = TICRATE;
player->karthud[khud_itemblinkmode] = 0;
player->itemroulette = 0;
player->roulettetype = 0;
player->itemRoulette.active = false;
if (P_IsDisplayPlayer(player))
S_StartSound(NULL, sfx_itrolf);
}

View file

@ -6124,7 +6124,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
break;
// see also K_drawKartItem in k_hud.c
case MT_PLAYERARROW:
case MT_PLAYERARROW: // FIXME: Delete this object, attach to name tags instead.
if (mobj->target && mobj->target->health
&& mobj->target->player && !mobj->target->player->spectator
&& mobj->target->health && mobj->target->player->playerstate != PST_DEAD
@ -6178,7 +6178,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
}
// Do this in an easy way
if (mobj->target->player->itemroulette)
if (mobj->target->player->itemRoulette.active)
{
mobj->tracer->color = mobj->target->player->skincolor;
mobj->tracer->colorized = true;
@ -6194,11 +6194,11 @@ static void P_MobjSceneryThink(mobj_t *mobj)
const INT32 numberdisplaymin = ((mobj->target->player->itemtype == KITEM_ORBINAUT) ? 5 : 2);
// Set it to use the correct states for its condition
if (mobj->target->player->itemroulette)
if (mobj->target->player->itemRoulette.active)
{
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
mobj->tracer->sprite = SPR_ITEM;
mobj->tracer->frame = K_GetRollingRouletteItem(mobj->target->player) | FF_FULLBRIGHT;
mobj->tracer->frame = 1 | FF_FULLBRIGHT;
mobj->tracer->renderflags &= ~RF_DONTDRAW;
}
else if (mobj->target->player->stealingtimer < 0)

View file

@ -310,9 +310,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].tripwirePass);
WRITEUINT16(save_p, players[i].tripwireLeniency);
WRITEUINT16(save_p, players[i].itemroulette);
WRITEUINT8(save_p, players[i].roulettetype);
WRITESINT8(save_p, players[i].itemtype);
WRITEUINT8(save_p, players[i].itemamount);
WRITESINT8(save_p, players[i].throwdir);
@ -410,6 +407,19 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].botvars.itemconfirm);
WRITESINT8(save_p, players[i].botvars.turnconfirm);
WRITEUINT32(save_p, players[i].botvars.spindashconfirm);
// itemroulette_t
WRITEUINT8(save_p, players[i].itemRoulette.active);
WRITEUINT32(save_p, players[i].itemRoulette.itemListCap);
WRITEUINT32(save_p, players[i].itemRoulette.itemListLen);
for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++)
{
WRITESINT8(save_p, players[i].itemRoulette.itemList[j]);
}
WRITEUINT32(save_p, players[i].itemRoulette.index);
WRITEUINT32(save_p, players[i].itemRoulette.speed);
WRITEUINT32(save_p, players[i].itemRoulette.tics);
WRITEUINT32(save_p, players[i].itemRoulette.elapsed);
}
}
@ -612,9 +622,6 @@ static void P_NetUnArchivePlayers(void)
players[i].tripwirePass = READUINT8(save_p);
players[i].tripwireLeniency = READUINT16(save_p);
players[i].itemroulette = READUINT16(save_p);
players[i].roulettetype = READUINT8(save_p);
players[i].itemtype = READSINT8(save_p);
players[i].itemamount = READUINT8(save_p);
players[i].throwdir = READSINT8(save_p);
@ -713,6 +720,39 @@ static void P_NetUnArchivePlayers(void)
players[i].botvars.turnconfirm = READSINT8(save_p);
players[i].botvars.spindashconfirm = READUINT32(save_p);
// itemroulette_t
players[i].itemRoulette.active = READUINT8(save_p);
players[i].itemRoulette.itemListCap = READUINT32(save_p);
players[i].itemRoulette.itemListLen = READUINT32(save_p);
if (players[i].itemRoulette.itemList == NULL)
{
players[i].itemRoulette.itemList = Z_Calloc(
sizeof(SINT8) * players[i].itemRoulette.itemListCap,
PU_LEVEL,
&players[i].itemRoulette.itemList
);
}
else
{
players[i].itemRoulette.itemList = Z_Realloc(
players[i].itemRoulette.itemList,
sizeof(SINT8) * players[i].itemRoulette.itemListCap,
PU_LEVEL,
&players[i].itemRoulette.itemList
);
}
for (j = 0; (unsigned)j < players[i].itemRoulette.itemListLen; j++)
{
players[i].itemRoulette.itemList[j] = READSINT8(save_p);
}
players[i].itemRoulette.index = READUINT32(save_p);
players[i].itemRoulette.speed = READUINT32(save_p);
players[i].itemRoulette.tics = READUINT32(save_p);
players[i].itemRoulette.elapsed = READUINT32(save_p);
//players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point
}
}

View file

@ -37,6 +37,7 @@ TYPEDEF (discordRequest_t);
TYPEDEF (respawnvars_t);
TYPEDEF (botvars_t);
TYPEDEF (skybox_t);
TYPEDEF (itemroulette_t);
TYPEDEF (player_t);
// d_clisrv.h