Merge remote-tracking branch 'origin/master' into newmenus

This commit is contained in:
Jaime Passos 2019-08-20 19:07:34 -03:00
commit 403eafb003
20 changed files with 551 additions and 542 deletions

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
VERSION 2.1.24
VERSION 2.1.25
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View file

@ -1,4 +1,4 @@
version: 2.1.24.{branch}-{build}
version: 2.1.25.{branch}-{build}
os: MinGW
environment:

View file

@ -24,12 +24,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define APNG_H
#ifndef _MSC_VER
#ifndef _WII
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#endif
#endif
#ifndef _LFS64_LARGEFILE
#define _LFS64_LARGEFILE

View file

@ -1666,7 +1666,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (joyaxis_default)
{
#if !defined (_WII) && !defined (WMINPUT)
if (!stricmp(v->name, "joyaxis_turn"))
{
if (joyaxis_count > 6) return false;
@ -1676,7 +1675,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "X-Axis")) joyaxis_count++;
else joyaxis_default = false;
}
#if !defined (PSP)
if (!stricmp(v->name, "joyaxis_move"))
{
if (joyaxis_count > 6) return false;
@ -1685,8 +1683,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "Y-Axis")) joyaxis_count++;
else joyaxis_default = false;
}
#endif
#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (PSP)
if (!stricmp(v->name, "joyaxis_side"))
{
if (joyaxis_count > 6) return false;
@ -1695,8 +1691,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "Z-Axis")) joyaxis_count++;
else joyaxis_default = false;
}
#endif
#if !defined (_XBOX) && !defined (PSP)
if (!stricmp(v->name, "joyaxis_look"))
{
if (joyaxis_count > 6) return false;
@ -1705,7 +1699,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "None")) joyaxis_count++;
else joyaxis_default = false;
}
#endif
if (!stricmp(v->name, "joyaxis_fire")
|| !stricmp(v->name, "joyaxis_firenormal"))
{
@ -1715,7 +1708,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "None")) joyaxis_count++;
else joyaxis_default = false;
}
#endif
// reset all axis settings to defaults
if (joyaxis_count == 6)
{
@ -1732,7 +1724,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (joyaxis2_default)
{
#if !defined (_WII) && !defined (WMINPUT)
if (!stricmp(v->name, "joyaxis2_turn"))
{
if (joyaxis2_count > 6) return false;
@ -1742,7 +1733,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "X-Axis")) joyaxis2_count++;
else joyaxis2_default = false;
}
// #if !defined (PSP)
if (!stricmp(v->name, "joyaxis2_move"))
{
if (joyaxis2_count > 6) return false;
@ -1751,8 +1741,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "Y-Axis")) joyaxis2_count++;
else joyaxis2_default = false;
}
// #endif
#if !defined (_arch_dreamcast) && !defined (_XBOX) && !defined (PSP)
if (!stricmp(v->name, "joyaxis2_side"))
{
if (joyaxis2_count > 6) return false;
@ -1761,8 +1749,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "Z-Axis")) joyaxis2_count++;
else joyaxis2_default = false;
}
#endif
#if !defined (_XBOX) // && !defined (PSP)
if (!stricmp(v->name, "joyaxis2_look"))
{
if (joyaxis2_count > 6) return false;
@ -1771,7 +1757,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "None")) joyaxis2_count++;
else joyaxis2_default = false;
}
#endif
if (!stricmp(v->name, "joyaxis2_fire")
|| !stricmp(v->name, "joyaxis2_firenormal"))
{
@ -1781,7 +1766,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
if (!stricmp(valstr, "None")) joyaxis2_count++;
else joyaxis2_default = false;
}
#endif
// reset all axis settings to defaults
if (joyaxis2_count == 6)

View file

@ -42,6 +42,7 @@
#include "lzf.h"
#include "lua_script.h"
#include "lua_hook.h"
#include "md5.h"
#ifdef CLIENT_LOADINGSCREEN
// cl loading screen
@ -110,6 +111,9 @@ static UINT8 resynch_local_inprogress = false; // WE are desynched and getting p
static UINT8 player_joining = false;
UINT8 hu_resynching = 0;
UINT8 adminpassmd5[16];
boolean adminpasswordset = false;
// Client specific
static ticcmd_t localcmds;
static ticcmd_t localcmds2;
@ -3784,6 +3788,7 @@ static void HandlePacketFromPlayer(SINT8 node)
INT32 netconsole;
tic_t realend, realstart;
UINT8 *pak, *txtpak, numtxtpak;
UINT8 finalmd5[16];/* Well, it's the cool thing to do? */
txtpak = NULL;
@ -3981,6 +3986,32 @@ static void HandlePacketFromPlayer(SINT8 node)
textcmd[0] += (UINT8)netbuffer->u.textcmd[0];
}
break;
case PT_LOGIN:
if (client)
break;
#ifndef NOMD5
if (doomcom->datalength < 16)/* ignore partial sends */
break;
if (!adminpasswordset)
{
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]);
break;
}
// Do the final pass to compare with the sent md5
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5);
if (!memcmp(netbuffer->u.md5sum, finalmd5, 16))
{
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]);
COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately
}
else
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]);
#endif
break;
case PT_NODETIMEOUT:
case PT_CLIENTQUIT:
if (client)
@ -4858,3 +4889,29 @@ tic_t GetLag(INT32 node)
{
return gametic - nettics[node];
}
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest)
{
#ifdef NOMD5
(void)buffer;
(void)len;
(void)salt;
memset(dest, 0, 16);
#else
char tmpbuf[256];
const size_t sl = strlen(salt);
if (len > 256-sl)
len = 256-sl;
memcpy(tmpbuf, buffer, len);
memmove(&tmpbuf[len], salt, sl);
//strcpy(&tmpbuf[len], salt);
len += strlen(salt);
if (len < 256)
memset(&tmpbuf[len],0,256-len);
// Yes, we intentionally md5 the ENTIRE buffer regardless of size...
md5_buffer(tmpbuf, 256, dest);
#endif
}

View file

@ -70,6 +70,9 @@ typedef enum
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
PT_RESYNCHING, // Packet sent to resync players.
// Blocks game advance until synched.
PT_LOGIN, // Login attempt from the client.
#ifdef NEWPING
PT_PING, // Packet sent to tell clients the other client's latency to server.
#endif
@ -407,6 +410,7 @@ typedef struct
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes
clientconfig_pak clientcfg; // 136 bytes
UINT8 md5sum[16];
serverinfo_pak serverinfo; // 1024 bytes
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes
@ -535,5 +539,10 @@ void D_ResetTiccmds(void);
tic_t GetLag(INT32 node);
UINT8 GetFreeXCmdSize(void);
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
extern UINT8 hu_resynching;
extern UINT8 adminpassmd5[16];
extern boolean adminpasswordset;
#endif

View file

@ -34,18 +34,19 @@
#include "p_spec.h"
#include "m_cheat.h"
#include "d_clisrv.h"
#include "d_net.h"
#include "v_video.h"
#include "d_main.h"
#include "m_random.h"
#include "f_finale.h"
#include "filesrch.h"
#include "mserv.h"
#include "md5.h"
#include "z_zone.h"
#include "lua_script.h"
#include "lua_hook.h"
#include "m_cond.h"
#include "m_anigif.h"
#include "md5.h"
#ifdef NETGAME_DEVMODE
#define CV_RESTRICT CV_NETVAR
@ -140,7 +141,6 @@ static void Command_Clearscores_f(void);
// Remote Administration
static void Command_Changepassword_f(void);
static void Command_Login_f(void);
static void Got_Login(UINT8 **cp, INT32 playernum);
static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void);
@ -435,7 +435,6 @@ void D_RegisterServerCommands(void)
// Remote Administration
COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
COM_AddCommand("promote", Command_Verify_f);
RegisterNetXCmd(XD_VERIFIED, Got_Verification);
@ -599,6 +598,11 @@ void D_RegisterClientCommands(void)
Color_cons_t[MAXSKINCOLORS].value = 0;
Color_cons_t[MAXSKINCOLORS].strvalue = NULL;
// Set default player names
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
for (i = 0; i < MAXPLAYERS; i++)
sprintf(player_names[i], "Player %d", i);
if (dedicated)
return;
@ -2719,35 +2723,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
// Attempts to make password system a little sane without
// rewriting the entire goddamn XD_file system
//
#include "md5.h"
static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest)
{
#ifdef NOMD5
(void)buffer;
(void)len;
(void)salt;
memset(dest, 0, 16);
#else
char tmpbuf[256];
const size_t sl = strlen(salt);
if (len > 256-sl)
len = 256-sl;
memcpy(tmpbuf, buffer, len);
memmove(&tmpbuf[len], salt, sl);
//strcpy(&tmpbuf[len], salt);
len += strlen(salt);
if (len < 256)
memset(&tmpbuf[len],0,256-len);
// Yes, we intentionally md5 the ENTIRE buffer regardless of size...
md5_buffer(tmpbuf, 256, dest);
#endif
}
#define BASESALT "basepasswordstorage"
static UINT8 adminpassmd5[16];
static boolean adminpasswordset = false;
void D_SetPassword(const char *pw)
{
@ -2785,7 +2761,6 @@ static void Command_Login_f(void)
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
UINT8 finalmd5[16];
const char *pw;
if (!netgame)
@ -2805,47 +2780,15 @@ static void Command_Login_f(void)
pw = COM_Argv(1);
// Do the base pass to get what the server has (or should?)
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &netbuffer->u.md5sum);
// Do the final pass to get the comparison the server will come up with
D_MD5PasswordPass(finalmd5, 16, va("PNUM%02d", consoleplayer), &finalmd5);
D_MD5PasswordPass(netbuffer->u.md5sum, 16, va("PNUM%02d", consoleplayer), &netbuffer->u.md5sum);
CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n"));
SendNetXCmd(XD_LOGIN, finalmd5, 16);
#endif
}
static void Got_Login(UINT8 **cp, INT32 playernum)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
(void)cp;
(void)playernum;
#else
UINT8 sentmd5[16], finalmd5[16];
READMEM(*cp, sentmd5, 16);
if (client)
return;
if (!adminpasswordset)
{
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[playernum]);
return;
}
// Do the final pass to compare with the sent md5
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5);
if (!memcmp(sentmd5, finalmd5, 16))
{
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
}
else
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[playernum]);
netbuffer->packettype = PT_LOGIN;
HSendPacket(servernode, true, 0, 16);
#endif
}

View file

@ -129,8 +129,8 @@ typedef enum
XD_ADDPLAYER, // 10
XD_TEAMCHANGE, // 11
XD_CLEARSCORES, // 12
XD_LOGIN, // 13
XD_VERIFIED, // 14
// UNUSED 13 (Because I don't want to change these comments)
XD_VERIFIED = 14,//14
XD_RANDOMSEED, // 15
XD_RUNSOC, // 16
XD_REQADDFILE, // 17

View file

@ -210,7 +210,7 @@ typedef struct
extern const UINT8 Color_Index[MAXTRANSLATIONS-1][16];
extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS];
extern const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2];
extern const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2];
#define NUMMAPS 1035

View file

@ -206,7 +206,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 28
#define MODVERSION 30
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond

View file

@ -416,49 +416,13 @@ consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 32
#error "please update player_name table using the new value for MAXPLAYERS"
#endif
#ifdef SEENAMES
player_t *seenplayer; // player we're aiming at right now
#endif
char player_names[MAXPLAYERS][MAXPLAYERNAME+1] =
{
"Player 1",
"Player 2",
"Player 3",
"Player 4",
"Player 5",
"Player 6",
"Player 7",
"Player 8",
"Player 9",
"Player 10",
"Player 11",
"Player 12",
"Player 13",
"Player 14",
"Player 15",
"Player 16",
"Player 17",
"Player 18",
"Player 19",
"Player 20",
"Player 21",
"Player 22",
"Player 23",
"Player 24",
"Player 25",
"Player 26",
"Player 27",
"Player 28",
"Player 29",
"Player 30",
"Player 31",
"Player 32"
};
// now automatically allocated in D_RegisterClientCommands
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
INT16 rw_maximums[NUM_WEAPONS] =
{

View file

@ -173,15 +173,15 @@ static int lib_all7emeralds(lua_State *L)
return 1;
}
// Whee, special Lua-exclusive function for making use of Color_Opposite[] without needing *2 or +1
// Returns both color and frame numbers!
// Whee, special Lua-exclusive function for making use of Color_Opposite[]
// Returns both color and signpost shade numbers!
static int lib_coloropposite(lua_State *L)
{
UINT8 colornum = (UINT8)luaL_checkinteger(L, 1);
if (colornum >= MAXSKINCOLORS)
return luaL_error(L, "skincolor %d out of range (0 - %d).", colornum, MAXSKINCOLORS-1);
lua_pushinteger(L, Color_Opposite[colornum*2]); // push color
lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame
if (!colornum || colornum >= MAXSKINCOLORS)
return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, MAXSKINCOLORS-1);
lua_pushinteger(L, Color_Opposite[colornum-1][0]); // push color
lua_pushinteger(L, Color_Opposite[colornum-1][1]); // push sign shade index, 0-15
return 2;
}

View file

@ -7247,8 +7247,8 @@ static void M_DrawLoadGameData(void)
col = 134;
else
{
col = (charskin->prefcolor - 1)*2;
col = Color_Index[Color_Opposite[col]-1][Color_Opposite[col+1]];
col = charskin->prefcolor - 1;
col = Color_Index[Color_Opposite[col][0]-1][Color_Opposite[col][1]];
}
V_DrawFill(x+6, y+64, 72, 50, col);

View file

@ -4898,12 +4898,12 @@ void A_SignPlayer(mobj_t *actor)
of in the name. If you have a better idea, feel free
to let me know. ~toast 2016/07/20
*/
actor->frame += (15 - Color_Opposite[(Color_Opposite[(skin->prefoppositecolor - 1)*2] - 1)*2 + 1]);
actor->frame += (15 - Color_Opposite[Color_Opposite[skin->prefoppositecolor - 1][0] - 1][1]);
}
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
{
actor->color = Color_Opposite[(actor->target->player->skincolor - 1)*2];
actor->frame += (15 - Color_Opposite[(actor->target->player->skincolor - 1)*2 + 1]);
actor->color = Color_Opposite[actor->target->player->skincolor - 1][0];
actor->frame += (15 - Color_Opposite[actor->target->player->skincolor - 1][1]);
}
if (skin->sprites[SPR2_SIGN].numframes)

View file

@ -2884,7 +2884,7 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (thing->z != oldz)
{
if (thing->player)
P_PlayerHitFloor(thing->player, false);
P_PlayerHitFloor(thing->player, !onfloor);
}
// debug: be sure it falls to the floor
@ -4136,7 +4136,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
{
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
if (!P_MobjTouchingPolyobj(po, mo))
if (!P_MobjInsidePolyobj(po, mo))
continue;
if (!PIT_ChangeSector(mo, false))
@ -4246,7 +4246,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
{
// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
if (!P_MobjTouchingPolyobj(po, mo))
if (!P_MobjInsidePolyobj(po, mo))
continue;
PIT_ChangeSector(mo, true);

View file

@ -716,9 +716,11 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
vector3_t mom; // Ditto.
if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
//thing->momz = -P_MobjFlip(thing);
if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
{
thing->standingslope = slope;
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
thing->momz = -P_MobjFlip(thing);
}
return;
}
@ -732,9 +734,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
thing->momx = mom.x;
thing->momy = mom.y;
//thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope;
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
thing->momz = -P_MobjFlip(thing);
}
}

View file

@ -3096,7 +3096,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
case 432: // Enable 2D Mode (Disable if noclimb)
if (mo->player)
if (mo && mo->player)
{
if (line->flags & ML_NOCLIMB)
mo->flags2 &= ~MF2_TWOD;
@ -3122,7 +3122,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
case 434: // Custom Power
if (mo->player)
if (mo && mo->player)
{
mobj_t *dummy = P_SpawnMobj(mo->x, mo->y, mo->z, MT_NULL);
@ -3205,7 +3205,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break;
case 437: // Disable Player Controls
if (mo->player)
if (mo && mo->player)
{
UINT16 fractime = (UINT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS);
if (fractime < 1)

View file

@ -2198,7 +2198,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
{
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
player->pflags |= PF_SPINNING;
else
else if (!(player->pflags & PF_STARTDASH))
player->pflags &= ~PF_SPINNING;
}
@ -2217,7 +2217,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
player->skidtime = TICRATE;
player->mo->tics = -1;
}
else
else if (!player->skidtime)
player->pflags &= ~PF_GLIDING;
}
else if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
@ -2268,7 +2268,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
}
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
;
else if (player->pflags & PF_JUMPED || player->powers[pw_tailsfly] || player->mo->state-states == S_PLAY_FLY_TIRED)
else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH)
{
if (player->cmomx || player->cmomy)
{
@ -10134,6 +10134,7 @@ void P_DoPityCheck(player_t *player)
}
}
static sector_t *P_GetMinecartSector(fixed_t x, fixed_t y, fixed_t z, fixed_t *nz)
{
sector_t *sec = R_PointInSubsector(x, y)->sector;
@ -10546,6 +10547,191 @@ static void P_MinecartThink(player_t *player)
player->powers[pw_flashing]--;
}
// Handle Tails' fluff
static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
{
// init...
boolean smilesonground = P_IsObjectOnGround(player->mo);
angle_t horizangle = player->drawangle;
fixed_t zoffs = 0;
fixed_t backwards = -1*FRACUNIT;
boolean doroll = (player->panim == PA_ROLL || player->panim == PA_JUMP);
angle_t rollangle;
boolean panimchange;
INT32 ticnum = 0;
statenum_t chosenstate;
if (!tails->skin)
{
tails->skin = player->mo->skin;
P_SetMobjState(tails, S_TAILSOVERLAY_STAND);
tails->movecount = -1;
}
panimchange = (tails->movecount != (INT32)player->panim);
// initial position...
if (doroll)
{
fixed_t testval, zdist;
if (player->speed < FRACUNIT)
testval = FRACUNIT;
else
{
testval = (FixedMul(player->speed, FINECOSINE((horizangle - R_PointToAngle2(0, 0, player->rmomx, player->rmomy)) >> ANGLETOFINESHIFT)));
if (testval < FRACUNIT)
testval = FRACUNIT;
}
if (smilesonground && !player->mo->reactiontime)
zdist = (player->mo->z - tails->threshold);
else
zdist = player->mo->momz;
rollangle = R_PointToAngle2(0, 0, testval, -P_MobjFlip(player->mo)*zdist);
zoffs = 3*FRACUNIT + 12*FINESINE(rollangle >> ANGLETOFINESHIFT);
backwards = -12*FINECOSINE(rollangle >> ANGLETOFINESHIFT);
}
else if (player->panim == PA_RUN)
backwards = -5*FRACUNIT;
else if (player->panim == PA_SPRING)
{
zoffs += 4*FRACUNIT;
backwards /= 2;
}
else if (player->panim == PA_PAIN)
backwards /= 16;
else if (player->mo->state-states == S_PLAY_GASP)
{
backwards /= 16;
zoffs += 12*FRACUNIT;
}
else if (player->mo->state-states == S_PLAY_EDGE)
{
backwards /= 16;
zoffs = 3*FRACUNIT;
}
else if (player->panim == PA_ABILITY2)
{
zoffs = -7*FRACUNIT;
backwards = -9*FRACUNIT;
}
else if (player->mo->sprite2 == SPR2_FLY || player->mo->sprite2 == SPR2_TIRE)
backwards = -5*FRACUNIT;
// sprite...
if (doroll)
{
statenum_t add = ((rollangle > ANGLE_180) ? 2 : 0);
if (add)
rollangle = InvAngle(rollangle);
rollangle += ANG15; // modify the thresholds to be nice clean numbers
if (rollangle > ANG60)
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES + add;
else if (rollangle > ANG30)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES + add;
else
chosenstate = S_TAILSOVERLAY_0DEGREES;
}
else if (player->panim == PA_SPRING)
chosenstate = S_TAILSOVERLAY_MINUS60DEGREES;
else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES;
else if (player->panim == PA_PAIN)
chosenstate = S_TAILSOVERLAY_PAIN;
else if (player->mo->state-states == S_PLAY_GASP)
chosenstate = S_TAILSOVERLAY_GASP;
else if (player->mo->state-states == S_PLAY_EDGE)
chosenstate = S_TAILSOVERLAY_EDGE;
else if (player->panim == PA_RUN)
chosenstate = S_TAILSOVERLAY_RUN;
else if (player->panim == PA_WALK)
{
if (!smilesonground || player->mo->state-states == S_PLAY_SKID)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale))
chosenstate = S_TAILSOVERLAY_0DEGREES;
else
chosenstate = S_TAILSOVERLAY_MINUS30DEGREES;
}
else if (player->mo->sprite2 == SPR2_FLY)
chosenstate = S_TAILSOVERLAY_FLY;
else if (player->mo->sprite2 == SPR2_TIRE)
chosenstate = S_TAILSOVERLAY_TIRE;
else if (player->panim == PA_ABILITY2)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->panim == PA_IDLE)
chosenstate = S_TAILSOVERLAY_STAND;
else
chosenstate = S_INVISIBLE;
// state...
if (panimchange)
{
tails->sprite2 = -1;
P_SetMobjState(tails, chosenstate);
}
else
{
if (tails->state != states+chosenstate)
{
if (states[chosenstate].sprite == SPR_PLAY)
tails->sprite2 = P_GetSkinSprite2(((skin_t *)tails->skin), (states[chosenstate].frame & FF_FRAMEMASK), player);
P_SetMobjState(tails, chosenstate);
}
}
if (player->fly1 != 0 && player->powers[pw_tailsfly] != 0 && !smilesonground)
P_SetMobjState(tails, chosenstate);
// animation...
if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
{
if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS)
ticnum = 2;
else
ticnum = 1;
}
else if (player->panim == PA_PAIN)
ticnum = 2;
else if (player->mo->state-states == S_PLAY_GASP)
tails->tics = -1;
else if (player->mo->sprite2 == SPR2_TIRE)
ticnum = 4;
else if (player->panim != PA_IDLE)
ticnum = player->mo->tics;
if (ticnum && tails->tics > ticnum)
tails->tics = ticnum;
// final handling...
tails->color = player->mo->color;
tails->threshold = player->mo->z;
tails->movecount = player->panim;
tails->angle = horizangle;
P_SetScale(tails, player->mo->scale);
tails->destscale = player->mo->destscale;
tails->radius = player->mo->radius;
tails->height = player->mo->height;
zoffs = FixedMul(zoffs, tails->scale);
if (player->mo->eflags & MFE_VERTICALFLIP)
{
tails->eflags |= MFE_VERTICALFLIP;
tails->flags2 |= MF2_OBJECTFLIP;
zoffs = player->mo->height - tails->height - zoffs;
}
else
{
tails->eflags &= ~MFE_VERTICALFLIP;
tails->flags2 &= ~MF2_OBJECTFLIP;
}
P_UnsetThingPosition(tails);
tails->x = player->mo->x + P_ReturnThrustX(tails, tails->angle, FixedMul(backwards, tails->scale));
tails->y = player->mo->y + P_ReturnThrustY(tails, tails->angle, FixedMul(backwards, tails->scale));
tails->z = player->mo->z + zoffs;
P_SetThingPosition(tails);
}
//
// P_PlayerThink
//
@ -10688,6 +10874,9 @@ void P_PlayerThink(player_t *player)
if (player->exiting && countdown2)
player->exiting = 5;
// The following code is disabled for now as this causes the game to freeze sometimes
// Monster Iestyn -- 16/08/19
#if 0
// Same check as below, just at 1 second before
// so we can fade music
if (!exitfadestarted &&
@ -10725,6 +10914,7 @@ void P_PlayerThink(player_t *player)
S_FadeOutStopMusic(1*MUSICRATE);
}
}
#endif
if (player->exiting == 2 || countdown2 == 2)
{
@ -11500,130 +11690,149 @@ void P_PlayerAfterThink(player_t *player)
/* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing)
P_SetTarget(&player->mo->tracer, NULL);
else */
if (player->powers[pw_carry] == CR_PLAYER && player->mo->tracer)
if (player->mo->tracer)
{
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
if (player->mo->tracer->player && !(player->mo->tracer->player->pflags & PF_CANCARRY))
player->powers[pw_carry] = CR_NONE;
if (player->mo->eflags & MFE_VERTICALFLIP)
switch (player->powers[pw_carry])
{
if ((player->mo->tracer->z + player->mo->tracer->height + player->mo->height + FixedMul(FRACUNIT, player->mo->scale)) <= player->mo->tracer->ceilingz
&& (player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z + player->mo->tracer->height + FixedMul(FRACUNIT, player->mo->scale);
else
player->powers[pw_carry] = CR_NONE;
}
else
{
if ((player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale)) >= player->mo->tracer->floorz
&& !(player->mo->tracer->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
player->mo->z = player->mo->tracer->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
else
player->powers[pw_carry] = CR_NONE;
}
if (player->mo->tracer->health <= 0)
player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, true);
player->mo->momx = player->mo->tracer->momx;
player->mo->momy = player->mo->tracer->momy;
player->mo->momz = player->mo->tracer->momz;
}
if (gametype == GT_COOP)
{
player->mo->angle = player->mo->tracer->angle;
if (!demoplayback || P_AnalogMove(player))
case CR_PLAYER: // being carried by a flying character (such as Tails)
{
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
}
}
mobj_t *tails = player->mo->tracer;
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
if (P_AproxDistance(player->mo->x - player->mo->tracer->x, player->mo->y - player->mo->tracer->y) > player->mo->radius)
player->powers[pw_carry] = CR_NONE;
if (tails->player && !(tails->player->pflags & PF_CANCARRY))
player->powers[pw_carry] = CR_NONE;
if (player->powers[pw_carry] != CR_NONE)
{
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
}
else
P_SetTarget(&player->mo->tracer, NULL);
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER));
}
else if (player->powers[pw_carry] == CR_GENERIC && player->mo->tracer)
{
// tracer is what you're hanging onto
P_UnsetThingPosition(player->mo);
player->mo->x = player->mo->tracer->x;
player->mo->y = player->mo->tracer->y;
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z = player->mo->tracer->z + player->mo->tracer->height - FixedDiv(player->mo->height, 3*FRACUNIT);
else
player->mo->z = player->mo->tracer->z - FixedDiv(player->mo->height, 3*FRACUNIT/2);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
P_SetThingPosition(player->mo);
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
// Controllable missile
if (player->mo->tracer->type == MT_BLACKEGGMAN_MISSILE)
{
if (cmd->forwardmove > 0)
player->mo->tracer->momz += FixedMul(FRACUNIT/4, player->mo->tracer->scale);
else if (cmd->forwardmove < 0)
player->mo->tracer->momz -= FixedMul(FRACUNIT/4, player->mo->tracer->scale);
player->mo->tracer->angle = player->mo->angle;
P_InstaThrust(player->mo->tracer, player->mo->tracer->angle, FixedMul(player->mo->tracer->info->speed, player->mo->tracer->scale));
if (player->mo->z <= player->mo->floorz
|| player->mo->tracer->health <= 0)
{
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
}
}
else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->tracer)
{
player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto....
player->mo->momx = (player->mo->tracer->x - player->mo->x)*2;
player->mo->momy = (player->mo->tracer->y - player->mo->y)*2;
player->mo->momz = (player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2) - player->mo->z)*2;
P_TeleportMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2));
if (!player->powers[pw_flashing]) // handle getting hurt
{
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_NOJUMPDAMAGE;
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
{
player->mo->tracer->tracer->angle += cmd->sidemove<<ANGLETOFINESHIFT;
player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
if (!demoplayback || P_AnalogMove(player))
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if (player == &players[consoleplayer])
localangle = player->mo->angle; // Adjust the local control angle.
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
if ((tails->z + tails->height + player->mo->height + FixedMul(FRACUNIT, player->mo->scale)) <= tails->ceilingz
&& (tails->eflags & MFE_VERTICALFLIP)) // Reverse gravity check for the carrier - Flame
player->mo->z = tails->z + tails->height + FixedMul(FRACUNIT, player->mo->scale);
else
player->powers[pw_carry] = CR_NONE;
}
else
{
if ((tails->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale)) >= tails->floorz
&& !(tails->eflags & MFE_VERTICALFLIP)) // Correct gravity check for the carrier - Flame
player->mo->z = tails->z - player->mo->height - FixedMul(FRACUNIT, player->mo->scale);
else
player->powers[pw_carry] = CR_NONE;
}
if (tails->health <= 0)
player->powers[pw_carry] = CR_NONE;
else
{
P_TryMove(player->mo, tails->x, tails->y, true);
player->mo->momx = tails->momx;
player->mo->momy = tails->momy;
player->mo->momz = tails->momz;
}
if (gametype == GT_COOP)
{
player->mo->angle = tails->angle;
if (!demoplayback || P_AnalogMove(player))
{
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
}
}
if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius)
player->powers[pw_carry] = CR_NONE;
if (player->powers[pw_carry] != CR_NONE)
{
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
}
else
P_SetTarget(&player->mo->tracer, NULL);
if (player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER));
break;
}
case CR_GENERIC: // being carried by some generic item
{
mobj_t *item = player->mo->tracer;
// tracer is what you're hanging onto
P_UnsetThingPosition(player->mo);
player->mo->x = item->x;
player->mo->y = item->y;
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z = item->z + item->height - FixedDiv(player->mo->height, 3*FRACUNIT);
else
player->mo->z = item->z - FixedDiv(player->mo->height, 3*FRACUNIT/2);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
P_SetThingPosition(player->mo);
if (player->mo->state-states != S_PLAY_RIDE)
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
// Controllable missile
if (item->type == MT_BLACKEGGMAN_MISSILE)
{
if (cmd->forwardmove > 0)
item->momz += FixedMul(FRACUNIT/4, item->scale);
else if (cmd->forwardmove < 0)
item->momz -= FixedMul(FRACUNIT/4, item->scale);
item->angle = player->mo->angle;
P_InstaThrust(item, item->angle, FixedMul(item->info->speed, item->scale));
if (player->mo->z <= player->mo->floorz || item->health <= 0)
{
player->powers[pw_carry] = CR_NONE;
P_SetTarget(&player->mo->tracer, NULL);
}
}
break;
}
case CR_MACESPIN: // being carried by a spinning chain
{
mobj_t *chain;
mobj_t *macecenter;
if (!player->mo->tracer->tracer) // can't spin around a point if... there is no point in doing so
break;
chain = player->mo->tracer;
macecenter = player->mo->tracer->tracer;
player->mo->height = P_GetPlayerSpinHeight(player);
// tracer is what you're hanging onto....
player->mo->momx = (chain->x - player->mo->x)*2;
player->mo->momy = (chain->y - player->mo->y)*2;
player->mo->momz = (chain->z - (player->mo->height-chain->height/2) - player->mo->z)*2;
P_TeleportMove(player->mo, chain->x, chain->y, chain->z - (player->mo->height-chain->height/2));
if (!player->powers[pw_flashing]) // handle getting hurt
{
player->pflags |= PF_JUMPED;
player->pflags &= ~PF_NOJUMPDAMAGE;
player->secondjump = 0;
player->pflags &= ~PF_THOKKED;
if ((macecenter->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
{
macecenter->angle += cmd->sidemove<<ANGLETOFINESHIFT;
player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
if (!demoplayback || P_AnalogMove(player))
{
if (player == &players[consoleplayer])
localangle = player->mo->angle; // Adjust the local control angle.
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
}
}
}
break;
}
default:
break;
}
}
@ -11684,188 +11893,7 @@ void P_PlayerAfterThink(player_t *player)
switch (player->followmobj->type)
{
case MT_TAILSOVERLAY: // c:
{
// init...
boolean smilesonground = P_IsObjectOnGround(player->mo);
angle_t horizangle = player->drawangle;
fixed_t zoffs = 0;
fixed_t backwards = -1*FRACUNIT;
boolean doroll = (player->panim == PA_ROLL || player->panim == PA_JUMP);
angle_t rollangle;
boolean panimchange;
INT32 ticnum = 0;
statenum_t chosenstate;
if (!player->followmobj->skin)
{
player->followmobj->skin = player->mo->skin;
P_SetMobjState(player->followmobj, S_TAILSOVERLAY_STAND);
player->followmobj->movecount = -1;
}
panimchange = (player->followmobj->movecount != (INT32)player->panim);
// initial position...
if (doroll)
{
fixed_t testval, zdist;
if (player->speed < FRACUNIT)
testval = FRACUNIT;
else
{
testval = (FixedMul(player->speed, FINECOSINE((horizangle - R_PointToAngle2(0, 0, player->rmomx, player->rmomy)) >> ANGLETOFINESHIFT)));
if (testval < FRACUNIT)
testval = FRACUNIT;
}
if (smilesonground && !player->mo->reactiontime)
zdist = (player->mo->z - player->followmobj->threshold);
else
zdist = player->mo->momz;
rollangle = R_PointToAngle2(0, 0, testval, -P_MobjFlip(player->mo)*zdist);
zoffs = 3*FRACUNIT + 12*FINESINE(rollangle >> ANGLETOFINESHIFT);
backwards = -12*FINECOSINE(rollangle >> ANGLETOFINESHIFT);
}
else if (player->panim == PA_RUN)
backwards = -5*FRACUNIT;
else if (player->panim == PA_SPRING)
{
zoffs += 4*FRACUNIT;
backwards /= 2;
}
else if (player->panim == PA_PAIN)
backwards /= 16;
else if (player->mo->state-states == S_PLAY_GASP)
{
backwards /= 16;
zoffs += 12*FRACUNIT;
}
else if (player->mo->state-states == S_PLAY_EDGE)
{
backwards /= 16;
zoffs = 3*FRACUNIT;
}
else if (player->panim == PA_ABILITY2)
{
zoffs = -7*FRACUNIT;
backwards = -9*FRACUNIT;
}
else if (player->mo->sprite2 == SPR2_FLY || player->mo->sprite2 == SPR2_TIRE)
backwards = -5*FRACUNIT;
// sprite...
if (doroll)
{
statenum_t add = ((rollangle > ANGLE_180) ? 2 : 0);
if (add)
rollangle = InvAngle(rollangle);
rollangle += ANG15; // modify the thresholds to be nice clean numbers
if (rollangle > ANG60)
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES + add;
else if (rollangle > ANG30)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES + add;
else
chosenstate = S_TAILSOVERLAY_0DEGREES;
}
else if (player->panim == PA_SPRING)
chosenstate = S_TAILSOVERLAY_MINUS60DEGREES;
else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES;
else if (player->panim == PA_PAIN)
chosenstate = S_TAILSOVERLAY_PAIN;
else if (player->mo->state-states == S_PLAY_GASP)
chosenstate = S_TAILSOVERLAY_GASP;
else if (player->mo->state-states == S_PLAY_EDGE)
chosenstate = S_TAILSOVERLAY_EDGE;
else if (player->panim == PA_RUN)
chosenstate = S_TAILSOVERLAY_RUN;
else if (player->panim == PA_WALK)
{
if (!smilesonground || player->mo->state-states == S_PLAY_SKID)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale))
chosenstate = S_TAILSOVERLAY_0DEGREES;
else
chosenstate = S_TAILSOVERLAY_MINUS30DEGREES;
}
else if (player->mo->sprite2 == SPR2_FLY)
chosenstate = S_TAILSOVERLAY_FLY;
else if (player->mo->sprite2 == SPR2_TIRE)
chosenstate = S_TAILSOVERLAY_TIRE;
else if (player->panim == PA_ABILITY2)
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->panim == PA_IDLE)
chosenstate = S_TAILSOVERLAY_STAND;
else
chosenstate = S_INVISIBLE;
// state...
if (panimchange)
{
player->followmobj->sprite2 = -1;
P_SetMobjState(player->followmobj, chosenstate);
}
else
{
if (player->followmobj->state != states+chosenstate)
{
if (states[chosenstate].sprite == SPR_PLAY)
player->followmobj->sprite2 = P_GetSkinSprite2(((skin_t *)player->followmobj->skin), (states[chosenstate].frame & FF_FRAMEMASK), player);
P_SetMobjState(player->followmobj, chosenstate);
}
}
if (player->fly1 != 0 && player->powers[pw_tailsfly] != 0 && !smilesonground)
P_SetMobjState(player->followmobj, chosenstate);
// animation...
if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
{
if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS)
ticnum = 2;
else
ticnum = 1;
}
else if (player->panim == PA_PAIN)
ticnum = 2;
else if (player->mo->state-states == S_PLAY_GASP)
player->followmobj->tics = -1;
else if (player->mo->sprite2 == SPR2_TIRE)
ticnum = 4;
else if (player->panim != PA_IDLE)
ticnum = player->mo->tics;
if (ticnum && player->followmobj->tics > ticnum)
player->followmobj->tics = ticnum;
// final handling...
player->followmobj->color = player->mo->color;
player->followmobj->threshold = player->mo->z;
player->followmobj->movecount = player->panim;
player->followmobj->angle = horizangle;
P_SetScale(player->followmobj, player->mo->scale);
player->followmobj->destscale = player->mo->destscale;
player->followmobj->radius = player->mo->radius;
player->followmobj->height = player->mo->height;
zoffs = FixedMul(zoffs, player->followmobj->scale);
if (player->mo->eflags & MFE_VERTICALFLIP)
{
player->followmobj->eflags |= MFE_VERTICALFLIP;
player->followmobj->flags2 |= MF2_OBJECTFLIP;
zoffs = player->mo->height - player->followmobj->height - zoffs;
}
else
{
player->followmobj->eflags &= ~MFE_VERTICALFLIP;
player->followmobj->flags2 &= ~MF2_OBJECTFLIP;
}
P_UnsetThingPosition(player->followmobj);
player->followmobj->x = player->mo->x + P_ReturnThrustX(player->followmobj, player->followmobj->angle, FixedMul(backwards, player->followmobj->scale));
player->followmobj->y = player->mo->y + P_ReturnThrustY(player->followmobj, player->followmobj->angle, FixedMul(backwards, player->followmobj->scale));
player->followmobj->z = player->mo->z + zoffs;
P_SetThingPosition(player->followmobj);
}
P_DoTailsOverlay(player, player->followmobj);
break;
default:
var1 = 1;

