Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into FileManagement
This commit is contained in:
commit
8b64a6eef3
33
SRB2.cbp
33
SRB2.cbp
|
@ -1174,6 +1174,39 @@ HW3SOUND for 3D hardware sound support
|
||||||
<Option target="Debug Mingw64/DirectX" />
|
<Option target="Debug Mingw64/DirectX" />
|
||||||
<Option target="Release Mingw64/DirectX" />
|
<Option target="Release Mingw64/DirectX" />
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit filename="src/hardware/hw_clip.c">
|
||||||
|
<Option compilerVar="CC" />
|
||||||
|
<Option target="Debug Native/SDL" />
|
||||||
|
<Option target="Release Native/SDL" />
|
||||||
|
<Option target="Debug Mingw/SDL" />
|
||||||
|
<Option target="Release Mingw/SDL" />
|
||||||
|
<Option target="Debug Mingw/DirectX" />
|
||||||
|
<Option target="Release Mingw/DirectX" />
|
||||||
|
<Option target="Debug Any/Dummy" />
|
||||||
|
<Option target="Release Any/Dummy" />
|
||||||
|
<Option target="Debug Linux/SDL" />
|
||||||
|
<Option target="Release Linux/SDL" />
|
||||||
|
<Option target="Debug Mingw64/SDL" />
|
||||||
|
<Option target="Release Mingw64/SDL" />
|
||||||
|
<Option target="Debug Mingw64/DirectX" />
|
||||||
|
<Option target="Release Mingw64/DirectX" />
|
||||||
|
</Unit>
|
||||||
|
<Unit filename="src/hardware/hw_clip.h">
|
||||||
|
<Option target="Debug Native/SDL" />
|
||||||
|
<Option target="Release Native/SDL" />
|
||||||
|
<Option target="Debug Mingw/SDL" />
|
||||||
|
<Option target="Release Mingw/SDL" />
|
||||||
|
<Option target="Debug Mingw/DirectX" />
|
||||||
|
<Option target="Release Mingw/DirectX" />
|
||||||
|
<Option target="Debug Any/Dummy" />
|
||||||
|
<Option target="Release Any/Dummy" />
|
||||||
|
<Option target="Debug Linux/SDL" />
|
||||||
|
<Option target="Release Linux/SDL" />
|
||||||
|
<Option target="Debug Mingw64/SDL" />
|
||||||
|
<Option target="Release Mingw64/SDL" />
|
||||||
|
<Option target="Debug Mingw64/DirectX" />
|
||||||
|
<Option target="Release Mingw64/DirectX" />
|
||||||
|
</Unit>
|
||||||
<Unit filename="src/hardware/hw_data.h">
|
<Unit filename="src/hardware/hw_data.h">
|
||||||
<Option target="Debug Native/SDL" />
|
<Option target="Debug Native/SDL" />
|
||||||
<Option target="Release Native/SDL" />
|
<Option target="Release Native/SDL" />
|
||||||
|
|
|
@ -351,6 +351,7 @@ if(${SRB2_CONFIG_HWRENDER})
|
||||||
set(SRB2_HWRENDER_SOURCES
|
set(SRB2_HWRENDER_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
|
||||||
|
@ -359,6 +360,7 @@ if(${SRB2_CONFIG_HWRENDER})
|
||||||
)
|
)
|
||||||
|
|
||||||
set (SRB2_HWRENDER_HEADERS
|
set (SRB2_HWRENDER_HEADERS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
|
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
|
||||||
|
|
12
src/Makefile
12
src/Makefile
|
@ -259,7 +259,7 @@ ifndef DC
|
||||||
endif
|
endif
|
||||||
OPTS+=-DHWRENDER
|
OPTS+=-DHWRENDER
|
||||||
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
|
||||||
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
|
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef NOHS
|
ifdef NOHS
|
||||||
|
@ -703,7 +703,7 @@ ifdef MINGW
|
||||||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
|
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
|
||||||
|
@ -711,7 +711,7 @@ else
|
||||||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
|
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
|
||||||
|
@ -864,7 +864,7 @@ ifndef NOHW
|
||||||
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
|
||||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
|
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||||
|
@ -872,7 +872,7 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
|
||||||
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
|
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
|
||||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
|
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||||
|
@ -880,7 +880,7 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
|
||||||
$(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \
|
$(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \
|
||||||
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
|
||||||
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
|
||||||
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h am_map.h \
|
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
|
||||||
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
|
||||||
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
|
||||||
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include "win32/win_main.h"
|
#include "win32/win_main.h"
|
||||||
|
@ -1275,12 +1276,15 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case CONS_NOTICE:
|
case CONS_NOTICE:
|
||||||
|
// no notice for notices, hehe
|
||||||
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
||||||
break;
|
break;
|
||||||
case CONS_WARNING:
|
case CONS_WARNING:
|
||||||
|
refreshdirmenu |= REFRESHDIR_WARNING;
|
||||||
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
||||||
break;
|
break;
|
||||||
case CONS_ERROR:
|
case CONS_ERROR:
|
||||||
|
refreshdirmenu |= REFRESHDIR_ERROR;
|
||||||
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2527,12 +2527,18 @@ static void Command_Nodes(void)
|
||||||
|
|
||||||
static void Command_Ban(void)
|
static void Command_Ban(void)
|
||||||
{
|
{
|
||||||
if (COM_Argc() == 1)
|
if (COM_Argc() < 2)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || adminplayer == consoleplayer)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
@ -2542,8 +2548,9 @@ static void Command_Ban(void)
|
||||||
|
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
else
|
|
||||||
WRITEUINT8(p, pn);
|
WRITEUINT8(p, pn);
|
||||||
|
|
||||||
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||||
|
@ -2586,21 +2593,27 @@ static void Command_Ban(void)
|
||||||
|
|
||||||
static void Command_Kick(void)
|
static void Command_Kick(void)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
if (COM_Argc() < 2)
|
||||||
UINT8 *p = buf;
|
|
||||||
|
|
||||||
if (COM_Argc() == 1)
|
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || adminplayer == consoleplayer)
|
||||||
{
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
UINT8 *p = buf;
|
||||||
const SINT8 pn = nametonum(COM_Argv(1));
|
const SINT8 pn = nametonum(COM_Argv(1));
|
||||||
WRITESINT8(p, pn);
|
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Special case if we are trying to kick a player who is downloading the game state:
|
// Special case if we are trying to kick a player who is downloading the game state:
|
||||||
// trigger a timeout instead of kicking them, because a kick would only
|
// trigger a timeout instead of kicking them, because a kick would only
|
||||||
// take effect after they have finished downloading
|
// take effect after they have finished downloading
|
||||||
|
@ -2609,6 +2622,9 @@ static void Command_Kick(void)
|
||||||
Net_ConnectionTimeout(playernode[pn]);
|
Net_ConnectionTimeout(playernode[pn]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITESINT8(p, pn);
|
||||||
|
|
||||||
if (COM_Argc() == 2)
|
if (COM_Argc() == 2)
|
||||||
{
|
{
|
||||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||||
|
|
|
@ -315,6 +315,7 @@ typedef struct
|
||||||
} ATTRPACK clientconfig_pak;
|
} ATTRPACK clientconfig_pak;
|
||||||
|
|
||||||
#define MAXSERVERNAME 32
|
#define MAXSERVERNAME 32
|
||||||
|
#define MAXFILENEEDED 915
|
||||||
// This packet is too large
|
// This packet is too large
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -336,7 +337,7 @@ typedef struct
|
||||||
unsigned char mapmd5[16];
|
unsigned char mapmd5[16];
|
||||||
UINT8 actnum;
|
UINT8 actnum;
|
||||||
UINT8 iszone;
|
UINT8 iszone;
|
||||||
UINT8 fileneeded[915]; // is filled with writexxx (byteptr.h)
|
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||||
} ATTRPACK serverinfo_pak;
|
} ATTRPACK serverinfo_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
90
src/d_main.c
90
src/d_main.c
|
@ -74,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#include "m_cond.h" // condition initialization
|
#include "m_cond.h" // condition initialization
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -107,8 +108,6 @@ UINT8 window_notinfocus = false;
|
||||||
//
|
//
|
||||||
// DEMO LOOP
|
// DEMO LOOP
|
||||||
//
|
//
|
||||||
//static INT32 demosequence;
|
|
||||||
static const char *pagename = "MAP1PIC";
|
|
||||||
static char *startupwadfiles[MAX_WADFILES];
|
static char *startupwadfiles[MAX_WADFILES];
|
||||||
|
|
||||||
boolean devparm = false; // started game with -devparm
|
boolean devparm = false; // started game with -devparm
|
||||||
|
@ -420,10 +419,13 @@ static void D_Display(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image postprocessing effect
|
// Image postprocessing effect
|
||||||
if (postimgtype)
|
if (rendermode == render_soft)
|
||||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
{
|
||||||
if (postimgtype2)
|
if (postimgtype)
|
||||||
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||||
|
if (postimgtype2)
|
||||||
|
V_DoPostProcessor(1, postimgtype2, postimgparam2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastdraw)
|
if (lastdraw)
|
||||||
|
@ -586,6 +588,8 @@ void D_SRB2Loop(void)
|
||||||
realtics = entertic - oldentertics;
|
realtics = entertic - oldentertics;
|
||||||
oldentertics = entertic;
|
oldentertics = entertic;
|
||||||
|
|
||||||
|
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||||
|
|
||||||
#ifdef DEBUGFILE
|
#ifdef DEBUGFILE
|
||||||
if (!realtics)
|
if (!realtics)
|
||||||
if (debugload)
|
if (debugload)
|
||||||
|
@ -711,6 +715,7 @@ void D_StartTitle(void)
|
||||||
botskin = 0;
|
botskin = 0;
|
||||||
cv_debug = 0;
|
cv_debug = 0;
|
||||||
emeralds = 0;
|
emeralds = 0;
|
||||||
|
lastmaploaded = 0;
|
||||||
|
|
||||||
// In case someone exits out at the same time they start a time attack run,
|
// In case someone exits out at the same time they start a time attack run,
|
||||||
// reset modeattacking
|
// reset modeattacking
|
||||||
|
@ -721,7 +726,6 @@ void D_StartTitle(void)
|
||||||
|
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
displayplayer = consoleplayer = 0;
|
displayplayer = consoleplayer = 0;
|
||||||
//demosequence = -1;
|
|
||||||
gametype = GT_COOP;
|
gametype = GT_COOP;
|
||||||
paused = false;
|
paused = false;
|
||||||
advancedemo = false;
|
advancedemo = false;
|
||||||
|
@ -870,7 +874,7 @@ static void IdentifyVersion(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 // This section can be deleted when music_new is merged with music.dta
|
#ifdef DEVELOP // This section can be deleted when music_new is merged with music.dta
|
||||||
{
|
{
|
||||||
const char *musicfile = "music_new.dta";
|
const char *musicfile = "music_new.dta";
|
||||||
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
||||||
|
@ -883,27 +887,10 @@ static void IdentifyVersion(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================== */
|
|
||||||
// Just print the nice red titlebar like the original SRB2 for DOS.
|
|
||||||
/* ======================================================================== */
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
static inline void D_Titlebar(char *title1, char *title2)
|
/* ======================================================================== */
|
||||||
{
|
// Code for printing SRB2's title bar in DOS
|
||||||
// SRB2 banner
|
/* ======================================================================== */
|
||||||
clrscr();
|
|
||||||
textattr((BLUE<<4)+WHITE);
|
|
||||||
clreol();
|
|
||||||
cputs(title1);
|
|
||||||
|
|
||||||
// standard srb2 banner
|
|
||||||
textattr((RED<<4)+WHITE);
|
|
||||||
clreol();
|
|
||||||
gotoxy((80-strlen(title2))/2, 2);
|
|
||||||
cputs(title2);
|
|
||||||
normvideo();
|
|
||||||
gotoxy(1,3);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Center the title string, then add the date and time of compilation.
|
// Center the title string, then add the date and time of compilation.
|
||||||
|
@ -932,6 +919,31 @@ static inline void D_MakeTitleString(char *s)
|
||||||
strcpy(s, temp);
|
strcpy(s, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void D_Titlebar(void)
|
||||||
|
{
|
||||||
|
char title1[82]; // srb2 title banner
|
||||||
|
char title2[82];
|
||||||
|
|
||||||
|
strcpy(title1, "Sonic Robo Blast 2");
|
||||||
|
strcpy(title2, "Sonic Robo Blast 2");
|
||||||
|
|
||||||
|
D_MakeTitleString(title1);
|
||||||
|
|
||||||
|
// SRB2 banner
|
||||||
|
clrscr();
|
||||||
|
textattr((BLUE<<4)+WHITE);
|
||||||
|
clreol();
|
||||||
|
cputs(title1);
|
||||||
|
|
||||||
|
// standard srb2 banner
|
||||||
|
textattr((RED<<4)+WHITE);
|
||||||
|
clreol();
|
||||||
|
gotoxy((80-strlen(title2))/2, 2);
|
||||||
|
cputs(title2);
|
||||||
|
normvideo();
|
||||||
|
gotoxy(1,3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// D_SRB2Main
|
// D_SRB2Main
|
||||||
|
@ -939,8 +951,6 @@ static inline void D_MakeTitleString(char *s)
|
||||||
void D_SRB2Main(void)
|
void D_SRB2Main(void)
|
||||||
{
|
{
|
||||||
INT32 p;
|
INT32 p;
|
||||||
char srb2[82]; // srb2 title banner
|
|
||||||
char title[82];
|
|
||||||
|
|
||||||
INT32 pstartmap = 1;
|
INT32 pstartmap = 1;
|
||||||
boolean autostart = false;
|
boolean autostart = false;
|
||||||
|
@ -983,20 +993,8 @@ void D_SRB2Main(void)
|
||||||
dedicated = M_CheckParm("-dedicated") != 0;
|
dedicated = M_CheckParm("-dedicated") != 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy(title, "Sonic Robo Blast 2");
|
|
||||||
strcpy(srb2, "Sonic Robo Blast 2");
|
|
||||||
D_MakeTitleString(srb2);
|
|
||||||
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
D_Titlebar(srb2, title);
|
D_Titlebar();
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__OS2__) && !defined (HAVE_SDL)
|
|
||||||
// set PM window title
|
|
||||||
snprintf(pmData->title, sizeof (pmData->title),
|
|
||||||
"Sonic Robo Blast 2" VERSIONSTRING ": %s",
|
|
||||||
title);
|
|
||||||
pmData->title[sizeof (pmData->title) - 1] = '\0';
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (devparm)
|
if (devparm)
|
||||||
|
@ -1167,6 +1165,11 @@ void D_SRB2Main(void)
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
++mainwads; // patch.dta adds one more
|
++mainwads; // patch.dta adds one more
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEVELOP
|
||||||
|
++mainwads; // music_new, too
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mainwadstally = packetsizetally;
|
||||||
|
|
||||||
cht_Init();
|
cht_Init();
|
||||||
|
|
||||||
|
@ -1397,7 +1400,6 @@ void D_SRB2Main(void)
|
||||||
|
|
||||||
if (dedicated && server)
|
if (dedicated && server)
|
||||||
{
|
{
|
||||||
pagename = "TITLESKY";
|
|
||||||
levelstarttic = gametic;
|
levelstarttic = gametic;
|
||||||
G_SetGamestate(GS_LEVEL);
|
G_SetGamestate(GS_LEVEL);
|
||||||
if (!P_SetupLevel(false))
|
if (!P_SetupLevel(false))
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "filesrch.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
@ -714,6 +715,14 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_firenaxis);
|
CV_RegisterVar(&cv_firenaxis);
|
||||||
CV_RegisterVar(&cv_firenaxis2);
|
CV_RegisterVar(&cv_firenaxis2);
|
||||||
|
|
||||||
|
// filesrch.c
|
||||||
|
CV_RegisterVar(&cv_addons_option);
|
||||||
|
CV_RegisterVar(&cv_addons_folder);
|
||||||
|
CV_RegisterVar(&cv_addons_md5);
|
||||||
|
CV_RegisterVar(&cv_addons_showall);
|
||||||
|
CV_RegisterVar(&cv_addons_search_type);
|
||||||
|
CV_RegisterVar(&cv_addons_search_case);
|
||||||
|
|
||||||
// WARNING: the order is important when initialising mouse2
|
// WARNING: the order is important when initialising mouse2
|
||||||
// we need the mouse2port
|
// we need the mouse2port
|
||||||
CV_RegisterVar(&cv_mouse2port);
|
CV_RegisterVar(&cv_mouse2port);
|
||||||
|
|
|
@ -104,6 +104,7 @@ INT32 lastfilenum = -1;
|
||||||
/** Fills a serverinfo packet with information about wad files loaded.
|
/** Fills a serverinfo packet with information about wad files loaded.
|
||||||
*
|
*
|
||||||
* \todo Give this function a better name since it is in global scope.
|
* \todo Give this function a better name since it is in global scope.
|
||||||
|
* Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
UINT8 *PutFileNeeded(void)
|
UINT8 *PutFileNeeded(void)
|
||||||
|
@ -112,29 +113,22 @@ UINT8 *PutFileNeeded(void)
|
||||||
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
||||||
char wadfilename[MAX_WADPATH] = "";
|
char wadfilename[MAX_WADPATH] = "";
|
||||||
UINT8 filestatus;
|
UINT8 filestatus;
|
||||||
size_t bytesused = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < numwadfiles; i++)
|
for (i = 0; i < numwadfiles; i++)
|
||||||
{
|
{
|
||||||
// If it has only music/sound lumps, mark it as unimportant
|
// If it has only music/sound lumps, don't put it in the list
|
||||||
if (W_VerifyNMUSlumps(wadfiles[i]->filename))
|
if (!wadfiles[i]->important)
|
||||||
filestatus = 0;
|
continue;
|
||||||
else
|
|
||||||
filestatus = 1; // Important
|
filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS
|
||||||
|
|
||||||
// Store in the upper four bits
|
// Store in the upper four bits
|
||||||
if (!cv_downloading.value)
|
if (!cv_downloading.value)
|
||||||
filestatus += (2 << 4); // Won't send
|
filestatus += (2 << 4); // Won't send
|
||||||
else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024))
|
else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024))
|
||||||
filestatus += (0 << 4); // Won't send
|
|
||||||
else
|
|
||||||
filestatus += (1 << 4); // Will send if requested
|
filestatus += (1 << 4); // Will send if requested
|
||||||
|
// else
|
||||||
bytesused += (nameonlylength(wadfilename) + 22);
|
// filestatus += (0 << 4); -- Won't send, too big
|
||||||
|
|
||||||
// Don't write too far...
|
|
||||||
if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded))
|
|
||||||
I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename);
|
|
||||||
|
|
||||||
WRITEUINT8(p, filestatus);
|
WRITEUINT8(p, filestatus);
|
||||||
|
|
||||||
|
@ -167,7 +161,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
|
||||||
{
|
{
|
||||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
||||||
filestatus = READUINT8(p); // The first byte is the file status
|
filestatus = READUINT8(p); // The first byte is the file status
|
||||||
fileneeded[i].important = (UINT8)(filestatus & 3);
|
|
||||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||||
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
||||||
fileneeded[i].file = NULL; // The file isn't open yet
|
fileneeded[i].file = NULL; // The file isn't open yet
|
||||||
|
@ -197,7 +190,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
UINT8 i,dlstatus = 0;
|
UINT8 i,dlstatus = 0;
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
if (fileneeded[i].willsend == 1)
|
if (fileneeded[i].willsend == 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -218,7 +211,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
// not downloadable, put reason in console
|
// not downloadable, put reason in console
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||||
|
|
||||||
|
@ -271,7 +264,7 @@ boolean CL_SendRequestFile(void)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||||
&& fileneeded[i].important && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||||
{
|
{
|
||||||
I_Error("Attempted to download files that were not sendable");
|
I_Error("Attempted to download files that were not sendable");
|
||||||
}
|
}
|
||||||
|
@ -280,8 +273,7 @@ boolean CL_SendRequestFile(void)
|
||||||
netbuffer->packettype = PT_REQUESTFILE;
|
netbuffer->packettype = PT_REQUESTFILE;
|
||||||
p = (char *)netbuffer->u.textcmd;
|
p = (char *)netbuffer->u.textcmd;
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||||
&& fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||||
nameonly(fileneeded[i].filename);
|
nameonly(fileneeded[i].filename);
|
||||||
|
@ -360,15 +352,9 @@ INT32 CL_CheckFiles(void)
|
||||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||||
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
||||||
{
|
{
|
||||||
if (i < fileneedednum && !fileneeded[i].important)
|
if (j < numwadfiles && !wadfiles[j]->important)
|
||||||
{
|
{
|
||||||
// Eh whatever, don't care
|
// Unimportant on our side.
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename))
|
|
||||||
{
|
|
||||||
// Unimportant on our side. still don't care.
|
|
||||||
++j;
|
++j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +397,7 @@ INT32 CL_CheckFiles(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
if (fileneeded[i].status != FS_NOTFOUND)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||||
|
@ -449,27 +435,8 @@ void CL_LoadServerFiles(void)
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
}
|
}
|
||||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||||
{
|
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||||
// If the file is marked important, don't even bother proceeding.
|
else
|
||||||
if (fileneeded[i].important)
|
|
||||||
I_Error("Wrong version of important file %s", fileneeded[i].filename);
|
|
||||||
|
|
||||||
// If it isn't, no need to worry the user with a console message,
|
|
||||||
// although it can't hurt to put something in the debug file.
|
|
||||||
|
|
||||||
// ...but wait a second. What if the local version is "important"?
|
|
||||||
if (!W_VerifyNMUSlumps(fileneeded[i].filename))
|
|
||||||
I_Error("File %s should only contain music and sound effects!",
|
|
||||||
fileneeded[i].filename);
|
|
||||||
|
|
||||||
// Okay, NOW we know it's safe. Whew.
|
|
||||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
|
||||||
if (fileneeded[i].important)
|
|
||||||
G_SetGameModified(true);
|
|
||||||
fileneeded[i].status = FS_OPEN;
|
|
||||||
DEBFILE(va("File %s found but with different md5sum\n", fileneeded[i].filename));
|
|
||||||
}
|
|
||||||
else if (fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
switch(fileneeded[i].status)
|
switch(fileneeded[i].status)
|
||||||
|
|
|
@ -35,7 +35,6 @@ typedef enum
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 important;
|
|
||||||
UINT8 willsend; // Is the server willing to send it?
|
UINT8 willsend; // Is the server willing to send it?
|
||||||
char filename[MAX_WADPATH];
|
char filename[MAX_WADPATH];
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
|
497
src/dehacked.c
497
src/dehacked.c
|
@ -382,56 +382,6 @@ static void clear_levels(void)
|
||||||
P_AllocMapHeader(gamemap-1);
|
P_AllocMapHeader(gamemap-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Edits an animated texture slot on the array
|
|
||||||
// Tails 12-27-2003
|
|
||||||
static void readAnimTex(MYFILE *f, INT32 num)
|
|
||||||
{
|
|
||||||
char s[MAXLINELEN];
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (myfgets(s, sizeof s, f) != NULL)
|
|
||||||
{
|
|
||||||
if (s[0] == '\n') break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
// set the value in the appropriate field
|
|
||||||
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " = ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (word2[strlen(word2)-1] == '\n')
|
|
||||||
word2[strlen(word2)-1] = '\0';
|
|
||||||
|
|
||||||
i = atoi(word2);
|
|
||||||
|
|
||||||
if (fastcmp(word, "START"))
|
|
||||||
strncpy(harddefs[num].startname, word2, 8);
|
|
||||||
if (fastcmp(word, "END"))
|
|
||||||
strncpy(harddefs[num].endname, word2, 8);
|
|
||||||
else if (fastcmp(word, "SPEED")) harddefs[num].speed = i;
|
|
||||||
else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i;
|
|
||||||
|
|
||||||
else deh_warning("readAnimTex %d: unknown word '%s'", num, word);
|
|
||||||
}
|
|
||||||
} while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static boolean findFreeSlot(INT32 *num)
|
static boolean findFreeSlot(INT32 *num)
|
||||||
{
|
{
|
||||||
// Send the character select entry to a free slot.
|
// Send the character select entry to a free slot.
|
||||||
|
@ -1379,6 +1329,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
||||||
else
|
else
|
||||||
mapheaderinfo[num-1]->levelflags &= ~LF_NOZONE;
|
mapheaderinfo[num-1]->levelflags &= ~LF_NOZONE;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "SAVEGAME"))
|
||||||
|
{
|
||||||
|
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||||
|
mapheaderinfo[num-1]->levelflags |= LF_SAVEGAME;
|
||||||
|
else
|
||||||
|
mapheaderinfo[num-1]->levelflags &= ~LF_SAVEGAME;
|
||||||
|
}
|
||||||
|
|
||||||
// Individual triggers for menu flags
|
// Individual triggers for menu flags
|
||||||
else if (fastcmp(word, "HIDDEN"))
|
else if (fastcmp(word, "HIDDEN"))
|
||||||
|
@ -1826,7 +1783,6 @@ static actionpointer_t actionpointers[] =
|
||||||
{{A_CapeChase}, "A_CAPECHASE"},
|
{{A_CapeChase}, "A_CAPECHASE"},
|
||||||
{{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"},
|
{{A_RotateSpikeBall}, "A_ROTATESPIKEBALL"},
|
||||||
{{A_SlingAppear}, "A_SLINGAPPEAR"},
|
{{A_SlingAppear}, "A_SLINGAPPEAR"},
|
||||||
{{A_MaceRotate}, "A_MACEROTATE"},
|
|
||||||
{{A_UnidusBall}, "A_UNIDUSBALL"},
|
{{A_UnidusBall}, "A_UNIDUSBALL"},
|
||||||
{{A_RockSpawn}, "A_ROCKSPAWN"},
|
{{A_RockSpawn}, "A_ROCKSPAWN"},
|
||||||
{{A_SetFuse}, "A_SETFUSE"},
|
{{A_SetFuse}, "A_SETFUSE"},
|
||||||
|
@ -2106,7 +2062,7 @@ static void readframe(MYFILE *f, INT32 num)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
static void readsound(MYFILE *f, INT32 num)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
char *word;
|
char *word;
|
||||||
|
@ -2142,21 +2098,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (fastcmp(word, "OFFSET"))
|
if (fastcmp(word, "SINGULAR"))
|
||||||
{
|
|
||||||
value -= 150360;
|
|
||||||
if (value <= 64)
|
|
||||||
value /= 8;
|
|
||||||
else if (value <= 260)
|
|
||||||
value = (value+4)/8;
|
|
||||||
else
|
|
||||||
value = (value+8)/8;
|
|
||||||
if (value >= -1 && value < sfx_freeslot0 - 1)
|
|
||||||
S_sfx[num].name = savesfxnames[value+1];
|
|
||||||
else
|
|
||||||
deh_warning("Sound %d: offset out of bounds", num);
|
|
||||||
}
|
|
||||||
else */if (fastcmp(word, "SINGULAR"))
|
|
||||||
{
|
{
|
||||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||||
S_sfx[num].singularity = value;
|
S_sfx[num].singularity = value;
|
||||||
|
@ -2182,8 +2124,6 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||||
} while (!myfeof(f));
|
} while (!myfeof(f));
|
||||||
|
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
|
|
||||||
(void)savesfxnames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if a game data file name for a mod is good.
|
/** Checks if a game data file name for a mod is good.
|
||||||
|
@ -2293,12 +2233,12 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||||
emblemlocations[num-1].type = ET_TIME;
|
emblemlocations[num-1].type = ET_TIME;
|
||||||
else if (fastcmp(word2, "RINGS"))
|
else if (fastcmp(word2, "RINGS"))
|
||||||
emblemlocations[num-1].type = ET_RINGS;
|
emblemlocations[num-1].type = ET_RINGS;
|
||||||
|
else if (fastcmp(word2, "MAP"))
|
||||||
|
emblemlocations[num-1].type = ET_MAP;
|
||||||
else if (fastcmp(word2, "NGRADE"))
|
else if (fastcmp(word2, "NGRADE"))
|
||||||
emblemlocations[num-1].type = ET_NGRADE;
|
emblemlocations[num-1].type = ET_NGRADE;
|
||||||
else if (fastcmp(word2, "NTIME"))
|
else if (fastcmp(word2, "NTIME"))
|
||||||
emblemlocations[num-1].type = ET_NTIME;
|
emblemlocations[num-1].type = ET_NTIME;
|
||||||
else if (fastcmp(word2, "MAP"))
|
|
||||||
emblemlocations[num-1].type = ET_MAP;
|
|
||||||
else
|
else
|
||||||
emblemlocations[num-1].type = (UINT8)value;
|
emblemlocations[num-1].type = (UINT8)value;
|
||||||
}
|
}
|
||||||
|
@ -2811,190 +2751,6 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readtexture(MYFILE *f, const char *name)
|
|
||||||
{
|
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
char *tmp;
|
|
||||||
INT32 i, j, value;
|
|
||||||
UINT16 width = 0, height = 0;
|
|
||||||
INT16 patchcount = 0;
|
|
||||||
texture_t *texture;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
if (s[0] == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
value = searchvalue(s);
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Width of the texture.
|
|
||||||
if (fastcmp(word, "WIDTH"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", width), UNDO_NONE);
|
|
||||||
width = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
// Height of the texture.
|
|
||||||
else if (fastcmp(word, "HEIGHT"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", height), UNDO_NONE);
|
|
||||||
height = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
// Number of patches the texture has.
|
|
||||||
else if (fastcmp(word, "NUMPATCHES"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", patchcount), UNDO_NONE);
|
|
||||||
patchcount = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("readtexture: unknown word '%s'", word);
|
|
||||||
}
|
|
||||||
} while (!myfeof(f));
|
|
||||||
|
|
||||||
// Error checking.
|
|
||||||
if (!width)
|
|
||||||
I_Error("Texture %s has no width!\n", name);
|
|
||||||
|
|
||||||
if (!height)
|
|
||||||
I_Error("Texture %s has no height!\n", name);
|
|
||||||
|
|
||||||
if (!patchcount)
|
|
||||||
I_Error("Texture %s has no patches!\n", name);
|
|
||||||
|
|
||||||
// Allocate memory for the texture, and fill in information.
|
|
||||||
texture = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * SHORT(patchcount)), PU_STATIC, NULL);
|
|
||||||
M_Memcpy(texture->name, name, sizeof(texture->name));
|
|
||||||
texture->width = width;
|
|
||||||
texture->height = height;
|
|
||||||
texture->patchcount = patchcount;
|
|
||||||
texture->holes = false;
|
|
||||||
// Fill out the texture patches, to allow them to be detected
|
|
||||||
// accurately by readpatch.
|
|
||||||
for (i = 0; i < patchcount; i++)
|
|
||||||
{
|
|
||||||
texture->patches[i].originx = 0;
|
|
||||||
texture->patches[i].originy = 0;
|
|
||||||
texture->patches[i].wad = UINT16_MAX;
|
|
||||||
texture->patches[i].lump = UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jump to the next empty texture entry.
|
|
||||||
i = 0;
|
|
||||||
while (textures[i])
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Fill the global texture buffer entries.
|
|
||||||
j = 1;
|
|
||||||
while (j << 1 <= texture->width)
|
|
||||||
j <<= 1;
|
|
||||||
|
|
||||||
textures[i] = texture;
|
|
||||||
texturewidthmask[i] = j - 1;
|
|
||||||
textureheight[i] = texture->height << FRACBITS;
|
|
||||||
|
|
||||||
// Clean up.
|
|
||||||
Z_Free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
|
||||||
{
|
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
char *tmp;
|
|
||||||
INT32 i = 0, j = 0, value;
|
|
||||||
texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0, 255, AST_COPY};
|
|
||||||
|
|
||||||
// Jump to the texture this patch belongs to, which,
|
|
||||||
// coincidentally, is always the last one on the buffer cache.
|
|
||||||
while (textures[i+1])
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Jump to the next empty patch entry.
|
|
||||||
while (memcmp(&(textures[i]->patches[j]), &patch, sizeof(patch)))
|
|
||||||
j++;
|
|
||||||
|
|
||||||
patch.wad = wad;
|
|
||||||
// Set the texture number, but only if the lump exists.
|
|
||||||
if ((patch.lump = W_CheckNumForNamePwad(name, wad, 0)) == INT16_MAX)
|
|
||||||
I_Error("readpatch: Missing patch in texture %s", textures[i]->name);
|
|
||||||
|
|
||||||
// note: undoing this patch will be done by other means
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
if (s[0] == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
value = searchvalue(s);
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
// X position of the patch in the texture.
|
|
||||||
if (fastcmp(word, "X"))
|
|
||||||
{
|
|
||||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
|
||||||
patch.originx = (INT16)value;
|
|
||||||
}
|
|
||||||
// Y position of the patch in the texture.
|
|
||||||
else if (fastcmp(word, "Y"))
|
|
||||||
{
|
|
||||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
|
||||||
patch.originy = (INT16)value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("readpatch: unknown word '%s'", word);
|
|
||||||
}
|
|
||||||
} while (!myfeof(f));
|
|
||||||
|
|
||||||
// Error checking.
|
|
||||||
/* // Irrelevant. Origins cannot be unsigned.
|
|
||||||
if (patch.originx == UINT16_MAX)
|
|
||||||
I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name);
|
|
||||||
|
|
||||||
if (patch.originy == UINT16_MAX)
|
|
||||||
I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set the patch as that patch number.
|
|
||||||
textures[i]->patches[j] = patch;
|
|
||||||
|
|
||||||
// Clean up.
|
|
||||||
Z_Free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void readmaincfg(MYFILE *f)
|
static void readmaincfg(MYFILE *f)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
|
@ -3405,30 +3161,17 @@ static void ignorelines(MYFILE *f)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
static void DEH_LoadDehackedFile(MYFILE *f)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
char *word;
|
char *word;
|
||||||
char *word2;
|
char *word2;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
// do a copy of this for cross references probleme
|
|
||||||
//XBOXSTATIC actionf_t saveactions[NUMSTATES];
|
|
||||||
//XBOXSTATIC const char *savesprnames[NUMSPRITES];
|
|
||||||
XBOXSTATIC const char *savesfxnames[NUMSFX];
|
|
||||||
|
|
||||||
if (!deh_loaded)
|
if (!deh_loaded)
|
||||||
initfreeslots();
|
initfreeslots();
|
||||||
|
|
||||||
deh_num_warning = 0;
|
deh_num_warning = 0;
|
||||||
// save values for cross reference
|
|
||||||
/*
|
|
||||||
for (i = 0; i < NUMSTATES; i++)
|
|
||||||
saveactions[i] = states[i].action;
|
|
||||||
for (i = 0; i < NUMSPRITES; i++)
|
|
||||||
savesprnames[i] = sprnames[i];
|
|
||||||
*/
|
|
||||||
for (i = 0; i < NUMSFX; i++)
|
|
||||||
savesfxnames[i] = S_sfx[i].name;
|
|
||||||
|
|
||||||
gamedataadded = false;
|
gamedataadded = false;
|
||||||
|
|
||||||
|
@ -3505,19 +3248,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
if (word2[strlen(word2)-1] == '\n')
|
if (word2[strlen(word2)-1] == '\n')
|
||||||
word2[strlen(word2)-1] = '\0';
|
word2[strlen(word2)-1] = '\0';
|
||||||
i = atoi(word2);
|
i = atoi(word2);
|
||||||
if (fastcmp(word, "TEXTURE"))
|
if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||||
{
|
|
||||||
// Read texture from spec file.
|
|
||||||
readtexture(f, word2);
|
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
|
||||||
}
|
|
||||||
else if (fastcmp(word, "PATCH"))
|
|
||||||
{
|
|
||||||
// Read patch from spec file.
|
|
||||||
readpatch(f, word2, wad);
|
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
|
||||||
}
|
|
||||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_mobjtype(word2); // find a thing by name
|
i = get_mobjtype(word2); // find a thing by name
|
||||||
|
@ -3530,10 +3261,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
/* else if (fastcmp(word, "ANIMTEX"))
|
|
||||||
{
|
|
||||||
readAnimTex(f, i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "LIGHT"))
|
else if (fastcmp(word, "LIGHT"))
|
||||||
{
|
{
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
@ -3605,34 +3332,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
// <Callum> Added translations to this just in case its re-enabled
|
|
||||||
/* else if (fastcmp(word, "POINTER"))
|
|
||||||
{
|
|
||||||
word = strtok(NULL, " "); // get frame
|
|
||||||
word = strtok(NULL, ")");
|
|
||||||
if (word)
|
|
||||||
{
|
|
||||||
i = atoi(word);
|
|
||||||
if (i < NUMSTATES && i >= 0)
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
states[i].action = saveactions[searchvalue(s)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deh_warning("Pointer: Frame %d doesn't exist", i);
|
|
||||||
ignorelines(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "SOUND"))
|
else if (fastcmp(word, "SOUND"))
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_sfx(word2); // find a sound by name
|
i = get_sfx(word2); // find a sound by name
|
||||||
if (i < NUMSFX && i > 0)
|
if (i < NUMSFX && i > 0)
|
||||||
readsound(f, i, savesfxnames);
|
readsound(f, i);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
||||||
|
@ -3640,26 +3345,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
/* else if (fastcmp(word, "SPRITE"))
|
|
||||||
{
|
|
||||||
if (i < NUMSPRITES && i >= 0)
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
INT32 k;
|
|
||||||
k = (searchvalue(s) - 151328)/8;
|
|
||||||
if (k >= 0 && k < NUMSPRITES)
|
|
||||||
sprnames[i] = savesprnames[k];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deh_warning("Sprite %d: offset out of bounds", i);
|
|
||||||
ignorelines(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("Sprite %d doesn't exist",i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "HUDITEM"))
|
else if (fastcmp(word, "HUDITEM"))
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
|
@ -3746,7 +3431,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
// no undo support for this insanity yet
|
// no undo support for this insanity yet
|
||||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "SRB2"))
|
// Last I heard this crashes the game if you try to use it
|
||||||
|
// so this is disabled for now
|
||||||
|
// -- Monster Iestyn
|
||||||
|
/* else if (fastcmp(word, "SRB2"))
|
||||||
{
|
{
|
||||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||||
if (ver != PATCHVERSION)
|
if (ver != PATCHVERSION)
|
||||||
|
@ -3757,6 +3445,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
// Unless you REALLY want to piss people off,
|
// Unless you REALLY want to piss people off,
|
||||||
// define a custom gamedata /before/ doing this!!
|
// define a custom gamedata /before/ doing this!!
|
||||||
// (then again, modifiedgame will prevent game data saving anyway)
|
// (then again, modifiedgame will prevent game data saving anyway)
|
||||||
|
*/
|
||||||
else if (fastcmp(word, "CLEAR"))
|
else if (fastcmp(word, "CLEAR"))
|
||||||
{
|
{
|
||||||
boolean clearall = (fastcmp(word2, "ALL"));
|
boolean clearall = (fastcmp(word2, "ALL"));
|
||||||
|
@ -3830,7 +3519,7 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
||||||
W_ReadLumpPwad(wad, lump, f.data);
|
W_ReadLumpPwad(wad, lump, f.data);
|
||||||
f.curpos = f.data;
|
f.curpos = f.data;
|
||||||
f.data[f.size] = 0;
|
f.data[f.size] = 0;
|
||||||
DEH_LoadDehackedFile(&f, wad);
|
DEH_LoadDehackedFile(&f);
|
||||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||||
Z_Free(f.data);
|
Z_Free(f.data);
|
||||||
}
|
}
|
||||||
|
@ -4838,12 +4527,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
// Individual Team Rings
|
// Individual Team Rings
|
||||||
"S_TEAMRING",
|
"S_TEAMRING",
|
||||||
|
|
||||||
// Special Stage Token
|
|
||||||
"S_EMMY",
|
|
||||||
|
|
||||||
// Special Stage Token
|
// Special Stage Token
|
||||||
"S_TOKEN",
|
"S_TOKEN",
|
||||||
"S_MOVINGTOKEN",
|
|
||||||
|
|
||||||
// CTF Flags
|
// CTF Flags
|
||||||
"S_REDFLAG",
|
"S_REDFLAG",
|
||||||
|
@ -4994,6 +4679,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_SPIKED1",
|
"S_SPIKED1",
|
||||||
"S_SPIKED2",
|
"S_SPIKED2",
|
||||||
|
|
||||||
|
// Wall spikes
|
||||||
|
"S_WALLSPIKE1",
|
||||||
|
"S_WALLSPIKE2",
|
||||||
|
"S_WALLSPIKE3",
|
||||||
|
"S_WALLSPIKE4",
|
||||||
|
"S_WALLSPIKE5",
|
||||||
|
"S_WALLSPIKE6",
|
||||||
|
"S_WALLSPIKEBASE",
|
||||||
|
"S_WALLSPIKED1",
|
||||||
|
"S_WALLSPIKED2",
|
||||||
|
|
||||||
// Starpost
|
// Starpost
|
||||||
"S_STARPOST_IDLE",
|
"S_STARPOST_IDLE",
|
||||||
"S_STARPOST_FLASH",
|
"S_STARPOST_FLASH",
|
||||||
|
@ -5180,6 +4876,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_DEMONFIRE5",
|
"S_DEMONFIRE5",
|
||||||
"S_DEMONFIRE6",
|
"S_DEMONFIRE6",
|
||||||
|
|
||||||
|
// GFZ flowers
|
||||||
"S_GFZFLOWERA",
|
"S_GFZFLOWERA",
|
||||||
"S_GFZFLOWERB",
|
"S_GFZFLOWERB",
|
||||||
"S_GFZFLOWERC",
|
"S_GFZFLOWERC",
|
||||||
|
@ -5187,6 +4884,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_BERRYBUSH",
|
"S_BERRYBUSH",
|
||||||
"S_BUSH",
|
"S_BUSH",
|
||||||
|
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
"S_GFZTREE",
|
||||||
|
"S_GFZBERRYTREE",
|
||||||
|
"S_GFZCHERRYTREE",
|
||||||
|
"S_CHECKERTREE",
|
||||||
|
"S_CHECKERSUNSETTREE",
|
||||||
|
"S_FHZTREE", // Frozen Hillside
|
||||||
|
"S_FHZPINKTREE",
|
||||||
|
"S_POLYGONTREE",
|
||||||
|
"S_BUSHTREE",
|
||||||
|
"S_BUSHREDTREE",
|
||||||
|
|
||||||
// THZ Plant
|
// THZ Plant
|
||||||
"S_THZFLOWERA",
|
"S_THZFLOWERA",
|
||||||
"S_THZFLOWERB",
|
"S_THZFLOWERB",
|
||||||
|
@ -5248,18 +4957,62 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_SLING1",
|
"S_SLING1",
|
||||||
"S_SLING2",
|
"S_SLING2",
|
||||||
|
|
||||||
// CEZ Small Mace Chain
|
// CEZ maces and chains
|
||||||
"S_SMALLMACECHAIN",
|
"S_SMALLMACECHAIN",
|
||||||
|
|
||||||
// CEZ Big Mace Chain
|
|
||||||
"S_BIGMACECHAIN",
|
"S_BIGMACECHAIN",
|
||||||
|
|
||||||
// CEZ Small Mace
|
|
||||||
"S_SMALLMACE",
|
"S_SMALLMACE",
|
||||||
|
|
||||||
// CEZ Big Mace
|
|
||||||
"S_BIGMACE",
|
"S_BIGMACE",
|
||||||
|
|
||||||
|
// Yellow spring on a ball
|
||||||
|
"S_YELLOWSPRINGBALL",
|
||||||
|
"S_YELLOWSPRINGBALL2",
|
||||||
|
"S_YELLOWSPRINGBALL3",
|
||||||
|
"S_YELLOWSPRINGBALL4",
|
||||||
|
"S_YELLOWSPRINGBALL5",
|
||||||
|
|
||||||
|
// Red spring on a ball
|
||||||
|
"S_REDSPRINGBALL",
|
||||||
|
"S_REDSPRINGBALL2",
|
||||||
|
"S_REDSPRINGBALL3",
|
||||||
|
"S_REDSPRINGBALL4",
|
||||||
|
"S_REDSPRINGBALL5",
|
||||||
|
|
||||||
|
// Small Firebar
|
||||||
|
"S_SMALLFIREBAR1",
|
||||||
|
"S_SMALLFIREBAR2",
|
||||||
|
"S_SMALLFIREBAR3",
|
||||||
|
"S_SMALLFIREBAR4",
|
||||||
|
"S_SMALLFIREBAR5",
|
||||||
|
"S_SMALLFIREBAR6",
|
||||||
|
"S_SMALLFIREBAR7",
|
||||||
|
"S_SMALLFIREBAR8",
|
||||||
|
"S_SMALLFIREBAR9",
|
||||||
|
"S_SMALLFIREBAR10",
|
||||||
|
"S_SMALLFIREBAR11",
|
||||||
|
"S_SMALLFIREBAR12",
|
||||||
|
"S_SMALLFIREBAR13",
|
||||||
|
"S_SMALLFIREBAR14",
|
||||||
|
"S_SMALLFIREBAR15",
|
||||||
|
"S_SMALLFIREBAR16",
|
||||||
|
|
||||||
|
// Big Firebar
|
||||||
|
"S_BIGFIREBAR1",
|
||||||
|
"S_BIGFIREBAR2",
|
||||||
|
"S_BIGFIREBAR3",
|
||||||
|
"S_BIGFIREBAR4",
|
||||||
|
"S_BIGFIREBAR5",
|
||||||
|
"S_BIGFIREBAR6",
|
||||||
|
"S_BIGFIREBAR7",
|
||||||
|
"S_BIGFIREBAR8",
|
||||||
|
"S_BIGFIREBAR9",
|
||||||
|
"S_BIGFIREBAR10",
|
||||||
|
"S_BIGFIREBAR11",
|
||||||
|
"S_BIGFIREBAR12",
|
||||||
|
"S_BIGFIREBAR13",
|
||||||
|
"S_BIGFIREBAR14",
|
||||||
|
"S_BIGFIREBAR15",
|
||||||
|
"S_BIGFIREBAR16",
|
||||||
|
|
||||||
"S_CEZFLOWER1",
|
"S_CEZFLOWER1",
|
||||||
|
|
||||||
// Big Tumbleweed
|
// Big Tumbleweed
|
||||||
|
@ -6233,16 +5986,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_NIGHTSWING_XMAS",
|
"S_NIGHTSWING_XMAS",
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
"S_NIGHTSPOWERUP1",
|
"S_NIGHTSSUPERLOOP",
|
||||||
"S_NIGHTSPOWERUP2",
|
"S_NIGHTSDRILLREFILL",
|
||||||
"S_NIGHTSPOWERUP3",
|
"S_NIGHTSHELPER",
|
||||||
"S_NIGHTSPOWERUP4",
|
"S_NIGHTSEXTRATIME",
|
||||||
"S_NIGHTSPOWERUP5",
|
"S_NIGHTSLINKFREEZE",
|
||||||
"S_NIGHTSPOWERUP6",
|
|
||||||
"S_NIGHTSPOWERUP7",
|
|
||||||
"S_NIGHTSPOWERUP8",
|
|
||||||
"S_NIGHTSPOWERUP9",
|
|
||||||
"S_NIGHTSPOWERUP10",
|
|
||||||
"S_EGGCAPSULE",
|
"S_EGGCAPSULE",
|
||||||
|
|
||||||
// Orbiting Chaos Emeralds
|
// Orbiting Chaos Emeralds
|
||||||
|
@ -6439,8 +6187,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_BLUEBALL", // Blue sphere replacement for special stages
|
"MT_BLUEBALL", // Blue sphere replacement for special stages
|
||||||
"MT_REDTEAMRING", //Rings collectable by red team.
|
"MT_REDTEAMRING", //Rings collectable by red team.
|
||||||
"MT_BLUETEAMRING", //Rings collectable by blue team.
|
"MT_BLUETEAMRING", //Rings collectable by blue team.
|
||||||
"MT_EMMY", // emerald token for special stage
|
"MT_TOKEN", // Special Stage Token
|
||||||
"MT_TOKEN", // Special Stage Token (uncollectible part)
|
|
||||||
"MT_REDFLAG", // Red CTF Flag
|
"MT_REDFLAG", // Red CTF Flag
|
||||||
"MT_BLUEFLAG", // Blue CTF Flag
|
"MT_BLUEFLAG", // Blue CTF Flag
|
||||||
"MT_EMBLEM",
|
"MT_EMBLEM",
|
||||||
|
@ -6474,6 +6221,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_SPECIALSPIKEBALL",
|
"MT_SPECIALSPIKEBALL",
|
||||||
"MT_SPINFIRE",
|
"MT_SPINFIRE",
|
||||||
"MT_SPIKE",
|
"MT_SPIKE",
|
||||||
|
"MT_WALLSPIKE",
|
||||||
|
"MT_WALLSPIKEBASE",
|
||||||
"MT_STARPOST",
|
"MT_STARPOST",
|
||||||
"MT_BIGMINE",
|
"MT_BIGMINE",
|
||||||
"MT_BIGAIRMINE",
|
"MT_BIGAIRMINE",
|
||||||
|
@ -6564,6 +6313,17 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_GFZFLOWER3",
|
"MT_GFZFLOWER3",
|
||||||
"MT_BERRYBUSH",
|
"MT_BERRYBUSH",
|
||||||
"MT_BUSH",
|
"MT_BUSH",
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
"MT_GFZTREE",
|
||||||
|
"MT_GFZBERRYTREE",
|
||||||
|
"MT_GFZCHERRYTREE",
|
||||||
|
"MT_CHECKERTREE",
|
||||||
|
"MT_CHECKERSUNSETTREE",
|
||||||
|
"MT_FHZTREE", // Frozen Hillside
|
||||||
|
"MT_FHZPINKTREE",
|
||||||
|
"MT_POLYGONTREE",
|
||||||
|
"MT_BUSHTREE",
|
||||||
|
"MT_BUSHREDTREE",
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
"MT_THZFLOWER1",
|
"MT_THZFLOWER1",
|
||||||
|
@ -6587,14 +6347,20 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
||||||
"MT_FLAMEPARTICLE",
|
"MT_FLAMEPARTICLE",
|
||||||
"MT_EGGSTATUE", // Eggman Statue
|
"MT_EGGSTATUE", // Eggman Statue
|
||||||
"MT_MACEPOINT", // Mace rotation point
|
"MT_MACEPOINT", // Mace rotation point
|
||||||
"MT_SWINGMACEPOINT", // Mace swinging point
|
"MT_CHAINMACEPOINT", // Combination of chains and maces point
|
||||||
"MT_HANGMACEPOINT", // Hangable mace chain
|
"MT_SPRINGBALLPOINT", // Spring ball point
|
||||||
"MT_SPINMACEPOINT", // Spin/Controllable mace chain
|
"MT_CHAINPOINT", // Mace chain
|
||||||
"MT_HIDDEN_SLING", // Spin mace chain (activatable)
|
"MT_HIDDEN_SLING", // Spin mace chain (activatable)
|
||||||
|
"MT_FIREBARPOINT", // Firebar
|
||||||
|
"MT_CUSTOMMACEPOINT", // Custom mace
|
||||||
"MT_SMALLMACECHAIN", // Small Mace Chain
|
"MT_SMALLMACECHAIN", // Small Mace Chain
|
||||||
"MT_BIGMACECHAIN", // Big Mace Chain
|
"MT_BIGMACECHAIN", // Big Mace Chain
|
||||||
"MT_SMALLMACE", // Small Mace
|
"MT_SMALLMACE", // Small Mace
|
||||||
"MT_BIGMACE", // Big Mace
|
"MT_BIGMACE", // Big Mace
|
||||||
|
"MT_YELLOWSPRINGBALL", // Yellow spring on a ball
|
||||||
|
"MT_REDSPRINGBALL", // Red spring on a ball
|
||||||
|
"MT_SMALLFIREBAR", // Small Firebar
|
||||||
|
"MT_BIGFIREBAR", // Big Firebar
|
||||||
"MT_CEZFLOWER",
|
"MT_CEZFLOWER",
|
||||||
|
|
||||||
// Arid Canyon Scenery
|
// Arid Canyon Scenery
|
||||||
|
@ -6947,6 +6713,7 @@ static const char *const MOBJFLAG2_LIST[] = {
|
||||||
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
|
"AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH
|
||||||
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
"LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
||||||
"SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
"SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
||||||
|
"MACEROTATE", // Thinker calls P_MaceRotate around tracer
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7333,6 +7100,7 @@ struct {
|
||||||
{"LF_NOSSMUSIC",LF_NOSSMUSIC},
|
{"LF_NOSSMUSIC",LF_NOSSMUSIC},
|
||||||
{"LF_NORELOAD",LF_NORELOAD},
|
{"LF_NORELOAD",LF_NORELOAD},
|
||||||
{"LF_NOZONE",LF_NOZONE},
|
{"LF_NOZONE",LF_NOZONE},
|
||||||
|
{"LF_SAVEGAME",LF_SAVEGAME},
|
||||||
// And map flags
|
// And map flags
|
||||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||||
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
||||||
|
@ -7465,7 +7233,11 @@ struct {
|
||||||
{"SF_X8AWAYSOUND",SF_X8AWAYSOUND},
|
{"SF_X8AWAYSOUND",SF_X8AWAYSOUND},
|
||||||
{"SF_NOINTERRUPT",SF_NOINTERRUPT},
|
{"SF_NOINTERRUPT",SF_NOINTERRUPT},
|
||||||
{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
|
{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
|
||||||
|
|
||||||
|
// Global emblem var flags
|
||||||
|
{"GE_NIGHTSPULL",GE_NIGHTSPULL},
|
||||||
|
{"GE_NIGHTSITEM",GE_NIGHTSITEM},
|
||||||
|
|
||||||
// Map emblem var flags
|
// Map emblem var flags
|
||||||
{"ME_ALLEMERALDS",ME_ALLEMERALDS},
|
{"ME_ALLEMERALDS",ME_ALLEMERALDS},
|
||||||
{"ME_ULTIMATE",ME_ULTIMATE},
|
{"ME_ULTIMATE",ME_ULTIMATE},
|
||||||
|
@ -8147,11 +7919,14 @@ void FUNCMATH DEH_Check(void)
|
||||||
static inline int lib_freeslot(lua_State *L)
|
static inline int lib_freeslot(lua_State *L)
|
||||||
{
|
{
|
||||||
int n = lua_gettop(L);
|
int n = lua_gettop(L);
|
||||||
int r = 0; // args returned
|
int r = 0; // args returned
|
||||||
char *s, *type,*word;
|
char *s, *type,*word;
|
||||||
|
|
||||||
while (n-- > 0)
|
if (!lua_lumploading)
|
||||||
{
|
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||||
|
|
||||||
|
while (n-- > 0)
|
||||||
|
{
|
||||||
s = Z_StrDup(luaL_checkstring(L,1));
|
s = Z_StrDup(luaL_checkstring(L,1));
|
||||||
type = strtok(s, "_");
|
type = strtok(s, "_");
|
||||||
if (type)
|
if (type)
|
||||||
|
|
|
@ -546,6 +546,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
/// Hudname padding.
|
/// Hudname padding.
|
||||||
#define SKINNAMEPADDING
|
#define SKINNAMEPADDING
|
||||||
|
|
||||||
|
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
|
||||||
|
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
|
||||||
|
/// on the bright side it fixes some weird issues with translucent walls
|
||||||
|
/// \note SRB2CB port.
|
||||||
|
/// SRB2CB itself ported this from PrBoom+
|
||||||
|
#define NEWCLIP
|
||||||
|
|
||||||
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
|
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
|
||||||
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
||||||
//#define SECTORSPECIALSAFTERTHINK
|
//#define SECTORSPECIALSAFTERTHINK
|
||||||
|
|
|
@ -41,7 +41,8 @@ extern INT16 maptol;
|
||||||
extern UINT8 globalweather;
|
extern UINT8 globalweather;
|
||||||
extern INT32 curWeather;
|
extern INT32 curWeather;
|
||||||
extern INT32 cursaveslot;
|
extern INT32 cursaveslot;
|
||||||
extern INT16 lastmapsaved;
|
//extern INT16 lastmapsaved;
|
||||||
|
extern INT16 lastmaploaded;
|
||||||
extern boolean gamecomplete;
|
extern boolean gamecomplete;
|
||||||
|
|
||||||
#define PRECIP_NONE 0
|
#define PRECIP_NONE 0
|
||||||
|
@ -263,6 +264,7 @@ typedef struct
|
||||||
#define LF_NOSSMUSIC 4 ///< Disable Super Sonic music
|
#define LF_NOSSMUSIC 4 ///< Disable Super Sonic music
|
||||||
#define LF_NORELOAD 8 ///< Don't reload level on death
|
#define LF_NORELOAD 8 ///< Don't reload level on death
|
||||||
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
|
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
|
||||||
|
#define LF_SAVEGAME 32 ///< Save the game upon loading this level
|
||||||
|
|
||||||
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
|
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
|
||||||
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen
|
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen
|
||||||
|
|
335
src/filesrch.c
335
src/filesrch.c
|
@ -31,6 +31,8 @@
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
#include "m_menu.h" // Addons_option_Onchange
|
||||||
|
|
||||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||||
|
|
||||||
|
@ -255,6 +257,28 @@ readdir (DIR * dirp)
|
||||||
return (struct dirent *) 0;
|
return (struct dirent *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rewinddir
|
||||||
|
*
|
||||||
|
* Makes the next readdir start from the beginning.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rewinddir (DIR * dirp)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* Check for valid DIR struct. */
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirp->dd_stat = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* closedir
|
* closedir
|
||||||
*
|
*
|
||||||
|
@ -285,6 +309,35 @@ closedir (DIR * dirp)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, {2, "SRB2 Folder"},*/ {3, "CUSTOM"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
char menupath[1024];
|
||||||
|
size_t menupathindex[menudepth];
|
||||||
|
size_t menudepthleft = menudepth;
|
||||||
|
|
||||||
|
char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
char **dirmenu;
|
||||||
|
size_t sizedirmenu;
|
||||||
|
size_t dir_on[menudepth];
|
||||||
|
UINT8 refreshdirmenu = 0;
|
||||||
|
|
||||||
|
size_t packetsizetally = 0;
|
||||||
|
size_t mainwadstally = 0;
|
||||||
|
|
||||||
#if defined (_XBOX) && defined (_MSC_VER)
|
#if defined (_XBOX) && defined (_MSC_VER)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
@ -296,6 +349,13 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
completepath = false;
|
completepath = false;
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined (_WIN32_WCE)
|
#elif defined (_WIN32_WCE)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
@ -346,6 +406,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
#endif
|
#endif
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||||
{
|
{
|
||||||
|
@ -387,25 +453,29 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
{
|
{
|
||||||
searchpath[searchpathindex[depthleft]]=0;
|
searchpath[searchpathindex[depthleft]]=0;
|
||||||
dent = readdir(dirhandle[depthleft]);
|
dent = readdir(dirhandle[depthleft]);
|
||||||
if (dent)
|
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
|
|
||||||
if (!dent)
|
if (!dent)
|
||||||
|
{
|
||||||
closedir(dirhandle[depthleft++]);
|
closedir(dirhandle[depthleft++]);
|
||||||
else if (dent->d_name[0]=='.' &&
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dent->d_name[0]=='.' &&
|
||||||
(dent->d_name[1]=='\0' ||
|
(dent->d_name[1]=='\0' ||
|
||||||
(dent->d_name[1]=='.' &&
|
(dent->d_name[1]=='.' &&
|
||||||
dent->d_name[2]=='\0')))
|
dent->d_name[2]=='\0')))
|
||||||
{
|
{
|
||||||
// we don't want to scan uptree
|
// we don't want to scan uptree
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
|
||||||
{
|
// okay, now we actually want searchpath to incorporate d_name
|
||||||
// was the file (re)moved? can't stat it
|
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||||
}
|
|
||||||
|
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
||||||
{
|
{
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||||
dirhandle[depthleft] = opendir(searchpath);
|
dirhandle[depthleft] = opendir(searchpath);
|
||||||
if (!dirhandle[depthleft])
|
if (!dirhandle[depthleft])
|
||||||
|
@ -444,6 +514,255 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
free(searchname);
|
free(searchname);
|
||||||
free(searchpathindex);
|
free(searchpathindex);
|
||||||
free(dirhandle);
|
free(dirhandle);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char exttable[NUM_EXT_TABLE][5] = {
|
||||||
|
".txt", ".cfg", // exec
|
||||||
|
".wad", ".soc", ".lua"}; // addfile
|
||||||
|
|
||||||
|
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||||
|
|
||||||
|
|
||||||
|
static boolean filemenusearch(char *haystack, char *needle)
|
||||||
|
{
|
||||||
|
static char localhaystack[128];
|
||||||
|
strlcpy(localhaystack, haystack, 128);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localhaystack);
|
||||||
|
return ((cv_addons_search_type.value)
|
||||||
|
? (strstr(localhaystack, needle) != 0)
|
||||||
|
: (!strncmp(localhaystack, needle, menusearch[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\
|
||||||
|
{\
|
||||||
|
rejected++;\
|
||||||
|
continue;\
|
||||||
|
}\
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
DIR *dirhandle;
|
||||||
|
struct dirent *dent;
|
||||||
|
struct stat fsstat;
|
||||||
|
size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0;
|
||||||
|
char *tempname = NULL;
|
||||||
|
boolean noresults = false;
|
||||||
|
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||||
|
|
||||||
|
if (samedepth)
|
||||||
|
{
|
||||||
|
if (dirmenu && dirmenu[dir_on[menudepthleft]])
|
||||||
|
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
|
||||||
|
}
|
||||||
|
else
|
||||||
|
menusearch[0] = menusearch[1] = 0; // clear search
|
||||||
|
|
||||||
|
for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[sizedirmenu-1]);
|
||||||
|
dirmenu[sizedirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirhandle = opendir(menupath))) // get directory
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (menusearch[0])
|
||||||
|
{
|
||||||
|
strcpy(localmenusearch, menusearch+1);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localmenusearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!cv_addons_showall.value)
|
||||||
|
{
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext;
|
||||||
|
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||||
|
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
||||||
|
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
|
||||||
|
}
|
||||||
|
searchdir;
|
||||||
|
}
|
||||||
|
else // directory
|
||||||
|
{
|
||||||
|
searchdir;
|
||||||
|
numfolders++;
|
||||||
|
}
|
||||||
|
sizedirmenu++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rejected && !sizedirmenu)
|
||||||
|
{
|
||||||
|
if (tempname)
|
||||||
|
Z_Free(tempname);
|
||||||
|
closedir(dirhandle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((noresults = (menusearch[0] && !sizedirmenu)))
|
||||||
|
|| (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry
|
||||||
|
{
|
||||||
|
sizedirmenu++;
|
||||||
|
numfolders++;
|
||||||
|
folderpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
|
||||||
|
{
|
||||||
|
closedir(dirhandle); // just in case
|
||||||
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
rejected = 0;
|
||||||
|
rewinddir(dirhandle);
|
||||||
|
|
||||||
|
while ((pos+folderpos) < sizedirmenu)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
char *temp;
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext = EXT_FOLDER;
|
||||||
|
UINT8 folder;
|
||||||
|
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention
|
||||||
|
for (; ext < NUM_EXT_TABLE; ext++)
|
||||||
|
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
|
||||||
|
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
|
||||||
|
ext += EXT_START; // moving to be appropriate position
|
||||||
|
|
||||||
|
searchdir;
|
||||||
|
|
||||||
|
if (ext >= EXT_LOADSTART)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
{
|
||||||
|
if (!filenamebuf[i][0])
|
||||||
|
{
|
||||||
|
strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH);
|
||||||
|
filenamebuf[i][MAX_WADPATH - 1] = '\0';
|
||||||
|
nameonly(filenamebuf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dent->d_name, filenamebuf[i]))
|
||||||
|
continue;
|
||||||
|
if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ext == EXT_TXT)
|
||||||
|
{
|
||||||
|
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(dent->d_name, configfile))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
|
||||||
|
folder = 0;
|
||||||
|
}
|
||||||
|
else // directory
|
||||||
|
{
|
||||||
|
searchdir;
|
||||||
|
len += (folder = 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL)))
|
||||||
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
|
temp[DIR_TYPE] = ext;
|
||||||
|
temp[DIR_LEN] = (UINT8)(len);
|
||||||
|
strlcpy(temp+DIR_STRING, dent->d_name, len);
|
||||||
|
if (folder)
|
||||||
|
{
|
||||||
|
strcpy(temp+len, "/");
|
||||||
|
dirmenu[folderpos++] = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dirmenu[numfolders + pos++] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dirhandle);
|
||||||
|
|
||||||
|
if (noresults) // no results
|
||||||
|
dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS));
|
||||||
|
else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry
|
||||||
|
dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP));
|
||||||
|
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
|
||||||
|
|
||||||
|
if (tempname)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < sizedirmenu; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Z_Free(tempname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizedirmenu)
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (dir_on[menudepthleft] >= sizedirmenu)
|
||||||
|
dir_on[menudepthleft] = sizedirmenu-1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
|
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||||
|
|
||||||
|
extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type;
|
||||||
|
|
||||||
/** \brief The filesearch function
|
/** \brief The filesearch function
|
||||||
|
|
||||||
|
@ -25,4 +28,64 @@
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth);
|
boolean completepath, int maxsearchdepth);
|
||||||
|
|
||||||
|
#define menudepth 20
|
||||||
|
|
||||||
|
extern char menupath[1024];
|
||||||
|
extern size_t menupathindex[menudepth];
|
||||||
|
extern size_t menudepthleft;
|
||||||
|
|
||||||
|
extern char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
extern char **dirmenu;
|
||||||
|
extern size_t sizedirmenu;
|
||||||
|
extern size_t dir_on[menudepth];
|
||||||
|
extern UINT8 refreshdirmenu;
|
||||||
|
|
||||||
|
extern size_t packetsizetally;
|
||||||
|
extern size_t mainwadstally;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
EXT_FOLDER = 0,
|
||||||
|
EXT_UP,
|
||||||
|
EXT_NORESULTS,
|
||||||
|
EXT_START,
|
||||||
|
EXT_TXT = EXT_START,
|
||||||
|
EXT_CFG,
|
||||||
|
EXT_LOADSTART,
|
||||||
|
EXT_WAD = EXT_LOADSTART,
|
||||||
|
EXT_SOC,
|
||||||
|
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||||
|
NUM_EXT,
|
||||||
|
NUM_EXT_TABLE = NUM_EXT-EXT_START,
|
||||||
|
EXT_LOADED = 0x80
|
||||||
|
/*
|
||||||
|
obviously there can only be 0x7F supported extensions in
|
||||||
|
addons menu because we're cramming this into a char out of
|
||||||
|
laziness/easy memory allocation (what's the difference?)
|
||||||
|
and have stolen a bit to show whether it's loaded or not
|
||||||
|
in practice the size of the data type is probably overkill
|
||||||
|
toast 02/05/17
|
||||||
|
*/
|
||||||
|
} ext_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIR_TYPE = 0,
|
||||||
|
DIR_LEN,
|
||||||
|
DIR_STRING
|
||||||
|
} dirname_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
REFRESHDIR_NORMAL = 1,
|
||||||
|
REFRESHDIR_ADDFILE = 2,
|
||||||
|
REFRESHDIR_WARNING = 4,
|
||||||
|
REFRESHDIR_ERROR = 8,
|
||||||
|
REFRESHDIR_NOTLOADED = 16,
|
||||||
|
REFRESHDIR_MAX = 32
|
||||||
|
} refreshdir_enum;
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth);
|
||||||
|
|
||||||
#endif // __FILESRCH_H__
|
#endif // __FILESRCH_H__
|
||||||
|
|
|
@ -77,7 +77,8 @@ INT16 maptol;
|
||||||
UINT8 globalweather = 0;
|
UINT8 globalweather = 0;
|
||||||
INT32 curWeather = PRECIP_NONE;
|
INT32 curWeather = PRECIP_NONE;
|
||||||
INT32 cursaveslot = -1; // Auto-save 1p savegame slot
|
INT32 cursaveslot = -1; // Auto-save 1p savegame slot
|
||||||
INT16 lastmapsaved = 0; // Last map we auto-saved at
|
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||||
|
INT16 lastmaploaded = 0; // Last map the game loaded
|
||||||
boolean gamecomplete = false;
|
boolean gamecomplete = false;
|
||||||
|
|
||||||
UINT16 mainwads = 0;
|
UINT16 mainwads = 0;
|
||||||
|
|
|
@ -878,8 +878,8 @@ static void AdjustSegs(void)
|
||||||
count = subsectors[i].numlines;
|
count = subsectors[i].numlines;
|
||||||
lseg = &segs[subsectors[i].firstline];
|
lseg = &segs[subsectors[i].firstline];
|
||||||
p = extrasubsectors[i].planepoly;
|
p = extrasubsectors[i].planepoly;
|
||||||
if (!p)
|
//if (!p)
|
||||||
continue;
|
//continue;
|
||||||
for (; count--; lseg++)
|
for (; count--; lseg++)
|
||||||
{
|
{
|
||||||
float distv1,distv2,tmp;
|
float distv1,distv2,tmp;
|
||||||
|
@ -892,29 +892,31 @@ static void AdjustSegs(void)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (j = 0; j < p->numpts; j++)
|
if (p) {
|
||||||
{
|
for (j = 0; j < p->numpts; j++)
|
||||||
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
|
|
||||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
|
|
||||||
distv1 = distv1*distv1+tmp*tmp;
|
|
||||||
if (distv1 <= nearv1)
|
|
||||||
{
|
{
|
||||||
v1found = j;
|
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
|
||||||
nearv1 = distv1;
|
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
|
||||||
}
|
distv1 = distv1*distv1+tmp*tmp;
|
||||||
// the same with v2
|
if (distv1 <= nearv1)
|
||||||
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
|
{
|
||||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
|
v1found = j;
|
||||||
distv2 = distv2*distv2+tmp*tmp;
|
nearv1 = distv1;
|
||||||
if (distv2 <= nearv2)
|
}
|
||||||
{
|
// the same with v2
|
||||||
v2found = j;
|
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
|
||||||
nearv2 = distv2;
|
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
|
||||||
|
distv2 = distv2*distv2+tmp*tmp;
|
||||||
|
if (distv2 <= nearv2)
|
||||||
|
{
|
||||||
|
v2found = j;
|
||||||
|
nearv2 = distv2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nearv1 <= NEARDIST*NEARDIST)
|
if (p && nearv1 <= NEARDIST*NEARDIST)
|
||||||
// share vertice with segs
|
// share vertice with segs
|
||||||
lseg->v1 = (vertex_t *)&(p->pts[v1found]);
|
lseg->pv1 = &(p->pts[v1found]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// BP: here we can do better, using PointInSeg and compute
|
// BP: here we can do better, using PointInSeg and compute
|
||||||
|
@ -925,24 +927,24 @@ static void AdjustSegs(void)
|
||||||
polyvertex_t *pv = HWR_AllocVertex();
|
polyvertex_t *pv = HWR_AllocVertex();
|
||||||
pv->x = FIXED_TO_FLOAT(lseg->v1->x);
|
pv->x = FIXED_TO_FLOAT(lseg->v1->x);
|
||||||
pv->y = FIXED_TO_FLOAT(lseg->v1->y);
|
pv->y = FIXED_TO_FLOAT(lseg->v1->y);
|
||||||
lseg->v1 = (vertex_t *)pv;
|
lseg->pv1 = pv;
|
||||||
}
|
}
|
||||||
if (nearv2 <= NEARDIST*NEARDIST)
|
if (p && nearv2 <= NEARDIST*NEARDIST)
|
||||||
lseg->v2 = (vertex_t *)&(p->pts[v2found]);
|
lseg->pv2 = &(p->pts[v2found]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
polyvertex_t *pv = HWR_AllocVertex();
|
polyvertex_t *pv = HWR_AllocVertex();
|
||||||
pv->x = FIXED_TO_FLOAT(lseg->v2->x);
|
pv->x = FIXED_TO_FLOAT(lseg->v2->x);
|
||||||
pv->y = FIXED_TO_FLOAT(lseg->v2->y);
|
pv->y = FIXED_TO_FLOAT(lseg->v2->y);
|
||||||
lseg->v2 = (vertex_t *)pv;
|
lseg->pv2 = pv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recompute length
|
// recompute length
|
||||||
{
|
{
|
||||||
float x,y;
|
float x,y;
|
||||||
x = ((polyvertex_t *)lseg->v2)->x - ((polyvertex_t *)lseg->v1)->x
|
x = ((polyvertex_t *)lseg->pv2)->x - ((polyvertex_t *)lseg->pv1)->x
|
||||||
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
||||||
y = ((polyvertex_t *)lseg->v2)->y - ((polyvertex_t *)lseg->v1)->y
|
y = ((polyvertex_t *)lseg->pv2)->y - ((polyvertex_t *)lseg->pv1)->y
|
||||||
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
||||||
lseg->flength = (float)hypot(x, y);
|
lseg->flength = (float)hypot(x, y);
|
||||||
// BP: debug see this kind of segs
|
// BP: debug see this kind of segs
|
||||||
|
|
|
@ -0,0 +1,465 @@
|
||||||
|
/* Emacs style mode select -*- C++ -*-
|
||||||
|
*-----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
|
||||||
|
* based on BOOM, a modified and improved DOOM engine
|
||||||
|
* Copyright (C) 1999 by
|
||||||
|
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
||||||
|
* Copyright (C) 1999-2000 by
|
||||||
|
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
||||||
|
* Copyright 2005, 2006 by
|
||||||
|
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
*---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
** gl_clipper.cpp
|
||||||
|
**
|
||||||
|
** Handles visibility checks.
|
||||||
|
** Loosely based on the JDoom clipper.
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2003 Tim Stump
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "../v_video.h"
|
||||||
|
#include "hw_clip.h"
|
||||||
|
#include "hw_glob.h"
|
||||||
|
#include "../r_state.h"
|
||||||
|
#include "../tables.h"
|
||||||
|
#include "r_opengl/r_opengl.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SPHEREFRUSTRUM
|
||||||
|
static GLdouble viewMatrix[16];
|
||||||
|
static GLdouble projMatrix[16];
|
||||||
|
float frustum[6][4];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct clipnode_s
|
||||||
|
{
|
||||||
|
struct clipnode_s *prev, *next;
|
||||||
|
angle_t start, end;
|
||||||
|
} clipnode_t;
|
||||||
|
|
||||||
|
clipnode_t *freelist;
|
||||||
|
clipnode_t *clipnodes;
|
||||||
|
clipnode_t *cliphead;
|
||||||
|
|
||||||
|
static clipnode_t * gld_clipnode_GetNew(void);
|
||||||
|
static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end);
|
||||||
|
static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle);
|
||||||
|
static void gld_clipper_AddClipRange(angle_t start, angle_t end);
|
||||||
|
static void gld_clipper_RemoveRange(clipnode_t * range);
|
||||||
|
static void gld_clipnode_Free(clipnode_t *node);
|
||||||
|
|
||||||
|
static clipnode_t * gld_clipnode_GetNew(void)
|
||||||
|
{
|
||||||
|
if (freelist)
|
||||||
|
{
|
||||||
|
clipnode_t * p = freelist;
|
||||||
|
freelist = p->next;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (clipnode_t*)malloc(sizeof(clipnode_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static clipnode_t * gld_clipnode_NewRange(angle_t start, angle_t end)
|
||||||
|
{
|
||||||
|
clipnode_t * c = gld_clipnode_GetNew();
|
||||||
|
c->start = start;
|
||||||
|
c->end = end;
|
||||||
|
c->next = c->prev=NULL;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle)
|
||||||
|
{
|
||||||
|
if(startAngle > endAngle)
|
||||||
|
{
|
||||||
|
return (gld_clipper_IsRangeVisible(startAngle, ANGLE_MAX) || gld_clipper_IsRangeVisible(0, endAngle));
|
||||||
|
}
|
||||||
|
|
||||||
|
return gld_clipper_IsRangeVisible(startAngle, endAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean gld_clipper_IsRangeVisible(angle_t startAngle, angle_t endAngle)
|
||||||
|
{
|
||||||
|
clipnode_t *ci;
|
||||||
|
ci = cliphead;
|
||||||
|
|
||||||
|
if (endAngle == 0 && ci && ci->start == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (ci != NULL && ci->start < endAngle)
|
||||||
|
{
|
||||||
|
if (startAngle >= ci->start && endAngle <= ci->end)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ci = ci->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gld_clipnode_Free(clipnode_t *node)
|
||||||
|
{
|
||||||
|
node->next = freelist;
|
||||||
|
freelist = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gld_clipper_RemoveRange(clipnode_t *range)
|
||||||
|
{
|
||||||
|
if (range == cliphead)
|
||||||
|
{
|
||||||
|
cliphead = cliphead->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (range->prev)
|
||||||
|
{
|
||||||
|
range->prev->next = range->next;
|
||||||
|
}
|
||||||
|
if (range->next)
|
||||||
|
{
|
||||||
|
range->next->prev = range->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gld_clipnode_Free(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle)
|
||||||
|
{
|
||||||
|
if(startangle > endangle)
|
||||||
|
{
|
||||||
|
// The range has to added in two parts.
|
||||||
|
gld_clipper_AddClipRange(startangle, ANGLE_MAX);
|
||||||
|
gld_clipper_AddClipRange(0, endangle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the range as usual.
|
||||||
|
gld_clipper_AddClipRange(startangle, endangle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gld_clipper_AddClipRange(angle_t start, angle_t end)
|
||||||
|
{
|
||||||
|
clipnode_t *node, *temp, *prevNode, *node2, *delnode;
|
||||||
|
|
||||||
|
if (cliphead)
|
||||||
|
{
|
||||||
|
//check to see if range contains any old ranges
|
||||||
|
node = cliphead;
|
||||||
|
while (node != NULL && node->start < end)
|
||||||
|
{
|
||||||
|
if (node->start >= start && node->end <= end)
|
||||||
|
{
|
||||||
|
temp = node;
|
||||||
|
node = node->next;
|
||||||
|
gld_clipper_RemoveRange(temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (node->start <= start && node->end >= end)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check to see if range overlaps a range (or possibly 2)
|
||||||
|
node = cliphead;
|
||||||
|
while (node != NULL && node->start <= end)
|
||||||
|
{
|
||||||
|
if (node->end >= start)
|
||||||
|
{
|
||||||
|
// we found the first overlapping node
|
||||||
|
if (node->start > start)
|
||||||
|
{
|
||||||
|
// the new range overlaps with this node's start point
|
||||||
|
node->start = start;
|
||||||
|
}
|
||||||
|
if (node->end < end)
|
||||||
|
{
|
||||||
|
node->end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
node2 = node->next;
|
||||||
|
while (node2 && node2->start <= node->end)
|
||||||
|
{
|
||||||
|
if (node2->end > node->end)
|
||||||
|
{
|
||||||
|
node->end = node2->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
delnode = node2;
|
||||||
|
node2 = node2->next;
|
||||||
|
gld_clipper_RemoveRange(delnode);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//just add range
|
||||||
|
node = cliphead;
|
||||||
|
prevNode = NULL;
|
||||||
|
temp = gld_clipnode_NewRange(start, end);
|
||||||
|
while (node != NULL && node->start < end)
|
||||||
|
{
|
||||||
|
prevNode = node;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
temp->next = node;
|
||||||
|
if (node == NULL)
|
||||||
|
{
|
||||||
|
temp->prev = prevNode;
|
||||||
|
if (prevNode)
|
||||||
|
{
|
||||||
|
prevNode->next = temp;
|
||||||
|
}
|
||||||
|
if (!cliphead)
|
||||||
|
{
|
||||||
|
cliphead = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (node == cliphead)
|
||||||
|
{
|
||||||
|
cliphead->prev = temp;
|
||||||
|
cliphead = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp->prev = prevNode;
|
||||||
|
prevNode->next = temp;
|
||||||
|
node->prev = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = gld_clipnode_NewRange(start, end);
|
||||||
|
cliphead = temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gld_clipper_Clear(void)
|
||||||
|
{
|
||||||
|
clipnode_t *node = cliphead;
|
||||||
|
clipnode_t *temp;
|
||||||
|
|
||||||
|
while (node != NULL)
|
||||||
|
{
|
||||||
|
temp = node;
|
||||||
|
node = node->next;
|
||||||
|
gld_clipnode_Free(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
cliphead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMUL (1.6f/1.333333f)
|
||||||
|
|
||||||
|
angle_t gld_FrustumAngle(void)
|
||||||
|
{
|
||||||
|
double floatangle;
|
||||||
|
angle_t a1;
|
||||||
|
|
||||||
|
float tilt = (float)fabs(((double)(int)aimingangle) / ANG1);
|
||||||
|
|
||||||
|
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
|
||||||
|
|
||||||
|
float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
|
||||||
|
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
|
||||||
|
float render_multiplier = 64.0f / render_fovratio / RMUL;
|
||||||
|
|
||||||
|
if (tilt > 90.0f)
|
||||||
|
{
|
||||||
|
tilt = 90.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the pitch is larger than this you can look all around at a FOV of 90
|
||||||
|
if (abs(aimingangle) > 46 * ANG1)
|
||||||
|
return 0xffffffff;
|
||||||
|
|
||||||
|
// ok, this is a gross hack that barely works...
|
||||||
|
// but at least it doesn't overestimate too much...
|
||||||
|
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * (float)render_fov * 48.0f / render_multiplier / 90.0f;
|
||||||
|
a1 = ANG1 * (int)floatangle;
|
||||||
|
if (a1 >= ANGLE_180)
|
||||||
|
return 0xffffffff;
|
||||||
|
return a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
|
||||||
|
// compiler complains about (p)glGetDoublev anyway, in case anyone wants this
|
||||||
|
// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
|
||||||
|
// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
|
||||||
|
#ifdef HAVE_SPHEREFRUSTRUM
|
||||||
|
//
|
||||||
|
// gld_FrustrumSetup
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CALCMATRIX(a, b, c, d, e, f, g, h)\
|
||||||
|
(float)(viewMatrix[a] * projMatrix[b] + \
|
||||||
|
viewMatrix[c] * projMatrix[d] + \
|
||||||
|
viewMatrix[e] * projMatrix[f] + \
|
||||||
|
viewMatrix[g] * projMatrix[h])
|
||||||
|
|
||||||
|
#define NORMALIZE_PLANE(i)\
|
||||||
|
t = (float)sqrt(\
|
||||||
|
frustum[i][0] * frustum[i][0] + \
|
||||||
|
frustum[i][1] * frustum[i][1] + \
|
||||||
|
frustum[i][2] * frustum[i][2]); \
|
||||||
|
frustum[i][0] /= t; \
|
||||||
|
frustum[i][1] /= t; \
|
||||||
|
frustum[i][2] /= t; \
|
||||||
|
frustum[i][3] /= t
|
||||||
|
|
||||||
|
void gld_FrustrumSetup(void)
|
||||||
|
{
|
||||||
|
float t;
|
||||||
|
float clip[16];
|
||||||
|
|
||||||
|
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
|
||||||
|
pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);
|
||||||
|
|
||||||
|
clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);
|
||||||
|
clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13);
|
||||||
|
clip[2] = CALCMATRIX(0, 2, 1, 6, 2, 10, 3, 14);
|
||||||
|
clip[3] = CALCMATRIX(0, 3, 1, 7, 2, 11, 3, 15);
|
||||||
|
|
||||||
|
clip[4] = CALCMATRIX(4, 0, 5, 4, 6, 8, 7, 12);
|
||||||
|
clip[5] = CALCMATRIX(4, 1, 5, 5, 6, 9, 7, 13);
|
||||||
|
clip[6] = CALCMATRIX(4, 2, 5, 6, 6, 10, 7, 14);
|
||||||
|
clip[7] = CALCMATRIX(4, 3, 5, 7, 6, 11, 7, 15);
|
||||||
|
|
||||||
|
clip[8] = CALCMATRIX(8, 0, 9, 4, 10, 8, 11, 12);
|
||||||
|
clip[9] = CALCMATRIX(8, 1, 9, 5, 10, 9, 11, 13);
|
||||||
|
clip[10] = CALCMATRIX(8, 2, 9, 6, 10, 10, 11, 14);
|
||||||
|
clip[11] = CALCMATRIX(8, 3, 9, 7, 10, 11, 11, 15);
|
||||||
|
|
||||||
|
clip[12] = CALCMATRIX(12, 0, 13, 4, 14, 8, 15, 12);
|
||||||
|
clip[13] = CALCMATRIX(12, 1, 13, 5, 14, 9, 15, 13);
|
||||||
|
clip[14] = CALCMATRIX(12, 2, 13, 6, 14, 10, 15, 14);
|
||||||
|
clip[15] = CALCMATRIX(12, 3, 13, 7, 14, 11, 15, 15);
|
||||||
|
|
||||||
|
// Right plane
|
||||||
|
frustum[0][0] = clip[ 3] - clip[ 0];
|
||||||
|
frustum[0][1] = clip[ 7] - clip[ 4];
|
||||||
|
frustum[0][2] = clip[11] - clip[ 8];
|
||||||
|
frustum[0][3] = clip[15] - clip[12];
|
||||||
|
NORMALIZE_PLANE(0);
|
||||||
|
|
||||||
|
// Left plane
|
||||||
|
frustum[1][0] = clip[ 3] + clip[ 0];
|
||||||
|
frustum[1][1] = clip[ 7] + clip[ 4];
|
||||||
|
frustum[1][2] = clip[11] + clip[ 8];
|
||||||
|
frustum[1][3] = clip[15] + clip[12];
|
||||||
|
NORMALIZE_PLANE(1);
|
||||||
|
|
||||||
|
// Bottom plane
|
||||||
|
frustum[2][0] = clip[ 3] + clip[ 1];
|
||||||
|
frustum[2][1] = clip[ 7] + clip[ 5];
|
||||||
|
frustum[2][2] = clip[11] + clip[ 9];
|
||||||
|
frustum[2][3] = clip[15] + clip[13];
|
||||||
|
NORMALIZE_PLANE(2);
|
||||||
|
|
||||||
|
// Top plane
|
||||||
|
frustum[3][0] = clip[ 3] - clip[ 1];
|
||||||
|
frustum[3][1] = clip[ 7] - clip[ 5];
|
||||||
|
frustum[3][2] = clip[11] - clip[ 9];
|
||||||
|
frustum[3][3] = clip[15] - clip[13];
|
||||||
|
NORMALIZE_PLANE(3);
|
||||||
|
|
||||||
|
// Far plane
|
||||||
|
frustum[4][0] = clip[ 3] - clip[ 2];
|
||||||
|
frustum[4][1] = clip[ 7] - clip[ 6];
|
||||||
|
frustum[4][2] = clip[11] - clip[10];
|
||||||
|
frustum[4][3] = clip[15] - clip[14];
|
||||||
|
NORMALIZE_PLANE(4);
|
||||||
|
|
||||||
|
// Near plane
|
||||||
|
frustum[5][0] = clip[ 3] + clip[ 2];
|
||||||
|
frustum[5][1] = clip[ 7] + clip[ 6];
|
||||||
|
frustum[5][2] = clip[11] + clip[10];
|
||||||
|
frustum[5][3] = clip[15] + clip[14];
|
||||||
|
NORMALIZE_PLANE(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean gld_SphereInFrustum(float x, float y, float z, float radius)
|
||||||
|
{
|
||||||
|
int p;
|
||||||
|
|
||||||
|
for (p = 0; p < 4; p++)
|
||||||
|
{
|
||||||
|
if (frustum[p][0] * x +
|
||||||
|
frustum[p][1] * y +
|
||||||
|
frustum[p][2] * z +
|
||||||
|
frustum[p][3] <= -radius)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* hw_clip.h
|
||||||
|
* SRB2CB
|
||||||
|
*
|
||||||
|
* PrBoom's OpenGL clipping
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// OpenGL BSP clipping
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../tables.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
//#define HAVE_SPHEREFRUSTRUM // enable if you want gld_SphereInFrustum and related code
|
||||||
|
|
||||||
|
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
|
||||||
|
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
|
||||||
|
void gld_clipper_Clear(void);
|
||||||
|
angle_t gld_FrustumAngle(void);
|
||||||
|
#ifdef HAVE_SPHEREFRUSTRUM
|
||||||
|
void gld_FrustrumSetup(void);
|
||||||
|
boolean gld_SphereInFrustum(float x, float y, float z, float radius);
|
||||||
|
#endif
|
|
@ -78,6 +78,7 @@ typedef struct gr_vissprite_s
|
||||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||||
UINT8 *colormap;
|
UINT8 *colormap;
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
|
float z1, z2;
|
||||||
} gr_vissprite_t;
|
} gr_vissprite_t;
|
||||||
|
|
||||||
// --------
|
// --------
|
||||||
|
|
|
@ -226,8 +226,7 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
// Collectible Items
|
// Collectible Items
|
||||||
&lspr[NOLIGHT], // SPR_RING
|
&lspr[NOLIGHT], // SPR_RING
|
||||||
&lspr[NOLIGHT], // SPR_TRNG
|
&lspr[NOLIGHT], // SPR_TRNG
|
||||||
&lspr[NOLIGHT], // SPR_EMMY
|
&lspr[NOLIGHT], // SPR_TOKE
|
||||||
&lspr[BLUEBALL_L], // SPR_TOKE
|
|
||||||
&lspr[REDBALL_L], // SPR_RFLG
|
&lspr[REDBALL_L], // SPR_RFLG
|
||||||
&lspr[BLUEBALL_L], // SPR_BFLG
|
&lspr[BLUEBALL_L], // SPR_BFLG
|
||||||
&lspr[NOLIGHT], // SPR_NWNG
|
&lspr[NOLIGHT], // SPR_NWNG
|
||||||
|
@ -243,6 +242,8 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_SPIK
|
&lspr[NOLIGHT], // SPR_SPIK
|
||||||
&lspr[NOLIGHT], // SPR_SFLM
|
&lspr[NOLIGHT], // SPR_SFLM
|
||||||
&lspr[NOLIGHT], // SPR_USPK
|
&lspr[NOLIGHT], // SPR_USPK
|
||||||
|
&lspr[NOLIGHT], // SPR_WSPK
|
||||||
|
&lspr[NOLIGHT], // SPR_WSPB
|
||||||
&lspr[NOLIGHT], // SPR_STPT
|
&lspr[NOLIGHT], // SPR_STPT
|
||||||
&lspr[NOLIGHT], // SPR_BMNE
|
&lspr[NOLIGHT], // SPR_BMNE
|
||||||
|
|
||||||
|
@ -293,6 +294,12 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_FWR4
|
&lspr[NOLIGHT], // SPR_FWR4
|
||||||
&lspr[NOLIGHT], // SPR_BUS1
|
&lspr[NOLIGHT], // SPR_BUS1
|
||||||
&lspr[NOLIGHT], // SPR_BUS2
|
&lspr[NOLIGHT], // SPR_BUS2
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
&lspr[NOLIGHT], // SPR_TRE1
|
||||||
|
&lspr[NOLIGHT], // SPR_TRE2
|
||||||
|
&lspr[NOLIGHT], // SPR_TRE3
|
||||||
|
&lspr[NOLIGHT], // SPR_TRE4
|
||||||
|
&lspr[NOLIGHT], // SPR_TRE5
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
&lspr[NOLIGHT], // SPR_THZP
|
&lspr[NOLIGHT], // SPR_THZP
|
||||||
|
@ -316,6 +323,10 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_BMCH
|
&lspr[NOLIGHT], // SPR_BMCH
|
||||||
&lspr[NOLIGHT], // SPR_SMCE
|
&lspr[NOLIGHT], // SPR_SMCE
|
||||||
&lspr[NOLIGHT], // SPR_BMCE
|
&lspr[NOLIGHT], // SPR_BMCE
|
||||||
|
&lspr[NOLIGHT], // SPR_YSPB
|
||||||
|
&lspr[NOLIGHT], // SPR_RSPB
|
||||||
|
&lspr[REDBALL_L], // SPR_SFBR
|
||||||
|
&lspr[REDBALL_L], // SPR_BFBR
|
||||||
|
|
||||||
// Arid Canyon Scenery
|
// Arid Canyon Scenery
|
||||||
&lspr[NOLIGHT], // SPR_BTBL
|
&lspr[NOLIGHT], // SPR_BTBL
|
||||||
|
@ -334,6 +345,8 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_XMS1
|
&lspr[NOLIGHT], // SPR_XMS1
|
||||||
&lspr[NOLIGHT], // SPR_XMS2
|
&lspr[NOLIGHT], // SPR_XMS2
|
||||||
&lspr[NOLIGHT], // SPR_XMS3
|
&lspr[NOLIGHT], // SPR_XMS3
|
||||||
|
&lspr[NOLIGHT], // SPR_XMS4
|
||||||
|
&lspr[NOLIGHT], // SPR_XMS5
|
||||||
|
|
||||||
// Botanic Serenity Scenery
|
// Botanic Serenity Scenery
|
||||||
&lspr[NOLIGHT], // SPR_BSZ1
|
&lspr[NOLIGHT], // SPR_BSZ1
|
||||||
|
@ -345,13 +358,9 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_BSZ7
|
&lspr[NOLIGHT], // SPR_BSZ7
|
||||||
&lspr[NOLIGHT], // SPR_BSZ8
|
&lspr[NOLIGHT], // SPR_BSZ8
|
||||||
|
|
||||||
// Stalagmites
|
// Misc Scenery
|
||||||
&lspr[NOLIGHT], // SPR_STLG
|
&lspr[NOLIGHT], // SPR_STLG
|
||||||
|
|
||||||
// Disco Ball
|
|
||||||
&lspr[NOLIGHT], // SPR_DBAL
|
&lspr[NOLIGHT], // SPR_DBAL
|
||||||
|
|
||||||
// ATZ Red Crystal
|
|
||||||
&lspr[NOLIGHT], // SPR_RCRY
|
&lspr[NOLIGHT], // SPR_RCRY
|
||||||
|
|
||||||
// Powerup Indicators
|
// Powerup Indicators
|
||||||
|
@ -396,8 +405,11 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_SPRB Graue
|
&lspr[NOLIGHT], // SPR_SPRB Graue
|
||||||
&lspr[NOLIGHT], // SPR_YSPR
|
&lspr[NOLIGHT], // SPR_YSPR
|
||||||
&lspr[NOLIGHT], // SPR_RSPR
|
&lspr[NOLIGHT], // SPR_RSPR
|
||||||
|
&lspr[NOLIGHT], // SPR_SSWY
|
||||||
|
&lspr[NOLIGHT], // SPR_SSWR
|
||||||
|
&lspr[NOLIGHT], // SPR_SSWB
|
||||||
|
|
||||||
// Environmentals Effects
|
// Environmental Effects
|
||||||
&lspr[NOLIGHT], // SPR_RAIN
|
&lspr[NOLIGHT], // SPR_RAIN
|
||||||
&lspr[NOLIGHT], // SPR_SNO1
|
&lspr[NOLIGHT], // SPR_SNO1
|
||||||
&lspr[NOLIGHT], // SPR_SPLH
|
&lspr[NOLIGHT], // SPR_SPLH
|
||||||
|
@ -405,6 +417,8 @@ light_t *t_lspr[NUMSPRITES] =
|
||||||
&lspr[NOLIGHT], // SPR_SMOK
|
&lspr[NOLIGHT], // SPR_SMOK
|
||||||
&lspr[NOLIGHT], // SPR_BUBL
|
&lspr[NOLIGHT], // SPR_BUBL
|
||||||
&lspr[RINGLIGHT_L], // SPR_WZAP
|
&lspr[RINGLIGHT_L], // SPR_WZAP
|
||||||
|
&lspr[NOLIGHT], // SPR_DUST
|
||||||
|
&lspr[NOLIGHT], // SPR_FPRT
|
||||||
&lspr[SUPERSPARK_L], // SPR_TFOG
|
&lspr[SUPERSPARK_L], // SPR_TFOG
|
||||||
&lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed
|
&lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed
|
||||||
&lspr[NOLIGHT], // SPR_PRTL
|
&lspr[NOLIGHT], // SPR_PRTL
|
||||||
|
|
|
@ -44,6 +44,10 @@
|
||||||
#endif
|
#endif
|
||||||
#include "hw_md2.h"
|
#include "hw_md2.h"
|
||||||
|
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
#include "hw_clip.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define R_FAKEFLOORS
|
#define R_FAKEFLOORS
|
||||||
#define HWPRECIP
|
#define HWPRECIP
|
||||||
#define SORTING
|
#define SORTING
|
||||||
|
@ -99,8 +103,9 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU
|
||||||
boolean drawsky = true;
|
boolean drawsky = true;
|
||||||
|
|
||||||
// needs fix: walls are incorrectly clipped one column less
|
// needs fix: walls are incorrectly clipped one column less
|
||||||
|
#ifndef NEWCLIP
|
||||||
static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
#endif
|
||||||
//development variables for diverse uses
|
//development variables for diverse uses
|
||||||
static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -323,9 +328,6 @@ static angle_t gr_xtoviewangle[MAXVIDWIDTH+1];
|
||||||
// test change fov when looking up/down but bsp projection messup :(
|
// test change fov when looking up/down but bsp projection messup :(
|
||||||
//#define NOCRAPPYMLOOK
|
//#define NOCRAPPYMLOOK
|
||||||
|
|
||||||
/// \note crappy
|
|
||||||
#define drawtextured true
|
|
||||||
|
|
||||||
// base values set at SetViewSize
|
// base values set at SetViewSize
|
||||||
static float gr_basecentery;
|
static float gr_basecentery;
|
||||||
|
|
||||||
|
@ -641,13 +643,13 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
|
||||||
angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT;
|
angle = FOFsector->floorpic_angle;
|
||||||
}
|
}
|
||||||
else // it's a ceiling
|
else // it's a ceiling
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
|
||||||
angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT;
|
angle = FOFsector->ceilingpic_angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gr_frontsector)
|
else if (gr_frontsector)
|
||||||
|
@ -656,25 +658,19 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
|
||||||
angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT;
|
angle = gr_frontsector->floorpic_angle;
|
||||||
}
|
}
|
||||||
else // it's a ceiling
|
else // it's a ceiling
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
|
||||||
angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT;
|
angle = gr_frontsector->ceilingpic_angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle) // Only needs to be done if there's an altered angle
|
if (angle) // Only needs to be done if there's an altered angle
|
||||||
{
|
{
|
||||||
|
angle = InvAngle(angle)>>ANGLETOFINESHIFT;
|
||||||
// This needs to be done so that it scrolls in a different direction after rotation like software
|
|
||||||
tempxsow = FLOAT_TO_FIXED(scrollx);
|
|
||||||
tempytow = FLOAT_TO_FIXED(scrolly);
|
|
||||||
scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
|
||||||
scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
|
||||||
|
|
||||||
// This needs to be done so everything aligns after rotation
|
// This needs to be done so everything aligns after rotation
|
||||||
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
|
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
|
||||||
tempxsow = FLOAT_TO_FIXED(flatxref);
|
tempxsow = FLOAT_TO_FIXED(flatxref);
|
||||||
|
@ -687,7 +683,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
// Hurdler: add scrolling texture on floor/ceiling
|
// Hurdler: add scrolling texture on floor/ceiling
|
||||||
v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx);
|
v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx);
|
||||||
v3d->tow = (float)(flatyref - (pv->y / fflatsize) + scrolly);
|
v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly);
|
||||||
|
|
||||||
//v3d->sow = (float)(pv->x / fflatsize);
|
//v3d->sow = (float)(pv->x / fflatsize);
|
||||||
//v3d->tow = (float)(pv->y / fflatsize);
|
//v3d->tow = (float)(pv->y / fflatsize);
|
||||||
|
@ -698,7 +694,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
tempxsow = FLOAT_TO_FIXED(v3d->sow);
|
tempxsow = FLOAT_TO_FIXED(v3d->sow);
|
||||||
tempytow = FLOAT_TO_FIXED(v3d->tow);
|
tempytow = FLOAT_TO_FIXED(v3d->tow);
|
||||||
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
||||||
v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle))));
|
v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
||||||
}
|
}
|
||||||
|
|
||||||
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
|
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
|
||||||
|
@ -858,11 +854,11 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
|
||||||
|
|
||||||
M_ClearBox(segbbox);
|
M_ClearBox(segbbox);
|
||||||
M_AddToBox(segbbox,
|
M_AddToBox(segbbox,
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x),
|
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x),
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y));
|
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y));
|
||||||
M_AddToBox(segbbox,
|
M_AddToBox(segbbox,
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x),
|
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x),
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y));
|
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y));
|
||||||
|
|
||||||
splat = (wallsplat_t *)gr_curline->linedef->splats;
|
splat = (wallsplat_t *)gr_curline->linedef->splats;
|
||||||
for (; splat; splat = splat->next)
|
for (; splat; splat = splat->next)
|
||||||
|
@ -1035,6 +1031,7 @@ static void HWR_ProjectWall(wallVert3D * wallVerts,
|
||||||
// (in fact a clipping plane that has a constant, so can clip with simple 2d)
|
// (in fact a clipping plane that has a constant, so can clip with simple 2d)
|
||||||
// with the wall segment
|
// with the wall segment
|
||||||
//
|
//
|
||||||
|
#ifndef NEWCLIP
|
||||||
static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
|
static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
|
||||||
{
|
{
|
||||||
float num, den;
|
float num, den;
|
||||||
|
@ -1063,6 +1060,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
|
||||||
|
|
||||||
return num / den;
|
return num / den;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// HWR_SplitWall
|
// HWR_SplitWall
|
||||||
|
@ -1437,7 +1435,11 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b
|
||||||
// Anything between means the wall segment has been clipped with solidsegs,
|
// Anything between means the wall segment has been clipped with solidsegs,
|
||||||
// reducing wall overdraw to a minimum
|
// reducing wall overdraw to a minimum
|
||||||
//
|
//
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
|
#else
|
||||||
static void HWR_StoreWallRange(double startfrac, double endfrac)
|
static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
wallVert3D wallVerts[4];
|
wallVert3D wallVerts[4];
|
||||||
v2d_t vs, ve; // start, end vertices of 2d line (view from above)
|
v2d_t vs, ve; // start, end vertices of 2d line (view from above)
|
||||||
|
@ -1462,16 +1464,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
extracolormap_t *colormap;
|
extracolormap_t *colormap;
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
|
|
||||||
|
#ifndef NEWCLIP
|
||||||
if (startfrac > endfrac)
|
if (startfrac > endfrac)
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
gr_sidedef = gr_curline->sidedef;
|
gr_sidedef = gr_curline->sidedef;
|
||||||
gr_linedef = gr_curline->linedef;
|
gr_linedef = gr_curline->linedef;
|
||||||
|
|
||||||
vs.x = ((polyvertex_t *)gr_curline->v1)->x;
|
vs.x = ((polyvertex_t *)gr_curline->pv1)->x;
|
||||||
vs.y = ((polyvertex_t *)gr_curline->v1)->y;
|
vs.y = ((polyvertex_t *)gr_curline->pv1)->y;
|
||||||
ve.x = ((polyvertex_t *)gr_curline->v2)->x;
|
ve.x = ((polyvertex_t *)gr_curline->pv2)->x;
|
||||||
ve.y = ((polyvertex_t *)gr_curline->v2)->y;
|
ve.y = ((polyvertex_t *)gr_curline->pv2)->y;
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
v1x = FLOAT_TO_FIXED(vs.x);
|
v1x = FLOAT_TO_FIXED(vs.x);
|
||||||
|
@ -1479,44 +1483,21 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
v2x = FLOAT_TO_FIXED(ve.x);
|
v2x = FLOAT_TO_FIXED(ve.x);
|
||||||
v2y = FLOAT_TO_FIXED(ve.y);
|
v2y = FLOAT_TO_FIXED(ve.y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gr_frontsector->heightsec != -1)
|
|
||||||
{
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
worldtop = worldtopslope = sectors[gr_frontsector->heightsec].ceilingheight;
|
|
||||||
worldbottom = worldbottomslope = sectors[gr_frontsector->heightsec].floorheight;
|
|
||||||
#else
|
|
||||||
worldtop = sectors[gr_frontsector->heightsec].ceilingheight;
|
|
||||||
worldbottom = sectors[gr_frontsector->heightsec].floorheight;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef ESLOPE
|
|
||||||
if (gr_frontsector->c_slope)
|
|
||||||
{
|
|
||||||
worldtop = P_GetZAt(gr_frontsector->c_slope, v1x, v1y);
|
|
||||||
worldtopslope = P_GetZAt(gr_frontsector->c_slope, v2x, v2y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worldtop = worldtopslope = gr_frontsector->ceilingheight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gr_frontsector->f_slope)
|
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
|
||||||
{
|
if (slope) { \
|
||||||
worldbottom = P_GetZAt(gr_frontsector->f_slope, v1x, v1y);
|
end1 = P_GetZAt(slope, v1x, v1y); \
|
||||||
worldbottomslope = P_GetZAt(gr_frontsector->f_slope, v2x, v2y);
|
end2 = P_GetZAt(slope, v2x, v2y); \
|
||||||
}
|
} else \
|
||||||
else
|
end1 = end2 = normalheight;
|
||||||
{
|
|
||||||
worldbottom = worldbottomslope = gr_frontsector->floorheight;
|
SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight)
|
||||||
}
|
SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight)
|
||||||
#else
|
#else
|
||||||
worldtop = gr_frontsector->ceilingheight;
|
worldtop = gr_frontsector->ceilingheight;
|
||||||
worldbottom = gr_frontsector->floorheight;
|
worldbottom = gr_frontsector->floorheight;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// remember vertices ordering
|
// remember vertices ordering
|
||||||
// 3--2
|
// 3--2
|
||||||
|
@ -1531,20 +1512,23 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
wallVerts[2].z = wallVerts[1].z = ve.y;
|
wallVerts[2].z = wallVerts[1].z = ve.y;
|
||||||
wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f;
|
wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f;
|
||||||
|
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
// x offset the texture
|
// x offset the texture
|
||||||
fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset;
|
fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset;
|
||||||
|
|
||||||
|
#ifndef NEWCLIP
|
||||||
// clip texture s start/end coords with solidsegs
|
// clip texture s start/end coords with solidsegs
|
||||||
if (startfrac > 0.0f && startfrac < 1.0f)
|
if (startfrac > 0.0f && startfrac < 1.0f)
|
||||||
cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac);
|
cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
cliplow = (float)texturehpeg;
|
cliplow = (float)texturehpeg;
|
||||||
|
|
||||||
|
#ifndef NEWCLIP
|
||||||
if (endfrac > 0.0f && endfrac < 1.0f)
|
if (endfrac > 0.0f && endfrac < 1.0f)
|
||||||
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac);
|
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
|
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1560,43 +1544,15 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
{
|
{
|
||||||
INT32 gr_toptexture, gr_bottomtexture;
|
INT32 gr_toptexture, gr_bottomtexture;
|
||||||
// two sided line
|
// two sided line
|
||||||
if (gr_backsector->heightsec != -1)
|
|
||||||
{
|
|
||||||
#ifdef ESLOPE
|
|
||||||
worldhigh = worldhighslope = sectors[gr_backsector->heightsec].ceilingheight;
|
|
||||||
worldlow = worldlowslope = sectors[gr_backsector->heightsec].floorheight;
|
|
||||||
#else
|
|
||||||
worldhigh = sectors[gr_backsector->heightsec].ceilingheight;
|
|
||||||
worldlow = sectors[gr_backsector->heightsec].floorheight;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef ESLOPE
|
|
||||||
if (gr_backsector->c_slope)
|
|
||||||
{
|
|
||||||
worldhigh = P_GetZAt(gr_backsector->c_slope, v1x, v1y);
|
|
||||||
worldhighslope = P_GetZAt(gr_backsector->c_slope, v2x, v2y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worldhigh = worldhighslope = gr_backsector->ceilingheight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gr_backsector->f_slope)
|
#ifdef ESLOPE
|
||||||
{
|
SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight)
|
||||||
worldlow = P_GetZAt(gr_backsector->f_slope, v1x, v1y);
|
SLOPEPARAMS(gr_backsector->f_slope, worldlow, worldlowslope, gr_backsector->floorheight)
|
||||||
worldlowslope = P_GetZAt(gr_backsector->f_slope, v2x, v2y);
|
#undef SLOPEPARAMS
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worldlow = worldlowslope = gr_backsector->floorheight;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
worldhigh = gr_backsector->ceilingheight;
|
worldhigh = gr_backsector->ceilingheight;
|
||||||
worldlow = gr_backsector->floorheight;
|
worldlow = gr_backsector->floorheight;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// hack to allow height changes in outdoor areas
|
// hack to allow height changes in outdoor areas
|
||||||
// This is what gets rid of the upper textures if there should be sky
|
// This is what gets rid of the upper textures if there should be sky
|
||||||
|
@ -1620,7 +1576,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
worldhigh < worldtop
|
worldhigh < worldtop
|
||||||
) && gr_toptexture)
|
) && gr_toptexture)
|
||||||
{
|
{
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
fixed_t texturevpegtop; // top
|
fixed_t texturevpegtop; // top
|
||||||
|
|
||||||
|
@ -1701,7 +1656,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
#endif
|
#endif
|
||||||
worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!!
|
worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!!
|
||||||
{
|
{
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
fixed_t texturevpegbottom = 0; // bottom
|
fixed_t texturevpegbottom = 0; // bottom
|
||||||
|
|
||||||
|
@ -1893,7 +1847,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
h = min(highcut, polytop);
|
h = min(highcut, polytop);
|
||||||
l = max(polybottom, lowcut);
|
l = max(polybottom, lowcut);
|
||||||
|
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
// PEGGING
|
// PEGGING
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -1949,7 +1902,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
h = min(highcut, polytop);
|
h = min(highcut, polytop);
|
||||||
l = max(polybottom, lowcut);
|
l = max(polybottom, lowcut);
|
||||||
|
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
// PEGGING
|
// PEGGING
|
||||||
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
|
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
|
||||||
|
@ -2141,7 +2093,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
|
gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
|
||||||
if (gr_midtexture)
|
if (gr_midtexture)
|
||||||
{
|
{
|
||||||
if (drawtextured)
|
|
||||||
{
|
{
|
||||||
fixed_t texturevpeg;
|
fixed_t texturevpeg;
|
||||||
// PEGGING
|
// PEGGING
|
||||||
|
@ -2282,7 +2233,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
wallVerts[0].s = wallVerts[3].s = 0;
|
wallVerts[0].s = wallVerts[3].s = 0;
|
||||||
wallVerts[2].s = wallVerts[1].s = 0;
|
wallVerts[2].s = wallVerts[1].s = 0;
|
||||||
}
|
}
|
||||||
else if (drawtextured)
|
else
|
||||||
{
|
{
|
||||||
#ifdef ESLOPE // P.S. this is better-organized than the old version
|
#ifdef ESLOPE // P.S. this is better-organized than the old version
|
||||||
fixed_t offs = sides[(newline ? newline : rover->master)->sidenum[0]].rowoffset;
|
fixed_t offs = sides[(newline ? newline : rover->master)->sidenum[0]].rowoffset;
|
||||||
|
@ -2415,7 +2366,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
wallVerts[0].s = wallVerts[3].s = 0;
|
wallVerts[0].s = wallVerts[3].s = 0;
|
||||||
wallVerts[2].s = wallVerts[1].s = 0;
|
wallVerts[2].s = wallVerts[1].s = 0;
|
||||||
}
|
}
|
||||||
else if (drawtextured)
|
else
|
||||||
{
|
{
|
||||||
grTex = HWR_GetTexture(texnum);
|
grTex = HWR_GetTexture(texnum);
|
||||||
|
|
||||||
|
@ -2488,6 +2439,110 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
//Hurdler: end of 3d-floors test
|
//Hurdler: end of 3d-floors test
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From PrBoom:
|
||||||
|
//
|
||||||
|
// e6y: Check whether the player can look beyond this line
|
||||||
|
//
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
boolean checkforemptylines = true;
|
||||||
|
// Don't modify anything here, just check
|
||||||
|
// Kalaron: Modified for sloped linedefs
|
||||||
|
static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector)
|
||||||
|
{
|
||||||
|
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
|
||||||
|
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
|
||||||
|
|
||||||
|
// GZDoom method of sloped line clipping
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope)
|
||||||
|
{
|
||||||
|
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
|
||||||
|
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x);
|
||||||
|
v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y);
|
||||||
|
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x);
|
||||||
|
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y);
|
||||||
|
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
|
||||||
|
if (slope) { \
|
||||||
|
end1 = P_GetZAt(slope, v1x, v1y); \
|
||||||
|
end2 = P_GetZAt(slope, v2x, v2y); \
|
||||||
|
} else \
|
||||||
|
end1 = end2 = normalheight;
|
||||||
|
|
||||||
|
SLOPEPARAMS(afrontsector->f_slope, frontf1, frontf2, afrontsector->floorheight)
|
||||||
|
SLOPEPARAMS(afrontsector->c_slope, frontc1, frontc2, afrontsector->ceilingheight)
|
||||||
|
SLOPEPARAMS( abacksector->f_slope, backf1, backf2, abacksector->floorheight)
|
||||||
|
SLOPEPARAMS( abacksector->c_slope, backc1, backc2, abacksector->ceilingheight)
|
||||||
|
#undef SLOPEPARAMS
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
frontf1 = frontf2 = afrontsector->floorheight;
|
||||||
|
frontc1 = frontc2 = afrontsector->ceilingheight;
|
||||||
|
backf1 = backf2 = abacksector->floorheight;
|
||||||
|
backc1 = backc2 = abacksector->ceilingheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check for closed sectors!
|
||||||
|
if (backc1 <= frontf1 && backc2 <= frontf2)
|
||||||
|
{
|
||||||
|
checkforemptylines = false;
|
||||||
|
if (!seg->sidedef->toptexture)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backf1 >= frontc1 && backf2 >= frontc2)
|
||||||
|
{
|
||||||
|
checkforemptylines = false;
|
||||||
|
if (!seg->sidedef->bottomtexture)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// properly render skies (consider door "open" if both floors are sky):
|
||||||
|
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backc1 <= backf1 && backc2 <= backf2)
|
||||||
|
{
|
||||||
|
checkforemptylines = false;
|
||||||
|
// preserve a kind of transparent door/lift special effect:
|
||||||
|
if (backc1 < frontc1 || backc2 < frontc2)
|
||||||
|
{
|
||||||
|
if (!seg->sidedef->toptexture)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (backf1 > frontf1 || backf2 > frontf2)
|
||||||
|
{
|
||||||
|
if (!seg->sidedef->bottomtexture)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backc1 != frontc1 || backc2 != frontc2
|
||||||
|
|| backf1 != frontf1 || backf2 != frontf2)
|
||||||
|
{
|
||||||
|
checkforemptylines = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
//Hurdler: just like in r_bsp.c
|
//Hurdler: just like in r_bsp.c
|
||||||
#if 1
|
#if 1
|
||||||
#define MAXSEGS MAXVIDWIDTH/2+1
|
#define MAXSEGS MAXVIDWIDTH/2+1
|
||||||
|
@ -2559,7 +2614,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(0, highfrac);
|
HWR_StoreWallRange(0, highfrac);
|
||||||
}
|
}
|
||||||
// Now adjust the clip size.
|
// Now adjust the clip size.
|
||||||
|
@ -2583,8 +2638,8 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(lowfrac, highfrac);
|
HWR_StoreWallRange(lowfrac, highfrac);
|
||||||
}
|
}
|
||||||
next++;
|
next++;
|
||||||
|
@ -2618,7 +2673,7 @@ static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(lowfrac, 1);
|
HWR_StoreWallRange(lowfrac, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2681,8 +2736,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
highfrac = HWR_ClipViewSegment(min(start->first + 1,
|
highfrac = HWR_ClipViewSegment(min(start->first + 1,
|
||||||
start->last), (polyvertex_t *)gr_curline->v1,
|
start->last), (polyvertex_t *)gr_curline->pv1,
|
||||||
(polyvertex_t *)gr_curline->v2);
|
(polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(0, highfrac);
|
HWR_StoreWallRange(0, highfrac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2701,8 +2756,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->v1, (polyvertex_t *)gr_curline->v2);
|
highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(lowfrac, highfrac);
|
HWR_StoreWallRange(lowfrac, highfrac);
|
||||||
}
|
}
|
||||||
start++;
|
start++;
|
||||||
|
@ -2732,8 +2787,8 @@ static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lowfrac = HWR_ClipViewSegment(max(start->last - 1,
|
lowfrac = HWR_ClipViewSegment(max(start->last - 1,
|
||||||
start->first), (polyvertex_t *)gr_curline->v1,
|
start->first), (polyvertex_t *)gr_curline->pv1,
|
||||||
(polyvertex_t *)gr_curline->v2);
|
(polyvertex_t *)gr_curline->pv2);
|
||||||
HWR_StoreWallRange(lowfrac, 1);
|
HWR_StoreWallRange(lowfrac, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2773,6 +2828,7 @@ static void HWR_ClearClipSegs(void)
|
||||||
gr_solidsegs[1].last = 0x7fffffff;
|
gr_solidsegs[1].last = 0x7fffffff;
|
||||||
hw_newend = gr_solidsegs+2;
|
hw_newend = gr_solidsegs+2;
|
||||||
}
|
}
|
||||||
|
#endif // NEWCLIP
|
||||||
|
|
||||||
// -----------------+
|
// -----------------+
|
||||||
// HWR_AddLine : Clips the given segment and adds any visible pieces to the line list.
|
// HWR_AddLine : Clips the given segment and adds any visible pieces to the line list.
|
||||||
|
@ -2781,24 +2837,46 @@ static void HWR_ClearClipSegs(void)
|
||||||
// -----------------+
|
// -----------------+
|
||||||
static void HWR_AddLine(seg_t * line)
|
static void HWR_AddLine(seg_t * line)
|
||||||
{
|
{
|
||||||
INT32 x1, x2;
|
|
||||||
angle_t angle1, angle2;
|
angle_t angle1, angle2;
|
||||||
|
#ifndef NEWCLIP
|
||||||
|
INT32 x1, x2;
|
||||||
angle_t span, tspan;
|
angle_t span, tspan;
|
||||||
|
#endif
|
||||||
|
|
||||||
// SoM: Backsector needs to be run through R_FakeFlat
|
// SoM: Backsector needs to be run through R_FakeFlat
|
||||||
sector_t tempsec;
|
sector_t tempsec;
|
||||||
|
|
||||||
|
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
gr_curline = line;
|
gr_curline = line;
|
||||||
|
|
||||||
// OPTIMIZE: quickly reject orthogonal back sides.
|
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x);
|
||||||
angle1 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x),
|
v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y);
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y));
|
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x);
|
||||||
angle2 = R_PointToAngle(FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x),
|
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y);
|
||||||
FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y));
|
|
||||||
|
|
||||||
|
// OPTIMIZE: quickly reject orthogonal back sides.
|
||||||
|
angle1 = R_PointToAngle(v1x, v1y);
|
||||||
|
angle2 = R_PointToAngle(v2x, v2y);
|
||||||
|
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
// PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle!
|
||||||
|
if (angle2 - angle1 < ANGLE_180)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// PrBoom: use REAL clipping math YAYYYYYYY!!!
|
||||||
|
|
||||||
|
if (!gld_clipper_SafeCheckRange(angle2, angle1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkforemptylines = true;
|
||||||
|
#else
|
||||||
// Clip to view edges.
|
// Clip to view edges.
|
||||||
span = angle1 - angle2;
|
span = angle1 - angle2;
|
||||||
|
|
||||||
|
@ -2839,8 +2917,8 @@ static void HWR_AddLine(seg_t * line)
|
||||||
float fx1,fx2,fy1,fy2;
|
float fx1,fx2,fy1,fy2;
|
||||||
//BP: test with a better projection than viewangletox[R_PointToAngle(angle)]
|
//BP: test with a better projection than viewangletox[R_PointToAngle(angle)]
|
||||||
// do not enable this at release 4 mul and 2 div
|
// do not enable this at release 4 mul and 2 div
|
||||||
fx1 = ((polyvertex_t *)(line->v1))->x-gr_viewx;
|
fx1 = ((polyvertex_t *)(line->pv1))->x-gr_viewx;
|
||||||
fy1 = ((polyvertex_t *)(line->v1))->y-gr_viewy;
|
fy1 = ((polyvertex_t *)(line->pv1))->y-gr_viewy;
|
||||||
fy2 = (fx1 * gr_viewcos + fy1 * gr_viewsin);
|
fy2 = (fx1 * gr_viewcos + fy1 * gr_viewsin);
|
||||||
if (fy2 < 0)
|
if (fy2 < 0)
|
||||||
// the point is back
|
// the point is back
|
||||||
|
@ -2848,8 +2926,8 @@ static void HWR_AddLine(seg_t * line)
|
||||||
else
|
else
|
||||||
fx1 = gr_windowcenterx + (fx1 * gr_viewsin - fy1 * gr_viewcos) * gr_centerx / fy2;
|
fx1 = gr_windowcenterx + (fx1 * gr_viewsin - fy1 * gr_viewcos) * gr_centerx / fy2;
|
||||||
|
|
||||||
fx2 = ((polyvertex_t *)(line->v2))->x-gr_viewx;
|
fx2 = ((polyvertex_t *)(line->pv2))->x-gr_viewx;
|
||||||
fy2 = ((polyvertex_t *)(line->v2))->y-gr_viewy;
|
fy2 = ((polyvertex_t *)(line->pv2))->y-gr_viewy;
|
||||||
fy1 = (fx2 * gr_viewcos + fy2 * gr_viewsin);
|
fy1 = (fx2 * gr_viewcos + fy2 * gr_viewsin);
|
||||||
if (fy1 < 0)
|
if (fy1 < 0)
|
||||||
// the point is back
|
// the point is back
|
||||||
|
@ -2877,8 +2955,34 @@ static void HWR_AddLine(seg_t * line)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
gr_backsector = line->backsector;
|
gr_backsector = line->backsector;
|
||||||
|
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
if (!line->backsector)
|
||||||
|
{
|
||||||
|
gld_clipper_SafeAddClipRange(angle2, angle1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true);
|
||||||
|
if (CheckClip(line, gr_frontsector, gr_backsector))
|
||||||
|
{
|
||||||
|
gld_clipper_SafeAddClipRange(angle2, angle1);
|
||||||
|
checkforemptylines = false;
|
||||||
|
}
|
||||||
|
// Reject empty lines used for triggers and special events.
|
||||||
|
// Identical floor and ceiling on both sides,
|
||||||
|
// identical light levels on both sides,
|
||||||
|
// and no middle texture.
|
||||||
|
if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
|
||||||
|
return;
|
||||||
|
#else
|
||||||
// Single sided line?
|
// Single sided line?
|
||||||
if (!gr_backsector)
|
if (!gr_backsector)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
|
@ -2888,14 +2992,9 @@ static void HWR_AddLine(seg_t * line)
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope)
|
if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope)
|
||||||
{
|
{
|
||||||
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
|
|
||||||
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
|
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
|
||||||
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
|
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
|
||||||
|
|
||||||
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->x);
|
|
||||||
v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v1)->y);
|
|
||||||
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->x);
|
|
||||||
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->v2)->y);
|
|
||||||
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
|
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
|
||||||
if (slope) { \
|
if (slope) { \
|
||||||
end1 = P_GetZAt(slope, v1x, v1y); \
|
end1 = P_GetZAt(slope, v1x, v1y); \
|
||||||
|
@ -2916,6 +3015,13 @@ static void HWR_AddLine(seg_t * line)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for automap fix.
|
||||||
|
if (backc1 <= backf1 && backc2 <= backf2
|
||||||
|
&& ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture)
|
||||||
|
&& ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture)
|
||||||
|
&& (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum))
|
||||||
|
goto clipsolid;
|
||||||
|
|
||||||
// Window.
|
// Window.
|
||||||
if (backc1 != frontc1 || backc2 != frontc2
|
if (backc1 != frontc1 || backc2 != frontc2
|
||||||
|| backf1 != frontf1 || backf2 != frontf2)
|
|| backf1 != frontf1 || backf2 != frontf2)
|
||||||
|
@ -2931,6 +3037,13 @@ static void HWR_AddLine(seg_t * line)
|
||||||
gr_backsector->floorheight >= gr_frontsector->ceilingheight)
|
gr_backsector->floorheight >= gr_frontsector->ceilingheight)
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
|
|
||||||
|
// Check for automap fix.
|
||||||
|
if (gr_backsector->ceilingheight <= gr_backsector->floorheight
|
||||||
|
&& ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture)
|
||||||
|
&& ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture)
|
||||||
|
&& (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum))
|
||||||
|
goto clipsolid;
|
||||||
|
|
||||||
// Window.
|
// Window.
|
||||||
if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight ||
|
if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight ||
|
||||||
gr_backsector->floorheight != gr_frontsector->floorheight)
|
gr_backsector->floorheight != gr_frontsector->floorheight)
|
||||||
|
@ -2941,25 +3054,8 @@ static void HWR_AddLine(seg_t * line)
|
||||||
// Identical floor and ceiling on both sides,
|
// Identical floor and ceiling on both sides,
|
||||||
// identical light levels on both sides,
|
// identical light levels on both sides,
|
||||||
// and no middle texture.
|
// and no middle texture.
|
||||||
if (
|
if (R_IsEmptyLine(gr_curline, gr_frontsector, gr_backsector))
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
!line->polyseg &&
|
|
||||||
#endif
|
|
||||||
gr_backsector->ceilingpic == gr_frontsector->ceilingpic
|
|
||||||
&& gr_backsector->floorpic == gr_frontsector->floorpic
|
|
||||||
#ifdef ESLOPE
|
|
||||||
&& gr_backsector->f_slope == gr_frontsector->f_slope
|
|
||||||
&& gr_backsector->c_slope == gr_frontsector->c_slope
|
|
||||||
#endif
|
|
||||||
&& gr_backsector->lightlevel == gr_frontsector->lightlevel
|
|
||||||
&& gr_curline->sidedef->midtexture == 0
|
|
||||||
&& !gr_backsector->ffloors && !gr_frontsector->ffloors)
|
|
||||||
// SoM: For 3D sides... Boris, would you like to take a
|
|
||||||
// crack at rendering 3D sides? You would need to add the
|
|
||||||
// above check and add code to HWR_StoreWallRange...
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
clippass:
|
clippass:
|
||||||
if (x1 == x2)
|
if (x1 == x2)
|
||||||
|
@ -2971,6 +3067,7 @@ clipsolid:
|
||||||
if (x1 == x2)
|
if (x1 == x2)
|
||||||
goto clippass;
|
goto clippass;
|
||||||
HWR_ClipSolidWallSegment(x1, x2-1);
|
HWR_ClipSolidWallSegment(x1, x2-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// HWR_CheckBBox
|
// HWR_CheckBBox
|
||||||
|
@ -2982,9 +3079,13 @@ clipsolid:
|
||||||
|
|
||||||
static boolean HWR_CheckBBox(fixed_t *bspcoord)
|
static boolean HWR_CheckBBox(fixed_t *bspcoord)
|
||||||
{
|
{
|
||||||
INT32 boxpos, sx1, sx2;
|
INT32 boxpos;
|
||||||
fixed_t px1, py1, px2, py2;
|
fixed_t px1, py1, px2, py2;
|
||||||
angle_t angle1, angle2, span, tspan;
|
angle_t angle1, angle2;
|
||||||
|
#ifndef NEWCLIP
|
||||||
|
INT32 sx1, sx2;
|
||||||
|
angle_t span, tspan;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Find the corners of the box
|
// Find the corners of the box
|
||||||
// that define the edges from current viewpoint.
|
// that define the edges from current viewpoint.
|
||||||
|
@ -3010,6 +3111,11 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
|
||||||
px2 = bspcoord[checkcoord[boxpos][2]];
|
px2 = bspcoord[checkcoord[boxpos][2]];
|
||||||
py2 = bspcoord[checkcoord[boxpos][3]];
|
py2 = bspcoord[checkcoord[boxpos][3]];
|
||||||
|
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
angle1 = R_PointToAngle(px1, py1);
|
||||||
|
angle2 = R_PointToAngle(px2, py2);
|
||||||
|
return gld_clipper_SafeCheckRange(angle2, angle1);
|
||||||
|
#else
|
||||||
// check clip list for an open space
|
// check clip list for an open space
|
||||||
angle1 = R_PointToAngle(px1, py1) - dup_viewangle;
|
angle1 = R_PointToAngle(px1, py1) - dup_viewangle;
|
||||||
angle2 = R_PointToAngle(px2, py2) - dup_viewangle;
|
angle2 = R_PointToAngle(px2, py2) - dup_viewangle;
|
||||||
|
@ -3057,6 +3163,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return HWR_ClipToSolidSegs(sx1, sx2 - 1);
|
return HWR_ClipToSolidSegs(sx1, sx2 - 1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
@ -3090,8 +3197,8 @@ static inline void HWR_AddPolyObjectSegs(void)
|
||||||
pv2->x = FIXED_TO_FLOAT(gr_fakeline->v2->x);
|
pv2->x = FIXED_TO_FLOAT(gr_fakeline->v2->x);
|
||||||
pv2->y = FIXED_TO_FLOAT(gr_fakeline->v2->y);
|
pv2->y = FIXED_TO_FLOAT(gr_fakeline->v2->y);
|
||||||
|
|
||||||
gr_fakeline->v1 = (vertex_t *)pv1;
|
gr_fakeline->pv1 = pv1;
|
||||||
gr_fakeline->v2 = (vertex_t *)pv2;
|
gr_fakeline->pv2 = pv2;
|
||||||
|
|
||||||
HWR_AddLine(gr_fakeline);
|
HWR_AddLine(gr_fakeline);
|
||||||
}
|
}
|
||||||
|
@ -4229,6 +4336,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
||||||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
||||||
|
//const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE));
|
||||||
if (spr->mobj)
|
if (spr->mobj)
|
||||||
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
||||||
if (hires)
|
if (hires)
|
||||||
|
@ -4272,7 +4380,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
||||||
|
|
||||||
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
||||||
// and the 2d map coords of start/end vertices
|
// and the 2d map coords of start/end vertices
|
||||||
wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz;
|
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||||
|
wallVerts[2].z = wallVerts[1].z = spr->z2;
|
||||||
|
|
||||||
// transform
|
// transform
|
||||||
wv = wallVerts;
|
wv = wallVerts;
|
||||||
|
@ -5068,6 +5177,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
angle_t ang;
|
angle_t ang;
|
||||||
INT32 heightsec, phs;
|
INT32 heightsec, phs;
|
||||||
|
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||||
|
float offset;
|
||||||
|
float ang_scale = 1.0f, ang_scalez = 0.0f;
|
||||||
|
float z1, z2;
|
||||||
|
|
||||||
if (!thing)
|
if (!thing)
|
||||||
return;
|
return;
|
||||||
|
@ -5082,7 +5195,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||||
|
|
||||||
// thing is behind view plane?
|
// thing is behind view plane?
|
||||||
if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
||||||
|
@ -5120,6 +5233,27 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (papersprite)
|
||||||
|
{
|
||||||
|
// Use the actual view angle, rather than the angle formed
|
||||||
|
// between the view point and the thing
|
||||||
|
// this makes sure paper sprites always appear at the right angle!
|
||||||
|
// Note: DO NOT do this in software mode version, it actually
|
||||||
|
// makes papersprites look WORSE there (I know, I've tried)
|
||||||
|
// Monster Iestyn - 13/05/17
|
||||||
|
ang = dup_viewangle - thing->angle;
|
||||||
|
ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
if (ang_scale < 0)
|
||||||
|
{
|
||||||
|
ang_scale = -ang_scale;
|
||||||
|
ang_scalez = -ang_scalez;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sprframe->rotate != SRF_SINGLE)
|
||||||
|
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||||
|
|
||||||
if (sprframe->rotate == SRF_SINGLE)
|
if (sprframe->rotate == SRF_SINGLE)
|
||||||
{
|
{
|
||||||
// use single rotation for all views
|
// use single rotation for all views
|
||||||
|
@ -5130,8 +5264,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// choose a different rotation based on player view
|
// choose a different rotation based on player view
|
||||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
|
||||||
|
|
||||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||||
rot = 6; // F7 slot
|
rot = 6; // F7 slot
|
||||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||||
|
@ -5149,9 +5281,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
// calculate edges of the shape
|
// calculate edges of the shape
|
||||||
if (flip)
|
if (flip)
|
||||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||||
else
|
else
|
||||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||||
|
|
||||||
|
z1 = tz - (offset * ang_scalez);
|
||||||
|
tx -= offset * ang_scale;
|
||||||
|
|
||||||
// project x
|
// project x
|
||||||
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||||
|
@ -5162,7 +5297,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
x1 = tx;
|
x1 = tx;
|
||||||
|
|
||||||
tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||||
|
|
||||||
|
z2 = z1 + (offset * ang_scalez);
|
||||||
|
tx += offset * ang_scale;
|
||||||
|
|
||||||
|
if (papersprite && max(z1, z2) < ZCLIP_PLANE)
|
||||||
|
return;
|
||||||
|
|
||||||
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||||
|
|
||||||
if (vflip)
|
if (vflip)
|
||||||
|
@ -5211,6 +5353,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
vis->patchlumpnum = sprframe->lumppat[rot];
|
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||||
vis->flip = flip;
|
vis->flip = flip;
|
||||||
vis->mobj = thing;
|
vis->mobj = thing;
|
||||||
|
vis->z1 = z1;
|
||||||
|
vis->z2 = z2;
|
||||||
|
|
||||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||||
|
@ -5599,7 +5743,19 @@ if (0)
|
||||||
#ifdef SORTING
|
#ifdef SORTING
|
||||||
drawcount = 0;
|
drawcount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
if (rendermode == render_opengl)
|
||||||
|
{
|
||||||
|
angle_t a1 = gld_FrustumAngle();
|
||||||
|
gld_clipper_Clear();
|
||||||
|
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
|
||||||
|
#ifdef HAVE_SPHEREFRUSTRUM
|
||||||
|
gld_FrustrumSetup();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
HWR_ClearClipSegs();
|
HWR_ClearClipSegs();
|
||||||
|
#endif
|
||||||
|
|
||||||
//04/01/2000: Hurdler: added for T&L
|
//04/01/2000: Hurdler: added for T&L
|
||||||
// Actually it only works on Walls and Planes
|
// Actually it only works on Walls and Planes
|
||||||
|
@ -5609,6 +5765,7 @@ if (0)
|
||||||
|
|
||||||
HWR_RenderBSPNode((INT32)numnodes-1);
|
HWR_RenderBSPNode((INT32)numnodes-1);
|
||||||
|
|
||||||
|
#ifndef NEWCLIP
|
||||||
// Make a viewangle int so we can render things based on mouselook
|
// Make a viewangle int so we can render things based on mouselook
|
||||||
if (player == &players[consoleplayer])
|
if (player == &players[consoleplayer])
|
||||||
viewangle = localaiming;
|
viewangle = localaiming;
|
||||||
|
@ -5635,6 +5792,7 @@ if (0)
|
||||||
|
|
||||||
dup_viewangle += ANGLE_90;
|
dup_viewangle += ANGLE_90;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check for new console commands.
|
// Check for new console commands.
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
|
@ -5829,7 +5987,19 @@ if (0)
|
||||||
#ifdef SORTING
|
#ifdef SORTING
|
||||||
drawcount = 0;
|
drawcount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef NEWCLIP
|
||||||
|
if (rendermode == render_opengl)
|
||||||
|
{
|
||||||
|
angle_t a1 = gld_FrustumAngle();
|
||||||
|
gld_clipper_Clear();
|
||||||
|
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
|
||||||
|
#ifdef HAVE_SPHEREFRUSTRUM
|
||||||
|
gld_FrustrumSetup();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
HWR_ClearClipSegs();
|
HWR_ClearClipSegs();
|
||||||
|
#endif
|
||||||
|
|
||||||
//04/01/2000: Hurdler: added for T&L
|
//04/01/2000: Hurdler: added for T&L
|
||||||
// Actually it only works on Walls and Planes
|
// Actually it only works on Walls and Planes
|
||||||
|
@ -5839,6 +6009,7 @@ if (0)
|
||||||
|
|
||||||
HWR_RenderBSPNode((INT32)numnodes-1);
|
HWR_RenderBSPNode((INT32)numnodes-1);
|
||||||
|
|
||||||
|
#ifndef NEWCLIP
|
||||||
// Make a viewangle int so we can render things based on mouselook
|
// Make a viewangle int so we can render things based on mouselook
|
||||||
if (player == &players[consoleplayer])
|
if (player == &players[consoleplayer])
|
||||||
viewangle = localaiming;
|
viewangle = localaiming;
|
||||||
|
@ -5865,6 +6036,7 @@ if (0)
|
||||||
|
|
||||||
dup_viewangle += ANGLE_90;
|
dup_viewangle += ANGLE_90;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check for new console commands.
|
// Check for new console commands.
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
|
@ -6010,7 +6182,9 @@ static inline void HWR_AddEngineCommands(void)
|
||||||
{
|
{
|
||||||
// engine state variables
|
// engine state variables
|
||||||
//CV_RegisterVar(&cv_grzbuffer);
|
//CV_RegisterVar(&cv_grzbuffer);
|
||||||
|
#ifndef NEWCLIP
|
||||||
CV_RegisterVar(&cv_grclipwalls);
|
CV_RegisterVar(&cv_grclipwalls);
|
||||||
|
#endif
|
||||||
|
|
||||||
// engine development mode variables
|
// engine development mode variables
|
||||||
// - usage may vary from version to version..
|
// - usage may vary from version to version..
|
||||||
|
|
|
@ -298,8 +298,8 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
// initialize model and read header
|
// initialize model and read header
|
||||||
|
|
||||||
if (fread(&model->header, sizeof (model->header), 1, file) != 1
|
if (fread(&model->header, sizeof (model->header), 1, file) != 1
|
||||||
|| model->header.magic !=
|
|| model->header.magic != MD2_IDENT
|
||||||
(INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I'))
|
|| model->header.version != MD2_VERSION)
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
free(model);
|
free(model);
|
||||||
|
@ -313,6 +313,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
{ \
|
{ \
|
||||||
CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \
|
CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \
|
||||||
md2_freeModel (model); \
|
md2_freeModel (model); \
|
||||||
|
fclose(file); \
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +335,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file))
|
fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file))
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,6 +349,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file))
|
fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file))
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,6 +363,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file))
|
fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file))
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,6 +376,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
if (!model->frames)
|
if (!model->frames)
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +390,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
fread(frame, 1, model->header.frameSize, file))
|
fread(frame, 1, model->header.frameSize, file))
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +416,7 @@ static md2_model_t *md2_readModel(const char *filename)
|
||||||
fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file))
|
fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file))
|
||||||
{
|
{
|
||||||
md2_freeModel (model);
|
md2_freeModel (model);
|
||||||
|
fclose(file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,6 +945,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
||||||
{
|
{
|
||||||
UINT16 w = gpatch->width, h = gpatch->height;
|
UINT16 w = gpatch->width, h = gpatch->height;
|
||||||
UINT32 size = w*h;
|
UINT32 size = w*h;
|
||||||
|
UINT8 c = 255;
|
||||||
RGBA_t *image, *blendimage, *cur, blendcolor;
|
RGBA_t *image, *blendimage, *cur, blendcolor;
|
||||||
|
|
||||||
if (grmip->width == 0)
|
if (grmip->width == 0)
|
||||||
|
@ -961,244 +969,59 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
||||||
image = gpatch->mipmap.grInfo.data;
|
image = gpatch->mipmap.grInfo.data;
|
||||||
blendimage = blendgpatch->mipmap.grInfo.data;
|
blendimage = blendgpatch->mipmap.grInfo.data;
|
||||||
|
|
||||||
|
#define SUPERCOLORBLEND(name, c1, c2, c3, c4, c5) \
|
||||||
|
case SKINCOLOR_SUPER ## name ## 1: c = c1; break; \
|
||||||
|
case SKINCOLOR_SUPER ## name ## 2: c = c2; break; \
|
||||||
|
case SKINCOLOR_SUPER ## name ## 3: c = c3; break; \
|
||||||
|
case SKINCOLOR_SUPER ## name ## 4: c = c4; break; \
|
||||||
|
case SKINCOLOR_SUPER ## name ## 5: c = c5; break;
|
||||||
|
|
||||||
switch (color)
|
switch (color)
|
||||||
{
|
{
|
||||||
case SKINCOLOR_WHITE:
|
case SKINCOLOR_WHITE: c = 3; break;
|
||||||
blendcolor = V_GetColor(3);
|
case SKINCOLOR_SILVER: c = 10; break;
|
||||||
break;
|
case SKINCOLOR_GREY: c = 15; break;
|
||||||
case SKINCOLOR_SILVER:
|
case SKINCOLOR_BLACK: c = 27; break;
|
||||||
blendcolor = V_GetColor(10);
|
case SKINCOLOR_BEIGE: c = 247; break;
|
||||||
break;
|
case SKINCOLOR_PEACH: c = 218; break;
|
||||||
case SKINCOLOR_GREY:
|
case SKINCOLOR_BROWN: c = 234; break;
|
||||||
blendcolor = V_GetColor(15);
|
case SKINCOLOR_RED: c = 38; break;
|
||||||
break;
|
case SKINCOLOR_CRIMSON: c = 45; break;
|
||||||
case SKINCOLOR_BLACK:
|
case SKINCOLOR_ORANGE: c = 54; break;
|
||||||
blendcolor = V_GetColor(27);
|
case SKINCOLOR_RUST: c = 60; break;
|
||||||
break;
|
case SKINCOLOR_GOLD: c = 67; break;
|
||||||
case SKINCOLOR_BEIGE:
|
case SKINCOLOR_YELLOW: c = 73; break;
|
||||||
blendcolor = V_GetColor(247);
|
case SKINCOLOR_TAN: c = 85; break;
|
||||||
break;
|
case SKINCOLOR_MOSS: c = 92; break;
|
||||||
case SKINCOLOR_PEACH:
|
case SKINCOLOR_PERIDOT: c = 188; break;
|
||||||
blendcolor = V_GetColor(218);
|
case SKINCOLOR_GREEN: c = 101; break;
|
||||||
break;
|
case SKINCOLOR_EMERALD: c = 112; break;
|
||||||
case SKINCOLOR_BROWN:
|
case SKINCOLOR_AQUA: c = 122; break;
|
||||||
blendcolor = V_GetColor(234);
|
case SKINCOLOR_TEAL: c = 141; break;
|
||||||
break;
|
case SKINCOLOR_CYAN: c = 131; break;
|
||||||
case SKINCOLOR_RED:
|
case SKINCOLOR_BLUE: c = 152; break;
|
||||||
blendcolor = V_GetColor(38);
|
case SKINCOLOR_AZURE: c = 171; break;
|
||||||
break;
|
case SKINCOLOR_PASTEL: c = 161; break;
|
||||||
case SKINCOLOR_CRIMSON:
|
case SKINCOLOR_PURPLE: c = 165; break;
|
||||||
blendcolor = V_GetColor(45);
|
case SKINCOLOR_LAVENDER: c = 195; break;
|
||||||
break;
|
case SKINCOLOR_MAGENTA: c = 183; break;
|
||||||
case SKINCOLOR_ORANGE:
|
case SKINCOLOR_PINK: c = 211; break;
|
||||||
blendcolor = V_GetColor(54);
|
case SKINCOLOR_ROSY: c = 202; break;
|
||||||
break;
|
|
||||||
case SKINCOLOR_RUST:
|
|
||||||
blendcolor = V_GetColor(60);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_GOLD:
|
|
||||||
blendcolor = V_GetColor(67);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_YELLOW:
|
|
||||||
blendcolor = V_GetColor(73);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_TAN:
|
|
||||||
blendcolor = V_GetColor(85);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_MOSS:
|
|
||||||
blendcolor = V_GetColor(92);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_PERIDOT:
|
|
||||||
blendcolor = V_GetColor(188);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_GREEN:
|
|
||||||
blendcolor = V_GetColor(101);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_EMERALD:
|
|
||||||
blendcolor = V_GetColor(112);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_AQUA:
|
|
||||||
blendcolor = V_GetColor(122);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_TEAL:
|
|
||||||
blendcolor = V_GetColor(141);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_CYAN:
|
|
||||||
blendcolor = V_GetColor(131);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_BLUE:
|
|
||||||
blendcolor = V_GetColor(152);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_AZURE:
|
|
||||||
blendcolor = V_GetColor(171);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_PASTEL:
|
|
||||||
blendcolor = V_GetColor(161);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_PURPLE:
|
|
||||||
blendcolor = V_GetColor(165);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_LAVENDER:
|
|
||||||
blendcolor = V_GetColor(195);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_MAGENTA:
|
|
||||||
blendcolor = V_GetColor(183);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_PINK:
|
|
||||||
blendcolor = V_GetColor(211);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_ROSY:
|
|
||||||
blendcolor = V_GetColor(202);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERSILVER1: // Super silver
|
SUPERCOLORBLEND(SILVER, 0, 2, 4, 7, 10) // Super silver
|
||||||
blendcolor = V_GetColor(0);
|
SUPERCOLORBLEND(RED, 208, 210, 32, 33, 35) // Super red
|
||||||
break;
|
SUPERCOLORBLEND(ORANGE, 208, 48, 50, 54, 58) // Super orange
|
||||||
case SKINCOLOR_SUPERSILVER2:
|
SUPERCOLORBLEND(GOLD, 80, 83, 73, 64, 67) // Super gold
|
||||||
blendcolor = V_GetColor(2);
|
SUPERCOLORBLEND(PERIDOT, 88, 188, 189, 190, 191) // Super peridot
|
||||||
break;
|
SUPERCOLORBLEND(CYAN, 128, 131, 133, 134, 136) // Super cyan
|
||||||
case SKINCOLOR_SUPERSILVER3:
|
SUPERCOLORBLEND(PURPLE, 144, 162, 164, 166, 168) // Super purple
|
||||||
blendcolor = V_GetColor(4);
|
SUPERCOLORBLEND(RUST, 51, 54, 68, 70, 234) // Super rust
|
||||||
break;
|
SUPERCOLORBLEND(TAN, 80, 82, 84, 87, 247) // Super tan
|
||||||
case SKINCOLOR_SUPERSILVER4:
|
default: c = 255; break;
|
||||||
blendcolor = V_GetColor(7);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERSILVER5:
|
|
||||||
blendcolor = V_GetColor(10);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERRED1: // Super red
|
|
||||||
blendcolor = V_GetColor(208);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRED2:
|
|
||||||
blendcolor = V_GetColor(210);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRED3:
|
|
||||||
blendcolor = V_GetColor(32);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRED4:
|
|
||||||
blendcolor = V_GetColor(33);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRED5:
|
|
||||||
blendcolor = V_GetColor(35);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERORANGE1: // Super orange
|
|
||||||
blendcolor = V_GetColor(208);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERORANGE2:
|
|
||||||
blendcolor = V_GetColor(48);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERORANGE3:
|
|
||||||
blendcolor = V_GetColor(50);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERORANGE4:
|
|
||||||
blendcolor = V_GetColor(54);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERORANGE5:
|
|
||||||
blendcolor = V_GetColor(58);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERGOLD1: // Super gold
|
|
||||||
blendcolor = V_GetColor(80);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERGOLD2:
|
|
||||||
blendcolor = V_GetColor(83);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERGOLD3:
|
|
||||||
blendcolor = V_GetColor(73);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERGOLD4:
|
|
||||||
blendcolor = V_GetColor(64);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERGOLD5:
|
|
||||||
blendcolor = V_GetColor(67);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERPERIDOT1: // Super peridot
|
|
||||||
blendcolor = V_GetColor(88);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPERIDOT2:
|
|
||||||
blendcolor = V_GetColor(188);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPERIDOT3:
|
|
||||||
blendcolor = V_GetColor(189);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPERIDOT4:
|
|
||||||
blendcolor = V_GetColor(190);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPERIDOT5:
|
|
||||||
blendcolor = V_GetColor(191);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERCYAN1: // Super cyan
|
|
||||||
blendcolor = V_GetColor(128);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERCYAN2:
|
|
||||||
blendcolor = V_GetColor(131);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERCYAN3:
|
|
||||||
blendcolor = V_GetColor(133);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERCYAN4:
|
|
||||||
blendcolor = V_GetColor(134);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERCYAN5:
|
|
||||||
blendcolor = V_GetColor(136);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERPURPLE1: // Super purple
|
|
||||||
blendcolor = V_GetColor(144);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPURPLE2:
|
|
||||||
blendcolor = V_GetColor(162);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPURPLE3:
|
|
||||||
blendcolor = V_GetColor(164);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPURPLE4:
|
|
||||||
blendcolor = V_GetColor(166);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERPURPLE5:
|
|
||||||
blendcolor = V_GetColor(168);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERRUST1: // Super rust
|
|
||||||
blendcolor = V_GetColor(51);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRUST2:
|
|
||||||
blendcolor = V_GetColor(54);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRUST3:
|
|
||||||
blendcolor = V_GetColor(68);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRUST4:
|
|
||||||
blendcolor = V_GetColor(70);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERRUST5:
|
|
||||||
blendcolor = V_GetColor(234);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SKINCOLOR_SUPERTAN1: // Super tan
|
|
||||||
blendcolor = V_GetColor(80);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERTAN2:
|
|
||||||
blendcolor = V_GetColor(82);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERTAN3:
|
|
||||||
blendcolor = V_GetColor(84);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERTAN4:
|
|
||||||
blendcolor = V_GetColor(87);
|
|
||||||
break;
|
|
||||||
case SKINCOLOR_SUPERTAN5:
|
|
||||||
blendcolor = V_GetColor(247);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
blendcolor = V_GetColor(255);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
blendcolor = V_GetColor(c);
|
||||||
|
|
||||||
|
#undef SUPERCOLORBLEND
|
||||||
|
|
||||||
while (size--)
|
while (size--)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
|
|
||||||
#include "hw_glob.h"
|
#include "hw_glob.h"
|
||||||
|
|
||||||
|
// magic number "IDP2" or 844121161
|
||||||
|
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||||
|
// model version
|
||||||
|
#define MD2_VERSION 8
|
||||||
|
|
||||||
#define MD2_MAX_TRIANGLES 8192
|
#define MD2_MAX_TRIANGLES 8192
|
||||||
#define MD2_MAX_VERTICES 4096
|
#define MD2_MAX_VERTICES 4096
|
||||||
#define MD2_MAX_TEXCOORDS 4096
|
#define MD2_MAX_TEXCOORDS 4096
|
||||||
|
|
|
@ -107,17 +107,17 @@ static void releaseLineChains(void)
|
||||||
|
|
||||||
for (i = 0; i < numsectors; i++)
|
for (i = 0; i < numsectors; i++)
|
||||||
{
|
{
|
||||||
sector = §ors[i];
|
sector = §ors[i];
|
||||||
nextElem = sector->sectorLines;
|
nextElem = sector->sectorLines;
|
||||||
|
|
||||||
while (nextElem)
|
while (nextElem)
|
||||||
{
|
{
|
||||||
thisElem = nextElem;
|
thisElem = nextElem;
|
||||||
nextElem = thisElem->next;
|
nextElem = thisElem->next;
|
||||||
free(thisElem);
|
free(thisElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
sector->sectorLines = NULL;
|
sector->sectorLines = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ static void sortStacklist(sector_t *sector)
|
||||||
i = 0;
|
i = 0;
|
||||||
finished = true;
|
finished = true;
|
||||||
|
|
||||||
while (NULL != *(list+i+1))
|
while (*(list+i+1))
|
||||||
{
|
{
|
||||||
sec1 = *(list+i);
|
sec1 = *(list+i);
|
||||||
sec2 = *(list+i+1);
|
sec2 = *(list+i+1);
|
||||||
|
@ -438,7 +438,7 @@ static double calcLineoutLength(sector_t *sector)
|
||||||
double length = 0.0L;
|
double length = 0.0L;
|
||||||
chain = sector->sectorLines;
|
chain = sector->sectorLines;
|
||||||
|
|
||||||
while (NULL != chain) // sum up lengths of all lines
|
while (chain) // sum up lengths of all lines
|
||||||
{
|
{
|
||||||
length += lineLength(chain->line);
|
length += lineLength(chain->line);
|
||||||
chain = chain->next;
|
chain = chain->next;
|
||||||
|
@ -454,7 +454,7 @@ static void calcLineouts(sector_t *sector)
|
||||||
size_t secCount = 0;
|
size_t secCount = 0;
|
||||||
sector_t *encSector = *(sector->stackList);
|
sector_t *encSector = *(sector->stackList);
|
||||||
|
|
||||||
while (NULL != encSector)
|
while (encSector)
|
||||||
{
|
{
|
||||||
if (encSector->lineoutLength < 0.0L) // if length has not yet been calculated
|
if (encSector->lineoutLength < 0.0L) // if length has not yet been calculated
|
||||||
{
|
{
|
||||||
|
@ -552,7 +552,7 @@ static boolean areBottomtexturesMissing(sector_t *thisSector)
|
||||||
if (frontSector == backSector) // skip damn renderer tricks here
|
if (frontSector == backSector) // skip damn renderer tricks here
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (frontSector == NULL || backSector == NULL)
|
if (!frontSector || !backSector)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sider = &sides[thisElem->line->sidenum[0]];
|
sider = &sides[thisElem->line->sidenum[0]];
|
||||||
|
@ -587,73 +587,12 @@ static boolean areBottomtexturesMissing(sector_t *thisSector)
|
||||||
static boolean isCeilingFloating(sector_t *thisSector)
|
static boolean isCeilingFloating(sector_t *thisSector)
|
||||||
{
|
{
|
||||||
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
||||||
boolean floating = true;
|
|
||||||
linechain_t *thisElem, *nextElem;
|
linechain_t *thisElem, *nextElem;
|
||||||
|
|
||||||
if (!thisSector)
|
if (!thisSector)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nextElem = thisSector->sectorLines;
|
nextElem = thisSector->sectorLines;
|
||||||
|
|
||||||
while (NULL != nextElem) // walk through chain
|
|
||||||
{
|
|
||||||
thisElem = nextElem;
|
|
||||||
nextElem = thisElem->next;
|
|
||||||
|
|
||||||
frontSector = thisElem->line->frontsector;
|
|
||||||
backSector = thisElem->line->backsector;
|
|
||||||
|
|
||||||
if (frontSector == thisSector)
|
|
||||||
adjSector = backSector;
|
|
||||||
else
|
|
||||||
adjSector = frontSector;
|
|
||||||
|
|
||||||
if (!adjSector) // assume floating sectors have surrounding sectors
|
|
||||||
{
|
|
||||||
floating = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!refSector)
|
|
||||||
{
|
|
||||||
refSector = adjSector;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
|
||||||
if (thisSector->ceilingheight == adjSector->ceilingheight ||
|
|
||||||
refSector != adjSector)
|
|
||||||
{
|
|
||||||
floating = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now check for walltextures
|
|
||||||
if (floating)
|
|
||||||
{
|
|
||||||
if (!areToptexturesMissing(thisSector))
|
|
||||||
{
|
|
||||||
floating = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return floating;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// check if no adjacent sector has same ceiling height
|
|
||||||
// FIXME: throw that together with isCeilingFloating??
|
|
||||||
//
|
|
||||||
static boolean isFloorFloating(sector_t *thisSector)
|
|
||||||
{
|
|
||||||
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
|
||||||
boolean floating = true;
|
|
||||||
linechain_t *thisElem, *nextElem;
|
|
||||||
|
|
||||||
if (!thisSector)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nextElem = thisSector->sectorLines;
|
|
||||||
|
|
||||||
while (nextElem) // walk through chain
|
while (nextElem) // walk through chain
|
||||||
{
|
{
|
||||||
|
@ -668,36 +607,83 @@ static boolean isFloorFloating(sector_t *thisSector)
|
||||||
else
|
else
|
||||||
adjSector = frontSector;
|
adjSector = frontSector;
|
||||||
|
|
||||||
if (NULL == adjSector) // assume floating sectors have surrounding sectors
|
if (!adjSector) // assume floating sectors have surrounding sectors
|
||||||
{
|
return false;
|
||||||
floating = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == refSector)
|
#ifdef ESLOPE
|
||||||
|
if (adjSector->c_slope) // Don't bother with slopes
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!refSector)
|
||||||
{
|
{
|
||||||
refSector = adjSector;
|
refSector = adjSector;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
||||||
if (thisSector->floorheight == adjSector->floorheight ||
|
if (thisSector->ceilingheight == adjSector->ceilingheight || refSector != adjSector)
|
||||||
refSector != adjSector)
|
return false;
|
||||||
{
|
|
||||||
floating = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check for walltextures
|
// now check for walltextures
|
||||||
if (floating)
|
if (!areToptexturesMissing(thisSector))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if no adjacent sector has same ceiling height
|
||||||
|
// FIXME: throw that together with isCeilingFloating??
|
||||||
|
//
|
||||||
|
static boolean isFloorFloating(sector_t *thisSector)
|
||||||
|
{
|
||||||
|
sector_t *adjSector, *refSector = NULL, *frontSector, *backSector;
|
||||||
|
linechain_t *thisElem, *nextElem;
|
||||||
|
|
||||||
|
if (!thisSector)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
nextElem = thisSector->sectorLines;
|
||||||
|
|
||||||
|
while (nextElem) // walk through chain
|
||||||
{
|
{
|
||||||
if (!areBottomtexturesMissing(thisSector))
|
thisElem = nextElem;
|
||||||
|
nextElem = thisElem->next;
|
||||||
|
|
||||||
|
frontSector = thisElem->line->frontsector;
|
||||||
|
backSector = thisElem->line->backsector;
|
||||||
|
|
||||||
|
if (frontSector == thisSector)
|
||||||
|
adjSector = backSector;
|
||||||
|
else
|
||||||
|
adjSector = frontSector;
|
||||||
|
|
||||||
|
if (!adjSector) // assume floating sectors have surrounding sectors
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (adjSector->f_slope) // Don't bother with slopes
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!refSector)
|
||||||
{
|
{
|
||||||
floating = false;
|
refSector = adjSector;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if adjacent sector has same height or more than one adjacent sector exists -> stop
|
||||||
|
if (thisSector->floorheight == adjSector->floorheight || refSector != adjSector)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return floating;
|
|
||||||
|
// now check for walltextures
|
||||||
|
if (!areBottomtexturesMissing(thisSector))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -707,14 +693,12 @@ static fixed_t estimateCeilHeight(sector_t *thisSector)
|
||||||
{
|
{
|
||||||
sector_t *adjSector;
|
sector_t *adjSector;
|
||||||
|
|
||||||
if (!thisSector ||
|
if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
|
||||||
!thisSector->sectorLines ||
|
|
||||||
!thisSector->sectorLines->line)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
adjSector = thisSector->sectorLines->line->frontsector;
|
adjSector = thisSector->sectorLines->line->frontsector;
|
||||||
if (adjSector == thisSector)
|
if (adjSector == thisSector)
|
||||||
adjSector = thisSector->sectorLines->line->backsector;
|
adjSector = thisSector->sectorLines->line->backsector;
|
||||||
|
|
||||||
if (!adjSector)
|
if (!adjSector)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -729,17 +713,15 @@ static fixed_t estimateFloorHeight(sector_t *thisSector)
|
||||||
{
|
{
|
||||||
sector_t *adjSector;
|
sector_t *adjSector;
|
||||||
|
|
||||||
if (!thisSector ||
|
if (!thisSector || !thisSector->sectorLines || !thisSector->sectorLines->line)
|
||||||
!thisSector->sectorLines ||
|
return 0;
|
||||||
!thisSector->sectorLines->line)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
adjSector = thisSector->sectorLines->line->frontsector;
|
adjSector = thisSector->sectorLines->line->frontsector;
|
||||||
if (adjSector == thisSector)
|
if (adjSector == thisSector)
|
||||||
adjSector = thisSector->sectorLines->line->backsector;
|
adjSector = thisSector->sectorLines->line->backsector;
|
||||||
|
|
||||||
if (NULL == adjSector)
|
if (!adjSector)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return adjSector->floorheight;
|
return adjSector->floorheight;
|
||||||
}
|
}
|
||||||
|
@ -845,18 +827,12 @@ void HWR_CorrectSWTricks(void)
|
||||||
// correct height of floating sectors
|
// correct height of floating sectors
|
||||||
if (isCeilingFloating(floatSector))
|
if (isCeilingFloating(floatSector))
|
||||||
{
|
{
|
||||||
fixed_t corrheight;
|
floatSector->virtualCeilingheight = estimateCeilHeight(floatSector);
|
||||||
|
|
||||||
corrheight = estimateCeilHeight(floatSector);
|
|
||||||
floatSector->virtualCeilingheight = corrheight;
|
|
||||||
floatSector->virtualCeiling = true;
|
floatSector->virtualCeiling = true;
|
||||||
}
|
}
|
||||||
if (isFloorFloating(floatSector))
|
if (isFloorFloating(floatSector))
|
||||||
{
|
{
|
||||||
fixed_t corrheight;
|
floatSector->virtualFloorheight = estimateFloorHeight(floatSector);
|
||||||
|
|
||||||
corrheight = estimateFloorHeight(floatSector);
|
|
||||||
floatSector->virtualFloorheight = corrheight;
|
|
||||||
floatSector->virtualFloor = true;
|
floatSector->virtualFloor = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
720
src/info.c
720
src/info.c
|
@ -114,7 +114,6 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
// Collectible Items
|
// Collectible Items
|
||||||
"RING",
|
"RING",
|
||||||
"TRNG", // Team Rings
|
"TRNG", // Team Rings
|
||||||
"EMMY", // emerald test
|
|
||||||
"TOKE", // Special Stage Token
|
"TOKE", // Special Stage Token
|
||||||
"RFLG", // Red CTF Flag
|
"RFLG", // Red CTF Flag
|
||||||
"BFLG", // Blue CTF Flag
|
"BFLG", // Blue CTF Flag
|
||||||
|
@ -131,6 +130,8 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
"SPIK", // Spike Ball
|
"SPIK", // Spike Ball
|
||||||
"SFLM", // Spin fire
|
"SFLM", // Spin fire
|
||||||
"USPK", // Floor spike
|
"USPK", // Floor spike
|
||||||
|
"WSPK", // Wall spike
|
||||||
|
"WSPB", // Wall spike base
|
||||||
"STPT", // Starpost
|
"STPT", // Starpost
|
||||||
"BMNE", // Big floating mine
|
"BMNE", // Big floating mine
|
||||||
|
|
||||||
|
@ -181,6 +182,12 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
"FWR4",
|
"FWR4",
|
||||||
"BUS1", // GFZ Bush w/ berries
|
"BUS1", // GFZ Bush w/ berries
|
||||||
"BUS2", // GFZ Bush w/o berries
|
"BUS2", // GFZ Bush w/o berries
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
"TRE1", // GFZ
|
||||||
|
"TRE2", // Checker
|
||||||
|
"TRE3", // Frozen Hillside
|
||||||
|
"TRE4", // Polygon
|
||||||
|
"TRE5", // Bush tree
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
"THZP", // Techno Hill Zone Plant
|
"THZP", // Techno Hill Zone Plant
|
||||||
|
@ -204,6 +211,10 @@ char sprnames[NUMSPRITES + 1][5] =
|
||||||
"BMCH", // Big Mace Chain
|
"BMCH", // Big Mace Chain
|
||||||
"SMCE", // Small Mace
|
"SMCE", // Small Mace
|
||||||
"BMCE", // Big Mace
|
"BMCE", // Big Mace
|
||||||
|
"YSPB", // Yellow spring on a ball
|
||||||
|
"RSPB", // Red spring on a ball
|
||||||
|
"SFBR", // Small Firebar
|
||||||
|
"BFBR", // Big Firebar
|
||||||
|
|
||||||
// Arid Canyon Scenery
|
// Arid Canyon Scenery
|
||||||
"BTBL", // Big tumbleweed
|
"BTBL", // Big tumbleweed
|
||||||
|
@ -1409,14 +1420,10 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3
|
{SPR_GWLR, 2, 1, {NULL}, 0, 0, S_GRAVWELLRED}, // S_GRAVWELLRED3
|
||||||
|
|
||||||
// Individual Team Rings (now with shield attracting action! =P)
|
// Individual Team Rings (now with shield attracting action! =P)
|
||||||
{SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING1
|
{SPR_TRNG, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_TEAMRING}, // S_TEAMRING
|
||||||
|
|
||||||
// Special Stage Token
|
// Special Stage Token
|
||||||
{SPR_EMMY, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 6, 2, S_EMMY}, // S_EMMY
|
{SPR_TOKE, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 19, 1, S_TOKEN}, // S_TOKEN
|
||||||
|
|
||||||
// Special Stage Token
|
|
||||||
{SPR_TOKE, FF_TRANS50|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_TOKEN
|
|
||||||
{SPR_TOKE, FF_TRANS50|FF_FULLBRIGHT, 1, {A_CapeChase}, 0, 0, S_MOVINGTOKEN}, // S_MOVINGTOKEN
|
|
||||||
|
|
||||||
// CTF Flags
|
// CTF Flags
|
||||||
{SPR_RFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDFLAG
|
{SPR_RFLG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDFLAG
|
||||||
|
@ -1560,13 +1567,24 @@ state_t states[NUMSTATES] =
|
||||||
|
|
||||||
// Floor Spike
|
// Floor Spike
|
||||||
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
|
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
|
||||||
{SPR_USPK, 5, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
|
{SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
|
||||||
{SPR_USPK, 4, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3
|
{SPR_USPK, 2, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3
|
||||||
{SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted
|
{SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted
|
||||||
{SPR_USPK, 4, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5
|
{SPR_USPK, 2, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5
|
||||||
{SPR_USPK, 5, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6
|
{SPR_USPK, 1, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6
|
||||||
{SPR_USPK, 1,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles
|
{SPR_USPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles
|
||||||
{SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
{SPR_USPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2
|
||||||
|
|
||||||
|
// Wall Spike
|
||||||
|
{SPR_WSPK, 0|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 1, 0, S_WALLSPIKE2}, // S_WALLSPIKE1 -- Fully extended
|
||||||
|
{SPR_WSPK, 1|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE3}, // S_WALLSPIKE2
|
||||||
|
{SPR_WSPK, 2|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE4}, // S_WALLSPIKE3
|
||||||
|
{SPR_WSPK, 3|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 0, 0, S_WALLSPIKE5}, // S_WALLSPIKE4 -- Fully retracted
|
||||||
|
{SPR_WSPK, 2|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE6}, // S_WALLSPIKE5
|
||||||
|
{SPR_WSPK, 1|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE1}, // S_WALLSPIKE6
|
||||||
|
{SPR_WSPB, 0|FF_PAPERSPRITE,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKEBASE -- Base
|
||||||
|
{SPR_WSPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED1 -- Busted spike particles
|
||||||
|
{SPR_WSPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED2
|
||||||
|
|
||||||
// Starpost
|
// Starpost
|
||||||
{SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE
|
{SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE
|
||||||
|
@ -1761,6 +1779,18 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH
|
{SPR_BUS1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BERRYBUSH
|
||||||
{SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH
|
{SPR_BUS2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSH
|
||||||
|
|
||||||
|
// Trees
|
||||||
|
{SPR_TRE1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GFZTREE
|
||||||
|
{SPR_TRE1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_GFZBERRYTREE
|
||||||
|
{SPR_TRE1, 2, -1, {NULL}, 0, 0, S_NULL}, // S_GFZCHERRYTREE
|
||||||
|
{SPR_TRE2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CHECKERTREE
|
||||||
|
{SPR_TRE2, 1, -1, {NULL}, 0, 0, S_NULL}, // S_CHECKERSUNSETTREE
|
||||||
|
{SPR_TRE3, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FHZTREE
|
||||||
|
{SPR_TRE3, 1, -1, {NULL}, 0, 0, S_NULL}, // S_FHZPINKTREE
|
||||||
|
{SPR_TRE4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POLYGONTREE
|
||||||
|
{SPR_TRE5, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHTREE
|
||||||
|
{SPR_TRE5, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BUSHREDTREE
|
||||||
|
|
||||||
{SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA
|
{SPR_THZP, FF_ANIMATE, -1, {NULL}, 7, 4, S_NULL}, // S_THZFLOWERA
|
||||||
{SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB
|
{SPR_FWR5, FF_ANIMATE, -1, {NULL}, 19, 2, S_NULL}, // S_THZFLOWERB
|
||||||
|
|
||||||
|
@ -1804,13 +1834,13 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
|
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
|
||||||
|
|
||||||
// Flame
|
// Flame
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20, 3, {A_FlameParticle}, 3, 0, S_FLAME2}, // S_FLAME1
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME2}, // S_FLAME1
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|1, 3, {NULL}, 0, 0, S_FLAME3}, // S_FLAME2
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|1, 3, {NULL}, 0, 0 , S_FLAME3}, // S_FLAME2
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|2, 3, {A_FlameParticle}, 3, 0, S_FLAME4}, // S_FLAME3
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|2, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME4}, // S_FLAME3
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0, S_FLAME5}, // S_FLAME4
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|3, 3, {NULL}, 0, 0 , S_FLAME5}, // S_FLAME4
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|4, 3, {A_FlameParticle}, 3, 0, S_FLAME6}, // S_FLAME5
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|4, 3, {A_FlameParticle}, 3, FRACUNIT/2, S_FLAME6}, // S_FLAME5
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|5, 3, {NULL}, 0, 0, S_FLAME1}, // S_FLAME6
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|5, 3, {NULL}, 0, 0 , S_FLAME1}, // S_FLAME6
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS10|6, 24, {NULL}, 0, 0, S_NULL}, // S_FLAMEPARTICLE
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS10|6, 24, {NULL}, 0, 0 , S_NULL}, // S_FLAMEPARTICLE
|
||||||
|
|
||||||
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|FF_ANIMATE, -1, {NULL}, 5, 3, S_FLAME2}, // S_FLAMEREST
|
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANS20|FF_ANIMATE, -1, {NULL}, 5, 3, S_FLAME2}, // S_FLAMEREST
|
||||||
|
|
||||||
|
@ -1821,31 +1851,75 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_SLING2}, // S_SLING1
|
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_SLING2}, // S_SLING1
|
||||||
{SPR_NULL, 0, -1, {A_SlingAppear}, 0, 0, S_NULL}, // S_SLING2
|
{SPR_NULL, 0, -1, {A_SlingAppear}, 0, 0, S_NULL}, // S_SLING2
|
||||||
|
|
||||||
// Small Mace Chain
|
// CEZ maces and chains
|
||||||
{SPR_SMCH, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACECHAIN}, // S_SMALLMACECHAIN
|
{SPR_SMCH, 0, -1, {NULL}, 0, 0, S_SMALLMACECHAIN}, // S_SMALLMACECHAIN
|
||||||
|
{SPR_BMCH, 0, -1, {NULL}, 0, 0, S_BIGMACECHAIN}, // S_BIGMACECHAIN
|
||||||
|
{SPR_SMCE, 0, -1, {NULL}, 0, 0, S_SMALLMACE}, // S_SMALLMACE
|
||||||
|
{SPR_BMCE, 0, -1, {NULL}, 0, 0, S_BIGMACE}, // S_BIGMACE
|
||||||
|
|
||||||
// Big Mace Chain
|
// Yellow spring on a ball
|
||||||
{SPR_BMCH, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACECHAIN}, // S_BIGMACECHAIN
|
{SPR_YSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRINGBALL
|
||||||
|
{SPR_YSPB, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRINGBALL3}, // S_YELLOWSPRINGBALL2
|
||||||
|
{SPR_YSPB, 3, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL4}, // S_YELLOWSPRINGBALL3
|
||||||
|
{SPR_YSPB, 2, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL5}, // S_YELLOWSPRINGBALL4
|
||||||
|
{SPR_YSPB, 1, 1, {NULL}, 0, 0, S_YELLOWSPRINGBALL}, // S_YELLOWSPRINGBALL5
|
||||||
|
|
||||||
// Small Mace
|
// Red spring on a ball
|
||||||
{SPR_SMCE, 0, 1, {A_MaceRotate}, 0, 0, S_SMALLMACE}, // S_SMALLMACE
|
{SPR_RSPB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRINGBALL
|
||||||
|
{SPR_RSPB, 4, 4, {A_Pain}, 0, 0, S_REDSPRINGBALL3}, // S_REDSPRINGBALL2
|
||||||
|
{SPR_RSPB, 3, 1, {NULL}, 0, 0, S_REDSPRINGBALL4}, // S_REDSPRINGBALL3
|
||||||
|
{SPR_RSPB, 2, 1, {NULL}, 0, 0, S_REDSPRINGBALL5}, // S_REDSPRINGBALL4
|
||||||
|
{SPR_RSPB, 1, 1, {NULL}, 0, 0, S_REDSPRINGBALL}, // S_REDSPRINGBALL5
|
||||||
|
|
||||||
// Big Mace
|
// Small Firebar
|
||||||
{SPR_BMCE, 0, 1, {A_MaceRotate}, 0, 0, S_BIGMACE}, // S_BIGMACE
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR2}, // S_SMALLFIREBAR1
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 1, 1, {NULL}, 0, 0, S_SMALLFIREBAR3}, // S_SMALLFIREBAR2
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 2, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR4}, // S_SMALLFIREBAR3
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 3, 1, {NULL}, 0, 0, S_SMALLFIREBAR5}, // S_SMALLFIREBAR4
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 4, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR6}, // S_SMALLFIREBAR5
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 5, 1, {NULL}, 0, 0, S_SMALLFIREBAR7}, // S_SMALLFIREBAR6
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 6, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR8}, // S_SMALLFIREBAR7
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 7, 1, {NULL}, 0, 0, S_SMALLFIREBAR9}, // S_SMALLFIREBAR8
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 8, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR10}, // S_SMALLFIREBAR9
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20| 9, 1, {NULL}, 0, 0, S_SMALLFIREBAR11}, // S_SMALLFIREBAR10
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|10, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR12}, // S_SMALLFIREBAR11
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|11, 1, {NULL}, 0, 0, S_SMALLFIREBAR13}, // S_SMALLFIREBAR12
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|12, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR14}, // S_SMALLFIREBAR13
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|13, 1, {NULL}, 0, 0, S_SMALLFIREBAR15}, // S_SMALLFIREBAR14
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|14, 1, {A_FlameParticle}, 3, FRACUNIT/3, S_SMALLFIREBAR16}, // S_SMALLFIREBAR15
|
||||||
|
{SPR_SFBR, FF_FULLBRIGHT|FF_TRANS20|15, 1, {NULL}, 0, 0, S_SMALLFIREBAR1}, // S_SMALLFIREBAR16
|
||||||
|
|
||||||
|
// Big Firebar
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR2}, // S_BIGFIREBAR1
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 1, 1, {NULL}, 0, 0, S_BIGFIREBAR3}, // S_BIGFIREBAR2
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 2, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR4}, // S_BIGFIREBAR3
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 3, 1, {NULL}, 0, 0, S_BIGFIREBAR5}, // S_BIGFIREBAR4
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 4, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR6}, // S_BIGFIREBAR5
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 5, 1, {NULL}, 0, 0, S_BIGFIREBAR7}, // S_BIGFIREBAR6
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 6, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR8}, // S_BIGFIREBAR7
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 7, 1, {NULL}, 0, 0, S_BIGFIREBAR9}, // S_BIGFIREBAR8
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 8, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR10}, // S_BIGFIREBAR9
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20| 9, 1, {NULL}, 0, 0, S_BIGFIREBAR11}, // S_BIGFIREBAR10
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|10, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR12}, // S_BIGFIREBAR11
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|11, 1, {NULL}, 0, 0, S_BIGFIREBAR13}, // S_BIGFIREBAR12
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|12, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR14}, // S_BIGFIREBAR13
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|13, 1, {NULL}, 0, 0, S_BIGFIREBAR15}, // S_BIGFIREBAR14
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|14, 1, {A_FlameParticle}, 3, FRACUNIT/2, S_BIGFIREBAR16}, // S_BIGFIREBAR15
|
||||||
|
{SPR_BFBR, FF_FULLBRIGHT|FF_TRANS20|15, 1, {NULL}, 0, 0, S_BIGFIREBAR1}, // S_BIGFIREBAR16
|
||||||
|
|
||||||
// CEZ Flower
|
// CEZ Flower
|
||||||
{SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER1
|
{SPR_FWR4, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZFLOWER1
|
||||||
|
|
||||||
// Big Tumbleweed
|
// Big Tumbleweed
|
||||||
{SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED
|
{SPR_BTBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BIGTUMBLEWEED
|
||||||
{SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1
|
{SPR_BTBL, 0, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL2}, // S_BIGTUMBLEWEED_ROLL1
|
||||||
{SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2
|
{SPR_BTBL, 1, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL3}, // S_BIGTUMBLEWEED_ROLL2
|
||||||
{SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3
|
{SPR_BTBL, 2, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL4}, // S_BIGTUMBLEWEED_ROLL3
|
||||||
{SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4
|
{SPR_BTBL, 3, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL5}, // S_BIGTUMBLEWEED_ROLL4
|
||||||
{SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5
|
{SPR_BTBL, 4, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL6}, // S_BIGTUMBLEWEED_ROLL5
|
||||||
{SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6
|
{SPR_BTBL, 5, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL7}, // S_BIGTUMBLEWEED_ROLL6
|
||||||
{SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7
|
{SPR_BTBL, 6, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL8}, // S_BIGTUMBLEWEED_ROLL7
|
||||||
{SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8
|
{SPR_BTBL, 7, 5, {NULL}, 0, 0, S_BIGTUMBLEWEED_ROLL1}, // S_BIGTUMBLEWEED_ROLL8
|
||||||
|
|
||||||
// Little Tumbleweed
|
// Little Tumbleweed
|
||||||
{SPR_STBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LITTLETUMBLEWEED
|
{SPR_STBL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LITTLETUMBLEWEED
|
||||||
|
@ -2870,16 +2944,11 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS
|
{SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP1
|
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP
|
||||||
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP2
|
{SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSDRILLREFILL
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP3
|
{SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSHELPER
|
||||||
{SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP4
|
{SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSEXTRATIME
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP5
|
{SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSLINKFREEZE
|
||||||
{SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP6
|
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP7
|
|
||||||
{SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP8
|
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP9
|
|
||||||
{SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP10
|
|
||||||
|
|
||||||
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
|
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
|
||||||
|
|
||||||
|
@ -5162,9 +5231,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_EMMY
|
{ // MT_TOKEN
|
||||||
312, // doomednum
|
312, // doomednum
|
||||||
S_EMMY, // spawnstate
|
S_TOKEN, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NULL, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
|
@ -5189,33 +5258,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_TOKEN
|
|
||||||
-1, // doomednum
|
|
||||||
S_TOKEN, // spawnstate
|
|
||||||
1000, // spawnhealth
|
|
||||||
S_MOVINGTOKEN, // 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
|
|
||||||
8*FRACUNIT, // radius
|
|
||||||
16*FRACUNIT, // height
|
|
||||||
0, // display offset
|
|
||||||
100, // mass
|
|
||||||
0, // damage
|
|
||||||
sfx_None, // activesound
|
|
||||||
MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags
|
|
||||||
S_NULL // raisestate
|
|
||||||
},
|
|
||||||
|
|
||||||
{ // MT_REDFLAG
|
{ // MT_REDFLAG
|
||||||
310, // doomednum
|
310, // doomednum
|
||||||
S_REDFLAG, // spawnstate
|
S_REDFLAG, // spawnstate
|
||||||
|
@ -5993,6 +6035,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_WALLSPIKE
|
||||||
|
522, // doomednum
|
||||||
|
S_WALLSPIKE1, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_s3k64, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_WALLSPIKED1, // deathstate
|
||||||
|
S_WALLSPIKED2, // xdeathstate
|
||||||
|
sfx_mspogo, // deathsound
|
||||||
|
2*TICRATE, // speed
|
||||||
|
16*FRACUNIT, // radius
|
||||||
|
14*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
4, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_WALLSPIKEBASE
|
||||||
|
-1, // doomednum
|
||||||
|
S_WALLSPIKEBASE, // 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
|
||||||
|
7*FRACUNIT, // radius
|
||||||
|
14*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
4, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPTHING, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_STARPOST
|
{ // MT_STARPOST
|
||||||
502, // doomednum
|
502, // doomednum
|
||||||
S_STARPOST_IDLE, // spawnstate
|
S_STARPOST_IDLE, // spawnstate
|
||||||
|
@ -8045,6 +8141,276 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_GFZTREE
|
||||||
|
806, // doomednum
|
||||||
|
S_GFZTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
128*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SOLID|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_GFZBERRYTREE
|
||||||
|
807, // doomednum
|
||||||
|
S_GFZBERRYTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
128*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SOLID|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_GFZCHERRYTREE
|
||||||
|
808, // doomednum
|
||||||
|
S_GFZCHERRYTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
128*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SOLID|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_CHECKERTREE
|
||||||
|
810, // doomednum
|
||||||
|
S_CHECKERTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_CHECKERSUNSETTREE
|
||||||
|
811, // doomednum
|
||||||
|
S_CHECKERSUNSETTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_FHZTREE
|
||||||
|
812, // doomednum
|
||||||
|
S_FHZTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_FHZPINKTREE
|
||||||
|
813, // doomednum
|
||||||
|
S_FHZPINKTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_POLYGONTREE
|
||||||
|
814, // doomednum
|
||||||
|
S_POLYGONTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_BUSHTREE
|
||||||
|
815, // doomednum
|
||||||
|
S_BUSHTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_BUSHREDTREE
|
||||||
|
816, // doomednum
|
||||||
|
S_BUSHREDTREE, // 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
|
||||||
|
20*FRACUNIT, // radius
|
||||||
|
200*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_THZFLOWER1
|
{ // MT_THZFLOWER1
|
||||||
900, // doomednum
|
900, // doomednum
|
||||||
S_THZFLOWERA, // spawnstate
|
S_THZFLOWERA, // spawnstate
|
||||||
|
@ -8504,7 +8870,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_SWINGMACEPOINT
|
{ // MT_CHAINMACEPOINT
|
||||||
1105, // doomednum
|
1105, // doomednum
|
||||||
S_INVISIBLE, // spawnstate
|
S_INVISIBLE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
|
@ -8531,7 +8897,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_HANGMACEPOINT
|
{ // MT_SPRINGBALLPOINT
|
||||||
1106, // doomednum
|
1106, // doomednum
|
||||||
S_INVISIBLE, // spawnstate
|
S_INVISIBLE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
|
@ -8558,7 +8924,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
{ // MT_SPINMACEPOINT
|
{ // MT_CHAINPOINT
|
||||||
1107, // doomednum
|
1107, // doomednum
|
||||||
S_INVISIBLE, // spawnstate
|
S_INVISIBLE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
|
@ -8578,7 +8944,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
128*FRACUNIT, // radius
|
128*FRACUNIT, // radius
|
||||||
1*FRACUNIT, // height
|
1*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
200, // mass
|
10000, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||||
|
@ -8612,6 +8978,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ // MT_FIREBARPOINT
|
||||||
|
1109, // doomednum
|
||||||
|
S_INVISIBLE, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
0, // 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
|
||||||
|
10*FRACUNIT, // speed
|
||||||
|
128*FRACUNIT, // radius
|
||||||
|
1*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
200, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_CUSTOMMACEPOINT
|
||||||
|
1111, // doomednum
|
||||||
|
S_INVISIBLE, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
0, // 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
|
||||||
|
10*FRACUNIT, // speed
|
||||||
|
128*FRACUNIT, // radius
|
||||||
|
1*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
200, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
{ // MT_SMALLMACECHAIN
|
{ // MT_SMALLMACECHAIN
|
||||||
-1, // doomednum
|
-1, // doomednum
|
||||||
S_SMALLMACECHAIN, // spawnstate
|
S_SMALLMACECHAIN, // spawnstate
|
||||||
|
@ -8635,7 +9055,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
100, // mass
|
100, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags
|
MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8662,7 +9082,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
100, // mass
|
100, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOGRAVITY|MF_SPECIAL|MF_NOCLIPHEIGHT, // flags
|
MF_SCENERY|MF_SPECIAL|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8685,11 +9105,11 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
24*FRACUNIT, // speed
|
24*FRACUNIT, // speed
|
||||||
17*FRACUNIT, // radius
|
17*FRACUNIT, // radius
|
||||||
34*FRACUNIT, // height
|
34*FRACUNIT, // height
|
||||||
0, // display offset
|
1, // display offset
|
||||||
100, // mass
|
100, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
sfx_mswing, // activesound
|
sfx_mswing, // activesound
|
||||||
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8712,11 +9132,119 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
48*FRACUNIT, // speed
|
48*FRACUNIT, // speed
|
||||||
34*FRACUNIT, // radius
|
34*FRACUNIT, // radius
|
||||||
68*FRACUNIT, // height
|
68*FRACUNIT, // height
|
||||||
0, // display offset
|
1, // display offset
|
||||||
100, // mass
|
100, // mass
|
||||||
1, // damage
|
1, // damage
|
||||||
sfx_mswing, // activesound
|
sfx_mswing, // activesound
|
||||||
MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_YELLOWSPRINGBALL
|
||||||
|
-1, // doomednum
|
||||||
|
S_YELLOWSPRINGBALL, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_YELLOWSPRINGBALL2, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_spring, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
24*FRACUNIT, // speed
|
||||||
|
17*FRACUNIT, // radius
|
||||||
|
34*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
20*FRACUNIT, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_mswing, // activesound
|
||||||
|
MF_SCENERY|MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
|
||||||
|
S_YELLOWSPRINGBALL2 // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_REDSPRINGBALL
|
||||||
|
-1, // doomednum
|
||||||
|
S_REDSPRINGBALL, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_REDSPRINGBALL2, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
0, // painchance
|
||||||
|
sfx_spring, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
24*FRACUNIT, // speed
|
||||||
|
17*FRACUNIT, // radius
|
||||||
|
34*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
32*FRACUNIT, // mass
|
||||||
|
0, // damage
|
||||||
|
sfx_mswing, // activesound
|
||||||
|
MF_SCENERY|MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
|
||||||
|
S_REDSPRINGBALL2 // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_SMALLFIREBAR
|
||||||
|
-1, // doomednum
|
||||||
|
S_SMALLFIREBAR1, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
MT_FLAMEPARTICLE, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
24*FRACUNIT, // speed
|
||||||
|
17*FRACUNIT, // radius
|
||||||
|
34*FRACUNIT, // height
|
||||||
|
0, // display offset
|
||||||
|
100, // mass
|
||||||
|
1, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags
|
||||||
|
S_NULL // raisestate
|
||||||
|
},
|
||||||
|
|
||||||
|
{ // MT_BIGFIREBAR
|
||||||
|
-1, // doomednum
|
||||||
|
S_BIGFIREBAR1, // spawnstate
|
||||||
|
1000, // spawnhealth
|
||||||
|
S_NULL, // seestate
|
||||||
|
sfx_None, // seesound
|
||||||
|
8, // reactiontime
|
||||||
|
sfx_None, // attacksound
|
||||||
|
S_NULL, // painstate
|
||||||
|
MT_FLAMEPARTICLE, // painchance
|
||||||
|
sfx_None, // painsound
|
||||||
|
S_NULL, // meleestate
|
||||||
|
S_NULL, // missilestate
|
||||||
|
S_NULL, // deathstate
|
||||||
|
S_NULL, // xdeathstate
|
||||||
|
sfx_None, // deathsound
|
||||||
|
48*FRACUNIT, // speed
|
||||||
|
34*FRACUNIT, // radius
|
||||||
|
68*FRACUNIT, // height
|
||||||
|
1, // display offset
|
||||||
|
100, // mass
|
||||||
|
1, // damage
|
||||||
|
sfx_None, // activesound
|
||||||
|
MF_SCENERY|MF_PAIN|MF_FIRE|MF_NOGRAVITY, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -13973,9 +14501,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSSUPERLOOP
|
{ // MT_NIGHTSSUPERLOOP
|
||||||
1707, // doomednum
|
1707, // doomednum
|
||||||
S_NIGHTSPOWERUP1, // spawnstate
|
S_NIGHTSSUPERLOOP, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP2, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
@ -14000,9 +14528,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSDRILLREFILL
|
{ // MT_NIGHTSDRILLREFILL
|
||||||
1708, // doomednum
|
1708, // doomednum
|
||||||
S_NIGHTSPOWERUP3, // spawnstate
|
S_NIGHTSDRILLREFILL, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP4, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
@ -14027,9 +14555,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSHELPER
|
{ // MT_NIGHTSHELPER
|
||||||
1709, // doomednum
|
1709, // doomednum
|
||||||
S_NIGHTSPOWERUP5, // spawnstate
|
S_NIGHTSHELPER, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP6, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
@ -14054,9 +14582,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSEXTRATIME
|
{ // MT_NIGHTSEXTRATIME
|
||||||
1711, // doomednum
|
1711, // doomednum
|
||||||
S_NIGHTSPOWERUP7, // spawnstate
|
S_NIGHTSEXTRATIME, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP8, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
@ -14081,9 +14609,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSLINKFREEZE
|
{ // MT_NIGHTSLINKFREEZE
|
||||||
1712, // doomednum
|
1712, // doomednum
|
||||||
S_NIGHTSPOWERUP9, // spawnstate
|
S_NIGHTSLINKFREEZE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP10, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
143
src/info.h
143
src/info.h
|
@ -84,7 +84,6 @@ void A_DetonChase(); // Deton Chaser
|
||||||
void A_CapeChase(); // Fake little Super Sonic cape
|
void A_CapeChase(); // Fake little Super Sonic cape
|
||||||
void A_RotateSpikeBall(); // Spike ball rotation
|
void A_RotateSpikeBall(); // Spike ball rotation
|
||||||
void A_SlingAppear();
|
void A_SlingAppear();
|
||||||
void A_MaceRotate();
|
|
||||||
void A_UnidusBall();
|
void A_UnidusBall();
|
||||||
void A_RockSpawn();
|
void A_RockSpawn();
|
||||||
void A_SetFuse();
|
void A_SetFuse();
|
||||||
|
@ -320,7 +319,6 @@ typedef enum sprite
|
||||||
// Collectible Items
|
// Collectible Items
|
||||||
SPR_RING,
|
SPR_RING,
|
||||||
SPR_TRNG, // Team Rings
|
SPR_TRNG, // Team Rings
|
||||||
SPR_EMMY, // emerald test
|
|
||||||
SPR_TOKE, // Special Stage Token
|
SPR_TOKE, // Special Stage Token
|
||||||
SPR_RFLG, // Red CTF Flag
|
SPR_RFLG, // Red CTF Flag
|
||||||
SPR_BFLG, // Blue CTF Flag
|
SPR_BFLG, // Blue CTF Flag
|
||||||
|
@ -337,6 +335,8 @@ typedef enum sprite
|
||||||
SPR_SPIK, // Spike Ball
|
SPR_SPIK, // Spike Ball
|
||||||
SPR_SFLM, // Spin fire
|
SPR_SFLM, // Spin fire
|
||||||
SPR_USPK, // Floor spike
|
SPR_USPK, // Floor spike
|
||||||
|
SPR_WSPK, // Wall spike
|
||||||
|
SPR_WSPB, // Wall spike base
|
||||||
SPR_STPT, // Starpost
|
SPR_STPT, // Starpost
|
||||||
SPR_BMNE, // Big floating mine
|
SPR_BMNE, // Big floating mine
|
||||||
|
|
||||||
|
@ -387,6 +387,12 @@ typedef enum sprite
|
||||||
SPR_FWR4,
|
SPR_FWR4,
|
||||||
SPR_BUS1, // GFZ Bush w/ berries
|
SPR_BUS1, // GFZ Bush w/ berries
|
||||||
SPR_BUS2, // GFZ Bush w/o berries
|
SPR_BUS2, // GFZ Bush w/o berries
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
SPR_TRE1, // GFZ
|
||||||
|
SPR_TRE2, // Checker
|
||||||
|
SPR_TRE3, // Frozen Hillside
|
||||||
|
SPR_TRE4, // Polygon
|
||||||
|
SPR_TRE5, // Bush tree
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
SPR_THZP, // THZ1 Flower
|
SPR_THZP, // THZ1 Flower
|
||||||
|
@ -410,6 +416,10 @@ typedef enum sprite
|
||||||
SPR_BMCH, // Big Mace Chain
|
SPR_BMCH, // Big Mace Chain
|
||||||
SPR_SMCE, // Small Mace
|
SPR_SMCE, // Small Mace
|
||||||
SPR_BMCE, // Big Mace
|
SPR_BMCE, // Big Mace
|
||||||
|
SPR_YSPB, // Yellow spring on a ball
|
||||||
|
SPR_RSPB, // Red spring on a ball
|
||||||
|
SPR_SFBR, // Small Firebar
|
||||||
|
SPR_BFBR, // Big Firebar
|
||||||
|
|
||||||
// Arid Canyon Scenery
|
// Arid Canyon Scenery
|
||||||
SPR_BTBL, // Big tumbleweed
|
SPR_BTBL, // Big tumbleweed
|
||||||
|
@ -1617,12 +1627,8 @@ typedef enum state
|
||||||
// Individual Team Rings
|
// Individual Team Rings
|
||||||
S_TEAMRING,
|
S_TEAMRING,
|
||||||
|
|
||||||
// Special Stage Token
|
|
||||||
S_EMMY,
|
|
||||||
|
|
||||||
// Special Stage Token
|
// Special Stage Token
|
||||||
S_TOKEN,
|
S_TOKEN,
|
||||||
S_MOVINGTOKEN,
|
|
||||||
|
|
||||||
// CTF Flags
|
// CTF Flags
|
||||||
S_REDFLAG,
|
S_REDFLAG,
|
||||||
|
@ -1773,6 +1779,17 @@ typedef enum state
|
||||||
S_SPIKED1,
|
S_SPIKED1,
|
||||||
S_SPIKED2,
|
S_SPIKED2,
|
||||||
|
|
||||||
|
// Wall spikes
|
||||||
|
S_WALLSPIKE1,
|
||||||
|
S_WALLSPIKE2,
|
||||||
|
S_WALLSPIKE3,
|
||||||
|
S_WALLSPIKE4,
|
||||||
|
S_WALLSPIKE5,
|
||||||
|
S_WALLSPIKE6,
|
||||||
|
S_WALLSPIKEBASE,
|
||||||
|
S_WALLSPIKED1,
|
||||||
|
S_WALLSPIKED2,
|
||||||
|
|
||||||
// Starpost
|
// Starpost
|
||||||
S_STARPOST_IDLE,
|
S_STARPOST_IDLE,
|
||||||
S_STARPOST_FLASH,
|
S_STARPOST_FLASH,
|
||||||
|
@ -1961,6 +1978,7 @@ typedef enum state
|
||||||
S_DEMONFIRE5,
|
S_DEMONFIRE5,
|
||||||
S_DEMONFIRE6,
|
S_DEMONFIRE6,
|
||||||
|
|
||||||
|
// GFZ flowers
|
||||||
S_GFZFLOWERA,
|
S_GFZFLOWERA,
|
||||||
S_GFZFLOWERB,
|
S_GFZFLOWERB,
|
||||||
S_GFZFLOWERC,
|
S_GFZFLOWERC,
|
||||||
|
@ -1968,6 +1986,18 @@ typedef enum state
|
||||||
S_BERRYBUSH,
|
S_BERRYBUSH,
|
||||||
S_BUSH,
|
S_BUSH,
|
||||||
|
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
S_GFZTREE,
|
||||||
|
S_GFZBERRYTREE,
|
||||||
|
S_GFZCHERRYTREE,
|
||||||
|
S_CHECKERTREE,
|
||||||
|
S_CHECKERSUNSETTREE,
|
||||||
|
S_FHZTREE, // Frozen Hillside
|
||||||
|
S_FHZPINKTREE,
|
||||||
|
S_POLYGONTREE,
|
||||||
|
S_BUSHTREE,
|
||||||
|
S_BUSHREDTREE,
|
||||||
|
|
||||||
// THZ Plant
|
// THZ Plant
|
||||||
S_THZFLOWERA,
|
S_THZFLOWERA,
|
||||||
S_THZFLOWERB,
|
S_THZFLOWERB,
|
||||||
|
@ -2029,18 +2059,62 @@ typedef enum state
|
||||||
S_SLING1,
|
S_SLING1,
|
||||||
S_SLING2,
|
S_SLING2,
|
||||||
|
|
||||||
// CEZ Small Mace Chain
|
// CEZ maces and chains
|
||||||
S_SMALLMACECHAIN,
|
S_SMALLMACECHAIN,
|
||||||
|
|
||||||
// CEZ Big Mace Chain
|
|
||||||
S_BIGMACECHAIN,
|
S_BIGMACECHAIN,
|
||||||
|
|
||||||
// CEZ Small Mace
|
|
||||||
S_SMALLMACE,
|
S_SMALLMACE,
|
||||||
|
|
||||||
// CEZ Big Mace
|
|
||||||
S_BIGMACE,
|
S_BIGMACE,
|
||||||
|
|
||||||
|
// Yellow spring on a ball
|
||||||
|
S_YELLOWSPRINGBALL,
|
||||||
|
S_YELLOWSPRINGBALL2,
|
||||||
|
S_YELLOWSPRINGBALL3,
|
||||||
|
S_YELLOWSPRINGBALL4,
|
||||||
|
S_YELLOWSPRINGBALL5,
|
||||||
|
|
||||||
|
// Red spring on a ball
|
||||||
|
S_REDSPRINGBALL,
|
||||||
|
S_REDSPRINGBALL2,
|
||||||
|
S_REDSPRINGBALL3,
|
||||||
|
S_REDSPRINGBALL4,
|
||||||
|
S_REDSPRINGBALL5,
|
||||||
|
|
||||||
|
// Small Firebar
|
||||||
|
S_SMALLFIREBAR1,
|
||||||
|
S_SMALLFIREBAR2,
|
||||||
|
S_SMALLFIREBAR3,
|
||||||
|
S_SMALLFIREBAR4,
|
||||||
|
S_SMALLFIREBAR5,
|
||||||
|
S_SMALLFIREBAR6,
|
||||||
|
S_SMALLFIREBAR7,
|
||||||
|
S_SMALLFIREBAR8,
|
||||||
|
S_SMALLFIREBAR9,
|
||||||
|
S_SMALLFIREBAR10,
|
||||||
|
S_SMALLFIREBAR11,
|
||||||
|
S_SMALLFIREBAR12,
|
||||||
|
S_SMALLFIREBAR13,
|
||||||
|
S_SMALLFIREBAR14,
|
||||||
|
S_SMALLFIREBAR15,
|
||||||
|
S_SMALLFIREBAR16,
|
||||||
|
|
||||||
|
// Big Firebar
|
||||||
|
S_BIGFIREBAR1,
|
||||||
|
S_BIGFIREBAR2,
|
||||||
|
S_BIGFIREBAR3,
|
||||||
|
S_BIGFIREBAR4,
|
||||||
|
S_BIGFIREBAR5,
|
||||||
|
S_BIGFIREBAR6,
|
||||||
|
S_BIGFIREBAR7,
|
||||||
|
S_BIGFIREBAR8,
|
||||||
|
S_BIGFIREBAR9,
|
||||||
|
S_BIGFIREBAR10,
|
||||||
|
S_BIGFIREBAR11,
|
||||||
|
S_BIGFIREBAR12,
|
||||||
|
S_BIGFIREBAR13,
|
||||||
|
S_BIGFIREBAR14,
|
||||||
|
S_BIGFIREBAR15,
|
||||||
|
S_BIGFIREBAR16,
|
||||||
|
|
||||||
S_CEZFLOWER1,
|
S_CEZFLOWER1,
|
||||||
|
|
||||||
// Big Tumbleweed
|
// Big Tumbleweed
|
||||||
|
@ -3014,16 +3088,11 @@ typedef enum state
|
||||||
S_NIGHTSWING_XMAS,
|
S_NIGHTSWING_XMAS,
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
S_NIGHTSPOWERUP1,
|
S_NIGHTSSUPERLOOP,
|
||||||
S_NIGHTSPOWERUP2,
|
S_NIGHTSDRILLREFILL,
|
||||||
S_NIGHTSPOWERUP3,
|
S_NIGHTSHELPER,
|
||||||
S_NIGHTSPOWERUP4,
|
S_NIGHTSEXTRATIME,
|
||||||
S_NIGHTSPOWERUP5,
|
S_NIGHTSLINKFREEZE,
|
||||||
S_NIGHTSPOWERUP6,
|
|
||||||
S_NIGHTSPOWERUP7,
|
|
||||||
S_NIGHTSPOWERUP8,
|
|
||||||
S_NIGHTSPOWERUP9,
|
|
||||||
S_NIGHTSPOWERUP10,
|
|
||||||
S_EGGCAPSULE,
|
S_EGGCAPSULE,
|
||||||
|
|
||||||
// Orbiting Chaos Emeralds
|
// Orbiting Chaos Emeralds
|
||||||
|
@ -3239,8 +3308,7 @@ typedef enum mobj_type
|
||||||
MT_BLUEBALL, // Blue sphere replacement for special stages
|
MT_BLUEBALL, // Blue sphere replacement for special stages
|
||||||
MT_REDTEAMRING, //Rings collectable by red team.
|
MT_REDTEAMRING, //Rings collectable by red team.
|
||||||
MT_BLUETEAMRING, //Rings collectable by blue team.
|
MT_BLUETEAMRING, //Rings collectable by blue team.
|
||||||
MT_EMMY, // emerald token for special stage
|
MT_TOKEN, // Special Stage token for special stage
|
||||||
MT_TOKEN, // Special Stage Token (uncollectible part)
|
|
||||||
MT_REDFLAG, // Red CTF Flag
|
MT_REDFLAG, // Red CTF Flag
|
||||||
MT_BLUEFLAG, // Blue CTF Flag
|
MT_BLUEFLAG, // Blue CTF Flag
|
||||||
MT_EMBLEM,
|
MT_EMBLEM,
|
||||||
|
@ -3274,6 +3342,8 @@ typedef enum mobj_type
|
||||||
MT_SPECIALSPIKEBALL,
|
MT_SPECIALSPIKEBALL,
|
||||||
MT_SPINFIRE,
|
MT_SPINFIRE,
|
||||||
MT_SPIKE,
|
MT_SPIKE,
|
||||||
|
MT_WALLSPIKE,
|
||||||
|
MT_WALLSPIKEBASE,
|
||||||
MT_STARPOST,
|
MT_STARPOST,
|
||||||
MT_BIGMINE,
|
MT_BIGMINE,
|
||||||
MT_BIGAIRMINE,
|
MT_BIGAIRMINE,
|
||||||
|
@ -3364,6 +3434,17 @@ typedef enum mobj_type
|
||||||
MT_GFZFLOWER3,
|
MT_GFZFLOWER3,
|
||||||
MT_BERRYBUSH,
|
MT_BERRYBUSH,
|
||||||
MT_BUSH,
|
MT_BUSH,
|
||||||
|
// Trees (both GFZ and misc)
|
||||||
|
MT_GFZTREE,
|
||||||
|
MT_GFZBERRYTREE,
|
||||||
|
MT_GFZCHERRYTREE,
|
||||||
|
MT_CHECKERTREE,
|
||||||
|
MT_CHECKERSUNSETTREE,
|
||||||
|
MT_FHZTREE, // Frozen Hillside
|
||||||
|
MT_FHZPINKTREE,
|
||||||
|
MT_POLYGONTREE,
|
||||||
|
MT_BUSHTREE,
|
||||||
|
MT_BUSHREDTREE,
|
||||||
|
|
||||||
// Techno Hill Scenery
|
// Techno Hill Scenery
|
||||||
MT_THZFLOWER1,
|
MT_THZFLOWER1,
|
||||||
|
@ -3387,14 +3468,20 @@ typedef enum mobj_type
|
||||||
MT_FLAMEPARTICLE,
|
MT_FLAMEPARTICLE,
|
||||||
MT_EGGSTATUE, // Eggman Statue
|
MT_EGGSTATUE, // Eggman Statue
|
||||||
MT_MACEPOINT, // Mace rotation point
|
MT_MACEPOINT, // Mace rotation point
|
||||||
MT_SWINGMACEPOINT, // Mace swinging point
|
MT_CHAINMACEPOINT, // Combination of chains and maces point
|
||||||
MT_HANGMACEPOINT, // Hangable mace chain
|
MT_SPRINGBALLPOINT, // Spring ball point
|
||||||
MT_SPINMACEPOINT, // Spin/Controllable mace chain
|
MT_CHAINPOINT, // Mace chain
|
||||||
MT_HIDDEN_SLING, // Spin mace chain (activatable)
|
MT_HIDDEN_SLING, // Spin mace chain (activatable)
|
||||||
|
MT_FIREBARPOINT, // Firebar
|
||||||
|
MT_CUSTOMMACEPOINT, // Custom mace
|
||||||
MT_SMALLMACECHAIN, // Small Mace Chain
|
MT_SMALLMACECHAIN, // Small Mace Chain
|
||||||
MT_BIGMACECHAIN, // Big Mace Chain
|
MT_BIGMACECHAIN, // Big Mace Chain
|
||||||
MT_SMALLMACE, // Small Mace
|
MT_SMALLMACE, // Small Mace
|
||||||
MT_BIGMACE, // Big Mace
|
MT_BIGMACE, // Big Mace
|
||||||
|
MT_YELLOWSPRINGBALL, // Yellow spring on a ball
|
||||||
|
MT_REDSPRINGBALL, // Red spring on a ball
|
||||||
|
MT_SMALLFIREBAR, // Small Firebar
|
||||||
|
MT_BIGFIREBAR, // Big Firebar
|
||||||
MT_CEZFLOWER,
|
MT_CEZFLOWER,
|
||||||
|
|
||||||
// Arid Canyon Scenery
|
// Arid Canyon Scenery
|
||||||
|
|
|
@ -22,8 +22,13 @@
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
#include "lua_hud.h" // hud_running errors
|
#include "lua_hud.h" // hud_running errors
|
||||||
|
|
||||||
|
// for functions not allowed in hud.add hooks
|
||||||
#define NOHUD if (hud_running)\
|
#define NOHUD if (hud_running)\
|
||||||
return luaL_error(L, "HUD rendering code should not call this function!");
|
return luaL_error(L, "HUD rendering code should not call this function!");
|
||||||
|
// for functions not allowed in hooks or coroutines (supercedes above)
|
||||||
|
#define NOHOOK if (!lua_lumploading)\
|
||||||
|
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||||
|
// for functions only allowed within a level
|
||||||
#define INLEVEL if (gamestate != GS_LEVEL)\
|
#define INLEVEL if (gamestate != GS_LEVEL)\
|
||||||
return luaL_error(L, "This function can only be used in a level!");
|
return luaL_error(L, "This function can only be used in a level!");
|
||||||
|
|
||||||
|
@ -184,7 +189,7 @@ static int lib_comAddCommand(lua_State *L)
|
||||||
strlwr(name);
|
strlwr(name);
|
||||||
|
|
||||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||||
NOHUD
|
NOHOOK
|
||||||
if (lua_gettop(L) >= 3)
|
if (lua_gettop(L) >= 3)
|
||||||
{ // For the third argument, only take a boolean or a number.
|
{ // For the third argument, only take a boolean or a number.
|
||||||
lua_settop(L, 3);
|
lua_settop(L, 3);
|
||||||
|
@ -296,7 +301,7 @@ static int lib_cvRegisterVar(lua_State *L)
|
||||||
consvar_t *cvar;
|
consvar_t *cvar;
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
||||||
NOHUD
|
NOHOOK
|
||||||
cvar = lua_newuserdata(L, sizeof(consvar_t));
|
cvar = lua_newuserdata(L, sizeof(consvar_t));
|
||||||
luaL_getmetatable(L, META_CVAR);
|
luaL_getmetatable(L, META_CVAR);
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
|
|
|
@ -46,6 +46,7 @@ enum hook {
|
||||||
hook_ShieldSpawn,
|
hook_ShieldSpawn,
|
||||||
hook_ShieldSpecial,
|
hook_ShieldSpecial,
|
||||||
hook_MobjMoveBlocked,
|
hook_MobjMoveBlocked,
|
||||||
|
hook_MapThingSpawn,
|
||||||
|
|
||||||
hook_MAX // last hook
|
hook_MAX // last hook
|
||||||
};
|
};
|
||||||
|
@ -83,5 +84,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
||||||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||||
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
||||||
|
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = {
|
||||||
"ShieldSpawn",
|
"ShieldSpawn",
|
||||||
"ShieldSpecial",
|
"ShieldSpecial",
|
||||||
"MobjMoveBlocked",
|
"MobjMoveBlocked",
|
||||||
|
"MapThingSpawn",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,8 +109,8 @@ static int lib_addHook(lua_State *L)
|
||||||
|
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
|
|
||||||
if (hud_running)
|
if (!lua_lumploading)
|
||||||
return luaL_error(L, "HUD rendering code should not call this function!");
|
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||||
|
|
||||||
switch(hook.type)
|
switch(hook.type)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +129,7 @@ static int lib_addHook(lua_State *L)
|
||||||
case hook_MobjRemoved:
|
case hook_MobjRemoved:
|
||||||
case hook_HurtMsg:
|
case hook_HurtMsg:
|
||||||
case hook_MobjMoveBlocked:
|
case hook_MobjMoveBlocked:
|
||||||
|
case hook_MapThingSpawn:
|
||||||
hook.s.mt = MT_NULL;
|
hook.s.mt = MT_NULL;
|
||||||
if (lua_isnumber(L, 2))
|
if (lua_isnumber(L, 2))
|
||||||
hook.s.mt = lua_tonumber(L, 2);
|
hook.s.mt = lua_tonumber(L, 2);
|
||||||
|
@ -187,6 +189,7 @@ static int lib_addHook(lua_State *L)
|
||||||
case hook_BossDeath:
|
case hook_BossDeath:
|
||||||
case hook_MobjRemoved:
|
case hook_MobjRemoved:
|
||||||
case hook_MobjMoveBlocked:
|
case hook_MobjMoveBlocked:
|
||||||
|
case hook_MapThingSpawn:
|
||||||
lastp = &mobjhooks[hook.s.mt];
|
lastp = &mobjhooks[hook.s.mt];
|
||||||
break;
|
break;
|
||||||
case hook_JumpSpecial:
|
case hook_JumpSpecial:
|
||||||
|
@ -1073,4 +1076,66 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
||||||
// stack: tables
|
// stack: tables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing)
|
||||||
|
{
|
||||||
|
hook_p hookp;
|
||||||
|
boolean hooked = false;
|
||||||
|
if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8))))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
|
||||||
|
// Look for all generic mobj map thing spawn hooks
|
||||||
|
for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next)
|
||||||
|
if (hookp->type == hook_MapThingSpawn)
|
||||||
|
{
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||||
|
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
hooked = true;
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next)
|
||||||
|
if (hookp->type == hook_MapThingSpawn)
|
||||||
|
{
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||||
|
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
hooked = true;
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
return hooked;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -612,6 +612,9 @@ static int lib_hudadd(lua_State *L)
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
field = luaL_checkoption(L, 2, "game", hudhook_opt);
|
field = luaL_checkoption(L, 2, "game", hudhook_opt);
|
||||||
|
|
||||||
|
if (!lua_lumploading)
|
||||||
|
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
|
lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
|
||||||
I_Assert(lua_istable(L, -1));
|
I_Assert(lua_istable(L, -1));
|
||||||
lua_rawgeti(L, -1, field+2); // HUD[2+]
|
lua_rawgeti(L, -1, field+2); // HUD[2+]
|
||||||
|
|
|
@ -161,6 +161,11 @@ void LUA_ClearExtVars(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Use this variable to prevent certain functions from running
|
||||||
|
// if they were not called on lump load
|
||||||
|
// (i.e. they were called in hooks or coroutines etc)
|
||||||
|
boolean lua_lumploading = false;
|
||||||
|
|
||||||
// Load a script from a MYFILE
|
// Load a script from a MYFILE
|
||||||
static inline void LUA_LoadFile(MYFILE *f, char *name)
|
static inline void LUA_LoadFile(MYFILE *f, char *name)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +203,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||||
name[strlen(wadfiles[wad]->filename)+9] = '\0';
|
name[strlen(wadfiles[wad]->filename)+9] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
LUA_LoadFile(&f, name);
|
lua_lumploading = true; // turn on loading flag
|
||||||
|
LUA_LoadFile(&f, name); // actually load file!
|
||||||
|
lua_lumploading = false; // turn off again
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
Z_Free(f.data);
|
Z_Free(f.data);
|
||||||
|
@ -596,14 +603,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||||
{
|
{
|
||||||
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
||||||
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
||||||
WRITEUINT8(save_p, info - mobjinfo);
|
WRITEUINT16(save_p, info - mobjinfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARCH_STATE:
|
case ARCH_STATE:
|
||||||
{
|
{
|
||||||
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
||||||
WRITEUINT8(save_p, ARCH_STATE);
|
WRITEUINT8(save_p, ARCH_STATE);
|
||||||
WRITEUINT8(save_p, state - states);
|
WRITEUINT16(save_p, state - states);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARCH_MOBJ:
|
case ARCH_MOBJ:
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
void LUA_ClearExtVars(void);
|
void LUA_ClearExtVars(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern boolean lua_lumploading; // is LUA_LoadLump being called?
|
||||||
|
|
||||||
void LUA_LoadLump(UINT16 wad, UINT16 lump);
|
void LUA_LoadLump(UINT16 wad, UINT16 lump);
|
||||||
#ifdef LUA_ALLOW_BYTECODE
|
#ifdef LUA_ALLOW_BYTECODE
|
||||||
void LUA_DumpFile(const char *filename);
|
void LUA_DumpFile(const char *filename);
|
||||||
|
|
20
src/m_cond.h
20
src/m_cond.h
|
@ -66,14 +66,18 @@ typedef struct
|
||||||
} conditionset_t;
|
} conditionset_t;
|
||||||
|
|
||||||
// Emblem information
|
// Emblem information
|
||||||
#define ET_GLOBAL 0 // Global map emblem, var == color
|
#define ET_GLOBAL 0 // Emblem with a position in space
|
||||||
#define ET_SKIN 1 // Skin specific emblem, var == skin
|
#define ET_SKIN 1 // Skin specific emblem with a position in space, var == skin
|
||||||
#define ET_SCORE 2
|
#define ET_MAP 2 // Beat the map
|
||||||
#define ET_TIME 3
|
#define ET_SCORE 3 // Get the score
|
||||||
#define ET_RINGS 4
|
#define ET_TIME 4 // Get the time
|
||||||
#define ET_NGRADE 5
|
#define ET_RINGS 5 // Get the rings
|
||||||
#define ET_NTIME 6
|
#define ET_NGRADE 6 // Get the grade
|
||||||
#define ET_MAP 7
|
#define ET_NTIME 7 // Get the time (NiGHTS mode)
|
||||||
|
|
||||||
|
// Global emblem flags
|
||||||
|
#define GE_NIGHTSPULL 1 // sun off the nights track - loop it
|
||||||
|
#define GE_NIGHTSITEM 2 // moon on the nights track - find it
|
||||||
|
|
||||||
// Map emblem flags
|
// Map emblem flags
|
||||||
#define ME_ALLEMERALDS 1
|
#define ME_ALLEMERALDS 1
|
||||||
|
|
668
src/m_menu.c
668
src/m_menu.c
|
@ -33,6 +33,9 @@
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
||||||
|
// Addfile
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
@ -74,7 +77,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#define SMALLLINEHEIGHT 8
|
#define SMALLLINEHEIGHT 8
|
||||||
#define SLIDER_RANGE 9
|
#define SLIDER_RANGE 9
|
||||||
#define SLIDER_WIDTH 78
|
#define SLIDER_WIDTH 78
|
||||||
#define MAXSTRINGLENGTH 32
|
|
||||||
#define SERVERS_PER_PAGE 11
|
#define SERVERS_PER_PAGE 11
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -211,14 +213,13 @@ menu_t SPauseDef;
|
||||||
|
|
||||||
// Level Select
|
// Level Select
|
||||||
static levelselect_t levelselect = {0, NULL};
|
static levelselect_t levelselect = {0, NULL};
|
||||||
static UINT8 levelselectselect[4];
|
static UINT8 levelselectselect[3];
|
||||||
static patch_t *levselp[2][3];
|
static patch_t *levselp[2][3];
|
||||||
static INT32 lsoffs[2];
|
static INT32 lsoffs[2];
|
||||||
|
|
||||||
#define lsrow levelselectselect[0]
|
#define lsrow levelselectselect[0]
|
||||||
#define lscol levelselectselect[1]
|
#define lscol levelselectselect[1]
|
||||||
#define lstic levelselectselect[2]
|
#define lshli levelselectselect[2]
|
||||||
#define lshli levelselectselect[3]
|
|
||||||
|
|
||||||
#define lshseperation 101
|
#define lshseperation 101
|
||||||
#define lsbasevseperation 62
|
#define lsbasevseperation 62
|
||||||
|
@ -334,12 +335,20 @@ menu_t OP_MonitorToggleDef;
|
||||||
static void M_ScreenshotOptions(INT32 choice);
|
static void M_ScreenshotOptions(INT32 choice);
|
||||||
static void M_EraseData(INT32 choice);
|
static void M_EraseData(INT32 choice);
|
||||||
|
|
||||||
static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight);
|
static void M_Addons(INT32 choice);
|
||||||
|
static void M_AddonsOptions(INT32 choice);
|
||||||
|
static patch_t *addonsp[NUM_EXT+6];
|
||||||
|
static UINT8 addonsresponselimit = 0;
|
||||||
|
|
||||||
|
#define numaddonsshown 4
|
||||||
|
|
||||||
|
static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase);
|
||||||
|
|
||||||
// Drawing functions
|
// Drawing functions
|
||||||
static void M_DrawGenericMenu(void);
|
static void M_DrawGenericMenu(void);
|
||||||
static void M_DrawGenericScrollMenu(void);
|
static void M_DrawGenericScrollMenu(void);
|
||||||
static void M_DrawCenteredMenu(void);
|
static void M_DrawCenteredMenu(void);
|
||||||
|
static void M_DrawAddons(void);
|
||||||
static void M_DrawSkyRoom(void);
|
static void M_DrawSkyRoom(void);
|
||||||
static void M_DrawChecklist(void);
|
static void M_DrawChecklist(void);
|
||||||
static void M_DrawEmblemHints(void);
|
static void M_DrawEmblemHints(void);
|
||||||
|
@ -379,6 +388,7 @@ static boolean M_CancelConnect(void);
|
||||||
#endif
|
#endif
|
||||||
static boolean M_ExitPandorasBox(void);
|
static boolean M_ExitPandorasBox(void);
|
||||||
static boolean M_QuitMultiPlayerMenu(void);
|
static boolean M_QuitMultiPlayerMenu(void);
|
||||||
|
static void M_HandleAddons(INT32 choice);
|
||||||
static void M_HandleLevelPlatter(INT32 choice);
|
static void M_HandleLevelPlatter(INT32 choice);
|
||||||
static void M_HandleSoundTest(INT32 choice);
|
static void M_HandleSoundTest(INT32 choice);
|
||||||
static void M_HandleImageDef(INT32 choice);
|
static void M_HandleImageDef(INT32 choice);
|
||||||
|
@ -487,10 +497,11 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum
|
||||||
// ---------
|
// ---------
|
||||||
static menuitem_t MainMenu[] =
|
static menuitem_t MainMenu[] =
|
||||||
{
|
{
|
||||||
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 84},
|
{IT_CALL |IT_STRING, NULL, "Secrets", M_SecretsMenu, 76},
|
||||||
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 92},
|
{IT_CALL |IT_STRING, NULL, "1 player", M_SinglePlayerMenu, 84},
|
||||||
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 100},
|
{IT_SUBMENU|IT_STRING, NULL, "multiplayer", &MP_MainDef, 92},
|
||||||
{IT_CALL |IT_STRING, NULL, "options", M_Options, 108},
|
{IT_CALL |IT_STRING, NULL, "options", M_Options, 100},
|
||||||
|
{IT_CALL |IT_STRING, NULL, "addons", M_Addons, 108},
|
||||||
{IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116},
|
{IT_CALL |IT_STRING, NULL, "quit game", M_QuitSRB2, 116},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -500,9 +511,15 @@ typedef enum
|
||||||
singleplr,
|
singleplr,
|
||||||
multiplr,
|
multiplr,
|
||||||
options,
|
options,
|
||||||
|
addons,
|
||||||
quitdoom
|
quitdoom
|
||||||
} main_e;
|
} main_e;
|
||||||
|
|
||||||
|
static menuitem_t MISC_AddonsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleAddons, 0}, // dummy menuitem for the control func
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// Pause Menu Mode Attacking Edition
|
// Pause Menu Mode Attacking Edition
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -525,26 +542,28 @@ typedef enum
|
||||||
// ---------------------
|
// ---------------------
|
||||||
static menuitem_t MPauseMenu[] =
|
static menuitem_t MPauseMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
{IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
|
||||||
{IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24},
|
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24},
|
||||||
|
|
||||||
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40},
|
{IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40},
|
||||||
{IT_CALL | IT_STRING, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen
|
{IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen
|
||||||
{IT_CALL | IT_STRING, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen
|
{IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48},
|
{IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48},
|
||||||
{IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48},
|
{IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48},
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
|
{IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
|
||||||
{IT_CALL | IT_STRING, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone
|
{IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone
|
||||||
{IT_CALL | IT_STRING, NULL, "Options", M_Options, 64},
|
{IT_STRING | IT_CALL, NULL, "Options", M_Options, 64},
|
||||||
|
|
||||||
{IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80},
|
{IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 80},
|
||||||
{IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88},
|
{IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 88},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
mpause_scramble = 0,
|
mpause_addons = 0,
|
||||||
|
mpause_scramble,
|
||||||
mpause_switchmap,
|
mpause_switchmap,
|
||||||
|
|
||||||
mpause_continue,
|
mpause_continue,
|
||||||
|
@ -587,6 +606,7 @@ typedef enum
|
||||||
spause_continue,
|
spause_continue,
|
||||||
spause_retry,
|
spause_retry,
|
||||||
spause_options,
|
spause_options,
|
||||||
|
|
||||||
spause_title,
|
spause_title,
|
||||||
spause_quit
|
spause_quit
|
||||||
} spause_e;
|
} spause_e;
|
||||||
|
@ -1318,9 +1338,10 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
||||||
|
|
||||||
static menuitem_t OP_DataOptionsMenu[] =
|
static menuitem_t OP_DataOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10},
|
{IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 10},
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 20},
|
||||||
|
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 20},
|
{IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ScreenshotOptionsMenu[] =
|
static menuitem_t OP_ScreenshotOptionsMenu[] =
|
||||||
|
@ -1367,6 +1388,24 @@ static menuitem_t OP_EraseDataMenu[] =
|
||||||
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static menuitem_t OP_AddonsOptionsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_HEADER, NULL, "Menu", NULL, 0},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 12},
|
||||||
|
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 22},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Identify loaded files via", &cv_addons_md5, 50},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 60},
|
||||||
|
|
||||||
|
{IT_HEADER, NULL, "Search", NULL, 78},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 90},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 100},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
op_addons_folder = 2,
|
||||||
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ServerOptionsMenu[] =
|
static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_HEADER, NULL, "General", NULL, 0},
|
{IT_HEADER, NULL, "General", NULL, 0},
|
||||||
|
@ -1441,6 +1480,18 @@ static menuitem_t OP_MonitorToggleMenu[] =
|
||||||
// Main Menu and related
|
// Main Menu and related
|
||||||
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
||||||
|
|
||||||
|
menu_t MISC_AddonsDef =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
|
||||||
|
&MainDef,
|
||||||
|
MISC_AddonsMenu,
|
||||||
|
M_DrawAddons,
|
||||||
|
50, 28,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
||||||
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
||||||
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
||||||
|
@ -1804,17 +1855,7 @@ menu_t OP_SoundOptionsDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_t OP_ServerOptionsDef =
|
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30);
|
||||||
{
|
|
||||||
"M_SERVER",
|
|
||||||
sizeof (OP_ServerOptionsMenu)/sizeof (menuitem_t),
|
|
||||||
&OP_MainDef,
|
|
||||||
OP_ServerOptionsMenu,
|
|
||||||
M_DrawGenericScrollMenu,
|
|
||||||
30, 30,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
menu_t OP_MonitorToggleDef =
|
menu_t OP_MonitorToggleDef =
|
||||||
{
|
{
|
||||||
|
@ -1856,7 +1897,7 @@ menu_t OP_OpenGLColorDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 30, 30);
|
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
||||||
|
|
||||||
menu_t OP_ScreenshotOptionsDef =
|
menu_t OP_ScreenshotOptionsDef =
|
||||||
{
|
{
|
||||||
|
@ -1870,6 +1911,8 @@ menu_t OP_ScreenshotOptionsDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30);
|
||||||
|
|
||||||
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -2088,6 +2131,12 @@ void Moviemode_mode_Onchange(void)
|
||||||
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Addons_option_Onchange(void)
|
||||||
|
{
|
||||||
|
OP_AddonsOptionsMenu[op_addons_folder].status =
|
||||||
|
(cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// END ORGANIZATION STUFF.
|
// END ORGANIZATION STUFF.
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -2150,9 +2199,12 @@ static void M_ChangeCvar(INT32 choice)
|
||||||
static boolean M_ChangeStringCvar(INT32 choice)
|
static boolean M_ChangeStringCvar(INT32 choice)
|
||||||
{
|
{
|
||||||
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
|
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
|
||||||
char buf[255];
|
char buf[MAXSTRINGLENGTH];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (shiftdown && choice >= 32 && choice <= 127)
|
||||||
|
choice = shiftxform[choice];
|
||||||
|
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case KEY_BACKSPACE:
|
case KEY_BACKSPACE:
|
||||||
|
@ -2463,8 +2515,6 @@ boolean M_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
|
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
|
||||||
{
|
{
|
||||||
if (shiftdown && ch >= 32 && ch <= 127)
|
|
||||||
ch = shiftxform[ch];
|
|
||||||
if (M_ChangeStringCvar(ch))
|
if (M_ChangeStringCvar(ch))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -2710,6 +2760,7 @@ void M_StartControlPanel(void)
|
||||||
else // multiplayer
|
else // multiplayer
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
||||||
|
@ -2721,6 +2772,7 @@ void M_StartControlPanel(void)
|
||||||
if ((server || adminplayer == consoleplayer))
|
if ((server || adminplayer == consoleplayer))
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
||||||
}
|
}
|
||||||
|
@ -3262,7 +3314,7 @@ static void M_DrawGenericMenu(void)
|
||||||
y = currentMenu->y+currentMenu->menuitems[i].alphaKey;
|
y = currentMenu->y+currentMenu->menuitems[i].alphaKey;
|
||||||
|
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false);
|
||||||
y += SMALLLINEHEIGHT;
|
y += SMALLLINEHEIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3402,7 +3454,7 @@ static void M_DrawGenericScrollMenu(void)
|
||||||
break;
|
break;
|
||||||
case IT_HEADERTEXT:
|
case IT_HEADERTEXT:
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3912,7 +3964,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt)
|
||||||
I_Error("Insufficient memory to prepare level platter");
|
I_Error("Insufficient memory to prepare level platter");
|
||||||
|
|
||||||
// done here so lsrow and lscol can be set if cv_nextmap is on the platter
|
// done here so lsrow and lscol can be set if cv_nextmap is on the platter
|
||||||
lsrow = lscol = lstic = lshli = lsoffs[0] = lsoffs[1] = 0;
|
lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0;
|
||||||
|
|
||||||
while (mapnum < NUMMAPS)
|
while (mapnum < NUMMAPS)
|
||||||
{
|
{
|
||||||
|
@ -4171,10 +4223,10 @@ static void M_HandleLevelPlatter(INT32 choice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight)
|
void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase)
|
||||||
{
|
{
|
||||||
y += lsheadingheight - 12;
|
y += lsheadingheight - 12;
|
||||||
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0), header);
|
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header);
|
||||||
y += 9;
|
y += 9;
|
||||||
if ((y >= 0) && (y < 200))
|
if ((y >= 0) && (y < 200))
|
||||||
{
|
{
|
||||||
|
@ -4183,9 +4235,7 @@ void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlig
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
if ((y >= 0) && (y < 200))
|
if ((y >= 0) && (y < 200))
|
||||||
{
|
|
||||||
V_DrawFill(19, y, 282, 1, 26);
|
V_DrawFill(19, y, 282, 1, 26);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
||||||
|
@ -4279,7 +4329,7 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y)
|
||||||
const boolean rowhighlight = (row == lsrow);
|
const boolean rowhighlight = (row == lsrow);
|
||||||
if (levelselect.rows[row].header[0])
|
if (levelselect.rows[row].header[0])
|
||||||
{
|
{
|
||||||
M_DrawLevelPlatterHeader(y, levelselect.rows[row].header, (rowhighlight || (row == lshli)));
|
M_DrawLevelPlatterHeader(y, levelselect.rows[row].header, (rowhighlight || (row == lshli)), false);
|
||||||
y += lsheadingheight;
|
y += lsheadingheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4298,9 +4348,6 @@ static void M_DrawLevelPlatterMenu(void)
|
||||||
INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow);
|
INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow);
|
||||||
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
|
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
|
||||||
|
|
||||||
if (++lstic == 32)
|
|
||||||
lstic = 0;
|
|
||||||
|
|
||||||
if (gamestate == GS_TIMEATTACK)
|
if (gamestate == GS_TIMEATTACK)
|
||||||
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
|
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
|
||||||
|
|
||||||
|
@ -4320,7 +4367,7 @@ static void M_DrawLevelPlatterMenu(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw cursor box
|
// draw cursor box
|
||||||
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, ((lstic & 8) ? levselp[sizeselect][0] : levselp[sizeselect][1]));
|
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
||||||
|
|
||||||
if (levelselect.rows[lsrow].maplist[lscol])
|
if (levelselect.rows[lsrow].maplist[lscol])
|
||||||
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||||
|
@ -4620,6 +4667,511 @@ static void M_HandleImageDef(INT32 choice)
|
||||||
// MISC MAIN MENU OPTIONS
|
// MISC MAIN MENU OPTIONS
|
||||||
// ======================
|
// ======================
|
||||||
|
|
||||||
|
static void M_AddonsOptions(INT32 choice)
|
||||||
|
{
|
||||||
|
(void)choice;
|
||||||
|
Addons_option_Onchange();
|
||||||
|
|
||||||
|
M_SetupNextMenu(&OP_AddonsOptionsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCATIONSTRING "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||||
|
|
||||||
|
static void M_Addons(INT32 choice)
|
||||||
|
{
|
||||||
|
const char *pathname = ".";
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
|
/*if (cv_addons_option.value == 0)
|
||||||
|
pathname = srb2home; usehome ? srb2home : srb2path;
|
||||||
|
else if (cv_addons_option.value == 1)
|
||||||
|
pathname = srb2home;
|
||||||
|
else if (cv_addons_option.value == 2)
|
||||||
|
pathname = srb2path;
|
||||||
|
else*/
|
||||||
|
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
|
||||||
|
pathname = cv_addons_folder.string;
|
||||||
|
|
||||||
|
strlcpy(menupath, pathname, 1024);
|
||||||
|
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
|
||||||
|
|
||||||
|
if (menupath[menupathindex[menudepthleft]-2] != '/')
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]-1] = '/';
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
--menupathindex[menudepthleft];
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
M_StartMessage(M_GetText("No files/folders found.\n\n"LOCATIONSTRING"\n\n(Press a key)\n"),NULL,MM_NOTHING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
|
||||||
|
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < NUM_EXT+6; i++)
|
||||||
|
W_UnlockCachedPatch(addonsp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC);
|
||||||
|
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC);
|
||||||
|
addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC);
|
||||||
|
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||||
|
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||||
|
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||||
|
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
||||||
|
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL1", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+3] = W_CachePatchName("M_FLOAD", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+4] = W_CachePatchName("M_FSRCH", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+5] = W_CachePatchName("M_FSAVE", PU_STATIC);
|
||||||
|
|
||||||
|
MISC_AddonsDef.prevMenu = currentMenu;
|
||||||
|
M_SetupNextMenu(&MISC_AddonsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define width 4
|
||||||
|
#define vpadding 27
|
||||||
|
#define h (BASEVIDHEIGHT-(2*vpadding))
|
||||||
|
#define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker
|
||||||
|
static void M_DrawTemperature(INT32 x, fixed_t t)
|
||||||
|
{
|
||||||
|
INT32 y;
|
||||||
|
|
||||||
|
// bounds check
|
||||||
|
if (t > FRACUNIT)
|
||||||
|
t = FRACUNIT;
|
||||||
|
/*else if (t < 0) -- not needed
|
||||||
|
t = 0;*/
|
||||||
|
|
||||||
|
// scale
|
||||||
|
if (t > 1)
|
||||||
|
t = (FixedMul(h<<FRACBITS, t)>>FRACBITS);
|
||||||
|
|
||||||
|
// border
|
||||||
|
V_DrawFill(x - 1, vpadding, 1, h, 3);
|
||||||
|
V_DrawFill(x + width, vpadding, 1, h, 3);
|
||||||
|
V_DrawFill(x - 1, vpadding-1, width+2, 1, 3);
|
||||||
|
V_DrawFill(x - 1, vpadding+h, width+2, 1, 3);
|
||||||
|
|
||||||
|
// bar itself
|
||||||
|
y = h;
|
||||||
|
if (t)
|
||||||
|
for (t = h - t; y > 0; y--)
|
||||||
|
{
|
||||||
|
UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98};
|
||||||
|
UINT8 c;
|
||||||
|
if (y <= t) break;
|
||||||
|
if (y+vpadding >= BASEVIDHEIGHT/2)
|
||||||
|
c = 113;
|
||||||
|
else
|
||||||
|
c = colours[(NUMCOLOURS*(y-1))/(h/2)];
|
||||||
|
V_DrawFill(x, y-1 + vpadding, width, 1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the rest of the backing
|
||||||
|
if (y)
|
||||||
|
V_DrawFill(x, vpadding, width, y, 27);
|
||||||
|
}
|
||||||
|
#undef width
|
||||||
|
#undef vpadding
|
||||||
|
#undef h
|
||||||
|
#undef NUMCOLOURS
|
||||||
|
|
||||||
|
static char *M_AddonsHeaderPath(void)
|
||||||
|
{
|
||||||
|
UINT32 len;
|
||||||
|
static char header[1024];
|
||||||
|
|
||||||
|
if (menupath[0] == '.')
|
||||||
|
strlcpy(header, va("SRB2 folder%s", menupath+1), 1024);
|
||||||
|
else
|
||||||
|
strcpy(header, menupath);
|
||||||
|
|
||||||
|
len = strlen(header);
|
||||||
|
if (len > 34)
|
||||||
|
{
|
||||||
|
len = len-34;
|
||||||
|
header[len] = header[len+1] = header[len+2] = '.';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
return header+len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UNEXIST S_StartSound(NULL, sfx_lose);\
|
||||||
|
M_SetupNextMenu(MISC_AddonsDef.prevMenu);\
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING)
|
||||||
|
|
||||||
|
// returns whether to do message draw
|
||||||
|
static boolean M_AddonsRefresh(void)
|
||||||
|
{
|
||||||
|
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
||||||
|
{
|
||||||
|
addonsresponselimit = 0;
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_NOTLOADED)
|
||||||
|
{
|
||||||
|
char *message = NULL;
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
if (refreshdirmenu & REFRESHDIR_MAX)
|
||||||
|
message = va("\x82%s\x80\nMaximum number of add-ons reached.\nThis file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||||
|
else
|
||||||
|
message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||||
|
M_StartMessage(message,NULL,MM_NOTHING);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define offs 1
|
||||||
|
|
||||||
|
static void M_DrawAddons(void)
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
ssize_t i, max;
|
||||||
|
|
||||||
|
// hack - need to refresh at end of frame to handle addfile...
|
||||||
|
if (refreshdirmenu & M_AddonsRefresh())
|
||||||
|
return M_DrawMessageMenu();
|
||||||
|
|
||||||
|
if (addonsresponselimit)
|
||||||
|
addonsresponselimit--;
|
||||||
|
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing()
|
||||||
|
? "\x85""Adding files mid-game may cause problems."
|
||||||
|
: LOCATIONSTRING));
|
||||||
|
|
||||||
|
if (numwadfiles <= mainwads+1)
|
||||||
|
y = 0;
|
||||||
|
else if (numwadfiles >= MAX_WADFILES)
|
||||||
|
y = FRACUNIT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = FixedDiv((numwadfiles - mainwads+1)<<FRACBITS, (MAX_WADFILES - mainwads+1)<<FRACBITS);
|
||||||
|
y = FixedDiv(((packetsizetally-mainwadstally)<<FRACBITS), (((MAXFILENEEDED*sizeof(UINT8)-mainwadstally)-(5+22))<<FRACBITS)); // 5+22 = (a.ext + checksum length) is minimum addition to packet size tally
|
||||||
|
if (x > y)
|
||||||
|
y = x;
|
||||||
|
if (y > FRACUNIT) // happens because of how we're shrinkin' it a little
|
||||||
|
y = FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y);
|
||||||
|
|
||||||
|
// DRAW MENU
|
||||||
|
x = currentMenu->x;
|
||||||
|
y = currentMenu->y + offs;
|
||||||
|
|
||||||
|
//M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width
|
||||||
|
V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath());
|
||||||
|
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), (MAXSTRINGLENGTH*8+6 - 1), 1, yellowmap[3]);
|
||||||
|
V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26);
|
||||||
|
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26);
|
||||||
|
|
||||||
|
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1 + offs) - (y - 1), 159);
|
||||||
|
|
||||||
|
// get bottom...
|
||||||
|
max = dir_on[menudepthleft] + numaddonsshown + 1;
|
||||||
|
if (max > (ssize_t)sizedirmenu)
|
||||||
|
max = sizedirmenu;
|
||||||
|
|
||||||
|
// then top...
|
||||||
|
i = max - (2*numaddonsshown + 1);
|
||||||
|
|
||||||
|
// then adjust!
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
if ((max -= i) > (ssize_t)sizedirmenu)
|
||||||
|
max = sizedirmenu;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
V_DrawString(19, y+4, V_YELLOWMAP, "\x1A");
|
||||||
|
|
||||||
|
for (; i < max; i++)
|
||||||
|
{
|
||||||
|
UINT32 flags = V_ALLOWLOWERCASE;
|
||||||
|
if (y > BASEVIDHEIGHT) break;
|
||||||
|
if (dirmenu[i])
|
||||||
|
#define type (UINT8)(dirmenu[i][DIR_TYPE])
|
||||||
|
{
|
||||||
|
if (type & EXT_LOADED)
|
||||||
|
flags |= V_TRANSLUCENT;
|
||||||
|
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]);
|
||||||
|
|
||||||
|
if (type & EXT_LOADED)
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]);
|
||||||
|
|
||||||
|
if ((size_t)i == dir_on[menudepthleft])
|
||||||
|
{
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+1+((skullAnimCounter/4) ? 1 : 0)]);
|
||||||
|
flags = V_ALLOWLOWERCASE|V_YELLOWMAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define charsonside 14
|
||||||
|
if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3))
|
||||||
|
V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1)));
|
||||||
|
#undef charsonside
|
||||||
|
else
|
||||||
|
V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING);
|
||||||
|
}
|
||||||
|
#undef type
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != (ssize_t)sizedirmenu)
|
||||||
|
V_DrawString(19, y-12, V_YELLOWMAP, "\x1B");
|
||||||
|
|
||||||
|
y = BASEVIDHEIGHT - currentMenu->y + offs;
|
||||||
|
|
||||||
|
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
|
||||||
|
if (menusearch[0])
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1);
|
||||||
|
else
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
|
||||||
|
if (skullAnimCounter < 4)
|
||||||
|
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
|
||||||
|
'_' | 0x80, false);
|
||||||
|
|
||||||
|
x -= (21 + 5 + 16);
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
|
||||||
|
|
||||||
|
#define CANSAVE (!modifiedgame || savemoddata)
|
||||||
|
x = BASEVIDWIDTH - x - 16;
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]);
|
||||||
|
|
||||||
|
if CANSAVE
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]);
|
||||||
|
#undef CANSAVE
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef offs
|
||||||
|
|
||||||
|
static void M_AddonExec(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch != 'y' && ch != KEY_ENTER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define len menusearch[0]
|
||||||
|
static boolean M_ChangeStringAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
if (shiftdown && choice >= 32 && choice <= 127)
|
||||||
|
choice = shiftxform[choice];
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DEL:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
len = menusearch[1] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
menusearch[1+--len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (choice >= 32 && choice <= 127)
|
||||||
|
{
|
||||||
|
if (len < MAXSTRINGLENGTH - 1)
|
||||||
|
{
|
||||||
|
menusearch[1+len++] = (char)choice;
|
||||||
|
menusearch[1+len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#undef len
|
||||||
|
|
||||||
|
static void M_HandleAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
boolean exitmenu = false; // exit to previous menu
|
||||||
|
|
||||||
|
if (addonsresponselimit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (M_ChangeStringAddons(choice))
|
||||||
|
{
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DOWNARROW:
|
||||||
|
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_UPARROW:
|
||||||
|
if (dir_on[menudepthleft])
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGDN:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGUP:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--)
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
{
|
||||||
|
boolean refresh = true;
|
||||||
|
if (!dirmenu[dir_on[menudepthleft]])
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||||
|
{
|
||||||
|
case EXT_FOLDER:
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||||
|
if (menudepthleft)
|
||||||
|
{
|
||||||
|
menupathindex[--menudepthleft] = strlen(menupath);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder is empty.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
dir_on[menudepthleft] = 1;
|
||||||
|
}
|
||||||
|
refresh = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_UP:
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_TXT:
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
|
||||||
|
break;
|
||||||
|
case EXT_CFG:
|
||||||
|
M_AddonExec(KEY_ENTER);
|
||||||
|
break;
|
||||||
|
case EXT_LUA:
|
||||||
|
#ifndef HAVE_BLUA
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
// else intentional fallthrough
|
||||||
|
case EXT_SOC:
|
||||||
|
case EXT_WAD:
|
||||||
|
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
addonsresponselimit = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (refresh)
|
||||||
|
refreshdirmenu |= REFRESHDIR_NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_ESCAPE:
|
||||||
|
exitmenu = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (exitmenu)
|
||||||
|
{
|
||||||
|
for (; sizedirmenu > 0; sizedirmenu--)
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[sizedirmenu-1]);
|
||||||
|
dirmenu[sizedirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
dirmenu = NULL;
|
||||||
|
|
||||||
|
// secrets disabled by addfile...
|
||||||
|
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||||
|
|
||||||
|
if (currentMenu->prevMenu)
|
||||||
|
M_SetupNextMenu(currentMenu->prevMenu);
|
||||||
|
else
|
||||||
|
M_ClearMenus(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void M_PandorasBox(INT32 choice)
|
static void M_PandorasBox(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
@ -4722,7 +5274,7 @@ static void M_Options(INT32 choice)
|
||||||
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
||||||
|
|
||||||
// if the player is playing _at all_, disable the erase data options
|
// if the player is playing _at all_, disable the erase data options
|
||||||
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
OP_DataOptionsMenu[2].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||||
|
|
||||||
OP_MainDef.prevMenu = currentMenu;
|
OP_MainDef.prevMenu = currentMenu;
|
||||||
M_SetupNextMenu(&OP_MainDef);
|
M_SetupNextMenu(&OP_MainDef);
|
||||||
|
@ -5136,9 +5688,7 @@ static void M_DrawChecklist(void)
|
||||||
|
|
||||||
finishchecklist:
|
finishchecklist:
|
||||||
if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks.
|
if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks.
|
||||||
{
|
|
||||||
V_DrawString(10, currentMenu->y+(scrollareaheight*2), V_YELLOWMAP, "\x1B");
|
V_DrawString(10, currentMenu->y+(scrollareaheight*2), V_YELLOWMAP, "\x1B");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUMHINTS 5
|
#define NUMHINTS 5
|
||||||
|
@ -6111,7 +6661,7 @@ static void M_ChoosePlayer(INT32 choice)
|
||||||
if (startmap != spstage_start)
|
if (startmap != spstage_start)
|
||||||
cursaveslot = -1;
|
cursaveslot = -1;
|
||||||
|
|
||||||
lastmapsaved = 0;
|
//lastmapsaved = 0;
|
||||||
gamecomplete = false;
|
gamecomplete = false;
|
||||||
|
|
||||||
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)skinnum, false, fromlevelselect);
|
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), (UINT8)skinnum, false, fromlevelselect);
|
||||||
|
@ -6441,7 +6991,7 @@ void M_DrawTimeAttackMenu(void)
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
char beststr[40];
|
char beststr[40];
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true);
|
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
@ -6618,7 +7168,7 @@ void M_DrawNightsAttackMenu(void)
|
||||||
UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value);
|
UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value);
|
||||||
tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value);
|
tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value);
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true);
|
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
@ -7374,7 +7924,7 @@ static void M_DrawServerMenu(void)
|
||||||
// Room name
|
// Room name
|
||||||
if (currentMenu == &MP_ServerDef)
|
if (currentMenu == &MP_ServerDef)
|
||||||
{
|
{
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true);
|
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false);
|
||||||
if (ms_RoomId < 0)
|
if (ms_RoomId < 0)
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
||||||
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>");
|
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>");
|
||||||
|
@ -7392,7 +7942,7 @@ static void M_DrawServerMenu(void)
|
||||||
|
|
||||||
sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string);
|
sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string);
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y + MP_ServerMenu[mp_server_levelgt].alphaKey - 10 - lsheadingheight/2, (const char *)headerstr, true);
|
M_DrawLevelPlatterHeader(currentMenu->y + MP_ServerMenu[mp_server_levelgt].alphaKey - 10 - lsheadingheight/2, (const char *)headerstr, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
@ -7422,7 +7972,7 @@ static void M_GameTypeChange(INT32 choice)
|
||||||
void M_DrawGameTypeMenu(void)
|
void M_DrawGameTypeMenu(void)
|
||||||
{
|
{
|
||||||
M_DrawGenericMenu();
|
M_DrawGenericMenu();
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight, "Select Gametype", true);
|
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight, "Select Gametype", true, false);
|
||||||
|
|
||||||
if (!char_notes)
|
if (!char_notes)
|
||||||
char_notes = V_WordWrap(0, (160 - 30) - 8, V_ALLOWLOWERCASE, gametypedesc[itemOn].notes);
|
char_notes = V_WordWrap(0, (160 - 30) - 8, V_ALLOWLOWERCASE, gametypedesc[itemOn].notes);
|
||||||
|
@ -8174,7 +8724,7 @@ static void M_DrawControl(void)
|
||||||
/*else if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2)
|
/*else if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2)
|
||||||
V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);*/
|
V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);*/
|
||||||
else if ((currentMenu->menuitems[i].status == IT_HEADER) && (i != max-1))
|
else if ((currentMenu->menuitems[i].status == IT_HEADER) && (i != max-1))
|
||||||
M_DrawLevelPlatterHeader(y, currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y, currentMenu->menuitems[i].text, true, false);
|
||||||
|
|
||||||
y += SMALLLINEHEIGHT;
|
y += SMALLLINEHEIGHT;
|
||||||
}
|
}
|
||||||
|
@ -8749,7 +9299,7 @@ static void M_DrawColorMenu(void)
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
V_DrawFill(19, y, 281, 9, currentMenu->menuitems[i+1].alphaKey);
|
V_DrawFill(19, y, 281, 9, currentMenu->menuitems[i+1].alphaKey);
|
||||||
V_DrawFill(300, y, 1, 9, 26);
|
V_DrawFill(300, y, 1, 9, 26);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, false);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, false, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/m_menu.h
17
src/m_menu.h
|
@ -124,6 +124,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||||
|
|
||||||
|
#define MAXSTRINGLENGTH 32
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct menu_s *submenu; // IT_SUBMENU
|
struct menu_s *submenu; // IT_SUBMENU
|
||||||
|
@ -249,6 +251,9 @@ void Nextmap_OnChange(void);
|
||||||
void Moviemode_mode_Onchange(void);
|
void Moviemode_mode_Onchange(void);
|
||||||
void Screenshot_option_Onchange(void);
|
void Screenshot_option_Onchange(void);
|
||||||
|
|
||||||
|
// Addons menu updating
|
||||||
|
void Addons_option_Onchange(void);
|
||||||
|
|
||||||
// These defines make it a little easier to make menus
|
// These defines make it a little easier to make menus
|
||||||
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
||||||
{\
|
{\
|
||||||
|
@ -262,6 +267,18 @@ void Screenshot_option_Onchange(void);
|
||||||
NULL\
|
NULL\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFAULTSCROLLMENUSTYLE(header, source, prev, x, y)\
|
||||||
|
{\
|
||||||
|
header,\
|
||||||
|
sizeof(source)/sizeof(menuitem_t),\
|
||||||
|
prev,\
|
||||||
|
source,\
|
||||||
|
M_DrawGenericScrollMenu,\
|
||||||
|
x, y,\
|
||||||
|
0,\
|
||||||
|
NULL\
|
||||||
|
}
|
||||||
|
|
||||||
#define PAUSEMENUSTYLE(source, x, y)\
|
#define PAUSEMENUSTYLE(source, x, y)\
|
||||||
{\
|
{\
|
||||||
NULL,\
|
NULL,\
|
||||||
|
|
|
@ -100,7 +100,7 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2
|
||||||
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
||||||
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
175
src/p_enemy.c
175
src/p_enemy.c
|
@ -137,7 +137,6 @@ void A_DetonChase(mobj_t *actor);
|
||||||
void A_CapeChase(mobj_t *actor);
|
void A_CapeChase(mobj_t *actor);
|
||||||
void A_RotateSpikeBall(mobj_t *actor);
|
void A_RotateSpikeBall(mobj_t *actor);
|
||||||
void A_SlingAppear(mobj_t *actor);
|
void A_SlingAppear(mobj_t *actor);
|
||||||
void A_MaceRotate(mobj_t *actor);
|
|
||||||
void A_UnidusBall(mobj_t *actor);
|
void A_UnidusBall(mobj_t *actor);
|
||||||
void A_RockSpawn(mobj_t *actor);
|
void A_RockSpawn(mobj_t *actor);
|
||||||
void A_SetFuse(mobj_t *actor);
|
void A_SetFuse(mobj_t *actor);
|
||||||
|
@ -4110,15 +4109,18 @@ void A_SetSolidSteam(mobj_t *actor)
|
||||||
#endif
|
#endif
|
||||||
actor->flags &= ~MF_NOCLIP;
|
actor->flags &= ~MF_NOCLIP;
|
||||||
actor->flags |= MF_SOLID;
|
actor->flags |= MF_SOLID;
|
||||||
if (P_RandomChance(FRACUNIT/8))
|
if (!(actor->flags2 & MF2_AMBUSH))
|
||||||
{
|
{
|
||||||
if (actor->info->deathsound)
|
if (P_RandomChance(FRACUNIT/8))
|
||||||
S_StartSound(actor, actor->info->deathsound); // Hiss!
|
{
|
||||||
}
|
if (actor->info->deathsound)
|
||||||
else
|
S_StartSound(actor, actor->info->deathsound); // Hiss!
|
||||||
{
|
}
|
||||||
if (actor->info->painsound)
|
else
|
||||||
S_StartSound(actor, actor->info->painsound);
|
{
|
||||||
|
if (actor->info->painsound)
|
||||||
|
S_StartSound(actor, actor->info->painsound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
P_SetObjectMomZ (actor, 1, true);
|
P_SetObjectMomZ (actor, 1, true);
|
||||||
|
@ -5142,15 +5144,12 @@ void A_SlingAppear(mobj_t *actor)
|
||||||
actor->movefactor = actor->threshold;
|
actor->movefactor = actor->threshold;
|
||||||
actor->friction = 128;
|
actor->friction = 128;
|
||||||
|
|
||||||
actor->flags |= MF_SLIDEME;
|
|
||||||
|
|
||||||
while (mlength > 0)
|
while (mlength > 0)
|
||||||
{
|
{
|
||||||
spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN);
|
spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN);
|
||||||
|
|
||||||
P_SetTarget(&spawnee->target, actor);
|
P_SetTarget(&spawnee->target, actor);
|
||||||
|
|
||||||
spawnee->movecount = 0;
|
|
||||||
spawnee->threshold = 0;
|
spawnee->threshold = 0;
|
||||||
spawnee->reactiontime = mlength;
|
spawnee->reactiontime = mlength;
|
||||||
|
|
||||||
|
@ -5165,129 +5164,6 @@ void A_SlingAppear(mobj_t *actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Function: A_MaceRotate
|
|
||||||
//
|
|
||||||
// Spins an object around its target, or, swings it from side to side.
|
|
||||||
//
|
|
||||||
// var1 = unused
|
|
||||||
// var2 = unused
|
|
||||||
//
|
|
||||||
// So NOBODY forgets:
|
|
||||||
// actor->
|
|
||||||
// threshold - X tilt
|
|
||||||
// movecount - Z tilt
|
|
||||||
// reactiontime - link # in the chain (1 is closest)
|
|
||||||
// lastlook - speed
|
|
||||||
// friction - top speed
|
|
||||||
// movedir - current angle holder
|
|
||||||
// extravalue1 - smoothly move link into place
|
|
||||||
//
|
|
||||||
void A_MaceRotate(mobj_t *actor)
|
|
||||||
{
|
|
||||||
TVector v;
|
|
||||||
TVector *res;
|
|
||||||
fixed_t radius;
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
if (LUA_CallAction("A_MaceRotate", actor))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Target was removed.
|
|
||||||
if (!actor->target)
|
|
||||||
{
|
|
||||||
P_RemoveMobj(actor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
P_UnsetThingPosition(actor);
|
|
||||||
|
|
||||||
// Radius of the link's rotation.
|
|
||||||
radius = FixedMul(actor->info->speed * actor->reactiontime, actor->target->scale);
|
|
||||||
|
|
||||||
// Double the radius if the chain links are made up of maces.
|
|
||||||
if (actor->target->type == MT_AXIS && (actor->type == MT_SMALLMACE || actor->type == MT_BIGMACE))
|
|
||||||
radius *= 2;
|
|
||||||
|
|
||||||
// Axis offset for the axis.
|
|
||||||
radius += actor->target->extravalue1;
|
|
||||||
|
|
||||||
// Smoothly move the link into position.
|
|
||||||
if (actor->extravalue1)
|
|
||||||
{
|
|
||||||
radius = FixedMul(radius, FixedDiv(actor->extravalue1, 100));
|
|
||||||
actor->extravalue1 += 1;
|
|
||||||
if (actor->extravalue1 >= 100)
|
|
||||||
actor->extravalue1 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
actor->x = actor->target->x;
|
|
||||||
actor->y = actor->target->y;
|
|
||||||
actor->z = actor->target->z;
|
|
||||||
|
|
||||||
// Cut the height to align the link with the axis.
|
|
||||||
if (actor->type == MT_SMALLMACECHAIN || actor->type == MT_BIGMACECHAIN)
|
|
||||||
actor->z -= actor->height/4;
|
|
||||||
else
|
|
||||||
actor->z -= actor->height/2;
|
|
||||||
|
|
||||||
// Set the top speed for the link if it happens to be over that speed.
|
|
||||||
if (actor->target->lastlook > actor->target->friction)
|
|
||||||
actor->target->lastlook = actor->target->friction;
|
|
||||||
|
|
||||||
// Swinging Chain.
|
|
||||||
if (actor->target->type == MT_HANGMACEPOINT || actor->target->type == MT_SWINGMACEPOINT)
|
|
||||||
{
|
|
||||||
actor->movecount += actor->target->lastlook;
|
|
||||||
actor->movecount &= FINEMASK;
|
|
||||||
|
|
||||||
actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS);
|
|
||||||
|
|
||||||
v[0] = FRACUNIT;
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = -radius;
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
|
|
||||||
// Calculate the angle matrixes for the link.
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold)));
|
|
||||||
M_Memcpy(&v, res, sizeof(v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT));
|
|
||||||
M_Memcpy(&v, res, sizeof(v));
|
|
||||||
}
|
|
||||||
// Rotating Chain.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
angle_t fa;
|
|
||||||
|
|
||||||
actor->threshold += actor->target->lastlook;
|
|
||||||
actor->threshold &= FINEMASK;
|
|
||||||
actor->target->health &= FINEMASK;
|
|
||||||
|
|
||||||
fa = actor->threshold;
|
|
||||||
v[0] = FixedMul(FINECOSINE(fa), radius);
|
|
||||||
v[1] = 0;
|
|
||||||
v[2] = FixedMul(FINESINE(fa), radius);
|
|
||||||
v[3] = FRACUNIT;
|
|
||||||
|
|
||||||
// Calculate the angle matrixes for the link.
|
|
||||||
res = VectorMatrixMultiply(v, *RotateXMatrix(actor->target->threshold << ANGLETOFINESHIFT));
|
|
||||||
M_Memcpy(&v, res, sizeof(v));
|
|
||||||
res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT));
|
|
||||||
M_Memcpy(&v, res, sizeof(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add on the appropriate distances to the actor's co-ordinates.
|
|
||||||
actor->x += v[0];
|
|
||||||
actor->y += v[1];
|
|
||||||
actor->z += v[2];
|
|
||||||
|
|
||||||
P_SetThingPosition(actor);
|
|
||||||
|
|
||||||
if (!(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes maces shut up on request
|
|
||||||
&& !(leveltime & 63) && (actor->type == MT_BIGMACE || actor->type == MT_SMALLMACE) && actor->target->type == MT_MACEPOINT)
|
|
||||||
S_StartSound(actor, actor->info->activesound);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function: A_SetFuse
|
// Function: A_SetFuse
|
||||||
//
|
//
|
||||||
// Description: Sets the actor's fuse timer if not set already. May also change state when fuse reaches the last tic, otherwise by default the actor will die or disappear. (Replaces A_SnowBall)
|
// Description: Sets the actor's fuse timer if not set already. May also change state when fuse reaches the last tic, otherwise by default the actor will die or disappear. (Replaces A_SnowBall)
|
||||||
|
@ -10791,26 +10667,33 @@ void A_FlickyFlutter(mobj_t *actor)
|
||||||
// Description: Creates the mobj's painchance at a random position around the object's radius.
|
// Description: Creates the mobj's painchance at a random position around the object's radius.
|
||||||
//
|
//
|
||||||
// var1 = momz of particle.
|
// var1 = momz of particle.
|
||||||
|
// var2 = chance of particle spawn
|
||||||
//
|
//
|
||||||
void A_FlameParticle(mobj_t *actor)
|
void A_FlameParticle(mobj_t *actor)
|
||||||
{
|
{
|
||||||
mobjtype_t type = (mobjtype_t)(mobjinfo[actor->type].painchance);
|
mobjtype_t type = (mobjtype_t)(mobjinfo[actor->type].painchance);
|
||||||
|
fixed_t rad, hei;
|
||||||
|
mobj_t *particle;
|
||||||
INT32 locvar1 = var1;
|
INT32 locvar1 = var1;
|
||||||
|
INT32 locvar2 = var2;
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_FlameParticle", actor))
|
if (LUA_CallAction("A_FlameParticle", actor))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (type)
|
if (!P_RandomChance(locvar2))
|
||||||
{
|
return;
|
||||||
fixed_t rad = 2*actor->radius>>FRACBITS;
|
|
||||||
fixed_t hei = actor->height>>FRACBITS;
|
if (!type)
|
||||||
mobj_t *particle = P_SpawnMobjFromMobj(actor,
|
return;
|
||||||
P_RandomRange(rad, -rad)<<FRACBITS,
|
|
||||||
P_RandomRange(rad, -rad)<<FRACBITS,
|
rad = 2*actor->radius>>FRACBITS;
|
||||||
P_RandomRange(hei/2, hei)<<FRACBITS,
|
hei = actor->height>>FRACBITS;
|
||||||
type);
|
particle = P_SpawnMobjFromMobj(actor,
|
||||||
P_SetObjectMomZ(particle, locvar1<<FRACBITS, false);
|
P_RandomRange(rad, -rad)<<FRACBITS,
|
||||||
}
|
P_RandomRange(rad, -rad)<<FRACBITS,
|
||||||
|
P_RandomRange(hei/2, hei)<<FRACBITS,
|
||||||
|
type);
|
||||||
|
P_SetObjectMomZ(particle, locvar1<<FRACBITS, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2061,6 +2061,33 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
|
||||||
P_RemoveThinker(&nobaddies->thinker);
|
P_RemoveThinker(&nobaddies->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_IsObjectOnRealGround
|
||||||
|
//
|
||||||
|
// Helper function for T_EachTimeThinker
|
||||||
|
// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS
|
||||||
|
// I'll consider whether to make this a more globally accessible function or whatever in future
|
||||||
|
// -- Monster Iestyn
|
||||||
|
//
|
||||||
|
static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec)
|
||||||
|
{
|
||||||
|
// Is the object in reverse gravity?
|
||||||
|
if (mo->eflags & MFE_VERTICALFLIP)
|
||||||
|
{
|
||||||
|
// Detect if the player is on the ceiling.
|
||||||
|
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Nope!
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Detect if the player is on the floor.
|
||||||
|
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_HavePlayersEnteredArea
|
// P_HavePlayersEnteredArea
|
||||||
//
|
//
|
||||||
|
@ -2264,7 +2291,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
||||||
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
|
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
|
if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec))
|
||||||
{
|
{
|
||||||
if (i & 1)
|
if (i & 1)
|
||||||
eachtime->var2s[i/2] |= 1;
|
eachtime->var2s[i/2] |= 1;
|
||||||
|
@ -3283,14 +3310,6 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL))
|
|
||||||
{
|
|
||||||
mobj_t *tokenobj = P_SpawnMobj(sector->soundorg.x, sector->soundorg.y, topheight, MT_TOKEN);
|
|
||||||
P_SetTarget(&thing->tracer, tokenobj);
|
|
||||||
P_SetTarget(&tokenobj->target, thing);
|
|
||||||
P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Powerup rise" sound
|
// "Powerup rise" sound
|
||||||
S_StartSound(puncher, sfx_mario9); // Puncher is "close enough"
|
S_StartSound(puncher, sfx_mario9); // Puncher is "close enough"
|
||||||
}
|
}
|
||||||
|
|
252
src/p_inter.c
252
src/p_inter.c
|
@ -570,7 +570,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
// Gameplay related collectibles //
|
// Gameplay related collectibles //
|
||||||
// ***************************** //
|
// ***************************** //
|
||||||
// Special Stage Token
|
// Special Stage Token
|
||||||
case MT_EMMY:
|
case MT_TOKEN:
|
||||||
if (player->bot)
|
if (player->bot)
|
||||||
return;
|
return;
|
||||||
tokenlist += special->health;
|
tokenlist += special->health;
|
||||||
|
@ -589,9 +589,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
token++;
|
token++;
|
||||||
|
|
||||||
if (special->tracer) // token BG
|
|
||||||
P_RemoveMobj(special->tracer);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Emerald Hunt
|
// Emerald Hunt
|
||||||
|
@ -881,7 +878,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
|
|
||||||
if (!(mo2->flags & MF_SPECIAL) && mo2->health)
|
if (!(mo2->flags & MF_SPECIAL) && mo2->health)
|
||||||
{
|
{
|
||||||
P_SetMobjState(mo2, mo2->info->seestate);
|
mo2->flags2 &= ~MF2_DONTDRAW;
|
||||||
mo2->flags |= MF_SPECIAL;
|
mo2->flags |= MF_SPECIAL;
|
||||||
mo2->flags &= ~MF_NIGHTSITEM;
|
mo2->flags &= ~MF_NIGHTSITEM;
|
||||||
S_StartSound(toucher, sfx_hidden);
|
S_StartSound(toucher, sfx_hidden);
|
||||||
|
@ -890,7 +887,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
|
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
|
||||||
|| mo2->type == MT_BLUEBALL))
|
|| mo2->type == MT_BLUEBALL
|
||||||
|
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Yay! The thing's in reach! Pull it in!
|
// Yay! The thing's in reach! Pull it in!
|
||||||
|
@ -1471,10 +1469,19 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
if (player->powers[pw_flashing])
|
if (player->powers[pw_flashing])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (special->movefactor && special->tracer && (angle_t)special->tracer->health != ANGLE_90 && (angle_t)special->tracer->health != ANGLE_270)
|
||||||
|
{ // I don't expect you to understand this, Mr Bond...
|
||||||
|
angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold;
|
||||||
|
if ((special->movefactor > 0) == ((angle_t)special->tracer->health > ANGLE_90 && (angle_t)special->tracer->health < ANGLE_270))
|
||||||
|
ang += ANGLE_180;
|
||||||
|
if (ang < ANGLE_180)
|
||||||
|
return; // I expect you to die.
|
||||||
|
}
|
||||||
|
|
||||||
P_ResetPlayer(player);
|
P_ResetPlayer(player);
|
||||||
P_SetTarget(&toucher->tracer, special);
|
P_SetTarget(&toucher->tracer, special);
|
||||||
|
|
||||||
if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING))
|
if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX))
|
||||||
{
|
{
|
||||||
player->powers[pw_carry] = CR_MACESPIN;
|
player->powers[pw_carry] = CR_MACESPIN;
|
||||||
S_StartSound(toucher, sfx_spin);
|
S_StartSound(toucher, sfx_spin);
|
||||||
|
@ -1485,6 +1492,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
|
|
||||||
// Can't jump first frame
|
// Can't jump first frame
|
||||||
player->pflags |= PF_JUMPSTASIS;
|
player->pflags |= PF_JUMPSTASIS;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case MT_BIGMINE:
|
case MT_BIGMINE:
|
||||||
case MT_BIGAIRMINE:
|
case MT_BIGAIRMINE:
|
||||||
|
@ -1668,7 +1676,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
||||||
if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield
|
if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield
|
||||||
str = M_GetText("%s%s's armageddon blast %s %s.\n");
|
str = M_GetText("%s%s's armageddon blast %s %s.\n");
|
||||||
else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY))
|
else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY))
|
||||||
str = M_GetText("%s%s's flame stomp %s %s.\n");
|
str = M_GetText("%s%s's elemental stomp %s %s.\n");
|
||||||
else if (inflictor->player->powers[pw_invulnerability])
|
else if (inflictor->player->powers[pw_invulnerability])
|
||||||
str = M_GetText("%s%s's invincibility aura %s %s.\n");
|
str = M_GetText("%s%s's invincibility aura %s %s.\n");
|
||||||
else if (inflictor->player->powers[pw_super])
|
else if (inflictor->player->powers[pw_super])
|
||||||
|
@ -1722,6 +1730,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
|
||||||
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
|
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
|
||||||
break;
|
break;
|
||||||
case MT_SPIKE:
|
case MT_SPIKE:
|
||||||
|
case MT_WALLSPIKE:
|
||||||
str = M_GetText("%s was %s by spikes.\n");
|
str = M_GetText("%s was %s by spikes.\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2398,7 +2407,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_SetObjectMomZ(target, 14*FRACUNIT, false);
|
P_SetObjectMomZ(target, 14*FRACUNIT, false);
|
||||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
|
if (damagetype == DMG_SPIKE) // Spikes
|
||||||
S_StartSound(target, sfx_spkdth);
|
S_StartSound(target, sfx_spkdth);
|
||||||
else
|
else
|
||||||
P_PlayDeathSound(target);
|
P_PlayDeathSound(target);
|
||||||
|
@ -2460,90 +2469,159 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL)
|
if (target->type == MT_SPIKE && target->info->deathstate != S_NULL)
|
||||||
{
|
{
|
||||||
const fixed_t x=target->x,y=target->y,z=target->z;
|
const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90;
|
||||||
const fixed_t scale=target->scale;
|
const fixed_t scale = target->scale;
|
||||||
const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP;
|
const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale);
|
||||||
S_StartSound(target,target->info->deathsound);
|
const UINT16 flip = (target->eflags & MFE_VERTICALFLIP);
|
||||||
|
mobj_t *chunk;
|
||||||
|
fixed_t momz;
|
||||||
|
|
||||||
P_SetMobjState(target, target->info->deathstate);
|
S_StartSound(target, target->info->deathsound);
|
||||||
target->health = 0;
|
|
||||||
target->angle = inflictor->angle + ANGLE_90;
|
|
||||||
P_UnsetThingPosition(target);
|
|
||||||
target->flags = MF_NOCLIP;
|
|
||||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
if (flip)
|
|
||||||
target->z -= FixedMul(12*FRACUNIT, target->scale);
|
|
||||||
else
|
|
||||||
target->z += FixedMul(12*FRACUNIT, target->scale);
|
|
||||||
P_SetThingPosition(target);
|
|
||||||
P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale));
|
|
||||||
target->momz = FixedMul(7*FRACUNIT, target->scale);
|
|
||||||
if (flip)
|
|
||||||
target->momz = -target->momz;
|
|
||||||
|
|
||||||
if (flip)
|
|
||||||
{
|
|
||||||
target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE);
|
|
||||||
target->eflags |= MFE_VERTICALFLIP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
target = P_SpawnMobj(x,y,z+FixedMul(12*FRACUNIT, target->scale),MT_SPIKE);
|
|
||||||
P_SetMobjState(target, target->info->deathstate);
|
|
||||||
target->health = 0;
|
|
||||||
target->angle = inflictor->angle - ANGLE_90;
|
|
||||||
target->destscale = scale;
|
|
||||||
P_SetScale(target, scale);
|
|
||||||
P_UnsetThingPosition(target);
|
|
||||||
target->flags = MF_NOCLIP;
|
|
||||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
P_SetThingPosition(target);
|
|
||||||
P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale));
|
|
||||||
target->momz = FixedMul(7*FRACUNIT, target->scale);
|
|
||||||
if (flip)
|
|
||||||
target->momz = -target->momz;
|
|
||||||
|
|
||||||
if (target->info->xdeathstate != S_NULL)
|
if (target->info->xdeathstate != S_NULL)
|
||||||
{
|
{
|
||||||
target = P_SpawnMobj(x,y,z,MT_SPIKE);
|
momz = 6*scale;
|
||||||
if (flip)
|
if (flip)
|
||||||
target->eflags |= MFE_VERTICALFLIP;
|
momz *= -1;
|
||||||
P_SetMobjState(target, target->info->xdeathstate);
|
#define makechunk(angtweak, xmov, ymov) \
|
||||||
target->health = 0;
|
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\
|
||||||
target->angle = inflictor->angle + ANGLE_90;
|
chunk->eflags |= flip;\
|
||||||
target->destscale = scale;
|
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||||
P_SetScale(target, scale);
|
chunk->health = 0;\
|
||||||
P_UnsetThingPosition(target);
|
chunk->angle = angtweak;\
|
||||||
target->flags = MF_NOCLIP;
|
chunk->destscale = scale;\
|
||||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
P_SetScale(chunk, scale);\
|
||||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
P_UnsetThingPosition(chunk);\
|
||||||
P_SetThingPosition(target);
|
chunk->flags = MF_NOCLIP;\
|
||||||
P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale));
|
chunk->x += xmov;\
|
||||||
target->momz = FixedMul(6*FRACUNIT, target->scale);
|
chunk->y += ymov;\
|
||||||
if (flip)
|
P_SetThingPosition(chunk);\
|
||||||
target->momz = -target->momz;
|
P_InstaThrust(chunk,chunk->angle, 4*scale);\
|
||||||
|
chunk->momz = momz
|
||||||
|
|
||||||
target = P_SpawnMobj(x,y,z,MT_SPIKE);
|
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||||
if (flip)
|
makechunk(ang, xoffs, yoffs);
|
||||||
target->eflags |= MFE_VERTICALFLIP;
|
|
||||||
P_SetMobjState(target, target->info->xdeathstate);
|
#undef makechunk
|
||||||
target->health = 0;
|
|
||||||
target->angle = inflictor->angle - ANGLE_90;
|
|
||||||
target->destscale = scale;
|
|
||||||
P_SetScale(target, scale);
|
|
||||||
P_UnsetThingPosition(target);
|
|
||||||
target->flags = MF_NOCLIP;
|
|
||||||
target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale));
|
|
||||||
P_SetThingPosition(target);
|
|
||||||
P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale));
|
|
||||||
target->momz = FixedMul(6*FRACUNIT, target->scale);
|
|
||||||
if (flip)
|
|
||||||
target->momz = -target->momz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
momz = 7*scale;
|
||||||
|
if (flip)
|
||||||
|
momz *= -1;
|
||||||
|
|
||||||
|
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);
|
||||||
|
chunk->eflags |= flip;
|
||||||
|
|
||||||
|
P_SetMobjState(chunk, target->info->deathstate);
|
||||||
|
chunk->health = 0;
|
||||||
|
chunk->angle = ang + ANGLE_180;
|
||||||
|
chunk->destscale = scale;
|
||||||
|
P_SetScale(chunk, scale);
|
||||||
|
P_UnsetThingPosition(chunk);
|
||||||
|
chunk->flags = MF_NOCLIP;
|
||||||
|
chunk->x -= xoffs;
|
||||||
|
chunk->y -= yoffs;
|
||||||
|
if (flip)
|
||||||
|
chunk->z -= 12*scale;
|
||||||
|
else
|
||||||
|
chunk->z += 12*scale;
|
||||||
|
P_SetThingPosition(chunk);
|
||||||
|
P_InstaThrust(chunk, chunk->angle, 2*scale);
|
||||||
|
chunk->momz = momz;
|
||||||
|
|
||||||
|
P_SetMobjState(target, target->info->deathstate);
|
||||||
|
target->health = 0;
|
||||||
|
target->angle = ang;
|
||||||
|
P_UnsetThingPosition(target);
|
||||||
|
target->flags = MF_NOCLIP;
|
||||||
|
target->x += xoffs;
|
||||||
|
target->y += yoffs;
|
||||||
|
target->z = chunk->z;
|
||||||
|
P_SetThingPosition(target);
|
||||||
|
P_InstaThrust(target, target->angle, 2*scale);
|
||||||
|
target->momz = momz;
|
||||||
|
}
|
||||||
|
else if (target->type == MT_WALLSPIKE && target->info->deathstate != S_NULL)
|
||||||
|
{
|
||||||
|
const angle_t ang = (/*(inflictor) ? inflictor->angle : */target->angle) + ANGLE_90;
|
||||||
|
const fixed_t scale = target->scale;
|
||||||
|
const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale), forwardxoffs = P_ReturnThrustX(target, target->angle, 7*scale), forwardyoffs = P_ReturnThrustY(target, target->angle, 7*scale);
|
||||||
|
const UINT16 flip = (target->eflags & MFE_VERTICALFLIP);
|
||||||
|
mobj_t *chunk;
|
||||||
|
boolean sprflip;
|
||||||
|
|
||||||
|
S_StartSound(target, target->info->deathsound);
|
||||||
|
if (!P_MobjWasRemoved(target->tracer))
|
||||||
|
P_RemoveMobj(target->tracer);
|
||||||
|
|
||||||
|
if (target->info->xdeathstate != S_NULL)
|
||||||
|
{
|
||||||
|
sprflip = P_RandomChance(FRACUNIT/2);
|
||||||
|
|
||||||
|
#define makechunk(angtweak, xmov, ymov) \
|
||||||
|
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\
|
||||||
|
chunk->eflags |= flip;\
|
||||||
|
P_SetMobjState(chunk, target->info->xdeathstate);\
|
||||||
|
chunk->health = 0;\
|
||||||
|
chunk->angle = target->angle;\
|
||||||
|
chunk->destscale = scale;\
|
||||||
|
P_SetScale(chunk, scale);\
|
||||||
|
P_UnsetThingPosition(chunk);\
|
||||||
|
chunk->flags = MF_NOCLIP;\
|
||||||
|
chunk->x += xmov - forwardxoffs;\
|
||||||
|
chunk->y += ymov - forwardyoffs;\
|
||||||
|
P_SetThingPosition(chunk);\
|
||||||
|
P_InstaThrust(chunk, angtweak, 4*scale);\
|
||||||
|
chunk->momz = P_RandomRange(5, 7)*scale;\
|
||||||
|
if (flip)\
|
||||||
|
chunk->momz *= -1;\
|
||||||
|
if (sprflip)\
|
||||||
|
chunk->frame |= FF_VERTICALFLIP
|
||||||
|
|
||||||
|
makechunk(ang + ANGLE_180, -xoffs, -yoffs);
|
||||||
|
sprflip = !sprflip;
|
||||||
|
makechunk(ang, xoffs, yoffs);
|
||||||
|
|
||||||
|
#undef makechunk
|
||||||
|
}
|
||||||
|
|
||||||
|
sprflip = P_RandomChance(FRACUNIT/2);
|
||||||
|
|
||||||
|
chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);
|
||||||
|
chunk->eflags |= flip;
|
||||||
|
|
||||||
|
P_SetMobjState(chunk, target->info->deathstate);
|
||||||
|
chunk->health = 0;
|
||||||
|
chunk->angle = target->angle;
|
||||||
|
chunk->destscale = scale;
|
||||||
|
P_SetScale(chunk, scale);
|
||||||
|
P_UnsetThingPosition(chunk);
|
||||||
|
chunk->flags = MF_NOCLIP;
|
||||||
|
chunk->x += forwardxoffs - xoffs;
|
||||||
|
chunk->y += forwardyoffs - yoffs;
|
||||||
|
P_SetThingPosition(chunk);
|
||||||
|
P_InstaThrust(chunk, ang + ANGLE_180, 2*scale);
|
||||||
|
chunk->momz = P_RandomRange(5, 7)*scale;
|
||||||
|
if (flip)
|
||||||
|
chunk->momz *= -1;
|
||||||
|
if (sprflip)
|
||||||
|
chunk->frame |= FF_VERTICALFLIP;
|
||||||
|
|
||||||
|
P_SetMobjState(target, target->info->deathstate);
|
||||||
|
target->health = 0;
|
||||||
|
P_UnsetThingPosition(target);
|
||||||
|
target->flags = MF_NOCLIP;
|
||||||
|
target->x += forwardxoffs + xoffs;
|
||||||
|
target->y += forwardyoffs + yoffs;
|
||||||
|
P_SetThingPosition(target);
|
||||||
|
P_InstaThrust(target, ang, 2*scale);
|
||||||
|
target->momz = P_RandomRange(5, 7)*scale;
|
||||||
|
if (flip)
|
||||||
|
target->momz *= -1;
|
||||||
|
if (!sprflip)
|
||||||
|
target->frame |= FF_VERTICALFLIP;
|
||||||
}
|
}
|
||||||
else if (target->player)
|
else if (target->player)
|
||||||
{
|
{
|
||||||
|
@ -2879,7 +2957,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
|
|
||||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||||
|
|
||||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
if (damagetype == DMG_SPIKE) // spikes
|
||||||
S_StartSound(player->mo, sfx_spkdth);
|
S_StartSound(player->mo, sfx_spkdth);
|
||||||
else
|
else
|
||||||
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss.
|
||||||
|
@ -2908,7 +2986,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
||||||
|
|
||||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||||
|
|
||||||
if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes
|
if (damagetype == DMG_SPIKE) // spikes
|
||||||
S_StartSound(player->mo, sfx_spkdth);
|
S_StartSound(player->mo, sfx_spkdth);
|
||||||
|
|
||||||
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
if (source && source->player && !player->powers[pw_super]) //don't score points against super players
|
||||||
|
|
175
src/p_map.c
175
src/p_map.c
|
@ -439,7 +439,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
// Metal Sonic destroys tiny baby objects.
|
// Metal Sonic destroys tiny baby objects.
|
||||||
if (tmthing->type == MT_METALSONIC_RACE
|
if (tmthing->type == MT_METALSONIC_RACE
|
||||||
&& (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE))
|
&& (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS)
|
||||||
|
|| (thing->type == MT_SPIKE
|
||||||
|
|| thing->type == MT_WALLSPIKE)))
|
||||||
{
|
{
|
||||||
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
||||||
return true;
|
return true;
|
||||||
|
@ -451,12 +453,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
return true; // overhead
|
return true; // overhead
|
||||||
if (tmthing->z + tmthing->height < thing->z)
|
if (tmthing->z + tmthing->height < thing->z)
|
||||||
return true; // underneath
|
return true; // underneath
|
||||||
if (thing->type == MT_SPIKE)
|
if (thing->type == MT_SPIKE
|
||||||
|
|| thing->type == MT_WALLSPIKE)
|
||||||
{
|
{
|
||||||
|
mobjtype_t type = thing->type;
|
||||||
if (thing->flags & MF_SOLID)
|
if (thing->flags & MF_SOLID)
|
||||||
S_StartSound(tmthing, thing->info->deathsound);
|
S_StartSound(tmthing, thing->info->deathsound);
|
||||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||||
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
|
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -470,10 +474,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
// SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
|
// SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
|
||||||
if ((tmthing->player)
|
if ((tmthing->player)
|
||||||
&& (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
|
&& (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
|
||||||
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|
&& (thing->flags & (MF_MONITOR)
|
||||||
|
|| (thing->type == MT_SPIKE
|
||||||
|
|| thing->type == MT_WALLSPIKE)))
|
||||||
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|
||||||
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
|
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
|
||||||
&& (thing->type == MT_SPIKE))))
|
&& (thing->type == MT_SPIKE
|
||||||
|
|| thing->type == MT_WALLSPIKE))))
|
||||||
{
|
{
|
||||||
if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
|
||||||
return true;
|
return true;
|
||||||
|
@ -485,12 +492,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
return true; // overhead
|
return true; // overhead
|
||||||
if (tmthing->z + tmthing->height < thing->z)
|
if (tmthing->z + tmthing->height < thing->z)
|
||||||
return true; // underneath
|
return true; // underneath
|
||||||
if (thing->type == MT_SPIKE)
|
if (thing->type == MT_SPIKE
|
||||||
|
|| thing->type == MT_WALLSPIKE)
|
||||||
{
|
{
|
||||||
|
mobjtype_t type = thing->type;
|
||||||
if (thing->flags & MF_SOLID)
|
if (thing->flags & MF_SOLID)
|
||||||
S_StartSound(tmthing, thing->info->deathsound);
|
S_StartSound(tmthing, thing->info->deathsound);
|
||||||
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
|
||||||
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
|
if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale))
|
||||||
P_KillMobj(thing, tmthing, tmthing, 0);
|
P_KillMobj(thing, tmthing, tmthing, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -937,12 +946,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
|
if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale)
|
||||||
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
&& thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
|
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP))
|
||||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||||
}
|
}
|
||||||
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
|
else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale)
|
||||||
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
&& thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz
|
||||||
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
|
&& !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP)))
|
||||||
P_DamageMobj(thing, tmthing, tmthing, 1, 0);
|
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||||
}
|
}
|
||||||
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
|
else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?!
|
||||||
{
|
{
|
||||||
|
@ -951,12 +960,61 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
|
if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||||
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
|
&& tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale)
|
||||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
|
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP))
|
||||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||||
}
|
}
|
||||||
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||||
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
&& tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)
|
||||||
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
|
&& !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP)))
|
||||||
P_DamageMobj(tmthing, thing, thing, 1, 0);
|
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player
|
||||||
|
{
|
||||||
|
fixed_t bottomz, topz;
|
||||||
|
bottomz = tmthing->z;
|
||||||
|
topz = tmthing->z + tmthing->height;
|
||||||
|
if (tmthing->eflags & MFE_VERTICALFLIP)
|
||||||
|
bottomz -= FixedMul(FRACUNIT, tmthing->scale);
|
||||||
|
else
|
||||||
|
topz += FixedMul(FRACUNIT, tmthing->scale);
|
||||||
|
|
||||||
|
if (thing->z + thing->height > bottomz // above bottom
|
||||||
|
&& thing->z < topz) // below top
|
||||||
|
// don't check angle, the player was clearly in the way in this case
|
||||||
|
P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE);
|
||||||
|
}
|
||||||
|
else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player)
|
||||||
|
{
|
||||||
|
fixed_t bottomz, topz;
|
||||||
|
angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y);
|
||||||
|
|
||||||
|
if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy))
|
||||||
|
{
|
||||||
|
angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle;
|
||||||
|
if (playerangle > ANGLE_180)
|
||||||
|
playerangle = InvAngle(playerangle);
|
||||||
|
if (playerangle < ANGLE_90)
|
||||||
|
return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them.
|
||||||
|
}
|
||||||
|
|
||||||
|
bottomz = thing->z;
|
||||||
|
topz = thing->z + thing->height;
|
||||||
|
|
||||||
|
if (thing->eflags & MFE_VERTICALFLIP)
|
||||||
|
bottomz -= FixedMul(FRACUNIT, thing->scale);
|
||||||
|
else
|
||||||
|
topz += FixedMul(FRACUNIT, thing->scale);
|
||||||
|
|
||||||
|
if (tmthing->z + tmthing->height > bottomz // above bottom
|
||||||
|
&& tmthing->z < topz // below top
|
||||||
|
&& !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer
|
||||||
|
{ // use base as a reference point to determine what angle you touched the spike at
|
||||||
|
touchangle = thing->angle - touchangle;
|
||||||
|
if (touchangle > ANGLE_180)
|
||||||
|
touchangle = InvAngle(touchangle);
|
||||||
|
if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked!
|
||||||
|
P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thing->flags & MF_PUSHABLE)
|
if (thing->flags & MF_PUSHABLE)
|
||||||
|
@ -1112,11 +1170,15 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
|
if (!(tmthing->player) && (thing->player))
|
||||||
|
; // no solid thing should ever be able to step up onto a player
|
||||||
|
else if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
|
||||||
{
|
{
|
||||||
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
||||||
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
||||||
}
|
}
|
||||||
|
else if (tmthing->flags & MF_SPRING && (thing->flags & MF_PUSHABLE))
|
||||||
|
; // Fix a few nasty spring-jumping bugs that happen sometimes.
|
||||||
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
||||||
// unless it's a CTF team monitor and you're on the wrong team
|
// unless it's a CTF team monitor and you're on the wrong team
|
||||||
else if (thing->flags & MF_MONITOR && tmthing->player
|
else if (thing->flags & MF_MONITOR && tmthing->player
|
||||||
|
@ -1155,11 +1217,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||||
|
|
||||||
|
if (thing->flags & MF_SPRING)
|
||||||
|
;
|
||||||
// block only when jumping not high enough,
|
// block only when jumping not high enough,
|
||||||
// (dont climb max. 24units while already in air)
|
// (dont climb max. 24units while already in air)
|
||||||
// since return false doesn't handle momentum properly,
|
// since return false doesn't handle momentum properly,
|
||||||
// we lie to P_TryMove() so it's always too high
|
// we lie to P_TryMove() so it's always too high
|
||||||
if (tmthing->player && tmthing->z + tmthing->height > topz
|
else if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||||
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
||||||
{
|
{
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
|
@ -1171,8 +1235,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
#endif
|
#endif
|
||||||
tmfloorthing = thing; // needed for side collision
|
tmfloorthing = thing; // needed for side collision
|
||||||
}
|
}
|
||||||
else if (thing->flags & MF_SPRING)
|
|
||||||
;
|
|
||||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||||
{
|
{
|
||||||
tmceilingz = topz;
|
tmceilingz = topz;
|
||||||
|
@ -1201,11 +1263,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||||
|
|
||||||
|
if (thing->flags & MF_SPRING)
|
||||||
|
;
|
||||||
// block only when jumping not high enough,
|
// block only when jumping not high enough,
|
||||||
// (dont climb max. 24units while already in air)
|
// (dont climb max. 24units while already in air)
|
||||||
// since return false doesn't handle momentum properly,
|
// since return false doesn't handle momentum properly,
|
||||||
// we lie to P_TryMove() so it's always too high
|
// we lie to P_TryMove() so it's always too high
|
||||||
if (tmthing->player && tmthing->z < topz
|
else if (tmthing->player && tmthing->z < topz
|
||||||
&& tmthing->z > tmthing->floorz)
|
&& tmthing->z > tmthing->floorz)
|
||||||
{
|
{
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
|
@ -1217,8 +1281,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
#endif
|
#endif
|
||||||
tmfloorthing = thing; // needed for side collision
|
tmfloorthing = thing; // needed for side collision
|
||||||
}
|
}
|
||||||
else if (thing->flags & MF_SPRING)
|
|
||||||
;
|
|
||||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||||
{
|
{
|
||||||
tmfloorz = topz;
|
tmfloorz = topz;
|
||||||
|
@ -3052,12 +3114,86 @@ void P_SlideMove(mobj_t *mo)
|
||||||
INT16 hitcount = 0;
|
INT16 hitcount = 0;
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
|
|
||||||
|
boolean papercol = false;
|
||||||
|
vertex_t v1, v2; // fake vertexes
|
||||||
|
line_t junk; // fake linedef
|
||||||
|
|
||||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||||
{
|
{
|
||||||
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
||||||
if (tmhitthing->flags & MF_PUSHABLE)
|
if (tmhitthing->flags & MF_PUSHABLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (tmhitthing->flags & MF_PAPERCOLLISION)
|
||||||
|
{
|
||||||
|
fixed_t cosradius, sinradius, num, den;
|
||||||
|
|
||||||
|
// trace along the three leading corners
|
||||||
|
if (mo->momx > 0)
|
||||||
|
{
|
||||||
|
leadx = mo->x + mo->radius;
|
||||||
|
trailx = mo->x - mo->radius;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leadx = mo->x - mo->radius;
|
||||||
|
trailx = mo->x + mo->radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mo->momy > 0)
|
||||||
|
{
|
||||||
|
leady = mo->y + mo->radius;
|
||||||
|
traily = mo->y - mo->radius;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leady = mo->y - mo->radius;
|
||||||
|
traily = mo->y + mo->radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
papercol = true;
|
||||||
|
slidemo = mo;
|
||||||
|
bestslideline = &junk;
|
||||||
|
|
||||||
|
cosradius = FixedMul(tmhitthing->radius, FINECOSINE(tmhitthing->angle>>ANGLETOFINESHIFT));
|
||||||
|
sinradius = FixedMul(tmhitthing->radius, FINESINE(tmhitthing->angle>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
v1.x = tmhitthing->x - cosradius;
|
||||||
|
v1.y = tmhitthing->y - sinradius;
|
||||||
|
v2.x = tmhitthing->x + cosradius;
|
||||||
|
v2.y = tmhitthing->y + sinradius;
|
||||||
|
|
||||||
|
junk.v1 = &v1;
|
||||||
|
junk.v2 = &v2;
|
||||||
|
junk.dx = 2*cosradius; // v2.x - v1.x;
|
||||||
|
junk.dy = 2*sinradius; // v2.y - v1.y;
|
||||||
|
|
||||||
|
junk.slopetype = !cosradius ? ST_VERTICAL : !sinradius ? ST_HORIZONTAL :
|
||||||
|
((sinradius > 0) == (cosradius > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
||||||
|
|
||||||
|
bestslidefrac = FRACUNIT+1;
|
||||||
|
|
||||||
|
den = FixedMul(junk.dy>>8, mo->momx) - FixedMul(junk.dx>>8, mo->momy);
|
||||||
|
|
||||||
|
if (!den)
|
||||||
|
bestslidefrac = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t frac;
|
||||||
|
#define P_PaperTraverse(startx, starty) \
|
||||||
|
num = FixedMul((v1.x - leadx)>>8, junk.dy) + FixedMul((leady - v1.y)>>8, junk.dx); \
|
||||||
|
frac = FixedDiv(num, den); \
|
||||||
|
if (frac < bestslidefrac) \
|
||||||
|
bestslidefrac = frac
|
||||||
|
P_PaperTraverse(leadx, leady);
|
||||||
|
P_PaperTraverse(trailx, leady);
|
||||||
|
P_PaperTraverse(leadx, traily);
|
||||||
|
#undef dowork
|
||||||
|
}
|
||||||
|
|
||||||
|
goto papercollision;
|
||||||
|
}
|
||||||
|
|
||||||
// Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases.
|
// Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases.
|
||||||
if (mo->y + mo->radius <= tmhitthing->y - tmhitthing->radius)
|
if (mo->y + mo->radius <= tmhitthing->y - tmhitthing->radius)
|
||||||
{
|
{
|
||||||
|
@ -3088,7 +3224,7 @@ void P_SlideMove(mobj_t *mo)
|
||||||
bestslideline = NULL;
|
bestslideline = NULL;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (++hitcount == 3)
|
if ((++hitcount == 3) || papercol)
|
||||||
goto stairstep; // don't loop forever
|
goto stairstep; // don't loop forever
|
||||||
|
|
||||||
// trace along the three leading corners
|
// trace along the three leading corners
|
||||||
|
@ -3130,6 +3266,7 @@ retry:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
papercollision:
|
||||||
// move up to the wall
|
// move up to the wall
|
||||||
if (bestslidefrac == FRACUNIT+1)
|
if (bestslidefrac == FRACUNIT+1)
|
||||||
{
|
{
|
||||||
|
|
535
src/p_mobj.c
535
src/p_mobj.c
|
@ -2739,8 +2739,9 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case MT_SPIKE:
|
case MT_SPIKE:
|
||||||
|
case MT_WALLSPIKE:
|
||||||
// Dead spike particles disappear upon ground contact
|
// Dead spike particles disappear upon ground contact
|
||||||
if ((mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) && mo->health <= 0)
|
if (!mo->health && (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz))
|
||||||
{
|
{
|
||||||
P_RemoveMobj(mo);
|
P_RemoveMobj(mo);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6453,6 +6454,128 @@ static void P_NightsItemChase(mobj_t *thing)
|
||||||
P_Attract(thing, thing->tracer, true);
|
P_Attract(thing, thing->tracer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// P_MaceRotate
|
||||||
|
// Spins an object around its target, or, swings it from side to side.
|
||||||
|
//
|
||||||
|
static void P_MaceRotate(mobj_t *mobj)
|
||||||
|
{
|
||||||
|
TVector v;
|
||||||
|
TVector *res;
|
||||||
|
fixed_t radius, dist;
|
||||||
|
angle_t fa;
|
||||||
|
INT32 prevswing;
|
||||||
|
boolean donetwice = false;
|
||||||
|
|
||||||
|
// Tracer was removed.
|
||||||
|
if (!mobj->health)
|
||||||
|
return;
|
||||||
|
else if (!mobj->tracer)
|
||||||
|
{
|
||||||
|
P_KillMobj(mobj, NULL, NULL, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mobj->momx = mobj->momy = mobj->momz = 0;
|
||||||
|
|
||||||
|
prevswing = mobj->threshold;
|
||||||
|
mobj->threshold += mobj->tracer->lastlook;
|
||||||
|
mobj->threshold &= FINEMASK;
|
||||||
|
|
||||||
|
dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed);
|
||||||
|
|
||||||
|
// Radius of the link's rotation.
|
||||||
|
radius = FixedMul(dist * mobj->movecount, mobj->tracer->scale) + mobj->tracer->extravalue1;
|
||||||
|
|
||||||
|
maceretry:
|
||||||
|
|
||||||
|
fa = (FixedAngle(mobj->tracer->movefactor*FRACUNIT) >> ANGLETOFINESHIFT);
|
||||||
|
radius = FixedMul(FINECOSINE(fa), radius);
|
||||||
|
v[1] = -FixedMul(FINESINE(fa), radius)
|
||||||
|
+ FixedMul(dist * mobj->movefactor, mobj->tracer->scale);
|
||||||
|
v[3] = FRACUNIT;
|
||||||
|
|
||||||
|
// Swinging Chain.
|
||||||
|
if (mobj->tracer->flags2 & MF2_STRONGBOX)
|
||||||
|
{
|
||||||
|
fixed_t swingmagnitude = FixedMul(FINECOSINE(mobj->threshold), mobj->tracer->lastlook << FRACBITS);
|
||||||
|
prevswing = FINECOSINE(prevswing);
|
||||||
|
|
||||||
|
if (!donetwice
|
||||||
|
&& (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound
|
||||||
|
&& ((prevswing > 0) != (swingmagnitude > 0))) // just passed its lowest point
|
||||||
|
S_StartSound(mobj, mobj->info->activesound);
|
||||||
|
|
||||||
|
fa = ((FixedAngle(swingmagnitude) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK;
|
||||||
|
|
||||||
|
v[0] = FixedMul(FINESINE(fa), -radius);
|
||||||
|
v[2] = FixedMul(FINECOSINE(fa), -radius);
|
||||||
|
}
|
||||||
|
// Rotating Chain.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevswing = (prevswing + mobj->friction) & FINEMASK;
|
||||||
|
fa = (mobj->threshold + mobj->friction) & FINEMASK;
|
||||||
|
|
||||||
|
if (!donetwice
|
||||||
|
&& (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound
|
||||||
|
&& (!(prevswing > (FINEMASK/2)) && (fa > (FINEMASK/2)))) // completed a full swing
|
||||||
|
S_StartSound(mobj, mobj->info->activesound);
|
||||||
|
|
||||||
|
v[0] = FixedMul(FINECOSINE(fa), radius);
|
||||||
|
v[2] = FixedMul(FINESINE(fa), radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the angle matrixes for the link.
|
||||||
|
res = VectorMatrixMultiply(v, *RotateXMatrix(mobj->tracer->threshold << ANGLETOFINESHIFT));
|
||||||
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
res = VectorMatrixMultiply(v, *RotateZMatrix(mobj->tracer->health << ANGLETOFINESHIFT));
|
||||||
|
M_Memcpy(&v, res, sizeof(v));
|
||||||
|
|
||||||
|
// Cut the height to align the link with the axis.
|
||||||
|
if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN)
|
||||||
|
v[2] -= P_MobjFlip(mobj)*mobj->height/4;
|
||||||
|
else
|
||||||
|
v[2] -= P_MobjFlip(mobj)*mobj->height/2;
|
||||||
|
|
||||||
|
P_UnsetThingPosition(mobj);
|
||||||
|
|
||||||
|
// Add on the appropriate distances to the center's co-ordinates.
|
||||||
|
mobj->x = mobj->tracer->x + v[0];
|
||||||
|
mobj->y = mobj->tracer->y + v[1];
|
||||||
|
mobj->z = mobj->tracer->z + v[2];
|
||||||
|
|
||||||
|
P_SetThingPosition(mobj);
|
||||||
|
|
||||||
|
if (donetwice || P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mobj->subsector->sector->ffloors)
|
||||||
|
P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2);
|
||||||
|
|
||||||
|
// Variable reuse
|
||||||
|
if (mobj->floorz > mobj->z)
|
||||||
|
dist = (mobj->floorz - mobj->tracer->z);
|
||||||
|
else if (mobj->ceilingz < mobj->z)
|
||||||
|
dist = (mobj->ceilingz - mobj->tracer->z);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((dist = FixedDiv(dist, v[2])) > FRACUNIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
radius = FixedMul(radius, dist);
|
||||||
|
donetwice = true;
|
||||||
|
dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed);
|
||||||
|
goto maceretry;
|
||||||
|
}
|
||||||
|
|
||||||
static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
|
static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
|
||||||
{
|
{
|
||||||
if (!thing->target || thing->target->health <= 0 || !thing->target->player
|
if (!thing->target || thing->target->health <= 0 || !thing->target->player
|
||||||
|
@ -6810,6 +6933,13 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
// fade out when nearing the end of fuse...
|
// fade out when nearing the end of fuse...
|
||||||
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
mobj->frame = (mobj->frame & ~FF_TRANSMASK) | (((NUMTRANSMAPS-1) - mobj->fuse / 2) << FF_TRANSSHIFT);
|
||||||
|
|
||||||
|
if (mobj->flags2 & MF2_MACEROTATE)
|
||||||
|
{
|
||||||
|
P_MaceRotate(mobj);
|
||||||
|
if (P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Special thinker for scenery objects
|
// Special thinker for scenery objects
|
||||||
if (mobj->flags & MF_SCENERY)
|
if (mobj->flags & MF_SCENERY)
|
||||||
{
|
{
|
||||||
|
@ -7373,6 +7503,25 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
else switch (mobj->type)
|
else switch (mobj->type)
|
||||||
{
|
{
|
||||||
|
case MT_WALLSPIKEBASE:
|
||||||
|
if (!mobj->target) {
|
||||||
|
P_RemoveMobj(mobj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK);
|
||||||
|
#if 0
|
||||||
|
if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle
|
||||||
|
{
|
||||||
|
mobj_t *target = mobj->target; // shortcut
|
||||||
|
const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale);
|
||||||
|
P_UnsetThingPosition(mobj);
|
||||||
|
mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius);
|
||||||
|
mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius);
|
||||||
|
P_SetThingPosition(mobj);
|
||||||
|
mobj->angle = target->angle + ANGLE_90;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case MT_FALLINGROCK:
|
case MT_FALLINGROCK:
|
||||||
// Despawn rocks here in case zmovement code can't do so (blame slopes)
|
// Despawn rocks here in case zmovement code can't do so (blame slopes)
|
||||||
if (!mobj->momx && !mobj->momy && !mobj->momz
|
if (!mobj->momx && !mobj->momy && !mobj->momz
|
||||||
|
@ -7456,7 +7605,8 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_SPINMACEPOINT:
|
case MT_CHAINPOINT:
|
||||||
|
case MT_CHAINMACEPOINT:
|
||||||
if (leveltime & 1)
|
if (leveltime & 1)
|
||||||
{
|
{
|
||||||
if (mobj->lastlook > mobj->movecount)
|
if (mobj->lastlook > mobj->movecount)
|
||||||
|
@ -7792,6 +7942,10 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
if (mobj->flags2 & MF2_NIGHTSPULL)
|
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||||
P_NightsItemChase(mobj);
|
P_NightsItemChase(mobj);
|
||||||
break;
|
break;
|
||||||
|
case MT_EMBLEM:
|
||||||
|
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||||
|
P_NightsItemChase(mobj);
|
||||||
|
break;
|
||||||
case MT_SHELL:
|
case MT_SHELL:
|
||||||
if (mobj->threshold && mobj->threshold != TICRATE)
|
if (mobj->threshold && mobj->threshold != TICRATE)
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
|
@ -8066,6 +8220,10 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|
||||||
if (mobj->spawnpoint)
|
if (mobj->spawnpoint)
|
||||||
mobj->fuse += mobj->spawnpoint->angle;
|
mobj->fuse += mobj->spawnpoint->angle;
|
||||||
break;
|
break;
|
||||||
|
case MT_WALLSPIKE:
|
||||||
|
P_SetMobjState(mobj, mobj->state->nextstate);
|
||||||
|
mobj->fuse = mobj->info->speed;
|
||||||
|
break;
|
||||||
case MT_NIGHTSCORE:
|
case MT_NIGHTSCORE:
|
||||||
P_RemoveMobj(mobj);
|
P_RemoveMobj(mobj);
|
||||||
return;
|
return;
|
||||||
|
@ -8457,9 +8615,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
// Collision helper can be stood on but not pushed
|
// Collision helper can be stood on but not pushed
|
||||||
mobj->flags2 |= MF2_STANDONME;
|
mobj->flags2 |= MF2_STANDONME;
|
||||||
break;
|
break;
|
||||||
|
case MT_WALLSPIKE:
|
||||||
case MT_SPIKE:
|
case MT_SPIKE:
|
||||||
mobj->flags2 |= MF2_STANDONME;
|
mobj->flags2 |= MF2_STANDONME;
|
||||||
break;
|
break;
|
||||||
|
case MT_GFZTREE:
|
||||||
|
case MT_GFZBERRYTREE:
|
||||||
|
case MT_GFZCHERRYTREE:
|
||||||
case MT_LAMPPOST1:
|
case MT_LAMPPOST1:
|
||||||
case MT_LAMPPOST2:
|
case MT_LAMPPOST2:
|
||||||
mobj->flags2 |= MF2_STANDONME;
|
mobj->flags2 |= MF2_STANDONME;
|
||||||
|
@ -9478,7 +9640,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metalrecording) // Metal Sonic can't use these things.
|
if (metalrecording) // Metal Sonic can't use these things.
|
||||||
if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_EMMY || i == MT_STARPOST)
|
if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds
|
if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds
|
||||||
|
@ -9592,7 +9754,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Emerald Tokens -->> Score Tokens
|
// Emerald Tokens -->> Score Tokens
|
||||||
else if (i == MT_EMMY)
|
else if (i == MT_TOKEN)
|
||||||
return; /// \todo
|
return; /// \todo
|
||||||
|
|
||||||
// 1UPs -->> Score TVs
|
// 1UPs -->> Score TVs
|
||||||
|
@ -9620,7 +9782,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
// They're likely facets of the level's design and therefore required to progress.
|
// They're likely facets of the level's design and therefore required to progress.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == MT_EMMY && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
|
if (i == MT_TOKEN && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
|
||||||
return; // you already got this token, or there are too many, or the gametype's not right
|
return; // you already got this token, or there are too many, or the gametype's not right
|
||||||
|
|
||||||
// Objectplace landing point
|
// Objectplace landing point
|
||||||
|
@ -9639,7 +9801,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
|
ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||||
else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
|
else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
|
||||||
z = ONFLOORZ;
|
z = ONFLOORZ;
|
||||||
else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY)
|
else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN)
|
||||||
{
|
{
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
if (mthing->options & MTF_OBJECTFLIP)
|
||||||
{
|
{
|
||||||
|
@ -9729,6 +9891,16 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
mobj = P_SpawnMobj(x, y, z, i);
|
mobj = P_SpawnMobj(x, y, z, i);
|
||||||
mobj->spawnpoint = mthing;
|
mobj->spawnpoint = mthing;
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUAh_MapThingSpawn(mobj, mthing))
|
||||||
|
{
|
||||||
|
if (P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
switch(mobj->type)
|
switch(mobj->type)
|
||||||
{
|
{
|
||||||
case MT_SKYBOX:
|
case MT_SKYBOX:
|
||||||
|
@ -9771,15 +9943,20 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
mobj->movedir = mthing->extrainfo;
|
mobj->movedir = mthing->extrainfo;
|
||||||
break;
|
break;
|
||||||
case MT_MACEPOINT:
|
case MT_MACEPOINT:
|
||||||
case MT_SWINGMACEPOINT:
|
case MT_CHAINMACEPOINT:
|
||||||
case MT_HANGMACEPOINT:
|
case MT_SPRINGBALLPOINT:
|
||||||
case MT_SPINMACEPOINT:
|
case MT_CHAINPOINT:
|
||||||
|
case MT_FIREBARPOINT:
|
||||||
|
case MT_CUSTOMMACEPOINT:
|
||||||
{
|
{
|
||||||
fixed_t mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed;
|
fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor;
|
||||||
mobjtype_t chainlink = MT_SMALLMACECHAIN;
|
angle_t mspokeangle;
|
||||||
mobjtype_t macetype = MT_SMALLMACE;
|
mobjtype_t chainlink, macetype, firsttype, linktype;
|
||||||
boolean firsttime;
|
boolean mdoall = true;
|
||||||
mobj_t *spawnee;
|
mobj_t *spawnee;
|
||||||
|
mobjflag_t mflagsapply;
|
||||||
|
mobjflag2_t mflags2apply;
|
||||||
|
mobjeflag_t meflagsapply;
|
||||||
INT32 line;
|
INT32 line;
|
||||||
const size_t mthingi = (size_t)(mthing - mapthings);
|
const size_t mthingi = (size_t)(mthing - mapthings);
|
||||||
|
|
||||||
|
@ -9793,93 +9970,240 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
No deaf - small mace
|
mapthing -
|
||||||
Deaf - big mace
|
MTF_AMBUSH :
|
||||||
|
MT_SPRINGBALLPOINT - upgrade from yellow to red spring
|
||||||
|
anything else - bigger mace/chain theory
|
||||||
|
MTF_OBJECTSPECIAL - force silent
|
||||||
|
MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements
|
||||||
|
Parameter value : number of "spokes"
|
||||||
|
|
||||||
ML_NOCLIMB : Direction not controllable
|
linedef -
|
||||||
|
ML_NOCLIMB :
|
||||||
|
MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable
|
||||||
|
anything else - no functionality
|
||||||
|
ML_EFFECT1 : Swings instead of spins
|
||||||
|
ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT)
|
||||||
|
ML_EFFECT3 : Spawn a bonus macetype at the hinge point
|
||||||
|
ML_EFFECT4 : Don't clip inside the ground
|
||||||
*/
|
*/
|
||||||
mlength = abs(lines[line].dx >> FRACBITS);
|
mlength = abs(lines[line].dx >> FRACBITS);
|
||||||
mspeed = abs(lines[line].dy >> FRACBITS);
|
mspeed = abs(lines[line].dy >> (FRACBITS - 4));
|
||||||
mxspeed = sides[lines[line].sidenum[0]].textureoffset >> FRACBITS;
|
mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360;
|
||||||
mzspeed = sides[lines[line].sidenum[0]].rowoffset >> FRACBITS;
|
if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed)
|
||||||
mstartangle = lines[line].frontsector->floorheight >> FRACBITS;
|
mmaxspeed = mspeed << 1;
|
||||||
mmaxspeed = lines[line].frontsector->ceilingheight >> FRACBITS;
|
mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360;
|
||||||
|
myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360;
|
||||||
|
|
||||||
mstartangle %= 360;
|
mnumspokes = mthing->extrainfo + 1;
|
||||||
mxspeed %= 360;
|
mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes)>>ANGLETOFINESHIFT;
|
||||||
mzspeed %= 360;
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Mace Chain (mapthing #%s):\n"
|
if (lines[line].backsector)
|
||||||
|
{
|
||||||
|
mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360;
|
||||||
|
mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360;
|
||||||
|
mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS);
|
||||||
|
if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0)
|
||||||
|
mwidth = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mpinch = mroll = mnumnospokes = mwidth = 0;
|
||||||
|
|
||||||
|
CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n"
|
||||||
"Length is %d\n"
|
"Length is %d\n"
|
||||||
"Speed is %d\n"
|
"Speed is %d\n"
|
||||||
"Xspeed is %d\n"
|
"Phase is %d\n"
|
||||||
"Zspeed is %d\n"
|
"Yaw is %d\n"
|
||||||
"startangle is %d\n"
|
"Pitch is %d\n"
|
||||||
"maxspeed is %d\n",
|
"Max. speed is %d\n"
|
||||||
sizeu1(mthingi), mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed);
|
"No. of spokes is %d\n"
|
||||||
|
"Pinch is %d\n"
|
||||||
|
"Roll is %d\n"
|
||||||
|
"No. of antispokes is %d\n"
|
||||||
|
"Width is %d\n",
|
||||||
|
sizeu1(mthingi), mlength, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mpinch, mroll, mnumnospokes, mwidth);
|
||||||
|
|
||||||
mobj->lastlook = mspeed << 4;
|
if (mnumnospokes > 0 && (mnumnospokes < mnumspokes))
|
||||||
|
mnumnospokes = mnumspokes/mnumnospokes;
|
||||||
|
else
|
||||||
|
mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes - 1) : 0);
|
||||||
|
|
||||||
|
mobj->lastlook = mspeed;
|
||||||
mobj->movecount = mobj->lastlook;
|
mobj->movecount = mobj->lastlook;
|
||||||
mobj->health = (FixedAngle(mzspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT);
|
mobj->health = (FixedAngle(myaw*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||||
mobj->threshold = (FixedAngle(mxspeed*FRACUNIT)>>ANGLETOFINESHIFT) + (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT);
|
mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||||
mobj->movefactor = mobj->threshold;
|
|
||||||
mobj->friction = mmaxspeed;
|
mobj->friction = mmaxspeed;
|
||||||
|
mobj->movefactor = mpinch;
|
||||||
|
|
||||||
|
// Mobjtype selection
|
||||||
|
switch(mobj->type)
|
||||||
|
{
|
||||||
|
case MT_SPRINGBALLPOINT:
|
||||||
|
macetype = ((mthing->options & MTF_AMBUSH)
|
||||||
|
? MT_REDSPRINGBALL
|
||||||
|
: MT_YELLOWSPRINGBALL);
|
||||||
|
chainlink = MT_SMALLMACECHAIN;
|
||||||
|
break;
|
||||||
|
case MT_FIREBARPOINT:
|
||||||
|
macetype = ((mthing->options & MTF_AMBUSH)
|
||||||
|
? MT_BIGFIREBAR
|
||||||
|
: MT_SMALLFIREBAR);
|
||||||
|
chainlink = MT_NULL;
|
||||||
|
break;
|
||||||
|
case MT_CUSTOMMACEPOINT:
|
||||||
|
macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture;
|
||||||
|
if (lines[line].backsector)
|
||||||
|
chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture;
|
||||||
|
else
|
||||||
|
chainlink = MT_NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mthing->options & MTF_AMBUSH)
|
||||||
|
{
|
||||||
|
macetype = MT_BIGMACE;
|
||||||
|
chainlink = MT_BIGMACECHAIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
macetype = MT_SMALLMACE;
|
||||||
|
chainlink = MT_SMALLMACECHAIN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!macetype)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (mobj->type != MT_CHAINPOINT)
|
||||||
|
{
|
||||||
|
firsttype = macetype;
|
||||||
|
mlength++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!mlength)
|
||||||
|
break;
|
||||||
|
firsttype = chainlink;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjustable direction
|
||||||
if (lines[line].flags & ML_NOCLIMB)
|
if (lines[line].flags & ML_NOCLIMB)
|
||||||
mobj->flags |= MF_SLIDEME;
|
mobj->flags |= MF_SLIDEME;
|
||||||
|
|
||||||
mobj->reactiontime = 0;
|
// Swinging
|
||||||
|
if (lines[line].flags & ML_EFFECT1)
|
||||||
if (mthing->options & MTF_AMBUSH)
|
|
||||||
{
|
{
|
||||||
chainlink = MT_BIGMACECHAIN;
|
mobj->flags2 |= MF2_STRONGBOX;
|
||||||
macetype = MT_BIGMACE;
|
mmin = ((mnumnospokes > 1) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTSPECIAL)
|
|
||||||
mobj->flags2 |= MF2_BOSSNOTRAP; // shut up maces.
|
|
||||||
|
|
||||||
if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SPINMACEPOINT)
|
|
||||||
firsttime = true;
|
|
||||||
else
|
else
|
||||||
|
mmin = mnumspokes;
|
||||||
|
|
||||||
|
// Make the links the same type as the end - repeated below
|
||||||
|
if ((mobj->type != MT_CHAINPOINT) && (!(lines[line].flags & ML_EFFECT2) == (mobj->type == MT_FIREBARPOINT))) // exclusive or
|
||||||
{
|
{
|
||||||
firsttime = false;
|
linktype = macetype;
|
||||||
|
radiusfactor = 2; // Double the radius.
|
||||||
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, macetype);
|
|
||||||
P_SetTarget(&spawnee->target, mobj);
|
|
||||||
|
|
||||||
if (mobj->type == MT_SWINGMACEPOINT)
|
|
||||||
spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT;
|
|
||||||
else
|
|
||||||
spawnee->movecount = 0;
|
|
||||||
|
|
||||||
spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT;
|
|
||||||
spawnee->reactiontime = mlength+1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1);
|
||||||
|
|
||||||
while (mlength > 0)
|
mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT));
|
||||||
|
mflags2apply = (MF2_MACEROTATE|((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0));
|
||||||
|
meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0);
|
||||||
|
|
||||||
|
msound = ((firsttype == chainlink) ? 0 : (mwidth & 1));
|
||||||
|
|
||||||
|
// Quick and easy preparatory variable setting
|
||||||
|
mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||||
|
mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
#define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\
|
||||||
|
P_SetTarget(&spawnee->tracer, mobj);\
|
||||||
|
spawnee->threshold = mphase;\
|
||||||
|
spawnee->friction = mroll;\
|
||||||
|
spawnee->movefactor = mwidth;\
|
||||||
|
spawnee->movecount = dist;\
|
||||||
|
spawnee->angle = myaw;\
|
||||||
|
spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\
|
||||||
|
spawnee->flags2 |= (mflags2apply|moreflags2);\
|
||||||
|
spawnee->eflags |= meflagsapply
|
||||||
|
|
||||||
|
domaceagain:
|
||||||
|
mnumspokesset = mnumspokes;
|
||||||
|
|
||||||
|
if (mdoall && lines[line].flags & ML_EFFECT3) // Innermost mace/link
|
||||||
|
{ spawnee = makemace(macetype, 0, MF2_AMBUSH); }
|
||||||
|
|
||||||
|
// The actual spawning of spokes
|
||||||
|
while (mnumspokesset-- > 0)
|
||||||
{
|
{
|
||||||
spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink);
|
// Offsets
|
||||||
|
if (lines[line].flags & ML_EFFECT1) // Swinging
|
||||||
|
mroll = (mroll - mspokeangle) & FINEMASK;
|
||||||
|
else // Spinning
|
||||||
|
mphase = (mphase - mspokeangle) & FINEMASK;
|
||||||
|
|
||||||
P_SetTarget(&spawnee->target, mobj);
|
if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke
|
||||||
|
|
||||||
if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SWINGMACEPOINT)
|
|
||||||
spawnee->movecount = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT;
|
|
||||||
else
|
|
||||||
spawnee->movecount = 0;
|
|
||||||
|
|
||||||
spawnee->threshold = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT;
|
|
||||||
spawnee->reactiontime = mlength;
|
|
||||||
|
|
||||||
if (firsttime)
|
|
||||||
{
|
{
|
||||||
// This is the outermost link in the chain
|
if (mobj->type != MT_CHAINMACEPOINT)
|
||||||
spawnee->flags2 |= MF2_AMBUSH;
|
continue;
|
||||||
firsttime = false;
|
|
||||||
|
firsttype = linktype = chainlink;
|
||||||
|
mlengthset = 1 + (mlength - 1)*radiusfactor;
|
||||||
|
radiusfactor = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mobj->type == MT_CHAINMACEPOINT)
|
||||||
|
{
|
||||||
|
// Make the links the same type as the end - repeated above
|
||||||
|
if (lines[line].flags & ML_EFFECT2)
|
||||||
|
{
|
||||||
|
linktype = macetype;
|
||||||
|
radiusfactor = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
linktype = chainlink;
|
||||||
|
radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
firsttype = macetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
mlengthset = mlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlength--;
|
// Outermost mace/link
|
||||||
|
spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH);
|
||||||
|
|
||||||
|
if (mspeed && (mwidth == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokesset <= mmin) // Can it make a sound?
|
||||||
|
spawnee->flags2 |= MF2_BOSSNOTRAP;
|
||||||
|
|
||||||
|
if (!mdoall || !linktype)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// The rest of the links
|
||||||
|
while (mlengthset > 0)
|
||||||
|
{ spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mwidth > 0)
|
||||||
|
{
|
||||||
|
mwidth *= -1;
|
||||||
|
goto domaceagain;
|
||||||
|
}
|
||||||
|
else if (mwidth != 0)
|
||||||
|
{
|
||||||
|
if ((mwidth = -(mwidth + ((firsttype == chainlink) ? 1 : 2))) < 0)
|
||||||
|
break;
|
||||||
|
mdoall = false;
|
||||||
|
goto domaceagain;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef makemace
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MT_PARTICLEGEN:
|
case MT_PARTICLEGEN:
|
||||||
|
@ -10028,28 +10352,10 @@ ML_NOCLIMB : Direction not controllable
|
||||||
mobj->radius = (mthing->angle & 16383)*FRACUNIT;
|
mobj->radius = (mthing->angle & 16383)*FRACUNIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i == MT_EMMY)
|
else if (i == MT_TOKEN)
|
||||||
{
|
{
|
||||||
if (mthing->options & MTF_OBJECTSPECIAL) // Mario Block version
|
if (mthing->options & MTF_OBJECTSPECIAL) // Mario Block version
|
||||||
mobj->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
mobj->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||||
else
|
|
||||||
{
|
|
||||||
fixed_t zheight = mobj->z;
|
|
||||||
mobj_t *tokenobj;
|
|
||||||
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP)
|
|
||||||
zheight += mobj->height-FixedMul(mobjinfo[MT_TOKEN].height, mobj->scale); // align with emmy properly!
|
|
||||||
|
|
||||||
tokenobj = P_SpawnMobj(x, y, zheight, MT_TOKEN);
|
|
||||||
P_SetTarget(&mobj->tracer, tokenobj);
|
|
||||||
tokenobj->destscale = mobj->scale;
|
|
||||||
P_SetScale(tokenobj, mobj->scale);
|
|
||||||
if (mthing->options & MTF_OBJECTFLIP) // flip token to match emmy
|
|
||||||
{
|
|
||||||
tokenobj->eflags |= MFE_VERTICALFLIP;
|
|
||||||
tokenobj->flags2 |= MF2_OBJECTFLIP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We advanced tokenbits earlier due to the return check.
|
// We advanced tokenbits earlier due to the return check.
|
||||||
// Subtract 1 here for the correct value.
|
// Subtract 1 here for the correct value.
|
||||||
|
@ -10100,8 +10406,8 @@ ML_NOCLIMB : Direction not controllable
|
||||||
mobj->flags &= ~MF_SCENERY;
|
mobj->flags &= ~MF_SCENERY;
|
||||||
mobj->fuse = mthing->angle + mobj->info->speed;
|
mobj->fuse = mthing->angle + mobj->info->speed;
|
||||||
}
|
}
|
||||||
// Use per-thing collision for spikes if the deaf flag is checked.
|
// Use per-thing collision for spikes if the deaf flag isn't checked.
|
||||||
if (mthing->options & MTF_AMBUSH && !metalrecording)
|
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
|
||||||
{
|
{
|
||||||
P_UnsetThingPosition(mobj);
|
P_UnsetThingPosition(mobj);
|
||||||
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT);
|
||||||
|
@ -10109,6 +10415,38 @@ ML_NOCLIMB : Direction not controllable
|
||||||
P_SetThingPosition(mobj);
|
P_SetThingPosition(mobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (i == MT_WALLSPIKE)
|
||||||
|
{
|
||||||
|
// Pop up spikes!
|
||||||
|
if (mthing->options & MTF_OBJECTSPECIAL)
|
||||||
|
{
|
||||||
|
mobj->flags &= ~MF_SCENERY;
|
||||||
|
mobj->fuse = mobj->info->speed;
|
||||||
|
}
|
||||||
|
// Use per-thing collision for spikes if the deaf flag isn't checked.
|
||||||
|
if (!(mthing->options & MTF_AMBUSH) && !metalrecording)
|
||||||
|
{
|
||||||
|
P_UnsetThingPosition(mobj);
|
||||||
|
mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT);
|
||||||
|
mobj->flags |= MF_SOLID;
|
||||||
|
P_SetThingPosition(mobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawn base
|
||||||
|
{
|
||||||
|
const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so...
|
||||||
|
const fixed_t baseradius = mobj->radius - mobj->scale;
|
||||||
|
mobj_t *base = P_SpawnMobj(
|
||||||
|
mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius),
|
||||||
|
mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius),
|
||||||
|
mobj->z, MT_WALLSPIKEBASE);
|
||||||
|
base->angle = mobjangle + ANGLE_90;
|
||||||
|
base->destscale = mobj->destscale;
|
||||||
|
P_SetScale(base, mobj->scale);
|
||||||
|
P_SetTarget(&base->target, mobj);
|
||||||
|
P_SetTarget(&mobj->tracer, base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//count 10 ring boxes into the number of rings equation too.
|
//count 10 ring boxes into the number of rings equation too.
|
||||||
if (i == MT_RING_BOX)
|
if (i == MT_RING_BOX)
|
||||||
|
@ -10181,7 +10519,6 @@ ML_NOCLIMB : Direction not controllable
|
||||||
// Spawn already displayed
|
// Spawn already displayed
|
||||||
mobj->flags |= MF_SPECIAL;
|
mobj->flags |= MF_SPECIAL;
|
||||||
mobj->flags &= ~MF_NIGHTSITEM;
|
mobj->flags &= ~MF_NIGHTSITEM;
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->flags & MF_PUSHABLE)
|
if (mobj->flags & MF_PUSHABLE)
|
||||||
|
@ -10234,6 +10571,10 @@ ML_NOCLIMB : Direction not controllable
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final set of not being able to draw nightsitems.
|
||||||
|
if (mobj->flags & MF_NIGHTSITEM)
|
||||||
|
mobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
|
||||||
mthing->mobj = mobj;
|
mthing->mobj = mobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11235,4 +11576,4 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
||||||
newmobj->destscale = mobj->destscale;
|
newmobj->destscale = mobj->destscale;
|
||||||
P_SetScale(newmobj, mobj->scale);
|
P_SetScale(newmobj, mobj->scale);
|
||||||
return newmobj;
|
return newmobj;
|
||||||
}
|
}
|
|
@ -194,6 +194,7 @@ typedef enum
|
||||||
MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH
|
MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH
|
||||||
MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position)
|
||||||
MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use)
|
||||||
|
MF2_MACEROTATE = 1<<30, // Thinker calls P_MaceRotate around tracer
|
||||||
// free: to and including 1<<31
|
// free: to and including 1<<31
|
||||||
} mobjflag2_t;
|
} mobjflag2_t;
|
||||||
|
|
||||||
|
|
|
@ -1237,7 +1237,7 @@ static void Polyobj_rotateLine(line_t *ld)
|
||||||
|
|
||||||
// determine slopetype
|
// determine slopetype
|
||||||
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL :
|
||||||
FixedDiv(ld->dy, ld->dx) > 0 ? ST_POSITIVE : ST_NEGATIVE;
|
((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE;
|
||||||
|
|
||||||
// update bounding box
|
// update bounding box
|
||||||
if (v1->x < v2->x)
|
if (v1->x < v2->x)
|
||||||
|
|
|
@ -3159,7 +3159,8 @@ static inline void P_ArchiveMisc(void)
|
||||||
else
|
else
|
||||||
WRITEINT16(save_p, gamemap);
|
WRITEINT16(save_p, gamemap);
|
||||||
|
|
||||||
lastmapsaved = gamemap;
|
//lastmapsaved = gamemap;
|
||||||
|
lastmaploaded = gamemap;
|
||||||
|
|
||||||
WRITEUINT16(save_p, (botskin ? (emeralds|(1<<10)) : emeralds)+357);
|
WRITEUINT16(save_p, (botskin ? (emeralds|(1<<10)) : emeralds)+357);
|
||||||
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
|
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
|
||||||
|
@ -3184,7 +3185,8 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
|
||||||
if(!mapheaderinfo[gamemap-1])
|
if(!mapheaderinfo[gamemap-1])
|
||||||
P_AllocMapHeader(gamemap-1);
|
P_AllocMapHeader(gamemap-1);
|
||||||
|
|
||||||
lastmapsaved = gamemap;
|
//lastmapsaved = gamemap;
|
||||||
|
lastmaploaded = gamemap;
|
||||||
|
|
||||||
tokenlist = 0;
|
tokenlist = 0;
|
||||||
token = 0;
|
token = 0;
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
|
#include "filesrch.h" // refreshdirmenu
|
||||||
|
|
||||||
// wipes
|
// wipes
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
|
||||||
|
@ -509,6 +511,7 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||||
//Hurdler: 04/12/2000: for now, only used in hardware mode
|
//Hurdler: 04/12/2000: for now, only used in hardware mode
|
||||||
li->lightmaps = NULL; // list of static lightmap for this seg
|
li->lightmaps = NULL; // list of static lightmap for this seg
|
||||||
}
|
}
|
||||||
|
li->pv1 = li->pv2 = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
li->angle = (SHORT(ml->angle))<<FRACBITS;
|
li->angle = (SHORT(ml->angle))<<FRACBITS;
|
||||||
|
@ -1150,7 +1153,20 @@ static inline void P_SpawnEmblems(void)
|
||||||
P_SetThingPosition(emblemmobj);
|
P_SetThingPosition(emblemmobj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
emblemmobj->frame &= ~FF_TRANSMASK;
|
emblemmobj->frame &= ~FF_TRANSMASK;
|
||||||
|
|
||||||
|
if (emblemlocations[i].type == ET_GLOBAL)
|
||||||
|
{
|
||||||
|
emblemmobj->reactiontime = emblemlocations[i].var;
|
||||||
|
if (emblemlocations[i].var & GE_NIGHTSITEM)
|
||||||
|
{
|
||||||
|
emblemmobj->flags |= MF_NIGHTSITEM;
|
||||||
|
emblemmobj->flags &= ~MF_SPECIAL;
|
||||||
|
emblemmobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,7 +1254,7 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i)
|
||||||
ld->slopetype = ST_VERTICAL;
|
ld->slopetype = ST_VERTICAL;
|
||||||
else if (!ld->dy)
|
else if (!ld->dy)
|
||||||
ld->slopetype = ST_HORIZONTAL;
|
ld->slopetype = ST_HORIZONTAL;
|
||||||
else if (FixedDiv(ld->dy, ld->dx) > 0)
|
else if ((ld->dy > 0) == (ld->dx > 0))
|
||||||
ld->slopetype = ST_POSITIVE;
|
ld->slopetype = ST_POSITIVE;
|
||||||
else
|
else
|
||||||
ld->slopetype = ST_NEGATIVE;
|
ld->slopetype = ST_NEGATIVE;
|
||||||
|
@ -1611,6 +1627,7 @@ static void P_LoadRawSideDefs2(void *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 9: // Mace parameters
|
||||||
case 14: // Bustable block parameters
|
case 14: // Bustable block parameters
|
||||||
case 15: // Fan particle spawner parameters
|
case 15: // Fan particle spawner parameters
|
||||||
case 425: // Calls P_SetMobjState on calling mobj
|
case 425: // Calls P_SetMobjState on calling mobj
|
||||||
|
@ -2574,6 +2591,21 @@ static void P_LoadNightsGhosts(void)
|
||||||
free(gpath);
|
free(gpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean CanSaveLevel(INT32 mapnum)
|
||||||
|
{
|
||||||
|
if (ultimatemode) // never save in ultimate (probably redundant with cursaveslot also being checked)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (G_IsSpecialStage(mapnum) // don't save in special stages
|
||||||
|
|| mapnum == lastmaploaded) // don't save if the last map loaded was this one
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Any levels that have the savegame flag can save normally.
|
||||||
|
// If the game is complete for this save slot, then any level can save!
|
||||||
|
// On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP!
|
||||||
|
return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || gamecomplete || !lastmaploaded);
|
||||||
|
}
|
||||||
|
|
||||||
/** Loads a level from a lump or external wad.
|
/** Loads a level from a lump or external wad.
|
||||||
*
|
*
|
||||||
* \param skipprecip If true, don't spawn precipitation.
|
* \param skipprecip If true, don't spawn precipitation.
|
||||||
|
@ -3073,11 +3105,11 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
P_RunCachedActions();
|
P_RunCachedActions();
|
||||||
|
|
||||||
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
|
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
|
||||||
&& (!modifiedgame || savemoddata) && cursaveslot >= 0 && !ultimatemode
|
&& (!modifiedgame || savemoddata) && cursaveslot >= 0 && CanSaveLevel(gamemap))
|
||||||
&& !(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
|
||||||
&& (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete))
|
|
||||||
G_SaveGame((UINT32)cursaveslot);
|
G_SaveGame((UINT32)cursaveslot);
|
||||||
|
|
||||||
|
lastmaploaded = gamemap; // HAS to be set after saving!!
|
||||||
|
|
||||||
if (savedata.lives > 0)
|
if (savedata.lives > 0)
|
||||||
{
|
{
|
||||||
players[consoleplayer].continues = savedata.continues;
|
players[consoleplayer].continues = savedata.continues;
|
||||||
|
@ -3203,6 +3235,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
// Init file.
|
// Init file.
|
||||||
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
|
||||||
{
|
{
|
||||||
|
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||||
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
11
src/p_spec.c
11
src/p_spec.c
|
@ -459,7 +459,8 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
||||||
|
|
||||||
// Search for existing animdef
|
// Search for existing animdef
|
||||||
for (i = 0; i < maxanims; i++)
|
for (i = 0; i < maxanims; i++)
|
||||||
if (stricmp(animdefsToken, animdefs[i].startname) == 0)
|
if (animdefs[i].istexture == istexture // Check if it's the same type!
|
||||||
|
&& stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||||
{
|
{
|
||||||
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
||||||
|
|
||||||
|
@ -1751,7 +1752,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
||||||
case 305: // continuous
|
case 305: // continuous
|
||||||
case 306: // each time
|
case 306: // each time
|
||||||
case 307: // once
|
case 307: // once
|
||||||
if (!(actor && actor->player && actor->player->charability != dist/10))
|
if (!(actor && actor->player && actor->player->charability == dist/10))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case 309: // continuous
|
case 309: // continuous
|
||||||
|
@ -5881,10 +5882,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
}
|
}
|
||||||
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
||||||
{
|
{
|
||||||
fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT);
|
xoffs = -lines[i].v1->x;
|
||||||
fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT);
|
yoffs = lines[i].v1->y;
|
||||||
xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations.
|
|
||||||
yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
|
|
37
src/p_user.c
37
src/p_user.c
|
@ -821,7 +821,10 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
|
||||||
|
|
||||||
if (inflictor)
|
if (inflictor)
|
||||||
{
|
{
|
||||||
ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy);
|
if (inflictor->type == MT_WALLSPIKE)
|
||||||
|
ang = inflictor->angle;
|
||||||
|
else
|
||||||
|
ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy);
|
||||||
|
|
||||||
// explosion and rail rings send you farther back, making it more difficult
|
// explosion and rail rings send you farther back, making it more difficult
|
||||||
// to recover
|
// to recover
|
||||||
|
@ -1267,11 +1270,12 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If the FOF is configured to let players through, continue.
|
// If the FOF is configured to let the object through, continue.
|
||||||
if (!(rover->flags & FF_BLOCKPLAYER) && (rover->flags & FF_BLOCKOTHERS))
|
if (!((rover->flags & FF_BLOCKPLAYER && mo->player)
|
||||||
|
|| (rover->flags & FF_BLOCKOTHERS && !mo->player)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If the the platform is intangile from below, continue.
|
// If the the platform is intangible from below, continue.
|
||||||
if (rover->flags & FF_PLATFORM)
|
if (rover->flags & FF_PLATFORM)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1300,11 +1304,12 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If the FOF is configured to let players through, continue.
|
// If the FOF is configured to let the object through, continue.
|
||||||
if (!(rover->flags & FF_BLOCKPLAYER) && (rover->flags & FF_BLOCKOTHERS))
|
if (!((rover->flags & FF_BLOCKPLAYER && mo->player)
|
||||||
|
|| (rover->flags & FF_BLOCKOTHERS && !mo->player)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If the the platform is intangile from above, continue.
|
// If the the platform is intangible from above, continue.
|
||||||
if (rover->flags & FF_REVERSEPLATFORM)
|
if (rover->flags & FF_REVERSEPLATFORM)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -9969,7 +9974,7 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->target)
|
else if (player->powers[pw_carry] == CR_MACESPIN && player->mo->tracer && player->mo->tracer->tracer)
|
||||||
{
|
{
|
||||||
player->mo->height = P_GetPlayerSpinHeight(player);
|
player->mo->height = P_GetPlayerSpinHeight(player);
|
||||||
// tracer is what you're hanging onto....
|
// tracer is what you're hanging onto....
|
||||||
|
@ -9985,14 +9990,20 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
player->pflags &= ~PF_THOKKED;
|
player->pflags &= ~PF_THOKKED;
|
||||||
|
|
||||||
if (cmd->forwardmove > 0)
|
if (cmd->forwardmove > 0)
|
||||||
player->mo->tracer->target->lastlook += 2;
|
{
|
||||||
else if (cmd->forwardmove < 0 && player->mo->tracer->target->lastlook > player->mo->tracer->target->movecount)
|
if ((player->mo->tracer->tracer->lastlook += 2) > player->mo->tracer->tracer->friction)
|
||||||
player->mo->tracer->target->lastlook -= 2;
|
player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->friction;
|
||||||
|
}
|
||||||
|
else if (cmd->forwardmove < 0)
|
||||||
|
{
|
||||||
|
if ((player->mo->tracer->tracer->lastlook -= 2) < player->mo->tracer->tracer->movecount)
|
||||||
|
player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->movecount;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
|
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?
|
&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
|
||||||
{
|
{
|
||||||
player->mo->tracer->target->health += cmd->sidemove;
|
player->mo->tracer->tracer->health += cmd->sidemove;
|
||||||
player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
|
player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
|
||||||
|
|
||||||
if (!demoplayback || P_AnalogMove(player))
|
if (!demoplayback || P_AnalogMove(player))
|
||||||
|
|
60
src/r_bsp.c
60
src/r_bsp.c
|
@ -365,6 +365,36 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
!line->polyseg &&
|
||||||
|
#endif
|
||||||
|
back->ceilingpic == front->ceilingpic
|
||||||
|
&& back->floorpic == front->floorpic
|
||||||
|
#ifdef ESLOPE
|
||||||
|
&& back->f_slope == front->f_slope
|
||||||
|
&& back->c_slope == front->c_slope
|
||||||
|
#endif
|
||||||
|
&& back->lightlevel == front->lightlevel
|
||||||
|
&& !line->sidedef->midtexture
|
||||||
|
// Check offsets too!
|
||||||
|
&& back->floor_xoffs == front->floor_xoffs
|
||||||
|
&& back->floor_yoffs == front->floor_yoffs
|
||||||
|
&& back->floorpic_angle == front->floorpic_angle
|
||||||
|
&& back->ceiling_xoffs == front->ceiling_xoffs
|
||||||
|
&& back->ceiling_yoffs == front->ceiling_yoffs
|
||||||
|
&& back->ceilingpic_angle == front->ceilingpic_angle
|
||||||
|
// Consider altered lighting.
|
||||||
|
&& back->floorlightsec == front->floorlightsec
|
||||||
|
&& back->ceilinglightsec == front->ceilinglightsec
|
||||||
|
// Consider colormaps
|
||||||
|
&& back->extra_colormap == front->extra_colormap
|
||||||
|
&& ((!front->ffloors && !back->ffloors)
|
||||||
|
|| front->tag == back->tag));
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_AddLine
|
// R_AddLine
|
||||||
// Clips the given segment and adds any visible pieces to the line list.
|
// Clips the given segment and adds any visible pieces to the line list.
|
||||||
|
@ -526,36 +556,8 @@ static void R_AddLine(seg_t *line)
|
||||||
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
// Identical floor and ceiling on both sides, identical light levels on both sides,
|
||||||
// and no middle texture.
|
// and no middle texture.
|
||||||
|
|
||||||
if (
|
if (R_IsEmptyLine(line, frontsector, backsector))
|
||||||
#ifdef POLYOBJECTS
|
|
||||||
!line->polyseg &&
|
|
||||||
#endif
|
|
||||||
backsector->ceilingpic == frontsector->ceilingpic
|
|
||||||
&& backsector->floorpic == frontsector->floorpic
|
|
||||||
#ifdef ESLOPE
|
|
||||||
&& backsector->f_slope == frontsector->f_slope
|
|
||||||
&& backsector->c_slope == frontsector->c_slope
|
|
||||||
#endif
|
|
||||||
&& backsector->lightlevel == frontsector->lightlevel
|
|
||||||
&& !curline->sidedef->midtexture
|
|
||||||
// Check offsets too!
|
|
||||||
&& backsector->floor_xoffs == frontsector->floor_xoffs
|
|
||||||
&& backsector->floor_yoffs == frontsector->floor_yoffs
|
|
||||||
&& backsector->floorpic_angle == frontsector->floorpic_angle
|
|
||||||
&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
|
|
||||||
&& backsector->ceiling_yoffs == frontsector->ceiling_yoffs
|
|
||||||
&& backsector->ceilingpic_angle == frontsector->ceilingpic_angle
|
|
||||||
// Consider altered lighting.
|
|
||||||
&& backsector->floorlightsec == frontsector->floorlightsec
|
|
||||||
&& backsector->ceilinglightsec == frontsector->ceilinglightsec
|
|
||||||
// Consider colormaps
|
|
||||||
&& backsector->extra_colormap == frontsector->extra_colormap
|
|
||||||
&& ((!frontsector->ffloors && !backsector->ffloors)
|
|
||||||
|| frontsector->tag == backsector->tag))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
clippass:
|
clippass:
|
||||||
R_ClipPassWallSegment(x1, x2 - 1);
|
R_ClipPassWallSegment(x1, x2 - 1);
|
||||||
|
|
|
@ -50,6 +50,7 @@ extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
|
||||||
|
|
||||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
INT32 *ceilinglightlevel, boolean back);
|
INT32 *ceilinglightlevel, boolean back);
|
||||||
|
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back);
|
||||||
|
|
||||||
INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
|
INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside);
|
||||||
void R_Prep3DFloors(sector_t *sector);
|
void R_Prep3DFloors(sector_t *sector);
|
||||||
|
|
|
@ -574,6 +574,9 @@ typedef struct seg_s
|
||||||
sector_t *backsector;
|
sector_t *backsector;
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
// new pointers so that AdjustSegs doesn't mess with v1/v2
|
||||||
|
void *pv1; // polyvertex_t
|
||||||
|
void *pv2; // polyvertex_t
|
||||||
float flength; // length of the seg, used by hardware renderer
|
float flength; // length of the seg, used by hardware renderer
|
||||||
|
|
||||||
lightmap_t *lightmaps; // for static lightmap
|
lightmap_t *lightmaps; // for static lightmap
|
||||||
|
|
|
@ -445,17 +445,18 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (slope); else // Don't mess with this right now if a slope is involved
|
if (slope); else // Don't mess with this right now if a slope is involved
|
||||||
#endif
|
#endif
|
||||||
if (plangle != 0)
|
|
||||||
{
|
|
||||||
// Add the view offset, rotated by the plane angle.
|
|
||||||
angle_t angle = plangle>>ANGLETOFINESHIFT;
|
|
||||||
xoff += FixedMul(viewx,FINECOSINE(angle))-FixedMul(viewy,FINESINE(angle));
|
|
||||||
yoff += -FixedMul(viewx,FINESINE(angle))-FixedMul(viewy,FINECOSINE(angle));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
xoff += viewx;
|
xoff += viewx;
|
||||||
yoff -= viewy;
|
yoff -= viewy;
|
||||||
|
if (plangle != 0)
|
||||||
|
{
|
||||||
|
// Add the view offset, rotated by the plane angle.
|
||||||
|
fixed_t cosinecomponent = FINECOSINE(plangle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t sinecomponent = FINESINE(plangle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t oldxoff = xoff;
|
||||||
|
xoff = FixedMul(xoff,cosinecomponent)+FixedMul(yoff,sinecomponent);
|
||||||
|
yoff = -FixedMul(oldxoff,sinecomponent)+FixedMul(yoff,cosinecomponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This appears to fix the Nimbus Ruins sky bug.
|
// This appears to fix the Nimbus Ruins sky bug.
|
||||||
|
@ -483,6 +484,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||||
&& !pfloor && !check->ffloor
|
&& !pfloor && !check->ffloor
|
||||||
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
|
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
|
||||||
&& check->viewangle == viewangle
|
&& check->viewangle == viewangle
|
||||||
|
&& check->plangle == plangle
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
&& check->slope == slope
|
&& check->slope == slope
|
||||||
#endif
|
#endif
|
||||||
|
@ -951,19 +953,57 @@ void R_DrawSinglePlane(visplane_t *pl)
|
||||||
floatv3_t p, m, n;
|
floatv3_t p, m, n;
|
||||||
float ang;
|
float ang;
|
||||||
float vx, vy, vz;
|
float vx, vy, vz;
|
||||||
float fudge;
|
|
||||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||||
// use this as a temp var to store P_GetZAt's return value each time
|
// use this as a temp var to store P_GetZAt's return value each time
|
||||||
fixed_t temp;
|
fixed_t temp;
|
||||||
|
|
||||||
xoffs &= ((1 << (32-nflatshiftup))-1);
|
|
||||||
yoffs &= ((1 << (32-nflatshiftup))-1);
|
|
||||||
|
|
||||||
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
|
||||||
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
|
||||||
|
|
||||||
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
|
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
|
||||||
fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
|
const float fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
|
||||||
|
|
||||||
|
angle_t hack = (pl->plangle & (ANGLE_90-1));
|
||||||
|
|
||||||
|
yoffs *= 1;
|
||||||
|
|
||||||
|
if (hack)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Essentially: We can't & the components along the regular axes when the plane is rotated.
|
||||||
|
This is because the distance on each regular axis in order to loop is different.
|
||||||
|
We rotate them, & the components, add them together, & them again, and then rotate them back.
|
||||||
|
These three seperate & operations are done per axis in order to prevent overflows.
|
||||||
|
toast 10/04/17
|
||||||
|
*/
|
||||||
|
const fixed_t cosinecomponent = FINECOSINE(hack>>ANGLETOFINESHIFT);
|
||||||
|
const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1);
|
||||||
|
|
||||||
|
fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask);
|
||||||
|
fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask);
|
||||||
|
|
||||||
|
temp = ox & modmask;
|
||||||
|
oy &= modmask;
|
||||||
|
ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction
|
||||||
|
oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent);
|
||||||
|
|
||||||
|
temp = xoffs;
|
||||||
|
xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask);
|
||||||
|
yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask);
|
||||||
|
|
||||||
|
temp = xoffs & modmask;
|
||||||
|
yoffs &= modmask;
|
||||||
|
xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto
|
||||||
|
yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent);
|
||||||
|
|
||||||
|
xoffs -= (pl->slope->o.x - ox);
|
||||||
|
yoffs += (pl->slope->o.y + oy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xoffs &= ((1 << (32-nflatshiftup))-1);
|
||||||
|
yoffs &= ((1 << (32-nflatshiftup))-1);
|
||||||
|
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
||||||
|
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
||||||
|
}
|
||||||
|
|
||||||
xoffs = (fixed_t)(xoffs*fudge);
|
xoffs = (fixed_t)(xoffs*fudge);
|
||||||
yoffs = (fixed_t)(yoffs/fudge);
|
yoffs = (fixed_t)(yoffs/fudge);
|
||||||
|
|
193
src/r_things.c
193
src/r_things.c
|
@ -858,7 +858,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
|
|
||||||
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
|
colfunc = basecolfunc; // hack: this isn't resetting properly somewhere.
|
||||||
dc_colormap = vis->colormap;
|
dc_colormap = vis->colormap;
|
||||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||||
{
|
{
|
||||||
// translate certain pixels to white
|
// translate certain pixels to white
|
||||||
colfunc = transcolfunc;
|
colfunc = transcolfunc;
|
||||||
|
@ -873,7 +873,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
{
|
{
|
||||||
colfunc = transtransfunc;
|
colfunc = transtransfunc;
|
||||||
dc_transmap = vis->transmap;
|
dc_transmap = vis->transmap;
|
||||||
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
|
||||||
{
|
{
|
||||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||||
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
||||||
|
@ -892,7 +892,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
colfunc = transcolfunc;
|
colfunc = transcolfunc;
|
||||||
|
|
||||||
// New colormap stuff for skins Tails 06-07-2002
|
// New colormap stuff for skins Tails 06-07-2002
|
||||||
if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
|
||||||
{
|
{
|
||||||
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
size_t skinnum = (skin_t*)vis->mobj->skin-skins;
|
||||||
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE);
|
||||||
|
@ -922,18 +922,18 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
frac = vis->startfrac;
|
frac = vis->startfrac;
|
||||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||||
|
|
||||||
if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
|
if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
|
||||||
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
|
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
|
||||||
if (this_scale <= 0)
|
if (this_scale <= 0)
|
||||||
this_scale = 1;
|
this_scale = 1;
|
||||||
if (this_scale != FRACUNIT)
|
if (this_scale != FRACUNIT)
|
||||||
{
|
{
|
||||||
if (!vis->isScaled)
|
if (!(vis->cut & SC_ISSCALED))
|
||||||
{
|
{
|
||||||
vis->scale = FixedMul(vis->scale, this_scale);
|
vis->scale = FixedMul(vis->scale, this_scale);
|
||||||
vis->scalestep = FixedMul(vis->scalestep, this_scale);
|
vis->scalestep = FixedMul(vis->scalestep, this_scale);
|
||||||
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
||||||
vis->isScaled = true;
|
vis->cut |= SC_ISSCALED;
|
||||||
}
|
}
|
||||||
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
||||||
}
|
}
|
||||||
|
@ -975,7 +975,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||||
}
|
}
|
||||||
if (vis->vflip)
|
if (vis->cut & SC_VFLIP)
|
||||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||||
else
|
else
|
||||||
R_DrawMaskedColumn(column);
|
R_DrawMaskedColumn(column);
|
||||||
|
@ -1054,7 +1054,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
||||||
//
|
//
|
||||||
// R_SplitSprite
|
// R_SplitSprite
|
||||||
// runs through a sector's lightlist and
|
// runs through a sector's lightlist and
|
||||||
static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
static void R_SplitSprite(vissprite_t *sprite)
|
||||||
{
|
{
|
||||||
INT32 i, lightnum, lindex;
|
INT32 i, lightnum, lindex;
|
||||||
INT16 cutfrac;
|
INT16 cutfrac;
|
||||||
|
@ -1090,6 +1090,8 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
||||||
// adjust the heights.
|
// adjust the heights.
|
||||||
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
|
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
|
||||||
|
|
||||||
|
newsprite->cut |= (sprite->cut & SC_FLAGMASK);
|
||||||
|
|
||||||
sprite->cut |= SC_BOTTOM;
|
sprite->cut |= SC_BOTTOM;
|
||||||
sprite->gz = testheight;
|
sprite->gz = testheight;
|
||||||
|
|
||||||
|
@ -1122,15 +1124,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
||||||
|
|
||||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||||
|
|
||||||
/*
|
if (!((newsprite->cut & SC_FULLBRIGHT) && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
|
||||||
if (thing->frame & FF_TRANSMASK)
|
|
||||||
;
|
|
||||||
else if (thing->flags2 & MF2_SHADOW)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW)
|
|
||||||
&& (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
|
|
||||||
{
|
{
|
||||||
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
||||||
|
|
||||||
|
@ -1150,6 +1144,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
||||||
//
|
//
|
||||||
static void R_ProjectSprite(mobj_t *thing)
|
static void R_ProjectSprite(mobj_t *thing)
|
||||||
{
|
{
|
||||||
|
mobj_t *oldthing = thing;
|
||||||
fixed_t tr_x, tr_y;
|
fixed_t tr_x, tr_y;
|
||||||
fixed_t gxt, gyt;
|
fixed_t gxt, gyt;
|
||||||
fixed_t tx, tz;
|
fixed_t tx, tz;
|
||||||
|
@ -1169,6 +1164,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
vissprite_t *vis;
|
vissprite_t *vis;
|
||||||
|
|
||||||
|
spritecut_e cut = SC_NONE;
|
||||||
|
|
||||||
angle_t ang = 0; // compiler complaints
|
angle_t ang = 0; // compiler complaints
|
||||||
fixed_t iscale;
|
fixed_t iscale;
|
||||||
fixed_t scalestep;
|
fixed_t scalestep;
|
||||||
|
@ -1367,24 +1364,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||||
{
|
{
|
||||||
fixed_t linkscale;
|
fixed_t linkscale;
|
||||||
#if 0 // support for chains of linkdraw - probably not network safe to modify mobjs during rendering
|
|
||||||
mobj_t *link, *link2;
|
|
||||||
|
|
||||||
for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer)
|
thing = thing->tracer;
|
||||||
link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ;
|
|
||||||
|
|
||||||
for (link2 = thing->tracer; (link2->tracer && (link2 != link)); link2 = link2->tracer)
|
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||||
link->flags2 |= MF2_LINKDRAW; // only needed for correction of the above
|
return;
|
||||||
|
|
||||||
if (link->flags2 & MF2_LINKDRAW)
|
tr_x = thing->x - viewx;
|
||||||
link->flags2 &= ~MF2_LINKDRAW; // let's try and make sure this doesn't happen again...
|
tr_y = thing->y - viewy;
|
||||||
|
|
||||||
tr_x = link->x - viewx;
|
|
||||||
tr_y = link->y - viewy;
|
|
||||||
#else
|
|
||||||
tr_x = thing->tracer->x - viewx;
|
|
||||||
tr_y = thing->tracer->y - viewy;
|
|
||||||
#endif
|
|
||||||
gxt = FixedMul(tr_x, viewcos);
|
gxt = FixedMul(tr_x, viewcos);
|
||||||
gyt = -FixedMul(tr_y, viewsin);
|
gyt = -FixedMul(tr_y, viewsin);
|
||||||
tz = gxt-gyt;
|
tz = gxt-gyt;
|
||||||
|
@ -1397,6 +1384,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
|
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
|
||||||
|
|
||||||
sortscale = linkscale; // now make sure it's linked
|
sortscale = linkscale; // now make sure it's linked
|
||||||
|
cut = SC_LINKDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PORTAL SPRITE CLIPPING
|
// PORTAL SPRITE CLIPPING
|
||||||
|
@ -1415,12 +1403,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||||
gz = thing->z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||||
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
|
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gzt = thing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||||
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
|
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1510,7 +1498,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->sector = thing->subsector->sector;
|
vis->sector = thing->subsector->sector;
|
||||||
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
|
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
|
||||||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
||||||
vis->cut = SC_NONE;
|
vis->cut = cut;
|
||||||
if (thing->subsector->sector->numlights)
|
if (thing->subsector->sector->numlights)
|
||||||
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
|
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
|
||||||
else
|
else
|
||||||
|
@ -1547,12 +1535,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
// specific translucency
|
// specific translucency
|
||||||
if (!cv_translucency.value)
|
if (!cv_translucency.value)
|
||||||
; // no translucency
|
; // no translucency
|
||||||
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
|
else if (oldthing->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
|
vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK
|
||||||
else if (thing->frame & FF_TRANSMASK)
|
else if (oldthing->frame & FF_TRANSMASK)
|
||||||
vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000;
|
vis->transmap = transtables + (oldthing->frame & FF_TRANSMASK) - 0x10000;
|
||||||
|
|
||||||
if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW))
|
if ((oldthing->frame & FF_FULLBRIGHT) || (oldthing->flags2 & MF2_SHADOW))
|
||||||
|
vis->cut |= SC_FULLBRIGHT;
|
||||||
|
|
||||||
|
if (vis->cut & SC_FULLBRIGHT
|
||||||
&& (!vis->extra_colormap || !vis->extra_colormap->fog))
|
&& (!vis->extra_colormap || !vis->extra_colormap->fog))
|
||||||
{
|
{
|
||||||
// full bright: goggles
|
// full bright: goggles
|
||||||
|
@ -1569,14 +1560,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->colormap = spritelights[lindex];
|
vis->colormap = spritelights[lindex];
|
||||||
}
|
}
|
||||||
|
|
||||||
vis->precip = false;
|
if (vflip)
|
||||||
|
vis->cut |= SC_VFLIP;
|
||||||
vis->vflip = vflip;
|
|
||||||
|
|
||||||
vis->isScaled = false;
|
|
||||||
|
|
||||||
if (thing->subsector->sector->numlights)
|
if (thing->subsector->sector->numlights)
|
||||||
R_SplitSprite(vis, thing);
|
R_SplitSprite(vis);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
++objectsdrawn;
|
++objectsdrawn;
|
||||||
|
@ -1600,7 +1588,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
fixed_t iscale;
|
fixed_t iscale;
|
||||||
|
|
||||||
//SoM: 3/17/2000
|
//SoM: 3/17/2000
|
||||||
fixed_t gz ,gzt;
|
fixed_t gz, gzt;
|
||||||
|
|
||||||
// transform the origin point
|
// transform the origin point
|
||||||
tr_x = thing->x - viewx;
|
tr_x = thing->x - viewx;
|
||||||
|
@ -1736,16 +1724,14 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
else
|
else
|
||||||
vis->transmap = NULL;
|
vis->transmap = NULL;
|
||||||
|
|
||||||
|
vis->mobj = (mobj_t *)thing;
|
||||||
vis->mobjflags = 0;
|
vis->mobjflags = 0;
|
||||||
vis->cut = SC_NONE;
|
vis->cut = SC_PRECIP;
|
||||||
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||||
vis->heightsec = thing->subsector->sector->heightsec;
|
vis->heightsec = thing->subsector->sector->heightsec;
|
||||||
|
|
||||||
// Fullbright
|
// Fullbright
|
||||||
vis->colormap = colormaps;
|
vis->colormap = colormaps;
|
||||||
vis->precip = true;
|
|
||||||
vis->vflip = false;
|
|
||||||
vis->isScaled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// R_AddSprites
|
// R_AddSprites
|
||||||
|
@ -1838,7 +1824,7 @@ static vissprite_t vsprsortedhead;
|
||||||
|
|
||||||
void R_SortVisSprites(void)
|
void R_SortVisSprites(void)
|
||||||
{
|
{
|
||||||
UINT32 i;
|
UINT32 i, linkedvissprites = 0;
|
||||||
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
||||||
vissprite_t *best = NULL;
|
vissprite_t *best = NULL;
|
||||||
vissprite_t unsorted;
|
vissprite_t unsorted;
|
||||||
|
@ -1862,22 +1848,91 @@ void R_SortVisSprites(void)
|
||||||
|
|
||||||
ds->next = dsnext;
|
ds->next = dsnext;
|
||||||
ds->prev = dsprev;
|
ds->prev = dsprev;
|
||||||
|
ds->linkdraw = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix first and last. ds still points to the last one after the loop
|
// Fix first and last. ds still points to the last one after the loop
|
||||||
dsfirst->prev = &unsorted;
|
dsfirst->prev = &unsorted;
|
||||||
unsorted.next = dsfirst;
|
unsorted.next = dsfirst;
|
||||||
if (ds)
|
if (ds)
|
||||||
|
{
|
||||||
ds->next = &unsorted;
|
ds->next = &unsorted;
|
||||||
|
ds->linkdraw = NULL;
|
||||||
|
}
|
||||||
unsorted.prev = ds;
|
unsorted.prev = ds;
|
||||||
|
|
||||||
|
// bundle linkdraw
|
||||||
|
for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev)
|
||||||
|
{
|
||||||
|
if (!(ds->cut & SC_LINKDRAW))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// reuse dsfirst...
|
||||||
|
for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev)
|
||||||
|
{
|
||||||
|
// don't connect if it's also a link
|
||||||
|
if (dsfirst->cut & SC_LINKDRAW)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// don't connect if it's not the tracer
|
||||||
|
if (dsfirst->mobj != ds->mobj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// don't connect if the tracer's top is cut off, but lower than the link's top
|
||||||
|
if ((dsfirst->cut & SC_TOP)
|
||||||
|
&& dsfirst->szt > ds->szt)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// don't connect if the tracer's bottom is cut off, but higher than the link's bottom
|
||||||
|
if ((dsfirst->cut & SC_BOTTOM)
|
||||||
|
&& dsfirst->sz < ds->sz)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove from chain
|
||||||
|
ds->next->prev = ds->prev;
|
||||||
|
ds->prev->next = ds->next;
|
||||||
|
linkedvissprites++;
|
||||||
|
|
||||||
|
if (dsfirst != &unsorted)
|
||||||
|
{
|
||||||
|
if (!(ds->cut & SC_FULLBRIGHT))
|
||||||
|
ds->colormap = dsfirst->colormap;
|
||||||
|
ds->extra_colormap = dsfirst->extra_colormap;
|
||||||
|
|
||||||
|
// reusing dsnext...
|
||||||
|
dsnext = dsfirst->linkdraw;
|
||||||
|
|
||||||
|
if (!dsnext || ds->dispoffset < dsnext->dispoffset)
|
||||||
|
{
|
||||||
|
ds->next = dsnext;
|
||||||
|
dsfirst->linkdraw = ds;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; dsnext->next != NULL; dsnext = dsnext->next)
|
||||||
|
if (ds->dispoffset < dsnext->next->dispoffset)
|
||||||
|
break;
|
||||||
|
ds->next = dsnext->next;
|
||||||
|
dsnext->next = ds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pull the vissprites out by scale
|
// pull the vissprites out by scale
|
||||||
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
|
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
|
||||||
for (i = 0; i < visspritecount; i++)
|
for (i = 0; i < visspritecount-linkedvissprites; i++)
|
||||||
{
|
{
|
||||||
bestscale = bestdispoffset = INT32_MAX;
|
bestscale = bestdispoffset = INT32_MAX;
|
||||||
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
||||||
{
|
{
|
||||||
|
#ifdef PARANOIA
|
||||||
|
if (ds->cut & SC_LINKDRAW)
|
||||||
|
I_Error("R_SortVisSprites: no link or discardal made for linkdraw!");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ds->sortscale < bestscale)
|
if (ds->sortscale < bestscale)
|
||||||
{
|
{
|
||||||
bestscale = ds->sortscale;
|
bestscale = ds->sortscale;
|
||||||
|
@ -2131,20 +2186,6 @@ static void R_CreateDrawNodes(void)
|
||||||
}
|
}
|
||||||
else if (r2->seg)
|
else if (r2->seg)
|
||||||
{
|
{
|
||||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
|
||||||
if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) {
|
|
||||||
// Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where
|
|
||||||
// polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red
|
|
||||||
mobj_t *mo = rover->mobj;
|
|
||||||
sector_t *po = r2->seg->curline->backsector;
|
|
||||||
|
|
||||||
if (po->ceilingheight < viewz && mo->z+mo->height > po->ceilingheight)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (po->floorheight > viewz && mo->z < po->floorheight)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1)
|
if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2271,7 +2312,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
|
||||||
void R_ClipSprites(void)
|
void R_ClipSprites(void)
|
||||||
{
|
{
|
||||||
vissprite_t *spr;
|
vissprite_t *spr;
|
||||||
for (;clippedvissprites < visspritecount; clippedvissprites++)
|
for (; clippedvissprites < visspritecount; clippedvissprites++)
|
||||||
{
|
{
|
||||||
drawseg_t *ds;
|
drawseg_t *ds;
|
||||||
INT32 x;
|
INT32 x;
|
||||||
|
@ -2492,10 +2533,24 @@ void R_DrawMasked(void)
|
||||||
next = r2->prev;
|
next = r2->prev;
|
||||||
|
|
||||||
// Tails 08-18-2002
|
// Tails 08-18-2002
|
||||||
if (r2->sprite->precip == true)
|
if (r2->sprite->cut & SC_PRECIP)
|
||||||
R_DrawPrecipitationSprite(r2->sprite);
|
R_DrawPrecipitationSprite(r2->sprite);
|
||||||
else
|
else if (!r2->sprite->linkdraw)
|
||||||
R_DrawSprite(r2->sprite);
|
R_DrawSprite(r2->sprite);
|
||||||
|
else // unbundle linkdraw
|
||||||
|
{
|
||||||
|
vissprite_t *ds = r2->sprite->linkdraw;
|
||||||
|
|
||||||
|
for (;
|
||||||
|
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
||||||
|
ds = ds->next)
|
||||||
|
R_DrawSprite(ds);
|
||||||
|
|
||||||
|
R_DrawSprite(r2->sprite);
|
||||||
|
|
||||||
|
for (; ds != NULL; ds = ds->next)
|
||||||
|
R_DrawSprite(ds);
|
||||||
|
}
|
||||||
|
|
||||||
R_DoneWithNode(r2);
|
R_DoneWithNode(r2);
|
||||||
r2 = next;
|
r2 = next;
|
||||||
|
|
|
@ -129,9 +129,19 @@ typedef struct
|
||||||
// -----------
|
// -----------
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
// actual cuts
|
||||||
SC_NONE = 0,
|
SC_NONE = 0,
|
||||||
SC_TOP = 1,
|
SC_TOP = 1,
|
||||||
SC_BOTTOM = 2
|
SC_BOTTOM = 1<<1,
|
||||||
|
// other flags
|
||||||
|
SC_PRECIP = 1<<2,
|
||||||
|
SC_LINKDRAW = 1<<3,
|
||||||
|
SC_FULLBRIGHT = 1<<4,
|
||||||
|
SC_VFLIP = 1<<5,
|
||||||
|
SC_ISSCALED = 1>>6,
|
||||||
|
// masks
|
||||||
|
SC_CUTMASK = SC_TOP|SC_BOTTOM,
|
||||||
|
SC_FLAGMASK = ~SC_CUTMASK
|
||||||
} spritecut_e;
|
} spritecut_e;
|
||||||
|
|
||||||
// A vissprite_t is a thing that will be drawn during a refresh,
|
// A vissprite_t is a thing that will be drawn during a refresh,
|
||||||
|
@ -142,6 +152,9 @@ typedef struct vissprite_s
|
||||||
struct vissprite_s *prev;
|
struct vissprite_s *prev;
|
||||||
struct vissprite_s *next;
|
struct vissprite_s *next;
|
||||||
|
|
||||||
|
// Bonus linkdraw pointer.
|
||||||
|
struct vissprite_s *linkdraw;
|
||||||
|
|
||||||
mobj_t *mobj; // for easy access
|
mobj_t *mobj; // for easy access
|
||||||
|
|
||||||
INT32 x1, x2;
|
INT32 x1, x2;
|
||||||
|
@ -180,9 +193,6 @@ typedef struct vissprite_s
|
||||||
|
|
||||||
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
||||||
|
|
||||||
boolean precip;
|
|
||||||
boolean vflip; // Flip vertically
|
|
||||||
boolean isScaled;
|
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
} vissprite_t;
|
} vissprite_t;
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ static INT32 windowedModes[MAXWINMODES][2] =
|
||||||
static void Impl_VideoSetupSDLBuffer(void);
|
static void Impl_VideoSetupSDLBuffer(void);
|
||||||
static void Impl_VideoSetupBuffer(void);
|
static void Impl_VideoSetupBuffer(void);
|
||||||
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
||||||
static void Impl_SetWindowName(const char *title);
|
//static void Impl_SetWindowName(const char *title);
|
||||||
static void Impl_SetWindowIcon(void);
|
static void Impl_SetWindowIcon(void);
|
||||||
|
|
||||||
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||||
|
@ -1188,7 +1188,7 @@ INT32 VID_SetMode(INT32 modeNum)
|
||||||
}
|
}
|
||||||
vid.modenum = -1;
|
vid.modenum = -1;
|
||||||
}
|
}
|
||||||
Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||||
|
|
||||||
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
||||||
|
|
||||||
|
@ -1271,14 +1271,16 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void Impl_SetWindowName(const char *title)
|
static void Impl_SetWindowName(const char *title)
|
||||||
{
|
{
|
||||||
if (window != NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_SetWindowTitle(window, title);
|
SDL_SetWindowTitle(window, title);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static void Impl_SetWindowIcon(void)
|
static void Impl_SetWindowIcon(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -865,11 +865,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
||||||
//
|
//
|
||||||
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
||||||
{
|
{
|
||||||
if (skins[skinnum].flags & SF_HIRES
|
if (skins[skinnum].flags & SF_HIRES)
|
||||||
#ifdef HWRENDER
|
|
||||||
// || (rendermode != render_soft && rendermode != render_none)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
39
src/w_wad.c
39
src/w_wad.c
|
@ -37,6 +37,8 @@
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "i_video.h" // rendermode
|
#include "i_video.h" // rendermode
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
|
@ -312,12 +314,12 @@ UINT16 W_InitFile(const char *filename)
|
||||||
UINT16 numlumps;
|
UINT16 numlumps;
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 compressed = 0;
|
INT32 compressed = 0;
|
||||||
size_t packetsize = 0;
|
size_t packetsize;
|
||||||
serverinfo_pak *dummycheck = NULL;
|
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important;
|
||||||
|
|
||||||
// Shut the compiler up.
|
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
|
||||||
(void)dummycheck;
|
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
|
||||||
|
|
||||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
||||||
//
|
//
|
||||||
|
@ -326,6 +328,7 @@ UINT16 W_InitFile(const char *filename)
|
||||||
if (numwadfiles >= MAX_WADFILES)
|
if (numwadfiles >= MAX_WADFILES)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,21 +338,23 @@ UINT16 W_InitFile(const char *filename)
|
||||||
|
|
||||||
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
||||||
// is send in the packet; cf.
|
// is send in the packet; cf.
|
||||||
for (i = 0; i < numwadfiles; i++)
|
// see PutFileNeeded in d_netfil.c
|
||||||
|
if ((important = !W_VerifyNMUSlumps(filename)))
|
||||||
{
|
{
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename);
|
packetsize = packetsizetally;
|
||||||
packetsize += 22; // MD5, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
packetsize += nameonlylength(filename);
|
packetsize += nameonlylength(filename) + 22;
|
||||||
packetsize += 22;
|
|
||||||
|
|
||||||
if (packetsize > sizeof(dummycheck->fileneeded))
|
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
if (handle)
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
fclose(handle);
|
if (handle)
|
||||||
return INT16_MAX;
|
fclose(handle);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetsizetally = packetsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOMD5
|
#ifndef NOMD5
|
||||||
|
@ -694,6 +699,7 @@ UINT16 W_InitFile(const char *filename)
|
||||||
wadfile->handle = handle;
|
wadfile->handle = handle;
|
||||||
wadfile->numlumps = (UINT16)numlumps;
|
wadfile->numlumps = (UINT16)numlumps;
|
||||||
wadfile->lumpinfo = lumpinfo;
|
wadfile->lumpinfo = lumpinfo;
|
||||||
|
wadfile->important = important;
|
||||||
fseek(handle, 0, SEEK_END);
|
fseek(handle, 0, SEEK_END);
|
||||||
wadfile->filesize = (unsigned)ftell(handle);
|
wadfile->filesize = (unsigned)ftell(handle);
|
||||||
|
|
||||||
|
@ -1600,6 +1606,7 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||||
{"TNYFN", 5}, // Tiny console font changes
|
{"TNYFN", 5}, // Tiny console font changes
|
||||||
{"STT", 3}, // Acceptable HUD changes (Score Time Rings)
|
{"STT", 3}, // Acceptable HUD changes (Score Time Rings)
|
||||||
{"YB_", 3}, // Intermission graphics, goes with the above
|
{"YB_", 3}, // Intermission graphics, goes with the above
|
||||||
|
{"M_", 2}, // As does menu stuff
|
||||||
|
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,6 +87,7 @@ typedef struct wadfile_s
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
UINT32 filesize; // for network
|
UINT32 filesize; // for network
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important; // also network - !W_VerifyNMUSlumps
|
||||||
} wadfile_t;
|
} wadfile_t;
|
||||||
|
|
||||||
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
||||||
|
|
|
@ -160,6 +160,20 @@ static void Y_CalculateMatchWinners(void);
|
||||||
static void Y_FollowIntermission(void);
|
static void Y_FollowIntermission(void);
|
||||||
static void Y_UnloadData(void);
|
static void Y_UnloadData(void);
|
||||||
|
|
||||||
|
// Stuff copy+pasted from st_stuff.c
|
||||||
|
static INT32 SCX(INT32 x)
|
||||||
|
{
|
||||||
|
return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx));
|
||||||
|
}
|
||||||
|
static INT32 SCY(INT32 z)
|
||||||
|
{
|
||||||
|
return FixedInt(FixedMul(z<<FRACBITS, vid.fdupy));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n)
|
||||||
|
#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n, q)
|
||||||
|
#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, p)
|
||||||
|
|
||||||
static void Y_IntermissionTokenDrawer(void)
|
static void Y_IntermissionTokenDrawer(void)
|
||||||
{
|
{
|
||||||
INT32 y;
|
INT32 y;
|
||||||
|
@ -242,28 +256,31 @@ void Y_IntermissionDrawer(void)
|
||||||
Y_IntermissionTokenDrawer();
|
Y_IntermissionTokenDrawer();
|
||||||
|
|
||||||
// draw score
|
// draw score
|
||||||
V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore);
|
ST_DrawPatchFromHud(HUD_SCORE, sboscore);
|
||||||
V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score);
|
ST_DrawNumFromHud(HUD_SCORENUM, data.coop.score);
|
||||||
|
|
||||||
// draw time
|
// draw time
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIME].x, hudinfo[HUD_TIME].y, V_SNAPTOLEFT, sbotime);
|
ST_DrawPatchFromHud(HUD_TIME, sbotime);
|
||||||
if (cv_timetic.value == 1)
|
if (cv_timetic.value == 1)
|
||||||
V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, data.coop.tics);
|
ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
INT32 seconds, minutes, tictrn;
|
||||||
|
|
||||||
|
seconds = G_TicsToSeconds(data.coop.tics);
|
||||||
|
minutes = G_TicsToMinutes(data.coop.tics, true);
|
||||||
|
tictrn = G_TicsToCentiseconds(data.coop.tics);
|
||||||
|
|
||||||
|
ST_DrawNumFromHud(HUD_MINUTES, minutes); // Minutes
|
||||||
|
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon
|
||||||
|
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds
|
||||||
|
|
||||||
// we should show centiseconds on the intermission screen too, if the conditions are right.
|
// we should show centiseconds on the intermission screen too, if the conditions are right.
|
||||||
if (modeattacking || cv_timetic.value == 2)
|
if (modeattacking || cv_timetic.value == 2)
|
||||||
{
|
{
|
||||||
V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT,
|
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
|
||||||
G_TicsToCentiseconds(data.coop.tics), 2);
|
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawPaddedTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT,
|
|
||||||
G_TicsToSeconds(data.coop.tics), 2);
|
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, V_SNAPTOLEFT, sbocolon);
|
|
||||||
V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, V_SNAPTOLEFT,
|
|
||||||
G_TicsToMinutes(data.coop.tics, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the "got through act" lines and act number
|
// draw the "got through act" lines and act number
|
||||||
|
|
Loading…
Reference in New Issue