mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-24 08:52:33 +00:00
Merge branch 'master' into reloadmap-fix
This commit is contained in:
commit
e97de3d6f3
64 changed files with 762 additions and 335 deletions
|
|
@ -579,7 +579,7 @@ target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
|
|||
|
||||
# Misc. build options from Makefiles
|
||||
if(SRB2_CONFIG_DEBUGMODE)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DRANGECHECK -DPACKETDROP)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DPACKETDROP)
|
||||
endif()
|
||||
if(SRB2_CONFIG_TESTERS)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DTESTERS)
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ consvar_t cv_drawdist_precip = Player("drawdist_precip", "1024").values({
|
|||
{0, "None"},
|
||||
});
|
||||
|
||||
consvar_t cv_drawinput = Player("drawinput", "No").yes_no();
|
||||
consvar_t cv_drawinput = Player("drawinput", "Off").on_off();
|
||||
consvar_t cv_ffloorclip = Player("ffloorclip", "On").on_off();
|
||||
|
||||
consvar_t cv_fpscap = Player("fpscap", "Match refresh rate").values({
|
||||
|
|
@ -873,6 +873,10 @@ consvar_t cv_1pswap = PlayerCheat("1pswap", "1").min_max(1, MAXSPLITSCREENPLAYER
|
|||
consvar_t cv_debugfinishline = PlayerCheat("debugfinishline", "Off").on_off().description("Highlight finish lines, respawn lines, death pits and instakill planes with high contrast colors");
|
||||
consvar_t cv_debughudtracker = PlayerCheat("debughudtracker", "Off").on_off().description("Highlight overlapping HUD tracker blocks");
|
||||
|
||||
#ifdef DEVELOP
|
||||
consvar_t cv_debugprisoncd = PlayerCheat("debugprisoncd", "Off").on_off().description("Always drop a CD from breaking Prisons");
|
||||
#endif
|
||||
|
||||
consvar_t cv_debugrank = PlayerCheat("debugrank", "Off").description("Show GP rank state on the HUD; optionally force a rank grade").values({
|
||||
{0, "Off"},
|
||||
{1, "On"},
|
||||
|
|
@ -890,6 +894,7 @@ consvar_t cv_debugrender_freezebsp = PlayerCheat("debugrender_freezebsp", "Off")
|
|||
consvar_t cv_debugrender_portal = PlayerCheat("debugrender_portal", "Off").on_off().description("Highlight visual portals in red");
|
||||
consvar_t cv_debugrender_spriteclip = PlayerCheat("debugrender_spriteclip", "Off").on_off().description("Let sprites draw through walls");
|
||||
consvar_t cv_debugrender_visplanes = PlayerCheat("debugrender_visplanes", "Off").on_off().description("Highlight the number of visplanes");
|
||||
consvar_t cv_debugvirtualkeyboard = PlayerCheat("debugvirtualkeyboard", "Off").on_off().description("Always show virtual keyboard instead of using real keyboard input.");
|
||||
consvar_t cv_devmode_screen = PlayerCheat("devmode_screen", "1").min_max(1, 4).description("Choose which splitscreen player devmode applies to");
|
||||
consvar_t cv_drawpickups = PlayerCheat("drawpickups", "Yes").yes_no().description("Hide rings, spheres, item capsules, prison capsules (visual only)");
|
||||
|
||||
|
|
@ -926,6 +931,7 @@ consvar_t cv_dummygpdifficulty = MenuDummy("dummygpdifficulty", "Normal").values
|
|||
consvar_t cv_dummygpencore = MenuDummy("dummygpencore", "Off").on_off();
|
||||
|
||||
consvar_t cv_dummyip = MenuDummy("dummyip", "");
|
||||
consvar_t cv_dummyipselect = MenuDummy("dummyipselect", "0").min_max(0, 2);
|
||||
|
||||
extern CV_PossibleValue_t dummykartspeed_cons_t[];
|
||||
consvar_t cv_dummykartspeed = MenuDummy("dummykartspeed", "Gear 2").values(dummykartspeed_cons_t);
|
||||
|
|
@ -951,6 +957,7 @@ void Dummymenuplayer_OnChange(void);
|
|||
consvar_t cv_dummymenuplayer = MenuDummy("dummymenuplayer", "P1").onchange(Dummymenuplayer_OnChange).values({{0, "NOPE"}, {1, "P1"}, {2, "P2"}, {3, "P3"}, {4, "P4"}});
|
||||
|
||||
consvar_t cv_dummyprofileautoroulette = MenuDummy("dummyprofileautoroulette", "Off").on_off();
|
||||
consvar_t cv_dummyprofilefov = MenuDummy("dummyprofilefov", "90").min_max(70, 110);
|
||||
consvar_t cv_dummyprofilelitesteer = MenuDummy("dummyprofilelitesteer", "On").on_off();
|
||||
consvar_t cv_dummyprofilekickstart = MenuDummy("dummyprofilekickstart", "Off").on_off();
|
||||
consvar_t cv_dummyprofilename = MenuDummy("dummyprofilename", "");
|
||||
|
|
|
|||
|
|
@ -1947,7 +1947,7 @@ void D_SRB2Main(void)
|
|||
profile_t *pr = PR_GetProfile(cv_ttlprofilen.value);
|
||||
if (pr != NULL)
|
||||
{
|
||||
INT32 importskin = R_SkinAvailable(pr->skinname);
|
||||
INT32 importskin = R_SkinAvailableEx(pr->skinname, false);
|
||||
if (importskin != -1)
|
||||
{
|
||||
skins[importskin].records.wins = pr->wins;
|
||||
|
|
|
|||
|
|
@ -960,7 +960,7 @@ static void SendNameAndColor(const UINT8 n)
|
|||
|
||||
// check if player has the skin loaded (cv_skin may have
|
||||
// the name of a skin that was available in the previous game)
|
||||
cv_skin[n].value = R_SkinAvailable(cv_skin[n].string);
|
||||
cv_skin[n].value = R_SkinAvailableEx(cv_skin[n].string, false);
|
||||
if ((cv_skin[n].value < 0) || !R_SkinUsable(playernum, cv_skin[n].value, false))
|
||||
{
|
||||
CV_StealthSet(&cv_skin[n], DEFAULTSKIN);
|
||||
|
|
|
|||
|
|
@ -987,11 +987,13 @@ struct player_t
|
|||
|
||||
INT16 incontrol; // -1 to -175 when spinning out or tumbling, 1 to 175 when not. Use to check for combo hits or emergency inputs.
|
||||
UINT16 progressivethrust; // When getting beat up in GTR_BUMPERS, speed up the longer you've been out of control.
|
||||
UINT8 ringvisualwarning; // Check with > 1, not >= 1! Set when put in debt, counts down and holds at 1 when still in debt.
|
||||
|
||||
boolean analoginput; // Has an input been recorded that requires analog usage? For input display.
|
||||
|
||||
boolean markedfordeath;
|
||||
boolean dotrickfx;
|
||||
boolean stingfx;
|
||||
UINT8 bumperinflate;
|
||||
|
||||
UINT8 ringboxdelay; // Delay until Ring Box auto-activates
|
||||
|
|
|
|||
|
|
@ -506,6 +506,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
|
||||
// Prison Egg Drops
|
||||
"S_PRISONEGGDROP_CD",
|
||||
"S_PRISONEGGDROP_FLAREA1",
|
||||
"S_PRISONEGGDROP_FLAREA2",
|
||||
"S_PRISONEGGDROP_FLAREB1",
|
||||
"S_PRISONEGGDROP_FLAREB2",
|
||||
|
||||
// Bubble Source
|
||||
"S_BUBBLES1",
|
||||
|
|
|
|||
|
|
@ -67,12 +67,10 @@ extern "C" {
|
|||
#if !defined (NDEBUG)
|
||||
#define PACKETDROP
|
||||
#define PARANOIA
|
||||
//#define RANGECHECK
|
||||
#define ZDEBUG
|
||||
#endif
|
||||
|
||||
// Uncheck this to compile debugging code
|
||||
#define RANGECHECK
|
||||
//#ifndef PARANOIA
|
||||
//#define PARANOIA // do some tests that never fail but maybe
|
||||
// turn this on by make etc.. DEBUGMODE = 1 or use the Debug profile in the VC++ projects
|
||||
|
|
|
|||
|
|
@ -1345,12 +1345,12 @@ void F_TitleScreenDrawer(void)
|
|||
if (cache_gametrulystarted == true)
|
||||
{
|
||||
const char *eggName = "eggman";
|
||||
INT32 eggSkin = R_SkinAvailable(eggName);
|
||||
INT32 eggSkin = R_SkinAvailableEx(eggName, false);
|
||||
skincolornum_t eggColor = SKINCOLOR_RED;
|
||||
UINT8 *eggColormap = NULL;
|
||||
|
||||
const char *tailsName = "tails";
|
||||
INT32 tailsSkin = R_SkinAvailable(tailsName);
|
||||
INT32 tailsSkin = R_SkinAvailableEx(tailsName, false);
|
||||
skincolornum_t tailsColor = SKINCOLOR_ORANGE;
|
||||
UINT8 *tailsColormap = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -317,8 +317,8 @@ void G_ReadDemoExtraData(void)
|
|||
skinid = READUINT8(demobuf.p);
|
||||
if (skinid >= demo.numskins)
|
||||
skinid = 0;
|
||||
SetPlayerSkinByNum(p, demo.skinlist[skinid].mapping);
|
||||
demo.currentskinid[p] = skinid;
|
||||
ghostext[p].skinid = demo.currentskinid[p] = skinid;
|
||||
SetPlayerSkinByNum(p, skinid);
|
||||
|
||||
players[p].kartspeed = ghostext[p].kartspeed = demo.skinlist[skinid].kartspeed;
|
||||
players[p].kartweight = ghostext[p].kartweight = demo.skinlist[skinid].kartweight;
|
||||
|
|
@ -424,7 +424,7 @@ void G_WriteDemoExtraData(void)
|
|||
{
|
||||
for (j = 0; j < MAXAVAILABILITY; j++)
|
||||
{
|
||||
WRITEUINT8(demobuf.p, players[i].availabilities[i]);
|
||||
WRITEUINT8(demobuf.p, players[i].availabilities[j]);
|
||||
}
|
||||
|
||||
WRITEUINT8(demobuf.p, (UINT8)players[i].bot);
|
||||
|
|
@ -2033,7 +2033,6 @@ static void G_SaveDemoSkins(UINT8 **pp)
|
|||
|
||||
static democharlist_t *G_LoadDemoSkins(savebuffer_t *info, UINT8 *worknumskins, boolean getclosest)
|
||||
{
|
||||
char skin[17];
|
||||
UINT8 i, byte, shif;
|
||||
democharlist_t *skinlist = NULL;
|
||||
|
||||
|
|
@ -2052,8 +2051,6 @@ static democharlist_t *G_LoadDemoSkins(savebuffer_t *info, UINT8 *worknumskins,
|
|||
I_Error("G_LoadDemoSkins: Insufficient memory to allocate list");
|
||||
}
|
||||
|
||||
skin[16] = '\0';
|
||||
|
||||
for (i = 0; i < (*worknumskins); i++)
|
||||
{
|
||||
INT32 result = -1;
|
||||
|
|
@ -2064,12 +2061,14 @@ static democharlist_t *G_LoadDemoSkins(savebuffer_t *info, UINT8 *worknumskins,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
READMEM(info->p, skin, 16);
|
||||
READMEM(info->p, skinlist[i].name, 16);
|
||||
skinlist[i].name[16] = '\0';
|
||||
skinlist[i].namehash = quickncasehash(skinlist[i].name, SKINNAMESIZE);
|
||||
skinlist[i].kartspeed = READUINT8(info->p);
|
||||
skinlist[i].kartweight = READUINT8(info->p);
|
||||
skinlist[i].flags = READUINT32(info->p);
|
||||
|
||||
result = R_SkinAvailable(skin);
|
||||
result = R_SkinAvailableEx(skinlist[i].name, false);
|
||||
if (result == -1)
|
||||
{
|
||||
if (!getclosest)
|
||||
|
|
@ -3354,12 +3353,9 @@ void G_DoPlayDemo(const char *defdemoname)
|
|||
|
||||
// Skin
|
||||
|
||||
i = READUINT8(demobuf.p);
|
||||
if (i >= demo.numskins)
|
||||
i = 0;
|
||||
SetPlayerSkinByNum(p, demo.skinlist[i].mapping);
|
||||
demo.currentskinid[p] = ghostext[p].skinid = i;
|
||||
|
||||
demo.currentskinid[p] = READUINT8(demobuf.p);
|
||||
if (demo.currentskinid[p] >= demo.numskins)
|
||||
demo.currentskinid[p] = 0;
|
||||
lastfakeskin[p] = READUINT8(demobuf.p);
|
||||
|
||||
// Color
|
||||
|
|
@ -3442,6 +3438,15 @@ void G_DoPlayDemo(const char *defdemoname)
|
|||
UINT8 j;
|
||||
|
||||
p = slots[i];
|
||||
|
||||
for (j = 0; j < MAXAVAILABILITY; j++)
|
||||
{
|
||||
players[p].availabilities[j] = availabilities[p][j];
|
||||
}
|
||||
|
||||
ghostext[p].skinid = demo.currentskinid[p];
|
||||
SetPlayerSkinByNum(p, demo.currentskinid[p]);
|
||||
|
||||
if (players[p].mo)
|
||||
{
|
||||
players[p].mo->color = players[p].skincolor;
|
||||
|
|
@ -3457,11 +3462,6 @@ void G_DoPlayDemo(const char *defdemoname)
|
|||
players[p].kartweight = ghostext[p].kartweight = demo.skinlist[demo.currentskinid[p]].kartweight;
|
||||
players[p].charflags = ghostext[p].charflags = demo.skinlist[demo.currentskinid[p]].flags;
|
||||
players[p].lastfakeskin = lastfakeskin[p];
|
||||
|
||||
for (j = 0; j < MAXAVAILABILITY; j++)
|
||||
{
|
||||
players[p].availabilities[j] = availabilities[p][j];
|
||||
}
|
||||
}
|
||||
|
||||
demo.deferstart = true;
|
||||
|
|
@ -3591,7 +3591,7 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
|
|||
// Skip unlockables
|
||||
{
|
||||
UINT32 unlockables = READUINT32(p);
|
||||
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
|
||||
p += unlockables;
|
||||
}
|
||||
|
||||
p++; // mapmusrng
|
||||
|
|
@ -3814,7 +3814,7 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
|
|||
// Skip unlockables
|
||||
{
|
||||
UINT32 unlockables = READUINT32(p);
|
||||
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
|
||||
p += unlockables;
|
||||
}
|
||||
|
||||
p++; // mapmusrng
|
||||
|
|
@ -4131,7 +4131,6 @@ boolean G_CheckDemoTitleEntry(void)
|
|||
|
||||
demo.willsave = true;
|
||||
M_OpenVirtualKeyboard(
|
||||
false,
|
||||
sizeof demo.titlename,
|
||||
[](const char* replace) -> const char*
|
||||
{
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality;
|
|||
extern tic_t demostarttime;
|
||||
|
||||
struct democharlist_t {
|
||||
char name[17];
|
||||
UINT32 namehash;
|
||||
UINT8 mapping; // No, this isn't about levels. It maps to loaded character ID.
|
||||
UINT8 kartspeed;
|
||||
UINT8 kartweight;
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ void srb2::load_ng_gamedata()
|
|||
|
||||
for (auto& skinpair : js.skins)
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(skinpair.first.c_str());
|
||||
INT32 skin = R_SkinAvailableEx(skinpair.first.c_str(), false);
|
||||
skinrecord_t dummyrecord {};
|
||||
dummyrecord.wins = skinpair.second.records.wins;
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ void srb2::load_ng_gamedata()
|
|||
dummywindata[j].best_skin.id = MAXSKINS;
|
||||
dummywindata[j].best_skin.unloaded = nullptr;
|
||||
|
||||
int skinloaded = R_SkinAvailable(cuppair.second.records[j].bestskin.c_str());
|
||||
int skinloaded = R_SkinAvailableEx(cuppair.second.records[j].bestskin.c_str(), false);
|
||||
if (skinloaded >= 0)
|
||||
{
|
||||
dummywindata[j].best_skin.id = skinloaded;
|
||||
|
|
|
|||
|
|
@ -418,6 +418,12 @@ static INT32 AssignDeviceToFirstUnassignedPlayer(INT32 device)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void update_vkb_axis(INT32 axis)
|
||||
{
|
||||
if (axis > JOYAXISRANGE/2)
|
||||
M_SwitchVirtualKeyboard(true);
|
||||
}
|
||||
|
||||
//
|
||||
// Remaps the inputs to game controls.
|
||||
//
|
||||
|
|
@ -460,6 +466,8 @@ void G_MapEventsToControls(event_t *ev)
|
|||
case ev_keydown:
|
||||
if (ev->data1 < NUMINPUTS)
|
||||
{
|
||||
M_MenuTypingInput(ev->data1);
|
||||
|
||||
if (ev->data2) // OS repeat? We handle that ourselves
|
||||
{
|
||||
break;
|
||||
|
|
@ -556,11 +564,13 @@ void G_MapEventsToControls(event_t *ev)
|
|||
if (ev->data2 != INT32_MAX)
|
||||
{
|
||||
DeviceGameKeyDownArray[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2)] = max(0, ev->data2);
|
||||
update_vkb_axis(max(0, ev->data2));
|
||||
}
|
||||
|
||||
if (ev->data3 != INT32_MAX)
|
||||
{
|
||||
DeviceGameKeyDownArray[KEY_AXIS1 + (JOYANALOGS * 4) + (i * 2) + 1] = max(0, ev->data3);
|
||||
update_vkb_axis(max(0, ev->data3));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -592,6 +602,7 @@ void G_MapEventsToControls(event_t *ev)
|
|||
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4)] = 0;
|
||||
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 1] = abs(ev->data2);
|
||||
}
|
||||
update_vkb_axis(abs(ev->data2));
|
||||
}
|
||||
|
||||
if (ev->data3 != INT32_MAX)
|
||||
|
|
@ -608,6 +619,7 @@ void G_MapEventsToControls(event_t *ev)
|
|||
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 2] = 0;
|
||||
DeviceGameKeyDownArray[KEY_AXIS1 + (i * 4) + 3] = abs(ev->data3);
|
||||
}
|
||||
update_vkb_axis(abs(ev->data3));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -4740,10 +4740,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tr_y = FIXED_TO_FLOAT(interp.y);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
I_Error("HWR_ProjectSprite: invalid sprite number %i ", thing->sprite);
|
||||
#endif
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "HWR_ProjectSprite: invalid sprite number %i\n", thing->sprite);
|
||||
return;
|
||||
}
|
||||
|
||||
rot = thing->frame&FF_FRAMEMASK;
|
||||
|
||||
|
|
@ -5184,22 +5185,20 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
// decide which patch to use for sprite relative to player
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite number %i ",
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite number %i\n",
|
||||
thing->sprite);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
sprdef = &sprites[thing->sprite];
|
||||
|
||||
if ((size_t)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s",
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s\n",
|
||||
thing->sprite, thing->frame, sprnames[thing->sprite]);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
|
||||
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ void HWR_InitModels(void)
|
|||
|
||||
addskinmodel:
|
||||
// add player model
|
||||
s = R_SkinAvailable(skinname);
|
||||
s = R_SkinAvailableEx(skinname, false);
|
||||
if (s != -1)
|
||||
{
|
||||
md2_playermodels[s].skin = s;
|
||||
|
|
|
|||
|
|
@ -1013,6 +1013,10 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Prison Egg Drops
|
||||
{SPR_ALTM, 0|FF_PAPERSPRITE|FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PRISONEGGDROP_CD
|
||||
{SPR_LENS, 14|FF_FULLBRIGHT|FF_ADD|FF_TRANS10, 1, {NULL}, 0, 0, S_PRISONEGGDROP_FLAREA2}, // S_PRISONEGGDROP_FLAREA1
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_PRISONEGGDROP_FLAREA1}, // S_PRISONEGGDROP_FLAREA2
|
||||
{SPR_LENS, 11|FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE, 16, {NULL}, 7, 2, S_PRISONEGGDROP_FLAREB2}, // S_PRISONEGGDROP_FLAREB1
|
||||
{SPR_LENS, 19|FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE, 6, {NULL}, 1, 2, S_NULL}, // S_PRISONEGGDROP_FLAREB2
|
||||
|
||||
// Bubble Source
|
||||
{SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1
|
||||
|
|
|
|||
|
|
@ -1499,6 +1499,10 @@ typedef enum state
|
|||
|
||||
// Prison Egg Drops
|
||||
S_PRISONEGGDROP_CD,
|
||||
S_PRISONEGGDROP_FLAREA1,
|
||||
S_PRISONEGGDROP_FLAREA2,
|
||||
S_PRISONEGGDROP_FLAREB1,
|
||||
S_PRISONEGGDROP_FLAREB2,
|
||||
|
||||
// Bubble Source
|
||||
S_BUBBLES1,
|
||||
|
|
|
|||
|
|
@ -177,12 +177,12 @@ void K_UpdateMatchRaceBots(void)
|
|||
UINT8 numbots = 0;
|
||||
UINT8 numwaiting = 0;
|
||||
SINT8 wantedbots = 0;
|
||||
UINT8 usableskins = 0;
|
||||
UINT8 usableskins = 0, skincount = (demo.playback ? demo.numskins : numskins);;
|
||||
UINT8 grabskins[MAXSKINS+1];
|
||||
UINT8 i;
|
||||
|
||||
// Init usable bot skins list
|
||||
for (i = 0; i < numskins; i++)
|
||||
for (i = 0; i < skincount; i++)
|
||||
{
|
||||
grabskins[usableskins++] = i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void K_InitGrandPrixBots(void)
|
|||
UINT8 numplayers = 0;
|
||||
UINT8 competitors[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
UINT8 usableskins;
|
||||
UINT8 usableskins, skincount = (demo.playback ? demo.numskins : numskins);;
|
||||
UINT8 grabskins[MAXSKINS+1];
|
||||
|
||||
UINT8 botskinlist[MAXPLAYERS];
|
||||
|
|
@ -146,7 +146,7 @@ void K_InitGrandPrixBots(void)
|
|||
memset(botskinlist, defaultbotskin, sizeof (botskinlist));
|
||||
|
||||
// Init usable bot skins list
|
||||
for (usableskins = 0; usableskins < numskins; usableskins++)
|
||||
for (usableskins = 0; usableskins < skincount; usableskins++)
|
||||
{
|
||||
grabskins[usableskins] = usableskins;
|
||||
}
|
||||
|
|
@ -671,7 +671,7 @@ void K_RetireBots(void)
|
|||
const UINT8 defaultbotskin = R_BotDefaultSkin();
|
||||
SINT8 newDifficulty;
|
||||
|
||||
UINT8 usableskins;
|
||||
UINT8 usableskins, skincount = (demo.playback ? demo.numskins : numskins);
|
||||
UINT8 grabskins[MAXSKINS+1];
|
||||
|
||||
UINT8 i;
|
||||
|
|
@ -687,7 +687,7 @@ void K_RetireBots(void)
|
|||
}
|
||||
|
||||
// Init usable bot skins list
|
||||
for (usableskins = 0; usableskins < numskins; usableskins++)
|
||||
for (usableskins = 0; usableskins < skincount; usableskins++)
|
||||
{
|
||||
grabskins[usableskins] = usableskins;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ patch_t *kp_facenum[MAXPLAYERS+1];
|
|||
static patch_t *kp_facehighlight[8];
|
||||
|
||||
static patch_t *kp_nocontestminimap;
|
||||
static patch_t *kp_unknownminimap;
|
||||
static patch_t *kp_spbminimap;
|
||||
static patch_t *kp_wouldyoustillcatchmeifiwereaworm;
|
||||
static patch_t *kp_catcherminimap;
|
||||
|
|
@ -386,7 +387,7 @@ void K_LoadKartHUDGraphics(void)
|
|||
|
||||
// Special minimap icons
|
||||
HU_UpdatePatch(&kp_nocontestminimap, "MINIDEAD");
|
||||
|
||||
HU_UpdatePatch(&kp_unknownminimap, "HUHMAP");
|
||||
HU_UpdatePatch(&kp_spbminimap, "SPBMMAP");
|
||||
|
||||
HU_UpdatePatch(&kp_wouldyoustillcatchmeifiwereaworm, "MINIPROG");
|
||||
|
|
@ -2957,7 +2958,19 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
|
|||
rn[0] = ((abs(stplyr->hudrings) / 10) % 10);
|
||||
rn[1] = (abs(stplyr->hudrings) % 10);
|
||||
|
||||
if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt
|
||||
if (stplyr->hudrings <= 0 && stplyr->ringvisualwarning > 1)
|
||||
{
|
||||
colorring = true;
|
||||
if ((leveltime/2 & 1))
|
||||
{
|
||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
|
||||
}
|
||||
}
|
||||
else if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt
|
||||
{
|
||||
ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE);
|
||||
colorring = true;
|
||||
|
|
@ -3068,16 +3081,24 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
|
|||
|
||||
V_DrawMappedPatch(LAPS_X+ringx+7, fy-5, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_ring[ringanim_realframe], (colorring ? ringmap : NULL));
|
||||
|
||||
// "Why fy-4? Why LAPS_X+29+1?"
|
||||
// "use magic numbers" - jartha 2024-03-05
|
||||
if (stplyr->hudrings < 0) // Draw the minus for ring debt
|
||||
{
|
||||
V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminus, ringmap);
|
||||
V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[0]], ringmap);
|
||||
V_DrawMappedPatch(LAPS_X+35, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[1]], ringmap);
|
||||
V_DrawMappedPatch(LAPS_X+23-1, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminus, ringmap);
|
||||
using srb2::Draw;
|
||||
Draw row = Draw(LAPS_X+29+0, fy-4).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kThinTimer).colormap(ringmap);
|
||||
row.text("{:02}", abs(stplyr->hudrings));
|
||||
// V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[0]], ringmap);
|
||||
// V_DrawMappedPatch(LAPS_X+35, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[1]], ringmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[0]], ringmap);
|
||||
V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[1]], ringmap);
|
||||
using srb2::Draw;
|
||||
Draw row = Draw(LAPS_X+23+3, fy-4).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kThinTimer).colormap(ringmap);
|
||||
row.text("{:02}", abs(stplyr->hudrings));
|
||||
// V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[0]], ringmap);
|
||||
// V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[1]], ringmap);
|
||||
}
|
||||
|
||||
// SPB ring lock
|
||||
|
|
@ -4401,6 +4422,9 @@ static void K_drawKartMinimap(void)
|
|||
skin = ((skin_t*)g->mo->skin)-skins;
|
||||
else
|
||||
skin = 0;
|
||||
|
||||
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
|
||||
|
||||
if (g->mo->color)
|
||||
{
|
||||
if (g->mo->colorized)
|
||||
|
|
@ -4414,7 +4438,7 @@ static void K_drawKartMinimap(void)
|
|||
interpx = R_InterpolateFixed(g->mo->old_x, g->mo->x);
|
||||
interpy = R_InterpolateFixed(g->mo->old_y, g->mo->y);
|
||||
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap);
|
||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap);
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
|
|
@ -4470,7 +4494,7 @@ static void K_drawKartMinimap(void)
|
|||
{
|
||||
skin = ((skin_t*)mobj->skin)-skins;
|
||||
|
||||
workingPic = faceprefix[skin][FACE_MINIMAP];
|
||||
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
|
||||
|
||||
if (mobj->color)
|
||||
{
|
||||
|
|
@ -4666,7 +4690,7 @@ static void K_drawKartMinimap(void)
|
|||
{
|
||||
skin = ((skin_t*)mobj->skin)-skins;
|
||||
|
||||
workingPic = faceprefix[skin][FACE_MINIMAP];
|
||||
workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap;
|
||||
|
||||
if (mobj->color)
|
||||
{
|
||||
|
|
|
|||
67
src/k_kart.c
67
src/k_kart.c
|
|
@ -4819,6 +4819,12 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source)
|
|||
player->spinouttimer = length;
|
||||
player->wipeoutslow = min(length-1, wipeoutslowtime+1);
|
||||
|
||||
player->ringvisualwarning = TICRATE*2;
|
||||
player->stingfx = true;
|
||||
|
||||
if (P_IsDisplayPlayer(player))
|
||||
S_StartSoundAtVolume(NULL, sfx_sting0, 200);
|
||||
|
||||
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
||||
}
|
||||
|
||||
|
|
@ -8095,7 +8101,7 @@ void K_KartPlayerHUDUpdate(player_t *player)
|
|||
else
|
||||
player->karthud[khud_finish] = 0;
|
||||
|
||||
if (demo.playback == false && P_IsLocalPlayer(player) == true)
|
||||
if (demo.playback == false && P_IsMachineLocalPlayer(player) == true)
|
||||
{
|
||||
if (player->tumbleBounces != 0 && gamedata->totaltumbletime != UINT32_MAX)
|
||||
{
|
||||
|
|
@ -8423,20 +8429,38 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
// Battle: spawn zero-bumpers indicator
|
||||
if ((gametyperules & GTR_SPHERES) ? player->mo->health <= 1 : player->rings <= 0)
|
||||
{
|
||||
mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy,
|
||||
player->mo->z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale), MT_THOK);
|
||||
UINT8 doubler;
|
||||
|
||||
P_SetMobjState(debtflag, S_RINGDEBT);
|
||||
P_SetScale(debtflag, (debtflag->destscale = player->mo->scale));
|
||||
// GROSS. In order to have a transparent version of this for a splitscreen local player, we actually need to spawn two!
|
||||
for (doubler = 0; doubler < 2; doubler++)
|
||||
{
|
||||
mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy,
|
||||
player->mo->z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale), MT_THOK);
|
||||
|
||||
K_MatchGenericExtraFlags(debtflag, player->mo);
|
||||
debtflag->frame += (leveltime % 4);
|
||||
P_SetMobjState(debtflag, S_RINGDEBT);
|
||||
P_SetScale(debtflag, (debtflag->destscale = player->mo->scale));
|
||||
|
||||
if ((leveltime/12) & 1)
|
||||
debtflag->frame += 4;
|
||||
K_MatchGenericExtraFlags(debtflag, player->mo);
|
||||
debtflag->frame += (leveltime % 4);
|
||||
|
||||
debtflag->color = player->skincolor;
|
||||
debtflag->fuse = 2;
|
||||
if ((leveltime/12) & 1)
|
||||
debtflag->frame += 4;
|
||||
|
||||
debtflag->color = player->skincolor;
|
||||
debtflag->fuse = 2;
|
||||
|
||||
if (doubler == 0) // Real copy. Draw for everyone but us.
|
||||
{
|
||||
debtflag->renderflags |= K_GetPlayerDontDrawFlag(player);
|
||||
}
|
||||
else if (doubler == 1) // Fake copy. Draw for only us, and go transparent after a bit.
|
||||
{
|
||||
debtflag->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
|
||||
if (player->ringvisualwarning <= 1 || gametyperules & GTR_SPHERES)
|
||||
debtflag->renderflags |= RF_TRANS50;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (player->springstars && (leveltime & 1))
|
||||
|
|
@ -8960,6 +8984,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->dotrickfx = false;
|
||||
}
|
||||
|
||||
if (player->stingfx && !player->mo->hitlag)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s226l);
|
||||
player->stingfx = false;
|
||||
}
|
||||
|
||||
// Don't screw up chain ring pickup/usage with instawhip charge.
|
||||
// If the button stays held, delay charge a bit.
|
||||
if (player->instaWhipChargeLockout)
|
||||
|
|
@ -9024,6 +9054,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->incontrol++;
|
||||
}
|
||||
|
||||
if (player->rings <= 0)
|
||||
{
|
||||
if (player->ringvisualwarning > 1)
|
||||
player->ringvisualwarning--;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->ringvisualwarning = 0;
|
||||
}
|
||||
|
||||
if (player->ringvisualwarning == 0 && player->rings <= 0)
|
||||
{
|
||||
player->ringvisualwarning = 6*TICRATE/2;
|
||||
}
|
||||
|
||||
player->incontrol = min(player->incontrol, 5*TICRATE);
|
||||
player->incontrol = max(player->incontrol, -5*TICRATE);
|
||||
|
||||
|
|
|
|||
27
src/k_menu.h
27
src/k_menu.h
|
|
@ -295,10 +295,26 @@ extern menu_t PLAY_MP_OptSelectDef;
|
|||
|
||||
typedef enum
|
||||
{
|
||||
mp_host = 0,
|
||||
mp_browse,
|
||||
mp_directjoin,
|
||||
mp_back,
|
||||
} mp_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
mhost_gametype = 0,
|
||||
mhost_gameplay_options,
|
||||
mhost_server_options,
|
||||
mhost_boxend,
|
||||
mhost_mapselect = mhost_boxend,
|
||||
mhost_back,
|
||||
|
||||
// TODO, remove these (old code)
|
||||
mhost_sname = 0,
|
||||
mhost_public,
|
||||
mhost_maxp,
|
||||
mhost_gametype,
|
||||
//mhost_gametype,
|
||||
mhost_go,
|
||||
} mhost_e;
|
||||
|
||||
|
|
@ -686,9 +702,10 @@ void M_PlayMenuJam(void);
|
|||
|
||||
boolean M_ConsiderSealedSwapAlert(void);
|
||||
|
||||
void M_OpenVirtualKeyboard(boolean gamepad, size_t cachelen, vkb_query_fn_t queryfn, menu_t *dummymenu);
|
||||
void M_OpenVirtualKeyboard(size_t cachelen, vkb_query_fn_t queryfn, menu_t *dummymenu);
|
||||
void M_AbortVirtualKeyboard(void);
|
||||
void M_MenuTypingInput(INT32 key);
|
||||
void M_SwitchVirtualKeyboard(boolean gamepad);
|
||||
|
||||
void M_QuitResponse(INT32 ch);
|
||||
void M_QuitSRB2(INT32 choice);
|
||||
|
|
@ -1047,6 +1064,7 @@ extern consvar_t cv_dummyprofilekickstart;
|
|||
extern consvar_t cv_dummyprofileautoroulette;
|
||||
extern consvar_t cv_dummyprofilelitesteer;
|
||||
extern consvar_t cv_dummyprofilerumble;
|
||||
extern consvar_t cv_dummyprofilefov;
|
||||
|
||||
void M_ResetOptions(void);
|
||||
void M_InitOptions(INT32 choice); // necessary for multiplayer since there's some options we won't want to access
|
||||
|
|
@ -1057,6 +1075,8 @@ void M_OptionsChangeBGColour(INT16 newcolour); // changes the background colour
|
|||
|
||||
void M_VideoOptions(INT32 choice);
|
||||
void M_SoundOptions(INT32 choice);
|
||||
void M_GameplayOptions(INT32 choice);
|
||||
void M_ServerOptions(INT32 choice);
|
||||
|
||||
void M_HandleItemToggles(INT32 choice); // For item toggling
|
||||
void M_EraseData(INT32 choice); // For data erasing
|
||||
|
|
@ -1090,6 +1110,9 @@ void M_HandleVideoModes(INT32 ch);
|
|||
// data stuff
|
||||
void M_HandleProfileErase(INT32 choice);
|
||||
|
||||
// Draws "List via" at the bottom of the screen.
|
||||
void M_DrawMasterServerReminder(void);
|
||||
|
||||
// Draws the EGGA CHANNEL background.
|
||||
void M_DrawEggaChannel(void);
|
||||
|
||||
|
|
|
|||
105
src/k_menudraw.c
105
src/k_menudraw.c
|
|
@ -345,7 +345,7 @@ UINT16 M_GetCvPlayerColor(UINT8 pnum)
|
|||
if (color != SKINCOLOR_NONE)
|
||||
return color;
|
||||
|
||||
INT32 skin = R_SkinAvailable(cv_skin[pnum].string);
|
||||
INT32 skin = R_SkinAvailableEx(cv_skin[pnum].string, false);
|
||||
if (skin == -1)
|
||||
return SKINCOLOR_NONE;
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ static void M_DrawMenuParty(void)
|
|||
// Despite the work put into it, can't use M_GetCvPlayerColor directly - we need to reference skin always.
|
||||
#define grab_skin_and_colormap(pnum) \
|
||||
{ \
|
||||
skin = R_SkinAvailable(cv_skin[pnum].string); \
|
||||
skin = R_SkinAvailableEx(cv_skin[pnum].string, false); \
|
||||
color = cv_playercolor[pnum].value; \
|
||||
if (skin == -1) \
|
||||
skin = 0; \
|
||||
|
|
@ -999,12 +999,12 @@ void M_Drawer(void)
|
|||
F_VersionDrawer();
|
||||
}
|
||||
|
||||
// Draw message overlay when needed
|
||||
M_DrawMenuMessage();
|
||||
|
||||
// Draw typing overlay when needed, above all other menu elements.
|
||||
if (menutyping.active)
|
||||
M_DrawMenuTyping();
|
||||
|
||||
// Draw message overlay when needed
|
||||
M_DrawMenuMessage();
|
||||
}
|
||||
|
||||
if (menuwipe)
|
||||
|
|
@ -1222,6 +1222,38 @@ void M_DrawGenericMenu(void)
|
|||
|
||||
static tic_t gm_flipStart;
|
||||
|
||||
static INT32 M_DrawRejoinIP(INT32 x, INT32 y, INT32 tx)
|
||||
{
|
||||
extern consvar_t cv_dummyipselect;
|
||||
char (*ip)[MAX_LOGIP] = joinedIPlist[cv_dummyipselect.value];
|
||||
if (!*ip[0])
|
||||
return 0;
|
||||
|
||||
INT16 shift = 20;
|
||||
x -= shift;
|
||||
|
||||
INT16 j = 0;
|
||||
for (j=0; j <= (GM_YOFFSET + 10) / 2; j++)
|
||||
{
|
||||
// Draw rectangles that look like the current selected item starting from the top of the actual selection graphic and going up to where it's supposed to go.
|
||||
// With colour 169 (that's the index of the shade of black the plague colourization gives us. ...No I don't like using a magic number either.
|
||||
V_DrawFill((x-1) + j, y + (2*j), 226, 2, 169);
|
||||
}
|
||||
|
||||
x += GM_XOFFSET + 14;
|
||||
y += GM_YOFFSET;
|
||||
|
||||
const char *text = ip[0];
|
||||
INT32 w = V_ThinStringWidth(text, 0);
|
||||
INT32 f = highlightflags;
|
||||
V_DrawMenuString(x - 10 - (skullAnimCounter/5), y, f, "\x1C"); // left arrow
|
||||
V_DrawMenuString(x + w + 2+ (skullAnimCounter/5), y, f, "\x1D"); // right arrow
|
||||
V_DrawThinString(x, y, f, text);
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH + 4 + tx, y, V_ORANGEMAP, "\xAC Rejoin");
|
||||
|
||||
return shift;
|
||||
}
|
||||
|
||||
//
|
||||
// M_DrawKartGamemodeMenu
|
||||
//
|
||||
|
|
@ -1266,10 +1298,19 @@ void M_DrawKartGamemodeMenu(void)
|
|||
}
|
||||
|
||||
INT32 cx = x;
|
||||
boolean selected = (i == itemOn && menutransition.tics == menutransition.dest);
|
||||
|
||||
if (i == itemOn && menutransition.tics == menutransition.dest)
|
||||
if (selected)
|
||||
{
|
||||
cx -= Easing_OutSine(M_DueFrac(gm_flipStart, GM_FLIPTIME), 0, GM_XOFFSET / 2);
|
||||
fixed_t f = M_DueFrac(gm_flipStart, GM_FLIPTIME);
|
||||
cx -= Easing_OutSine(f, 0, (GM_XOFFSET / 2));
|
||||
|
||||
// Direct Join
|
||||
if (currentMenu == &PLAY_MP_OptSelectDef && i == mp_directjoin)
|
||||
{
|
||||
INT32 shift = M_DrawRejoinIP(cx, y, cx - x);
|
||||
cx -= Easing_OutSine(f, 0, shift);
|
||||
}
|
||||
}
|
||||
|
||||
type = (currentMenu->menuitems[i].status & IT_DISPLAY);
|
||||
|
|
@ -1281,7 +1322,7 @@ void M_DrawKartGamemodeMenu(void)
|
|||
{
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
if (i == itemOn && menutransition.tics == menutransition.dest)
|
||||
if (selected)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
||||
}
|
||||
|
|
@ -2277,7 +2318,7 @@ void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
|
|||
if (p != NULL && p->version)
|
||||
{
|
||||
truecol = p->color;
|
||||
skinnum = R_SkinAvailable(p->skinname);
|
||||
skinnum = R_SkinAvailableEx(p->skinname, false);
|
||||
strcpy(pname, p->profilename);
|
||||
}
|
||||
|
||||
|
|
@ -2550,7 +2591,7 @@ void M_DrawRaceDifficulty(void)
|
|||
|
||||
for (i = 0; i < currentMenu->numitems; i++)
|
||||
{
|
||||
if (i >= drace_boxend)
|
||||
if (i >= currentMenu->extra1)
|
||||
{
|
||||
x = GM_STARTX + (GM_XOFFSET * 5 / 2);
|
||||
y = GM_STARTY + (GM_YOFFSET * 5 / 2);
|
||||
|
|
@ -2615,7 +2656,7 @@ void M_DrawRaceDifficulty(void)
|
|||
{
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
||||
|
||||
if (i >= drace_boxend)
|
||||
if (i >= currentMenu->extra1)
|
||||
{
|
||||
cx -= Easing_OutSine(M_DueFrac(gm_flipStart, GM_FLIPTIME), 0, GM_XOFFSET / 2);
|
||||
}
|
||||
|
|
@ -2626,17 +2667,21 @@ void M_DrawRaceDifficulty(void)
|
|||
}
|
||||
|
||||
|
||||
if (currentMenu->menuitems[i].status & IT_CVAR)
|
||||
if (currentMenu->menuitems[i].status & (IT_CVAR | IT_ARROWS))
|
||||
{
|
||||
|
||||
INT32 fx = (cx - tx);
|
||||
INT32 centx = fx + (320-fx)/2 + (tx); // undo the menutransition movement to redo it here otherwise the text won't move at the same speed lole.
|
||||
|
||||
// implicitely we'll only take care of normal consvars
|
||||
consvar_t *cv = currentMenu->menuitems[i].itemaction.cvar;
|
||||
const char *val = currentMenu->menuitems[i].text;
|
||||
if (currentMenu->menuitems[i].status & IT_CVAR)
|
||||
{
|
||||
consvar_t *cv = currentMenu->menuitems[i].itemaction.cvar;
|
||||
val = cv->string;
|
||||
}
|
||||
|
||||
V_DrawFixedPatch(cx*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, W_CachePatchName("MENUSHRT", PU_CACHE), colormap);
|
||||
V_DrawCenteredGamemodeString(centx, y - 3, 0, colormap, cv->string);
|
||||
V_DrawCenteredGamemodeString(centx, y - 3, 0, colormap, val);
|
||||
|
||||
if (i == itemOn)
|
||||
{
|
||||
|
|
@ -2656,7 +2701,7 @@ void M_DrawRaceDifficulty(void)
|
|||
x += GM_XOFFSET;
|
||||
y += GM_YOFFSET;
|
||||
|
||||
if (i < drace_boxend)
|
||||
if (i < currentMenu->extra1)
|
||||
{
|
||||
y += 2; // extra spacing for Match Race options
|
||||
}
|
||||
|
|
@ -3715,7 +3760,7 @@ void M_DrawTimeAttack(void)
|
|||
|
||||
// NOTE: This is pretty rigid and only intended for use with the multiplayer options menu which has *3* choices.
|
||||
|
||||
static void M_DrawMasterServerReminder(void)
|
||||
void M_DrawMasterServerReminder(void)
|
||||
{
|
||||
// Did you change the Server Browser address? Have a little reminder.
|
||||
|
||||
|
|
@ -3725,7 +3770,7 @@ static void M_DrawMasterServerReminder(void)
|
|||
else
|
||||
mservflags = warningflags;
|
||||
|
||||
INT32 y = BASEVIDHEIGHT - 24;
|
||||
INT32 y = BASEVIDHEIGHT - 10;
|
||||
|
||||
V_DrawFadeFill(0, y-1, BASEVIDWIDTH, 10+1, 0, 31, 5);
|
||||
V_DrawCenteredThinString(BASEVIDWIDTH/2, y,
|
||||
|
|
@ -3785,7 +3830,7 @@ void M_DrawEggaChannel(void)
|
|||
patch_t *background = W_CachePatchName("M_EGGACH", PU_CACHE);
|
||||
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 25);
|
||||
V_DrawFixedPatch(160<<FRACBITS, 104<<FRACBITS, FRACUNIT, 0, background, NULL);
|
||||
V_DrawFixedPatch((menuactive ? 75 : 160)<<FRACBITS, 104<<FRACBITS, FRACUNIT, 0, background, NULL);
|
||||
V_DrawVhsEffect(false); // VHS the background! (...sorry OGL my love)
|
||||
}
|
||||
|
||||
|
|
@ -4119,6 +4164,13 @@ static void M_DrawServerCountAndHorizontalBar(void)
|
|||
|
||||
void M_DrawMPServerBrowser(void)
|
||||
{
|
||||
const char *header[3][2] = {
|
||||
{"Server Browser", "BG_MPS1"},
|
||||
{"Core Servers", "BG_MPS1"},
|
||||
{"Modded Servers", "BG_MPS2"},
|
||||
};
|
||||
int mode = M_SecretUnlocked(SECRET_ADDONS, true) ? (mpmenu.room ? 2 : 1) : 0;
|
||||
|
||||
patch_t *text1 = W_CachePatchName("MENUBGT1", PU_CACHE);
|
||||
patch_t *text2 = W_CachePatchName("MENUBGT2", PU_CACHE);
|
||||
|
||||
|
|
@ -4138,7 +4190,7 @@ void M_DrawMPServerBrowser(void)
|
|||
UINT8 i;
|
||||
|
||||
// background stuff
|
||||
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("BG_MPS3", PU_CACHE), NULL);
|
||||
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName(header[mode][1], PU_CACHE), NULL);
|
||||
|
||||
V_DrawFixedPatch(0, (BASEVIDHEIGHT + 16) * FRACUNIT, FRACUNIT, V_TRANSLUCENT, W_CachePatchName("MENUBG2", PU_CACHE), NULL);
|
||||
|
||||
|
|
@ -4212,12 +4264,7 @@ void M_DrawMPServerBrowser(void)
|
|||
V_DrawFill(0, 53, 320, 1, 31);
|
||||
V_DrawFill(0, 55, 320, 1, 31);
|
||||
|
||||
const char *headertext;
|
||||
if (M_SecretUnlocked(SECRET_ADDONS, true))
|
||||
headertext = va("%s Servers", mpmenu.room ? "Modded" : "Core");
|
||||
else
|
||||
headertext = "Server Browser";
|
||||
V_DrawCenteredGamemodeString(160, 2, 0, 0, headertext);
|
||||
V_DrawCenteredGamemodeString(160, 2, 0, 0, header[mode][0]);
|
||||
|
||||
// normal menu options
|
||||
M_DrawGenericMenu();
|
||||
|
|
@ -6516,7 +6563,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
|
|||
INT32 skin = M_UnlockableFollowerNum(ref);
|
||||
if (skin != -1)
|
||||
{
|
||||
INT32 psk = R_SkinAvailable(cv_skin[0].string);
|
||||
INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? &skins[psk] : &skins[0]);
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
pat = W_CachePatchName(followers[skin].icon, PU_CACHE);
|
||||
|
|
@ -6775,7 +6822,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
}
|
||||
case SECRET_FOLLOWER:
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(cv_skin[0].string);
|
||||
INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
INT32 fskin = M_UnlockableFollowerNum(ref);
|
||||
|
||||
// Draw proximity reference for character
|
||||
|
|
@ -6806,7 +6853,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
INT32 colorid = M_UnlockableColorNum(ref);
|
||||
if (colorid == SKINCOLOR_NONE)
|
||||
break;
|
||||
INT32 skin = R_SkinAvailable(cv_skin[0].string);
|
||||
INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
if (skin == -1)
|
||||
skin = 0;
|
||||
colormap = R_GetTranslationColormap(skin, colorid, GTC_MENUCACHE);
|
||||
|
|
|
|||
|
|
@ -275,8 +275,6 @@ static boolean M_GamestateCanOpenMenu(void)
|
|||
//
|
||||
boolean M_Responder(event_t *ev)
|
||||
{
|
||||
boolean menuKeyJustChanged = false;
|
||||
|
||||
if (dedicated
|
||||
|| (demo.playback && demo.attract)
|
||||
|| M_GamestateCanOpenMenu() == false)
|
||||
|
|
@ -311,7 +309,6 @@ boolean M_Responder(event_t *ev)
|
|||
{
|
||||
// Record keyboard presses
|
||||
menuKey = ev->data1;
|
||||
menuKeyJustChanged = true;
|
||||
}
|
||||
|
||||
// Profiles: Control mapping.
|
||||
|
|
@ -457,12 +454,6 @@ boolean M_Responder(event_t *ev)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Typing for CV_IT_STRING
|
||||
if (menuKeyJustChanged && menutyping.active && !menutyping.menutypingclose && menutyping.keyboardtyping)
|
||||
{
|
||||
M_ChangeStringCvar(menuKey);
|
||||
}
|
||||
|
||||
// We're in the menu itself now.
|
||||
// M_Ticker will take care of the rest.
|
||||
return true;
|
||||
|
|
@ -1097,7 +1088,7 @@ static void M_HandleMenuInput(void)
|
|||
// Typing for CV_IT_STRING
|
||||
if (menutyping.active)
|
||||
{
|
||||
M_MenuTypingInput(thisMenuKey);
|
||||
M_MenuTypingInput(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1136,7 +1127,7 @@ static void M_HandleMenuInput(void)
|
|||
if (M_MenuConfirmPressed(pid))
|
||||
{
|
||||
// If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller.
|
||||
M_OpenVirtualKeyboard(thisMenuKey == -1, MAXSTRINGLENGTH, M_QueryCvarAction, NULL);
|
||||
M_OpenVirtualKeyboard(MAXSTRINGLENGTH, M_QueryCvarAction, NULL);
|
||||
return;
|
||||
}
|
||||
else if (M_MenuExtraPressed(pid))
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "k_color.h"
|
||||
#include "command.h"
|
||||
|
||||
extern "C" consvar_t cv_dummyprofilefov, cv_fov[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
CV_PossibleValue_t lastprofile_cons_t[] = {{-1, "MIN"}, {MAXPROFILES, "MAX"}, {0, NULL}};
|
||||
|
||||
// List of all the profiles.
|
||||
|
|
@ -79,6 +81,7 @@ profile_t* PR_MakeProfile(
|
|||
newprofile->autoroulette = false;
|
||||
newprofile->litesteer = true;
|
||||
newprofile->rumble = true;
|
||||
newprofile->fov = atoi(cv_dummyprofilefov.defaultvalue);
|
||||
|
||||
// Copy from gamecontrol directly as we'll be setting controls up directly in the profile.
|
||||
memcpy(newprofile->controls, controlarray, sizeof(newprofile->controls));
|
||||
|
|
@ -98,6 +101,7 @@ profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const
|
|||
newprofile->autoroulette = cv_autoroulette[pnum].value;
|
||||
newprofile->litesteer = cv_litesteer[pnum].value;
|
||||
newprofile->rumble = cv_rumble[pnum].value;
|
||||
newprofile->fov = cv_fov[pnum].value / FRACUNIT;
|
||||
|
||||
return newprofile;
|
||||
}
|
||||
|
|
@ -292,6 +296,7 @@ void PR_SaveProfiles(void)
|
|||
jsonprof.preferences.autoroulette = cprof->autoroulette;
|
||||
jsonprof.preferences.litesteer = cprof->litesteer;
|
||||
jsonprof.preferences.rumble = cprof->rumble;
|
||||
jsonprof.preferences.fov = cprof->fov;
|
||||
|
||||
for (size_t j = 0; j < num_gamecontrols; j++)
|
||||
{
|
||||
|
|
@ -456,6 +461,7 @@ void PR_LoadProfiles(void)
|
|||
newprof->autoroulette = jsprof.preferences.autoroulette;
|
||||
newprof->litesteer = jsprof.preferences.litesteer;
|
||||
newprof->rumble = jsprof.preferences.rumble;
|
||||
newprof->fov = jsprof.preferences.fov;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -495,6 +501,7 @@ static void PR_ApplyProfile_Settings(profile_t *p, UINT8 playernum)
|
|||
CV_StealthSetValue(&cv_autoroulette[playernum], p->autoroulette);
|
||||
CV_StealthSetValue(&cv_litesteer[playernum], p->litesteer);
|
||||
CV_StealthSetValue(&cv_rumble[playernum], p->rumble);
|
||||
CV_StealthSetValue(&cv_fov[playernum], p->fov);
|
||||
|
||||
// set controls...
|
||||
G_ApplyControlScheme(playernum, p->controls);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct ProfilePreferencesJson
|
|||
bool autoroulette;
|
||||
bool litesteer;
|
||||
bool rumble;
|
||||
uint8_t fov;
|
||||
tm test;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(
|
||||
|
|
@ -54,7 +55,8 @@ struct ProfilePreferencesJson
|
|||
kickstartaccel,
|
||||
autoroulette,
|
||||
litesteer,
|
||||
rumble
|
||||
rumble,
|
||||
fov
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -153,6 +155,7 @@ struct profile_t
|
|||
boolean autoroulette; // cv_autoroulette
|
||||
boolean litesteer; // cv_litesteer
|
||||
boolean rumble; // cv_rumble
|
||||
UINT8 fov; // cv_fov
|
||||
|
||||
// Finally, control data itself
|
||||
INT32 controls[num_gamecontrols][MAXINPUTMAPPING]; // Lists of all the controls, defined the same way as default inputs in g_input.c
|
||||
|
|
|
|||
|
|
@ -2266,9 +2266,10 @@ static int lib_rSetPlayerSkin(lua_State *L)
|
|||
return luaL_error(L, "argument #2 not given (expected number or string)");
|
||||
else if (lua_type(L, 2) == LUA_TNUMBER) // skin number
|
||||
{
|
||||
INT32 skincount = (demo.playback ? demo.numskins : numskins);
|
||||
i = luaL_checkinteger(L, 2);
|
||||
if (i < 0 || i >= numskins)
|
||||
return luaL_error(L, "skin %d (argument #2) out of range (0 - %d)", i, numskins-1);
|
||||
if (i < 0 || i >= skincount)
|
||||
return luaL_error(L, "skin %d (argument #2) out of range (0 - %d)", i, skincount-1);
|
||||
}
|
||||
else // skin name
|
||||
{
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ static int libd_getSprite2Patch(lua_State *L)
|
|||
i = lua_tonumber(L, 1);
|
||||
if (i < 0 || i >= MAXSKINS)
|
||||
return luaL_error(L, "skin number %d out of range (0 - %d)", i, MAXSKINS-1);
|
||||
if (i >= numskins)
|
||||
if (i >= (demo.playback ? demo.numskins : numskins))
|
||||
return 0;
|
||||
}
|
||||
else // find skin by name
|
||||
|
|
@ -389,6 +389,9 @@ static int libd_getSprite2Patch(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (demo.playback)
|
||||
i = demo.skinlist[i].mapping;
|
||||
|
||||
lua_remove(L, 1); // remove skin now
|
||||
|
||||
if (lua_isnumber(L, 1)) // sprite number given, e.g. SPR2_STIL
|
||||
|
|
@ -1041,6 +1044,9 @@ static int libd_getColormap(lua_State *L)
|
|||
skinnum = i;
|
||||
}
|
||||
|
||||
if (demo.playback)
|
||||
skinnum = demo.skinlist[skinnum].mapping;
|
||||
|
||||
// all was successful above, now we generate the colormap at last!
|
||||
|
||||
colormap = R_GetTranslationColormap(skinnum, color, GTC_CACHE);
|
||||
|
|
|
|||
|
|
@ -721,7 +721,11 @@ static int mobj_set(lua_State *L)
|
|||
if (skin != -1)
|
||||
{
|
||||
if (!mo->player || R_SkinUsable(mo->player-players, skin, false))
|
||||
{
|
||||
if (demo.playback)
|
||||
skin = demo.skinlist[skin].mapping;
|
||||
mo->skin = &skins[skin];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,8 +263,12 @@ static int player_get(lua_State *L)
|
|||
lua_pushboolean(L, plr->incontrol);
|
||||
else if (fastcmp(field,"progressivethrust"))
|
||||
lua_pushboolean(L, plr->progressivethrust);
|
||||
else if (fastcmp(field,"ringvisualwarning"))
|
||||
lua_pushboolean(L, plr->ringvisualwarning);
|
||||
else if (fastcmp(field,"dotrickfx"))
|
||||
lua_pushboolean(L, plr->dotrickfx);
|
||||
else if (fastcmp(field,"stingfx"))
|
||||
lua_pushboolean(L, plr->stingfx);
|
||||
else if (fastcmp(field,"bumperinflate"))
|
||||
lua_pushboolean(L, plr->bumperinflate);
|
||||
else if (fastcmp(field,"ringboxdelay"))
|
||||
|
|
@ -801,12 +805,16 @@ static int player_set(lua_State *L)
|
|||
plr->incontrol = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"progressivethrust"))
|
||||
plr->progressivethrust = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"ringvisualwarning"))
|
||||
plr->ringvisualwarning = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"analoginput"))
|
||||
plr->markedfordeath = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"markedfordeath"))
|
||||
plr->markedfordeath = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"dotrickfx"))
|
||||
plr->dotrickfx = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"stingfx"))
|
||||
plr->stingfx = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"bumperinflate"))
|
||||
plr->bumperinflate = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"ringboxdelay"))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "deh_lua.h"
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "r_things.h" // numskins
|
||||
#include "p_setup.h"
|
||||
#include "r_state.h"
|
||||
#include "r_sky.h"
|
||||
|
|
@ -371,6 +372,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"replayplayback")) {
|
||||
lua_pushboolean(L, demo.playback);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"replaynumskins")) {
|
||||
lua_pushinteger(L, (demo.playback ? demo.numskins : numskins));
|
||||
return 1;
|
||||
} else if (fastcmp(word, "gamestate")) {
|
||||
lua_pushinteger(L, gamestate);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ static int lib_getSkin(lua_State *L)
|
|||
}
|
||||
|
||||
// find skin by name
|
||||
i = R_SkinAvailable(field);
|
||||
i = R_SkinAvailableEx(field, false);
|
||||
if (i != -1)
|
||||
{
|
||||
LUA_PushUserdata(L, &skins[i], META_SKIN);
|
||||
|
|
|
|||
32
src/m_cond.c
32
src/m_cond.c
|
|
@ -1019,6 +1019,32 @@ cacheprisoneggpickup:
|
|||
}
|
||||
|
||||
//CONS_Printf("thisprisoneggpickup = %u (MAXCONDITIONSETS is %u)\n", gamedata->thisprisoneggpickup, MAXCONDITIONSETS);
|
||||
|
||||
#ifdef DEVELOP
|
||||
extern consvar_t cv_debugprisoncd;
|
||||
// If all drops are collected, just force the first valid one.
|
||||
if (cv_debugprisoncd.value && gamedata->thisprisoneggpickup_cached == NULL)
|
||||
{
|
||||
for (i = 0; gamedata->thisprisoneggpickup_cached == NULL &&
|
||||
i < gamedata->numprisoneggpickups; i++)
|
||||
{
|
||||
c = &conditionSets[gamedata->prisoneggpickups[i]];
|
||||
if (c->numconditions)
|
||||
{
|
||||
for (j = 0; j < c->numconditions; ++j)
|
||||
{
|
||||
cn = &c->condition[j];
|
||||
if (cn->type != UC_PRISONEGGCD)
|
||||
continue;
|
||||
|
||||
gamedata->thisprisoneggpickup = gamedata->prisoneggpickups[i];
|
||||
gamedata->thisprisoneggpickup_cached = cn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void M_PrecacheLevelLocks(void)
|
||||
|
|
@ -1206,7 +1232,7 @@ void M_UpdateConditionSetsPending(void)
|
|||
case UCRP_ISCHARACTER:
|
||||
case UCRP_MAKERETIRE:
|
||||
{
|
||||
cn->requirement = R_SkinAvailable(cn->stringvar);
|
||||
cn->requirement = R_SkinAvailableEx(cn->stringvar, false);
|
||||
|
||||
if (cn->requirement < 0)
|
||||
{
|
||||
|
|
@ -2021,7 +2047,7 @@ static const char *M_GetConditionCharacter(INT32 skin, boolean directlyrequires)
|
|||
for (j = 0; j < SKINRIVALS; j++)
|
||||
{
|
||||
const char *rivalname = skins[i].rivals[j];
|
||||
INT32 rivalnum = R_SkinAvailable(rivalname);
|
||||
INT32 rivalnum = R_SkinAvailableEx(rivalname, false);
|
||||
|
||||
if (rivalnum != skin)
|
||||
continue;
|
||||
|
|
@ -3504,7 +3530,7 @@ INT32 M_UnlockableSkinNum(unlockable_t *unlock)
|
|||
}
|
||||
|
||||
// Get the skin from the string.
|
||||
skinnum = R_SkinAvailable(unlock->stringVar);
|
||||
skinnum = R_SkinAvailableEx(unlock->stringVar, false);
|
||||
if (skinnum != -1)
|
||||
{
|
||||
unlock->stringVarCache = skinnum;
|
||||
|
|
|
|||
|
|
@ -714,7 +714,7 @@ void M_ChallengesTick(void)
|
|||
INT32 fskin = M_UnlockableFollowerNum(ref);
|
||||
if (fskin != -1)
|
||||
{
|
||||
INT32 psk = R_SkinAvailable(cv_skin[0].string);
|
||||
INT32 psk = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
if (psk == -1)
|
||||
psk = 0;
|
||||
bombcolor = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[psk]);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public:
|
|||
{
|
||||
if (!skinName.empty())
|
||||
{
|
||||
this->skinID = R_SkinAvailable(skinName.c_str());
|
||||
this->skinID = R_SkinAvailableEx(skinName.c_str(), false);
|
||||
}
|
||||
|
||||
this->offset = offset;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ menuitem_t OPTIONS_Main[] =
|
|||
{IT_STRING | IT_SUBMENU, "HUD Options", "Options related to the Heads-Up Display.",
|
||||
NULL, {.submenu = &OPTIONS_HUDDef}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, "Gameplay Options", "Change various game related options",
|
||||
NULL, {.submenu = &OPTIONS_GameplayDef}, 0, 0},
|
||||
{IT_STRING | IT_CALL, "Gameplay Options", "Change various game related options",
|
||||
NULL, {.routine = M_GameplayOptions}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, "Server Options", "Change various specific options for your game server.",
|
||||
NULL, {.submenu = &OPTIONS_ServerDef}, 0, 0},
|
||||
{IT_STRING | IT_CALL, "Server Options", "Change various specific options for your game server.",
|
||||
NULL, {.routine = M_ServerOptions}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, "Data Options", "Miscellaneous data options such as the screenshot format.",
|
||||
NULL, {.submenu = &OPTIONS_DataDef}, 0, 0},
|
||||
|
|
@ -90,8 +90,8 @@ void M_InitOptions(INT32 choice)
|
|||
if (gamestate == GS_MENU
|
||||
|| ((server || IsPlayerAdmin(consoleplayer)) && K_CanChangeRules(false)))
|
||||
{
|
||||
OPTIONS_MainDef.menuitems[mopt_gameplay].status = IT_STRING | IT_SUBMENU;
|
||||
OPTIONS_MainDef.menuitems[mopt_server].status = IT_STRING | IT_SUBMENU;
|
||||
OPTIONS_MainDef.menuitems[mopt_gameplay].status = IT_STRING | IT_CALL;
|
||||
OPTIONS_MainDef.menuitems[mopt_server].status = IT_STRING | IT_CALL;
|
||||
OPTIONS_GameplayDef.menuitems[gopt_encore].status =
|
||||
(M_SecretUnlocked(SECRET_ENCORE, false) ? (IT_STRING | IT_CVAR) : IT_DISABLED);
|
||||
}
|
||||
|
|
@ -228,6 +228,18 @@ void M_SoundOptions(INT32 choice)
|
|||
M_GonerResetLooking(GDGONER_SOUND);
|
||||
}
|
||||
|
||||
void M_GameplayOptions(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
M_OptionsMenuGoto(&OPTIONS_GameplayDef);
|
||||
}
|
||||
|
||||
void M_ServerOptions(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
M_OptionsMenuGoto(&OPTIONS_ServerDef);
|
||||
}
|
||||
|
||||
boolean M_OptionsInputs(INT32 ch)
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ void M_StartEditProfile(INT32 c)
|
|||
CV_StealthSetValue(&cv_dummyprofileautoroulette, optionsmenu.profile->autoroulette);
|
||||
CV_StealthSetValue(&cv_dummyprofilelitesteer, optionsmenu.profile->litesteer);
|
||||
CV_StealthSetValue(&cv_dummyprofilerumble, optionsmenu.profile->rumble);
|
||||
CV_StealthSetValue(&cv_dummyprofilefov, optionsmenu.profile->fov);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -102,6 +103,7 @@ void M_StartEditProfile(INT32 c)
|
|||
CV_StealthSetValue(&cv_dummyprofileautoroulette, 0); // off
|
||||
CV_StealthSetValue(&cv_dummyprofilelitesteer, 1); // on
|
||||
CV_StealthSetValue(&cv_dummyprofilerumble, 1); // on
|
||||
CV_StealthSetValue(&cv_dummyprofilefov, 90);
|
||||
}
|
||||
|
||||
// Setup greyout and stuff.
|
||||
|
|
|
|||
|
|
@ -90,15 +90,18 @@ static void M_ProfileEditApply(void)
|
|||
optionsmenu.profile->autoroulette = cv_dummyprofileautoroulette.value;
|
||||
optionsmenu.profile->litesteer = cv_dummyprofilelitesteer.value;
|
||||
optionsmenu.profile->rumble = cv_dummyprofilerumble.value;
|
||||
optionsmenu.profile->fov = cv_dummyprofilefov.value;
|
||||
|
||||
// If this profile is in-use by anyone, apply the changes immediately upon exiting.
|
||||
// Don't apply the profile itself as that would lead to issues mid-game.
|
||||
if (belongsto > -1 && belongsto < MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS];
|
||||
CV_SetValue(&cv_kickstartaccel[belongsto], cv_dummyprofilekickstart.value);
|
||||
CV_SetValue(&cv_autoroulette[belongsto], cv_dummyprofileautoroulette.value);
|
||||
CV_SetValue(&cv_litesteer[belongsto], cv_dummyprofilelitesteer.value);
|
||||
CV_SetValue(&cv_rumble[belongsto], cv_dummyprofilerumble.value);
|
||||
CV_SetValue(&cv_fov[belongsto], cv_dummyprofilefov.value);
|
||||
}
|
||||
|
||||
// Reapply player 1's real profile.
|
||||
|
|
|
|||
|
|
@ -102,6 +102,9 @@ menuitem_t OPTIONS_ProfileAccessibility[] = {
|
|||
{IT_STRING | IT_CVAR, "Lite Steer", "Hold DOWN on d-pad/keyboard for shallow turns.",
|
||||
NULL, {.cvar = &cv_dummyprofilelitesteer}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR, "Field of View", "Higher FOV lets you see more.",
|
||||
NULL, {.cvar = &cv_dummyprofilefov}, 0, 0},
|
||||
|
||||
{IT_SPACE | IT_NOTHING, NULL, NULL,
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
|
|
@ -129,7 +132,7 @@ menu_t OPTIONS_ProfileAccessibilityDef = {
|
|||
&OPTIONS_EditProfileDef,
|
||||
0,
|
||||
OPTIONS_ProfileAccessibility,
|
||||
145, 52,
|
||||
145, 41,
|
||||
SKINCOLOR_ULTRAMARINE, 0,
|
||||
MBF_DRAWBGWHILEPLAYING,
|
||||
"FILE",
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ static INT16 M_GetMenuCategoryFromFollower(setup_player_t *p)
|
|||
static void M_SetupProfileGridPos(setup_player_t *p)
|
||||
{
|
||||
profile_t *pr = PR_GetProfile(p->profilen);
|
||||
INT32 i = R_SkinAvailable(pr->skinname);
|
||||
INT32 i = R_SkinAvailableEx(pr->skinname, false);
|
||||
INT32 alt = 0; // Hey it's my character's name!
|
||||
|
||||
if (i == -1)
|
||||
|
|
@ -247,7 +247,7 @@ static void M_SetupProfileGridPos(setup_player_t *p)
|
|||
|
||||
static void M_SetupMidGameGridPos(setup_player_t *p, UINT8 num)
|
||||
{
|
||||
INT32 i = R_SkinAvailable(cv_skin[num].zstring);
|
||||
INT32 i = R_SkinAvailableEx(cv_skin[num].zstring, false);
|
||||
INT32 alt = 0; // Hey it's my character's name!
|
||||
|
||||
if (i == -1)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ menu_t PLAY_RaceDifficultyDef = {
|
|||
0,
|
||||
PLAY_RaceDifficulty,
|
||||
0, 0,
|
||||
0, 0,
|
||||
drace_boxend, 0,
|
||||
0,
|
||||
NULL,
|
||||
1, 5,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "../m_cond.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../mserv.h" // cv_masterserver
|
||||
#include "../m_misc.h"
|
||||
|
||||
#if defined (TESTERS)
|
||||
#define IT_STRING_CALL_NOTESTERS IT_DISABLED
|
||||
|
|
@ -73,20 +74,117 @@ static void M_PreMPRoomSelectInit(INT32 choice)
|
|||
M_MPRoomSelectInit(0);
|
||||
}
|
||||
|
||||
static const char *query_ip(const char *replace)
|
||||
{
|
||||
if (replace)
|
||||
M_JoinIP(replace);
|
||||
return "";
|
||||
}
|
||||
|
||||
static boolean uses_gamepad;
|
||||
|
||||
static void ip_entry(void)
|
||||
{
|
||||
M_OpenVirtualKeyboard(MAXSTRINGLENGTH, query_ip, NULL);
|
||||
}
|
||||
|
||||
static consvar_t *ip_cvar(void)
|
||||
{
|
||||
extern consvar_t cv_dummyipselect;
|
||||
return &cv_dummyipselect;
|
||||
}
|
||||
|
||||
static void confirm_ip_select(INT32 choice)
|
||||
{
|
||||
if (choice == MA_YES)
|
||||
{
|
||||
consvar_t *cv = ip_cvar();
|
||||
M_JoinIP(joinedIPlist[cv->value][0]);
|
||||
}
|
||||
}
|
||||
|
||||
static void find_ip(INT32 add)
|
||||
{
|
||||
consvar_t *cv = ip_cvar();
|
||||
for (int i = 0; i < NUMLOGIP; ++i)
|
||||
{
|
||||
CV_AddValue(cv, add);
|
||||
if (*joinedIPlist[cv->value][0])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_join_routine(INT32 choice)
|
||||
{
|
||||
consvar_t *cv = ip_cvar();
|
||||
INT32 index = cv->value;
|
||||
|
||||
if (choice == 2)
|
||||
ip_entry();
|
||||
else if (choice == -1)
|
||||
{
|
||||
const char *ip = joinedIPlist[index][0];
|
||||
if (*ip)
|
||||
{
|
||||
M_StartMessage("Direct Join", va("Connect to %s?", joinedIPlist[index][0]),
|
||||
&confirm_ip_select, MM_YESNO, "Connect", "Back");
|
||||
}
|
||||
}
|
||||
else
|
||||
find_ip(choice ? 1 : -1);
|
||||
}
|
||||
|
||||
// mp_e
|
||||
menuitem_t PLAY_MP_OptSelect[] =
|
||||
{
|
||||
{IT_STRING_CALL_NOTESTERS, "Host Game", "Start your own online game!",
|
||||
NULL, {.routine = M_PreMPHostInit}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Server Browser", "Search for game servers to play in.",
|
||||
{IT_STRING | IT_CALL, "Browse", "Search for game servers to play in.",
|
||||
NULL, {.routine = M_PreMPRoomSelectInit}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Join by IP", "Join an online game by its IP address.",
|
||||
NULL, {.routine = M_MPJoinIPInit}, 0, 0},
|
||||
{IT_STRING | IT_ARROWS, "Direct Join", "Join an online game by its IP address.",
|
||||
NULL, {.routine = direct_join_routine}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Back", NULL, NULL, {.routine = M_GoBack}, 0, 0},
|
||||
};
|
||||
|
||||
#undef IT_STRING_CALL_NOTESTERS
|
||||
|
||||
static void draw_routine(void)
|
||||
{
|
||||
M_DrawKartGamemodeMenu();
|
||||
M_DrawMasterServerReminder();
|
||||
}
|
||||
|
||||
static boolean any_stored_ips(void)
|
||||
{
|
||||
for (int i = 0; i < NUMLOGIP; ++i)
|
||||
{
|
||||
if (*joinedIPlist[i][0])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void init_routine(void)
|
||||
{
|
||||
menuitem_t *it = &PLAY_MP_OptSelect[mp_directjoin];
|
||||
CV_SetValue(ip_cvar(), 0);
|
||||
if (any_stored_ips())
|
||||
{
|
||||
it->status = IT_STRING | IT_ARROWS;
|
||||
find_ip(1);
|
||||
}
|
||||
else
|
||||
it->status = IT_STRING | IT_CALL;
|
||||
}
|
||||
|
||||
static boolean input_routine(INT32 key)
|
||||
{
|
||||
uses_gamepad = (key == -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
menu_t PLAY_MP_OptSelectDef = {
|
||||
sizeof (PLAY_MP_OptSelect) / sizeof (menuitem_t),
|
||||
|
|
@ -101,13 +199,13 @@ menu_t PLAY_MP_OptSelectDef = {
|
|||
0, 0,
|
||||
0,
|
||||
"NETMD2",
|
||||
-1, 1,
|
||||
M_DrawMPOptSelect,
|
||||
4, 5,
|
||||
draw_routine,
|
||||
M_DrawEggaChannel,
|
||||
M_MPOptSelectTick,
|
||||
NULL,
|
||||
init_routine,
|
||||
NULL,
|
||||
NULL
|
||||
input_routine
|
||||
};
|
||||
|
||||
struct mpmenu_s mpmenu;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,21 @@
|
|||
#include "../z_zone.h"
|
||||
#include "../mserv.h"
|
||||
|
||||
static void draw_routine(void)
|
||||
{
|
||||
M_DrawRaceDifficulty();
|
||||
M_DrawMasterServerReminder();
|
||||
}
|
||||
|
||||
static void tick_routine(void)
|
||||
{
|
||||
PLAY_MP_Host[mhost_gametype].text = gametypes[menugametype]->name;
|
||||
}
|
||||
|
||||
// MULTIPLAYER HOST SCREEN -- see mhost_e
|
||||
menuitem_t PLAY_MP_Host[] =
|
||||
{
|
||||
#if 0
|
||||
//{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_MPOptSelect, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, "Server Name", "Display name for your game online. Other players will see this.",
|
||||
|
|
@ -25,7 +37,21 @@ menuitem_t PLAY_MP_Host[] =
|
|||
|
||||
{IT_STRING | IT_CALL, "GO", "Select a map with the currently selected gamemode",
|
||||
NULL, {.routine = M_MPSetupNetgameMapSelect}, 0, 0},
|
||||
#endif
|
||||
{IT_STRING | IT_ARROWS, "Gametype", "Choose the type of play on your serer.",
|
||||
NULL, {.routine = M_HandleHostMenuGametype}, 0, 0},
|
||||
|
||||
{IT_STRING2 | IT_CALL, "Gameplay Options...", "Adjust settings pertaining to gameplay.",
|
||||
NULL, {.routine = M_GameplayOptions}, 0, 0},
|
||||
|
||||
{IT_STRING2 | IT_CALL, "Server Options...", "Adjust settings pertaining to online play.",
|
||||
NULL, {.routine = M_ServerOptions}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Map Select", "Go on and select a level!",
|
||||
NULL, {.routine = M_MPSetupNetgameMapSelect}, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Back", NULL,
|
||||
NULL, {.routine = M_GoBack}, 0, 0},
|
||||
};
|
||||
|
||||
menu_t PLAY_MP_HostDef = {
|
||||
|
|
@ -34,13 +60,13 @@ menu_t PLAY_MP_HostDef = {
|
|||
0,
|
||||
PLAY_MP_Host,
|
||||
0, 0,
|
||||
0, 0,
|
||||
mhost_boxend, 0,
|
||||
0,
|
||||
"NETMD2",
|
||||
-1, 1, // 1 frame transition.... This is really just because I don't want the black fade when we press esc, hehe
|
||||
M_DrawMPHost,
|
||||
4, 5,
|
||||
draw_routine,
|
||||
M_DrawEggaChannel,
|
||||
M_MPOptSelectTick, // This handles the unfolding options
|
||||
tick_routine,
|
||||
NULL,
|
||||
M_MPResetOpts,
|
||||
NULL
|
||||
|
|
@ -66,8 +92,8 @@ void M_MPHostInit(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
mpmenu.modewinextend[0][0] = 1;
|
||||
M_SetupNextMenu(&PLAY_MP_HostDef, true);
|
||||
itemOn = mhost_go;
|
||||
PLAY_MP_HostDef.lastOn = mhost_mapselect;
|
||||
M_SetupNextMenu(&PLAY_MP_HostDef, false);
|
||||
|
||||
Get_rules();
|
||||
// There's one downside to doing it this way:
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ void M_JoinIP(const char *ipa)
|
|||
{
|
||||
if (*(ipa) == '\0') // Jack shit
|
||||
{
|
||||
M_StartMessage("Online Play", "Please specify an address.\n", NULL, MM_NOTHING, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,15 +54,22 @@ menu_t PAUSE_PlaybackMenuDef = {
|
|||
|
||||
void M_EndModeAttackRun(void)
|
||||
{
|
||||
G_CheckDemoStatus(); // Cancel recording
|
||||
if (demo.playback)
|
||||
{
|
||||
G_CheckDemoStatus(); // Cancel recording
|
||||
return;
|
||||
}
|
||||
|
||||
Command_ExitGame_f(); // Clear a bunch of state
|
||||
|
||||
if (!modeattacking)
|
||||
return;
|
||||
|
||||
modeattacking = ATTACKING_NONE; // Kept until now because of Command_ExitGame_f
|
||||
|
||||
if (demo.attract == DEMO_ATTRACT_TITLE)
|
||||
{
|
||||
D_StartTitle();
|
||||
D_SetDeferredStartTitle(true);
|
||||
}
|
||||
else if (demo.attract == DEMO_ATTRACT_CREDITS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -190,24 +190,29 @@ void M_AbortVirtualKeyboard(void)
|
|||
return;
|
||||
|
||||
menutyping.active = false;
|
||||
menutyping.menutypingfade = 0;
|
||||
Z_Free(menutyping.cache);
|
||||
|
||||
if (currentMenu == menutyping.dummymenu)
|
||||
M_GoBack(0);
|
||||
}
|
||||
|
||||
static boolean M_IsTypingKey(INT32 key)
|
||||
{
|
||||
return key == KEY_BACKSPACE || key == KEY_ENTER
|
||||
|| key == KEY_ESCAPE || key == KEY_DEL
|
||||
|| key == KEY_LCTRL || key == KEY_RCTRL
|
||||
|| isprint(key);
|
||||
}
|
||||
|
||||
void M_MenuTypingInput(INT32 key)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
|
||||
// Determine when to check for keyboard inputs or controller inputs using menuKey, which is the key passed here as argument.
|
||||
if (key > 0)
|
||||
{
|
||||
boolean gamepad = (key >= NUMKEYS);
|
||||
M_SwitchVirtualKeyboard(gamepad);
|
||||
if (gamepad)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!menutyping.active)
|
||||
return;
|
||||
|
||||
// Fade-in
|
||||
|
||||
if (menutyping.menutypingclose)
|
||||
|
|
@ -233,6 +238,25 @@ void M_MenuTypingInput(INT32 key)
|
|||
menutyping.menutypingfade++;
|
||||
}
|
||||
|
||||
if (menutyping.menutypingfade >= 9) // either is visible
|
||||
{
|
||||
if (key == KEY_ENTER || key == KEY_ESCAPE)
|
||||
{
|
||||
M_CloseVirtualKeyboard();
|
||||
|
||||
M_SetMenuDelay(pid);
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (menutyping.keyboardtyping)
|
||||
{
|
||||
M_ChangeStringCvar(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (menutyping.menutypingfade != destination)
|
||||
{
|
||||
// Don't allow typing until it's fully opened.
|
||||
|
|
@ -240,68 +264,6 @@ void M_MenuTypingInput(INT32 key)
|
|||
}
|
||||
}
|
||||
|
||||
// Determine when to check for keyboard inputs or controller inputs using menuKey, which is the key passed here as argument.
|
||||
if (!menutyping.keyboardtyping) // controller inputs
|
||||
{
|
||||
// we pressed a keyboard input that's not any of our buttons
|
||||
if (key >= 0 && M_IsTypingKey(key) && menucmd[pid].dpad_lr == 0 && menucmd[pid].dpad_ud == 0
|
||||
&& !(menucmd[pid].buttons & MBT_A)
|
||||
&& !(menucmd[pid].buttons & MBT_B)
|
||||
&& !(menucmd[pid].buttons & MBT_C)
|
||||
&& !(menucmd[pid].buttons & MBT_X)
|
||||
&& !(menucmd[pid].buttons & MBT_Y)
|
||||
&& !(menucmd[pid].buttons & MBT_Z)
|
||||
&& !(menucmd[pid].buttons & MBT_START))
|
||||
{
|
||||
menutyping.keyboardtyping = true;
|
||||
}
|
||||
}
|
||||
else // Keyboard inputs.
|
||||
{
|
||||
// On the flipside, if we're pressing any keyboard input, switch to controller inputs.
|
||||
if (key >= 0 && !M_IsTypingKey(key) && (
|
||||
M_MenuButtonPressed(pid, MBT_A)
|
||||
|| M_MenuButtonPressed(pid, MBT_B)
|
||||
|| M_MenuButtonPressed(pid, MBT_C)
|
||||
|| M_MenuButtonPressed(pid, MBT_X)
|
||||
|| M_MenuButtonPressed(pid, MBT_Y)
|
||||
|| M_MenuButtonPressed(pid, MBT_Z)
|
||||
|| M_MenuButtonPressed(pid, MBT_START)
|
||||
|| (menucmd[pid].dpad_lr != 0 && menucmd[pid].prev_dpad_lr == 0)
|
||||
|| (menucmd[pid].dpad_ud != 0 && menucmd[pid].prev_dpad_ud != 0)
|
||||
))
|
||||
{
|
||||
/*CONS_Printf("key is %d, \
|
||||
%c%c%c-%c%c%c-%c-%c%c%c%c\n",
|
||||
key,
|
||||
M_MenuButtonPressed(pid, MBT_A) ? 'A' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_B) ? 'B' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_C) ? 'C' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_X) ? 'X' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_Y) ? 'Y' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_Z) ? 'Z' : ' ',
|
||||
M_MenuButtonPressed(pid, MBT_START) ? '+' : ' ',
|
||||
menucmd[pid].dpad_lr < 0 ? '<' : ' ',
|
||||
menucmd[pid].dpad_ud > 0 ? '^' : ' ',
|
||||
menucmd[pid].dpad_ud < 0 ? 'v' : ' ',
|
||||
menucmd[pid].dpad_lr > 0 ? '>' : ' '
|
||||
);*/
|
||||
menutyping.keyboardtyping = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// OTHERWISE, process keyboard inputs for typing!
|
||||
if (key == KEY_ENTER || key == KEY_ESCAPE)
|
||||
{
|
||||
M_CloseVirtualKeyboard();
|
||||
|
||||
M_SetMenuDelay(pid);
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (menucmd[pid].delay == 0 && !menutyping.keyboardtyping) // We must check for this here because we bypass the normal delay check to allow for normal keyboard inputs
|
||||
{
|
||||
if (menucmd[pid].dpad_ud > 0) // down
|
||||
|
|
@ -418,9 +380,8 @@ void M_MenuTypingInput(INT32 key)
|
|||
}
|
||||
}
|
||||
|
||||
void M_OpenVirtualKeyboard(boolean gamepad, size_t cachelen, vkb_query_fn_t queryfn, menu_t *dummymenu)
|
||||
void M_OpenVirtualKeyboard(size_t cachelen, vkb_query_fn_t queryfn, menu_t *dummymenu)
|
||||
{
|
||||
menutyping.keyboardtyping = !gamepad;
|
||||
menutyping.active = true;
|
||||
menutyping.menutypingclose = false;
|
||||
|
||||
|
|
@ -443,3 +404,9 @@ void M_OpenVirtualKeyboard(boolean gamepad, size_t cachelen, vkb_query_fn_t quer
|
|||
M_SetupNextMenu(dummymenu, true);
|
||||
}
|
||||
}
|
||||
|
||||
void M_SwitchVirtualKeyboard(boolean gamepad)
|
||||
{
|
||||
extern consvar_t cv_debugvirtualkeyboard;
|
||||
menutyping.keyboardtyping = cv_debugvirtualkeyboard.value ? false : !gamepad;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3522,6 +3522,16 @@ void A_AttractChase(mobj_t *actor)
|
|||
|
||||
S_ReducedVFXSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume, NULL);
|
||||
|
||||
if (actor->target->player->rings <= 10 && P_IsDisplayPlayer(actor->target->player))
|
||||
{
|
||||
S_ReducedVFXSoundAtVolume(actor->target, sfx_gshab,
|
||||
210 - 10*actor->target->player->rings
|
||||
, NULL);
|
||||
|
||||
if (actor->target->player->rings == 0)
|
||||
S_ReducedVFXSoundAtVolume(actor->target, sfx_gshad, 127, NULL);
|
||||
}
|
||||
|
||||
actor->target->player->ringvolume -= RINGVOLUMEUSEPENALTY;
|
||||
|
||||
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
|
||||
|
|
|
|||
|
|
@ -1198,13 +1198,21 @@ static void P_AddBrokenPrison(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
secretextratime = TICRATE/2;
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
#ifdef DEVELOP
|
||||
extern consvar_t cv_debugprisoncd;
|
||||
#endif
|
||||
if ((
|
||||
grandprixinfo.gp == true // Bonus Round
|
||||
&& demo.playback == false // Not playback
|
||||
&& netgame == false // game design + makes it easier to implement
|
||||
&& gamedata->thisprisoneggpickup_cached != NULL
|
||||
&& gamedata->prisoneggstothispickup == 0
|
||||
&& gamedata->thisprisoneggpickupgrabbed == false
|
||||
)
|
||||
#ifdef DEVELOP
|
||||
|| (cv_debugprisoncd.value && gamedata->thisprisoneggpickup_cached != NULL)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
// Will be 0 for the next level
|
||||
|
|
@ -1218,6 +1226,10 @@ static void P_AddBrokenPrison(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
|
||||
if (secretpickup)
|
||||
{
|
||||
// Grab attention with a long sound effect.
|
||||
target->hitlag += 56;
|
||||
S_StartSound(target, sfx_s3k85);
|
||||
|
||||
secretpickup->hitlag = target->hitlag;
|
||||
|
||||
secretpickup->z -= secretpickup->height/2;
|
||||
|
|
@ -1244,6 +1256,26 @@ static void P_AddBrokenPrison(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
secretpickup, secretpickup->angle,
|
||||
P_ReturnThrustX(secretpickup, launchangle, launchmomentum)
|
||||
);
|
||||
|
||||
mobj_t *flare = P_SpawnMobj(
|
||||
target->x, target->y,
|
||||
target->z + target->height/2,
|
||||
MT_SPARK
|
||||
);
|
||||
|
||||
if (flare)
|
||||
{
|
||||
// Will flicker in place until secretpickup exits hitlag.
|
||||
flare->colorized = true;
|
||||
flare->renderflags |= RF_ALWAYSONTOP;
|
||||
P_InstaScale(flare, 4 * flare->scale);
|
||||
P_SetTarget(&secretpickup->target, flare);
|
||||
P_SetMobjStateNF(flare, S_PRISONEGGDROP_FLAREA1);
|
||||
}
|
||||
|
||||
// Darken the level for roughly how long it takes until the last sound effect stops playing.
|
||||
g_darkness.start = leveltime;
|
||||
g_darkness.end = leveltime + target->hitlag + TICRATE + DARKNESS_FADE_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/p_mobj.c
10
src/p_mobj.c
|
|
@ -7499,6 +7499,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
mobj->z += P_MobjFlip(mobj);
|
||||
mobj->flags2 |= MF2_AMBUSH;
|
||||
|
||||
// Finish flare animation.
|
||||
if (mobj->target && !P_MobjWasRemoved(mobj->target))
|
||||
P_SetMobjStateNF(mobj->target, S_PRISONEGGDROP_FLAREB1);
|
||||
}
|
||||
|
||||
if (teststate == S_PRISONEGGDROP_CD)
|
||||
|
|
@ -7538,6 +7542,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
sparkle->color = M_RandomChance(FRACUNIT/2) ? SKINCOLOR_ULTRAMARINE : SKINCOLOR_MAGENTA;
|
||||
sparkle->momz += 8 * mobj->scale * P_MobjFlip(mobj);
|
||||
sparkle->scale = 3 * sparkle->scale;
|
||||
sparkle->scalespeed = abs(sparkle->scale - sparkle->destscale) / 16;
|
||||
|
||||
// Colorize flare.
|
||||
if (mobj->target && !P_MobjWasRemoved(mobj->target))
|
||||
mobj->target->color = sparkle->color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1427,15 +1427,11 @@ void T_PolyObjRotate(polyrotate_t *th)
|
|||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjRotate: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotate: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -1508,15 +1504,11 @@ void T_PolyObjMove(polymove_t *th)
|
|||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjMove: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjMove: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -1598,15 +1590,11 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
|||
fixed_t speed = th->speed;
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjWaypoint: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjWaypoint: thinker with invalid id %d removed.", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (!po->thinker)
|
||||
|
|
@ -1714,15 +1702,11 @@ void T_PolyDoorSlide(polyslidedoor_t *th)
|
|||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyDoorSlide: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSlide: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -1819,15 +1803,11 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
|
|||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -1918,15 +1898,11 @@ void T_PolyObjDisplace(polydisplace_t *th)
|
|||
fixed_t dx, dy;
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -1958,15 +1934,11 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th)
|
|||
fixed_t rotangle;
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -2442,15 +2414,11 @@ void T_PolyObjFlag(polymove_t *th)
|
|||
size_t i;
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjFlag: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFlag: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
@ -2549,15 +2517,11 @@ void T_PolyObjFade(polyfade_t *th)
|
|||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinker(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ static boolean P_UnArchivePlayer(savebuffer_t *save)
|
|||
INT32 skin;
|
||||
|
||||
READSTRINGN(save->p, skinname, SKINNAMESIZE);
|
||||
skin = R_SkinAvailable(skinname);
|
||||
skin = R_SkinAvailableEx(skinname, false);
|
||||
|
||||
if (skin == -1)
|
||||
{
|
||||
|
|
@ -176,7 +176,7 @@ static boolean P_UnArchivePlayer(savebuffer_t *save)
|
|||
savedata.bots[pid].valid = true;
|
||||
|
||||
READSTRINGN(save->p, skinname, SKINNAMESIZE);
|
||||
skin = R_SkinAvailable(skinname);
|
||||
skin = R_SkinAvailableEx(skinname, false);
|
||||
|
||||
if (skin == -1)
|
||||
{
|
||||
|
|
@ -598,11 +598,13 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
|
||||
WRITEINT16(save->p, players[i].incontrol);
|
||||
WRITEUINT16(save->p, players[i].progressivethrust);
|
||||
WRITEUINT8(save->p, players[i].ringvisualwarning);
|
||||
|
||||
WRITEUINT8(save->p, players[i].analoginput);
|
||||
|
||||
WRITEUINT8(save->p, players[i].markedfordeath);
|
||||
WRITEUINT8(save->p, players[i].dotrickfx);
|
||||
WRITEUINT8(save->p, players[i].stingfx);
|
||||
WRITEUINT8(save->p, players[i].bumperinflate);
|
||||
|
||||
WRITEUINT8(save->p, players[i].ringboxdelay);
|
||||
|
|
@ -1184,11 +1186,13 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
|
||||
players[i].incontrol = READINT16(save->p);
|
||||
players[i].progressivethrust = READUINT16(save->p);
|
||||
players[i].ringvisualwarning = READUINT8(save->p);
|
||||
|
||||
players[i].analoginput = READUINT8(save->p);
|
||||
|
||||
players[i].markedfordeath = READUINT8(save->p);
|
||||
players[i].dotrickfx = READUINT8(save->p);
|
||||
players[i].stingfx = READUINT8(save->p);
|
||||
players[i].bumperinflate = READUINT8(save->p);
|
||||
|
||||
players[i].ringboxdelay = READUINT8(save->p);
|
||||
|
|
|
|||
|
|
@ -7850,8 +7850,8 @@ static void P_LoadRecordGhosts(void)
|
|||
|
||||
if (sameGhosts)
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(cv_skin[0].string);
|
||||
if (skin < 0 || !R_SkinUsable(consoleplayer, skin, false))
|
||||
INT32 skin = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
if (skin < 0 || !R_SkinUsable(-1, skin, false))
|
||||
skin = 0; // use default skin
|
||||
add_ghosts(fmt::format("{}-{}{}", gpath, skins[skin].name, modeprefix), sameGhosts);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -469,10 +469,11 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, register los_fu
|
|||
seg_t *seg;
|
||||
INT32 count;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num >= numsubsectors)
|
||||
I_Error("P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
|
||||
#endif
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
|
||||
return true;
|
||||
}
|
||||
|
||||
// haleyjd 02/23/06: this assignment should be after the above check
|
||||
seg = segs + subsectors[num].firstline;
|
||||
|
|
|
|||
23
src/p_spec.c
23
src/p_spec.c
|
|
@ -1906,12 +1906,31 @@ void P_SwitchWeather(preciptype_t newWeather)
|
|||
P_SpawnPrecipitation();
|
||||
}
|
||||
|
||||
static boolean K_IgnoreFinishLine(player_t *player)
|
||||
{
|
||||
// Lightsnake travels to the first waypoint in a straight
|
||||
// line (init).
|
||||
// This has the potential to inadvertently cross a finish
|
||||
// line and remove a lap (happened on Hardhat Havoc).
|
||||
// After the first waypoint, lightsnake follows the
|
||||
// waypoints in order so it's not an issue there.
|
||||
if (player->respawn.state == RESPAWNST_MOVE && player->respawn.init == true)
|
||||
return true;
|
||||
|
||||
// If potential lap cheating has been detected, do not
|
||||
// interact with the finish line at all.
|
||||
if (player->bigwaypointgap)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passed over the finish line forwards
|
||||
static void K_HandleLapIncrement(player_t *player)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
if (player->respawn.state == RESPAWNST_MOVE || player->bigwaypointgap)
|
||||
if (K_IgnoreFinishLine(player))
|
||||
return;
|
||||
if (!G_TimeAttackStart() && leveltime < starttime && !(gametyperules & GTR_ROLLINGSTART))
|
||||
{
|
||||
|
|
@ -2184,7 +2203,7 @@ static void K_HandleLapDecrement(player_t *player)
|
|||
{
|
||||
if (player)
|
||||
{
|
||||
if (player->respawn.state == RESPAWNST_MOVE || player->bigwaypointgap)
|
||||
if (K_IgnoreFinishLine(player))
|
||||
return;
|
||||
if ((player->cheatchecknum == 0) && (player->laps > 0))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1314,13 +1314,13 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
|
|||
PR_SaveProfiles();
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player) && player->skin < numskins)
|
||||
if (P_IsMachineLocalPlayer(player) && player->skin < numskins)
|
||||
{
|
||||
skins[player->skin].records.wins++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!demo.savebutton && P_IsLocalPlayer(player))
|
||||
if (!demo.savebutton && P_IsMachineLocalPlayer(player))
|
||||
demo.savebutton = leveltime;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -909,14 +909,12 @@ static void R_Subsector(size_t num)
|
|||
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num >= numsubsectors)
|
||||
I_Error("R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
|
||||
#endif
|
||||
|
||||
// subsectors added at run-time
|
||||
if (num >= numsubsectors)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
|
||||
return;
|
||||
}
|
||||
|
||||
sub = &subsectors[num];
|
||||
frontsector = sub->sector;
|
||||
|
|
|
|||
|
|
@ -105,12 +105,10 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if constexpr (Type & DrawColumnType::DC_LIGHTLIST)
|
||||
{
|
||||
|
|
@ -341,10 +339,8 @@ void R_DrawFogColumn(drawcolumndata_t *dc)
|
|||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
// Use ylookup LUT to avoid multiply with ScreenWidth.
|
||||
|
|
@ -408,10 +404,8 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc)
|
|||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
// Use ylookup LUT to avoid multiply with ScreenWidth.
|
||||
|
|
|
|||
|
|
@ -1435,7 +1435,7 @@ static void R_ParseSpriteInfoSkin(struct ParseSpriteInfoState *parser)
|
|||
skinName[sprinfoTokenLength] = '\0';
|
||||
strlwr(skinName);
|
||||
|
||||
skinnum = R_SkinAvailable(skinName);
|
||||
skinnum = R_SkinAvailableEx(skinName, false);
|
||||
if (skinnum == -1)
|
||||
I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,15 +136,17 @@ static void Sk_SetDefaultValue(skin_t *skin)
|
|||
}
|
||||
|
||||
// Grab the default skin
|
||||
#define DEFAULTBOTSKINNAME "eggrobo"
|
||||
UINT8 R_BotDefaultSkin(void)
|
||||
{
|
||||
static INT32 defaultbotskin = -1;
|
||||
|
||||
if (demo.playback)
|
||||
return R_SkinAvailableEx(DEFAULTBOTSKINNAME, true);
|
||||
|
||||
if (defaultbotskin == -1)
|
||||
{
|
||||
const char *defaultbotskinname = "eggrobo";
|
||||
|
||||
defaultbotskin = R_SkinAvailable(defaultbotskinname);
|
||||
defaultbotskin = R_SkinAvailableEx(DEFAULTBOTSKINNAME, false);
|
||||
|
||||
if (defaultbotskin == -1)
|
||||
{
|
||||
|
|
@ -155,6 +157,7 @@ UINT8 R_BotDefaultSkin(void)
|
|||
|
||||
return (UINT8)defaultbotskin;
|
||||
}
|
||||
#undef DEFAULTBOTSKINNAME
|
||||
|
||||
//
|
||||
// Initialize the basic skins
|
||||
|
|
@ -226,7 +229,7 @@ UINT8 *R_GetSkinAvailabilities(boolean demolock, INT32 botforcecharacter)
|
|||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins)
|
||||
{
|
||||
boolean needsunlocked = false;
|
||||
boolean useplayerstruct = (Playing() && playernum != -1);
|
||||
boolean useplayerstruct = ((Playing() || demo.playback) && playernum >= 0);
|
||||
UINT16 i;
|
||||
INT32 skinid;
|
||||
|
||||
|
|
@ -296,6 +299,13 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins)
|
|||
return (boolean)(gamedata->unlocked[i]);
|
||||
}
|
||||
|
||||
boolean R_CanShowSkinInDemo(INT32 skinnum)
|
||||
{
|
||||
if (modeattacking == ATTACKING_NONE && !(demo.playback && demo.attract))
|
||||
return true;
|
||||
return R_SkinUsable(-2, skinnum, false);
|
||||
}
|
||||
|
||||
// Returns a random unlocked skin ID.
|
||||
UINT32 R_GetLocalRandomSkin(void)
|
||||
{
|
||||
|
|
@ -304,7 +314,7 @@ UINT32 R_GetLocalRandomSkin(void)
|
|||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
if (!R_SkinUsable(-1, i, false))
|
||||
if (!R_SkinUsable(-2, i, false))
|
||||
continue;
|
||||
grabskins[usableskins++] = i;
|
||||
}
|
||||
|
|
@ -318,10 +328,29 @@ UINT32 R_GetLocalRandomSkin(void)
|
|||
// returns true if the skin name is found (loaded from pwad)
|
||||
// warning return -1 if not found
|
||||
INT32 R_SkinAvailable(const char *name)
|
||||
{
|
||||
return R_SkinAvailableEx(name, true);
|
||||
}
|
||||
|
||||
INT32 R_SkinAvailableEx(const char *name, boolean demoskins)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash = quickncasehash(name, SKINNAMESIZE);
|
||||
|
||||
if (demo.playback && demoskins)
|
||||
{
|
||||
for (i = 0; i < demo.numskins; i++)
|
||||
{
|
||||
if (demo.skinlist[i].namehash != hash)
|
||||
continue;
|
||||
|
||||
if (stricmp(demo.skinlist[i].name,name)!=0)
|
||||
continue;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
if (skins[i].namehash != hash)
|
||||
|
|
@ -357,6 +386,9 @@ engineclass_t R_GetEngineClass(SINT8 speed, SINT8 weight, skinflags_t flags)
|
|||
// Auxillary function that actually sets the skin
|
||||
static void SetSkin(player_t *player, INT32 skinnum)
|
||||
{
|
||||
if (demo.playback)
|
||||
skinnum = demo.skinlist[skinnum].mapping;
|
||||
|
||||
skin_t *skin = &skins[skinnum];
|
||||
|
||||
player->skin = skinnum;
|
||||
|
|
@ -404,9 +436,9 @@ static void SetSkin(player_t *player, INT32 skinnum)
|
|||
// (If your mod locked them all, then you kinda stupid)
|
||||
static INT32 GetPlayerDefaultSkin(INT32 playernum)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 i, skincount = (demo.playback ? demo.numskins : numskins);
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
for (i = 0; i < skincount; i++)
|
||||
{
|
||||
if (R_SkinUsable(playernum, i, false))
|
||||
{
|
||||
|
|
@ -943,7 +975,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
|
|||
// Others can't go in there because we don't want them to be patchable.
|
||||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
INT32 skinnum = R_SkinAvailable(value);
|
||||
INT32 skinnum = R_SkinAvailableEx(value, false);
|
||||
strlwr(value);
|
||||
if (skinnum == -1)
|
||||
STRBUFCPY(skin->name, value);
|
||||
|
|
@ -958,7 +990,7 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
|
|||
snprintf(value2, stringspace,
|
||||
"%s%d", value, numskins);
|
||||
value2[stringspace - 1] = '\0';
|
||||
if (R_SkinAvailable(value2) == -1)
|
||||
if (R_SkinAvailableEx(value2, false) == -1)
|
||||
// I'm lazy so if NEW name is already used I leave the 'skin x'
|
||||
// default skin name set in Sk_SetDefaultValue
|
||||
STRBUFCPY(skin->name, value2);
|
||||
|
|
@ -1138,7 +1170,7 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile)
|
|||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
strlwr(value);
|
||||
skinnum = R_SkinAvailable(value);
|
||||
skinnum = R_SkinAvailableEx(value, false);
|
||||
if (skinnum != -1)
|
||||
skin = &skins[skinnum];
|
||||
else
|
||||
|
|
|
|||
|
|
@ -112,8 +112,10 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile);
|
|||
|
||||
// Access
|
||||
INT32 R_SkinAvailable(const char *name);
|
||||
INT32 R_SkinAvailableEx(const char *name, boolean demoskins);
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum, boolean demoskins);
|
||||
UINT8 *R_GetSkinAvailabilities(boolean demolock, INT32 botforcecharacter);
|
||||
boolean R_CanShowSkinInDemo(INT32 skinnum);
|
||||
|
||||
// Setting
|
||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ INT32 R_ThingLightLevel(mobj_t* thing)
|
|||
{
|
||||
lightlevel -= 255;
|
||||
}
|
||||
|
||||
if (!R_CanShowSkinInDemo((skin_t*)thing->skin-skins)
|
||||
&& !thing->colorized
|
||||
&& !thing->hitlag)
|
||||
{
|
||||
lightlevel -= 128;
|
||||
}
|
||||
}
|
||||
|
||||
return lightlevel;
|
||||
|
|
|
|||
|
|
@ -835,37 +835,42 @@ boolean R_ThingIsFlashing(mobj_t *thing)
|
|||
|
||||
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
|
||||
{
|
||||
if (!(vis->cut & SC_PRECIP) &&
|
||||
R_ThingIsFlashing(vis->mobj))
|
||||
if (vis->cut & SC_PRECIP)
|
||||
{
|
||||
return R_GetTranslationColormap(TC_HITLAG, static_cast<skincolornum_t>(0), GTC_CACHE);
|
||||
// Simplified func, less safe properties to check
|
||||
if (vis->mobj->color)
|
||||
R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
else if (R_SpriteIsFlashing(vis)) // Bosses "flash"
|
||||
|
||||
size_t skinnum = TC_DEFAULT;
|
||||
|
||||
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
{
|
||||
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
|
||||
return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
|
||||
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
|
||||
return R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE);
|
||||
else
|
||||
return R_GetTranslationColormap(TC_BOSS, 0, GTC_CACHE);
|
||||
}
|
||||
*/
|
||||
else if (vis->mobj->color)
|
||||
{
|
||||
// New colormap stuff for skins Tails 06-07-2002
|
||||
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
|
||||
return R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
|
||||
else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||
skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
|
||||
// Hide not-yet-unlocked characters in replays from other people
|
||||
if (!R_CanShowSkinInDemo(skinnum))
|
||||
{
|
||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||
return R_GetTranslationColormap((INT32)skinnum, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
|
||||
skinnum = TC_BLINK;
|
||||
}
|
||||
else // Use the defaults
|
||||
return R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
|
||||
}
|
||||
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
|
||||
return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE);
|
||||
|
||||
if (R_ThingIsFlashing(vis->mobj))
|
||||
{
|
||||
if (skinnum != (size_t)TC_BLINK)
|
||||
skinnum = TC_HITLAG;
|
||||
|
||||
return R_GetTranslationColormap(skinnum, static_cast<skincolornum_t>(0), GTC_CACHE);
|
||||
}
|
||||
|
||||
if (vis->mobj->color)
|
||||
{
|
||||
if (skinnum != (size_t)TC_BLINK && vis->mobj->colorized)
|
||||
skinnum = TC_RAINBOW;
|
||||
|
||||
return R_GetTranslationColormap(skinnum, static_cast<skincolornum_t>(vis->mobj->color), GTC_CACHE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1073,9 +1078,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
}
|
||||
else if (vis->cut & SC_SHEAR)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
pwidth = patch->width;
|
||||
#endif
|
||||
|
||||
// Vertically sheared sprite
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, dc.texturemid -= vis->shear.tan)
|
||||
|
|
@ -1093,7 +1096,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
else
|
||||
{
|
||||
|
||||
#ifdef RANGECHECK
|
||||
#if 0
|
||||
if (vis->x1test && vis->x2test)
|
||||
{
|
||||
INT32 x1test = vis->x1test;
|
||||
|
|
@ -1112,7 +1115,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1));
|
||||
}
|
||||
}
|
||||
#endif // RANGECHECK
|
||||
#endif
|
||||
|
||||
// Non-paper drawing loop
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
|
|
@ -1191,10 +1194,11 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
{
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (texturecolumn < 0 || texturecolumn >= patch->width)
|
||||
I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn");
|
||||
#endif
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n");
|
||||
break;
|
||||
}
|
||||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
|
||||
|
|
@ -1832,10 +1836,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
sortscale = FixedDiv(projectiony[viewssnum], tz);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
if ((size_t)(thing->sprite) >= numsprites)
|
||||
I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite);
|
||||
#endif
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_ProjectSprite: invalid sprite number %d\n", thing->sprite);
|
||||
return;
|
||||
}
|
||||
|
||||
frame = thing->frame&FF_FRAMEMASK;
|
||||
|
||||
|
|
@ -2634,19 +2639,21 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
yscale = FixedDiv(projectiony[viewssnum], tz);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)thing->sprite >= numsprites)
|
||||
I_Error("R_ProjectPrecipitationSprite: invalid sprite number %d ",
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite number %d\n",
|
||||
thing->sprite);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
sprdef = &sprites[thing->sprite];
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((UINT8)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
|
||||
I_Error("R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s",
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s\n",
|
||||
thing->sprite, thing->frame, sprnames[thing->sprite]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];
|
||||
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
|
||||
{"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
|
||||
{"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
|
||||
{"s3k85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering down"},
|
||||
{"s3k85", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR, "Powering down"},
|
||||
{"s3k86", false, 128, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"},
|
||||
{"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
|
||||
{"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic squeak"},
|
||||
|
|
@ -1520,6 +1520,12 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"tmxbdn", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Button down
|
||||
{"tmxbup", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Button up
|
||||
|
||||
// SMS
|
||||
{"sting0", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Ring loss
|
||||
|
||||
// Patching up base sounds
|
||||
{"s226l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // s2 spikes LOUD
|
||||
|
||||
// SRB2kart - Skin sounds
|
||||
{"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR, ""},
|
||||
{"klose", false, 64, 96, -1, NULL, 0, SKSKLOSE, -1, LUMPERROR, ""},
|
||||
|
|
|
|||
|
|
@ -1596,6 +1596,12 @@ typedef enum
|
|||
sfx_tmxbdn,
|
||||
sfx_tmxbup,
|
||||
|
||||
// SMS
|
||||
sfx_sting0,
|
||||
|
||||
// Patch-up
|
||||
sfx_s226l,
|
||||
|
||||
// And LASTLY, Kart's skin sounds.
|
||||
sfx_kwin,
|
||||
sfx_klose,
|
||||
|
|
|
|||
|
|
@ -987,10 +987,8 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
|
|||
UINT8 *dest;
|
||||
const UINT8 *deststop;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (x < 0 || x + width > vid.width || y < 0 || y + height > vid.height || (unsigned)scrn > 4)
|
||||
I_Error("Bad V_DrawBlock");
|
||||
#endif
|
||||
|
||||
dest = screens[scrn] + y*vid.width + x;
|
||||
deststop = screens[scrn] + vid.rowbytes * vid.height;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue