mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-05 01:38:13 +00:00
Merge branch 'deterministic-roulette' into 'master'
Deterministic roulette See merge request KartKrew/Kart!808
This commit is contained in:
commit
03b37e2871
20 changed files with 1935 additions and 1256 deletions
|
|
@ -125,3 +125,4 @@ k_director.c
|
|||
k_follower.c
|
||||
k_profiles.c
|
||||
k_specialstage.c
|
||||
k_roulette.c
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ typedef enum
|
|||
// Item box
|
||||
khud_itemblink, // Item flashing after roulette, serves as a mashing indicator
|
||||
khud_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items)
|
||||
khud_rouletteoffset,// Roulette stop height
|
||||
|
||||
// Rings
|
||||
khud_ringframe, // Ring spin frame
|
||||
|
|
@ -329,6 +330,41 @@ struct skybox_t {
|
|||
mobj_t * centerpoint;
|
||||
};
|
||||
|
||||
// player_t struct for item roulette variables
|
||||
|
||||
// Doing this the right way is causing problems.
|
||||
// so FINE, it's a static length now.
|
||||
#define ITEM_LIST_SIZE (NUMKARTRESULTS << 3)
|
||||
|
||||
struct itemroulette_t
|
||||
{
|
||||
boolean active;
|
||||
|
||||
#ifdef ITEM_LIST_SIZE
|
||||
size_t itemListLen;
|
||||
SINT8 itemList[ITEM_LIST_SIZE];
|
||||
#else
|
||||
size_t itemListCap;
|
||||
size_t itemListLen;
|
||||
SINT8 *itemList;
|
||||
#endif
|
||||
|
||||
UINT8 useOdds;
|
||||
UINT8 playing, exiting;
|
||||
UINT32 dist, baseDist;
|
||||
UINT32 firstDist, secondDist;
|
||||
UINT32 secondToFirst;
|
||||
|
||||
size_t index;
|
||||
UINT8 sound;
|
||||
|
||||
tic_t speed;
|
||||
tic_t tics;
|
||||
tic_t elapsed;
|
||||
|
||||
boolean eggman;
|
||||
};
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
|
|
@ -477,8 +513,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
|
||||
|
|
|
|||
19
src/g_game.c
19
src/g_game.c
|
|
@ -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;
|
||||
|
|
@ -2323,10 +2322,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE));
|
||||
|
||||
// SRB2kart
|
||||
memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette));
|
||||
memcpy(&respawn, &players[player].respawn, sizeof (respawn));
|
||||
|
||||
if (betweenmaps || leveltime < introtime)
|
||||
{
|
||||
itemroulette = 0;
|
||||
roulettetype = 0;
|
||||
itemRoulette.active = false;
|
||||
|
||||
itemtype = 0;
|
||||
itemamount = 0;
|
||||
growshrinktimer = 0;
|
||||
|
|
@ -2348,9 +2350,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,8 +2405,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
P_SetTarget(&players[player].follower, NULL);
|
||||
}
|
||||
|
||||
memcpy(&respawn, &players[player].respawn, sizeof (respawn));
|
||||
|
||||
p = &players[player];
|
||||
memset(p, 0, sizeof (*p));
|
||||
|
||||
|
|
@ -2453,8 +2450,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 +2465,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 +2477,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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1393,27 +1394,15 @@ static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
|||
--------------------------------------------------*/
|
||||
static void K_BotItemRouletteMash(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
boolean mash = false;
|
||||
|
||||
if (K_ItemButtonWasDown(player) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->rings < 0 && cv_superring.value)
|
||||
{
|
||||
// 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.
|
||||
mash = true;
|
||||
}
|
||||
// TODO: Would be nice to implement smarter behavior
|
||||
// for selecting items.
|
||||
|
||||
// TODO: Mash based on how far behind you are, when items are
|
||||
// almost garantueed to be in your favor.
|
||||
|
||||
if (mash == true)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
}
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -1441,7 +1430,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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
321
src/k_hud.c
321
src/k_hud.c
|
|
@ -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;
|
||||
|
|
@ -1022,63 +1023,83 @@ static void K_drawKartItem(void)
|
|||
// Why write V_DrawScaledPatch calls over and over when they're all the same?
|
||||
// Set to 'no item' just in case.
|
||||
const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0);
|
||||
patch_t *localpatch = kp_nodraw;
|
||||
patch_t *localpatch[3] = { kp_nodraw };
|
||||
patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]);
|
||||
patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]);
|
||||
INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags...
|
||||
const INT32 numberdisplaymin = ((!offset && stplyr->itemtype == KITEM_ORBINAUT) ? 5 : 2);
|
||||
INT32 itembar = 0;
|
||||
INT32 maxl = 0; // itembar's normal highest value
|
||||
const INT32 barlength = (r_splitscreen > 1 ? 12 : 26);
|
||||
UINT16 localcolor = SKINCOLOR_NONE;
|
||||
SINT8 colormode = TC_RAINBOW;
|
||||
UINT8 *colmap = NULL;
|
||||
const INT32 barlength = (offset ? 12 : 26);
|
||||
UINT16 localcolor[3] = { stplyr->skincolor };
|
||||
SINT8 colormode[3] = { TC_RAINBOW };
|
||||
boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff
|
||||
|
||||
if (stplyr->itemroulette)
|
||||
fixed_t rouletteOffset = 0;
|
||||
fixed_t rouletteSpace = ROULETTE_SPACING;
|
||||
vector2_t rouletteCrop = {7, 7};
|
||||
INT32 i;
|
||||
|
||||
if (stplyr->itemRoulette.itemListLen > 0)
|
||||
{
|
||||
const INT32 item = K_GetRollingRouletteItem(stplyr);
|
||||
|
||||
if (stplyr->skincolor)
|
||||
localcolor = stplyr->skincolor;
|
||||
|
||||
switch (item)
|
||||
// Init with item roulette stuff.
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
case KITEM_INVINCIBILITY:
|
||||
localpatch = localinv;
|
||||
break;
|
||||
const SINT8 indexOfs = i-1;
|
||||
const size_t index = (stplyr->itemRoulette.index + indexOfs) % stplyr->itemRoulette.itemListLen;
|
||||
|
||||
case KITEM_ORBINAUT:
|
||||
localpatch = kp_orbinaut[3 + offset];
|
||||
break;
|
||||
const SINT8 result = stplyr->itemRoulette.itemList[index];
|
||||
const SINT8 item = K_ItemResultToType(result);
|
||||
const UINT8 amt = K_ItemResultToAmount(result);
|
||||
|
||||
default:
|
||||
localpatch = K_GetCachedItemPatch(item, offset);
|
||||
switch (item)
|
||||
{
|
||||
case KITEM_INVINCIBILITY:
|
||||
localpatch[i] = localinv;
|
||||
break;
|
||||
|
||||
case KITEM_ORBINAUT:
|
||||
localpatch[i] = kp_orbinaut[(offset ? 4 : min(amt-1, 3))];
|
||||
break;
|
||||
|
||||
default:
|
||||
localpatch[i] = K_GetCachedItemPatch(item, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stplyr->itemRoulette.active == true)
|
||||
{
|
||||
rouletteOffset = K_GetRouletteOffset(&stplyr->itemRoulette, rendertimefrac);
|
||||
}
|
||||
else
|
||||
{
|
||||
// I'm doing this a little weird and drawing mostly in reverse order
|
||||
// The only actual reason is to make sneakers line up this way in the code below
|
||||
// This shouldn't have any actual baring over how it functions
|
||||
// Hyudoro is first, because we're drawing it on top of the player's current item
|
||||
|
||||
localcolor[1] = SKINCOLOR_NONE;
|
||||
rouletteOffset = stplyr->karthud[khud_rouletteoffset];
|
||||
|
||||
if (stplyr->stealingtimer < 0)
|
||||
{
|
||||
if (leveltime & 2)
|
||||
localpatch = kp_hyudoro[offset];
|
||||
localpatch[1] = kp_hyudoro[offset];
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
else if ((stplyr->stealingtimer > 0) && (leveltime & 2))
|
||||
{
|
||||
localpatch = kp_hyudoro[offset];
|
||||
localpatch[1] = kp_hyudoro[offset];
|
||||
}
|
||||
else if (stplyr->eggmanexplode > 1)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
localpatch = kp_eggman[offset];
|
||||
localpatch[1] = kp_eggman[offset];
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
else if (stplyr->ballhogcharge > 0)
|
||||
{
|
||||
|
|
@ -1086,9 +1107,9 @@ static void K_drawKartItem(void)
|
|||
maxl = (((stplyr->itemamount-1) * BALLHOGINCREMENT) + 1);
|
||||
|
||||
if (leveltime & 1)
|
||||
localpatch = kp_ballhog[offset];
|
||||
localpatch[1] = kp_ballhog[offset];
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
else if (stplyr->rocketsneakertimer > 1)
|
||||
{
|
||||
|
|
@ -1096,31 +1117,31 @@ static void K_drawKartItem(void)
|
|||
maxl = (itemtime*3) - barlength;
|
||||
|
||||
if (leveltime & 1)
|
||||
localpatch = kp_rocketsneaker[offset];
|
||||
localpatch[1] = kp_rocketsneaker[offset];
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
else if (stplyr->sadtimer > 0)
|
||||
{
|
||||
if (leveltime & 2)
|
||||
localpatch = kp_sadface[offset];
|
||||
localpatch[1] = kp_sadface[offset];
|
||||
else
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stplyr->itemamount <= 0)
|
||||
return;
|
||||
|
||||
switch(stplyr->itemtype)
|
||||
switch (stplyr->itemtype)
|
||||
{
|
||||
case KITEM_INVINCIBILITY:
|
||||
localpatch = localinv;
|
||||
localpatch[1] = localinv;
|
||||
localbg = kp_itembg[offset+1];
|
||||
break;
|
||||
|
||||
case KITEM_ORBINAUT:
|
||||
localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))];
|
||||
localpatch[1] = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))];
|
||||
break;
|
||||
|
||||
case KITEM_SPB:
|
||||
|
|
@ -1131,44 +1152,45 @@ static void K_drawKartItem(void)
|
|||
/*FALLTHRU*/
|
||||
|
||||
default:
|
||||
localpatch = K_GetCachedItemPatch(stplyr->itemtype, offset);
|
||||
localpatch[1] = K_GetCachedItemPatch(stplyr->itemtype, offset);
|
||||
|
||||
if (localpatch == NULL)
|
||||
localpatch = kp_nodraw; // diagnose underflows
|
||||
if (localpatch[1] == NULL)
|
||||
localpatch[1] = kp_nodraw; // diagnose underflows
|
||||
break;
|
||||
}
|
||||
|
||||
if ((stplyr->pflags & PF_ITEMOUT) && !(leveltime & 1))
|
||||
localpatch = kp_nodraw;
|
||||
localpatch[1] = kp_nodraw;
|
||||
}
|
||||
|
||||
if (stplyr->karthud[khud_itemblink] && (leveltime & 1))
|
||||
{
|
||||
colormode = TC_BLINK;
|
||||
colormode[1] = TC_BLINK;
|
||||
|
||||
switch (stplyr->karthud[khud_itemblinkmode])
|
||||
{
|
||||
case 2:
|
||||
localcolor = K_RainbowColor(leveltime);
|
||||
localcolor[1] = K_RainbowColor(leveltime);
|
||||
break;
|
||||
case 1:
|
||||
localcolor = SKINCOLOR_RED;
|
||||
localcolor[1] = SKINCOLOR_RED;
|
||||
break;
|
||||
default:
|
||||
localcolor = SKINCOLOR_WHITE;
|
||||
localcolor[1] = SKINCOLOR_WHITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide the other items.
|
||||
// Effectively lets the other roulette items
|
||||
// show flicker away after you select.
|
||||
localpatch[0] = localpatch[2] = kp_nodraw;
|
||||
}
|
||||
}
|
||||
|
||||
// pain and suffering defined below
|
||||
if (r_splitscreen < 2) // don't change shit for THIS splitscreen.
|
||||
{
|
||||
fx = ITEM_X;
|
||||
fy = ITEM_Y;
|
||||
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
|
||||
}
|
||||
else // now we're having a fun game.
|
||||
if (offset)
|
||||
{
|
||||
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
|
||||
{
|
||||
|
|
@ -1183,35 +1205,91 @@ static void K_drawKartItem(void)
|
|||
fflags = V_SNAPTORIGHT|V_SNAPTOTOP|V_SPLITSCREEN;
|
||||
flipamount = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (localcolor != SKINCOLOR_NONE)
|
||||
colmap = R_GetTranslationColormap(colormode, localcolor, GTC_CACHE);
|
||||
rouletteSpace = ROULETTE_SPACING_SPLITSCREEN;
|
||||
rouletteOffset = FixedMul(rouletteOffset, FixedDiv(ROULETTE_SPACING_SPLITSCREEN, ROULETTE_SPACING));
|
||||
rouletteCrop.x = 16;
|
||||
rouletteCrop.y = 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
fx = ITEM_X;
|
||||
fy = ITEM_Y;
|
||||
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
|
||||
|
||||
//V_SetClipRect((fx + 10) << FRACBITS, (fy + 10) << FRACBITS, 30 << FRACBITS, 30 << FRACBITS, V_HUDTRANS|V_SLIDEIN|fflags);
|
||||
// Need to draw these in a particular order, for sorting.
|
||||
V_SetClipRect(
|
||||
(fx + rouletteCrop.x) << FRACBITS, (fy + rouletteCrop.y) << FRACBITS,
|
||||
rouletteSpace, rouletteSpace,
|
||||
V_SLIDEIN|fflags
|
||||
);
|
||||
|
||||
// Then, the numbers:
|
||||
if (stplyr->itemamount >= numberdisplaymin && !stplyr->itemroulette)
|
||||
V_DrawFixedPatch(
|
||||
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset + rouletteSpace,
|
||||
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
|
||||
localpatch[0], (localcolor[0] ? R_GetTranslationColormap(colormode[0], localcolor[0], GTC_CACHE) : NULL)
|
||||
);
|
||||
V_DrawFixedPatch(
|
||||
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset - rouletteSpace,
|
||||
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
|
||||
localpatch[2], (localcolor[2] ? R_GetTranslationColormap(colormode[2], localcolor[2], GTC_CACHE) : NULL)
|
||||
);
|
||||
|
||||
if (stplyr->itemRoulette.active == true)
|
||||
{
|
||||
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);
|
||||
if (offset)
|
||||
if (flipamount) // reminder that this is for 3/4p's right end of the screen.
|
||||
V_DrawString(fx+2, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount));
|
||||
else
|
||||
V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount));
|
||||
else
|
||||
{
|
||||
V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx);
|
||||
V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->itemamount));
|
||||
}
|
||||
// Draw the item underneath the box.
|
||||
V_DrawFixedPatch(
|
||||
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset,
|
||||
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
|
||||
localpatch[1], (localcolor[1] ? R_GetTranslationColormap(colormode[1], localcolor[1], GTC_CACHE) : NULL)
|
||||
);
|
||||
V_ClearClipRect();
|
||||
}
|
||||
else
|
||||
V_DrawFixedPatch(fx<<FRACBITS, fy<<FRACBITS, FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags, localpatch, colmap);
|
||||
{
|
||||
// Draw the item above the box.
|
||||
V_ClearClipRect();
|
||||
|
||||
//V_ClearClipRect();
|
||||
if (stplyr->itemamount >= numberdisplaymin && stplyr->itemRoulette.active == false)
|
||||
{
|
||||
// Then, the numbers:
|
||||
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) + rouletteOffset,
|
||||
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
|
||||
localpatch[1], (localcolor[1] ? R_GetTranslationColormap(colormode[1], localcolor[1], GTC_CACHE) : NULL)
|
||||
);
|
||||
|
||||
if (offset)
|
||||
{
|
||||
if (flipamount) // reminder that this is for 3/4p's right end of the screen.
|
||||
V_DrawString(fx+2, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount));
|
||||
else
|
||||
V_DrawString(fx+24, fy+31, V_ALLOWLOWERCASE|V_HUDTRANS|V_SLIDEIN|fflags, va("x%d", stplyr->itemamount));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawScaledPatch(fy+28, fy+41, V_HUDTRANS|V_SLIDEIN|fflags, kp_itemx);
|
||||
V_DrawKartString(fx+38, fy+36, V_HUDTRANS|V_SLIDEIN|fflags, va("%d", stplyr->itemamount));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch(
|
||||
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset,
|
||||
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
|
||||
localpatch[1], (localcolor[1] ? R_GetTranslationColormap(colormode[1], localcolor[1], GTC_CACHE) : NULL)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Extensible meter, currently only used for rocket sneaker...
|
||||
if (itembar)
|
||||
|
|
@ -4434,7 +4512,7 @@ K_drawMiniPing (void)
|
|||
|
||||
static void K_drawDistributionDebugger(void)
|
||||
{
|
||||
patch_t *items[NUMKARTRESULTS] = {
|
||||
patch_t *patches[NUMKARTRESULTS] = {
|
||||
kp_sadface[1],
|
||||
kp_sneaker[1],
|
||||
kp_rocketsneaker[1],
|
||||
|
|
@ -4466,86 +4544,67 @@ static void K_drawDistributionDebugger(void)
|
|||
kp_orbinaut[4],
|
||||
kp_jawz[1]
|
||||
};
|
||||
UINT8 useodds = 0;
|
||||
UINT8 pingame = 0, bestbumper = 0;
|
||||
UINT32 pdis = 0;
|
||||
INT32 i;
|
||||
INT32 x = -9, y = -9;
|
||||
|
||||
itemroulette_t rouletteData = {0};
|
||||
|
||||
const fixed_t scale = (FRACUNIT >> 1);
|
||||
const fixed_t space = 24 * scale;
|
||||
const fixed_t pad = 9 * scale;
|
||||
|
||||
fixed_t x = -pad;
|
||||
fixed_t y = -pad;
|
||||
size_t i;
|
||||
|
||||
if (stplyr != &players[displayplayers[0]]) // only for p1
|
||||
return;
|
||||
|
||||
if (K_ForcedSPB(stplyr) == true)
|
||||
{
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[KITEM_SPB]);
|
||||
V_DrawThinString(x+11, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, "EX");
|
||||
return;
|
||||
}
|
||||
|
||||
// The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
pingame++;
|
||||
if (players[i].bumpers > bestbumper)
|
||||
bestbumper = players[i].bumpers;
|
||||
}
|
||||
K_FillItemRouletteData(stplyr, &rouletteData);
|
||||
|
||||
// lovely double loop......
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
for (i = 0; i < rouletteData.itemListLen; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator
|
||||
&& players[i].position == 1)
|
||||
const kartitems_t item = rouletteData.itemList[i];
|
||||
UINT8 amount = 1;
|
||||
|
||||
if (y > (BASEVIDHEIGHT << FRACBITS) - space - pad)
|
||||
{
|
||||
// This player is first! Yay!
|
||||
pdis = stplyr->distancetofinish - players[i].distancetofinish;
|
||||
break;
|
||||
x += space;
|
||||
y = -pad;
|
||||
}
|
||||
}
|
||||
|
||||
pdis = K_ScaleItemDistance(pdis, pingame);
|
||||
|
||||
if (stplyr->bot && stplyr->botvars.rival)
|
||||
{
|
||||
// Rival has better odds :)
|
||||
pdis = (15 * pdis) / 14;
|
||||
}
|
||||
|
||||
useodds = K_FindUseodds(stplyr, 0, pdis, bestbumper);
|
||||
|
||||
for (i = 1; i < NUMKARTRESULTS; i++)
|
||||
{
|
||||
INT32 itemodds = K_KartGetItemOdds(
|
||||
useodds, i,
|
||||
stplyr->distancetofinish,
|
||||
0,
|
||||
stplyr->bot, (stplyr->bot && stplyr->botvars.rival)
|
||||
);
|
||||
INT32 amount = 1;
|
||||
|
||||
if (itemodds <= 0)
|
||||
continue;
|
||||
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOTOP, items[i]);
|
||||
V_DrawThinString(x+11, y+31, V_SNAPTOTOP, va("%d", itemodds));
|
||||
V_DrawFixedPatch(x, y, scale, V_SNAPTOTOP, patches[item], NULL);
|
||||
|
||||
// Display amount for multi-items
|
||||
amount = K_ItemResultToAmount(i);
|
||||
amount = K_ItemResultToAmount(item);
|
||||
if (amount > 1)
|
||||
{
|
||||
V_DrawString(x+24, y+31, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("x%d", amount));
|
||||
V_DrawStringScaled(
|
||||
x + (18 * scale),
|
||||
y + (23 * scale),
|
||||
scale, FRACUNIT, FRACUNIT,
|
||||
V_ALLOWLOWERCASE|V_SNAPTOTOP,
|
||||
NULL, HU_FONT,
|
||||
va("x%d", amount)
|
||||
);
|
||||
}
|
||||
|
||||
x += 32;
|
||||
if (x >= 297)
|
||||
{
|
||||
x = -9;
|
||||
y += 32;
|
||||
}
|
||||
y += space;
|
||||
}
|
||||
|
||||
V_DrawString(0, 0, V_SNAPTOTOP, va("USEODDS %d", useodds));
|
||||
V_DrawString((x >> FRACBITS) + 20, 2, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("useOdds[%u]", rouletteData.useOdds));
|
||||
V_DrawString((x >> FRACBITS) + 20, 10, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("speed = %u", rouletteData.speed));
|
||||
|
||||
V_DrawString((x >> FRACBITS) + 20, 22, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("baseDist = %u", rouletteData.baseDist));
|
||||
V_DrawString((x >> FRACBITS) + 20, 30, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("dist = %u", rouletteData.dist));
|
||||
|
||||
V_DrawString((x >> FRACBITS) + 20, 42, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("firstDist = %u", rouletteData.firstDist));
|
||||
V_DrawString((x >> FRACBITS) + 20, 50, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("secondDist = %u", rouletteData.secondDist));
|
||||
V_DrawString((x >> FRACBITS) + 20, 58, V_ALLOWLOWERCASE|V_SNAPTOTOP, va("secondToFirst = %u", rouletteData.secondToFirst));
|
||||
|
||||
#ifndef ITEM_LIST_SIZE
|
||||
Z_Free(rouletteData.itemList);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void K_DrawWaypointDebugger(void)
|
||||
|
|
|
|||
1024
src/k_kart.c
1024
src/k_kart.c
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
1332
src/k_roulette.c
Normal file
1332
src/k_roulette.c
Normal file
File diff suppressed because it is too large
Load diff
169
src/k_roulette.h
Normal file
169
src/k_roulette.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// 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"
|
||||
|
||||
#define ROULETTE_SPACING (36 << FRACBITS)
|
||||
#define ROULETTE_SPACING_SPLITSCREEN (16 << FRACBITS)
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_ItemEnabled(kartitems_t item);
|
||||
|
||||
Determines whenever or not an item should
|
||||
be enabled. Accounts for situations where
|
||||
rules should not be able to be changed.
|
||||
|
||||
Input Arguments:-
|
||||
item - The item to check.
|
||||
|
||||
Return:-
|
||||
true if the item is enabled, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_ItemEnabled(kartitems_t item);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_ItemSingularity(kartitems_t item);
|
||||
|
||||
Determines whenever or not this item should
|
||||
be using special cases to prevent more than
|
||||
one existing at a time.
|
||||
|
||||
Input Arguments:-
|
||||
item - The item to check.
|
||||
|
||||
Return:-
|
||||
true to use the special rules, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_ItemSingularity(kartitems_t item);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item);
|
||||
|
||||
Gets the frequency an item should show up in
|
||||
an item bracket, and adjusted for special
|
||||
factors (such as Frantic Items).
|
||||
|
||||
Input Arguments:-
|
||||
player - The player we intend to give the item to later.
|
||||
Can be NULL for generic use.
|
||||
roulette - The roulette data that we intend to
|
||||
insert this item into.
|
||||
pos - The item bracket we are in.
|
||||
item - The item to give.
|
||||
|
||||
Return:-
|
||||
The number of items we want to insert
|
||||
into the roulette.
|
||||
--------------------------------------------------*/
|
||||
|
||||
INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette);
|
||||
|
||||
Fills out the item roulette struct when it is
|
||||
initially created. This function needs to be
|
||||
HUD-safe for the item debugger, so the player
|
||||
cannot be modified at this stage.
|
||||
|
||||
Input Arguments:-
|
||||
player - The player this roulette data is for.
|
||||
Can be NULL for generic use.
|
||||
roulette - The roulette data struct to fill out.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulette);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_StartItemRoulette(player_t *const player);
|
||||
|
||||
Starts the item roulette sequence for a player.
|
||||
This stage can only be used by gameplay, thus
|
||||
this handles gameplay modifications as well.
|
||||
|
||||
Input Arguments:-
|
||||
player - The player to start the item roulette for.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_StartItemRoulette(player_t *const player);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_StartEggmanRoulette(player_t *const player);
|
||||
|
||||
Starts the Eggman Mark roulette sequence for
|
||||
a player. Looks identical to a regular item
|
||||
roulette, but gives you the Eggman explosion
|
||||
countdown instead when confirming it.
|
||||
|
||||
Input Arguments:-
|
||||
player - The player to start the Eggman roulette for.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_StartEggmanRoulette(player_t *const player);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta);
|
||||
|
||||
Gets the Y offset, for use in the roulette HUD.
|
||||
A separate function since it is used both by the
|
||||
HUD itself, as well as when confirming an item.
|
||||
|
||||
Input Arguments:-
|
||||
roulette - The roulette we are drawing for.
|
||||
renderDelta - Fractional tic delta, when used for HUD.
|
||||
|
||||
Return:-
|
||||
The Y offset when drawing the item.
|
||||
--------------------------------------------------*/
|
||||
|
||||
fixed_t K_GetRouletteOffset(itemroulette_t *const roulette, fixed_t renderDelta);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd);
|
||||
|
||||
Handles ticking a player's item roulette,
|
||||
and player input for stopping it.
|
||||
|
||||
Input Arguments:-
|
||||
player - The player to run the item roulette for.
|
||||
cmd - The player's controls.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_KartItemRoulette(player_t *const player, ticcmd_t *cmd);
|
||||
|
||||
|
||||
#endif // __K_ROULETTE_H__
|
||||
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -13043,9 +13044,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);
|
||||
}
|
||||
|
||||
// Here at mapload in battle?
|
||||
if ((gametyperules & GTR_BUMPERS) && (actor->flags2 & MF2_BOSSNOTRAP))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6128,7 +6128,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
|
||||
|
|
@ -6182,7 +6182,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;
|
||||
|
|
@ -6198,11 +6198,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)
|
||||
|
|
|
|||
108
src/p_saveg.c
108
src/p_saveg.c
|
|
@ -96,7 +96,7 @@ static void P_NetArchivePlayers(void)
|
|||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
// size_t q;
|
||||
size_t q;
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS);
|
||||
|
||||
|
|
@ -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,50 @@ 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);
|
||||
|
||||
#ifdef ITEM_LIST_SIZE
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.itemListLen);
|
||||
|
||||
for (q = 0; q < ITEM_LIST_SIZE; q++)
|
||||
{
|
||||
if (q >= players[i].itemRoulette.itemListLen)
|
||||
{
|
||||
WRITESINT8(save_p, KITEM_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITESINT8(save_p, players[i].itemRoulette.itemList[q]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (players[i].itemRoulette.itemList == NULL)
|
||||
{
|
||||
WRITEUINT32(save_p, 0);
|
||||
WRITEUINT32(save_p, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.itemListCap);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.itemListLen);
|
||||
|
||||
for (q = 0; q < players[i].itemRoulette.itemListLen; q++)
|
||||
{
|
||||
WRITESINT8(save_p, players[i].itemRoulette.itemList[q]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WRITEUINT8(save_p, players[i].itemRoulette.useOdds);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.dist);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.index);
|
||||
WRITEUINT8(save_p, players[i].itemRoulette.sound);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.speed);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.tics);
|
||||
WRITEUINT32(save_p, players[i].itemRoulette.elapsed);
|
||||
WRITEUINT8(save_p, players[i].itemRoulette.eggman);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,6 +458,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
{
|
||||
INT32 i, j;
|
||||
UINT16 flags;
|
||||
size_t q;
|
||||
|
||||
if (READUINT32(save_p) != ARCHIVEBLOCK_PLAYERS)
|
||||
I_Error("Bad $$$.sav at archive block Players");
|
||||
|
|
@ -612,9 +654,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 +752,61 @@ 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 = (boolean)READUINT8(save_p);
|
||||
|
||||
#ifdef ITEM_LIST_SIZE
|
||||
players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p);
|
||||
|
||||
for (q = 0; q < ITEM_LIST_SIZE; q++)
|
||||
{
|
||||
players[i].itemRoulette.itemList[q] = READSINT8(save_p);
|
||||
}
|
||||
#else
|
||||
players[i].itemRoulette.itemListCap = (size_t)READUINT32(save_p);
|
||||
players[i].itemRoulette.itemListLen = (size_t)READUINT32(save_p);
|
||||
|
||||
if (players[i].itemRoulette.itemListCap > 0)
|
||||
{
|
||||
if (players[i].itemRoulette.itemList == NULL)
|
||||
{
|
||||
players[i].itemRoulette.itemList = Z_Calloc(
|
||||
sizeof(SINT8) * players[i].itemRoulette.itemListCap,
|
||||
PU_STATIC,
|
||||
&players[i].itemRoulette.itemList
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
players[i].itemRoulette.itemList = Z_Realloc(
|
||||
players[i].itemRoulette.itemList,
|
||||
sizeof(SINT8) * players[i].itemRoulette.itemListCap,
|
||||
PU_STATIC,
|
||||
&players[i].itemRoulette.itemList
|
||||
);
|
||||
}
|
||||
|
||||
if (players[i].itemRoulette.itemList == NULL)
|
||||
{
|
||||
I_Error("Not enough memory for item roulette list\n");
|
||||
}
|
||||
|
||||
for (q = 0; q < players[i].itemRoulette.itemListLen; q++)
|
||||
{
|
||||
players[i].itemRoulette.itemList[q] = READSINT8(save_p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
players[i].itemRoulette.useOdds = READUINT8(save_p);
|
||||
players[i].itemRoulette.dist = READUINT32(save_p);
|
||||
players[i].itemRoulette.index = (size_t)READUINT32(save_p);
|
||||
players[i].itemRoulette.sound = READUINT8(save_p);
|
||||
players[i].itemRoulette.speed = (tic_t)READUINT32(save_p);
|
||||
players[i].itemRoulette.tics = (tic_t)READUINT32(save_p);
|
||||
players[i].itemRoulette.elapsed = (tic_t)READUINT32(save_p);
|
||||
players[i].itemRoulette.eggman = (boolean)READUINT8(save_p);
|
||||
|
||||
//players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue