mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into spindash
This commit is contained in:
commit
25e9c72bab
36 changed files with 2493 additions and 502 deletions
|
|
@ -1,3 +1,4 @@
|
|||
# vim: ft=make
|
||||
#
|
||||
# Makefile.cfg for SRB2
|
||||
#
|
||||
|
|
@ -7,6 +8,66 @@
|
|||
# and other things
|
||||
#
|
||||
|
||||
# See the following variable don't start with 'GCC'. This is
|
||||
# to avoid a false positive with the version detection...
|
||||
|
||||
SUPPORTED_GCC_VERSIONS:=\
|
||||
91\
|
||||
81 82 83\
|
||||
71 72\
|
||||
61 62 63 64\
|
||||
51 52 53 54\
|
||||
40 41 42 43 44 45 46 47 48 49
|
||||
|
||||
LATEST_GCC_VERSION=9.1
|
||||
|
||||
# gcc or g++
|
||||
ifdef PREFIX
|
||||
CC=$(PREFIX)-gcc
|
||||
CXX=$(PREFIX)-g++
|
||||
OBJCOPY=$(PREFIX)-objcopy
|
||||
OBJDUMP=$(PREFIX)-objdump
|
||||
STRIP=$(PREFIX)-strip
|
||||
WINDRES=$(PREFIX)-windres
|
||||
else
|
||||
OBJCOPY=objcopy
|
||||
OBJDUMP=objdump
|
||||
STRIP=strip
|
||||
WINDRES=windres
|
||||
endif
|
||||
|
||||
# because Apple screws with us on this
|
||||
# need to get bintools from homebrew
|
||||
ifdef MACOSX
|
||||
CC=clang
|
||||
CXX=clang
|
||||
OBJCOPY=gobjcopy
|
||||
OBJDUMP=gobjdump
|
||||
endif
|
||||
|
||||
# Automatically set version flag, but not if one was manually set
|
||||
ifeq (,$(filter GCC%,$(.VARIABLES)))
|
||||
ifneq (,$(findstring gcc,$(shell $(CC) --version))) # if it's GCC
|
||||
version:=$(shell $(CC) -dumpversion)
|
||||
|
||||
# Turn version into words of major, minor
|
||||
v:=$(subst ., ,$(version))
|
||||
# concat. major minor
|
||||
v:=$(word 1,$(v))$(word 2,$(v))
|
||||
|
||||
# If this version is not in the list, default to the latest supported
|
||||
ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS)))
|
||||
$(info\
|
||||
Your compiler version, GCC $(version), is not supported by the Makefile.\
|
||||
The Makefile will assume GCC $(LATEST_GCC_VERSION).)
|
||||
GCC$(subst .,,$(LATEST_GCC_VERSION))=1
|
||||
else
|
||||
$(info Detected GCC $(version) (GCC$(v)))
|
||||
GCC$(v)=1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef GCC91
|
||||
GCC83=1
|
||||
endif
|
||||
|
|
@ -134,6 +195,9 @@ endif
|
|||
ifndef GCC295
|
||||
WFLAGS+=-Wendif-labels
|
||||
endif
|
||||
ifdef GCC40
|
||||
WFLAGS+=-std=gnu89
|
||||
endif
|
||||
ifdef GCC41
|
||||
WFLAGS+=-Wshadow
|
||||
endif
|
||||
|
|
@ -463,30 +527,6 @@ ifdef ARCHNAME
|
|||
BIN:=$(BIN)/$(ARCHNAME)
|
||||
endif
|
||||
|
||||
# gcc or g++
|
||||
ifdef PREFIX
|
||||
CC=$(PREFIX)-gcc
|
||||
CXX=$(PREFIX)-g++
|
||||
OBJCOPY=$(PREFIX)-objcopy
|
||||
OBJDUMP=$(PREFIX)-objdump
|
||||
STRIP=$(PREFIX)-strip
|
||||
WINDRES=$(PREFIX)-windres
|
||||
else
|
||||
OBJCOPY=objcopy
|
||||
OBJDUMP=objdump
|
||||
STRIP=strip
|
||||
WINDRES=windres
|
||||
endif
|
||||
|
||||
# because Apple screws with us on this
|
||||
# need to get bintools from homebrew
|
||||
ifdef MACOSX
|
||||
CC=clang
|
||||
CXX=clang
|
||||
OBJCOPY=gobjcopy
|
||||
OBJDUMP=gobjdump
|
||||
endif
|
||||
|
||||
OBJDUMP_OPTS?=--wide --source --line-numbers
|
||||
LD=$(CC)
|
||||
|
||||
|
|
|
|||
322
src/d_netcmd.c
322
src/d_netcmd.c
|
|
@ -116,6 +116,16 @@ static void Skin_OnChange(void);
|
|||
static void Skin2_OnChange(void);
|
||||
static void Skin3_OnChange(void);
|
||||
static void Skin4_OnChange(void);
|
||||
|
||||
static void Follower_OnChange(void);
|
||||
static void Follower2_OnChange(void);
|
||||
static void Follower3_OnChange(void);
|
||||
static void Follower4_OnChange(void);
|
||||
static void Followercolor_OnChange(void);
|
||||
static void Followercolor2_OnChange(void);
|
||||
static void Followercolor3_OnChange(void);
|
||||
static void Followercolor4_OnChange(void);
|
||||
|
||||
static void Color_OnChange(void);
|
||||
static void Color2_OnChange(void);
|
||||
static void Color3_OnChange(void);
|
||||
|
|
@ -292,6 +302,23 @@ consvar_t cv_skin2 = {"skin2", DEFAULTSKIN2, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Sk
|
|||
consvar_t cv_skin3 = {"skin3", DEFAULTSKIN3, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_skin4 = {"skin4", DEFAULTSKIN4, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// player's followers. Also saved.
|
||||
consvar_t cv_follower = {"follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_follower2 = {"follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_follower3 = {"follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_follower4 = {"follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// player's follower colors... Also saved...
|
||||
consvar_t cv_followercolor = {"followercolor", "Match", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_followercolor2 = {"followercolor2", "Match", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_followercolor3 = {"followercolor3", "Match", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor3_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_followercolor4 = {"followercolor4", "Match", CV_SAVE|CV_CALL|CV_NOINIT, Followercolor_cons_t, Followercolor4_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
||||
// Follower toggle
|
||||
static CV_PossibleValue_t followers_cons_t[] = {{0, "Yours only"}, {1, "Everyone's"}, {0, NULL}};
|
||||
consvar_t cv_showfollowers = {"showfollowers", "Everyone's", CV_SAVE, followers_cons_t, 0, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_skipmapcheck = {"skipmapcheck", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
INT32 cv_debug;
|
||||
|
|
@ -804,11 +831,17 @@ void D_RegisterClientCommands(void)
|
|||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
Color_cons_t[i].value = i;
|
||||
Color_cons_t[i].strvalue = KartColor_Names[i]; // SRB2kart
|
||||
Color_cons_t[i].value = Followercolor_cons_t[i].value = i;
|
||||
Color_cons_t[i].strvalue = Followercolor_cons_t[i].strvalue = KartColor_Names[i]; // SRB2kart
|
||||
}
|
||||
Color_cons_t[MAXSKINCOLORS].value = 0;
|
||||
Color_cons_t[MAXSKINCOLORS].strvalue = NULL;
|
||||
Color_cons_t[MAXSKINCOLORS].value = Followercolor_cons_t[MAXSKINCOLORS+2].value = 0;
|
||||
Color_cons_t[MAXSKINCOLORS].strvalue = Followercolor_cons_t[MAXSKINCOLORS+2].strvalue = NULL;
|
||||
|
||||
Followercolor_cons_t[MAXSKINCOLORS].value = MAXSKINCOLORS;
|
||||
Followercolor_cons_t[MAXSKINCOLORS].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's
|
||||
|
||||
Followercolor_cons_t[MAXSKINCOLORS+1].value = MAXSKINCOLORS+1;
|
||||
Followercolor_cons_t[MAXSKINCOLORS+1].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite.
|
||||
|
||||
if (dedicated)
|
||||
return;
|
||||
|
|
@ -880,18 +913,27 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_playername);
|
||||
CV_RegisterVar(&cv_playercolor);
|
||||
CV_RegisterVar(&cv_skin); // r_things.c (skin NAME)
|
||||
CV_RegisterVar(&cv_follower);
|
||||
CV_RegisterVar(&cv_followercolor);
|
||||
CV_RegisterVar(&cv_showfollowers);
|
||||
// secondary player (splitscreen)
|
||||
CV_RegisterVar(&cv_playername2);
|
||||
CV_RegisterVar(&cv_playercolor2);
|
||||
CV_RegisterVar(&cv_skin2);
|
||||
CV_RegisterVar(&cv_follower2);
|
||||
CV_RegisterVar(&cv_followercolor2);
|
||||
// third player
|
||||
CV_RegisterVar(&cv_playername3);
|
||||
CV_RegisterVar(&cv_playercolor3);
|
||||
CV_RegisterVar(&cv_skin3);
|
||||
CV_RegisterVar(&cv_follower3);
|
||||
CV_RegisterVar(&cv_followercolor3);
|
||||
// fourth player
|
||||
CV_RegisterVar(&cv_playername4);
|
||||
CV_RegisterVar(&cv_playercolor4);
|
||||
CV_RegisterVar(&cv_skin4);
|
||||
CV_RegisterVar(&cv_follower4);
|
||||
CV_RegisterVar(&cv_followercolor4);
|
||||
// preferred number of players
|
||||
CV_RegisterVar(&cv_splitplayers);
|
||||
|
||||
|
|
@ -1449,7 +1491,7 @@ static INT32 snacpending = 0, snac2pending = 0, snac3pending = 0, snac4pending =
|
|||
//
|
||||
static void SendNameAndColor(void)
|
||||
{
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+3];
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
|
|
@ -1474,10 +1516,13 @@ static void SendNameAndColor(void)
|
|||
CV_StealthSet(&cv_playercolor, cv_playercolor.defaultvalue);
|
||||
}
|
||||
|
||||
if (!strcmp(cv_playername.string, player_names[consoleplayer])
|
||||
&& cv_playercolor.value == players[consoleplayer].skincolor
|
||||
&& !strcmp(cv_skin.string, skins[players[consoleplayer].skin].name))
|
||||
return;
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor.value)
|
||||
CV_StealthSet(&cv_followercolor, "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
|
||||
// so like, this is sent before we even use anything like cvars or w/e so it's possible that follower is set to a pretty yikes value, so let's fix that before we send garbage that could crash the game:
|
||||
if (cv_follower.value > numfollowers-1 || cv_follower.value < -1)
|
||||
CV_StealthSet(&cv_follower, "-1");
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
|
|
@ -1496,6 +1541,10 @@ static void SendNameAndColor(void)
|
|||
if (players[consoleplayer].mo)
|
||||
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
|
||||
|
||||
// Update follower for local games:
|
||||
if (cv_follower.value >= -1 && cv_follower.value != players[consoleplayer].followerskin)
|
||||
SetFollower(consoleplayer, cv_follower.value);
|
||||
|
||||
if (metalrecording)
|
||||
{ // Metal Sonic is Sonic, obviously.
|
||||
SetPlayerSkinByNum(consoleplayer, 0);
|
||||
|
|
@ -1559,6 +1608,8 @@ static void SendNameAndColor(void)
|
|||
WRITESTRINGN(p, cv_playername.zstring, MAXPLAYERNAME);
|
||||
WRITEUINT8(p, (UINT8)cv_playercolor.value);
|
||||
WRITEUINT8(p, (UINT8)cv_skin.value);
|
||||
WRITESINT8(p, (UINT8)cv_follower.value);
|
||||
WRITESINT8(p, (UINT8)cv_followercolor.value);
|
||||
SendNetXCmd(XD_NAMEANDCOLOR, buf, p - buf);
|
||||
}
|
||||
|
||||
|
|
@ -1566,7 +1617,7 @@ static void SendNameAndColor(void)
|
|||
static void SendNameAndColor2(void)
|
||||
{
|
||||
INT32 secondplaya = -1;
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+3];
|
||||
char *p;
|
||||
|
||||
if (splitscreen < 1)
|
||||
|
|
@ -1602,6 +1653,14 @@ static void SendNameAndColor2(void)
|
|||
CV_StealthSet(&cv_playercolor2, cv_playercolor2.defaultvalue);
|
||||
}
|
||||
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor2.value)
|
||||
CV_StealthSet(&cv_followercolor2, "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
|
||||
// so like, this is sent before we even use anything like cvars or w/e so it's possible that follower is set to a pretty yikes value, so let's fix that before we send garbage that could crash the game:
|
||||
if (cv_follower2.value > numfollowers-1 || cv_follower2.value < -1)
|
||||
CV_StealthSet(&cv_follower2, "-1");
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
|
@ -1619,6 +1678,10 @@ static void SendNameAndColor2(void)
|
|||
if (players[secondplaya].mo)
|
||||
players[secondplaya].mo->color = players[secondplaya].skincolor;
|
||||
|
||||
// Update follower for local games:
|
||||
if (cv_follower2.value >= -1 && cv_follower2.value != players[secondplaya].followerskin)
|
||||
SetFollower(secondplaya, cv_follower2.value);
|
||||
|
||||
if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1)
|
||||
{
|
||||
//boolean notsame;
|
||||
|
|
@ -1675,13 +1738,15 @@ static void SendNameAndColor2(void)
|
|||
WRITESTRINGN(p, cv_playername2.zstring, MAXPLAYERNAME);
|
||||
WRITEUINT8(p, (UINT8)cv_playercolor2.value);
|
||||
WRITEUINT8(p, (UINT8)cv_skin2.value);
|
||||
WRITESINT8(p, (UINT8)cv_follower2.value);
|
||||
WRITESINT8(p, (UINT8)cv_followercolor2.value);
|
||||
SendNetXCmd2(XD_NAMEANDCOLOR, buf, p - buf);
|
||||
}
|
||||
|
||||
static void SendNameAndColor3(void)
|
||||
{
|
||||
INT32 thirdplaya = -1;
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+3];
|
||||
char *p;
|
||||
|
||||
if (splitscreen < 2)
|
||||
|
|
@ -1706,6 +1771,10 @@ static void SendNameAndColor3(void)
|
|||
CV_StealthSetValue(&cv_playercolor3, skincolor_blueteam);
|
||||
}
|
||||
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor3.value)
|
||||
CV_StealthSet(&cv_followercolor3, "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
|
||||
// never allow the color "none"
|
||||
if (!cv_playercolor3.value)
|
||||
{
|
||||
|
|
@ -1717,6 +1786,10 @@ static void SendNameAndColor3(void)
|
|||
CV_StealthSet(&cv_playercolor3, cv_playercolor3.defaultvalue);
|
||||
}
|
||||
|
||||
// so like, this is sent before we even use anything like cvars or w/e so it's possible that follower is set to a pretty yikes value, so let's fix that before we send garbage that could crash the game:
|
||||
if (cv_follower3.value > numfollowers-1 || cv_follower3.value < -1)
|
||||
CV_StealthSet(&cv_follower3, "-1");
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
|
@ -1734,6 +1807,10 @@ static void SendNameAndColor3(void)
|
|||
if (players[thirdplaya].mo)
|
||||
players[thirdplaya].mo->color = players[thirdplaya].skincolor;
|
||||
|
||||
// Update follower for local games:
|
||||
if (cv_follower3.value >= -1 && cv_follower3.value != players[thirdplaya].followerskin)
|
||||
SetFollower(thirdplaya, cv_follower3.value);
|
||||
|
||||
if ((foundskin = R_SkinAvailable(cv_skin3.string)) != -1)
|
||||
{
|
||||
//boolean notsame;
|
||||
|
|
@ -1790,13 +1867,15 @@ static void SendNameAndColor3(void)
|
|||
WRITESTRINGN(p, cv_playername3.zstring, MAXPLAYERNAME);
|
||||
WRITEUINT8(p, (UINT8)cv_playercolor3.value);
|
||||
WRITEUINT8(p, (UINT8)cv_skin3.value);
|
||||
WRITESINT8(p, (UINT8)cv_follower3.value);
|
||||
WRITESINT8(p, (UINT8)cv_followercolor3.value);
|
||||
SendNetXCmd3(XD_NAMEANDCOLOR, buf, p - buf);
|
||||
}
|
||||
|
||||
static void SendNameAndColor4(void)
|
||||
{
|
||||
INT32 fourthplaya = -1;
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||
XBOXSTATIC char buf[MAXPLAYERNAME+3];
|
||||
char *p;
|
||||
|
||||
if (splitscreen < 3)
|
||||
|
|
@ -1821,6 +1900,10 @@ static void SendNameAndColor4(void)
|
|||
CV_StealthSetValue(&cv_playercolor4, skincolor_blueteam);
|
||||
}
|
||||
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor4.value)
|
||||
CV_StealthSet(&cv_followercolor4, "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
|
||||
// never allow the color "none"
|
||||
if (!cv_playercolor4.value)
|
||||
{
|
||||
|
|
@ -1832,6 +1915,10 @@ static void SendNameAndColor4(void)
|
|||
CV_StealthSet(&cv_playercolor4, cv_playercolor4.defaultvalue);
|
||||
}
|
||||
|
||||
// so like, this is sent before we even use anything like cvars or w/e so it's possible that follower is set to a pretty yikes value, so let's fix that before we send garbage that could crash the game:
|
||||
if (cv_follower4.value > numfollowers-1 || cv_follower4.value < -1)
|
||||
CV_StealthSet(&cv_follower4, "-1");
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
|
@ -1849,6 +1936,10 @@ static void SendNameAndColor4(void)
|
|||
if (players[fourthplaya].mo)
|
||||
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
|
||||
|
||||
// Update follower for local games:
|
||||
if (cv_follower4.value >= -1 && cv_follower4.value != players[fourthplaya].followerskin)
|
||||
SetFollower(fourthplaya, cv_follower4.value);
|
||||
|
||||
if ((foundskin = R_SkinAvailable(cv_skin4.string)) != -1)
|
||||
{
|
||||
//boolean notsame;
|
||||
|
|
@ -1905,6 +1996,8 @@ static void SendNameAndColor4(void)
|
|||
WRITESTRINGN(p, cv_playername4.zstring, MAXPLAYERNAME);
|
||||
WRITEUINT8(p, (UINT8)cv_playercolor4.value);
|
||||
WRITEUINT8(p, (UINT8)cv_skin4.value);
|
||||
WRITESINT8(p, (UINT8)cv_follower4.value);
|
||||
WRITESINT8(p, (UINT8)cv_followercolor4.value);
|
||||
SendNetXCmd4(XD_NAMEANDCOLOR, buf, p - buf);
|
||||
}
|
||||
|
||||
|
|
@ -1912,7 +2005,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
player_t *p = &players[playernum];
|
||||
char name[MAXPLAYERNAME+1];
|
||||
UINT8 color, skin;
|
||||
UINT8 color, skin, followercolor;
|
||||
SINT8 follower;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (playernum < 0 || playernum > MAXPLAYERS)
|
||||
|
|
@ -1936,6 +2030,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
READSTRINGN(*cp, name, MAXPLAYERNAME);
|
||||
color = READUINT8(*cp);
|
||||
skin = READUINT8(*cp);
|
||||
follower = READSINT8(*cp);
|
||||
followercolor = READSINT8(*cp);
|
||||
|
||||
// set name
|
||||
if (strcasecmp(player_names[playernum], name) != 0)
|
||||
|
|
@ -1995,6 +2091,13 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
else
|
||||
SetPlayerSkinByNum(playernum, skin);
|
||||
|
||||
// set follower colour:
|
||||
// Don't bother doing garbage and kicking if we receive None, this is both silly and a waste of time, this will be handled properly in P_HandleFollower.
|
||||
p->followercolor = followercolor;
|
||||
|
||||
// set follower
|
||||
SetFollower(playernum, follower);
|
||||
}
|
||||
|
||||
void SendWeaponPref(void)
|
||||
|
|
@ -2815,6 +2918,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
|||
}
|
||||
|
||||
chmappending++;
|
||||
|
||||
if (netgame)
|
||||
WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed
|
||||
SendNetXCmd(XD_MAP, buf, buf_p - buf);
|
||||
|
|
@ -6034,6 +6138,198 @@ static void Name4_OnChange(void)
|
|||
SendNameAndColor4();
|
||||
}
|
||||
|
||||
// sends the follower change for players
|
||||
static void Follower_OnChange(void)
|
||||
{
|
||||
char str[SKINNAMESIZE+1], cpy[SKINNAMESIZE+1];
|
||||
INT32 num;
|
||||
char set[10]; // This isn't Lua and mixed declarations in the middle of code make caveman compilers scream.
|
||||
|
||||
// there is a slight chance that we will actually use a string instead so...
|
||||
// let's investigate the string...
|
||||
strcpy(str, cv_follower.string);
|
||||
strcpy(cpy, cv_follower.string);
|
||||
strlwr(str);
|
||||
if (stricmp(cpy,"0") !=0 && !atoi(cpy)) // yep, that's a string alright...
|
||||
{
|
||||
if (stricmp(cpy, "None") == 0)
|
||||
{
|
||||
CV_StealthSet(&cv_follower, "-1");
|
||||
|
||||
if (!Playing())
|
||||
return; // don't send anything there.
|
||||
|
||||
SendNameAndColor();
|
||||
return;
|
||||
}
|
||||
|
||||
num = R_FollowerAvailable(str);
|
||||
|
||||
if (num == -1) // that's an error.
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower '%s' not found\n"), str);
|
||||
|
||||
sprintf(set, "%d", num);
|
||||
CV_StealthSet(&cv_follower, set); // set it to a number. It's easier for us to send later :)
|
||||
}
|
||||
|
||||
if (!Playing())
|
||||
return; // don't send anything there.
|
||||
|
||||
SendNameAndColor();
|
||||
}
|
||||
|
||||
// About the same as Color_OnChange but for followers.
|
||||
static void Followercolor_OnChange(void)
|
||||
{
|
||||
|
||||
if (!Playing())
|
||||
return; // do whatever you want if you aren't in the game or don't have a follower.
|
||||
|
||||
if (!P_PlayerMoving(consoleplayer))
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor();
|
||||
}
|
||||
}
|
||||
|
||||
// repeat for the 3 other players
|
||||
|
||||
static void Follower2_OnChange(void)
|
||||
{
|
||||
char str[SKINNAMESIZE+1], cpy[SKINNAMESIZE+1];
|
||||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
strcpy(str, cv_follower2.string);
|
||||
strcpy(cpy, cv_follower2.string);
|
||||
strlwr(str);
|
||||
if (stricmp(cpy,"0") !=0 && !atoi(cpy)) // yep, that's a string alright...
|
||||
{
|
||||
|
||||
if (stricmp(cpy, "None") == 0)
|
||||
{
|
||||
CV_StealthSet(&cv_follower2, "-1");
|
||||
SendNameAndColor2();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
INT32 num = R_FollowerAvailable(str);
|
||||
char set[10];
|
||||
if (num == -1) // that's an error.
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower '%s' not found\n"), str);
|
||||
|
||||
sprintf(set, "%d", num);
|
||||
CV_StealthSet(&cv_follower2, set); // set it to a number. It's easier for us to send later :)
|
||||
}
|
||||
}
|
||||
SendNameAndColor2();
|
||||
}
|
||||
|
||||
static void Followercolor2_OnChange(void)
|
||||
{
|
||||
|
||||
if (!Playing())
|
||||
return; // do whatever you want if you aren't in the game or don't have a follower.
|
||||
|
||||
if (!P_PlayerMoving(g_localplayers[1]))
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor2();
|
||||
}
|
||||
}
|
||||
|
||||
static void Follower3_OnChange(void)
|
||||
{
|
||||
char str[SKINNAMESIZE+1], cpy[SKINNAMESIZE+1];
|
||||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
strcpy(str, cv_follower3.string);
|
||||
strcpy(cpy, cv_follower3.string);
|
||||
strlwr(str);
|
||||
if (stricmp(cpy,"0") !=0 && !atoi(cpy)) // yep, that's a string alright...
|
||||
{
|
||||
|
||||
if (stricmp(cpy, "None") == 0)
|
||||
{
|
||||
CV_StealthSet(&cv_follower3, "-1");
|
||||
SendNameAndColor3();
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
INT32 num = R_FollowerAvailable(str);
|
||||
char set[10];
|
||||
if (num == -1) // that's an error.
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower '%s' not found\n"), str);
|
||||
|
||||
sprintf(set, "%d", num);
|
||||
CV_StealthSet(&cv_follower3, set); // set it to a number. It's easier for us to send later :)
|
||||
}
|
||||
}
|
||||
SendNameAndColor3();
|
||||
}
|
||||
|
||||
static void Followercolor3_OnChange(void)
|
||||
{
|
||||
|
||||
if (!Playing())
|
||||
return; // do whatever you want if you aren't in the game or don't have a follower.
|
||||
|
||||
if (!P_PlayerMoving(g_localplayers[2]))
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor3();
|
||||
}
|
||||
}
|
||||
|
||||
static void Follower4_OnChange(void)
|
||||
{
|
||||
char str[SKINNAMESIZE+1], cpy[SKINNAMESIZE+1];
|
||||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
strcpy(str, cv_follower4.string);
|
||||
strcpy(cpy, cv_follower4.string);
|
||||
strlwr(str);
|
||||
if (stricmp(cpy,"0") !=0 && !atoi(cpy)) // yep, that's a string alright...
|
||||
{
|
||||
|
||||
if (stricmp(cpy, "None") == 0)
|
||||
{
|
||||
CV_StealthSet(&cv_follower4, "-1");
|
||||
SendNameAndColor4();
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
INT32 num = R_FollowerAvailable(str);
|
||||
char set[10];
|
||||
if (num == -1) // that's an error.
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Follower '%s' not found\n"), str);
|
||||
|
||||
sprintf(set, "%d", num);
|
||||
CV_StealthSet(&cv_follower4, set); // set it to a number. It's easier for us to send later :)
|
||||
}
|
||||
}
|
||||
SendNameAndColor4();
|
||||
}
|
||||
|
||||
static void Followercolor4_OnChange(void)
|
||||
{
|
||||
|
||||
if (!Playing())
|
||||
return; // do whatever you want if you aren't in the game or don't have a follower.
|
||||
|
||||
if (!P_PlayerMoving(g_localplayers[3]))
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor4();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sends a skin change for the console player, unless that player is moving.
|
||||
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
|
|
|
|||
|
|
@ -21,18 +21,23 @@
|
|||
extern consvar_t cv_playername;
|
||||
extern consvar_t cv_playercolor;
|
||||
extern consvar_t cv_skin;
|
||||
extern consvar_t cv_follower;
|
||||
extern consvar_t cv_showfollowers;
|
||||
// secondary splitscreen player
|
||||
extern consvar_t cv_playername2;
|
||||
extern consvar_t cv_playercolor2;
|
||||
extern consvar_t cv_skin2;
|
||||
extern consvar_t cv_follower2;
|
||||
// third splitscreen player
|
||||
extern consvar_t cv_playername3;
|
||||
extern consvar_t cv_playercolor3;
|
||||
extern consvar_t cv_skin3;
|
||||
extern consvar_t cv_follower3;
|
||||
// fourth splitscreen player
|
||||
extern consvar_t cv_playername4;
|
||||
extern consvar_t cv_playercolor4;
|
||||
extern consvar_t cv_skin4;
|
||||
extern consvar_t cv_follower4;
|
||||
// preferred number of players
|
||||
extern consvar_t cv_splitplayers;
|
||||
|
||||
|
|
|
|||
|
|
@ -513,6 +513,12 @@ typedef struct player_s
|
|||
// SRB2kart
|
||||
UINT8 kartspeed; // Kart speed stat between 1 and 9
|
||||
UINT8 kartweight; // Kart weight stat between 1 and 9
|
||||
|
||||
INT32 followerskin; // Kart: This player's follower "skin"
|
||||
boolean followerready; // Kart: Used to know when we can have a follower or not. (This is set on the first NameAndColor follower update)
|
||||
UINT8 followercolor; // Kart: Used to store the follower colour the player wishes to use
|
||||
mobj_t *follower; // Kart: This is the follower object we have. (If any)
|
||||
|
||||
//
|
||||
|
||||
UINT32 charflags; // Extra abilities/settings for skins (combinable stuff)
|
||||
|
|
|
|||
368
src/dehacked.c
368
src/dehacked.c
|
|
@ -34,6 +34,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "r_things.h" // for followers
|
||||
|
||||
#include "m_cond.h"
|
||||
|
||||
|
|
@ -674,6 +675,271 @@ static void readfreeslots(MYFILE *f)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
// This here is our current only way to make followers.
|
||||
INT32 numfollowers = 0;
|
||||
|
||||
static void readfollower(MYFILE *f)
|
||||
{
|
||||
char *s;
|
||||
char *word, *word2, dname[SKINNAMESIZE+1];
|
||||
char *tmp;
|
||||
char testname[SKINNAMESIZE];
|
||||
|
||||
boolean nameset;
|
||||
INT32 fallbackstate = 0;
|
||||
INT32 res;
|
||||
INT32 i;
|
||||
|
||||
if (numfollowers > MAXSKINS)
|
||||
{
|
||||
deh_warning("Error: Too many followers, cannot add anymore.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
||||
// Ready the default variables for followers. We will overwrite them as we go! We won't set the name or states RIGHT HERE as this is handled down instead.
|
||||
followers[numfollowers].scale = FRACUNIT;
|
||||
followers[numfollowers].bubblescale = 0; // No bubble by default
|
||||
followers[numfollowers].atangle = 230;
|
||||
followers[numfollowers].dist = 32; // changed from 16 to 32 to better account for ogl models
|
||||
followers[numfollowers].height = 16;
|
||||
followers[numfollowers].zoffs = 32;
|
||||
followers[numfollowers].horzlag = 2;
|
||||
followers[numfollowers].vertlag = 6;
|
||||
followers[numfollowers].bobspeed = TICRATE*2;
|
||||
followers[numfollowers].bobamp = 4;
|
||||
followers[numfollowers].hitconfirmtime = TICRATE;
|
||||
followers[numfollowers].defaultcolor = 1;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
|
||||
if (!word2)
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
|
||||
if (fastcmp(word, "NAME"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%s", followers[numfollowers].name), UNDO_NONE);
|
||||
strcpy(followers[numfollowers].name, word2);
|
||||
nameset = true;
|
||||
}
|
||||
else if (fastcmp(word, "DEFAULTCOLOR"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].defaultcolor), UNDO_NONE);
|
||||
followers[numfollowers].defaultcolor = (UINT8)get_number(word2);
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "SCALE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].scale), UNDO_NONE);
|
||||
followers[numfollowers].scale = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BUBBLESCALE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bubblescale), UNDO_NONE);
|
||||
followers[numfollowers].bubblescale = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ATANGLE"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].atangle), UNDO_NONE);
|
||||
followers[numfollowers].atangle = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HORZLAG"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].horzlag), UNDO_NONE);
|
||||
followers[numfollowers].horzlag = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "VERTLAG"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].vertlag), UNDO_NONE);
|
||||
followers[numfollowers].vertlag = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BOBSPEED"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bobspeed), UNDO_NONE);
|
||||
followers[numfollowers].bobspeed = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "BOBAMP"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].bobamp), UNDO_NONE);
|
||||
followers[numfollowers].bobamp = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ZOFFSET") || (fastcmp(word, "ZOFFS")))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].zoffs), UNDO_NONE);
|
||||
followers[numfollowers].zoffs = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "DISTANCE") || (fastcmp(word, "DIST")))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].dist), UNDO_NONE);
|
||||
followers[numfollowers].dist = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HEIGHT"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].height), UNDO_NONE);
|
||||
followers[numfollowers].height = (INT32)atoi(word2);
|
||||
}
|
||||
else if (fastcmp(word, "IDLESTATE"))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].idlestate), UNDO_NONE);
|
||||
followers[numfollowers].idlestate = get_number(word2);
|
||||
fallbackstate = followers[numfollowers].idlestate;
|
||||
}
|
||||
else if (fastcmp(word, "FOLLOWSTATE"))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].followstate), UNDO_NONE);
|
||||
followers[numfollowers].followstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HURTSTATE"))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].hurtstate), UNDO_NONE);
|
||||
followers[numfollowers].hurtstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "LOSESTATE"))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].losestate), UNDO_NONE);
|
||||
followers[numfollowers].losestate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "WINSTATE"))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].winstate), UNDO_NONE);
|
||||
followers[numfollowers].winstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HITSTATE") || (fastcmp(word, "HITCONFIRMSTATE")))
|
||||
{
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].hitconfirmstate), UNDO_NONE);
|
||||
followers[numfollowers].hitconfirmstate = get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "HITTIME") || (fastcmp(word, "HITCONFIRMTIME")))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%d", followers[numfollowers].hitconfirmtime), UNDO_NONE);
|
||||
followers[numfollowers].hitconfirmtime = (INT32)atoi(word2);
|
||||
}
|
||||
else
|
||||
deh_warning("Follower %d: unknown word '%s'", numfollowers, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
if (!nameset) // well this is problematic.
|
||||
{
|
||||
strcpy(followers[numfollowers].name, va("Follower%d", numfollowers)); // this is lazy, so what
|
||||
}
|
||||
|
||||
// set skin name (this is just the follower's name in lowercases):
|
||||
// but before we do, let's... actually check if another follower isn't doing the same shit...
|
||||
|
||||
strcpy(testname, followers[numfollowers].name);
|
||||
|
||||
// lower testname for skin checks...
|
||||
strlwr(testname);
|
||||
res = R_FollowerAvailable(testname);
|
||||
if (res > -1) // yikes, someone else has stolen our name already
|
||||
{
|
||||
INT32 startlen = strlen(testname);
|
||||
char cpy[2];
|
||||
//deh_warning("There was already a follower with the same name. (%s)", testname); This warning probably isn't necessary anymore?
|
||||
sprintf(cpy, "%d", numfollowers);
|
||||
memcpy(&testname[startlen], cpy, 2);
|
||||
// in that case, we'll be very lazy and copy numfollowers to the end of our skin name.
|
||||
}
|
||||
|
||||
strcpy(followers[numfollowers].skinname, testname);
|
||||
strcpy(dname, followers[numfollowers].skinname); // display name, just used for printing succesful stuff or errors later down the line.
|
||||
|
||||
// now that the skin name is ready, post process the actual name to turn the underscores into spaces!
|
||||
for (i = 0; followers[numfollowers].name[i]; i++)
|
||||
{
|
||||
if (followers[numfollowers].name[i] == '_')
|
||||
followers[numfollowers].name[i] = ' ';
|
||||
}
|
||||
|
||||
// fallbacks for variables
|
||||
// Print a warning if the variable is on a weird value and set it back to the minimum available if that's the case.
|
||||
#define FALLBACK(field, field2, threshold, set) \
|
||||
if (followers[numfollowers].field < threshold) \
|
||||
{ \
|
||||
followers[numfollowers].field = set; \
|
||||
deh_warning("Follower '%s': Value for '%s' is too low! Minimum should be %d. Value was overwritten to %d.", dname, field2, set, set); \
|
||||
} \
|
||||
|
||||
FALLBACK(dist, "DIST", 0, 0);
|
||||
FALLBACK(height, "HEIGHT", 1, 1);
|
||||
FALLBACK(zoffs, "ZOFFS", 0, 0);
|
||||
FALLBACK(horzlag, "HORZLAG", 1, 1);
|
||||
FALLBACK(vertlag, "VERTLAG", 1, 1);
|
||||
FALLBACK(bobamp, "BOBAMP", 0, 0);
|
||||
FALLBACK(bobspeed, "BOBSPEED", 0, 0);
|
||||
FALLBACK(hitconfirmtime, "HITCONFIRMTIME", 1, 1);
|
||||
FALLBACK(scale, "SCALE", 1, 1); // No null/negative scale
|
||||
FALLBACK(bubblescale, "BUBBLESCALE", 0, 0); // No negative scale
|
||||
|
||||
// Special case for color I suppose
|
||||
if (followers[numfollowers].defaultcolor > MAXSKINCOLORS-1)
|
||||
{
|
||||
followers[numfollowers].defaultcolor = 1;
|
||||
deh_warning("Follower \'%s\': Value for 'color' should be between 1 and %d.\n", dname, MAXSKINCOLORS-1);
|
||||
}
|
||||
|
||||
#undef FALLBACK
|
||||
|
||||
// also check if we forgot states. If we did, we will set any missing state to the follower's idlestate.
|
||||
// Print a warning in case we don't have a fallback and set the state to S_INVISIBLE (rather than S_NULL) if unavailable.
|
||||
|
||||
#define NOSTATE(field, field2) \
|
||||
if (!followers[numfollowers].field) \
|
||||
{ \
|
||||
followers[numfollowers].field = fallbackstate ? fallbackstate : S_INVISIBLE; \
|
||||
if (!fallbackstate) \
|
||||
deh_warning("Follower '%s' is missing state definition for '%s', no idlestate fallback was found", dname, field2); \
|
||||
} \
|
||||
|
||||
NOSTATE(idlestate, "IDLESTATE");
|
||||
NOSTATE(followstate, "FOLLOWSTATE");
|
||||
NOSTATE(hurtstate, "HURTSTATE");
|
||||
NOSTATE(losestate, "LOSESTATE");
|
||||
NOSTATE(winstate, "WINSTATE");
|
||||
NOSTATE(hitconfirmstate, "HITCONFIRMSTATE");
|
||||
#undef NOSTATE
|
||||
|
||||
CONS_Printf("Added follower '%s'\n", dname);
|
||||
numfollowers++; // add 1 follower
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readthing(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
|
@ -3418,6 +3684,13 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
|||
// This is not a major mod.
|
||||
continue;
|
||||
}
|
||||
else if (fastcmp(word, "FOLLOWER"))
|
||||
{
|
||||
readfollower(f); // at the same time this will be our only way to ADD followers for now. Yikes.
|
||||
DEH_WriteUndoline(word, "", UNDO_HEADER);
|
||||
// This is not a major mod either.
|
||||
continue; // continue so that we don't error.
|
||||
}
|
||||
word2 = strtok(NULL, " ");
|
||||
if (fastcmp(word, "CHARACTER"))
|
||||
{
|
||||
|
|
@ -6312,6 +6585,39 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_DRIFTEXPLODE2",
|
||||
"S_DRIFTEXPLODE3",
|
||||
"S_DRIFTEXPLODE4",
|
||||
"S_DRIFTEXPLODE5",
|
||||
"S_DRIFTEXPLODE6",
|
||||
"S_DRIFTEXPLODE7",
|
||||
"S_DRIFTEXPLODE8",
|
||||
|
||||
// Drift boost clip
|
||||
"S_DRIFTCLIPA1",
|
||||
"S_DRIFTCLIPA2",
|
||||
"S_DRIFTCLIPA3",
|
||||
"S_DRIFTCLIPA4",
|
||||
"S_DRIFTCLIPA5",
|
||||
"S_DRIFTCLIPA6",
|
||||
"S_DRIFTCLIPA7",
|
||||
"S_DRIFTCLIPA8",
|
||||
"S_DRIFTCLIPA9",
|
||||
"S_DRIFTCLIPA10",
|
||||
"S_DRIFTCLIPA11",
|
||||
"S_DRIFTCLIPA12",
|
||||
"S_DRIFTCLIPA13",
|
||||
"S_DRIFTCLIPA14",
|
||||
"S_DRIFTCLIPA15",
|
||||
"S_DRIFTCLIPA16",
|
||||
"S_DRIFTCLIPB1",
|
||||
"S_DRIFTCLIPB2",
|
||||
"S_DRIFTCLIPB3",
|
||||
"S_DRIFTCLIPB4",
|
||||
"S_DRIFTCLIPB5",
|
||||
"S_DRIFTCLIPB6",
|
||||
"S_DRIFTCLIPB7",
|
||||
"S_DRIFTCLIPB8",
|
||||
|
||||
// Drift boost clip spark
|
||||
"S_DRIFTCLIPSPARK",
|
||||
|
||||
// Sneaker boost effect
|
||||
"S_BOOSTFLAME",
|
||||
|
|
@ -7207,6 +7513,31 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_OPAQUESMOKE4",
|
||||
"S_OPAQUESMOKE5",
|
||||
|
||||
"S_FOLLOWERBUBBLE_FRONT",
|
||||
"S_FOLLOWERBUBBLE_BACK",
|
||||
|
||||
"S_GCHAOIDLE",
|
||||
"S_GCHAOFLY",
|
||||
"S_GCHAOSAD1",
|
||||
"S_GCHAOSAD2",
|
||||
"S_GCHAOSAD3",
|
||||
"S_GCHAOSAD4",
|
||||
"S_GCHAOHAPPY1",
|
||||
"S_GCHAOHAPPY2",
|
||||
"S_GCHAOHAPPY3",
|
||||
"S_GCHAOHAPPY4",
|
||||
|
||||
"S_CHEESEIDLE",
|
||||
"S_CHEESEFLY",
|
||||
"S_CHEESESAD1",
|
||||
"S_CHEESESAD2",
|
||||
"S_CHEESESAD3",
|
||||
"S_CHEESESAD4",
|
||||
"S_CHEESEHAPPY1",
|
||||
"S_CHEESEHAPPY2",
|
||||
"S_CHEESEHAPPY3",
|
||||
"S_CHEESEHAPPY4",
|
||||
|
||||
"S_RINGDEBT",
|
||||
"S_RINGSPARKS1",
|
||||
"S_RINGSPARKS2",
|
||||
|
|
@ -7795,6 +8126,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_FASTLINE",
|
||||
"MT_FASTDUST",
|
||||
"MT_DRIFTEXPLODE",
|
||||
"MT_DRIFTCLIP",
|
||||
"MT_DRIFTCLIPSPARK",
|
||||
"MT_BOOSTFLAME",
|
||||
"MT_BOOSTSMOKE",
|
||||
"MT_SNEAKERTRAIL",
|
||||
|
|
@ -8074,6 +8407,10 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BATTLECAPSULE",
|
||||
"MT_BATTLECAPSULE_PIECE",
|
||||
|
||||
"MT_FOLLOWER",
|
||||
"MT_FOLLOWERBUBBLE_FRONT",
|
||||
"MT_FOLLOWERBUBBLE_BACK",
|
||||
|
||||
"MT_WATERTRAIL",
|
||||
"MT_WATERTRAILUNDERLAY",
|
||||
|
||||
|
|
@ -8122,7 +8459,7 @@ static const char *const MOBJFLAG2_LIST[] = {
|
|||
"AXIS", // It's a NiGHTS axis! (For faster checking)
|
||||
"TWOD", // Moves like it's in a 2D level
|
||||
"DONTRESPAWN", // Don't respawn this object!
|
||||
"DONTDRAW", // Don't generate a vissprite
|
||||
"\x01", // free: 1<<3 (name un-matchable)
|
||||
"AUTOMATIC", // Thrown ring has automatic properties
|
||||
"RAILRING", // Thrown ring has rail properties
|
||||
"BOUNCERING", // Thrown ring has bounce properties
|
||||
|
|
@ -8139,7 +8476,7 @@ static const char *const MOBJFLAG2_LIST[] = {
|
|||
"JUSTATTACKED", // can be pushed by other moving mobjs
|
||||
"FIRING", // turret fire
|
||||
"SUPERFIRE", // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
||||
"SHADOW", // Fuzzy draw, makes targeting harder.
|
||||
"\x01", // free: 1<<20 (name un-matchable)
|
||||
"STRONGBOX", // Flag used for "strong" random monitors.
|
||||
"OBJECTFLIP", // Flag for objects that always have flipped gravity.
|
||||
"SKULLFLY", // Special handling: skull in flight.
|
||||
|
|
@ -8162,10 +8499,6 @@ static const char *const MOBJEFLAG_LIST[] = {
|
|||
"JUSTBOUNCEDWALL", // SRB2Kart: Mobj already bounced off a wall this tic
|
||||
"SPRUNG", // Mobj was already sprung this tic
|
||||
"APPLYPMOMZ", // Platform movement
|
||||
"DRAWONLYFORP1", // SRB2Kart: Splitscreen sprite draw flags
|
||||
"DRAWONLYFORP2",
|
||||
"DRAWONLYFORP3",
|
||||
"DRAWONLYFORP4",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -9099,6 +9432,29 @@ struct {
|
|||
{"TC_ALLWHITE",TC_ALLWHITE},
|
||||
{"TC_RAINBOW",TC_RAINBOW},
|
||||
{"TC_BLINK",TC_BLINK},
|
||||
|
||||
// MFD_ draw flag enum
|
||||
{"MFD_DONTDRAWP1",MFD_DONTDRAWP1},
|
||||
{"MFD_DONTDRAWP2",MFD_DONTDRAWP2},
|
||||
{"MFD_DONTDRAWP3",MFD_DONTDRAWP3},
|
||||
{"MFD_DONTDRAWP4",MFD_DONTDRAWP4},
|
||||
{"MFD_TRANS10",MFD_TRANS10},
|
||||
{"MFD_TRANS20",MFD_TRANS20},
|
||||
{"MFD_TRANS30",MFD_TRANS30},
|
||||
{"MFD_TRANS40",MFD_TRANS40},
|
||||
{"MFD_TRANS50",MFD_TRANS50},
|
||||
{"MFD_TRANS60",MFD_TRANS60},
|
||||
{"MFD_TRANS70",MFD_TRANS70},
|
||||
{"MFD_TRANS80",MFD_TRANS80},
|
||||
{"MFD_TRANS90",MFD_TRANS90},
|
||||
{"MFD_TRANSMASK",MFD_TRANSMASK},
|
||||
{"MFD_FULLBRIGHT",MFD_FULLBRIGHT},
|
||||
{"MFD_SEMIBRIGHT",MFD_SEMIBRIGHT},
|
||||
{"MFD_NOBRIGHT",MFD_NOBRIGHT},
|
||||
{"MFD_BRIGHTMASK",MFD_BRIGHTMASK},
|
||||
{"MFD_DONTDRAW",MFD_DONTDRAW},
|
||||
{"MFD_SHADOW",MFD_SHADOW},
|
||||
{"MFD_TRANSSHIFT",MFD_TRANSSHIFT},
|
||||
#endif
|
||||
|
||||
{NULL,0}
|
||||
|
|
|
|||
114
src/g_game.c
114
src/g_game.c
|
|
@ -2535,7 +2535,7 @@ static inline void G_PlayerFinishLevel(INT32 player)
|
|||
memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart
|
||||
p->ringweapons = 0;
|
||||
|
||||
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
|
||||
p->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); // cancel invisibility
|
||||
P_FlashPal(p, 0, 0); // Resets
|
||||
|
||||
p->starpostnum = 0;
|
||||
|
|
@ -2570,6 +2570,10 @@ void G_PlayerReborn(INT32 player)
|
|||
// SRB2kart
|
||||
UINT8 kartspeed;
|
||||
UINT8 kartweight;
|
||||
boolean followerready;
|
||||
INT32 followerskin;
|
||||
UINT8 followercolor;
|
||||
mobj_t *follower; // old follower, will probably be removed by the time we're dead but you never know.
|
||||
//
|
||||
INT32 charflags;
|
||||
INT32 pflags;
|
||||
|
|
@ -2630,6 +2634,10 @@ void G_PlayerReborn(INT32 player)
|
|||
// SRB2kart
|
||||
kartspeed = players[player].kartspeed;
|
||||
kartweight = players[player].kartweight;
|
||||
follower = players[player].follower;
|
||||
followerready = players[player].followerready;
|
||||
followercolor = players[player].followercolor;
|
||||
followerskin = players[player].followerskin;
|
||||
//
|
||||
charflags = players[player].charflags;
|
||||
|
||||
|
|
@ -2684,6 +2692,9 @@ void G_PlayerReborn(INT32 player)
|
|||
wanted = players[player].kartstuff[k_wanted];
|
||||
}
|
||||
|
||||
// Obliterate follower from existence
|
||||
P_SetTarget(&players[player].follower, NULL);
|
||||
|
||||
memcpy(&respawn, &players[player].respawn, sizeof (respawn));
|
||||
|
||||
p = &players[player];
|
||||
|
|
@ -2740,6 +2751,16 @@ void G_PlayerReborn(INT32 player)
|
|||
|
||||
memcpy(&p->respawn, &respawn, sizeof (p->respawn));
|
||||
|
||||
if (follower)
|
||||
P_RemoveMobj(follower);
|
||||
|
||||
p->followerready = followerready;
|
||||
p->followerskin = followerskin;
|
||||
p->followercolor = followercolor;
|
||||
//p->follower = NULL; // respawn a new one with you, it looks better.
|
||||
// ^ Not necessary anyway since it will be respawned regardless considering it doesn't exist anymore.
|
||||
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_USEDOWN;
|
||||
p->pflags |= PF_ATTACKDOWN;
|
||||
|
|
@ -3207,7 +3228,7 @@ void G_AddPlayer(INT32 playernum)
|
|||
p->jointime = 0;
|
||||
p->playerstate = PST_REBORN;
|
||||
|
||||
demo_extradata[playernum] |= DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN; // Set everything
|
||||
demo_extradata[playernum] |= DXD_PLAYSTATE|DXD_COLOR|DXD_NAME|DXD_SKIN|DXD_FOLLOWER; // Set everything
|
||||
}
|
||||
|
||||
void G_ExitLevel(void)
|
||||
|
|
@ -4936,6 +4957,25 @@ void G_ReadDemoExtraData(void)
|
|||
// Name
|
||||
M_Memcpy(player_names[p],demo_p,16);
|
||||
demo_p += 16;
|
||||
}
|
||||
if (extradata & DXD_FOLLOWER)
|
||||
{
|
||||
// Set our follower
|
||||
M_Memcpy(name, demo_p, 16);
|
||||
demo_p += 16;
|
||||
SetPlayerFollower(p, name);
|
||||
|
||||
// Follower's color
|
||||
M_Memcpy(name, demo_p, 16);
|
||||
demo_p += 16;
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
if (!stricmp(KartColor_Names[i], name)) // SRB2kart
|
||||
{
|
||||
players[p].followercolor = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (extradata & DXD_PLAYSTATE)
|
||||
{
|
||||
|
|
@ -5039,6 +5079,7 @@ void G_WriteDemoExtraData(void)
|
|||
|
||||
WRITEUINT8(demo_p, skins[players[i].skin].kartspeed);
|
||||
WRITEUINT8(demo_p, skins[players[i].skin].kartweight);
|
||||
|
||||
}
|
||||
if (demo_extradata[i] & DXD_COLOR)
|
||||
{
|
||||
|
|
@ -5056,6 +5097,21 @@ void G_WriteDemoExtraData(void)
|
|||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
}
|
||||
if (demo_extradata[i] & DXD_FOLLOWER)
|
||||
{
|
||||
// write follower
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, followers[players[i].followerskin].skinname, 16);
|
||||
M_Memcpy(demo_p, name, 16);
|
||||
demo_p += 16;
|
||||
|
||||
// write follower color
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, Followercolor_cons_t[players[i].followercolor].strvalue, 16); // Not KartColor_Names because followercolor has extra values such as "Match"
|
||||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
|
||||
}
|
||||
if (demo_extradata[i] & DXD_PLAYSTATE)
|
||||
{
|
||||
demo_writerng = 1;
|
||||
|
|
@ -5656,6 +5712,8 @@ void G_GhostTicker(void)
|
|||
g->p += 16; // Same tbh
|
||||
if (ziptic & DXD_NAME)
|
||||
g->p += 16; // yea
|
||||
if (ziptic & DXD_FOLLOWER)
|
||||
g->p += 32; // ok (32 because there's both the skin and the colour)
|
||||
if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING)
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
}
|
||||
|
|
@ -5961,7 +6019,7 @@ void G_PreviewRewind(tic_t previewtime)
|
|||
if (!info->playerinfo[i].ingame || !info->playerinfo[i].player.mo)
|
||||
{
|
||||
if (players[i].mo)
|
||||
players[i].mo->flags2 |= MF2_DONTDRAW;
|
||||
players[i].mo->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -5969,7 +6027,7 @@ void G_PreviewRewind(tic_t previewtime)
|
|||
if (!players[i].mo)
|
||||
continue; //@TODO spawn temp object to act as a player display
|
||||
|
||||
players[i].mo->flags2 &= ~MF2_DONTDRAW;
|
||||
players[i].mo->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
#define TWEEN(pr) info->playerinfo[i].mobj.pr + FixedMul((INT32) (next_info->playerinfo[i].mobj.pr - info->playerinfo[i].mobj.pr), tweenvalue)
|
||||
|
|
@ -6394,6 +6452,12 @@ void G_BeginRecording(void)
|
|||
CV_SaveNetVars(&demo_p, true);
|
||||
|
||||
// Now store some info for each in-game player
|
||||
|
||||
// Lat' 12/05/19: Do note that for the first game you load, everything that gets saved here is total garbage;
|
||||
// The name will always be Player <n>, the skin sonic, the color None and the follower 0. This is only correct on subsequent games.
|
||||
// In the case of said first game, the skin and the likes are updated with Got_NameAndColor, which are then saved in extradata for the demo with DXD_SKIN in r_things.c for instance.
|
||||
|
||||
|
||||
for (p = 0; p < MAXPLAYERS; p++) {
|
||||
if (playeringame[p]) {
|
||||
player = &players[p];
|
||||
|
|
@ -6418,6 +6482,25 @@ void G_BeginRecording(void)
|
|||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
|
||||
// Save follower's skin name
|
||||
// PS: We must check for 'follower' to determine if the followerskin is valid. It's going to be 0 if we don't have a follower, but 0 is also absolutely a valid follower!
|
||||
// Doesn't really matter if the follower mobj is valid so long as it exists in a way or another.
|
||||
|
||||
memset(name, 0, 16);
|
||||
if (player->follower)
|
||||
strncpy(name, followers[player->followerskin].skinname, 16);
|
||||
else
|
||||
strncpy(name, "None", 16); // Say we don't have one, then.
|
||||
|
||||
M_Memcpy(demo_p,name,16);
|
||||
demo_p += 16;
|
||||
|
||||
// Save follower's colour
|
||||
memset(name, 0, 16);
|
||||
strncpy(name, Followercolor_cons_t[player->followercolor].strvalue, 16); // Not KartColor_Names because followercolor has extra values such as "Match"
|
||||
M_Memcpy(demo_p, name, 16);
|
||||
demo_p += 16;
|
||||
|
||||
// Score, since Kart uses this to determine where you start on the map
|
||||
WRITEUINT32(demo_p, player->score);
|
||||
|
||||
|
|
@ -7017,7 +7100,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
{
|
||||
UINT8 i, p;
|
||||
lumpnum_t l;
|
||||
char skin[17],color[17],*n,*pdemoname;
|
||||
char skin[17],color[17],follower[17],*n,*pdemoname;
|
||||
UINT8 version,subversion;
|
||||
UINT32 randseed;
|
||||
char msg[1024];
|
||||
|
|
@ -7031,6 +7114,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
skin[16] = '\0';
|
||||
color[16] = '\0';
|
||||
follower[16] = '\0';
|
||||
|
||||
// No demo name means we're restarting the current demo
|
||||
if (defdemoname == NULL)
|
||||
|
|
@ -7345,6 +7429,23 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
break;
|
||||
}
|
||||
|
||||
// Follower
|
||||
M_Memcpy(follower, demo_p, 16);
|
||||
demo_p += 16;
|
||||
SetPlayerFollower(p, follower);
|
||||
|
||||
// Follower colour
|
||||
M_Memcpy(color, demo_p, 16);
|
||||
demo_p += 16;
|
||||
for (i = 0; i < MAXSKINCOLORS +2; i++) // +2 because of Match and Opposite
|
||||
{
|
||||
if (!stricmp(Followercolor_cons_t[i].strvalue, color))
|
||||
{
|
||||
players[p].followercolor = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Score, since Kart uses this to determine where you start on the map
|
||||
players[p].score = READUINT32(demo_p);
|
||||
|
||||
|
|
@ -7574,6 +7675,9 @@ void G_AddGhost(char *defdemoname)
|
|||
M_Memcpy(color, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Follower data was here, skip it, we don't care about it for ghosts.
|
||||
p += 32; // followerskin (16) + followercolor (16)
|
||||
|
||||
p += 4; // score
|
||||
p += 2; // powerlevel
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ extern UINT8 demo_writerng;
|
|||
#define DXD_NAME 0x04 // name changed
|
||||
#define DXD_COLOR 0x08 // color changed
|
||||
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
|
||||
#define DXD_FOLLOWER 0x20 // follower was changed
|
||||
|
||||
#define DXD_PST_PLAYING 0x01
|
||||
#define DXD_PST_SPECTATING 0x02
|
||||
|
|
|
|||
|
|
@ -2973,6 +2973,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
FUINT lightlevel;
|
||||
FBITFIELD blend = 0;
|
||||
UINT8 alpha;
|
||||
UINT8 brightmode = 0;
|
||||
|
||||
INT32 i;
|
||||
float realtop, realbot, top, bot;
|
||||
|
|
@ -3071,16 +3072,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
// co-ordinates
|
||||
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
|
||||
|
||||
if (!cv_translucency.value) // translucency disabled
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
}
|
||||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
}
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
|
|
@ -3097,15 +3090,30 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
|
||||
temp = FLOAT_TO_FIXED(realtop);
|
||||
|
||||
if (spr->mobj->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (spr->mobj->drawflags & MFD_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->drawflags & MFD_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
// Start with the lightlevel and colormap from the top of the sprite
|
||||
lightlevel = 255;
|
||||
colormap = list[sector->numlights - 1].extra_colormap;
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
{
|
||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
|
||||
|
|
@ -3115,10 +3123,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
: sector->lightlist[i].height;
|
||||
if (h <= temp)
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
{
|
||||
lightlevel = *list[i-1].lightlevel;
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
colormap = list[i-1].extra_colormap;
|
||||
|
|
@ -3127,10 +3135,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
}
|
||||
#else
|
||||
i = R_GetPlaneLight(sector, temp, false);
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
{
|
||||
lightlevel = *list[i].lightlevel;
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
colormap = list[i].extra_colormap;
|
||||
|
|
@ -3147,10 +3155,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
// even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite
|
||||
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
{
|
||||
lightlevel = *list[i].lightlevel;
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
colormap = list[i].extra_colormap;
|
||||
|
|
@ -3427,12 +3435,28 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
UINT8 brightmode = 0;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (spr->mobj->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (spr->mobj->drawflags & MFD_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->drawflags & MFD_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
|
||||
if (brightmode != 1)
|
||||
{
|
||||
lightlevel = sector->lightlevel;
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
}
|
||||
|
||||
|
|
@ -3441,16 +3465,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
|
||||
{
|
||||
FBITFIELD blend = 0;
|
||||
if (!cv_translucency.value) // translucency disabled
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0xFF;
|
||||
blend = PF_Translucent|PF_Occlude;
|
||||
}
|
||||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
}
|
||||
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
|
|
@ -3519,15 +3536,31 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
|||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
UINT8 brightmode = 0;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
|
||||
if (spr->mobj->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (spr->mobj->drawflags & MFD_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->drawflags & MFD_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
INT32 light;
|
||||
|
||||
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
|
|
@ -3535,24 +3568,21 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
lightlevel = sector->lightlevel;
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
}
|
||||
|
||||
if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
blend = PF_Translucent;
|
||||
}
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
|
|
@ -3587,8 +3617,14 @@ static int CompareVisSprites(const void *p1, const void *p2)
|
|||
// make transparent sprites last
|
||||
// "boolean to int"
|
||||
|
||||
int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK);
|
||||
int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK);
|
||||
int transparency1 = (spr1->mobj->drawflags & FF_TRANSMASK) ?
|
||||
((spr1->mobj->drawflags & FF_TRANSMASK)>>MFD_TRANSSHIFT) :
|
||||
((spr1->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT);
|
||||
|
||||
int transparency2 = (spr2->mobj->drawflags & FF_TRANSMASK) ?
|
||||
((spr2->mobj->drawflags & FF_TRANSMASK)>>MFD_TRANSSHIFT) :
|
||||
((spr2->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT);
|
||||
|
||||
idiff = transparency1 - transparency2;
|
||||
if (idiff != 0) return idiff;
|
||||
|
||||
|
|
@ -3962,9 +3998,6 @@ void HWR_AddSprites(sector_t *sec)
|
|||
precipmobj_t *precipthing;
|
||||
fixed_t approx_dist, limit_dist;
|
||||
|
||||
INT32 splitflags;
|
||||
boolean split_drawsprite; // drawing with splitscreen flags
|
||||
|
||||
// BSP is traversed by subsector.
|
||||
// A sector might have been split into several
|
||||
// subsectors during BSP building.
|
||||
|
|
@ -3981,36 +4014,13 @@ void HWR_AddSprites(sector_t *sec)
|
|||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
||||
split_drawsprite = false;
|
||||
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
if (thing->sprite == SPR_NULL)
|
||||
continue;
|
||||
|
||||
splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
|
||||
if (r_splitscreen && splitflags)
|
||||
{
|
||||
if (thing->eflags & MFE_DRAWONLYFORP1)
|
||||
if (viewssnum == 0)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP2)
|
||||
if (viewssnum == 1)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
|
||||
if (viewssnum == 2)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
|
||||
if (viewssnum == 3)
|
||||
split_drawsprite = true;
|
||||
}
|
||||
else
|
||||
split_drawsprite = true;
|
||||
|
||||
if (!split_drawsprite)
|
||||
if ((viewssnum == 0 && (thing->drawflags & MFD_DONTDRAWP1))
|
||||
|| (viewssnum == 1 && (thing->drawflags & MFD_DONTDRAWP2))
|
||||
|| (viewssnum == 2 && (thing->drawflags & MFD_DONTDRAWP3))
|
||||
|| (viewssnum == 3 && (thing->drawflags & MFD_DONTDRAWP4)))
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
|
@ -4026,36 +4036,13 @@ void HWR_AddSprites(sector_t *sec)
|
|||
// Draw everything in sector, no checks
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
||||
split_drawsprite = false;
|
||||
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
if (thing->sprite == SPR_NULL)
|
||||
continue;
|
||||
|
||||
splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
|
||||
if (r_splitscreen && splitflags)
|
||||
{
|
||||
if (thing->eflags & MFE_DRAWONLYFORP1)
|
||||
if (viewssnum == 0)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP2)
|
||||
if (viewssnum == 1)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
|
||||
if (viewssnum == 2)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
|
||||
if (viewssnum == 3)
|
||||
split_drawsprite = true;
|
||||
}
|
||||
else
|
||||
split_drawsprite = true;
|
||||
|
||||
if (!split_drawsprite)
|
||||
if ((viewssnum == 0 && (thing->drawflags & MFD_DONTDRAWP1))
|
||||
|| (viewssnum == 1 && (thing->drawflags & MFD_DONTDRAWP2))
|
||||
|| (viewssnum == 2 && (thing->drawflags & MFD_DONTDRAWP3))
|
||||
|| (viewssnum == 3 && (thing->drawflags & MFD_DONTDRAWP4)))
|
||||
continue;
|
||||
|
||||
HWR_ProjectSprite(thing);
|
||||
|
|
|
|||
|
|
@ -1083,6 +1083,22 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
UINT8 lightlevel = 255;
|
||||
UINT8 brightmode = 0;
|
||||
|
||||
if (spr->mobj->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (spr->mobj->drawflags & MFD_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->drawflags & MFD_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spr->mobj->frame & FF_FULLBRIGHT)
|
||||
brightmode = 1;
|
||||
else if (spr->mobj->frame & FF_SEMIBRIGHT)
|
||||
brightmode = 2;
|
||||
}
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
|
|
@ -1090,7 +1106,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
|
||||
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
|
|
@ -1098,13 +1114,16 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (brightmode != 1)
|
||||
lightlevel = sector->lightlevel;
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
if (brightmode == 2)
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
}
|
||||
else
|
||||
|
|
@ -1131,8 +1150,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
//if (tics > durs)
|
||||
//durs = tics;
|
||||
|
||||
if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
Surf.PolyColor.s.alpha = 0x40;
|
||||
if (spr->mobj->drawflags & MFD_TRANSMASK)
|
||||
HWR_TranstableToAlpha((spr->mobj->drawflags & MFD_TRANSMASK)>>MFD_TRANSSHIFT, &Surf);
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
|
||||
else
|
||||
|
|
|
|||
214
src/info.c
214
src/info.c
|
|
@ -53,6 +53,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK",
|
||||
"SRBL","SRBM","SRBN","SRBO",
|
||||
//SRB2kart Sprites
|
||||
|
||||
"RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV","KINF",
|
||||
"WIPD","DRIF","BDRF","DUST","DRWS","RSHE","FITM","BANA","ORBN","JAWZ","SSMN",
|
||||
"KRBM","BHOG","BHBM","SPBM","THNS","BUBS","BWVE",
|
||||
|
|
@ -69,8 +70,9 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"ICEB","CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS",
|
||||
"ZTCH","MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH",
|
||||
"BFRT","OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN",
|
||||
|
||||
"FWRK","MXCL","RGSP","DRAF","GRES","OTFG","DBOS","EGOO","WTRL","XMS4",
|
||||
"XMS5","VIEW"
|
||||
"XMS5","FBUB","GCHA","CHEZ","VIEW","DBCL","DBNC","DBST",
|
||||
};
|
||||
|
||||
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
|
||||
|
|
@ -2558,10 +2560,42 @@ state_t states[NUMSTATES] =
|
|||
{SPR_DSHR, FF_PAPERSPRITE|5, 1, {NULL}, 0, 0, S_FASTDUST7}, // S_FASTDUST6
|
||||
{SPR_DSHR, FF_PAPERSPRITE|6, 1, {NULL}, 0, 0, S_NULL}, // S_FASTDUST7
|
||||
|
||||
{SPR_DBOS, FF_FULLBRIGHT, 2, {NULL}, 6, 1, S_DRIFTEXPLODE2}, // S_DRIFTEXPLODE1
|
||||
{SPR_DBOS, FF_FULLBRIGHT|1, 2, {NULL}, 6, 1, S_DRIFTEXPLODE3}, // S_DRIFTEXPLODE2
|
||||
{SPR_DBOS, FF_FULLBRIGHT|2, 2, {NULL}, 6, 1, S_DRIFTEXPLODE4}, // S_DRIFTEXPLODE3
|
||||
{SPR_DBOS, FF_FULLBRIGHT|3, 2, {NULL}, 6, 1, S_DRIFTEXPLODE1}, // S_DRIFTEXPLODE4
|
||||
{SPR_DBOS, FF_FULLBRIGHT, 1, {NULL}, 6, 1, S_DRIFTEXPLODE2}, // S_DRIFTEXPLODE1
|
||||
{SPR_DBST, FF_PAPERSPRITE|FF_FULLBRIGHT, 1, {NULL}, 6, 1, S_DRIFTEXPLODE3}, // S_DRIFTEXPLODE2
|
||||
{SPR_DBOS, FF_FULLBRIGHT|1, 1, {NULL}, 6, 1, S_DRIFTEXPLODE4}, // S_DRIFTEXPLODE3
|
||||
{SPR_DBST, FF_PAPERSPRITE|FF_FULLBRIGHT|1, 1, {NULL}, 6, 1, S_DRIFTEXPLODE5}, // S_DRIFTEXPLODE4
|
||||
{SPR_DBOS, FF_FULLBRIGHT|2, 1, {NULL}, 6, 1, S_DRIFTEXPLODE6}, // S_DRIFTEXPLODE5
|
||||
{SPR_DBST, FF_PAPERSPRITE|FF_FULLBRIGHT|2, 1, {NULL}, 6, 1, S_DRIFTEXPLODE7}, // S_DRIFTEXPLODE6
|
||||
{SPR_DBOS, FF_FULLBRIGHT|3, 1, {NULL}, 6, 1, S_DRIFTEXPLODE8}, // S_DRIFTEXPLODE7
|
||||
{SPR_DBST, FF_PAPERSPRITE|FF_FULLBRIGHT|3, 1, {NULL}, 6, 1, S_DRIFTEXPLODE1}, // S_DRIFTEXPLODE8
|
||||
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x0, 1, {NULL}, 6, 1, S_DRIFTCLIPA2}, // S_DRIFTCLIPA1
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x8, 1, {NULL}, 6, 1, S_DRIFTCLIPA3}, // S_DRIFTCLIPA2
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x1, 1, {NULL}, 6, 1, S_DRIFTCLIPA4}, // S_DRIFTCLIPA3
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x9, 1, {NULL}, 6, 1, S_DRIFTCLIPA5}, // S_DRIFTCLIPA4
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x2, 1, {NULL}, 6, 1, S_DRIFTCLIPA6}, // S_DRIFTCLIPA5
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xA, 1, {NULL}, 6, 1, S_DRIFTCLIPA7}, // S_DRIFTCLIPA6
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x3, 1, {NULL}, 6, 1, S_DRIFTCLIPA8}, // S_DRIFTCLIPA7
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xB, 1, {NULL}, 6, 1, S_DRIFTCLIPA9}, // S_DRIFTCLIPA8
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x4, 1, {NULL}, 6, 1, S_DRIFTCLIPA10}, // S_DRIFTCLIPA9
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xC, 1, {NULL}, 6, 1, S_DRIFTCLIPA11}, // S_DRIFTCLIPA10
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x5, 1, {NULL}, 6, 1, S_DRIFTCLIPA12}, // S_DRIFTCLIPA11
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xD, 1, {NULL}, 6, 1, S_DRIFTCLIPA13}, // S_DRIFTCLIPA12
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x6, 1, {NULL}, 6, 1, S_DRIFTCLIPA14}, // S_DRIFTCLIPA13
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xE, 1, {NULL}, 6, 1, S_DRIFTCLIPA15}, // S_DRIFTCLIPA14
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0x7, 1, {NULL}, 6, 1, S_DRIFTCLIPA16}, // S_DRIFTCLIPA15
|
||||
{SPR_DBCL, FF_FULLBRIGHT|0xF, 1, {NULL}, 6, 1, S_DRIFTCLIPB1}, // S_DRIFTCLIPA16
|
||||
|
||||
{SPR_DBCL, FF_FULLBRIGHT, 2, {NULL}, 6, 1, S_DRIFTCLIPB2}, // S_DRIFTCLIPB1
|
||||
{SPR_DBCL, FF_FULLBRIGHT|1, 2, {NULL}, 6, 1, S_DRIFTCLIPB3}, // S_DRIFTCLIPB2
|
||||
{SPR_DBCL, FF_FULLBRIGHT|2, 2, {NULL}, 6, 1, S_DRIFTCLIPB4}, // S_DRIFTCLIPB3
|
||||
{SPR_DBCL, FF_FULLBRIGHT|3, 2, {NULL}, 6, 1, S_DRIFTCLIPB5}, // S_DRIFTCLIPB4
|
||||
{SPR_DBCL, FF_FULLBRIGHT|4, 2, {NULL}, 6, 1, S_DRIFTCLIPB6}, // S_DRIFTCLIPB5
|
||||
{SPR_DBCL, FF_FULLBRIGHT|5, 2, {NULL}, 6, 1, S_DRIFTCLIPB7}, // S_DRIFTCLIPB6
|
||||
{SPR_DBCL, FF_FULLBRIGHT|6, 2, {NULL}, 6, 1, S_DRIFTCLIPB8}, // S_DRIFTCLIPB7
|
||||
{SPR_DBCL, FF_FULLBRIGHT|7, 2, {NULL}, 6, 1, S_DRIFTCLIPB1}, // S_DRIFTCLIPB8
|
||||
|
||||
{SPR_DBNC, FF_FULLBRIGHT|FF_ANIMATE, 14, {NULL}, 6, 1, S_NULL}, // S_DRIFTCLIPSPARK
|
||||
|
||||
{SPR_BOST, FF_FULLBRIGHT|FF_ANIMATE, TICRATE, {NULL}, 6, 1, S_BOOSTSMOKESPAWNER}, // S_BOOSTFLAME
|
||||
{SPR_NULL, 0, TICRATE/2, {NULL}, 0, 0, S_NULL}, // S_BOOSTSMOKESPAWNER
|
||||
|
|
@ -3461,6 +3495,37 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SMOK, 3, 7, {NULL}, 0, 0, S_OPAQUESMOKE5}, // S_OPAQUESMOKE4
|
||||
{SPR_SMOK, 4, 8, {NULL}, 0, 0, S_NULL}, // S_OPAQUESMOKE5
|
||||
|
||||
|
||||
// followers:
|
||||
|
||||
// bubble
|
||||
{SPR_FBUB, 11|FF_ANIMATE|FF_TRANS70|FF_FULLBRIGHT, -1, {NULL}, 10, 3, S_FOLLOWERBUBBLE_FRONT}, // S_FOLLOWERBUBBLE_FRONT
|
||||
{SPR_FBUB, FF_ANIMATE|0|FF_FULLBRIGHT, -1, {NULL}, 10, 3, S_FOLLOWERBUBBLE_BACK}, // S_FOLLOWERBUBBLE_BACK
|
||||
|
||||
// generic chao:
|
||||
{SPR_GCHA, FF_ANIMATE, -1, {NULL}, 1, 4, S_GCHAOIDLE}, //S_GCHAOIDLE
|
||||
{SPR_GCHA, 2|FF_ANIMATE, -1, {NULL}, 1, 2, S_GCHAOFLY}, //S_GCHAOFLY
|
||||
{SPR_GCHA, 7, 5, {NULL}, 0, 0, S_GCHAOSAD2}, //S_GCHAOSAD1
|
||||
{SPR_GCHA, 8, 3, {NULL}, 0, 0, S_GCHAOSAD3}, //S_GCHAOSAD2
|
||||
{SPR_GCHA, 9, 6, {NULL}, 0, 0, S_GCHAOSAD4}, //S_GCHAOSAD3
|
||||
{SPR_GCHA, 8, 3, {NULL}, 0, 0, S_GCHAOSAD1}, //S_GCHAOSAD4
|
||||
{SPR_GCHA, 4, 8, {NULL}, 0, 0, S_GCHAOHAPPY2}, //S_GCHAOHAPPY1
|
||||
{SPR_GCHA, 5, 4, {NULL}, 0, 0, S_GCHAOHAPPY3}, //S_GCHAOHAPPY2
|
||||
{SPR_GCHA, 6, 8, {NULL}, 0, 0, S_GCHAOHAPPY4}, //S_GCHAOHAPPY3
|
||||
{SPR_GCHA, 5, 4, {NULL}, 0, 0, S_GCHAOHAPPY1}, //S_GCHAOHAPPY4
|
||||
|
||||
// cheese:
|
||||
{SPR_CHEZ, FF_ANIMATE, -1, {NULL}, 1, 4, S_CHEESEIDLE}, //S_CHEESEIDLE
|
||||
{SPR_CHEZ, 2|FF_ANIMATE, -1, {NULL}, 1, 2, S_CHEESEFLY}, //S_CHEESEFLY
|
||||
{SPR_CHEZ, 7, 5, {NULL}, 0, 0, S_CHEESESAD2}, //S_CHEESESAD1
|
||||
{SPR_CHEZ, 8, 3, {NULL}, 0, 0, S_CHEESESAD3}, //S_CHEESESAD2
|
||||
{SPR_CHEZ, 9, 6, {NULL}, 0, 0, S_CHEESESAD4}, //S_CHEESESAD3
|
||||
{SPR_CHEZ, 8, 3, {NULL}, 0, 0, S_CHEESESAD1}, //S_CHEESESAD4
|
||||
{SPR_CHEZ, 4, 8, {NULL}, 0, 0, S_CHEESEHAPPY2}, //S_CHEESEHAPPY1
|
||||
{SPR_CHEZ, 5, 4, {NULL}, 0, 0, S_CHEESEHAPPY3}, //S_CHEESEHAPPY2
|
||||
{SPR_CHEZ, 6, 8, {NULL}, 0, 0, S_CHEESEHAPPY4}, //S_CHEESEHAPPY3
|
||||
{SPR_CHEZ, 5, 4, {NULL}, 0, 0, S_CHEESEHAPPY1}, //S_CHEESEHAPPY4
|
||||
|
||||
{SPR_MXCL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_RINGDEBT
|
||||
|
||||
{SPR_RGSP, FF_PAPERSPRITE|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_RINGSPARKS2}, // S_RINGSPARKS1
|
||||
|
|
@ -15313,6 +15378,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRIFTCLIP
|
||||
-1, // doomednum
|
||||
S_DRIFTCLIPA1, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
105, // speed
|
||||
32*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
1, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_DONTENCOREMAP|MF_GRENADEBOUNCE|MF_BOUNCE, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_DRIFTCLIPSPARK
|
||||
-1, // doomednum
|
||||
S_DRIFTCLIPSPARK, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
8, // speed
|
||||
32*FRACUNIT, // radius
|
||||
64*FRACUNIT, // height
|
||||
1, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_DONTENCOREMAP, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_BOOSTFLAME
|
||||
-1, // doomednum
|
||||
S_BOOSTFLAME, // spawnstate
|
||||
|
|
@ -20553,6 +20672,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
||||
{ // MT_RINGSPARKS
|
||||
-1, // doomednum
|
||||
S_RINGSPARKS1, // spawnstate
|
||||
|
|
@ -20796,6 +20916,90 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FOLLOWER
|
||||
-1, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8<<FRACBITS, // radius
|
||||
16<<FRACBITS, // height
|
||||
1, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
||||
MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FOLLOWERBUBBLE_FRONT
|
||||
-1, // doomednum
|
||||
S_FOLLOWERBUBBLE_FRONT, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8<<FRACBITS, // radius
|
||||
16<<FRACBITS, // height
|
||||
2, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
||||
MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
{ // MT_FOLLOWERBUBBLE_BACK
|
||||
-1, // doomednum
|
||||
S_FOLLOWERBUBBLE_BACK, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8<<FRACBITS, // radius
|
||||
16<<FRACBITS, // height
|
||||
-2, // display offset
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
|
||||
MF_NOCLIPTHING|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_NULL, // raisestate
|
||||
},
|
||||
|
||||
{ // MT_WATERTRAIL
|
||||
-1, // doomednum
|
||||
S_WATERTRAIL1, // spawnstate
|
||||
|
|
|
|||
77
src/info.h
77
src/info.h
|
|
@ -804,9 +804,17 @@ typedef enum sprite
|
|||
SPR_XMS4,
|
||||
SPR_XMS5,
|
||||
|
||||
SPR_FBUB, // follower bubble
|
||||
SPR_GCHA, // follower: generic chao
|
||||
SPR_CHEZ, // follower: cheese
|
||||
|
||||
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
|
||||
SPR_VIEW,
|
||||
|
||||
SPR_DBCL, // Drift boost clip
|
||||
SPR_DBNC, // Drift boost clip's sparks
|
||||
SPR_DBST, // Drift boost plume
|
||||
|
||||
SPR_FIRSTFREESLOT,
|
||||
SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
|
||||
NUMSPRITES
|
||||
|
|
@ -3242,6 +3250,39 @@ typedef enum state
|
|||
S_DRIFTEXPLODE2,
|
||||
S_DRIFTEXPLODE3,
|
||||
S_DRIFTEXPLODE4,
|
||||
S_DRIFTEXPLODE5,
|
||||
S_DRIFTEXPLODE6,
|
||||
S_DRIFTEXPLODE7,
|
||||
S_DRIFTEXPLODE8,
|
||||
|
||||
// Drift boost clip
|
||||
S_DRIFTCLIPA1,
|
||||
S_DRIFTCLIPA2,
|
||||
S_DRIFTCLIPA3,
|
||||
S_DRIFTCLIPA4,
|
||||
S_DRIFTCLIPA5,
|
||||
S_DRIFTCLIPA6,
|
||||
S_DRIFTCLIPA7,
|
||||
S_DRIFTCLIPA8,
|
||||
S_DRIFTCLIPA9,
|
||||
S_DRIFTCLIPA10,
|
||||
S_DRIFTCLIPA11,
|
||||
S_DRIFTCLIPA12,
|
||||
S_DRIFTCLIPA13,
|
||||
S_DRIFTCLIPA14,
|
||||
S_DRIFTCLIPA15,
|
||||
S_DRIFTCLIPA16,
|
||||
S_DRIFTCLIPB1,
|
||||
S_DRIFTCLIPB2,
|
||||
S_DRIFTCLIPB3,
|
||||
S_DRIFTCLIPB4,
|
||||
S_DRIFTCLIPB5,
|
||||
S_DRIFTCLIPB6,
|
||||
S_DRIFTCLIPB7,
|
||||
S_DRIFTCLIPB8,
|
||||
|
||||
// Drift boost clip sparks
|
||||
S_DRIFTCLIPSPARK,
|
||||
|
||||
// Sneaker boost effect
|
||||
S_BOOSTFLAME,
|
||||
|
|
@ -4152,6 +4193,36 @@ typedef enum state
|
|||
S_OPAQUESMOKE4,
|
||||
S_OPAQUESMOKE5,
|
||||
|
||||
// followers:
|
||||
|
||||
// bubble:
|
||||
S_FOLLOWERBUBBLE_FRONT,
|
||||
S_FOLLOWERBUBBLE_BACK,
|
||||
|
||||
// generic chao:
|
||||
S_GCHAOIDLE,
|
||||
S_GCHAOFLY,
|
||||
S_GCHAOSAD1,
|
||||
S_GCHAOSAD2,
|
||||
S_GCHAOSAD3,
|
||||
S_GCHAOSAD4,
|
||||
S_GCHAOHAPPY1,
|
||||
S_GCHAOHAPPY2,
|
||||
S_GCHAOHAPPY3,
|
||||
S_GCHAOHAPPY4,
|
||||
|
||||
// cheese:
|
||||
S_CHEESEIDLE,
|
||||
S_CHEESEFLY,
|
||||
S_CHEESESAD1,
|
||||
S_CHEESESAD2,
|
||||
S_CHEESESAD3,
|
||||
S_CHEESESAD4,
|
||||
S_CHEESEHAPPY1,
|
||||
S_CHEESEHAPPY2,
|
||||
S_CHEESEHAPPY3,
|
||||
S_CHEESEHAPPY4,
|
||||
|
||||
S_RINGDEBT,
|
||||
S_RINGSPARKS1,
|
||||
S_RINGSPARKS2,
|
||||
|
|
@ -4757,6 +4828,8 @@ typedef enum mobj_type
|
|||
MT_FASTLINE,
|
||||
MT_FASTDUST,
|
||||
MT_DRIFTEXPLODE,
|
||||
MT_DRIFTCLIP,
|
||||
MT_DRIFTCLIPSPARK,
|
||||
MT_BOOSTFLAME,
|
||||
MT_BOOSTSMOKE,
|
||||
MT_SNEAKERTRAIL,
|
||||
|
|
@ -5036,6 +5109,10 @@ typedef enum mobj_type
|
|||
MT_BATTLECAPSULE,
|
||||
MT_BATTLECAPSULE_PIECE,
|
||||
|
||||
MT_FOLLOWER,
|
||||
MT_FOLLOWERBUBBLE_FRONT,
|
||||
MT_FOLLOWERBUBBLE_BACK,
|
||||
|
||||
MT_WATERTRAIL,
|
||||
MT_WATERTRAILUNDERLAY,
|
||||
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ static void K_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty
|
|||
//mo->destscale = mo->scale/4;
|
||||
mo->frame += ((leveltime/4) % 8);
|
||||
/*if (battleovertime.enabled < 10*TICRATE)
|
||||
mo->flags2 |= MF2_SHADOW;*/
|
||||
mo->drawflags |= MFD_SHADOW;*/
|
||||
mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90;
|
||||
mo->z += P_RandomRange(0,48) * mo->scale;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -469,6 +469,10 @@ boolean K_BHeapPop(bheap_t *const heap, bheapitem_t *const returnitemstorage)
|
|||
heap->array[0] = heap->array[heap->count];
|
||||
heap->array[0].heapindex = 0U;
|
||||
memset(&heap->array[heap->count], 0x00, sizeof(bheapitem_t));
|
||||
if (heap->array[0].indexchanged != NULL)
|
||||
{
|
||||
heap->array[0].indexchanged(heap->array[0].data, heap->array[0].heapindex);
|
||||
}
|
||||
|
||||
K_BHeapSortDown(heap, &heap->array[0]);
|
||||
popsuccess = true;
|
||||
|
|
|
|||
325
src/k_kart.c
325
src/k_kart.c
|
|
@ -40,6 +40,22 @@
|
|||
// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB
|
||||
// mapreset is set when enough players fill an empty server
|
||||
|
||||
UINT16 K_GetPlayerDontDrawFlag(player_t *player)
|
||||
{
|
||||
UINT16 flag = 0;
|
||||
|
||||
if (player == &players[displayplayers[0]])
|
||||
flag = MFD_DONTDRAWP1;
|
||||
else if (r_splitscreen >= 1 && player == &players[displayplayers[1]])
|
||||
flag = MFD_DONTDRAWP2;
|
||||
else if (r_splitscreen >= 2 && player == &players[displayplayers[2]])
|
||||
flag = MFD_DONTDRAWP3;
|
||||
else if (r_splitscreen >= 3 && player == &players[displayplayers[3]])
|
||||
flag = MFD_DONTDRAWP4;
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
player_t *K_GetItemBoxPlayer(mobj_t *mobj)
|
||||
{
|
||||
fixed_t closest = INT32_MAX;
|
||||
|
|
@ -1330,15 +1346,19 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
|
|||
cury + (P_RandomRange(-12,12)*mapobjectscale),
|
||||
curz + (P_RandomRange(24,48)*mapobjectscale),
|
||||
MT_SIGNSPARKLE);
|
||||
|
||||
P_SetMobjState(band, S_SIGNSPARK1 + (leveltime % 11));
|
||||
P_SetScale(band, (band->destscale = (3*player->mo->scale)/2));
|
||||
|
||||
band->color = colors[c];
|
||||
band->colorized = true;
|
||||
|
||||
band->fuse = 2;
|
||||
|
||||
if (transparent)
|
||||
band->flags2 |= MF2_SHADOW;
|
||||
if (!P_IsDisplayPlayer(player) && !P_IsDisplayPlayer(victim))
|
||||
band->flags2 |= MF2_DONTDRAW;
|
||||
band->drawflags |= MFD_SHADOW;
|
||||
|
||||
band->drawflags |= MFD_DONTDRAW & ~(K_GetPlayerDontDrawFlag(player) | K_GetPlayerDontDrawFlag(victim));
|
||||
}
|
||||
|
||||
curx += stepx;
|
||||
|
|
@ -1566,13 +1586,21 @@ void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
|||
K_FlipFromObject(mo, master);
|
||||
|
||||
// visibility (usually for hyudoro)
|
||||
mo->flags2 = (mo->flags2 & ~MF2_DONTDRAW)|(master->flags2 & MF2_DONTDRAW);
|
||||
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP1)|(master->eflags & MFE_DRAWONLYFORP1);
|
||||
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP2)|(master->eflags & MFE_DRAWONLYFORP2);
|
||||
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP3)|(master->eflags & MFE_DRAWONLYFORP3);
|
||||
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP4)|(master->eflags & MFE_DRAWONLYFORP4);
|
||||
mo->drawflags = (master->drawflags & MFD_DONTDRAW);
|
||||
}
|
||||
|
||||
// same as above, but does not adjust Z height when flipping
|
||||
void K_GenericExtraFlagsNoZAdjust(mobj_t *mo, mobj_t *master)
|
||||
{
|
||||
// flipping
|
||||
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP);
|
||||
mo->flags2 = (mo->flags2 & ~MF2_OBJECTFLIP)|(master->flags2 & MF2_OBJECTFLIP);
|
||||
|
||||
// visibility (usually for hyudoro)
|
||||
mo->drawflags = (master->drawflags & MFD_DONTDRAW);
|
||||
}
|
||||
|
||||
|
||||
void K_SpawnDashDustRelease(player_t *player)
|
||||
{
|
||||
fixed_t newx;
|
||||
|
|
@ -1629,7 +1657,54 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m
|
|||
P_SetTarget(&sparks->target, player->mo);
|
||||
P_SetScale(sparks, (sparks->destscale = player->mo->scale));
|
||||
K_MatchGenericExtraFlags(sparks, player->mo);
|
||||
sparks->flags2 |= MF2_DONTDRAW;
|
||||
sparks->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
static fixed_t K_RandomFlip(fixed_t f)
|
||||
{
|
||||
return ( ( leveltime & 1 ) ? f : -f );
|
||||
}
|
||||
|
||||
void K_SpawnDriftBoostClip(player_t *player)
|
||||
{
|
||||
mobj_t *clip;
|
||||
fixed_t scale = 115*FRACUNIT/100;
|
||||
fixed_t z;
|
||||
|
||||
if (( player->mo->eflags & MFE_VERTICALFLIP ))
|
||||
z = player->mo->z;
|
||||
else
|
||||
z = player->mo->z + player->mo->height;
|
||||
|
||||
clip = P_SpawnMobj(player->mo->x, player->mo->y, z, MT_DRIFTCLIP);
|
||||
|
||||
P_SetTarget(&clip->target, player->mo);
|
||||
P_SetScale(clip, ( clip->destscale = FixedMul(scale, player->mo->scale) ));
|
||||
K_MatchGenericExtraFlags(clip, player->mo);
|
||||
|
||||
clip->fuse = 105;
|
||||
clip->momz = 7 * P_MobjFlip(clip) * clip->scale;
|
||||
|
||||
if (player->mo->momz > 0)
|
||||
clip->momz += player->mo->momz;
|
||||
|
||||
P_InstaThrust(clip, player->mo->angle +
|
||||
K_RandomFlip(P_RandomRange(FRACUNIT/2, FRACUNIT)),
|
||||
FixedMul(scale, player->speed));
|
||||
}
|
||||
|
||||
void K_SpawnDriftBoostClipSpark(mobj_t *clip)
|
||||
{
|
||||
mobj_t *spark;
|
||||
|
||||
spark = P_SpawnMobj(clip->x, clip->y, clip->z, MT_DRIFTCLIPSPARK);
|
||||
|
||||
P_SetTarget(&spark->target, clip);
|
||||
P_SetScale(spark, ( spark->destscale = clip->scale ));
|
||||
K_MatchGenericExtraFlags(spark, clip);
|
||||
|
||||
spark->momx = clip->momx/2;
|
||||
spark->momy = clip->momx/2;
|
||||
}
|
||||
|
||||
/** \brief Handles the state changing for moving players, moved here to eliminate duplicate code
|
||||
|
|
@ -1899,6 +1974,13 @@ void K_PlayPainSound(mobj_t *source)
|
|||
|
||||
void K_PlayHitEmSound(mobj_t *source)
|
||||
{
|
||||
|
||||
if (source->player->follower)
|
||||
{
|
||||
follower_t fl = followers[source->player->followerskin];
|
||||
source->player->follower->movecount = fl.hitconfirmtime; // movecount is used to play the hitconfirm animation for followers.
|
||||
}
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(source, sfx_khitem);
|
||||
else
|
||||
|
|
@ -1946,9 +2028,17 @@ static fixed_t K_FlameShieldDashVar(INT32 val)
|
|||
return (3*FRACUNIT/4) + (((val * FRACUNIT) / TICRATE) / 2);
|
||||
}
|
||||
|
||||
// Light weights have stronger boost stacking -- aka, better metabolism than heavies XD
|
||||
#define METABOLISM
|
||||
|
||||
// sets k_boostpower, k_speedboost, and k_accelboost to whatever we need it to be
|
||||
static void K_GetKartBoostPower(player_t *player)
|
||||
{
|
||||
#ifdef METABOLISM
|
||||
const fixed_t maxmetabolismincrease = FRACUNIT/2;
|
||||
const fixed_t metabolism = FRACUNIT - ((9-player->kartweight) * maxmetabolismincrease / 8);
|
||||
#endif // METABOLISM
|
||||
|
||||
fixed_t boostpower = FRACUNIT;
|
||||
fixed_t speedboost = 0, accelboost = 0;
|
||||
UINT8 numboosts = 0;
|
||||
|
|
@ -1966,12 +2056,24 @@ static void K_GetKartBoostPower(player_t *player)
|
|||
if (player->kartstuff[k_bananadrag] > TICRATE)
|
||||
boostpower = (4*boostpower)/5;
|
||||
|
||||
#ifdef METABOLISM
|
||||
|
||||
#define ADDBOOST(s,a) { \
|
||||
numboosts++; \
|
||||
speedboost += (s) / numboosts; \
|
||||
accelboost += (a) / numboosts; \
|
||||
speedboost += FixedDiv(s, FRACUNIT + (metabolism * numboosts-1)); \
|
||||
accelboost += FixedDiv(a, FRACUNIT + (metabolism * numboosts-1)); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ADDBOOST(s,a) { \
|
||||
numboosts++; \
|
||||
speedboost += s / numboosts; \
|
||||
accelboost += a / numboosts; \
|
||||
}
|
||||
|
||||
#endif // METABOLISM
|
||||
|
||||
if (player->kartstuff[k_sneakertimer]) // Sneaker
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -2098,7 +2200,7 @@ fixed_t K_GetKartAccel(player_t *player)
|
|||
//k_accel += 3 * (9 - kartspeed); // 36 - 60
|
||||
k_accel += 4 * (9 - kartspeed); // 32 - 64
|
||||
|
||||
|
||||
|
||||
if (K_PlayerUsesBotMovement(player))
|
||||
{
|
||||
// Rubberbanding acceleration is waekened since it makes hits feel more meaningful
|
||||
|
|
@ -2116,11 +2218,11 @@ UINT16 K_GetKartFlashing(player_t *player)
|
|||
if (!player)
|
||||
return tics;
|
||||
|
||||
tics += (tics/8) * (player->kartspeed);
|
||||
|
||||
if (G_BattleGametype())
|
||||
tics *= 2;
|
||||
|
||||
tics += (flashingtics/8) * (player->kartspeed);
|
||||
|
||||
return tics;
|
||||
}
|
||||
|
||||
|
|
@ -3086,6 +3188,7 @@ static void K_SpawnDriftSparks(player_t *player)
|
|||
{
|
||||
// transition
|
||||
P_SetScale(spark, (spark->destscale = spark->scale*3/2));
|
||||
S_StartSound(player->mo, sfx_cock);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3327,7 +3430,7 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
|
|||
}
|
||||
|
||||
if (translucent)
|
||||
dust->flags2 |= MF2_SHADOW;
|
||||
dust->drawflags |= MFD_SHADOW;
|
||||
}
|
||||
|
||||
void K_SpawnDraftDust(mobj_t *mo)
|
||||
|
|
@ -4003,7 +4106,7 @@ void K_DoSneaker(player_t *player, INT32 type)
|
|||
{
|
||||
player->pflags |= PF_ATTACKDOWN;
|
||||
K_PlayBoostTaunt(player->mo);
|
||||
|
||||
|
||||
}
|
||||
|
||||
player->kartstuff[k_sneakertimer] = sneakertime;
|
||||
|
|
@ -4803,9 +4906,9 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
cur->flags &= ~MF_NOCLIPTHING;
|
||||
|
||||
if (player->kartstuff[k_rocketsneakertimer] <= TICRATE && (leveltime & 1))
|
||||
cur->flags2 |= MF2_DONTDRAW;
|
||||
cur->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
cur->flags2 &= ~MF2_DONTDRAW;
|
||||
cur->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
if (num & 1)
|
||||
P_SetMobjStateNF(cur, (vibrate ? S_ROCKETSNEAKER_LVIBRATE : S_ROCKETSNEAKER_L));
|
||||
|
|
@ -5354,7 +5457,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
//ghost->momy = (3*player->mo->momy)/4;
|
||||
//ghost->momz = (3*player->mo->momz)/4;
|
||||
if (leveltime & 1)
|
||||
ghost->flags2 |= MF2_DONTDRAW;
|
||||
ghost->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
|
|
@ -5381,16 +5484,20 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
{
|
||||
mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy,
|
||||
player->mo->z + player->mo->momz + player->mo->height + (24*player->mo->scale), MT_THOK);
|
||||
|
||||
P_SetMobjState(debtflag, S_RINGDEBT);
|
||||
P_SetScale(debtflag, (debtflag->destscale = player->mo->scale));
|
||||
|
||||
K_MatchGenericExtraFlags(debtflag, player->mo);
|
||||
debtflag->frame += (leveltime % 4);
|
||||
|
||||
if ((leveltime/12) & 1)
|
||||
debtflag->frame += 4;
|
||||
|
||||
debtflag->color = player->skincolor;
|
||||
debtflag->fuse = 2;
|
||||
if (P_IsDisplayPlayer(player))
|
||||
debtflag->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
debtflag->drawflags = K_GetPlayerDontDrawFlag(player);
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_springstars] && (leveltime & 1))
|
||||
|
|
@ -6306,6 +6413,45 @@ INT32 K_GetKartDriftSparkValue(player_t *player)
|
|||
return (26*4 + kartspeed*2 + (9 - player->kartweight))*8;
|
||||
}
|
||||
|
||||
/*
|
||||
Stage 1: red sparks
|
||||
Stage 2: blue sparks
|
||||
Stage 3: big large rainbow sparks
|
||||
*/
|
||||
static void K_SpawnDriftBoostExplosion(player_t *player, int stage)
|
||||
{
|
||||
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFTEXPLODE);
|
||||
|
||||
P_SetTarget(&overlay->target, player->mo);
|
||||
P_SetScale(overlay, (overlay->destscale = player->mo->scale));
|
||||
K_FlipFromObject(overlay, player->mo);
|
||||
|
||||
switch (stage)
|
||||
{
|
||||
case 1:
|
||||
overlay->color = SKINCOLOR_KETCHUP;
|
||||
overlay->fuse = 16;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
overlay->color = SKINCOLOR_SAPPHIRE;
|
||||
overlay->fuse = 32;
|
||||
|
||||
S_StartSound(player->mo, sfx_kc5b);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
overlay->color = SKINCOLOR_SILVER;
|
||||
overlay->fuse = 120;
|
||||
|
||||
S_StartSound(player->mo, sfx_kc5b);
|
||||
S_StartSound(player->mo, sfx_s3kc4l);
|
||||
break;
|
||||
}
|
||||
|
||||
overlay->extravalue1 = stage;
|
||||
}
|
||||
|
||||
static void K_KartDrift(player_t *player, boolean onground)
|
||||
{
|
||||
fixed_t minspeed = (10 * player->mo->scale);
|
||||
|
|
@ -6322,10 +6468,6 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_driftcharge] < 0 || player->kartstuff[k_driftcharge] >= dsone)
|
||||
{
|
||||
angle_t pushdir = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||
//mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFTEXPLODE);
|
||||
//P_SetTarget(&overlay->target, player->mo);
|
||||
//P_SetScale(overlay, (overlay->destscale = player->mo->scale));
|
||||
//K_FlipFromObject(overlay, player->mo);
|
||||
|
||||
S_StartSound(player->mo, sfx_s23c);
|
||||
//K_SpawnDashDustRelease(player);
|
||||
|
|
@ -6338,9 +6480,6 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
|
||||
if (player->kartstuff[k_driftboost] < 15)
|
||||
player->kartstuff[k_driftboost] = 15;
|
||||
|
||||
//overlay->color = SKINCOLOR_GOLD;
|
||||
//overlay->fuse = 8;
|
||||
}
|
||||
else if (player->kartstuff[k_driftcharge] >= dsone && player->kartstuff[k_driftcharge] < dstwo)
|
||||
{
|
||||
|
|
@ -6351,8 +6490,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_driftboost] < 20)
|
||||
player->kartstuff[k_driftboost] = 20;
|
||||
|
||||
//overlay->color = SKINCOLOR_KETCHUP;
|
||||
//overlay->fuse = 16;
|
||||
K_SpawnDriftBoostExplosion(player, 1);
|
||||
}
|
||||
else if (player->kartstuff[k_driftcharge] < dsthree)
|
||||
{
|
||||
|
|
@ -6363,8 +6501,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_driftboost] < 50)
|
||||
player->kartstuff[k_driftboost] = 50;
|
||||
|
||||
//overlay->color = SKINCOLOR_SAPPHIRE;
|
||||
//overlay->fuse = 32;
|
||||
K_SpawnDriftBoostExplosion(player, 2);
|
||||
}
|
||||
else if (player->kartstuff[k_driftcharge] >= dsthree)
|
||||
{
|
||||
|
|
@ -6375,8 +6512,7 @@ static void K_KartDrift(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_driftboost] < 125)
|
||||
player->kartstuff[k_driftboost] = 125;
|
||||
|
||||
//overlay->color = SKINCOLOR_SILVER;
|
||||
//overlay->fuse = 120;
|
||||
K_SpawnDriftBoostExplosion(player, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6678,7 +6814,7 @@ static INT32 K_FlameShieldMax(player_t *player)
|
|||
}
|
||||
|
||||
disttofinish = player->distancetofinish - disttofinish;
|
||||
distv = FixedDiv(distv * FRACUNIT, mapobjectscale) / FRACUNIT;
|
||||
distv = FixedMul(distv * FRACUNIT, mapobjectscale) / FRACUNIT;
|
||||
return min(16, 1 + (disttofinish / distv));
|
||||
}
|
||||
|
||||
|
|
@ -7408,61 +7544,35 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
if (G_RaceGametype())
|
||||
hyu *= 2; // double in race
|
||||
|
||||
if (r_splitscreen)
|
||||
if (leveltime & 1)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
if (player->kartstuff[k_hyudorotimer] >= (TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyu-(TICRATE/2))
|
||||
{
|
||||
if (player == &players[displayplayers[1]])
|
||||
player->mo->eflags |= MFE_DRAWONLYFORP2;
|
||||
else if (player == &players[displayplayers[2]] && r_splitscreen > 1)
|
||||
player->mo->eflags |= MFE_DRAWONLYFORP3;
|
||||
else if (player == &players[displayplayers[3]] && r_splitscreen > 2)
|
||||
player->mo->eflags |= MFE_DRAWONLYFORP4;
|
||||
else if (player == &players[displayplayers[0]])
|
||||
player->mo->eflags |= MFE_DRAWONLYFORP1;
|
||||
else
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
}
|
||||
else
|
||||
player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (P_IsDisplayPlayer(player)
|
||||
|| (!P_IsDisplayPlayer(player) && (player->kartstuff[k_hyudorotimer] < (TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyu-(TICRATE/2))))
|
||||
{
|
||||
if (leveltime & 1)
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
if (player->kartstuff[k_hyudorotimer] >= (TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyu-(TICRATE/2))
|
||||
player->mo->drawflags &= ~K_GetPlayerDontDrawFlag(player);
|
||||
else
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
player->powers[pw_flashing] = player->kartstuff[k_hyudorotimer]; // We'll do this for now, let's people know about the invisible people through subtle hints
|
||||
}
|
||||
else if (player->kartstuff[k_hyudorotimer] == 0)
|
||||
{
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
player->mo->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb
|
||||
{
|
||||
K_DropItems(player); //K_StripItems(player);
|
||||
K_StripOther(player);
|
||||
player->mo->flags2 |= MF2_SHADOW;
|
||||
player->mo->drawflags |= MFD_SHADOW;
|
||||
player->powers[pw_flashing] = player->kartstuff[k_comebacktimer];
|
||||
}
|
||||
else if (G_RaceGametype() || player->kartstuff[k_bumper] > 0)
|
||||
{
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9839,7 +9949,8 @@ static void K_ObjectTracking(fixed_t *hud_x, fixed_t *hud_y, vertex_t *campos, a
|
|||
{
|
||||
*hud_y /= 2;
|
||||
|
||||
if (camnum > 1)
|
||||
if ((r_splitscreen == 1 && camnum == 1)
|
||||
|| (r_splitscreen > 1 && camnum > 1))
|
||||
{
|
||||
*hud_y += shhalffixed;
|
||||
}
|
||||
|
|
@ -9953,6 +10064,30 @@ static void K_drawKartPlayerCheck(void)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean K_ShowPlayerNametag(player_t *p)
|
||||
{
|
||||
if (demo.playback == true && demo.freecam == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stplyr == p)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
if ((p->kartstuff[k_position] < stplyr->kartstuff[k_position]-2)
|
||||
|| (p->kartstuff[k_position] > stplyr->kartstuff[k_position]+2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void K_drawKartNameTags(void)
|
||||
{
|
||||
const fixed_t maxdistance = 8192*mapobjectscale;
|
||||
|
|
@ -9998,7 +10133,6 @@ static void K_drawKartNameTags(void)
|
|||
fixed_t y = -BASEVIDWIDTH * FRACUNIT;
|
||||
|
||||
vertex_t v;
|
||||
UINT8 j;
|
||||
|
||||
if (!playeringame[i] || ntplayer->spectator)
|
||||
{
|
||||
|
|
@ -10018,18 +10152,24 @@ static void K_drawKartNameTags(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j <= r_splitscreen; j++)
|
||||
if (!(demo.playback == true && demo.freecam == true))
|
||||
{
|
||||
if (ntplayer == &players[displayplayers[j]])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
UINT8 j;
|
||||
|
||||
if (j <= r_splitscreen)
|
||||
{
|
||||
// Is a player that's being shown on this computer
|
||||
continue;
|
||||
for (j = 0; j <= r_splitscreen; j++)
|
||||
{
|
||||
if (ntplayer == &players[displayplayers[j]])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j <= r_splitscreen)
|
||||
{
|
||||
// This is a player that's being shown on this computer
|
||||
// (Remove whenever we get splitscreen ABCD indicators)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
v.x = ntplayer->mo->x;
|
||||
|
|
@ -10065,10 +10205,9 @@ static void K_drawKartNameTags(void)
|
|||
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS, kp_rival[blink], NULL);
|
||||
}
|
||||
}
|
||||
else if (netgame)
|
||||
else if (netgame || demo.playback)
|
||||
{
|
||||
if ((ntplayer->kartstuff[k_position] >= stplyr->kartstuff[k_position]-2)
|
||||
&& (ntplayer->kartstuff[k_position] <= stplyr->kartstuff[k_position]+2))
|
||||
if (K_ShowPlayerNametag(ntplayer) == true)
|
||||
{
|
||||
INT32 namelen = V_ThinStringWidth(player_names[i], V_6WIDTHSPACE|V_ALLOWLOWERCASE);
|
||||
INT32 clr = K_SkincolorToTextColor(ntplayer->skincolor);
|
||||
|
|
@ -10095,7 +10234,7 @@ static void K_drawKartNameTags(void)
|
|||
{
|
||||
bary += (vid.height - (BASEVIDHEIGHT * vid.dupy)) / 2;
|
||||
}
|
||||
|
||||
|
||||
// Lat: 10/06/2020: colormap can be NULL on the frame you join a game, just arbitrarily use palette indexes 31 and 0 instead of whatever the colormap would give us instead to avoid crashes.
|
||||
V_DrawFill(barx, bary, barw, (3 * vid.dupy), (colormap ? colormap[31] : 31)|V_NOSCALESTART);
|
||||
V_DrawFill(barx, bary + vid.dupy, barw, vid.dupy, (colormap ? colormap[0] : 0)|V_NOSCALESTART);
|
||||
|
|
@ -10196,6 +10335,7 @@ static void K_drawKartMinimap(void)
|
|||
UINT8 *colormap = NULL;
|
||||
SINT8 localplayers[4];
|
||||
SINT8 numlocalplayers = 0;
|
||||
INT32 hyu = hyudorotime;
|
||||
mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!)
|
||||
|
||||
// Draw the HUD only when playing in a level.
|
||||
|
|
@ -10268,6 +10408,9 @@ static void K_drawKartMinimap(void)
|
|||
for (i = 0; i < 4; i++)
|
||||
localplayers[i] = -1;
|
||||
|
||||
if (G_RaceGametype())
|
||||
hyu *= 2; // double in race
|
||||
|
||||
// Player's tiny icons on the Automap. (drawn opposite direction so player 1 is drawn last in splitscreen)
|
||||
if (ghosts)
|
||||
{
|
||||
|
|
@ -10313,8 +10456,8 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
if (players[i].kartstuff[k_hyudorotimer] > 0)
|
||||
{
|
||||
if (!((players[i].kartstuff[k_hyudorotimer] < 1*TICRATE/2
|
||||
|| players[i].kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2))
|
||||
if (!((players[i].kartstuff[k_hyudorotimer] < TICRATE/2
|
||||
|| players[i].kartstuff[k_hyudorotimer] > hyu-(TICRATE/2))
|
||||
&& !(leveltime & 1)))
|
||||
continue;
|
||||
}
|
||||
|
|
@ -10596,7 +10739,7 @@ static void K_drawKartFirstPerson(void)
|
|||
UINT8 *colmap = NULL;
|
||||
ticcmd_t *cmd = &stplyr->cmd;
|
||||
|
||||
if (stplyr->spectator || !stplyr->mo || (stplyr->mo->flags2 & MF2_DONTDRAW))
|
||||
if (stplyr->spectator || !stplyr->mo || (stplyr->mo->drawflags & MFD_DONTDRAW))
|
||||
return;
|
||||
|
||||
if (stplyr == &players[displayplayers[1]] && r_splitscreen)
|
||||
|
|
@ -10618,9 +10761,9 @@ static void K_drawKartFirstPerson(void)
|
|||
{
|
||||
if (stplyr->speed < (20*stplyr->mo->scale) && (leveltime & 1) && !r_splitscreen)
|
||||
y++;
|
||||
// the following isn't EXPLICITLY right, it just gets the result we want, but i'm too lazy to look up the right way to do it
|
||||
if (stplyr->mo->flags2 & MF2_SHADOW)
|
||||
splitflags |= FF_TRANS80;
|
||||
|
||||
if (stplyr->mo->drawflags & MFD_TRANSMASK)
|
||||
splitflags |= ((stplyr->mo->drawflags & MFD_TRANSMASK) >> MFD_TRANSSHIFT) << FF_TRANSSHIFT;
|
||||
else if (stplyr->mo->frame & FF_TRANSMASK)
|
||||
splitflags |= (stplyr->mo->frame & FF_TRANSMASK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t
|
|||
|
||||
void K_RegisterKartStuff(void);
|
||||
|
||||
UINT16 K_GetPlayerDontDrawFlag(player_t *player);
|
||||
boolean K_IsPlayerLosing(player_t *player);
|
||||
fixed_t K_GetKartGameSpeedScalar(SINT8 value);
|
||||
|
||||
|
|
@ -28,7 +29,10 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
void K_KartPainEnergyFling(player_t *player);
|
||||
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||
void K_GenericExtraFlagsNoZAdjust(mobj_t *mo, mobj_t *master);
|
||||
void K_SpawnDashDustRelease(player_t *player);
|
||||
void K_SpawnDriftBoostClip(player_t *player);
|
||||
void K_SpawnDriftBoostClipSpark(mobj_t *clip);
|
||||
void K_KartMoveAnimation(player_t *player);
|
||||
void K_KartPlayerHUDUpdate(player_t *player);
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
||||
|
|
|
|||
|
|
@ -472,13 +472,44 @@ boolean K_PathfindAStar(path_t *const path, pathfindsetup_t *const pathfindsetup
|
|||
// Reallocate nodesarray if it's full
|
||||
if (nodesarraycount >= pathfindsetup->nodesarraycapacity)
|
||||
{
|
||||
pathfindnode_t *nodesarrayrealloc = NULL;
|
||||
pathfindsetup->nodesarraycapacity = pathfindsetup->nodesarraycapacity * 2;
|
||||
nodesarray = Z_Realloc(nodesarray, pathfindsetup->nodesarraycapacity * sizeof(pathfindnode_t), PU_STATIC, NULL);
|
||||
nodesarrayrealloc = Z_Realloc(nodesarray, pathfindsetup->nodesarraycapacity * sizeof(pathfindnode_t), PU_STATIC, NULL);
|
||||
|
||||
if (nodesarray == NULL)
|
||||
if (nodesarrayrealloc == NULL)
|
||||
{
|
||||
I_Error("K_PathfindAStar: Out of memory reallocating nodes array.");
|
||||
}
|
||||
|
||||
// Need to update pointers in closedset, openset, and node "camefrom" if nodesarray moved.
|
||||
if (nodesarray != nodesarrayrealloc)
|
||||
{
|
||||
size_t j = 0U;
|
||||
size_t arrayindex = 0U;
|
||||
for (j = 0U; j < closedsetcount; j++)
|
||||
{
|
||||
arrayindex = closedset[j] - nodesarray;
|
||||
closedset[j] = &nodesarrayrealloc[arrayindex];
|
||||
}
|
||||
for (j = 0U; j < openset.count; j++)
|
||||
{
|
||||
arrayindex = ((pathfindnode_t *)(openset.array[j].data)) - nodesarray;
|
||||
openset.array[j].data = &nodesarrayrealloc[arrayindex];
|
||||
}
|
||||
for (j = 0U; j < nodesarraycount; j++)
|
||||
{
|
||||
if (nodesarrayrealloc[j].camefrom != NULL)
|
||||
{
|
||||
arrayindex = nodesarrayrealloc[j].camefrom - nodesarray;
|
||||
nodesarrayrealloc[j].camefrom = &nodesarrayrealloc[arrayindex];
|
||||
}
|
||||
}
|
||||
|
||||
arrayindex = currentnode - nodesarray;
|
||||
currentnode = &nodesarrayrealloc[arrayindex];
|
||||
}
|
||||
|
||||
nodesarray = nodesarrayrealloc;
|
||||
}
|
||||
|
||||
// Create the new node and add it to the nodes array and open set
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ enum mobj_e {
|
|||
mobj_flags,
|
||||
mobj_flags2,
|
||||
mobj_eflags,
|
||||
mobj_drawflags,
|
||||
mobj_skin,
|
||||
mobj_color,
|
||||
mobj_bnext,
|
||||
|
|
@ -119,6 +120,7 @@ static const char *const mobj_opt[] = {
|
|||
"flags",
|
||||
"flags2",
|
||||
"eflags",
|
||||
"drawflags",
|
||||
"skin",
|
||||
"color",
|
||||
"bnext",
|
||||
|
|
@ -255,6 +257,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_eflags:
|
||||
lua_pushinteger(L, mo->eflags);
|
||||
break;
|
||||
case mobj_drawflags:
|
||||
lua_pushinteger(L, mo->drawflags);
|
||||
break;
|
||||
case mobj_skin: // skin name or nil, not struct
|
||||
if (!mo->skin)
|
||||
return 0;
|
||||
|
|
@ -541,7 +546,10 @@ static int mobj_set(lua_State *L)
|
|||
mo->flags2 = (UINT32)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_eflags:
|
||||
mo->eflags = (UINT32)luaL_checkinteger(L, 3);
|
||||
mo->eflags = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_drawflags:
|
||||
mo->drawflags = (UINT16)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_skin: // set skin by name
|
||||
{
|
||||
|
|
|
|||
|
|
@ -239,6 +239,14 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->kartspeed);
|
||||
else if (fastcmp(field,"kartweight"))
|
||||
lua_pushinteger(L, plr->kartweight);
|
||||
else if (fastcmp(field,"followerskin"))
|
||||
lua_pushinteger(L, plr->followerskin);
|
||||
else if (fastcmp(field,"followerready"))
|
||||
lua_pushboolean(L, plr->followerready);
|
||||
else if (fastcmp(field,"followercolor"))
|
||||
lua_pushinteger(L, plr->followercolor);
|
||||
else if (fastcmp(field,"follower"))
|
||||
LUA_PushUserdata(L, plr->follower, META_MOBJ);
|
||||
//
|
||||
else if (fastcmp(field,"charflags"))
|
||||
lua_pushinteger(L, plr->charflags);
|
||||
|
|
@ -368,6 +376,7 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->awayviewtics);
|
||||
else if (fastcmp(field,"awayviewaiming"))
|
||||
lua_pushangle(L, plr->awayviewaiming);
|
||||
|
||||
else if (fastcmp(field,"spectator"))
|
||||
lua_pushboolean(L, plr->spectator);
|
||||
else if (fastcmp(field,"bot"))
|
||||
|
|
@ -483,6 +492,14 @@ static int player_set(lua_State *L)
|
|||
plr->kartspeed = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"kartweight"))
|
||||
plr->kartweight = (UINT8)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"followerskin"))
|
||||
plr->followerskin = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"followercolor"))
|
||||
plr->followercolor = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"followerready"))
|
||||
plr->followerready = luaL_checkboolean(L, 3);
|
||||
else if (fastcmp(field,"follower")) // it's probably best we don't allow the follower mobj to change.
|
||||
return NOSET;
|
||||
//
|
||||
else if (fastcmp(field,"charflags"))
|
||||
plr->charflags = (UINT32)luaL_checkinteger(L, 3);
|
||||
|
|
|
|||
219
src/m_menu.c
219
src/m_menu.c
|
|
@ -158,6 +158,7 @@ INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
|
|||
|
||||
static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002
|
||||
static INT16 skullAnimCounter = 10; // skull animation counter
|
||||
static tic_t followertimer = 0; // Used for smooth follower floating
|
||||
|
||||
static UINT8 setupcontrolplayer;
|
||||
static INT32 (*setupcontrols)[2]; // pointer to the gamecontrols of the player being edited
|
||||
|
|
@ -1032,6 +1033,7 @@ static menuitem_t MP_PlayerSetupMenu[] =
|
|||
{
|
||||
{IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0},
|
||||
{IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // Tails 01-18-2001
|
||||
{IT_KEYHANDLER | IT_STRING, NULL, "Follower", M_HandleSetupMultiPlayer, 26},
|
||||
{IT_KEYHANDLER | IT_STRING, NULL, "Color", M_HandleSetupMultiPlayer, 152},
|
||||
};
|
||||
|
||||
|
|
@ -1430,24 +1432,27 @@ enum
|
|||
|
||||
static menuitem_t OP_HUDOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "HUD Visibility", &cv_translucenthud, 20},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show Followers", &cv_showfollowers, 10},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 20},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "HUD Visibility", &cv_translucenthud, 30},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 55},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Minimap Visibility", &cv_kartminimap, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 80},
|
||||
NULL, "Minimap Visibility", &cv_kartminimap, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Speedometer Display", &cv_kartspeedometer, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"CHECK\"", &cv_kartcheck, 90},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Menu Highlights", &cons_menuhighlight, 105},
|
||||
// highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 105 (see M_DrawHUDOptions)
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 130},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 145},
|
||||
};
|
||||
|
||||
// Ok it's still called chatoptions but we'll put ping display in here to be clean
|
||||
|
|
@ -3336,6 +3341,8 @@ void M_Ticker(void)
|
|||
if (--skullAnimCounter <= 0)
|
||||
skullAnimCounter = 8;
|
||||
|
||||
followertimer++;
|
||||
|
||||
if (currentMenu == &PlaybackMenuDef)
|
||||
{
|
||||
if (playback_enterheld > 0)
|
||||
|
|
@ -5693,7 +5700,7 @@ static void M_DrawReplayStartMenu(void)
|
|||
// Lat: 08/06/2020: For some reason missing skins have their value set to 255 (don't even ask me why I didn't write this)
|
||||
// and for an even STRANGER reason this passes the first check below, so we're going to make sure that the skin here ISN'T 255 before we do anything stupid.
|
||||
|
||||
if (demolist[dir_on[menudepthleft]].standings[0].skin != 0xFF && W_CheckNumForName(skins[demolist[dir_on[menudepthleft]].standings[i].skin].facerank) != LUMPERROR)
|
||||
if (demolist[dir_on[menudepthleft]].standings[i].skin != 0xFF && W_CheckNumForName(skins[demolist[dir_on[menudepthleft]].standings[i].skin].facerank) != LUMPERROR)
|
||||
{
|
||||
patch = facerankprefix[demolist[dir_on[menudepthleft]].standings[i].skin];
|
||||
colormap = R_GetTranslationColormap(
|
||||
|
|
@ -9312,9 +9319,15 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
// ========================
|
||||
// Tails 03-02-2002
|
||||
|
||||
// used for skin display on player setup menu
|
||||
static INT32 multi_tics;
|
||||
static state_t *multi_state;
|
||||
|
||||
// used for follower display on player setup menu
|
||||
static INT32 follower_tics;
|
||||
static UINT32 follower_frame; // used for FF_ANIMATE garbo
|
||||
static state_t *follower_state;
|
||||
|
||||
// this is set before entering the MultiPlayer setup menu,
|
||||
// for either player 1 or 2
|
||||
static char setupm_name[MAXPLAYERNAME+1];
|
||||
|
|
@ -9322,8 +9335,10 @@ static player_t *setupm_player;
|
|||
static consvar_t *setupm_cvskin;
|
||||
static consvar_t *setupm_cvcolor;
|
||||
static consvar_t *setupm_cvname;
|
||||
static consvar_t *setupm_cvfollower;
|
||||
static INT32 setupm_fakeskin;
|
||||
static INT32 setupm_fakecolor;
|
||||
static INT32 setupm_fakefollower; // -1 is for none, our followers start at 0
|
||||
|
||||
static void M_DrawSetupMultiPlayerMenu(void)
|
||||
{
|
||||
|
|
@ -9341,6 +9356,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
UINT8 i;
|
||||
const UINT8 *flashcol = V_GetStringColormap(highlightflags);
|
||||
INT32 statx, staty;
|
||||
char *fname;
|
||||
|
||||
mx = MP_PlayerSetupDef.x;
|
||||
my = MP_PlayerSetupDef.y;
|
||||
|
|
@ -9372,11 +9388,31 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
'\x1D' | highlightflags, false); // right arrow
|
||||
}
|
||||
|
||||
// draw follower string
|
||||
fname = malloc(SKINNAMESIZE+1);
|
||||
|
||||
if (setupm_fakefollower == -1)
|
||||
strcpy(fname, "None");
|
||||
else
|
||||
strcpy(fname, followers[setupm_fakefollower].name);
|
||||
|
||||
st = V_StringWidth(fname, 0);
|
||||
V_DrawString(BASEVIDWIDTH - mx - st, my + 26,
|
||||
((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|highlightflags|V_ALLOWLOWERCASE,
|
||||
fname);
|
||||
if (itemOn == 2)
|
||||
{
|
||||
V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 26,
|
||||
'\x1C' | highlightflags, false); // left arrow
|
||||
V_DrawCharacter(BASEVIDWIDTH - mx + 2 + (skullAnimCounter/5), my + 26,
|
||||
'\x1D' | highlightflags, false); // right arrow
|
||||
}
|
||||
|
||||
// draw the name of the color you have chosen
|
||||
// Just so people don't go thinking that "Default" is Green.
|
||||
st = V_StringWidth(KartColor_Names[setupm_fakecolor], 0);
|
||||
V_DrawString(BASEVIDWIDTH - mx - st, my + 152, highlightflags|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart
|
||||
if (itemOn == 2)
|
||||
if (itemOn == 3)
|
||||
{
|
||||
V_DrawCharacter(BASEVIDWIDTH - mx - 10 - st - (skullAnimCounter/5), my + 152,
|
||||
'\x1C' | highlightflags, false); // left arrow
|
||||
|
|
@ -9524,7 +9560,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
|
||||
sprframe = &sprdef->spriteframes[frame];
|
||||
patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
|
||||
if (sprframe->flip & 1) // Only for first sprite
|
||||
if (sprframe->flip & 2) // Only for first sprite
|
||||
flags |= V_FLIP; // This sprite is left/right flipped!
|
||||
|
||||
// draw box around guy
|
||||
|
|
@ -9545,9 +9581,88 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
else
|
||||
V_DrawMappedPatch(mx+43, my+131, flags, patch, colormap);
|
||||
}
|
||||
|
||||
// draw their follower if there is one
|
||||
if (setupm_fakefollower > -1 && setupm_fakefollower < numfollowers)
|
||||
{
|
||||
// animate the follower
|
||||
|
||||
if (--follower_tics <= 0)
|
||||
{
|
||||
|
||||
// FF_ANIMATE; cycle through FRAMES and get back afterwards. This will be prominent amongst followers hence why it's being supported here.
|
||||
if (follower_state->frame & FF_ANIMATE)
|
||||
{
|
||||
follower_frame++;
|
||||
follower_tics = follower_state->var2;
|
||||
if (follower_frame > (follower_state->frame & FF_FRAMEMASK) + follower_state->var1) // that's how it works, right?
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
st = follower_state->nextstate;
|
||||
if (st != S_NULL)
|
||||
follower_state = &states[st];
|
||||
follower_tics = follower_state->tics;
|
||||
if (follower_tics == -1)
|
||||
follower_tics = 15; // er, what?
|
||||
// get spritedef:
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
}
|
||||
sprdef = &sprites[follower_state->sprite];
|
||||
|
||||
// draw the follower
|
||||
|
||||
if (follower_frame >= sprdef->numframes)
|
||||
follower_frame = 0; // frame doesn't exist, we went beyond it... what?
|
||||
sprframe = &sprdef->spriteframes[follower_frame];
|
||||
patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE);
|
||||
if (sprframe->flip & 2) // Only for first sprite
|
||||
flags |= V_FLIP; // This sprite is left/right flipped!
|
||||
|
||||
// @TODO: Reminder that followers on the menu right now do NOT support the 'followercolor' command, considering this whole menu is getting remade anyway, I see no point in incorporating it in right now.
|
||||
|
||||
// draw follower sprite
|
||||
if (setupm_fakecolor) // inverse should never happen
|
||||
{
|
||||
|
||||
// Fake the follower's in game appearance by now also applying some of its variables! coolio, eh?
|
||||
follower_t fl = followers[setupm_fakefollower]; // shortcut for our sanity
|
||||
// smooth floating, totally not stolen from rocket sneakers.
|
||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||
fixed_t sine = fl.bobamp * FINESINE((((8*pi*(fl.bobspeed)) * followertimer)>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
|
||||
UINT8 *colormap = R_GetTranslationColormap(-1, setupm_fakecolor, 0);
|
||||
V_DrawFixedPatch((mx+65)*FRACUNIT, (my+131-fl.zoffs)*FRACUNIT+sine, fl.scale, flags, patch, colormap);
|
||||
Z_Free(colormap);
|
||||
}
|
||||
}
|
||||
|
||||
#undef charw
|
||||
}
|
||||
|
||||
// follower state update. This is its own function so that it's at least somewhat clean
|
||||
static void M_GetFollowerState(void)
|
||||
{
|
||||
|
||||
if (setupm_fakefollower <= -1 || setupm_fakefollower > numfollowers-1) // yikes, there's none!
|
||||
return;
|
||||
// ^ we don't actually need to set anything since it won't be displayed anyway.
|
||||
|
||||
//followertimer = 0; // reset timer. not like it'll overflow anytime soon but whatever.
|
||||
|
||||
// set follower state
|
||||
follower_state = &states[followers[setupm_fakefollower].followstate];
|
||||
|
||||
if (follower_state->frame & FF_ANIMATE)
|
||||
follower_tics = follower_state->var2; // support for FF_ANIMATE
|
||||
else
|
||||
follower_tics = follower_state->tics;
|
||||
|
||||
follower_frame = follower_state->frame & FF_FRAMEMASK;
|
||||
}
|
||||
|
||||
// Handle 1P/2P MP Setup
|
||||
static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
{
|
||||
|
|
@ -9575,7 +9690,13 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
|||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_fakeskin--;
|
||||
}
|
||||
else if (itemOn == 2) // player color
|
||||
else if (itemOn == 2) // follower
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1);
|
||||
setupm_fakefollower--;
|
||||
M_GetFollowerState(); // update follower state
|
||||
}
|
||||
else if (itemOn == 3) // player color
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_fakecolor--;
|
||||
|
|
@ -9587,8 +9708,15 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
|||
{
|
||||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_fakeskin++;
|
||||
M_GetFollowerState(); // update follower state
|
||||
}
|
||||
else if (itemOn == 2) // player color
|
||||
else if (itemOn == 2) // follower
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1);
|
||||
setupm_fakefollower++;
|
||||
M_GetFollowerState();
|
||||
}
|
||||
else if (itemOn == 3) // player color
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_fakecolor++;
|
||||
|
|
@ -9608,7 +9736,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
|||
setupm_name[l-1] =0;
|
||||
}
|
||||
}
|
||||
else if (itemOn == 2)
|
||||
else if (itemOn == 2) // follower
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1);
|
||||
setupm_fakefollower = -1;
|
||||
}
|
||||
else if (itemOn == 3)
|
||||
{
|
||||
UINT8 col = skins[setupm_fakeskin].prefcolor;
|
||||
if (setupm_fakecolor != col)
|
||||
|
|
@ -9646,6 +9779,18 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
|||
if (setupm_fakeskin > numskins-1)
|
||||
setupm_fakeskin = 0;
|
||||
|
||||
// check followers:
|
||||
if (setupm_fakefollower < -1)
|
||||
{
|
||||
setupm_fakefollower = numfollowers-1;
|
||||
M_GetFollowerState(); // update follower state
|
||||
}
|
||||
if (setupm_fakefollower > numfollowers-1)
|
||||
{
|
||||
setupm_fakefollower = -1;
|
||||
M_GetFollowerState(); // update follower state
|
||||
}
|
||||
|
||||
// check color
|
||||
if (setupm_fakecolor < 1)
|
||||
setupm_fakecolor = MAXSKINCOLORS-1;
|
||||
|
|
@ -9668,6 +9813,7 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
|
||||
multi_state = &states[mobjinfo[MT_PLAYER].seestate];
|
||||
multi_tics = multi_state->tics;
|
||||
|
||||
strcpy(setupm_name, cv_playername.string);
|
||||
|
||||
// set for player 1
|
||||
|
|
@ -9675,6 +9821,15 @@ static void M_SetupMultiPlayer(INT32 choice)
|
|||
setupm_cvskin = &cv_skin;
|
||||
setupm_cvcolor = &cv_playercolor;
|
||||
setupm_cvname = &cv_playername;
|
||||
setupm_cvfollower = &cv_follower;
|
||||
|
||||
setupm_fakefollower = atoi(setupm_cvfollower->string); // update fake follower value
|
||||
|
||||
// yikes, we don't want none of that...
|
||||
if (setupm_fakefollower > numfollowers-1)
|
||||
setupm_fakefollower = -1;
|
||||
|
||||
M_GetFollowerState(); // update follower state
|
||||
|
||||
// For whatever reason this doesn't work right if you just use ->value
|
||||
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
|
||||
|
|
@ -9706,6 +9861,15 @@ static void M_SetupMultiPlayer2(INT32 choice)
|
|||
setupm_cvskin = &cv_skin2;
|
||||
setupm_cvcolor = &cv_playercolor2;
|
||||
setupm_cvname = &cv_playername2;
|
||||
setupm_cvfollower = &cv_follower2;
|
||||
|
||||
setupm_fakefollower = atoi(setupm_cvfollower->string); // update fake follower value
|
||||
|
||||
// yikes, we don't want none of that...
|
||||
if (setupm_fakefollower > numfollowers-1)
|
||||
setupm_fakefollower = -1;
|
||||
|
||||
M_GetFollowerState(); // update follower state
|
||||
|
||||
// For whatever reason this doesn't work right if you just use ->value
|
||||
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
|
||||
|
|
@ -9737,6 +9901,15 @@ static void M_SetupMultiPlayer3(INT32 choice)
|
|||
setupm_cvskin = &cv_skin3;
|
||||
setupm_cvcolor = &cv_playercolor3;
|
||||
setupm_cvname = &cv_playername3;
|
||||
setupm_cvfollower = &cv_follower3;
|
||||
|
||||
setupm_fakefollower = atoi(setupm_cvfollower->string); // update fake follower value
|
||||
|
||||
// yikes, we don't want none of that...
|
||||
if (setupm_fakefollower > numfollowers-1)
|
||||
setupm_fakefollower = -1;
|
||||
|
||||
M_GetFollowerState(); // update follower state
|
||||
|
||||
// For whatever reason this doesn't work right if you just use ->value
|
||||
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
|
||||
|
|
@ -9768,6 +9941,15 @@ static void M_SetupMultiPlayer4(INT32 choice)
|
|||
setupm_cvskin = &cv_skin4;
|
||||
setupm_cvcolor = &cv_playercolor4;
|
||||
setupm_cvname = &cv_playername4;
|
||||
setupm_cvfollower = &cv_follower4;
|
||||
|
||||
setupm_fakefollower = atoi(setupm_cvfollower->string); // update fake follower value
|
||||
|
||||
// yikes, we don't want none of that...
|
||||
if (setupm_fakefollower > numfollowers-1)
|
||||
setupm_fakefollower = -1;
|
||||
|
||||
M_GetFollowerState(); // update follower state
|
||||
|
||||
// For whatever reason this doesn't work right if you just use ->value
|
||||
setupm_fakeskin = R_SkinAvailable(setupm_cvskin->string);
|
||||
|
|
@ -9800,6 +9982,7 @@ static boolean M_QuitMultiPlayerMenu(void)
|
|||
// you know what? always putting these in the buffer won't hurt anything.
|
||||
COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name));
|
||||
COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor));
|
||||
COM_BufAddText (va("%s %d\n",setupm_cvfollower->name,setupm_fakefollower));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -10683,7 +10866,7 @@ static void M_DrawHUDOptions(void)
|
|||
const char *str1 = " Warning highlight";
|
||||
const char *str2 = ",";
|
||||
const char *str3 = "Good highlight";
|
||||
INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 105;
|
||||
INT32 x = BASEVIDWIDTH - currentMenu->x + 2, y = currentMenu->y + 115;
|
||||
INT32 w0 = V_StringWidth(str0, 0), w1 = V_StringWidth(str1, 0), w2 = V_StringWidth(str2, 0), w3 = V_StringWidth(str3, 0);
|
||||
|
||||
M_DrawGenericMenu();
|
||||
|
|
|
|||
|
|
@ -3412,10 +3412,10 @@ void A_BubbleSpawn(mobj_t *actor)
|
|||
if (!(actor->eflags & MFE_UNDERWATER))
|
||||
{
|
||||
// Don't draw or spawn bubbles above water
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
actor->drawflags |= MFD_DONTDRAW;
|
||||
return;
|
||||
}
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
actor->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
if (!(actor->flags2 & MF2_AMBUSH))
|
||||
{
|
||||
|
|
@ -3547,9 +3547,9 @@ void A_BubbleCheck(mobj_t *actor)
|
|||
return;
|
||||
#endif
|
||||
if (actor->eflags & MFE_UNDERWATER)
|
||||
actor->flags2 &= ~MF2_DONTDRAW; // underwater so draw
|
||||
actor->drawflags &= ~MFD_DONTDRAW; // underwater so draw
|
||||
else
|
||||
actor->flags2 |= MF2_DONTDRAW; // above water so don't draw
|
||||
actor->drawflags |= MFD_DONTDRAW; // above water so don't draw
|
||||
}
|
||||
|
||||
// Function: A_AttractChase
|
||||
|
|
@ -3654,9 +3654,9 @@ void A_AttractChase(mobj_t *actor)
|
|||
|
||||
// Rings flicker before disappearing
|
||||
if (actor->fuse && actor->fuse < 5*TICRATE && (leveltime & 1))
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
actor->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
actor->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
// spilled rings have ghost trails and get capped to a certain speed
|
||||
if (actor->type == (mobjtype_t)actor->info->reactiontime)
|
||||
|
|
@ -3877,9 +3877,9 @@ void A_ThrownRing(mobj_t *actor)
|
|||
// spilled rings (and thrown bounce) flicker before disappearing
|
||||
if (leveltime & 1 && actor->fuse > 0 && actor->fuse < 2*TICRATE
|
||||
&& actor->type != MT_THROWNGRENADE)
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
actor->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
actor->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
if (actor->tracer && actor->tracer->health <= 0)
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
|
|
@ -5342,9 +5342,9 @@ void A_CrawlaCommanderThink(mobj_t *actor)
|
|||
thefloor = actor->floorz;
|
||||
|
||||
if (actor->fuse & 1)
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
actor->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
actor->flags2 &= ~MF2_DONTDRAW;
|
||||
actor->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
if (actor->reactiontime > 0)
|
||||
actor->reactiontime--;
|
||||
|
|
@ -9067,7 +9067,7 @@ void A_RandomShadowFrame(mobj_t *actor)
|
|||
fake->destscale = FRACUNIT*3/2;
|
||||
fake->angle = actor->angle;
|
||||
fake->tics = -1;
|
||||
actor->flags2 |= MF2_DONTDRAW;
|
||||
actor->drawflags |= MFD_DONTDRAW;
|
||||
actor->extravalue1 = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2218,7 +2218,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
|||
target->player->score = 0;
|
||||
}*/
|
||||
|
||||
target->flags2 &= ~MF2_DONTDRAW;
|
||||
target->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
// if killed by a player
|
||||
|
|
@ -2959,7 +2959,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
{
|
||||
mobj_t *boom;
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM);
|
||||
boom->scale = player->mo->scale;
|
||||
boom->angle = player->mo->angle;
|
||||
|
|
|
|||
253
src/p_mobj.c
253
src/p_mobj.c
|
|
@ -2457,6 +2457,17 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale);
|
||||
else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here
|
||||
;
|
||||
else if (mo->type == MT_DRIFTCLIP)
|
||||
{
|
||||
mom.z = -mom.z/2;
|
||||
if (abs(mom.z) > 4 * mo->scale / 3)
|
||||
{
|
||||
K_SpawnDriftBoostClipSpark(mo);
|
||||
S_StartSound(mo, sfx_tink);
|
||||
}
|
||||
else
|
||||
mo->flags2 ^= MFD_DONTDRAW;
|
||||
}
|
||||
else if (mo->flags & MF_MISSILE)
|
||||
{
|
||||
if (!(mo->flags & MF_NOCLIP))
|
||||
|
|
@ -4030,9 +4041,9 @@ static void P_RingThinker(mobj_t *mobj)
|
|||
if (mobj->fuse < TICRATE*3)
|
||||
{
|
||||
if (leveltime & 1)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
if (!mobj->fuse)
|
||||
|
|
@ -4041,7 +4052,7 @@ static void P_RingThinker(mobj_t *mobj)
|
|||
if (!LUAh_MobjFuse(mobj))
|
||||
#endif
|
||||
{
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
spark = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SIGNSPARKLE); // Spawn a fancy sparkle
|
||||
K_MatchGenericExtraFlags(spark, mobj);
|
||||
spark->colorized = true;
|
||||
|
|
@ -6068,14 +6079,14 @@ static void P_NightsItemChase(mobj_t *thing)
|
|||
if (thing->info->painstate)
|
||||
P_SetMobjState(thing,thing->info->painstate);
|
||||
else
|
||||
thing->flags2 |= MF2_SHADOW;
|
||||
thing->drawflags |= MFD_SHADOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thing->info->painstate)
|
||||
P_SetMobjState(thing,thing->info->spawnstate);
|
||||
else
|
||||
thing->flags2 &= ~MF2_SHADOW;
|
||||
thing->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6464,7 +6475,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
|
||||
&& (signed)(mobj->frame >> FF_TRANSSHIFT) < (NUMTRANSMAPS-1) - mobj->fuse / 2)
|
||||
// fade out when nearing the end of fuse...
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
||||
mobj->drawflags = (mobj->drawflags & ~MFD_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << MFD_TRANSSHIFT);
|
||||
|
||||
// Special thinker for scenery objects
|
||||
if (mobj->flags & MF_SCENERY)
|
||||
|
|
@ -6477,6 +6488,27 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
#endif
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_FOLLOWER:
|
||||
// small thinker for follower:
|
||||
// We cleanse ourselves from existence if our target player doesn't exist for whatever reason. (generally players leaving)
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player || mobj->target->player->spectator || mobj->target->player->followerskin < 0)
|
||||
{
|
||||
// Remove possible hnext list (bubble)
|
||||
mobj_t *bub = mobj->hnext;
|
||||
mobj_t *tmp;
|
||||
|
||||
while (bub && !P_MobjWasRemoved(bub))
|
||||
{
|
||||
tmp = bub->hnext;
|
||||
P_RemoveMobj(bub);
|
||||
bub = tmp;
|
||||
}
|
||||
|
||||
P_RemoveMobj(mobj);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case MT_HOOP:
|
||||
if (mobj->fuse > 1)
|
||||
P_MoveHoop(mobj);
|
||||
|
|
@ -6630,30 +6662,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
offz = mobj->target->height / 5;
|
||||
}
|
||||
|
||||
if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann...
|
||||
mobj->eflags |= MFE_DRAWONLYFORP1;
|
||||
else
|
||||
mobj->eflags &= ~MFE_DRAWONLYFORP1;
|
||||
|
||||
if (mobj->target->eflags & MFE_DRAWONLYFORP2)
|
||||
mobj->eflags |= MFE_DRAWONLYFORP2;
|
||||
else
|
||||
mobj->eflags &= ~MFE_DRAWONLYFORP2;
|
||||
|
||||
if (mobj->target->eflags & MFE_DRAWONLYFORP3)
|
||||
mobj->eflags |= MFE_DRAWONLYFORP3;
|
||||
else
|
||||
mobj->eflags &= ~MFE_DRAWONLYFORP3;
|
||||
|
||||
if (mobj->target->eflags & MFE_DRAWONLYFORP4)
|
||||
mobj->eflags |= MFE_DRAWONLYFORP4;
|
||||
else
|
||||
mobj->eflags &= ~MFE_DRAWONLYFORP4;
|
||||
|
||||
if (mobj->target->flags2 & MF2_DONTDRAW)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags = (mobj->target->drawflags & MFD_DONTDRAW);
|
||||
|
||||
if (mobj->target->eflags & MFE_VERTICALFLIP)
|
||||
offz += 4*FRACUNIT;
|
||||
|
|
@ -6716,7 +6725,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|| (P_IsDisplayPlayer(mobj->target->player))
|
||||
#endif
|
||||
)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = mobj->target->x;
|
||||
|
|
@ -6766,7 +6775,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer->colorized = false;
|
||||
}
|
||||
|
||||
if (!(mobj->flags2 & MF2_DONTDRAW))
|
||||
if (!(mobj->drawflags & MFD_DONTDRAW))
|
||||
{
|
||||
const INT32 numberdisplaymin = ((mobj->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2);
|
||||
|
||||
|
|
@ -6776,7 +6785,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|(((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3) + 1);
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->kartstuff[k_stolentimer] > 0)
|
||||
{
|
||||
|
|
@ -6784,16 +6793,16 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
if (leveltime & 2)
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->flags2 |= MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else if ((mobj->target->player->kartstuff[k_stealingtimer] > 0) && (leveltime & 2))
|
||||
{
|
||||
P_SetMobjState(mobj, S_PLAYERARROW_BOX);
|
||||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->kartstuff[k_eggmanexplode] > 1)
|
||||
{
|
||||
|
|
@ -6801,9 +6810,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->flags2 |= MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->kartstuff[k_rocketsneakertimer] > 1)
|
||||
{
|
||||
|
|
@ -6812,9 +6821,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->tracer->sprite = SPR_ITEM;
|
||||
mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER;
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->flags2 |= MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->target->player->kartstuff[k_itemtype] && mobj->target->player->kartstuff[k_itemamount] > 0)
|
||||
{
|
||||
|
|
@ -6843,12 +6852,12 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->target->player->kartstuff[k_itemheld])
|
||||
{
|
||||
if (leveltime & 1)
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->tracer->flags2 |= MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else
|
||||
mobj->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6889,7 +6898,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->movecount = 0;
|
||||
}
|
||||
else
|
||||
mobj->tracer->flags2 |= MF2_DONTDRAW;
|
||||
mobj->tracer->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->health > 0)
|
||||
{
|
||||
|
|
@ -6912,10 +6921,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mobj->tracer->flags2 & MF2_DONTDRAW)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
if (mobj->tracer->drawflags & MFD_DONTDRAW)
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = mobj->target->x;
|
||||
|
|
@ -6966,7 +6975,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->eflags |= MFE_VERTICALFLIP;
|
||||
|
||||
if (mobj->tics > 0)
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
break;
|
||||
//}
|
||||
case MT_WATERDROP:
|
||||
|
|
@ -7027,9 +7036,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes
|
||||
|
||||
if (mobj->threshold <= 35)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
if (mobj->threshold <= 30)
|
||||
mobj->threshold = 40;
|
||||
mobj->threshold--;
|
||||
|
|
@ -7349,14 +7359,15 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
break;
|
||||
case MT_PLAYER:
|
||||
/// \todo Have the player's dead body completely finish its animation even if they've already respawned.
|
||||
if (!(mobj->flags2 & MF2_DONTDRAW))
|
||||
// This feels like it has some serious potential for breakage. Is there anything else we can base this off of instead of a drawing flag?
|
||||
if (!(mobj->drawflags & MFD_DONTDRAW))
|
||||
{
|
||||
if (!mobj->fuse)
|
||||
{ // Go away.
|
||||
/// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it.
|
||||
mobj->momz = 0;
|
||||
if (mobj->player)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else // safe to remove, nobody's going to complain!
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
|
|
@ -7385,7 +7396,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
break;
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_DUD:
|
||||
|
|
@ -7393,7 +7404,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetMobjState(mobj, mobj->info->xdeathstate);
|
||||
// fallthru
|
||||
case MT_JAWZ_SHIELD:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
break;
|
||||
case MT_SSMINE:
|
||||
case MT_SPBEXPLOSION:
|
||||
|
|
@ -7413,7 +7424,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
case MT_CDUFO:
|
||||
if (mobj->fuse > TICRATE)
|
||||
mobj->flags2 ^= MF2_DONTDRAW; // only by good fortune does this end with it having MF2_DONTDRAW... don't touch!
|
||||
mobj->drawflags ^= MFD_DONTDRAW; // only by good fortune does this end with it having MFD_DONTDRAW... don't touch!
|
||||
break;
|
||||
case MT_SMK_PIPE:
|
||||
if (mobj->flags2 & MF2_AMBUSH)
|
||||
|
|
@ -7422,7 +7433,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetMobjStateNF(mobj, mobj->info->spawnstate);
|
||||
/* FALLTHRU */
|
||||
case MT_SMK_MOLE:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
|
|
@ -7443,7 +7454,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->frame &= (~FF_FULLBRIGHT);
|
||||
}
|
||||
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
if (P_IsObjectOnGround(mobj))
|
||||
{
|
||||
P_RemoveMobj(mobj);
|
||||
|
|
@ -7743,7 +7754,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_NIGHTSDRONE:
|
||||
if (mobj->state >= &states[S_NIGHTSDRONE_SPARKLING1] && mobj->state <= &states[S_NIGHTSDRONE_SPARKLING16])
|
||||
{
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
mobj->z = mobj->floorz + mobj->height + (mobj->spawnpoint->options >> ZSHIFT) * FRACUNIT;
|
||||
mobj->angle = 0;
|
||||
|
||||
|
|
@ -7769,7 +7780,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
{
|
||||
mobj->flags &= ~MF_NOGRAVITY;
|
||||
P_SetMobjState(mobj, S_NIGHTSDRONE1);
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
}
|
||||
else if (mobj->tracer && mobj->tracer->player)
|
||||
|
|
@ -7777,7 +7788,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (!(mobj->tracer->player->pflags & PF_NIGHTSMODE))
|
||||
{
|
||||
mobj->flags &= ~MF_NOGRAVITY;
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
P_SetMobjState(mobj, S_NIGHTSDRONE1);
|
||||
}
|
||||
else if (!mobj->tracer->player->bonustime)
|
||||
|
|
@ -7814,7 +7825,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_RemoveMobj(mobj->target);
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
}
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
}
|
||||
else if (mobj->tracer && mobj->tracer->player)
|
||||
|
|
@ -7834,10 +7845,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
else
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else // Not NiGHTS
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
mobj->angle += ANG10;
|
||||
if (mobj->z <= mobj->floorz)
|
||||
|
|
@ -8279,15 +8290,62 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
mobj->angle = mobj->target->angle;
|
||||
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||
//mobj->angle = mobj->target->angle;
|
||||
{
|
||||
angle_t angle = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy);
|
||||
fixed_t nudge;
|
||||
|
||||
mobj->angle = angle;
|
||||
|
||||
if (( mobj->fuse & 1 ))
|
||||
{
|
||||
nudge = 4*mobj->target->radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
nudge = 2*mobj->target->radius;
|
||||
/* rotate the papersprite frames to see the flat angle */
|
||||
mobj->angle += ANGLE_90;
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj,
|
||||
mobj->target->x + P_ReturnThrustX(mobj, angle + ANGLE_180, nudge),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, angle + ANGLE_180, nudge),
|
||||
mobj->target->z);
|
||||
}
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->target->modeltilt;
|
||||
#endif
|
||||
|
||||
if (mobj->fuse <= 16)
|
||||
{
|
||||
mobj->color = SKINCOLOR_KETCHUP;
|
||||
/* don't draw papersprite frames after blue boost */
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
}
|
||||
else if (mobj->fuse <= 32)
|
||||
mobj->color = SKINCOLOR_SAPPHIRE;
|
||||
else if (mobj->fuse > 32)
|
||||
mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
|
||||
|
||||
switch (mobj->extravalue1)
|
||||
{
|
||||
case 3:/* rainbow boost */
|
||||
/* every 20 tics, bang! */
|
||||
if (( 120 - mobj->fuse ) % 10 == 0)
|
||||
{
|
||||
K_SpawnDriftBoostClip(mobj->target->player);
|
||||
S_StartSound(mobj->target, sfx_s3k77);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:/* blue boost */
|
||||
if (mobj->fuse == 16)/* to red*/
|
||||
K_SpawnDriftBoostClip(mobj->target->player);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
player_t *p = NULL;
|
||||
if (mobj->target->target && mobj->target->target->player)
|
||||
|
|
@ -8402,7 +8460,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
if (leveltime & 1)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
break;
|
||||
case MT_PLAYERRETICULE:
|
||||
|
|
@ -8414,7 +8472,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
|
||||
break;
|
||||
case MT_INSTASHIELDB:
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
/* FALLTHRU */
|
||||
case MT_INSTASHIELDA:
|
||||
|
|
@ -8527,14 +8585,14 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
mobj->angle = ang;
|
||||
|
||||
if (leveltime & 1)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
if (trans >= NUMTRANSMAPS)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else if (trans == 0)
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK);
|
||||
mobj->drawflags = (mobj->drawflags & ~MFD_TRANSMASK);
|
||||
else
|
||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK)|(trans << FF_TRANSSHIFT);
|
||||
mobj->drawflags = (mobj->drawflags & ~MFD_TRANSMASK)|(trans << MFD_TRANSSHIFT);
|
||||
}
|
||||
break;
|
||||
case MT_THUNDERSHIELD:
|
||||
|
|
@ -8601,7 +8659,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetMobjState(mobj, S_BUBBLESHIELDBLOWUP);
|
||||
|
||||
mobj->angle += ANGLE_22h;
|
||||
mobj->flags2 &= ~MF2_SHADOW;
|
||||
mobj->drawflags &= ~MFD_SHADOW;
|
||||
scale += (blow * (3*scale)) / bubbletime;
|
||||
|
||||
mobj->frame = (states[S_BUBBLESHIELDBLOWUP].frame + mobj->extravalue1);
|
||||
|
|
@ -8671,9 +8729,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
else
|
||||
{
|
||||
if (mobj->target->player->kartstuff[k_bubblecool] && ((curstate-S_BUBBLESHIELD1) & 1))
|
||||
mobj->flags2 |= MF2_SHADOW;
|
||||
mobj->drawflags |= MFD_SHADOW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_SHADOW;
|
||||
mobj->drawflags &= ~MFD_SHADOW;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8886,9 +8944,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20)
|
||||
P_SetMobjState(mobj, S_PLAYERBOMB1);
|
||||
if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1))
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -8903,9 +8961,9 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
P_SetMobjState(mobj, S_PLAYERFAKE1);
|
||||
|
||||
if (mobj->target->player->powers[pw_flashing] && (leveltime & 1))
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
// Update mobj antigravity status:
|
||||
|
|
@ -8935,10 +8993,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
cur->colorized = true;
|
||||
K_FlipFromObject(cur, mobj->target);
|
||||
|
||||
if (mobj->flags2 & MF2_DONTDRAW)
|
||||
cur->flags2 |= MF2_DONTDRAW;
|
||||
if (mobj->drawflags & MFD_DONTDRAW)
|
||||
cur->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
cur->flags2 &= ~MF2_DONTDRAW;
|
||||
cur->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
cur = cur->hnext;
|
||||
}
|
||||
|
|
@ -10296,7 +10354,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|
|||
|
||||
P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_EXPLODE); // poof into existance
|
||||
// Transfer flags2 (strongbox, objectflip)
|
||||
newmobj->flags2 = mobj->flags2 & ~MF2_DONTDRAW;
|
||||
newmobj->flags2 = mobj->flags2;
|
||||
if (mobj->threshold == 70)
|
||||
newmobj->threshold = 70;
|
||||
}
|
||||
|
|
@ -10348,7 +10406,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|
|||
return;
|
||||
}
|
||||
else if (((mobj->type == MT_RANDOMITEM && mobj->threshold == 69) || mobj->type == MT_EGGMANITEM || mobj->type == MT_FALLINGROCK) && mobj->fuse <= TICRATE)
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
}
|
||||
|
||||
I_Assert(mobj != NULL);
|
||||
|
|
@ -10578,13 +10636,13 @@ void P_SceneryThinker(mobj_t *mobj)
|
|||
&& mobj->extravalue1 > 0 && mobj->extravalue2 >= 2)
|
||||
{
|
||||
if (mobj->extravalue2 == 2) // I don't know why the normal logic doesn't work for this.
|
||||
mobj->flags2 ^= MF2_DONTDRAW;
|
||||
mobj->drawflags ^= MFD_DONTDRAW;
|
||||
else
|
||||
{
|
||||
if (mobj->fuse == mobj->extravalue2)
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
mobj->drawflags &= ~MFD_DONTDRAW;
|
||||
else
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
mobj->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10715,6 +10773,9 @@ static void P_DefaultMobjShadowScale(mobj_t *thing)
|
|||
case MT_FLOATINGITEM:
|
||||
thing->shadowscale = FRACUNIT/2;
|
||||
break;
|
||||
case MT_DRIFTCLIP:
|
||||
thing->shadowscale = FRACUNIT/3;
|
||||
break;
|
||||
default:
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||
thing->shadowscale = FRACUNIT;
|
||||
|
|
@ -11711,8 +11772,8 @@ void P_RespawnSpecials(void)
|
|||
ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT;
|
||||
if (mthing->options & MTF_AMBUSH
|
||||
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
|
||||
z -= 24*FRACUNIT;
|
||||
z -= mobjinfo[i].height; // Don't forget the height!
|
||||
z -= 24 * mapobjectscale;
|
||||
z -= FixedMul(mobjinfo[i].height, mapobjectscale); // Don't forget the height!
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -11723,7 +11784,7 @@ void P_RespawnSpecials(void)
|
|||
ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT;
|
||||
if (mthing->options & MTF_AMBUSH
|
||||
&& (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i)))
|
||||
z += 24*FRACUNIT;
|
||||
z += 24 * mapobjectscale;
|
||||
}
|
||||
|
||||
mo = P_SpawnMobj(x, y, z, i);
|
||||
|
|
@ -11852,6 +11913,8 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
p->awayviewmobj = NULL;
|
||||
p->awayviewtics = 0;
|
||||
|
||||
P_SetTarget(&p->follower, NULL); // cleanse follower from existence
|
||||
|
||||
// set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't.
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !p->bot)
|
||||
mobj->destscale = 6*mobj->destscale/8;
|
||||
|
|
@ -11865,7 +11928,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
{
|
||||
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + P_GetPlayerHeight(p)+16*FRACUNIT, MT_PLAYERARROW);
|
||||
P_SetTarget(&overheadarrow->target, mobj);
|
||||
overheadarrow->flags2 |= MF2_DONTDRAW;
|
||||
overheadarrow->drawflags |= MFD_DONTDRAW;
|
||||
P_SetScale(overheadarrow, mobj->destscale);
|
||||
|
||||
if (p->spectator && pcount > 1) // HEY! No being cheap...
|
||||
|
|
@ -11891,10 +11954,10 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
P_SetTarget(&mo->target, mobj);
|
||||
mo->angle = (diff * (i-1));
|
||||
mo->color = mobj->color;
|
||||
if (mobj->flags2 & MF2_DONTDRAW)
|
||||
mo->flags2 |= MF2_DONTDRAW;
|
||||
if (mobj->drawflags & MFD_DONTDRAW)
|
||||
mo->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
mo->flags2 &= ~MF2_DONTDRAW;
|
||||
mo->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
src/p_mobj.h
48
src/p_mobj.h
|
|
@ -108,7 +108,7 @@ typedef enum
|
|||
// Don't use the blocklinks (inert but displayable)
|
||||
MF_NOBLOCKMAP = 1<<4,
|
||||
// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
|
||||
MF_PAPERCOLLISION = 1<<5,
|
||||
MF_PAPERCOLLISION = 1<<5,
|
||||
// You can push this object. It can activate switches and things by pushing it on top.
|
||||
MF_PUSHABLE = 1<<6,
|
||||
// Object is a boss.
|
||||
|
|
@ -160,7 +160,7 @@ typedef enum
|
|||
MF_GRENADEBOUNCE = 1<<28,
|
||||
// Run the action thinker on spawn.
|
||||
MF_RUNSPAWNFUNC = 1<<29,
|
||||
// Don't remap in Encore mode.
|
||||
// Don't remap in Encore mode. (Not a drawflag so that it's settable by mobjinfo.)
|
||||
MF_DONTENCOREMAP = 1<<30,
|
||||
// free: 1<<31
|
||||
} mobjflag_t;
|
||||
|
|
@ -170,7 +170,7 @@ typedef enum
|
|||
MF2_AXIS = 1, // It's a NiGHTS axis! (For faster checking)
|
||||
MF2_TWOD = 1<<1, // Moves like it's in a 2D level
|
||||
MF2_DONTRESPAWN = 1<<2, // Don't respawn this object!
|
||||
MF2_DONTDRAW = 1<<3, // Don't generate a vissprite
|
||||
// free: 1<<3
|
||||
MF2_AUTOMATIC = 1<<4, // Thrown ring has automatic properties
|
||||
MF2_RAILRING = 1<<5, // Thrown ring has rail properties
|
||||
MF2_BOUNCERING = 1<<6, // Thrown ring has bounce properties
|
||||
|
|
@ -187,7 +187,7 @@ typedef enum
|
|||
MF2_JUSTATTACKED = 1<<17, // can be pushed by other moving mobjs
|
||||
MF2_FIRING = 1<<18, // turret fire
|
||||
MF2_SUPERFIRE = 1<<19, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
|
||||
MF2_SHADOW = 1<<20, // Fuzzy draw, makes targeting harder.
|
||||
// free: 1<<20
|
||||
MF2_STRONGBOX = 1<<21, // Flag used for "strong" random monitors.
|
||||
MF2_OBJECTFLIP = 1<<22, // Flag for objects that always have flipped gravity.
|
||||
MF2_SKULLFLY = 1<<23, // Special handling: skull in flight.
|
||||
|
|
@ -241,14 +241,43 @@ typedef enum
|
|||
MFE_SPRUNG = 1<<8,
|
||||
// Platform movement
|
||||
MFE_APPLYPMOMZ = 1<<9,
|
||||
// SRB2Kart: Splitscreen sprite display; very wasteful but I couldn't think of another way to do it...
|
||||
MFE_DRAWONLYFORP1 = 1<<10,
|
||||
MFE_DRAWONLYFORP2 = 1<<11,
|
||||
MFE_DRAWONLYFORP3 = 1<<12,
|
||||
MFE_DRAWONLYFORP4 = 1<<13,
|
||||
// free: to and including 1<<15
|
||||
} mobjeflag_t;
|
||||
|
||||
//
|
||||
// Mobj drawing flags
|
||||
// Set by hex, to make masking shenanigans easier to keep track of.
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
// Don't generate a vissprite for individual screens
|
||||
MFD_DONTDRAWP1 = 0x0001,
|
||||
MFD_DONTDRAWP2 = 0x0002,
|
||||
MFD_DONTDRAWP3 = 0x0004,
|
||||
MFD_DONTDRAWP4 = 0x0008,
|
||||
// Transparency override flags
|
||||
MFD_TRANS10 = 0x0010,
|
||||
MFD_TRANS20 = 0x0020,
|
||||
MFD_TRANS30 = 0x0030,
|
||||
MFD_TRANS40 = 0x0040,
|
||||
MFD_TRANS50 = 0x0050,
|
||||
MFD_TRANS60 = 0x0060,
|
||||
MFD_TRANS70 = 0x0070,
|
||||
MFD_TRANS80 = 0x0080,
|
||||
MFD_TRANS90 = 0x0090,
|
||||
MFD_TRANSMASK = 0x00F0,
|
||||
// Brightness override flags
|
||||
MFD_FULLBRIGHT = 0x0100,
|
||||
MFD_SEMIBRIGHT = 0x0200,
|
||||
MFD_NOBRIGHT = 0x0300,
|
||||
MFD_BRIGHTMASK = 0x0F00,
|
||||
// Shortcuts
|
||||
MFD_DONTDRAW = MFD_DONTDRAWP1|MFD_DONTDRAWP2|MFD_DONTDRAWP3|MFD_DONTDRAWP4,
|
||||
MFD_SHADOW = MFD_TRANS80|MFD_FULLBRIGHT,
|
||||
MFD_TRANSSHIFT = 4,
|
||||
// free: to and including 0x8000
|
||||
} mobjdflag_t;
|
||||
|
||||
//
|
||||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
|
|
@ -304,6 +333,7 @@ typedef struct mobj_s
|
|||
UINT32 flags; // flags from mobjinfo tables
|
||||
UINT32 flags2; // MF2_ flags
|
||||
UINT16 eflags; // extra flags
|
||||
UINT16 drawflags; // Rendering-related flags. These should not be used for game logic.
|
||||
|
||||
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
|
||||
// Player and mobj sprites in multiplayer modes are modified
|
||||
|
|
|
|||
|
|
@ -57,10 +57,11 @@ typedef enum
|
|||
{
|
||||
// RFLAGPOINT = 0x01,
|
||||
// BFLAGPOINT = 0x02,
|
||||
CAPSULE = 0x04,
|
||||
AWAYVIEW = 0x08,
|
||||
FIRSTAXIS = 0x10,
|
||||
SECONDAXIS = 0x20,
|
||||
CAPSULE = 4,
|
||||
AWAYVIEW = 8,
|
||||
FIRSTAXIS = 16,
|
||||
SECONDAXIS = 32,
|
||||
FOLLOWER = 64,
|
||||
} player_saveflags;
|
||||
|
||||
//
|
||||
|
|
@ -218,6 +219,9 @@ static void P_NetArchivePlayers(void)
|
|||
if (players[i].axis2)
|
||||
flags |= SECONDAXIS;
|
||||
|
||||
if (players[i].follower)
|
||||
flags |= FOLLOWER;
|
||||
|
||||
WRITEINT16(save_p, players[i].lastsidehit);
|
||||
WRITEINT16(save_p, players[i].lastlinehit);
|
||||
|
||||
|
|
@ -249,6 +253,14 @@ static void P_NetArchivePlayers(void)
|
|||
// SRB2kart
|
||||
WRITEUINT8(save_p, players[i].kartspeed);
|
||||
WRITEUINT8(save_p, players[i].kartweight);
|
||||
|
||||
WRITEUINT8(save_p, players[i].followerskin);
|
||||
WRITEUINT8(save_p, players[i].followerready); // booleans are really just numbers eh??
|
||||
WRITEUINT8(save_p, players[i].followercolor);
|
||||
if (flags & FOLLOWER)
|
||||
WRITEUINT32(save_p, players[i].follower->mobjnum);
|
||||
|
||||
|
||||
//
|
||||
|
||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
|
|
@ -435,6 +447,13 @@ static void P_NetUnArchivePlayers(void)
|
|||
// SRB2kart
|
||||
players[i].kartspeed = READUINT8(save_p);
|
||||
players[i].kartweight = READUINT8(save_p);
|
||||
|
||||
players[i].followerskin = READUINT8(save_p);
|
||||
players[i].followerready = READUINT8(save_p);
|
||||
players[i].followercolor = READUINT8(save_p);
|
||||
if (flags & FOLLOWER)
|
||||
players[i].follower = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
|
||||
//
|
||||
|
||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
|
|
@ -980,6 +999,7 @@ typedef enum
|
|||
MD2_SLOPE = 1<<13,
|
||||
#endif
|
||||
MD2_SHADOWSCALE = 1<<14,
|
||||
MD2_DRAWFLAGS = 1<<15,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -1178,6 +1198,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
#endif
|
||||
if (mobj->shadowscale)
|
||||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (mobj->drawflags)
|
||||
diff2 |= MD2_DRAWFLAGS;
|
||||
if (mobj->colorized)
|
||||
diff2 |= MD2_COLORIZED;
|
||||
if (mobj == waypointcap)
|
||||
|
|
@ -1309,6 +1331,17 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEUINT8(save_p, mobj->colorized);
|
||||
if (diff2 & MD2_SHADOWSCALE)
|
||||
WRITEFIXED(save_p, mobj->shadowscale);
|
||||
if (diff2 & MD2_DRAWFLAGS)
|
||||
{
|
||||
UINT16 df = mobj->drawflags;
|
||||
|
||||
if ((mobj->drawflags & MFD_DONTDRAW) != MFD_DONTDRAW)
|
||||
{
|
||||
df = (mobj->drawflags & ~MFD_DONTDRAW);
|
||||
}
|
||||
|
||||
WRITEUINT16(save_p, df);
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
|
@ -2238,6 +2271,8 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->colorized = READUINT8(save_p);
|
||||
if (diff2 & MD2_SHADOWSCALE)
|
||||
mobj->shadowscale = READFIXED(save_p);
|
||||
if (diff2 & MD2_DRAWFLAGS)
|
||||
mobj->drawflags = READUINT16(save_p);
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
@ -3130,6 +3165,7 @@ static void P_RelinkPointers(void)
|
|||
if (!(mobj->itnext = P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type);
|
||||
}
|
||||
|
||||
if (mobj->player)
|
||||
{
|
||||
if (mobj->player->capsule)
|
||||
|
|
@ -3160,6 +3196,13 @@ static void P_RelinkPointers(void)
|
|||
if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player->follower)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->follower;
|
||||
mobj->player->follower = NULL;
|
||||
if (!P_SetTarget(&mobj->player->follower, P_FindNewPosition(temp)))
|
||||
CONS_Debug(DBG_GAMELOGIC, "follower not found on %d\n", mobj->type);
|
||||
}
|
||||
if (mobj->player->nextwaypoint)
|
||||
{
|
||||
temp = (UINT32)(size_t)mobj->player->nextwaypoint;
|
||||
|
|
|
|||
|
|
@ -1159,11 +1159,9 @@ static inline void P_SpawnEmblems(void)
|
|||
emblemmobj->flags |= MF_NOCLIP;
|
||||
emblemmobj->flags &= ~MF_SPECIAL;
|
||||
emblemmobj->flags |= MF_NOBLOCKMAP;
|
||||
emblemmobj->frame |= (tr_trans50<<FF_TRANSSHIFT);
|
||||
emblemmobj->drawflags |= (tr_trans50 << MFD_TRANSSHIFT);
|
||||
P_SetThingPosition(emblemmobj);
|
||||
}
|
||||
else
|
||||
emblemmobj->frame &= ~FF_TRANSMASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2460,6 +2458,9 @@ static void P_LevelInitStuff(void)
|
|||
|
||||
// and this stupid flag as a result
|
||||
players[i].pflags &= ~PF_TRANSFERTOCLOSEST;
|
||||
|
||||
// Wipe follower from existence to avoid crashes
|
||||
players[i].follower = NULL;
|
||||
}
|
||||
|
||||
// SRB2Kart: map load variables
|
||||
|
|
|
|||
323
src/p_user.c
323
src/p_user.c
|
|
@ -45,6 +45,7 @@
|
|||
// SRB2kart
|
||||
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
|
||||
#include "k_kart.h"
|
||||
#include "k_color.h" // KartColor_Opposite
|
||||
#include "console.h" // CON_LogMessage
|
||||
#include "k_respawn.h"
|
||||
#include "k_bot.h"
|
||||
|
|
@ -653,7 +654,7 @@ static void P_DeNightserizePlayer(player_t *player)
|
|||
|
||||
player->mo->flags &= ~MF_NOGRAVITY;
|
||||
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->drawflags &= ~MFD_DONTDRAW;
|
||||
|
||||
// Restore aiming angle
|
||||
if (player == &players[consoleplayer])
|
||||
|
|
@ -728,7 +729,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
|
||||
player->mo->flags |= MF_NOGRAVITY;
|
||||
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
player->nightstime = player->startedtime = nighttime*TICRATE;
|
||||
player->bonustime = false;
|
||||
|
|
@ -1622,7 +1623,7 @@ void P_SpawnShieldOrb(player_t *player)
|
|||
if (shieldobj->info->painstate)
|
||||
P_SetMobjState(shieldobj,shieldobj->info->painstate);
|
||||
else
|
||||
shieldobj->flags2 |= MF2_SHADOW;
|
||||
shieldobj->drawflags |= MFD_SHADOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1658,8 +1659,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
ghost->sprite = mobj->sprite;
|
||||
ghost->frame = mobj->frame;
|
||||
ghost->tics = -1;
|
||||
ghost->frame &= ~FF_TRANSMASK;
|
||||
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
||||
ghost->drawflags |= tr_trans50 << MFD_TRANSSHIFT;
|
||||
ghost->fuse = ghost->info->damage;
|
||||
ghost->skin = mobj->skin;
|
||||
ghost->standingslope = mobj->standingslope;
|
||||
|
|
@ -3410,7 +3410,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // SRB2kart - unused.
|
|||
return;
|
||||
P_SetWeaponDelay(player, (3*TICRATE)/2);
|
||||
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW);
|
||||
mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING);
|
||||
|
||||
// Rail has no unique thrown object, therefore its sound plays here.
|
||||
S_StartSound(player->mo, sfx_rail1);
|
||||
|
|
@ -4313,7 +4313,7 @@ static void P_SpectatorMovement(player_t *player)
|
|||
if (mo)
|
||||
{
|
||||
mo->flags2 |= MF2_RAILRING;
|
||||
mo->flags2 |= MF2_DONTDRAW;
|
||||
mo->drawflags |= MFD_DONTDRAW;
|
||||
mo->flags |= MF_NOCLIPHEIGHT;
|
||||
mo->flags |= MF_NOCLIP;
|
||||
mo->flags &= ~MF_MISSILE;
|
||||
|
|
@ -5056,7 +5056,7 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
radius = player->mo->target->radius;
|
||||
|
||||
player->mo->flags |= MF_NOGRAVITY;
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
P_SetScale(player->mo->tracer, player->mo->scale);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
|
|
@ -7096,7 +7096,7 @@ static void P_DeathThink(player_t *player)
|
|||
if (player->mo)
|
||||
{
|
||||
player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP);
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -7454,7 +7454,7 @@ void P_DemoCameraMovement(camera_t *cam)
|
|||
|
||||
awayviewmobj_hack = P_SpawnMobj(cam->x, cam->y, cam->z, MT_THOK);
|
||||
awayviewmobj_hack->tics = 2;
|
||||
awayviewmobj_hack->flags2 |= MF2_DONTDRAW;
|
||||
awayviewmobj_hack->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
democam.soundmobj = awayviewmobj_hack;
|
||||
|
||||
|
|
@ -8395,6 +8395,287 @@ void P_DoTimeOver(player_t *player)
|
|||
exitcountdown = 5*TICRATE;
|
||||
}
|
||||
|
||||
/* set follower state with our weird hacks
|
||||
the reason we do this is to avoid followers ever using actions (majormods, yikes!)
|
||||
without having to touch p_mobj.c.
|
||||
so we give it 1more tic and change the state when tic == 1 instead of 0
|
||||
cool beans?
|
||||
cool beans.
|
||||
*/
|
||||
static void P_SetFollowerState(mobj_t *f, INT32 state)
|
||||
{
|
||||
|
||||
if (!f || P_MobjWasRemoved(f))
|
||||
return; // safety net
|
||||
|
||||
// No, do NOT set the follower to S_NULL. Set it to S_INVISIBLE.
|
||||
if (state == S_NULL)
|
||||
{
|
||||
state = S_INVISIBLE;
|
||||
f->threshold = 1; // Threshold = 1 means stop doing anything related to setting states, so that we don't get out of S_INVISIBLE
|
||||
}
|
||||
|
||||
// extravalue2 stores the last "first state" we used.
|
||||
// because states default to idlestates, if we use an animation that uses an "ongoing" state line, don't reset it!
|
||||
// this prevents it from looking very dumb
|
||||
if (state == f->extravalue2)
|
||||
return;
|
||||
|
||||
// we will save the state into extravalue2.
|
||||
f->extravalue2 = state;
|
||||
|
||||
P_SetMobjStateNF(f, state);
|
||||
if (f->state->tics > 0)
|
||||
f->tics++;
|
||||
}
|
||||
|
||||
//
|
||||
//P_HandleFollower
|
||||
//
|
||||
//Handle the follower's spawning and moving along with the player. Do note that some of the stuff like the removal if a player doesn't exist anymore is handled in MT_FOLLOWER's thinker.
|
||||
static void P_HandleFollower(player_t *player)
|
||||
{
|
||||
follower_t fl;
|
||||
angle_t an;
|
||||
fixed_t zoffs;
|
||||
fixed_t sx, sy, sz;
|
||||
UINT8 color;
|
||||
|
||||
fixed_t bubble; // bubble scale (0 if no bubble)
|
||||
mobj_t *bmobj; // temp bubble mobj
|
||||
|
||||
|
||||
if (!player->followerready)
|
||||
return; // we aren't ready to perform anything follower related yet.
|
||||
|
||||
// How about making sure our follower exists and is added before trying to spawn it n' all?
|
||||
if (player->followerskin > numfollowers-1 || player->followerskin < -1)
|
||||
{
|
||||
//CONS_Printf("Follower skin invlaid. Setting to -1.\n");
|
||||
player->followerskin = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// don't do anything if we can't have a follower to begin with. (It gets removed under those conditions)
|
||||
if (player->spectator)
|
||||
return;
|
||||
if (player->followerskin < 0)
|
||||
return;
|
||||
// Before we do anything, let's be sure of where we're supposed to be
|
||||
fl = followers[player->followerskin];
|
||||
|
||||
an = player->mo->angle + (fl.atangle)*ANG1; // it's aproximative but it really doesn't matter in the grand scheme of things...
|
||||
zoffs = (fl.zoffs)*FRACUNIT;
|
||||
bubble = fl.bubblescale; // 0 if no bubble to spawn.
|
||||
|
||||
// do you like angle maths? I certainly don't...
|
||||
sx = player->mo->x + FixedMul((player->mo->scale*fl.dist), FINECOSINE((an)>>ANGLETOFINESHIFT));
|
||||
sy = player->mo->y + FixedMul((player->mo->scale*fl.dist), FINESINE((an)>>ANGLETOFINESHIFT));
|
||||
|
||||
// for the z coordinate, don't be a doof like Steel and forget that MFE_VERTICALFLIP exists :P
|
||||
sz = player->mo->z + FixedMul(player->mo->scale, zoffs)*P_MobjFlip(player->mo);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
sz += fl.height*player->mo->scale;
|
||||
|
||||
// finally, add a cool floating effect to the z height.
|
||||
// not stolen from k_kart I swear!!
|
||||
{
|
||||
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
|
||||
fixed_t sine = fl.bobamp * FINESINE((((8*pi*(fl.bobspeed)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
sz += FixedMul(player->mo->scale, sine)*P_MobjFlip(player->mo);
|
||||
}
|
||||
|
||||
// Set follower colour
|
||||
|
||||
switch (player->followercolor)
|
||||
{
|
||||
case MAXSKINCOLORS: // "Match"
|
||||
color = player->skincolor;
|
||||
break;
|
||||
case MAXSKINCOLORS+1: // "Opposite"
|
||||
color = KartColor_Opposite[player->skincolor*2];
|
||||
break;
|
||||
default:
|
||||
|
||||
color = player->followercolor;
|
||||
if (!color || color > MAXSKINCOLORS+2) // Make sure this isn't garbage
|
||||
color = player->skincolor; // "Match" as fallback.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!player->follower) // follower doesn't exist / isn't valid
|
||||
{
|
||||
//CONS_Printf("Spawning follower...\n");
|
||||
// so let's spawn one!
|
||||
P_SetTarget(&player->follower, P_SpawnMobj(sx, sy, sz, MT_FOLLOWER));
|
||||
P_SetFollowerState(player->follower, fl.idlestate);
|
||||
P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear
|
||||
player->follower->angle = player->mo->angle;
|
||||
|
||||
// This is safe to only spawn it here, the follower is removed then respawned when switched.
|
||||
if (bubble)
|
||||
{
|
||||
bmobj = P_SpawnMobj(player->follower->x, player->follower->y, player->follower->z, MT_FOLLOWERBUBBLE_FRONT);
|
||||
P_SetTarget(&player->follower->hnext, bmobj);
|
||||
P_SetTarget(&bmobj->target, player->follower); // Used to know if we have to despawn at some point.
|
||||
|
||||
bmobj = P_SpawnMobj(player->follower->x, player->follower->y, player->follower->z, MT_FOLLOWERBUBBLE_BACK);
|
||||
P_SetTarget(&player->follower->hnext->hnext, bmobj); // this seems absolutely stupid, I know, but this will make updating the momentums/flags of these a bit easier.
|
||||
P_SetTarget(&bmobj->target, player->follower); // Ditto
|
||||
}
|
||||
|
||||
player->follower->extravalue1 = 0; // extravalue1 is used to know what "state set" to use.
|
||||
/*
|
||||
0 = idle
|
||||
1 = forwards
|
||||
2 = hurt
|
||||
3 = win
|
||||
4 = lose
|
||||
5 = hitconfirm (< this one uses ->movecount as timer to know when to end, and goes back to normal states afterwards, unless hurt)
|
||||
*/
|
||||
}
|
||||
else // follower exists, woo!
|
||||
{
|
||||
|
||||
// Safety net (2)
|
||||
|
||||
if (P_MobjWasRemoved(player->follower))
|
||||
{
|
||||
P_SetTarget(&player->follower, NULL); // Remove this and respawn one, don't crash the game if Lua decides to P_RemoveMobj this thing.
|
||||
return;
|
||||
}
|
||||
|
||||
// first of all, handle states following the same model as above:
|
||||
if (player->follower->tics == 1)
|
||||
P_SetFollowerState(player->follower, player->follower->state->nextstate);
|
||||
|
||||
// move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)!
|
||||
player->follower->momx = (sx - player->follower->x)/fl.horzlag;
|
||||
player->follower->momy = (sy - player->follower->y)/fl.horzlag;
|
||||
player->follower->momz = (sz - player->follower->z)/fl.vertlag;
|
||||
player->follower->angle = player->mo->angle;
|
||||
|
||||
if (player->mo->colorized)
|
||||
player->follower->color = player->mo->color;
|
||||
else
|
||||
player->follower->color = color;
|
||||
|
||||
player->follower->colorized = player->mo->colorized;
|
||||
|
||||
P_SetScale(player->follower, FixedMul(fl.scale, player->mo->scale));
|
||||
K_GenericExtraFlagsNoZAdjust(player->follower, player->mo); // Not K_MatchGenericExtraFlag because the Z adjust it has only works properly if master & mo have the same Z height.
|
||||
|
||||
// Match how the player is being drawn
|
||||
player->follower->drawflags = player->mo->drawflags;
|
||||
|
||||
// Make the follower invisible if we no contest'd rather than removing it. No one will notice the diff seriously.
|
||||
// Also make the follower invisible if we choose not to have it displayed because it isn't ours. (also quick hacky check for f12)
|
||||
if (player->pflags & PF_TIMEOVER || (!cv_showfollowers.value && (!P_IsDisplayPlayer(player) || displayplayers[0] != consoleplayer) ))
|
||||
player->follower->drawflags |= MFD_DONTDRAW;
|
||||
|
||||
if (player->speed && (player->follower->momx || player->follower->momy))
|
||||
player->follower->angle = R_PointToAngle2(0, 0, player->follower->momx, player->follower->momy);
|
||||
// if we're moving let's make the angle the direction we're moving towards. This is to avoid drifting / reverse looking awkward.
|
||||
// Make sure the follower itself is also moving however, otherwise we'll be facing angle 0
|
||||
|
||||
// Finally, if the follower has bubbles, move them, set their scale, etc....
|
||||
// This is what I meant earlier by it being easier, now we can just use this weird lil loop to get the job done!
|
||||
|
||||
bmobj = player->follower->hnext; // will be NULL if there's no bubble
|
||||
|
||||
while (bmobj && !P_MobjWasRemoved(bmobj))
|
||||
{
|
||||
// match follower's momentums and (e)flags(2).
|
||||
bmobj->momx = player->follower->momx;
|
||||
bmobj->momy = player->follower->momy;
|
||||
bmobj->momz = player->follower->momz;
|
||||
|
||||
P_SetScale(bmobj, FixedMul(bubble, player->mo->scale));
|
||||
K_GenericExtraFlagsNoZAdjust(bmobj, player->follower);
|
||||
bmobj->drawflags = player->mo->drawflags;
|
||||
|
||||
if (player->follower->threshold) // threshold means the follower was "despawned" with S_NULL (is actually just set to S_INVISIBLE)
|
||||
P_SetMobjState(bmobj, S_INVISIBLE); // sooooo... let's do the same!
|
||||
|
||||
bmobj = bmobj->hnext; // switch to other bubble layer or exit
|
||||
}
|
||||
|
||||
|
||||
if (player->follower->threshold)
|
||||
return; // Threshold means the follower was "despanwed" with S_NULL.
|
||||
|
||||
// However with how the code is factored, this is just a special case of S_INVISBLE to avoid having to add other player variables.
|
||||
|
||||
|
||||
// handle follower animations. Could probably be better...
|
||||
// hurt or dead
|
||||
if (player->kartstuff[k_spinouttimer] || player->mo->state == &states[S_KART_SPIN] || player->mo->health <= 0)
|
||||
{
|
||||
player->follower->movecount = 0; // cancel hit confirm.
|
||||
player->follower->angle = player->frameangle; // spin out
|
||||
if (player->follower->extravalue1 != 2)
|
||||
{
|
||||
player->follower->extravalue1 = 2;
|
||||
P_SetFollowerState(player->follower, fl.hurtstate);
|
||||
}
|
||||
if (player->mo->health <= 0) // if dead, follow the player's z momentum exactly so they both look like they die at the same speed.
|
||||
player->follower->momz = player->mo->momz;
|
||||
}
|
||||
else if (player->follower->movecount)
|
||||
{
|
||||
if (player->follower->extravalue1 != 5)
|
||||
{
|
||||
player->follower->extravalue1 = 5;
|
||||
P_SetFollowerState(player->follower, fl.hitconfirmstate);
|
||||
}
|
||||
player->follower->movecount--;
|
||||
}
|
||||
else if (player->speed > 10*player->mo->scale) // animation for moving fast enough
|
||||
{
|
||||
|
||||
if (player->follower->extravalue1 != 1)
|
||||
{
|
||||
player->follower->extravalue1 = 1;
|
||||
P_SetFollowerState(player->follower, fl.followstate);
|
||||
}
|
||||
}
|
||||
else // animations when nearly still. This includes winning and losing.
|
||||
{
|
||||
if (player->follower->extravalue1 != 0)
|
||||
{
|
||||
|
||||
if (player->exiting) // win/ loss animations
|
||||
{
|
||||
if (K_IsPlayerLosing(player)) // L
|
||||
{
|
||||
if (player->follower->extravalue1 != 4)
|
||||
{
|
||||
player->follower->extravalue1 = 4;
|
||||
P_SetFollowerState(player->follower, fl.losestate);
|
||||
}
|
||||
}
|
||||
else // W
|
||||
{
|
||||
if (player->follower->extravalue1 != 3)
|
||||
{
|
||||
player->follower->extravalue1 = 3;
|
||||
P_SetFollowerState(player->follower, fl.winstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // normal standstill
|
||||
{
|
||||
player->follower->extravalue1 = 0;
|
||||
P_SetFollowerState(player->follower, fl.idlestate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PlayerThink
|
||||
//
|
||||
|
|
@ -8449,6 +8730,9 @@ void P_PlayerThink(player_t *player)
|
|||
player->awayviewtics = 0; // reset to zero
|
||||
}
|
||||
|
||||
// Run followes here. We need them to run even when we're dead to follow through what we're doing.
|
||||
P_HandleFollower(player);
|
||||
|
||||
if (player->flashcount)
|
||||
player->flashcount--;
|
||||
|
||||
|
|
@ -8570,9 +8854,9 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
if (player->spectator)
|
||||
player->mo->flags2 |= MF2_SHADOW;
|
||||
player->mo->drawflags |= MFD_SHADOW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK);
|
||||
P_DeathThink(player);
|
||||
|
||||
return;
|
||||
|
|
@ -8719,8 +9003,7 @@ void P_PlayerThink(player_t *player)
|
|||
gmobj->fuse = 2;
|
||||
if (leveltime & 1)
|
||||
{
|
||||
gmobj->frame &= ~FF_TRANSMASK;
|
||||
gmobj->frame |= tr_trans70<<FF_TRANSSHIFT;
|
||||
gmobj->drawflags |= tr_trans70 << MFD_TRANSSHIFT;
|
||||
}
|
||||
|
||||
// Hide the mobj from our sights if we're the displayplayer and chasecam is off.
|
||||
|
|
@ -8730,7 +9013,7 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
if (player == &players[displayplayers[i]] && !camera[i].chase)
|
||||
{
|
||||
gmobj->flags2 |= MF2_DONTDRAW;
|
||||
gmobj->drawflags |= MFD_DONTDRAW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -8870,16 +9153,16 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player)
|
||||
&& (leveltime & 1))
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->drawflags &= ~MFD_DONTDRAW;
|
||||
}
|
||||
/*else if (player->mo->tracer)
|
||||
{
|
||||
if (player->powers[pw_flashing] & 1)
|
||||
player->mo->tracer->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->tracer->drawflags |= MFD_DONTDRAW;
|
||||
else
|
||||
player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->tracer->drawflags &= ~MFD_DONTDRAW;
|
||||
}*/
|
||||
|
||||
player->pflags &= ~PF_SLIDING;
|
||||
|
|
@ -9257,7 +9540,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
// spectator invisibility and nogravity.
|
||||
if ((netgame || multiplayer) && player->spectator)
|
||||
{
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
player->mo->drawflags |= MFD_DONTDRAW;
|
||||
player->mo->flags |= MF_NOGRAVITY;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ extern INT16 color8to16[256]; // remap color index to highcolor
|
|||
extern INT16 *hicolormaps; // remap high colors to high colors..
|
||||
|
||||
extern CV_PossibleValue_t Color_cons_t[];
|
||||
extern CV_PossibleValue_t Followercolor_cons_t[]; // follower colours table, not a duplicate because of the "Match" option.
|
||||
|
||||
// Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables
|
||||
void R_LoadTextures(void);
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ static UINT8** translationtablecache[TT_CACHE_SIZE] = {NULL};
|
|||
// SKINCOLOR DEFINITIONS HAVE BEEN MOVED TO K_KART.C
|
||||
|
||||
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
|
||||
CV_PossibleValue_t Followercolor_cons_t[MAXSKINCOLORS+3]; // +3 to account for "Match", "Opposite" & NULL
|
||||
|
||||
/** \brief The R_InitTranslationTables
|
||||
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NU
|
|||
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_drawdist = {"drawdist", "8192", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
|
@ -1498,7 +1498,6 @@ void R_RegisterEngineStuff(void)
|
|||
return;
|
||||
|
||||
//CV_RegisterVar(&cv_precipdensity);
|
||||
CV_RegisterVar(&cv_translucency);
|
||||
CV_RegisterVar(&cv_drawdist);
|
||||
//CV_RegisterVar(&cv_drawdist_nights);
|
||||
CV_RegisterVar(&cv_drawdist_precip);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ extern consvar_t cv_homremoval;
|
|||
extern consvar_t cv_chasecam, cv_chasecam2, cv_chasecam3, cv_chasecam4;
|
||||
extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4;
|
||||
extern consvar_t cv_shadow;
|
||||
extern consvar_t cv_translucency;
|
||||
extern consvar_t /*cv_precipdensity,*/ cv_drawdist, /*cv_drawdist_nights,*/ cv_drawdist_precip;
|
||||
extern consvar_t cv_fov;
|
||||
extern consvar_t cv_skybox;
|
||||
|
|
|
|||
10
src/r_segs.c
10
src/r_segs.c
|
|
@ -179,14 +179,8 @@ static void R_DrawWallSplats(void)
|
|||
colfunc = basecolfunc;
|
||||
break;
|
||||
case SPLATDRAWMODE_TRANS:
|
||||
if (!cv_translucency.value)
|
||||
colfunc = basecolfunc;
|
||||
else
|
||||
{
|
||||
dc_transmap = transtables + ((tr_trans50 - 1)<<FF_TRANSSHIFT);
|
||||
colfunc = fuzzcolfunc;
|
||||
}
|
||||
|
||||
dc_transmap = transtables + ((tr_trans50 - 1)<<FF_TRANSSHIFT);
|
||||
colfunc = fuzzcolfunc;
|
||||
break;
|
||||
case SPLATDRAWMODE_SHADE:
|
||||
colfunc = shadecolfunc;
|
||||
|
|
|
|||
198
src/r_things.c
198
src/r_things.c
|
|
@ -1132,13 +1132,6 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
|
||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||
|
||||
/*
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
;
|
||||
else if (thing->flags2 & MF2_SHADOW)
|
||||
;
|
||||
else
|
||||
*/
|
||||
if (!((newsprite->cut & SC_FULLBRIGHT)
|
||||
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
|
||||
{
|
||||
|
|
@ -1850,19 +1843,27 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->transmap = NULL;
|
||||
|
||||
// specific translucency
|
||||
if (!cv_translucency.value)
|
||||
; // no translucency
|
||||
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
|
||||
vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK
|
||||
if (thing->drawflags & MFD_TRANSMASK) // Object is forcing transparency to a specific value
|
||||
vis->transmap = transtables + ((((thing->drawflags & MFD_TRANSMASK) - MFD_TRANS10) >> MFD_TRANSSHIFT) << FF_TRANSSHIFT);
|
||||
else if (thing->frame & FF_TRANSMASK)
|
||||
vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000;
|
||||
vis->transmap = transtables + ((thing->frame & FF_TRANSMASK) - FF_TRANS10);
|
||||
|
||||
if (thing->frame & FF_FULLBRIGHT || thing->flags2 & MF2_SHADOW)
|
||||
vis->cut |= SC_FULLBRIGHT;
|
||||
else if (thing->frame & FF_SEMIBRIGHT)
|
||||
vis->cut |= SC_SEMIBRIGHT;
|
||||
if (thing->drawflags & MFD_BRIGHTMASK)
|
||||
{
|
||||
if (thing->drawflags & MFD_FULLBRIGHT)
|
||||
vis->cut |= SC_FULLBRIGHT;
|
||||
else if (thing->drawflags & MFD_SEMIBRIGHT)
|
||||
vis->cut |= SC_SEMIBRIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thing->frame & FF_FULLBRIGHT)
|
||||
vis->cut |= SC_FULLBRIGHT;
|
||||
else if (thing->frame & FF_SEMIBRIGHT)
|
||||
vis->cut |= SC_SEMIBRIGHT;
|
||||
}
|
||||
|
||||
if (vis->cut & SC_FULLBRIGHT
|
||||
if ((vis->cut & SC_FULLBRIGHT)
|
||||
&& (!vis->extra_colormap || !(vis->extra_colormap->fog & 1)))
|
||||
{
|
||||
// full bright: goggles
|
||||
|
|
@ -2054,8 +2055,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->patch = sprframe->lumppat[0];
|
||||
|
||||
// specific translucency
|
||||
// (no draw flags)
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables;
|
||||
vis->transmap = ((thing->frame & FF_TRANSMASK) - FF_TRANS10) + transtables;
|
||||
else
|
||||
vis->transmap = NULL;
|
||||
|
||||
|
|
@ -2078,9 +2080,6 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
INT32 lightnum;
|
||||
fixed_t approx_dist, limit_dist;
|
||||
|
||||
INT32 splitflags; // check if a mobj has spliscreen flags
|
||||
boolean split_drawsprite; // used for splitscreen flags
|
||||
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
||||
|
|
@ -2114,35 +2113,13 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
split_drawsprite = false;
|
||||
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
if (thing->sprite == SPR_NULL)
|
||||
continue;
|
||||
|
||||
splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
|
||||
if (r_splitscreen && splitflags)
|
||||
{
|
||||
if (thing->eflags & MFE_DRAWONLYFORP1)
|
||||
if (viewssnum == 0)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP2)
|
||||
if (viewssnum == 1)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
|
||||
if (viewssnum == 2)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
|
||||
if (viewssnum == 3)
|
||||
split_drawsprite = true;
|
||||
}
|
||||
else
|
||||
split_drawsprite = true;
|
||||
|
||||
if (!split_drawsprite)
|
||||
if ((viewssnum == 0 && (thing->drawflags & MFD_DONTDRAWP1))
|
||||
|| (viewssnum == 1 && (thing->drawflags & MFD_DONTDRAWP2))
|
||||
|| (viewssnum == 2 && (thing->drawflags & MFD_DONTDRAWP3))
|
||||
|| (viewssnum == 3 && (thing->drawflags & MFD_DONTDRAWP4)))
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
|
@ -2158,36 +2135,13 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
// Draw everything in sector, no checks
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
|
||||
split_drawsprite = false;
|
||||
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
if (thing->sprite == SPR_NULL)
|
||||
continue;
|
||||
|
||||
splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||
|
||||
if (r_splitscreen && splitflags)
|
||||
{
|
||||
if (thing->eflags & MFE_DRAWONLYFORP1)
|
||||
if (viewssnum == 0)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP2)
|
||||
if (viewssnum == 1)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
|
||||
if (viewssnum == 2)
|
||||
split_drawsprite = true;
|
||||
|
||||
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
|
||||
if (viewssnum == 3)
|
||||
split_drawsprite = true;
|
||||
}
|
||||
else
|
||||
split_drawsprite = true;
|
||||
|
||||
if (!split_drawsprite)
|
||||
if ((viewssnum == 0 && (thing->drawflags & MFD_DONTDRAWP1))
|
||||
|| (viewssnum == 1 && (thing->drawflags & MFD_DONTDRAWP2))
|
||||
|| (viewssnum == 2 && (thing->drawflags & MFD_DONTDRAWP3))
|
||||
|| (viewssnum == 3 && (thing->drawflags & MFD_DONTDRAWP4)))
|
||||
continue;
|
||||
|
||||
R_ProjectSprite(thing);
|
||||
|
|
@ -2891,7 +2845,12 @@ void R_DrawMasked(void)
|
|||
//
|
||||
// ==========================================================================
|
||||
|
||||
// We can assume those are tied to skins somewhat, hence why they're defined here.
|
||||
INT32 numskins = 0;
|
||||
follower_t followers[MAXSKINS];
|
||||
// default followers are defined in SOC_FLWR in followers.kart / gfx.kart (depending on what exe this is, at this point)
|
||||
|
||||
|
||||
skin_t skins[MAXSKINS];
|
||||
// FIXTHIS: don't work because it must be inistilised before the config load
|
||||
//#define SKINVALUES
|
||||
|
|
@ -2954,6 +2913,19 @@ INT32 R_SkinAvailable(const char *name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// same thing 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;
|
||||
}
|
||||
|
||||
// network code calls this when a 'skin change' is received
|
||||
boolean SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||
{
|
||||
|
|
@ -2979,13 +2951,37 @@ boolean SetPlayerSkin(INT32 playernum, const char *skinname)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Again, same thing 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;
|
||||
}
|
||||
|
||||
// Same as SetPlayerSkin, but uses the skin #.
|
||||
// network code calls this when a 'skin change' is received
|
||||
void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
player_t *player = &players[playernum];
|
||||
skin_t *skin = &skins[skinnum];
|
||||
|
||||
if (skinnum >= 0 && skinnum < numskins) // Make sure it exists!
|
||||
{
|
||||
player->skin = skinnum;
|
||||
|
|
@ -3016,6 +3012,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
if (player->mo)
|
||||
P_SetScale(player->mo, player->mo->scale);
|
||||
|
||||
// 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;
|
||||
|
|
@ -3028,6 +3025,53 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
}
|
||||
|
||||
// you get the drill, now we do the same 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;
|
||||
//CONS_Printf("Updated player follower num\n");
|
||||
|
||||
// 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.
|
||||
}
|
||||
|
||||
//
|
||||
// Add skins from a pwad, each skin preceded by 'S_SKIN' marker
|
||||
//
|
||||
|
|
|
|||
|
|
@ -103,6 +103,45 @@ typedef struct
|
|||
} skin_t;
|
||||
|
||||
extern CV_PossibleValue_t Forceskin_cons_t[];
|
||||
//
|
||||
// for 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;
|
||||
|
||||
// -----------
|
||||
// NOT SKINS STUFF !
|
||||
|
|
@ -161,7 +200,7 @@ typedef struct vissprite_s
|
|||
lighttable_t *colormap; // for color translation and shadow draw
|
||||
// maxbright frames as well
|
||||
|
||||
UINT8 *transmap; // for MF2_SHADOW sprites, which translucency table to use
|
||||
UINT8 *transmap; // which translucency table to use
|
||||
|
||||
INT32 mobjflags;
|
||||
|
||||
|
|
@ -199,12 +238,18 @@ typedef struct drawnode_s
|
|||
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
extern INT32 numfollowers;
|
||||
extern follower_t followers[MAXSKINS]; // again, use the same rules as skins, no reason not to.
|
||||
|
||||
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);
|
||||
|
||||
INT32 R_FollowerAvailable(const char *name);
|
||||
boolean SetPlayerFollower(INT32 playernum,const char *skinname);
|
||||
void SetFollower(INT32 playernum,INT32 skinnum);
|
||||
|
||||
#ifdef DELFILE
|
||||
void R_DelSkins(UINT16 wadnum);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -820,6 +820,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
|||
{"sploss", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Down to yellow sparks
|
||||
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // :shitsfree:
|
||||
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Debug notification
|
||||
{"cock", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Hammer cocks, bang bang
|
||||
|
||||
// SRB2Kart - Engine sounds
|
||||
// Engine class A
|
||||
|
|
|
|||
|
|
@ -897,6 +897,7 @@ typedef enum
|
|||
sfx_sploss,
|
||||
sfx_itfree,
|
||||
sfx_dbgsal,
|
||||
sfx_cock,
|
||||
|
||||
// Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy...
|
||||
// Engine class A - Low Speed, Low Weight
|
||||
|
|
|
|||
|
|
@ -1879,6 +1879,7 @@ void V_DrawStringScaled(
|
|||
|
||||
chw <<= FRACBITS;
|
||||
spacew <<= FRACBITS;
|
||||
lfh <<= FRACBITS;
|
||||
|
||||
#define Mul( id, scale ) ( id = FixedMul (scale, id) )
|
||||
Mul (chw, scale);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue