Merge pull request 'Item roll tracker' (#198) from itemlists into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/198
This commit is contained in:
commit
cf3c123187
15 changed files with 542 additions and 25 deletions
|
|
@ -139,6 +139,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
k_botsearch.cpp
|
||||
k_cluster.cpp
|
||||
k_items.c
|
||||
k_itemlist.cpp
|
||||
k_grandprix.c
|
||||
k_boss.c
|
||||
k_hud.c
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@
|
|||
#include "g_party.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "k_items.h"
|
||||
#include "k_itemlist.hpp"
|
||||
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
||||
|
|
@ -174,6 +175,7 @@ static void KartItemPush_OnChange(void);
|
|||
static void KartAntiBump_OnChange(void);
|
||||
static void KartItemBreaker_OnChange(void);
|
||||
static void KartBumpSpark_OnChange(void);
|
||||
static void KartItemList_OnChange(void);
|
||||
|
||||
static void Schedule_OnChange(void);
|
||||
|
||||
|
|
@ -605,6 +607,8 @@ consvar_t cv_kartlegacyspbdist = CVAR_INIT ("kartlegacyspbdist", "2216", CV_NETV
|
|||
// SPB Rush toggle; toggles on/off the more aggressive "pressure" odds when an SPB is active
|
||||
consvar_t cv_kartspbrush = CVAR_INIT ("kartspbrush", "On", CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_itemlist = CVAR_INIT ("kartitemlist", "On", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartItemList_OnChange);
|
||||
|
||||
// Time limit for Alt. Shrink
|
||||
static CV_PossibleValue_t altshrinktime_cons_t[] = {{0, "MIN"}, {(INT16_MAX / TICRATE), "MAX"}, {0, NULL}};
|
||||
consvar_t cv_kartaltshrinktime = CVAR_INIT ("kartaltshrinktime", "14", CV_NETVAR|CV_CHEAT|CV_GUARD, altshrinktime_cons_t, NULL);
|
||||
|
|
@ -1075,6 +1079,8 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_dummyconsvar);
|
||||
CV_RegisterVar(&cv_encorevotes);
|
||||
|
||||
CV_RegisterVar(&cv_itemlist);
|
||||
|
||||
#ifdef USE_STUN
|
||||
CV_RegisterVar(&cv_stunserver);
|
||||
#endif
|
||||
|
|
@ -6527,6 +6533,8 @@ static void Got_Cheat(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
else
|
||||
{
|
||||
K_AddItemRollToList((INT32)(player - players), item, amt);
|
||||
|
||||
CV_CheaterWarning(playernum, va("give item %s x%d", DEH_KartItemName(item), amt));
|
||||
}
|
||||
break;
|
||||
|
|
@ -8350,6 +8358,39 @@ static void KartBumpSpark_OnChange(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void KartItemList_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!K_ItemListActive() && cv_itemlist.value)
|
||||
{
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
itemlistactive = true;
|
||||
CONS_Printf(M_GetText("Item rolls will be displayed.\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Item rolls will be displayed next round.\n"));
|
||||
}
|
||||
}
|
||||
else if (K_ItemListActive() && !cv_itemlist.value)
|
||||
{
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
itemlistactive = false;
|
||||
CONS_Printf(M_GetText("Item rolls will not be displayed.\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Item rolls will not be displayed next round.\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Schedule_OnChange(void)
|
||||
{
|
||||
size_t i;
|
||||
|
|
|
|||
|
|
@ -221,6 +221,8 @@ extern consvar_t cv_kartlegacyspbdist;
|
|||
|
||||
extern consvar_t cv_kartspbrush;
|
||||
|
||||
extern consvar_t cv_itemlist;
|
||||
|
||||
extern consvar_t cv_encorevotes;
|
||||
|
||||
extern consvar_t cv_votetime;
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ static patch_t *kp_racefinish[6];
|
|||
static patch_t *kp_positionnum[NUMPOSNUMS][NUMPOSFRAMES];
|
||||
static patch_t *kp_winnernum[NUMPOSFRAMES];
|
||||
|
||||
static patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
static patch_t *kp_facehighlight[8];
|
||||
|
||||
static patch_t *kp_nocontestminimap;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ extern consvar_t cv_colorizedhudcolor;
|
|||
|
||||
extern consvar_t cv_newtabranking;
|
||||
|
||||
extern patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
|
||||
struct trackingResult_t
|
||||
{
|
||||
fixed_t x, y;
|
||||
|
|
|
|||
151
src/k_itemlist.cpp
Normal file
151
src/k_itemlist.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "byteptr.h"
|
||||
#include "d_player.h"
|
||||
#include "doomdef.h"
|
||||
#include "k_items.h"
|
||||
#include "p_saveg.h"
|
||||
#include "v_video.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
std::unordered_map<kartitemtype_e, INT32> itemcounter[MAXPLAYERS];
|
||||
|
||||
//
|
||||
// Clears out all item lists for all players. Should only run during race setup.
|
||||
//
|
||||
void K_ClearItemRollLists(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
itemcounter[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Adds an item roll to the item roll list.
|
||||
// If an entry for the item already exists, this function adds to its roll count.
|
||||
//
|
||||
void K_AddItemRollToList(INT32 pid, kartitemtype_e item, INT32 amount)
|
||||
{
|
||||
if (auto search = itemcounter[pid].find(item); search != itemcounter[pid].end())
|
||||
itemcounter[pid][item] += amount;
|
||||
else
|
||||
itemcounter[pid][item] = amount; // If this roll didn't exist before, it does now :^)
|
||||
}
|
||||
|
||||
//
|
||||
// Gets the size of the item roll list. Primarily used for syncing netgames.
|
||||
//
|
||||
UINT32 K_GetItemListSize(INT32 pid)
|
||||
{
|
||||
return static_cast<UINT32>(itemcounter[pid].size());
|
||||
}
|
||||
|
||||
//
|
||||
// Sets an entry in the item roll list to a specific value.
|
||||
//
|
||||
void K_SetItemListEntry(INT32 pid, kartitemtype_e item, INT32 num)
|
||||
{
|
||||
itemcounter[pid][item] = num;
|
||||
}
|
||||
|
||||
//
|
||||
// Gets the value of an entry in the item roll list, given it exists.
|
||||
// If nothing is found, this value returns 0.
|
||||
//
|
||||
UINT32 K_GetItemListEntry(INT32 pid, kartitemtype_e item)
|
||||
{
|
||||
if (auto search = itemcounter[pid].find(item); search != itemcounter[pid].end())
|
||||
{
|
||||
return itemcounter[pid][item];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// C and C++ are like oil and water at points; we need to synch every entry in the unordered
|
||||
// map by doing... this.
|
||||
//
|
||||
UINT32 K_SyncItemList(savebuffer_t* save, INT32 pid)
|
||||
{
|
||||
UINT32 buffer_size;
|
||||
|
||||
if (save->write)
|
||||
{
|
||||
// Buffer size = list size * 2 (2 entries for each buffer element)
|
||||
buffer_size = static_cast<UINT32>(itemcounter[pid].size());
|
||||
|
||||
// First, write the size of the buffer we're about to send over.
|
||||
WRITEUINT32(save->p, buffer_size);
|
||||
|
||||
// Then, comb through the map and write every entry in it to the save buffer.
|
||||
for (const auto& n : itemcounter[pid])
|
||||
{
|
||||
WRITEUINT32(save->p, static_cast<UINT32>(n.first));
|
||||
WRITEUINT32(save->p, static_cast<UINT32>(n.second));
|
||||
}
|
||||
|
||||
return buffer_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the buffer size.
|
||||
buffer_size = READUINT32(save->p);
|
||||
|
||||
UINT32 i, item, amt;
|
||||
for (i = 0; i < buffer_size; i++)
|
||||
{
|
||||
// Loop through the save buffer and write everything we find into the given item
|
||||
// list.
|
||||
item = READUINT32(save->p);
|
||||
amt = READUINT32(save->p);
|
||||
|
||||
itemcounter[pid][static_cast<kartitemtype_e>(item)] = amt;
|
||||
}
|
||||
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ITEMLOG_SPACE 1
|
||||
|
||||
// Draws an item in the player's item list. Draws nothing if the list is empty.
|
||||
fixed_t K_DrawItemList(INT32 pid, fixed_t x, fixed_t y)
|
||||
{
|
||||
if (itemcounter[pid].size() < 1)
|
||||
return 0;
|
||||
|
||||
patch_t* localpatch;
|
||||
fixed_t dx = x;
|
||||
INT32 ir_length;
|
||||
|
||||
for (const auto& n : itemcounter[pid])
|
||||
{
|
||||
if (n.second < 1)
|
||||
continue;
|
||||
|
||||
localpatch = K_GetCachedItemPatch(n.first, true, 0);
|
||||
ir_length = static_cast<INT32>(strlen(va("%d", n.second)));
|
||||
|
||||
V_DrawFixedPatch(dx, y - (25 * FRACUNIT / 6), FRACUNIT / 3, 0, localpatch, NULL);
|
||||
|
||||
V_DrawSmallString((dx / FRACUNIT) + ((5 + (std::max(0, ir_length - 1) * 3))),
|
||||
(y / FRACUNIT) + 2,
|
||||
V_ALLOWLOWERCASE | V_6WIDTHSPACE,
|
||||
va("%d", n.second));
|
||||
|
||||
dx += (6 + std::max(0, (ir_length * 3) - 3) + ITEMLOG_SPACE) * FRACUNIT;
|
||||
}
|
||||
|
||||
// Return the overall "width" of the list.
|
||||
return dx - x;
|
||||
}
|
||||
|
||||
#undef ITEMLOG_SPACE
|
||||
}
|
||||
24
src/k_itemlist.hpp
Normal file
24
src/k_itemlist.hpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "doomdef.h"
|
||||
#include "k_items.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void K_ClearItemRollLists(void);
|
||||
void K_AddItemRollToList(INT32 pid, kartitemtype_e item, INT32 amount);
|
||||
fixed_t K_DrawItemList(INT32 pid, fixed_t x, fixed_t y);
|
||||
UINT32 K_GetItemListSize(INT32 pid);
|
||||
|
||||
// Getter and setter
|
||||
|
||||
void K_SetItemListEntry(INT32 pid, kartitemtype_e item, INT32 num);
|
||||
UINT32 K_GetItemListEntry(INT32 pid, kartitemtype_e item);
|
||||
|
||||
// Netsynch; returns the size of the list buffer, always.
|
||||
UINT32 K_SyncItemList(savebuffer_t *save, INT32 pid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include "k_waypoint.h"
|
||||
#include "k_director.h"
|
||||
#include "k_cluster.hpp"
|
||||
#include "k_itemlist.hpp"
|
||||
#include "k_items.h"
|
||||
#include "k_collide.h"
|
||||
|
||||
|
|
@ -379,6 +380,9 @@ void K_AwardPlayerItem(player_t *player, kartitemtype_e type, UINT8 amount, kart
|
|||
amount *= 2;
|
||||
|
||||
player->itemamount = amount;
|
||||
|
||||
if (itemlistactive)
|
||||
K_AddItemRollToList((INT32)(player - players), type, amount);
|
||||
}
|
||||
|
||||
static void K_AwardPlayerResult(player_t *player, kartresult_t *result, kartitemblink_e blink)
|
||||
|
|
|
|||
11
src/k_kart.c
11
src/k_kart.c
|
|
@ -10972,6 +10972,17 @@ boolean K_ItemLitterActive(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean K_ItemListActive(void)
|
||||
{
|
||||
if (itemlistactive)
|
||||
{
|
||||
// Item listing is enabled!
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean K_ItemPushingActive(void)
|
||||
{
|
||||
return itempushing;
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ boolean K_DraftingActive(void);
|
|||
boolean K_AirDropActive(void);
|
||||
boolean K_AirThrustActive(void);
|
||||
boolean K_ItemLitterActive(void);
|
||||
boolean K_ItemListActive(void);
|
||||
boolean K_ItemPushingActive(void);
|
||||
INT32 K_GetBumpSpark(void);
|
||||
boolean K_BoostChain(player_t *player, INT32 timer, boolean chainsound);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "k_hud.h"
|
||||
#include "k_waypoint.h"
|
||||
#include "k_items.h"
|
||||
#include "k_itemlist.hpp"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "m_menu.h" // Player Setup menu color stuff
|
||||
#include "p_spec.h" // P_StartQuake
|
||||
|
|
@ -4364,6 +4365,12 @@ static int lib_kItemLitterActive(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kItemListActive(lua_State *L)
|
||||
{
|
||||
lua_pushboolean(L, K_ItemListActive());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Gets the currently active bumpspark type.
|
||||
static int lib_kGetBumpSpark(lua_State *L)
|
||||
{
|
||||
|
|
@ -5244,6 +5251,75 @@ static int lib_kSetPlayerItemCooldown(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kAddItemRollToList(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
kartitemtype_e item_id = (kartitemtype_e)luaL_checkinteger(L, 2);
|
||||
INT32 amt = luaL_checkinteger(L, 3);
|
||||
//HUDSAFE
|
||||
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (item_id < 1 || item_id >= numkartitems)
|
||||
return luaL_error(L, "item number %d out of range (1 - %d)", item_id, numkartitems-1);
|
||||
|
||||
INT32 pid = (INT32)(player - players);
|
||||
|
||||
K_AddItemRollToList(pid, item_id, amt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kGetItemListSize(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
//HUDSAFE
|
||||
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
INT32 pid = (INT32)(player - players);
|
||||
|
||||
lua_pushinteger(L, K_GetItemListSize(pid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kSetItemListEntry(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
kartitemtype_e item_id = (kartitemtype_e)luaL_checkinteger(L, 2);
|
||||
INT32 num = luaL_checkinteger(L, 3);
|
||||
//HUDSAFE
|
||||
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (item_id < 1 || item_id >= numkartitems)
|
||||
return luaL_error(L, "item number %d out of range (1 - %d)", item_id, numkartitems-1);
|
||||
|
||||
INT32 pid = (INT32)(player - players);
|
||||
|
||||
K_SetItemListEntry(pid, item_id, num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kGetItemListEntry(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
kartitemtype_e item_id = (kartitemtype_e)luaL_checkinteger(L, 2);
|
||||
//HUDSAFE
|
||||
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (item_id < 1 || item_id >= numkartitems)
|
||||
return luaL_error(L, "item number %d out of range (1 - %d)", item_id, numkartitems-1);
|
||||
|
||||
INT32 pid = (INT32)(player - players);
|
||||
lua_pushinteger(L, K_GetItemListEntry(pid, item_id));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// G_INPUT
|
||||
////////////
|
||||
|
||||
|
|
@ -5618,6 +5694,7 @@ static luaL_Reg lib[] = {
|
|||
{"K_DraftingActive",lib_kDraftingActive},
|
||||
{"K_AirDropActive",lib_kAirDropActive},
|
||||
{"K_ItemLitterActive",lib_kItemLitterActive},
|
||||
{"K_ItemListActive", lib_kItemListActive},
|
||||
{"K_GetBumpSpark",lib_kGetBumpSpark},
|
||||
{"K_UsingLegacyCheckpoints",lib_kUsingLegacyCheckpoints},
|
||||
{"K_DoBoost",lib_kDoBoost},
|
||||
|
|
@ -5706,6 +5783,12 @@ static luaL_Reg lib[] = {
|
|||
// k_items
|
||||
{"K_SetPlayerItemCooldown", lib_kSetPlayerItemCooldown},
|
||||
|
||||
// k_itemlist
|
||||
{"K_AddItemRollToList", lib_kAddItemRollToList},
|
||||
{"K_GetItemListSize", lib_kGetItemListSize},
|
||||
{"K_SetItemListEntry", lib_kSetItemListEntry},
|
||||
{"K_GetItemListEntry", lib_kGetItemListEntry},
|
||||
|
||||
//g_input
|
||||
{"G_SetPlayerGamepadIndicatorColor",lib_gSetPlayerGamepadIndicatorColor},
|
||||
{"G_PlayerDeviceRumble",lib_gPlayerDeviceRumble},
|
||||
|
|
|
|||
|
|
@ -622,6 +622,7 @@ extern boolean airthrustactive;
|
|||
extern boolean itemlittering;
|
||||
extern boolean itempushing;
|
||||
extern UINT8 bumpsparkactive;
|
||||
extern boolean itemlistactive;
|
||||
extern UINT16 bossdisabled;
|
||||
extern boolean stoppedclock;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "acs/interface.h"
|
||||
#include "g_party.h"
|
||||
#include "k_waypoint.h"
|
||||
#include "k_itemlist.hpp"
|
||||
|
||||
#include <tracy/tracy/TracyC.h>
|
||||
|
||||
|
|
@ -404,6 +405,9 @@ static void P_RelinkWaypoint(savebuffer_t *save, waypoint_t **ptr)
|
|||
#define ARCHIVEBLOCK_SPECIALS 0x7F228378
|
||||
#define ARCHIVEBLOCK_WAYPOINTS 0x7F46498F
|
||||
|
||||
// Specialized netsynch markers
|
||||
#define PLYRSYNC_ITEMLIST (1)
|
||||
|
||||
static inline void P_ArchivePlayer(savebuffer_t *save)
|
||||
{
|
||||
const player_t *player = &players[consoleplayer];
|
||||
|
|
@ -457,6 +461,12 @@ static void P_NetSyncPlayers(savebuffer_t *save)
|
|||
SYNC(playerconsole[i]);
|
||||
SYNC(splitscreen_invitations[i]);
|
||||
|
||||
// Item lists
|
||||
if (P_SyncUINT32(save, (K_GetItemListSize(i) ? PLYRSYNC_ITEMLIST : 0)))
|
||||
{
|
||||
K_SyncItemList(save, i);
|
||||
}
|
||||
|
||||
SYNC(players[i].angleturn);
|
||||
SYNC(players[i].aiming);
|
||||
SYNC(players[i].drawangle);
|
||||
|
|
@ -4222,6 +4232,7 @@ static boolean P_NetSyncMisc(savebuffer_t *save, boolean resending)
|
|||
SYNCBOOLEAN(airdropactive);
|
||||
SYNCBOOLEAN(itemlittering);
|
||||
SYNCBOOLEAN(itempushing);
|
||||
SYNCBOOLEAN(itemlistactive);
|
||||
SYNC(bumpsparkactive);
|
||||
SYNC(antibumptime);
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@
|
|||
#include "k_mapuser.h"
|
||||
#include "p_deepcopy.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "k_itemlist.hpp"
|
||||
#include "g_input.h"
|
||||
|
||||
#include "blan/b_soc.h"
|
||||
|
|
@ -164,6 +165,7 @@ boolean airthrustactive;
|
|||
boolean itemlittering;
|
||||
boolean itempushing;
|
||||
UINT8 bumpsparkactive;
|
||||
boolean itemlistactive;
|
||||
UINT16 bossdisabled;
|
||||
boolean stoppedclock;
|
||||
boolean levelloading;
|
||||
|
|
@ -8177,6 +8179,7 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
airthrustactive = false;
|
||||
itemlittering = false;
|
||||
itempushing = false;
|
||||
itemlistactive = false;
|
||||
bumpsparkactive = 0;
|
||||
antibumptime = 0;
|
||||
|
||||
|
|
@ -8213,10 +8216,15 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
if (cv_kartitempush.value)
|
||||
itempushing = true;
|
||||
|
||||
if (cv_itemlist.value)
|
||||
itemlistactive = true;
|
||||
|
||||
bumpsparkactive = (UINT8)cv_kartbumpspark.value;
|
||||
|
||||
antibumptime = (tic_t)cv_kartantibump.value * TICRATE;
|
||||
|
||||
K_ClearItemRollLists();
|
||||
|
||||
// emerald hunt
|
||||
hunt1 = hunt2 = hunt3 = NULL;
|
||||
|
||||
|
|
|
|||
225
src/y_inter.c
225
src/y_inter.c
|
|
@ -49,11 +49,18 @@
|
|||
#include "k_grandprix.h"
|
||||
#include "k_bot.h" // cv_botcanvote
|
||||
#include "r_fps.h" // R_GetTimeFrac
|
||||
#include "k_hud.h"
|
||||
#include "k_itemlist.hpp"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
#define ITEMLIST_PLAYER_YOFFSET 9
|
||||
#define ITEMLIST_SCROLLSPEED (3 * FRACUNIT / 4)
|
||||
#define ITEMLIST_SCROLLDELAY (3 * TICRATE)
|
||||
#define ITEMLIST_SCROLLREPEAT 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char patch[9];
|
||||
|
|
@ -80,9 +87,23 @@ typedef struct
|
|||
UINT8 pos[MAXPLAYERS]; // player positions. used for ties
|
||||
|
||||
boolean rankingsmode; // rankings mode
|
||||
boolean itemrolls;
|
||||
boolean encore; // encore mode
|
||||
} y_data;
|
||||
|
||||
static boolean Y_ItemListActive(void)
|
||||
{
|
||||
UINT8 i = 0, nump = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
nump++;
|
||||
}
|
||||
|
||||
return ((itemlistactive) && (nump > 1));
|
||||
}
|
||||
|
||||
static y_data data;
|
||||
|
||||
// graphics
|
||||
|
|
@ -99,6 +120,12 @@ static UINT8 *y_screenbuffer;
|
|||
static INT32 intertic;
|
||||
static INT32 endtic = -1;
|
||||
static INT32 sorttic = -1;
|
||||
static INT32 rolltic = -1;
|
||||
|
||||
static fixed_t listscroll_length = 0;
|
||||
static boolean listscroll_reverse = false;
|
||||
static INT32 listscroll_delay = 0;
|
||||
static fixed_t xscroll = 0;
|
||||
|
||||
intertype_t intertype = int_none;
|
||||
intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
|
@ -253,6 +280,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
data.levelstring[sizeof data.levelstring - 1] = '\0';
|
||||
|
||||
data.encore = encoremode;
|
||||
data.itemrolls = Y_ItemListActive();
|
||||
|
||||
memset(data.jitter, 0, sizeof (data.jitter));
|
||||
}
|
||||
|
|
@ -382,10 +410,17 @@ void Y_CleanupScreenBuffer(void)
|
|||
void Y_IntermissionDrawer(void)
|
||||
{
|
||||
INT32 i, whiteplayer = MAXPLAYERS, x = 4, hilicol = V_YELLOWMAP; // fallback
|
||||
INT32 xx = x, x_base = x;
|
||||
|
||||
if (intertype == int_none || rendermode == render_none)
|
||||
return;
|
||||
|
||||
INT32 w = (vid.width / vid.dupx);
|
||||
INT32 h = (vid.height / vid.dupy);
|
||||
|
||||
const INT32 vidxdiff = (w - BASEVIDWIDTH) / 2;
|
||||
const INT32 vidydiff = (h - BASEVIDHEIGHT) / 2;
|
||||
|
||||
if (!useinterpic && y_screenbuffer == NULL
|
||||
#ifdef HWRENDER
|
||||
// TODO resolution changes breaks the screentexture capture, I have no clue why
|
||||
|
|
@ -435,7 +470,18 @@ void Y_IntermissionDrawer(void)
|
|||
hilicol = V_YELLOWMAP;
|
||||
}
|
||||
|
||||
if (sorttic != -1 && intertic > sorttic)
|
||||
if (rolltic != -1 && intertic > (rolltic - 8) && (intertic < (rolltic + 8)))
|
||||
{
|
||||
INT32 count = (intertic - (rolltic - 8));
|
||||
|
||||
if (count < 8)
|
||||
x -= ((((count<<FRACBITS) + R_GetTimeFrac(RTF_INTER)) * vid.width)>>FRACBITS) / (8 * vid.dupx);
|
||||
else if (count == 8)
|
||||
goto skiptallydrawer;
|
||||
else if (count < 16)
|
||||
x += (((((16 - count)<<FRACBITS) - R_GetTimeFrac(RTF_INTER)) * vid.width)>>FRACBITS) / (8 * vid.dupx);
|
||||
}
|
||||
else if (sorttic != -1 && intertic > sorttic)
|
||||
{
|
||||
INT32 count = (intertic - sorttic);
|
||||
|
||||
|
|
@ -452,10 +498,15 @@ void Y_IntermissionDrawer(void)
|
|||
#define NUMFORNEWCOLUMN 8
|
||||
INT32 y = 41, gutter = ((data.numplayers > NUMFORNEWCOLUMN) ? 0 : (BASEVIDWIDTH/2));
|
||||
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
|
||||
fixed_t newlist_xpush = (BASEVIDWIDTH/2) * FRACUNIT;
|
||||
const char *timeheader;
|
||||
|
||||
|
||||
boolean manyplayers16 = (data.numplayers > NUMFORNEWCOLUMN*2);
|
||||
boolean manyplayers8 = (data.numplayers > NUMFORNEWCOLUMN);
|
||||
boolean displayitemrolls = (data.itemrolls && (intertic <= rolltic));
|
||||
|
||||
if (displayitemrolls)
|
||||
manyplayers16 = manyplayers8 = false;
|
||||
|
||||
int y2;
|
||||
|
||||
|
|
@ -510,13 +561,8 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
V_DrawRightAlignedString(x+152, 24, hilicol, timeheader);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawCenteredString(x+6, 24, hilicol, "#");
|
||||
V_DrawString(x+36, 24, hilicol, "NAME");
|
||||
|
||||
V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 24, hilicol, timeheader);
|
||||
}
|
||||
|
||||
INT32 xscroll_px = (xscroll / FRACUNIT);
|
||||
|
||||
for (i = 0; i < data.numplayers; i++)
|
||||
{
|
||||
|
|
@ -530,36 +576,78 @@ void Y_IntermissionDrawer(void)
|
|||
if (dojitter)
|
||||
y--;
|
||||
|
||||
if (manyplayers16)
|
||||
V_DrawPingNum(x+6, y+2, 0, data.pos[i], NULL);
|
||||
if (displayitemrolls)
|
||||
{
|
||||
if (data.pos[i] < 0 || data.pos[i] > 16)
|
||||
V_DrawPingNum(x+2-xscroll_px, y+1, 0, data.pos[i], NULL);
|
||||
else
|
||||
V_DrawScaledPatch(x-5-xscroll_px, y+1, 0, kp_facenum[data.pos[i]]);
|
||||
}
|
||||
else if (manyplayers16)
|
||||
{
|
||||
V_DrawPingNum(x + 6, y + 2, 0, data.pos[i], NULL);
|
||||
}
|
||||
else
|
||||
V_DrawCenteredString(x+6, y, 0, va("%d", data.pos[i]));
|
||||
|
||||
if (data.color[i])
|
||||
{
|
||||
UINT8 *colormap = R_GetTranslationColormap(*data.character[i], *data.color[i], GTC_CACHE);
|
||||
patch_t *facerank = faceprefix[*data.character[i]][FACE_RANK];
|
||||
patch_t *facerank;
|
||||
|
||||
facerank = faceprefix[*data.character[i]][FACE_RANK];
|
||||
|
||||
fixed_t scale = FRACUNIT;
|
||||
|
||||
if (manyplayers16)
|
||||
{
|
||||
// fixed_t scale = K_UseHighResPortraits() ? FRACUNIT/4 : FRACUNIT/2;
|
||||
fixed_t scale = FRACUNIT/2;
|
||||
scale = FRACUNIT / 2;
|
||||
|
||||
V_DrawFixedPatch((x+8)<<FRACBITS, (y+1)<<FRACBITS, scale, 0, facerank, colormap);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawMappedPatch(x+16+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
|
||||
INT32 xoffs, yoffs;
|
||||
|
||||
scale = (displayitemrolls) ? FRACUNIT/2 : FRACUNIT;
|
||||
|
||||
xoffs = FixedMul(16, scale);
|
||||
yoffs = FixedMul(4, scale);
|
||||
|
||||
if (displayitemrolls)
|
||||
{
|
||||
V_DrawFixedPatch(
|
||||
((x+11-xscroll_px)*FRACUNIT) + ((facerank->leftoffset) * scale),
|
||||
((y+1)*FRACUNIT) + ((facerank->topoffset) * scale),
|
||||
scale,
|
||||
0,
|
||||
facerank,
|
||||
colormap
|
||||
);
|
||||
|
||||
if ((x_base - x) == 0)
|
||||
{
|
||||
// Terrible hack to remedy offset woes: Set a "base" value for x to reference.
|
||||
x_base = (x+11) + 20;
|
||||
}
|
||||
|
||||
xx = x + x_base - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((x+xoffs)<<FRACBITS, ((y-yoffs)<<FRACBITS), scale, 0, facerank, colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.num[i] == whiteplayer && data.numplayers <= NUMFORNEWCOLUMN*2)
|
||||
if ((!displayitemrolls) && data.num[i] == whiteplayer && data.numplayers <= NUMFORNEWCOLUMN*2)
|
||||
{
|
||||
UINT8 cursorframe = (intertic / 4) % 8;
|
||||
patch_t *highlight = W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE);
|
||||
V_DrawScaledPatch(x+16+highlight->leftoffset, y-4+highlight->topoffset, 0, highlight);
|
||||
}
|
||||
|
||||
if ((players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot)
|
||||
if ((!displayitemrolls) && (players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot)
|
||||
{
|
||||
// RETIRED!!
|
||||
patch_t *retire = W_CachePatchName("K_NOBLNS", PU_CACHE);
|
||||
|
|
@ -578,10 +666,32 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
y2 = y;
|
||||
|
||||
INT32 slen = 0;
|
||||
INT32 slen_temp = slen;
|
||||
|
||||
if (manyplayers16)
|
||||
V_DrawThinString(x+18, y, hilicol|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
V_DrawThinString(x+18, y, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
else if (displayitemrolls)
|
||||
{
|
||||
V_DrawThinString(x + 20 - xscroll_px, y, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
|
||||
// Get the longest string size. This is... gross.
|
||||
INT32 ii;
|
||||
|
||||
for (ii = 0; ii < data.numplayers; ii++)
|
||||
{
|
||||
if (data.num[ii] != MAXPLAYERS && playeringame[data.num[ii]] && !players[data.num[ii]].spectator)
|
||||
{
|
||||
slen_temp = V_ThinStringWidth(data.name[ii], ((data.num[ii] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE);
|
||||
slen = ((slen_temp > slen) ? slen_temp : slen);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (manyplayers8)
|
||||
V_DrawThinString(x+36, y2-1, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
{
|
||||
V_DrawThinString(xx, y2 - 1, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
slen = V_ThinStringWidth(strtime, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE);
|
||||
}
|
||||
else
|
||||
V_DrawString(x+36, y2, ((data.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
|
||||
|
||||
|
|
@ -622,6 +732,11 @@ void Y_IntermissionDrawer(void)
|
|||
else
|
||||
V_DrawRightAlignedString(x+152+gutter, y, 0, strtime);
|
||||
}
|
||||
else if (data.itemrolls && (intertic <= rolltic))
|
||||
{
|
||||
const fixed_t itemlistlen = K_DrawItemList((INT32)(data.num[i]), ((xx+2+slen-xscroll_px) * FRACUNIT), ((y+1) * FRACUNIT));
|
||||
newlist_xpush = max(newlist_xpush, ((x_base+9+slen) * FRACUNIT) + itemlistlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.val[i] == (UINT32_MAX-1))
|
||||
|
|
@ -671,17 +786,20 @@ void Y_IntermissionDrawer(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
y += 18;
|
||||
y += (displayitemrolls) ? ITEMLIST_PLAYER_YOFFSET : 18;
|
||||
|
||||
if (i == NUMFORNEWCOLUMN-1)
|
||||
if ((i % 16) == (((displayitemrolls) ? 2 : 1) * NUMFORNEWCOLUMN) - 1)
|
||||
{
|
||||
y = 41;
|
||||
x += BASEVIDWIDTH/2;
|
||||
x += (newlist_xpush / FRACUNIT);
|
||||
|
||||
newlist_xpush = (BASEVIDWIDTH / 2) * FRACUNIT;
|
||||
}
|
||||
}
|
||||
|
||||
#undef NUMFORNEWCOLUMN
|
||||
}
|
||||
|
||||
listscroll_length = max(0, x - BASEVIDWIDTH) * FRACUNIT;
|
||||
}
|
||||
|
||||
skiptallydrawer:
|
||||
|
|
@ -762,6 +880,53 @@ void Y_Ticker(void)
|
|||
|
||||
intertic++;
|
||||
|
||||
if (listscroll_length && (intertic > (TICRATE * 2)) && (intertic <= rolltic))
|
||||
{
|
||||
|
||||
if (!listscroll_reverse)
|
||||
{
|
||||
if ((xscroll >= listscroll_length))
|
||||
{
|
||||
if (!listscroll_delay)
|
||||
listscroll_delay = ITEMLIST_SCROLLDELAY;
|
||||
}
|
||||
else
|
||||
xscroll = min(listscroll_length, xscroll + ITEMLIST_SCROLLSPEED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((xscroll <= 0))
|
||||
{
|
||||
if (!listscroll_delay)
|
||||
listscroll_delay = ITEMLIST_SCROLLDELAY;
|
||||
}
|
||||
else
|
||||
xscroll = max(0, xscroll - ITEMLIST_SCROLLSPEED);
|
||||
}
|
||||
|
||||
if (listscroll_delay)
|
||||
{
|
||||
listscroll_delay--;
|
||||
|
||||
if (!listscroll_delay)
|
||||
listscroll_reverse = (!listscroll_reverse);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
listscroll_length = 0;
|
||||
listscroll_delay = 0;
|
||||
listscroll_reverse = false;
|
||||
|
||||
if (xscroll > 0)
|
||||
{
|
||||
if (intertic < rolltic)
|
||||
xscroll = max(0, xscroll - ITEMLIST_SCROLLSPEED);
|
||||
else
|
||||
xscroll = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Team scramble code for team match and CTF.
|
||||
// Don't do this if we're going to automatically scramble teams next round.
|
||||
/*if (G_GametypeHasTeams() && cv_teamscramble.value && !cv_scrambleonchange.value && server)
|
||||
|
|
@ -942,7 +1107,7 @@ void Y_StartIntermission(void)
|
|||
if (!timer)
|
||||
{
|
||||
// Prevent a weird bug
|
||||
timer = 1;
|
||||
timer = 1;
|
||||
}
|
||||
else if (nump < 2 && !netgame)
|
||||
{
|
||||
|
|
@ -991,6 +1156,14 @@ void Y_StartIntermission(void)
|
|||
{
|
||||
// Calculate who won
|
||||
Y_CalculateMatchData(0, Y_CompareTime);
|
||||
|
||||
if (data.itemrolls)
|
||||
{
|
||||
rolltic = (15 * TICRATE);
|
||||
|
||||
sorttic += rolltic;
|
||||
timer += rolltic;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2152,3 +2325,7 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level)
|
|||
g_pickedVote = pick;
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
#undef ITEMLIST_PLAYER_YOFFSET
|
||||
#undef ITEMLIST_SCROLLSPEED
|
||||
#undef ITEMLIST_SCROLLDELAY
|
||||
|
|
|
|||
Loading…
Reference in a new issue