View file

@ -352,77 +352,79 @@ const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] =
A word of warning: If the following array is non-symmetrical,
A_SignPlayer's prefoppositecolor behaviour will break.
*/
const UINT8 Color_Opposite[(MAXSKINCOLORS - 1)*2] =
// [0] = opposite skin color,
// [1] = shade index used by signpost, 0-15 (actual sprite frame is 15 minus this value)
const UINT8 Color_Opposite[MAXSKINCOLORS - 1][2] =
{
// SKINCOLOR_NONE,8, // SKINCOLOR_NONE
// {SKINCOLOR_NONE, 8}, // SKINCOLOR_NONE
// Greyscale ranges
SKINCOLOR_BLACK,5, // SKINCOLOR_WHITE,
SKINCOLOR_JET,7, // SKINCOLOR_BONE,
SKINCOLOR_CARBON,7, // SKINCOLOR_CLOUDY,
SKINCOLOR_AETHER,12, // SKINCOLOR_GREY,
SKINCOLOR_SLATE,12, // SKINCOLOR_SILVER,
SKINCOLOR_CLOUDY,7, // SKINCOLOR_CARBON,
SKINCOLOR_BONE,7, // SKINCOLOR_JET,
SKINCOLOR_WHITE,7, // SKINCOLOR_BLACK,
{SKINCOLOR_BLACK, 5}, // SKINCOLOR_WHITE,
{SKINCOLOR_JET, 7}, // SKINCOLOR_BONE,
{SKINCOLOR_CARBON, 7}, // SKINCOLOR_CLOUDY,
{SKINCOLOR_AETHER, 12}, // SKINCOLOR_GREY,
{SKINCOLOR_SLATE, 12}, // SKINCOLOR_SILVER,
{SKINCOLOR_CLOUDY, 7}, // SKINCOLOR_CARBON,
{SKINCOLOR_BONE, 7}, // SKINCOLOR_JET,
{SKINCOLOR_WHITE, 7}, // SKINCOLOR_BLACK,
// Desaturated
SKINCOLOR_GREY,15, // SKINCOLOR_AETHER,
SKINCOLOR_SILVER,12, // SKINCOLOR_SLATE,
SKINCOLOR_AZURE,9, // SKINCOLOR_PINK,
SKINCOLOR_RUST,7, // SKINCOLOR_YOGURT,
SKINCOLOR_TAN,2, // SKINCOLOR_BROWN,
SKINCOLOR_BROWN,12, // SKINCOLOR_TAN,
SKINCOLOR_MOSS,5, // SKINCOLOR_BEIGE,
SKINCOLOR_BEIGE,13, // SKINCOLOR_MOSS,
SKINCOLOR_PINK,5, // SKINCOLOR_AZURE,
SKINCOLOR_GOLD,4, // SKINCOLOR_LAVENDER,
{SKINCOLOR_GREY, 15}, // SKINCOLOR_AETHER,
{SKINCOLOR_SILVER, 12}, // SKINCOLOR_SLATE,
{SKINCOLOR_AZURE, 9}, // SKINCOLOR_PINK,
{SKINCOLOR_RUST, 7}, // SKINCOLOR_YOGURT,
{SKINCOLOR_TAN, 2}, // SKINCOLOR_BROWN,
{SKINCOLOR_BROWN, 12}, // SKINCOLOR_TAN,
{SKINCOLOR_MOSS, 5}, // SKINCOLOR_BEIGE,
{SKINCOLOR_BEIGE, 13}, // SKINCOLOR_MOSS,
{SKINCOLOR_PINK, 5}, // SKINCOLOR_AZURE,
{SKINCOLOR_GOLD, 4}, // SKINCOLOR_LAVENDER,
// Viv's vivid colours (toast 21/07/17)
SKINCOLOR_EMERALD,10, // SKINCOLOR_RUBY,
SKINCOLOR_FOREST,6, // SKINCOLOR_SALMON,
SKINCOLOR_GREEN,10, // SKINCOLOR_RED,
SKINCOLOR_ICY,10, // SKINCOLOR_CRIMSON,
SKINCOLOR_PURPLE,8, // SKINCOLOR_FLAME,
SKINCOLOR_TEAL,7, // SKINCOLOR_PEACHY,
SKINCOLOR_WAVE,5, // SKINCOLOR_QUAIL,
SKINCOLOR_SAPPHIRE,5, // SKINCOLOR_SUNSET,
SKINCOLOR_CYAN,4, // SKINCOLOR_APRICOT,
SKINCOLOR_BLUE,4, // SKINCOLOR_ORANGE,
SKINCOLOR_YOGURT,8, // SKINCOLOR_RUST,
SKINCOLOR_LAVENDER,10, // SKINCOLOR_GOLD,
SKINCOLOR_SKY,8, // SKINCOLOR_SANDY,
SKINCOLOR_CORNFLOWER,8, // SKINCOLOR_YELLOW,
SKINCOLOR_DUSK,3, // SKINCOLOR_OLIVE,
SKINCOLOR_MAGENTA,9, // SKINCOLOR_LIME,
SKINCOLOR_COBALT,2, // SKINCOLOR_PERIDOT,
SKINCOLOR_RED,6, // SKINCOLOR_GREEN,
SKINCOLOR_SALMON,9, // SKINCOLOR_FOREST,
SKINCOLOR_RUBY,4, // SKINCOLOR_EMERALD,
SKINCOLOR_VIOLET,5, // SKINCOLOR_MINT,
SKINCOLOR_PLUM,6, // SKINCOLOR_SEAFOAM,
SKINCOLOR_ROSY,7, // SKINCOLOR_AQUA,
SKINCOLOR_PEACHY,7, // SKINCOLOR_TEAL,
SKINCOLOR_QUAIL,5, // SKINCOLOR_WAVE,
SKINCOLOR_APRICOT,6, // SKINCOLOR_CYAN,
SKINCOLOR_SANDY,1, // SKINCOLOR_SKY,
SKINCOLOR_NEON,4, // SKINCOLOR_CERULEAN,
SKINCOLOR_CRIMSON,0, // SKINCOLOR_ICY,
SKINCOLOR_SUNSET,5, // SKINCOLOR_SAPPHIRE,
SKINCOLOR_YELLOW,4, // SKINCOLOR_CORNFLOWER,
SKINCOLOR_ORANGE,5, // SKINCOLOR_BLUE,
SKINCOLOR_PERIDOT,5, // SKINCOLOR_COBALT,
SKINCOLOR_LILAC,4, // SKINCOLOR_VAPOR,
SKINCOLOR_OLIVE,0, // SKINCOLOR_DUSK,
SKINCOLOR_BUBBLEGUM,9, // SKINCOLOR_PASTEL,
SKINCOLOR_FLAME,7, // SKINCOLOR_PURPLE,
SKINCOLOR_PASTEL,8, // SKINCOLOR_BUBBLEGUM,
SKINCOLOR_LIME,6, // SKINCOLOR_MAGENTA,
SKINCOLOR_CERULEAN,2, // SKINCOLOR_NEON,
SKINCOLOR_MINT,6, // SKINCOLOR_VIOLET,
SKINCOLOR_VAPOR,4, // SKINCOLOR_LILAC,
SKINCOLOR_MINT,7, // SKINCOLOR_PLUM,
SKINCOLOR_AQUA,1 // SKINCOLOR_ROSY,
{SKINCOLOR_EMERALD, 10}, // SKINCOLOR_RUBY,
{SKINCOLOR_FOREST, 6}, // SKINCOLOR_SALMON,
{SKINCOLOR_GREEN, 10}, // SKINCOLOR_RED,
{SKINCOLOR_ICY, 10}, // SKINCOLOR_CRIMSON,
{SKINCOLOR_PURPLE, 8}, // SKINCOLOR_FLAME,
{SKINCOLOR_TEAL, 7}, // SKINCOLOR_PEACHY,
{SKINCOLOR_WAVE, 5}, // SKINCOLOR_QUAIL,
{SKINCOLOR_SAPPHIRE, 5}, // SKINCOLOR_SUNSET,
{SKINCOLOR_CYAN, 4}, // SKINCOLOR_APRICOT,
{SKINCOLOR_BLUE, 4}, // SKINCOLOR_ORANGE,
{SKINCOLOR_YOGURT, 8}, // SKINCOLOR_RUST,
{SKINCOLOR_LAVENDER, 10}, // SKINCOLOR_GOLD,
{SKINCOLOR_SKY, 8}, // SKINCOLOR_SANDY,
{SKINCOLOR_CORNFLOWER, 8}, // SKINCOLOR_YELLOW,
{SKINCOLOR_DUSK, 3}, // SKINCOLOR_OLIVE,
{SKINCOLOR_MAGENTA, 9}, // SKINCOLOR_LIME,
{SKINCOLOR_COBALT, 2}, // SKINCOLOR_PERIDOT,
{SKINCOLOR_RED, 6}, // SKINCOLOR_GREEN,
{SKINCOLOR_SALMON, 9}, // SKINCOLOR_FOREST,
{SKINCOLOR_RUBY, 4}, // SKINCOLOR_EMERALD,
{SKINCOLOR_VIOLET, 5}, // SKINCOLOR_MINT,
{SKINCOLOR_PLUM, 6}, // SKINCOLOR_SEAFOAM,
{SKINCOLOR_ROSY, 7}, // SKINCOLOR_AQUA,
{SKINCOLOR_PEACHY, 7}, // SKINCOLOR_TEAL,
{SKINCOLOR_QUAIL, 5}, // SKINCOLOR_WAVE,
{SKINCOLOR_APRICOT, 6}, // SKINCOLOR_CYAN,
{SKINCOLOR_SANDY, 1}, // SKINCOLOR_SKY,
{SKINCOLOR_NEON, 4}, // SKINCOLOR_CERULEAN,
{SKINCOLOR_CRIMSON, 0}, // SKINCOLOR_ICY,
{SKINCOLOR_SUNSET, 5}, // SKINCOLOR_SAPPHIRE,
{SKINCOLOR_YELLOW, 4}, // SKINCOLOR_CORNFLOWER,
{SKINCOLOR_ORANGE, 5}, // SKINCOLOR_BLUE,
{SKINCOLOR_PERIDOT, 5}, // SKINCOLOR_COBALT,
{SKINCOLOR_LILAC, 4}, // SKINCOLOR_VAPOR,
{SKINCOLOR_OLIVE, 0}, // SKINCOLOR_DUSK,
{SKINCOLOR_BUBBLEGUM, 9}, // SKINCOLOR_PASTEL,
{SKINCOLOR_FLAME, 7}, // SKINCOLOR_PURPLE,
{SKINCOLOR_PASTEL, 8}, // SKINCOLOR_BUBBLEGUM,
{SKINCOLOR_LIME, 6}, // SKINCOLOR_MAGENTA,
{SKINCOLOR_CERULEAN, 2}, // SKINCOLOR_NEON,
{SKINCOLOR_MINT, 6}, // SKINCOLOR_VIOLET,
{SKINCOLOR_VAPOR, 4}, // SKINCOLOR_LILAC,
{SKINCOLOR_MINT, 7}, // SKINCOLOR_PLUM,
{SKINCOLOR_AQUA, 1} // SKINCOLOR_ROSY,
};
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@ -521,33 +523,49 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
INT32 i, starttranscolor, skinramplength;
// Handle a couple of simple special cases
if (skinnum == TC_BOSS
|| skinnum == TC_ALLWHITE
|| skinnum == TC_METALSONIC
|| skinnum == TC_BLINK
|| color == SKINCOLOR_NONE)
if (skinnum < TC_DEFAULT)
{
if (skinnum == TC_ALLWHITE)
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
else if (skinnum == TC_BLINK && color != SKINCOLOR_NONE)
memset(dest_colormap, Color_Index[color-1][3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
else
switch (skinnum)
{
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
case TC_ALLWHITE:
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
case TC_RAINBOW:
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
{
R_RainbowColormap(dest_colormap, color);
return;
}
break;
case TC_BLINK:
if (color >= MAXTRANSLATIONS)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
{
memset(dest_colormap, Color_Index[color-1][3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
}
break;
default:
break;
}
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
// White!
if (skinnum == TC_BOSS)
dest_colormap[31] = 0;
else if (skinnum == TC_METALSONIC)
dest_colormap[159] = 0;
return;
}
else if (skinnum == TC_RAINBOW)
else if (color == SKINCOLOR_NONE)
{
R_RainbowColormap(dest_colormap, color);
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
return;
}
@ -556,6 +574,9 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d.", starttranscolor);
// Fill in the entries of the palette that are fixed
for (i = 0; i < starttranscolor; i++)
dest_colormap[i] = (UINT8)i;
@ -568,7 +589,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
skinramplength = 16;
}
else
skinramplength = i - NUM_PALETTE_ENTRIES;
skinramplength = i - NUM_PALETTE_ENTRIES; // shouldn't this be NUM_PALETTE_ENTRIES - starttranscolor?
// Build the translated ramp
for (i = 0; i < skinramplength; i++)
@ -590,13 +611,16 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
INT32 skintableindex;
// Adjust if we want the default colormap
if (skinnum == TC_DEFAULT) skintableindex = DEFAULT_TT_CACHE_INDEX;
else if (skinnum == TC_BOSS) skintableindex = BOSS_TT_CACHE_INDEX;
else if (skinnum == TC_METALSONIC) skintableindex = METALSONIC_TT_CACHE_INDEX;
else if (skinnum == TC_ALLWHITE) skintableindex = ALLWHITE_TT_CACHE_INDEX;
else if (skinnum == TC_RAINBOW) skintableindex = RAINBOW_TT_CACHE_INDEX;
else if (skinnum == TC_BLINK) skintableindex = BLINK_TT_CACHE_INDEX;
else skintableindex = skinnum;
switch (skinnum)
{
case TC_DEFAULT: skintableindex = DEFAULT_TT_CACHE_INDEX; break;
case TC_BOSS: skintableindex = BOSS_TT_CACHE_INDEX; break;
case TC_METALSONIC: skintableindex = METALSONIC_TT_CACHE_INDEX; break;
case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break;
case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break;
case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break;
default: skintableindex = skinnum; break;
}
if (flags & GTC_CACHE)
{

View file

@ -1219,7 +1219,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.24;
CURRENT_PROJECT_VERSION = 2.1.25;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1231,7 +1231,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.24;
CURRENT_PROJECT_VERSION = 2.1.25;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (