mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge r_things.c/h
Includes r_skins, obviously, but also a little bit of m_cond to make availabilities better for kart's purposes
This commit is contained in:
parent
4b5c7d7510
commit
3f1d58754e
5 changed files with 431 additions and 1391 deletions
34
src/m_cond.h
34
src/m_cond.h
|
|
@ -20,8 +20,8 @@
|
|||
// [required] <optional>
|
||||
typedef enum
|
||||
{
|
||||
UC_PLAYTIME, // PLAYTIME [tics]
|
||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
||||
UC_PLAYTIME, // PLAYTIME [tics]
|
||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
||||
UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle]
|
||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||
|
|
@ -60,11 +60,11 @@ typedef struct
|
|||
#define ET_GLOBAL 0 // Emblem with a position in space
|
||||
#define ET_MAP 1 // Beat the map
|
||||
#define ET_TIME 2 // Get the time
|
||||
//#define ET_DEVTIME 3 // Time, but
|
||||
//#define ET_DEVTIME 3 // Time, but the value is tied to a Time Trial demo, not pre-defined
|
||||
|
||||
// Global emblem flags
|
||||
// (N/A to Kart yet)
|
||||
//#define GE_NIGHTSPULL 1
|
||||
//#define GE_OH 1
|
||||
|
||||
// Map emblem flags
|
||||
#define ME_ENCORE 1
|
||||
|
|
@ -109,21 +109,23 @@ typedef struct
|
|||
#define SECRET_NONE 0 // Does nil. Use with levels locked by UnlockRequired
|
||||
#define SECRET_HEADER 1 // Does nothing on its own, just serves as a header for the menu
|
||||
|
||||
#define SECRET_LEVELSELECT 2 // Selectable level select
|
||||
#define SECRET_SKIN 2 // Allow this character to be selected
|
||||
#define SECRET_WARP 3 // Selectable warp
|
||||
#define SECRET_TIMEATTACK 4 // Enables Time Attack on the main menu
|
||||
#define SECRET_BREAKTHECAPSULES 5 // Enables Break the Capsules on the main menu
|
||||
#define SECRET_SOUNDTEST 6 // Sound Test
|
||||
#define SECRET_CREDITS 7 // Enables Credits
|
||||
#define SECRET_LEVELSELECT 4 // Selectable level select
|
||||
|
||||
#define SECRET_ITEMFINDER 8 // Enables Item Finder/Emblem Radar
|
||||
#define SECRET_EMBLEMHINTS 9 // Enables Emblem Hints
|
||||
#define SECRET_TIMEATTACK 5 // Enables Time Attack on the main menu
|
||||
#define SECRET_BREAKTHECAPSULES 6 // Enables Break the Capsules on the main menu
|
||||
#define SECRET_SOUNDTEST 7 // Sound Test
|
||||
#define SECRET_CREDITS 8 // Enables Credits
|
||||
|
||||
#define SECRET_ENCORE 10 // Enables Encore mode cvar
|
||||
#define SECRET_HARDSPEED 11 // Enables Hard gamespeed
|
||||
#define SECRET_HELLATTACK 12 // Map Hell in record attack
|
||||
#define SECRET_ITEMFINDER 9 // Enables Item Finder/Emblem Radar
|
||||
#define SECRET_EMBLEMHINTS 10 // Enables Emblem Hints
|
||||
|
||||
#define SECRET_PANDORA 13 // Enables Pandora's Box
|
||||
#define SECRET_ENCORE 11 // Enables Encore mode cvar
|
||||
#define SECRET_HARDSPEED 12 // Enables Hard gamespeed
|
||||
#define SECRET_HELLATTACK 13 // Map Hell in record attack
|
||||
|
||||
#define SECRET_PANDORA 14 // Enables Pandora's Box
|
||||
|
||||
// If you have more secrets than these variables allow in your game,
|
||||
// you seriously need to get a life.
|
||||
|
|
@ -174,8 +176,6 @@ const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big);
|
|||
// They stop checking upon reaching the target number so they
|
||||
// should be (theoretically?) slightly faster.
|
||||
UINT8 M_GotEnoughEmblems(INT32 number);
|
||||
//UINT8 M_GotHighEnoughScore(INT32 tscore);
|
||||
UINT8 M_GotLowEnoughTime(INT32 tictime);
|
||||
//UINT8 M_GotHighEnoughRings(INT32 trings);
|
||||
|
||||
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved)
|
||||
|
|
|
|||
447
src/r_skins.c
447
src/r_skins.c
|
|
@ -46,6 +46,11 @@ skin_t skins[MAXSKINS];
|
|||
CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
|
||||
#endif
|
||||
|
||||
CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2];
|
||||
|
||||
// SRB2Kart followers
|
||||
follower_t followers[MAXSKINS];
|
||||
|
||||
//
|
||||
// P_GetSkinSprite2
|
||||
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
|
||||
|
|
@ -125,36 +130,12 @@ static void Sk_SetDefaultValue(skin_t *skin)
|
|||
skin->supercolor = SKINCOLOR_SUPERGOLD1;
|
||||
skin->prefoppositecolor = 0; // use tables
|
||||
|
||||
skin->normalspeed = 36<<FRACBITS;
|
||||
skin->runspeed = 28<<FRACBITS;
|
||||
skin->thrustfactor = 5;
|
||||
skin->accelstart = 96;
|
||||
skin->acceleration = 40;
|
||||
skin->kartspeed = 5;
|
||||
skin->kartweight = 5;
|
||||
|
||||
skin->ability = CA_NONE;
|
||||
skin->ability2 = CA2_SPINDASH;
|
||||
skin->jumpfactor = FRACUNIT;
|
||||
skin->actionspd = 30<<FRACBITS;
|
||||
skin->mindash = 15<<FRACBITS;
|
||||
skin->maxdash = 70<<FRACBITS;
|
||||
|
||||
skin->radius = mobjinfo[MT_PLAYER].radius;
|
||||
skin->height = mobjinfo[MT_PLAYER].height;
|
||||
skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3);
|
||||
|
||||
skin->shieldscale = FRACUNIT;
|
||||
skin->camerascale = FRACUNIT;
|
||||
|
||||
skin->thokitem = -1;
|
||||
skin->spinitem = -1;
|
||||
skin->revitem = -1;
|
||||
skin->followitem = 0;
|
||||
|
||||
skin->highresscale = FRACUNIT;
|
||||
skin->contspeed = 17;
|
||||
skin->contangle = 0;
|
||||
|
||||
skin->availability = 0;
|
||||
|
||||
for (i = 0; i < sfx_skinsoundslot0; i++)
|
||||
if (S_sfx[i].skinsound != -1)
|
||||
|
|
@ -182,14 +163,18 @@ void R_InitSkins(void)
|
|||
|
||||
UINT32 R_GetSkinAvailabilities(void)
|
||||
{
|
||||
INT32 s;
|
||||
UINT8 i;
|
||||
UINT32 response = 0;
|
||||
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
for (i = 0; i < MAXUNLOCKABLES; s++)
|
||||
{
|
||||
if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked)
|
||||
if (unlockables[i].type == SECRET_SKIN && unlockables[i].unlocked)
|
||||
{
|
||||
UINT8 s = min(unlockables[i].variable, MAXSKINS);
|
||||
response |= (1 << s);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
@ -197,14 +182,70 @@ UINT32 R_GetSkinAvailabilities(void)
|
|||
// warning don't use with an invalid skinnum other than -1 which always returns true
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|
||||
|| (!skins[skinnum].availability)
|
||||
|| (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked))
|
||||
|| (modeattacking) // If you have someone else's run you might as well take a look
|
||||
|| (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
|
||||
|| (netgame && (cv_forceskin.value == skinnum)) // Force 2.
|
||||
|| (metalrecording && skinnum == 5) // Force 3.
|
||||
);
|
||||
boolean needsunlocked = false;
|
||||
UINT8 i;
|
||||
|
||||
if (skinnum == -1)
|
||||
{
|
||||
// Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|
||||
return true;
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
// If you have someone else's run, you should be able to take a look
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum))
|
||||
{
|
||||
// Being forced to play as this character by the level
|
||||
return true;
|
||||
}
|
||||
|
||||
if (netgame && (cv_forceskin.value == skinnum))
|
||||
{
|
||||
// Being forced to play as this character by the server
|
||||
return true;
|
||||
}
|
||||
|
||||
if (metalrecording)
|
||||
{
|
||||
// Recording a Metal Sonic race
|
||||
const INT32 metalskin = R_SkinAvailable("metalsonic");
|
||||
return (skinnum == metalskin);
|
||||
}
|
||||
|
||||
// Determine if this character is supposed to be unlockable or not
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
if (unlockables[i].type == SECRET_SKIN && unlockables[i].variable == skinnum)
|
||||
{
|
||||
// i is now the unlockable index, we can use this later
|
||||
needsunlocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsunlocked == true)
|
||||
{
|
||||
// You can use this character IF you have it unlocked.
|
||||
if ((netgame || multiplayer) && playernum != -1)
|
||||
{
|
||||
// Use the netgame synchronized unlocks.
|
||||
return (boolean)(!(players[playernum].availabilities & (1 << skinnum)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the unlockables table directly
|
||||
return (boolean)(unlockables[i].unlocked);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Didn't trip anything, so we can use this character.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the skin name is found (loaded from pwad)
|
||||
|
|
@ -249,50 +290,33 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
player_t *player = &players[playernum];
|
||||
skin_t *skin = &skins[skinnum];
|
||||
UINT16 newcolor = 0;
|
||||
UINT8 i;
|
||||
|
||||
if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists!
|
||||
{
|
||||
player->skin = skinnum;
|
||||
|
||||
player->camerascale = skin->camerascale;
|
||||
player->shieldscale = skin->shieldscale;
|
||||
|
||||
player->charability = (UINT8)skin->ability;
|
||||
player->charability2 = (UINT8)skin->ability2;
|
||||
|
||||
player->charflags = (UINT32)skin->flags;
|
||||
|
||||
player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
|
||||
player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
|
||||
player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
|
||||
player->followitem = skin->followitem;
|
||||
|
||||
if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff.
|
||||
player->powers[pw_shield] &= SH_STACK;
|
||||
player->kartspeed = skin->kartspeed;
|
||||
player->kartweight = skin->kartweight;
|
||||
|
||||
player->actionspd = skin->actionspd;
|
||||
player->mindash = skin->mindash;
|
||||
player->maxdash = skin->maxdash;
|
||||
|
||||
player->normalspeed = skin->normalspeed;
|
||||
player->runspeed = skin->runspeed;
|
||||
player->thrustfactor = skin->thrustfactor;
|
||||
player->accelstart = skin->accelstart;
|
||||
player->acceleration = skin->acceleration;
|
||||
|
||||
player->jumpfactor = skin->jumpfactor;
|
||||
|
||||
player->height = skin->height;
|
||||
player->spinheight = skin->spinheight;
|
||||
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
#if 0
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demo.playback))
|
||||
{
|
||||
if (playernum == consoleplayer)
|
||||
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (playernum == g_localplayers[i])
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[i], skin->prefcolor);
|
||||
}
|
||||
}
|
||||
|
||||
player->skincolor = newcolor = skin->prefcolor;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (player->followmobj)
|
||||
{
|
||||
|
|
@ -302,22 +326,20 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
|
||||
if (player->mo)
|
||||
{
|
||||
fixed_t radius = FixedMul(skin->radius, player->mo->scale);
|
||||
if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
|
||||
{
|
||||
skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
player->followitem = skin->followitem;
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
newcolor = skin->prefcolor; // will be updated in thinker to flashing
|
||||
}
|
||||
player->mo->skin = skin;
|
||||
if (newcolor)
|
||||
player->mo->color = newcolor;
|
||||
P_SetScale(player->mo, player->mo->scale);
|
||||
player->mo->radius = radius;
|
||||
|
||||
if (newcolor)
|
||||
{
|
||||
player->mo->color = newcolor;
|
||||
}
|
||||
|
||||
P_SetScale(player->mo, player->mo->scale);
|
||||
P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames
|
||||
}
|
||||
|
||||
// for replays: We have changed our skin mid-game; let the game know so it can do the same in the replay!
|
||||
demo_extradata[playernum] |= DXD_SKIN;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +347,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
|
||||
SetPlayerSkinByNum(playernum, 0); // not found, put in the default skin
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -434,36 +457,9 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
|
||||
// character type identification
|
||||
FULLPROCESS(flags)
|
||||
FULLPROCESS(ability)
|
||||
FULLPROCESS(ability2)
|
||||
|
||||
FULLPROCESS(thokitem)
|
||||
FULLPROCESS(spinitem)
|
||||
FULLPROCESS(revitem)
|
||||
FULLPROCESS(followitem)
|
||||
#undef FULLPROCESS
|
||||
|
||||
#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
|
||||
GETFRACBITS(normalspeed)
|
||||
GETFRACBITS(runspeed)
|
||||
|
||||
GETFRACBITS(mindash)
|
||||
GETFRACBITS(maxdash)
|
||||
GETFRACBITS(actionspd)
|
||||
|
||||
GETFRACBITS(radius)
|
||||
GETFRACBITS(height)
|
||||
GETFRACBITS(spinheight)
|
||||
#undef GETFRACBITS
|
||||
|
||||
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
|
||||
GETINT(thrustfactor)
|
||||
GETINT(accelstart)
|
||||
GETINT(acceleration)
|
||||
GETINT(contspeed)
|
||||
GETINT(contangle)
|
||||
#undef GETINT
|
||||
|
||||
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
||||
GETSKINCOLOR(prefcolor)
|
||||
GETSKINCOLOR(prefoppositecolor)
|
||||
|
|
@ -472,12 +468,21 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
skin->supercolor = R_GetSuperColorByName(value);
|
||||
|
||||
#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value));
|
||||
GETFLOAT(jumpfactor)
|
||||
GETFLOAT(highresscale)
|
||||
GETFLOAT(shieldscale)
|
||||
GETFLOAT(camerascale)
|
||||
#undef GETFLOAT
|
||||
|
||||
#define GETKARTSTAT(field) \
|
||||
else if (!stricmp(stoken, #field)) \
|
||||
{ \
|
||||
skin->field = atoi(value); \
|
||||
if (skin->field < 1) skin->field = 1; \
|
||||
if (skin->field > 9) skin->field = 9; \
|
||||
}
|
||||
GETKARTSTAT(kartspeed)
|
||||
GETKARTSTAT(kartweight)
|
||||
#undef GETKARTSTAT
|
||||
|
||||
|
||||
#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \
|
||||
strupr(value); \
|
||||
if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \
|
||||
|
|
@ -488,23 +493,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
// parameters for individual character flags
|
||||
// these are uppercase so they can be concatenated with SF_
|
||||
// 1, true, yes are all valid values
|
||||
GETFLAG(SUPER)
|
||||
GETFLAG(NOSUPERSPIN)
|
||||
GETFLAG(NOSPINDASHDUST)
|
||||
GETFLAG(HIRES)
|
||||
GETFLAG(NOSKID)
|
||||
GETFLAG(NOSPEEDADJUST)
|
||||
GETFLAG(RUNONWATER)
|
||||
GETFLAG(NOJUMPSPIN)
|
||||
GETFLAG(NOJUMPDAMAGE)
|
||||
GETFLAG(STOMPDAMAGE)
|
||||
GETFLAG(MARIODAMAGE)
|
||||
GETFLAG(MACHINE)
|
||||
GETFLAG(DASHMODE)
|
||||
GETFLAG(FASTEDGE)
|
||||
GETFLAG(MULTIABILITY)
|
||||
GETFLAG(NONIGHTSROTATION)
|
||||
GETFLAG(NONIGHTSSUPER)
|
||||
#undef GETFLAG
|
||||
|
||||
else // let's check if it's a sound, otherwise error out
|
||||
|
|
@ -557,7 +547,7 @@ void R_AddSkins(UINT16 wadnum)
|
|||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean hudname, realname;
|
||||
boolean realname;
|
||||
|
||||
//
|
||||
// search for all skin markers in pwad
|
||||
|
|
@ -587,7 +577,7 @@ void R_AddSkins(UINT16 wadnum)
|
|||
skin = &skins[numskins];
|
||||
Sk_SetDefaultValue(skin);
|
||||
skin->wadnum = wadnum;
|
||||
hudname = realname = false;
|
||||
realname = false;
|
||||
// parse
|
||||
stoken = strtok (buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
|
|
@ -640,34 +630,51 @@ void R_AddSkins(UINT16 wadnum)
|
|||
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
|
||||
}
|
||||
}
|
||||
if (!hudname)
|
||||
{
|
||||
HUDNAMEWRITE(skin->name);
|
||||
strupr(skin->hudname);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
}
|
||||
}
|
||||
else if (!stricmp(stoken, "realname"))
|
||||
{ // Display name (eg. "Knuckles")
|
||||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!stricmp(stoken, "availability"))
|
||||
else if (!stricmp(stoken, "rivals"))
|
||||
{
|
||||
skin->availability = atoi(value);
|
||||
if (skin->availability >= MAXUNLOCKABLES)
|
||||
skin->availability = 0;
|
||||
size_t len = strlen(value);
|
||||
size_t i;
|
||||
char rivalname[SKINNAMESIZE] = "";
|
||||
UINT8 pos = 0;
|
||||
UINT8 numrivals = 0;
|
||||
|
||||
// Can't use strtok, because this function's already using it.
|
||||
// Using it causes it to upset the saved pointer,
|
||||
// corrupting the reading for the rest of the file.
|
||||
|
||||
// So instead we get to crawl through the value, character by character,
|
||||
// and write it down as we go, until we hit a comma or the end of the string.
|
||||
// Yaaay.
|
||||
|
||||
for (i = 0; i <= len; i++)
|
||||
{
|
||||
if (numrivals >= SKINRIVALS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (value[i] == ',' || i == len)
|
||||
{
|
||||
STRBUFCPY(skin->rivals[numrivals], rivalname);
|
||||
strlwr(skin->rivals[numrivals]);
|
||||
numrivals++;
|
||||
|
||||
memset(rivalname, 0, sizeof (rivalname));
|
||||
pos = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
rivalname[pos] = value[i];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
|
|
@ -690,6 +697,10 @@ next_token:
|
|||
skin_cons_t[numskins].strvalue = skin->name;
|
||||
#endif
|
||||
|
||||
// Update the forceskin possiblevalues
|
||||
Forceskin_cons_t[numskins+1].value = numskins;
|
||||
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddPlayerModel(numskins);
|
||||
|
|
@ -712,7 +723,7 @@ void R_PatchSkins(UINT16 wadnum)
|
|||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean noskincomplain, realname, hudname;
|
||||
boolean noskincomplain, realname;
|
||||
|
||||
//
|
||||
// search for all skin patch markers in pwad
|
||||
|
|
@ -736,7 +747,7 @@ void R_PatchSkins(UINT16 wadnum)
|
|||
buf2[size] = '\0';
|
||||
|
||||
skin = NULL;
|
||||
noskincomplain = realname = hudname = false;
|
||||
noskincomplain = realname = false;
|
||||
|
||||
/*
|
||||
Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation)
|
||||
|
|
@ -780,16 +791,45 @@ void R_PatchSkins(UINT16 wadnum)
|
|||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
else if (!stricmp(stoken, "rivals"))
|
||||
{
|
||||
size_t len = strlen(value);
|
||||
size_t i;
|
||||
char rivalname[SKINNAMESIZE] = "";
|
||||
UINT8 pos = 0;
|
||||
UINT8 numrivals = 0;
|
||||
|
||||
// Can't use strtok, because this function's already using it.
|
||||
// Using it causes it to upset the saved pointer,
|
||||
// corrupting the reading for the rest of the file.
|
||||
|
||||
// So instead we get to crawl through the value, character by character,
|
||||
// and write it down as we go, until we hit a comma or the end of the string.
|
||||
// Yaaay.
|
||||
|
||||
for (i = 0; i <= len; i++)
|
||||
{
|
||||
if (numrivals >= SKINRIVALS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (value[i] == ',' || i == len)
|
||||
{
|
||||
STRBUFCPY(skin->rivals[numrivals], rivalname);
|
||||
strlwr(skin->rivals[numrivals]);
|
||||
numrivals++;
|
||||
|
||||
memset(rivalname, 0, sizeof (rivalname));
|
||||
pos = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
rivalname[pos] = value[i];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
|
|
@ -824,3 +864,92 @@ next_token:
|
|||
|
||||
#undef HUDNAMEWRITE
|
||||
#undef SYMBOLCONVERT
|
||||
|
||||
// SRB2Kart: Followers!
|
||||
// TODO: put this stuff in its own file?
|
||||
|
||||
// same thing as R_SkinAvailable, but for followers
|
||||
INT32 R_FollowerAvailable(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < numfollowers; i++)
|
||||
{
|
||||
if (stricmp(followers[i].skinname,name)==0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// same thing as SetPlayerSkin, but for followers
|
||||
boolean SetPlayerFollower(INT32 playernum, const char *skinname)
|
||||
{
|
||||
INT32 i;
|
||||
player_t *player = &players[playernum];
|
||||
|
||||
for (i = 0; i < numfollowers; i++)
|
||||
{
|
||||
// search in the skin list
|
||||
if (stricmp(followers[i].skinname, skinname) == 0)
|
||||
{
|
||||
SetFollower(playernum, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower '%s' not found.\n"), skinname);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) follower '%s' not found\n"), playernum, player_names[playernum], skinname);
|
||||
|
||||
SetFollower(playernum, -1); // reminder that -1 is nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
// SetPlayerSkinByNum, for followers
|
||||
void SetFollower(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
player_t *player = &players[playernum];
|
||||
mobj_t *bub;
|
||||
mobj_t *tmp;
|
||||
|
||||
player->followerready = true; // we are ready to perform follower related actions in the player thinker, now.
|
||||
|
||||
if (skinnum >= -1 && skinnum <= numfollowers) // Make sure it exists!
|
||||
{
|
||||
/*
|
||||
We don't spawn the follower here since it'll be easier to handle all of it in the Player thinker itself.
|
||||
However, we will despawn it right here if there's any to make it easy for the player thinker to replace it or delete it.
|
||||
*/
|
||||
|
||||
if (player->follower && skinnum != player->followerskin) // this is also called when we change colour so don't respawn the follower unless we changed skins
|
||||
{
|
||||
// Remove follower's possible hnext list (bubble)
|
||||
bub = player->follower->hnext;
|
||||
|
||||
while (bub && !P_MobjWasRemoved(bub))
|
||||
{
|
||||
tmp = bub->hnext;
|
||||
P_RemoveMobj(bub);
|
||||
bub = tmp;
|
||||
}
|
||||
|
||||
P_RemoveMobj(player->follower);
|
||||
P_SetTarget(&player->follower, NULL);
|
||||
}
|
||||
|
||||
player->followerskin = skinnum;
|
||||
|
||||
// for replays: We have changed our follower mid-game; let the game know so it can do the same in the replay!
|
||||
demo_extradata[playernum] |= DXD_FOLLOWER;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) follower %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
|
||||
SetFollower(playernum, -1); // Not found, then set -1 (nothing) as our follower.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,12 @@
|
|||
|
||||
/// Defaults
|
||||
#define SKINNAMESIZE 16
|
||||
#define SKINRIVALS 3
|
||||
// should be all lowercase!! S_SKIN processing does a strlwr
|
||||
#define DEFAULTSKIN "sonic"
|
||||
#define DEFAULTSKIN "eggman"
|
||||
#define DEFAULTSKIN2 "tails" // secondary player
|
||||
#define DEFAULTNIGHTSSKIN 0
|
||||
#define DEFAULTSKIN3 "sonic" // third player
|
||||
#define DEFAULTSKIN4 "knuckles" // fourth player
|
||||
|
||||
/// The skin_t struct
|
||||
typedef struct
|
||||
|
|
@ -35,33 +37,11 @@ typedef struct
|
|||
skinflags_t flags;
|
||||
|
||||
char realname[SKINNAMESIZE+1]; // Display name for level completion.
|
||||
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
|
||||
|
||||
UINT8 ability; // ability definition
|
||||
UINT8 ability2; // secondary ability definition
|
||||
INT32 thokitem;
|
||||
INT32 spinitem;
|
||||
INT32 revitem;
|
||||
UINT8 kartspeed;
|
||||
UINT8 kartweight;
|
||||
|
||||
INT32 followitem;
|
||||
fixed_t actionspd;
|
||||
fixed_t mindash;
|
||||
fixed_t maxdash;
|
||||
|
||||
fixed_t normalspeed; // Normal ground
|
||||
fixed_t runspeed; // Speed that you break into your run animation
|
||||
|
||||
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
|
||||
UINT8 accelstart; // Acceleration if speed = 0
|
||||
UINT8 acceleration; // Acceleration
|
||||
|
||||
fixed_t jumpfactor; // multiple of standard jump height
|
||||
|
||||
fixed_t radius; // Bounding box changes.
|
||||
fixed_t height;
|
||||
fixed_t spinheight;
|
||||
|
||||
fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size
|
||||
fixed_t camerascale;
|
||||
|
||||
// Definable color translation table
|
||||
UINT8 starttranscolor;
|
||||
|
|
@ -70,8 +50,6 @@ typedef struct
|
|||
UINT16 prefoppositecolor; // if 0 use tables instead
|
||||
|
||||
fixed_t highresscale; // scale of highres, default is 0.5
|
||||
UINT8 contspeed; // continue screen animation speed
|
||||
UINT8 contangle; // initial angle on continue screen
|
||||
|
||||
// specific sounds per skin
|
||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||
|
|
@ -80,13 +58,15 @@ typedef struct
|
|||
spritedef_t sprites[NUMPLAYERSPRITES*2];
|
||||
spriteinfo_t sprinfo[NUMPLAYERSPRITES*2];
|
||||
|
||||
UINT8 availability; // lock?
|
||||
char rivals[SKINRIVALS][SKINNAMESIZE+1]; // Your top 3 rivals for GP mode. Uses names so that you can reference skins that aren't added
|
||||
} skin_t;
|
||||
|
||||
/// Externs
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
|
||||
extern CV_PossibleValue_t Forceskin_cons_t[];
|
||||
|
||||
/// Function prototypes
|
||||
void R_InitSkins(void);
|
||||
|
||||
|
|
@ -100,4 +80,51 @@ void R_AddSkins(UINT16 wadnum);
|
|||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);
|
||||
|
||||
// SRB2Kart Followers
|
||||
|
||||
//
|
||||
// We'll define these here because they're really just a mobj that'll follow some rules behind a player
|
||||
//
|
||||
typedef struct follower_s
|
||||
{
|
||||
char skinname[SKINNAMESIZE+1]; // Skin Name. This is what to refer to when asking the commands anything.
|
||||
char name[SKINNAMESIZE+1]; // Name. This is used for the menus. We'll just follow the same rules as skins for this.
|
||||
|
||||
UINT8 defaultcolor; // default color for menus.
|
||||
|
||||
fixed_t scale; // Scale relative to the player's.
|
||||
fixed_t bubblescale; // Bubble scale relative to the player scale. If not set, no bubble will spawn (default)
|
||||
|
||||
// some position shenanigans:
|
||||
INT32 atangle; // angle the object will be at around the player. The object itself will always face the same direction as the player.
|
||||
INT32 dist; // distance relative to the player. (In a circle)
|
||||
INT32 height; // height of the follower, this is mostly important for Z flipping.
|
||||
INT32 zoffs; // Z offset relative to the player's height. Cannot be negative.
|
||||
|
||||
// movement options
|
||||
|
||||
INT32 horzlag; // Lag for X/Y displacement. Default is 2. Must be > 0 because we divide by this number.
|
||||
INT32 vertlag; // not Vert from Neptunia lagging, this is for Z displacement lag Default is 6. Must be > 0 because we divide by this number.
|
||||
INT32 bobamp; // Bob amplitude. Default is 4.
|
||||
INT32 bobspeed; // Arbitrary modifier for bobbing speed, default is TICRATE*2 (70).
|
||||
|
||||
// from there on out, everything is STATES to allow customization
|
||||
// these are only set once when the action is performed and are then free to animate however they want.
|
||||
|
||||
INT32 idlestate; // state when the player is at a standstill
|
||||
INT32 followstate; // state when the player is moving
|
||||
INT32 hurtstate; // state when the player is being hurt
|
||||
INT32 winstate; // state when the player has won
|
||||
INT32 losestate; // state when the player has lost
|
||||
INT32 hitconfirmstate; // state for hit confirm
|
||||
INT32 hitconfirmtime; // time to keep the above playing for
|
||||
} follower_t;
|
||||
|
||||
extern INT32 numfollowers;
|
||||
extern follower_t followers[MAXSKINS]; // again, use the same rules as skins, no reason not to.
|
||||
|
||||
INT32 R_FollowerAvailable(const char *name);
|
||||
boolean SetPlayerFollower(INT32 playernum,const char *skinname);
|
||||
void SetFollower(INT32 playernum,INT32 skinnum);
|
||||
|
||||
#endif //__R_SKINS__
|
||||
|
|
|
|||
1172
src/r_things.c
1172
src/r_things.c
File diff suppressed because it is too large
Load diff
|
|
@ -53,20 +53,12 @@ void R_DrawFlippedMaskedColumn(column_t *column);
|
|||
// SPRITE RENDERING
|
||||
// ----------------
|
||||
|
||||
<<<<<<< HEAD
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
#ifdef DELFILE
|
||||
void R_DelSpriteDefs(UINT16 wadnum);
|
||||
#endif
|
||||
=======
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
>>>>>>> srb2/next
|
||||
|
||||
//SoM: 6/5/2000: Light sprites correctly!
|
||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
|
|
@ -74,19 +66,7 @@ void R_InitSprites(void);
|
|||
void R_ClearSprites(void);
|
||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
||||
|
||||
<<<<<<< HEAD
|
||||
// -----------
|
||||
// SKINS STUFF
|
||||
// -----------
|
||||
#define SKINNAMESIZE 16
|
||||
// should be all lowercase!! S_SKIN processing does a strlwr
|
||||
#define DEFAULTSKIN "sonic"
|
||||
#define DEFAULTSKIN2 "tails" // secondary player
|
||||
#define DEFAULTSKIN3 "knuckles" // third player
|
||||
#define DEFAULTSKIN4 "eggman" // fourth player
|
||||
=======
|
||||
boolean R_ThingVisible (mobj_t *thing);
|
||||
>>>>>>> srb2/next
|
||||
|
||||
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||
fixed_t draw_dist,
|
||||
|
|
@ -104,37 +84,6 @@ boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
|
||||
spritedef_t spritedef;
|
||||
UINT16 wadnum;
|
||||
char sprite[4]; // Sprite name, if seperated from S_SKIN.
|
||||
skinflags_t flags;
|
||||
|
||||
char realname[SKINNAMESIZE+1]; // Display name for level completion.
|
||||
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
|
||||
char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps
|
||||
|
||||
// SRB2kart
|
||||
UINT8 kartspeed;
|
||||
UINT8 kartweight;
|
||||
//
|
||||
|
||||
// Definable color translation table
|
||||
UINT8 starttranscolor;
|
||||
UINT8 prefcolor;
|
||||
fixed_t highresscale; // scale of highres, default is 0.5
|
||||
|
||||
// specific sounds per skin
|
||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||
} skin_t;
|
||||
|
||||
extern CV_PossibleValue_t Forceskin_cons_t[];
|
||||
|
||||
// -----------
|
||||
// NOT SKINS STUFF !
|
||||
// -----------
|
||||
=======
|
||||
size_t drawsegs[2];
|
||||
size_t vissprites[2];
|
||||
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
|
||||
|
|
@ -155,7 +104,6 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
|
|||
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
|
||||
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
|
||||
|
||||
>>>>>>> srb2/next
|
||||
typedef enum
|
||||
{
|
||||
// actual cuts
|
||||
|
|
@ -164,20 +112,12 @@ typedef enum
|
|||
SC_BOTTOM = 1<<1,
|
||||
// other flags
|
||||
SC_PRECIP = 1<<2,
|
||||
<<<<<<< HEAD
|
||||
//SC_LINKDRAW = 1<<3, -- 2.2 compat
|
||||
SC_LINKDRAW = 1<<3,
|
||||
SC_FULLBRIGHT = 1<<4,
|
||||
SC_SEMIBRIGHT = 1<<5,
|
||||
SC_VFLIP = 1<<6,
|
||||
SC_ISSCALED = 1<<7,
|
||||
SC_SHADOW = 1<<8,
|
||||
=======
|
||||
SC_LINKDRAW = 1<<3,
|
||||
SC_FULLBRIGHT = 1<<4,
|
||||
SC_VFLIP = 1<<5,
|
||||
SC_ISSCALED = 1<<6,
|
||||
SC_SHADOW = 1<<7,
|
||||
>>>>>>> srb2/next
|
||||
// masks
|
||||
SC_CUTMASK = SC_TOP|SC_BOTTOM,
|
||||
SC_FLAGMASK = ~SC_CUTMASK
|
||||
|
|
@ -203,13 +143,8 @@ typedef struct vissprite_s
|
|||
fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors
|
||||
|
||||
fixed_t startfrac; // horizontal position of x1
|
||||
<<<<<<< HEAD
|
||||
fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites
|
||||
fixed_t scalestep; // only for flat sprites, 0 otherwise
|
||||
=======
|
||||
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
||||
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
||||
>>>>>>> srb2/next
|
||||
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
||||
fixed_t xiscale; // negative if flipped
|
||||
|
||||
|
|
@ -268,21 +203,6 @@ typedef struct drawnode_s
|
|||
struct drawnode_s *prev;
|
||||
} drawnode_t;
|
||||
|
||||
<<<<<<< HEAD
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
|
||||
boolean SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||
INT32 R_SkinAvailable(const char *name);
|
||||
void R_AddSkins(UINT16 wadnum);
|
||||
|
||||
#ifdef DELFILE
|
||||
void R_DelSkins(UINT16 wadnum);
|
||||
#endif
|
||||
|
||||
=======
|
||||
>>>>>>> srb2/next
|
||||
void R_InitDrawNodes(void);
|
||||
|
||||
// -----------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue