mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 04:51:19 +00:00
Merge commit 'b0eb19b'
This commit is contained in:
commit
7a5df2bc28
47 changed files with 375 additions and 531 deletions
|
@ -92,6 +92,8 @@ conversation // Starts a dialog.
|
|||
|
||||
choice
|
||||
{
|
||||
specialname = <string>; // Allows specifying a special by name.
|
||||
|
||||
// The amount of an item needed for this option to become available.
|
||||
// You can have as many as needed. All require blocks must be satisfied
|
||||
// to show this option.
|
||||
|
|
|
@ -397,22 +397,6 @@ if (NOT ZDOOM_USE_SSE2)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if( SSE_MATTERS )
|
||||
if( WIN32 )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else()
|
||||
CHECK_FUNCTION_EXISTS(mprotect HAVE_MPROTECT)
|
||||
if( HAVE_MPROTECT )
|
||||
set( BACKPATCH 1 CACHE BOOL "Enable backpatching." )
|
||||
else()
|
||||
set( BACKPATCH 0 )
|
||||
endif()
|
||||
endif()
|
||||
set( SSE 1 CACHE BOOL "Build SSE and SSE2 versions of key code." )
|
||||
else()
|
||||
set( BACKPATCH 0 )
|
||||
endif()
|
||||
|
||||
if( X64 )
|
||||
set( HAVE_MMX 1 )
|
||||
else( X64 )
|
||||
|
@ -577,10 +561,6 @@ endif()
|
|||
|
||||
# Flags
|
||||
|
||||
if( BACKPATCH )
|
||||
add_definitions( -DBACKPATCH )
|
||||
endif()
|
||||
|
||||
# Update gitinfo.h
|
||||
|
||||
add_custom_target( revision_check ALL
|
||||
|
@ -727,18 +707,6 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h
|
|||
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
if( SSE_MATTERS )
|
||||
if( SSE )
|
||||
set( X86_SOURCES nodebuild_classify_sse2.cpp )
|
||||
set_source_files_properties( nodebuild_classify_sse2.cpp PROPERTIES COMPILE_FLAGS "${SSE2_ENABLE}" )
|
||||
else()
|
||||
add_definitions( -DDISABLE_SSE )
|
||||
endif()
|
||||
else()
|
||||
add_definitions( -DDISABLE_SSE )
|
||||
set( X86_SOURCES )
|
||||
endif()
|
||||
|
||||
if( SNDFILE_FOUND )
|
||||
add_definitions( -DHAVE_SNDFILE )
|
||||
endif()
|
||||
|
|
|
@ -15,7 +15,7 @@ DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5)
|
|||
DEFINE_SPECIAL(Door_Animated, 14, 4, 4, 4)
|
||||
DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now*
|
||||
DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2)
|
||||
DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Thing_Raise, 17, 1, 2, 2)
|
||||
DEFINE_SPECIAL(StartConversation, 18, 1, 2, 2)
|
||||
DEFINE_SPECIAL(Thing_Stop, 19, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Floor_LowerByValue, 20, 3, 4, 4)
|
||||
|
|
|
@ -389,6 +389,7 @@ enum ActorFlag7
|
|||
MF7_NOSHIELDREFLECT = 0x08000000, // will not be reflected by shields.
|
||||
MF7_FORCEZERORADIUSDMG = 0x10000000, // passes zero radius damage on to P_DamageMobj, this is necessary in some cases where DoSpecialDamage gets overrideen.
|
||||
MF7_NOINFIGHTSPECIES = 0x20000000, // don't start infights with one's own species.
|
||||
MF7_FORCEINFIGHTING = 0x40000000, // overrides a map setting of 'no infighting'.
|
||||
};
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
|
|
@ -90,7 +90,7 @@ CVAR (Bool, am_customcolors, true, CVAR_ARCHIVE);
|
|||
CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_drawmapback, 1, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE);
|
||||
CVAR (Bool, am_showtriggerlines, false, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_showtriggerlines, 0, CVAR_ARCHIVE);
|
||||
CVAR (Int, am_showthingsprites, 0, CVAR_ARCHIVE);
|
||||
|
||||
//=============================================================================
|
||||
|
@ -2281,34 +2281,32 @@ bool AM_checkSpecialBoundary (line_t &line, bool (*function)(int, int *), int *s
|
|||
return (line.backsector && AM_checkSectorActions(line.backsector, function, specialptr, argsptr, false));
|
||||
}
|
||||
|
||||
bool AM_isTeleportSpecial (int special, int *)
|
||||
bool AM_isTeleportBoundary (line_t &line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, [](int special, int *)
|
||||
{
|
||||
return (special == Teleport ||
|
||||
special == Teleport_NoFog ||
|
||||
special == Teleport_ZombieChanger ||
|
||||
special == Teleport_Line);
|
||||
}
|
||||
|
||||
bool AM_isTeleportBoundary (line_t &line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isTeleportSpecial);
|
||||
}
|
||||
|
||||
bool AM_isExitSpecial (int special, int *)
|
||||
{
|
||||
return (special == Teleport_NewMap ||
|
||||
special == Teleport_EndGame ||
|
||||
special == Exit_Normal ||
|
||||
special == Exit_Secret);
|
||||
});
|
||||
}
|
||||
|
||||
bool AM_isExitBoundary (line_t& line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isExitSpecial);
|
||||
return AM_checkSpecialBoundary(line, [](int special, int *)
|
||||
{
|
||||
return (special == Teleport_NewMap ||
|
||||
special == Teleport_EndGame ||
|
||||
special == Exit_Normal ||
|
||||
special == Exit_Secret);
|
||||
});
|
||||
}
|
||||
|
||||
bool AM_isTriggerSpecial (int special, int *)
|
||||
bool AM_isTriggerBoundary (line_t &line)
|
||||
{
|
||||
return am_showtriggerlines == 1? AM_checkSpecialBoundary(line, [](int special, int *)
|
||||
{
|
||||
FLineSpecial *spec = P_GetLineSpecialInfo(special);
|
||||
return spec != NULL
|
||||
&& spec->max_args >= 0
|
||||
|
@ -2318,21 +2316,12 @@ bool AM_isTriggerSpecial (int special, int *)
|
|||
&& special != Door_Raise
|
||||
&& special != Door_Animated
|
||||
&& special != Generic_Door;
|
||||
}
|
||||
|
||||
bool AM_isTriggerBoundary (line_t &line)
|
||||
{
|
||||
return AM_checkSpecialBoundary(line, &AM_isTriggerSpecial);
|
||||
}
|
||||
|
||||
bool AM_isLockSpecial (int special, int* args)
|
||||
{
|
||||
return special == Door_LockedRaise
|
||||
|| special == ACS_LockedExecute
|
||||
|| special == ACS_LockedExecuteDoor
|
||||
|| (special == Door_Animated && args[3] != 0)
|
||||
|| (special == Generic_Door && args[4] != 0)
|
||||
|| (special == FS_Execute && args[2] != 0);
|
||||
}) : AM_checkSpecialBoundary(line, [](int special, int *)
|
||||
{
|
||||
FLineSpecial *spec = P_GetLineSpecialInfo(special);
|
||||
return spec != NULL
|
||||
&& spec->max_args >= 0;
|
||||
});
|
||||
}
|
||||
|
||||
bool AM_isLockBoundary (line_t &line, int *lockptr = NULL)
|
||||
|
@ -2351,7 +2340,15 @@ bool AM_isLockBoundary (line_t &line, int *lockptr = NULL)
|
|||
|
||||
int special;
|
||||
int *args;
|
||||
bool result = AM_checkSpecialBoundary(line, &AM_isLockSpecial, &special, &args);
|
||||
bool result = AM_checkSpecialBoundary(line, [](int special, int* args)
|
||||
{
|
||||
return special == Door_LockedRaise
|
||||
|| special == ACS_LockedExecute
|
||||
|| special == ACS_LockedExecuteDoor
|
||||
|| (special == Door_Animated && args[3] != 0)
|
||||
|| (special == Generic_Door && args[4] != 0)
|
||||
|| (special == FS_Execute && args[2] != 0);
|
||||
}, &special, &args);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
|
|
@ -937,28 +937,37 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha
|
|||
AActor *mo;
|
||||
const PClass *FilterClass = NULL;
|
||||
int counter = 0;
|
||||
int tid = 0;
|
||||
|
||||
if (FilterName != NULL)
|
||||
{
|
||||
FilterClass = PClass::FindActor(FilterName);
|
||||
if (FilterClass == NULL)
|
||||
{
|
||||
char *endp;
|
||||
tid = (int)strtol(FilterName, &endp, 10);
|
||||
if (*endp != 0)
|
||||
{
|
||||
Printf("%s is not an actor class.\n", FilterName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
TThinkerIterator<AActor> it;
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo))
|
||||
{
|
||||
if (tid == 0 || tid == mo->tid)
|
||||
{
|
||||
counter++;
|
||||
if (!countOnly)
|
||||
Printf ("%s at (%f,%f,%f)\n",
|
||||
Printf("%s at (%f,%f,%f)\n",
|
||||
mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z());
|
||||
}
|
||||
}
|
||||
}
|
||||
Printf("%i match(s) found.\n", counter);
|
||||
}
|
||||
|
||||
|
|
|
@ -2376,25 +2376,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
break;
|
||||
|
||||
case DEM_SPRAY:
|
||||
{
|
||||
FTraceResults trace;
|
||||
|
||||
DAngle ang = players[player].mo->Angles.Yaw;
|
||||
DAngle pitch = players[player].mo->Angles.Pitch;
|
||||
double c = pitch.Cos();
|
||||
DVector3 vec(c * ang.Cos(), c * ang.Sin(), -pitch.Sin());
|
||||
|
||||
s = ReadString (stream);
|
||||
|
||||
if (Trace (players[player].mo->PosPlusZ(players[player].mo->Height/2), players[player].mo->Sector,
|
||||
vec, 172., 0, ML_BLOCKEVERYTHING, players[player].mo, trace, TRACE_NoSky))
|
||||
{
|
||||
if (trace.HitType == TRACE_HitWall)
|
||||
{
|
||||
DImpactDecal::StaticCreate (s, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
s = ReadString(stream);
|
||||
SprayDecal(players[player].mo, s);
|
||||
break;
|
||||
|
||||
case DEM_PAUSE:
|
||||
|
|
|
@ -209,13 +209,7 @@ typedef enum
|
|||
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
|
||||
CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted
|
||||
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
|
||||
CF_DRAIN = 1 << 16, // Player owns a drain powerup
|
||||
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
|
||||
CF_REFLECTION = 1 << 19,
|
||||
CF_PROSPERITY = 1 << 20,
|
||||
CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact
|
||||
CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.
|
||||
CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact
|
||||
CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either.
|
||||
CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either.
|
||||
CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die
|
||||
|
|
|
@ -449,7 +449,13 @@ DEFINE_EVENT_LOOPER(WorldLightning)
|
|||
DEFINE_EVENT_LOOPER(WorldTick)
|
||||
|
||||
// declarations
|
||||
IMPLEMENT_CLASS(DStaticEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DStaticEventHandler, false, true);
|
||||
|
||||
IMPLEMENT_POINTERS_START(DStaticEventHandler)
|
||||
IMPLEMENT_POINTER(next)
|
||||
IMPLEMENT_POINTER(prev)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
IMPLEMENT_CLASS(DEventHandler, false, false);
|
||||
IMPLEMENT_CLASS(DBaseEvent, false, false)
|
||||
IMPLEMENT_CLASS(DRenderEvent, false, false)
|
||||
|
|
|
@ -76,7 +76,7 @@ void E_SerializeEvents(FSerializer& arc);
|
|||
|
||||
class DStaticEventHandler : public DObject // make it a part of normal GC process
|
||||
{
|
||||
DECLARE_CLASS(DStaticEventHandler, DObject)
|
||||
DECLARE_CLASS(DStaticEventHandler, DObject);
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DStaticEventHandler()
|
||||
|
|
|
@ -1343,12 +1343,24 @@ void G_PlayerFinishLevel (int player, EFinishLevelType mode, int flags)
|
|||
|
||||
if (mode == FINISH_NoHub && !(level.flags2 & LEVEL2_KEEPFULLINVENTORY))
|
||||
{ // Reduce all owned (visible) inventory to defined maximum interhub amount
|
||||
TArray<AInventory*> todelete;
|
||||
for (item = p->mo->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
// If the player is carrying more samples of an item than allowed, reduce amount accordingly
|
||||
if (item->ItemFlags & IF_INVBAR && item->Amount > item->InterHubAmount)
|
||||
{
|
||||
item->Amount = item->InterHubAmount;
|
||||
if ((level.flags3 & LEVEL3_RESETINVENTORY) && !(item->ItemFlags & IF_UNDROPPABLE))
|
||||
{
|
||||
todelete.Push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it : todelete)
|
||||
{
|
||||
if (!(it->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
it->DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ enum ELevelFlags : unsigned int
|
|||
|
||||
// More flags!
|
||||
LEVEL3_FORCEFAKECONTRAST = 0x00000001, // forces fake contrast even with fog enabled
|
||||
LEVEL3_RESETINVENTORY = 0x00000002, // kills all INVBAR items on map change.
|
||||
};
|
||||
|
||||
|
||||
|
@ -324,6 +325,7 @@ struct level_info_t
|
|||
FString ExitPic;
|
||||
FString InterMusic;
|
||||
int intermusicorder;
|
||||
TMap <FName, std::pair<FString, int> > MapInterMusic;
|
||||
|
||||
FString SoundInfo;
|
||||
FString SndSeq;
|
||||
|
|
|
@ -915,6 +915,18 @@ DEFINE_MAP_OPTION(intermusic, true)
|
|||
parse.ParseMusic(info->InterMusic, info->intermusicorder);
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(mapintermusic, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
FString mapname = parse.sc.String;
|
||||
FString music;
|
||||
int order;
|
||||
parse.ParseComma();
|
||||
parse.ParseMusic(music, order);
|
||||
info->MapInterMusic[FName(mapname)] = std::make_pair(music, order);
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(fadetable, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
@ -1265,6 +1277,7 @@ MapFlagHandlers[] =
|
|||
{ "laxmonsteractivation", MITYPE_SETFLAG2, LEVEL2_LAXMONSTERACTIVATION, LEVEL2_LAXACTIVATIONMAPINFO },
|
||||
{ "additive_scrollers", MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL, 0 },
|
||||
{ "keepfullinventory", MITYPE_SETFLAG2, LEVEL2_KEEPFULLINVENTORY, 0 },
|
||||
{ "resetitems", MITYPE_SETFLAG3, LEVEL2_RESETINVENTORY, 0 },
|
||||
{ "monsterfallingdamage", MITYPE_SETFLAG2, LEVEL2_MONSTERFALLINGDAMAGE, 0 },
|
||||
{ "nomonsterfallingdamage", MITYPE_CLRFLAG2, LEVEL2_MONSTERFALLINGDAMAGE, 0 },
|
||||
{ "clipmidtextures", MITYPE_SETFLAG2, LEVEL2_CLIPMIDTEX, 0 },
|
||||
|
|
|
@ -704,6 +704,24 @@ CCMD (spray)
|
|||
Net_WriteString (argv[1]);
|
||||
}
|
||||
|
||||
void SprayDecal(AActor *shooter, const char *name)
|
||||
{
|
||||
FTraceResults trace;
|
||||
|
||||
DAngle ang = shooter->Angles.Yaw;
|
||||
DAngle pitch = shooter->Angles.Pitch;
|
||||
double c = pitch.Cos();
|
||||
DVector3 vec(c * ang.Cos(), c * ang.Sin(), -pitch.Sin());
|
||||
|
||||
if (Trace(shooter->PosPlusZ(shooter->Height / 2), shooter->Sector, vec, 172., 0, ML_BLOCKEVERYTHING, shooter, trace, TRACE_NoSky))
|
||||
{
|
||||
if (trace.HitType == TRACE_HitWall)
|
||||
{
|
||||
DImpactDecal::StaticCreate(name, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent)
|
||||
{
|
||||
if (tpl == NULL || (tpl = tpl->GetDecal()) == NULL)
|
||||
|
@ -751,14 +769,23 @@ IMPLEMENT_CLASS(ADecal, false, false)
|
|||
|
||||
void ADecal::BeginPlay ()
|
||||
{
|
||||
const FDecalTemplate *tpl;
|
||||
const FDecalTemplate *tpl = nullptr;
|
||||
|
||||
Super::BeginPlay ();
|
||||
|
||||
if (args[0] < 0)
|
||||
{
|
||||
FName name = ENamedName(-args[0]);
|
||||
tpl = DecalLibrary.GetDecalByName(name.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
int decalid = args[0] + (args[1] << 8); // [KS] High byte for decals.
|
||||
tpl = DecalLibrary.GetDecalByNum(decalid);
|
||||
}
|
||||
|
||||
// If no decal is specified, don't try to create one.
|
||||
if (decalid != 0 && (tpl = DecalLibrary.GetDecalByNum (decalid)) != 0)
|
||||
if (tpl != nullptr)
|
||||
{
|
||||
if (!tpl->PicNum.Exists())
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ struct F3DFloor;
|
|||
class DBaseDecal;
|
||||
|
||||
class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, double x, double y, double z, DAngle angle, double tracedist, bool permanent);
|
||||
void SprayDecal(AActor *shooter, const char *name);
|
||||
|
||||
class DBaseDecal : public DThinker
|
||||
{
|
||||
|
|
|
@ -374,6 +374,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_PATCH(mStatscreenEnteringFont, "statscreen_enteringpatch")
|
||||
GAMEINFOKEY_BOOL(norandomplayerclass, "norandomplayerclass")
|
||||
GAMEINFOKEY_BOOL(forcekillscripts, "forcekillscripts") // [JM] Force kill scripts on thing death. (MF7_NOKILLSCRIPTS overrides.)
|
||||
GAMEINFOKEY_STRING(Dialogue, "dialogue")
|
||||
|
||||
else
|
||||
{
|
||||
|
|
1
src/gi.h
1
src/gi.h
|
@ -176,6 +176,7 @@ struct gameinfo_t
|
|||
FName DefaultEndSequence;
|
||||
FString mMapArrow, mCheatMapArrow;
|
||||
FString mEasyKey, mCheatKey;
|
||||
FString Dialogue;
|
||||
FGIFont mStatscreenMapNameFont;
|
||||
FGIFont mStatscreenFinishedFont;
|
||||
FGIFont mStatscreenEnteringFont;
|
||||
|
|
|
@ -197,6 +197,10 @@ xx(PowerWeaponLevel2)
|
|||
xx(PowerFlight)
|
||||
xx(PowerSpeed)
|
||||
xx(PowerTorch)
|
||||
xx(PowerHighJump)
|
||||
xx(PowerReflection)
|
||||
xx(PowerDrain)
|
||||
xx(Reflection)
|
||||
xx(CustomInventory)
|
||||
xx(Inventory)
|
||||
xx(CallTryPickup)
|
||||
|
@ -356,6 +360,7 @@ xx(CeilingZ)
|
|||
xx(FloorZ)
|
||||
xx(Health)
|
||||
xx(Pitch)
|
||||
xx(SpecialName)
|
||||
xx(Special)
|
||||
xx(TID)
|
||||
xx(TIDtoHate)
|
||||
|
|
|
@ -1062,95 +1062,3 @@ void FNodeBuilder::PrintSet (int l, DWORD set)
|
|||
}
|
||||
Printf (PRINT_LOG, "*\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BACKPATCH
|
||||
#ifdef _WIN32
|
||||
extern "C" {
|
||||
__declspec(dllimport) int __stdcall VirtualProtect(void *, unsigned long, unsigned long, unsigned long *);
|
||||
}
|
||||
#define PAGE_EXECUTE_READWRITE 64
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern "C" int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
#else
|
||||
static int *CallerOffset;
|
||||
int ClassifyLineBackpatchC (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
#endif
|
||||
{
|
||||
// Select the routine based on SSE2 availability and patch the caller so that
|
||||
// they call that routine directly next time instead of going through here.
|
||||
int *calleroffset;
|
||||
int diff;
|
||||
int (*func)(node_t &, const FSimpleVert *, const FSimpleVert *, int[2]);
|
||||
|
||||
#ifdef __GNUC__
|
||||
calleroffset = (int *)__builtin_return_address(0);
|
||||
#else
|
||||
calleroffset = CallerOffset;
|
||||
#endif
|
||||
// printf ("Patching for SSE %d @ %p %d\n", SSELevel, calleroffset, *calleroffset);
|
||||
|
||||
#ifndef DISABLE_SSE
|
||||
if (CPU.bSSE2)
|
||||
{
|
||||
func = ClassifyLineSSE2;
|
||||
diff = int((char *)ClassifyLineSSE2 - (char *)calleroffset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
func = ClassifyLine2;
|
||||
diff = int((char *)ClassifyLine2 - (char *)calleroffset);
|
||||
}
|
||||
|
||||
calleroffset--;
|
||||
// Patch the caller.
|
||||
#ifdef _WIN32
|
||||
unsigned long oldprotect;
|
||||
if (VirtualProtect (calleroffset, 4, PAGE_EXECUTE_READWRITE, &oldprotect))
|
||||
#else
|
||||
// must make this page-aligned for mprotect
|
||||
long pagesize = sysconf(_SC_PAGESIZE);
|
||||
char *callerpage = (char *)((intptr_t)calleroffset & ~(pagesize - 1));
|
||||
size_t protectlen = (intptr_t)calleroffset + sizeof(void*) - (intptr_t)callerpage;
|
||||
int ptect;
|
||||
if (!(ptect = mprotect(callerpage, protectlen, PROT_READ|PROT_WRITE|PROT_EXEC)))
|
||||
#endif
|
||||
{
|
||||
*calleroffset = diff;
|
||||
#ifdef _WIN32
|
||||
VirtualProtect (calleroffset, sizeof(void*), oldprotect, &oldprotect);
|
||||
#else
|
||||
mprotect(callerpage, protectlen, PROT_READ|PROT_EXEC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// And return by calling the real function.
|
||||
return func (node, v1, v2, sidev);
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
// The ClassifyLineBackpatch() function here is a stub that uses inline assembly and nakedness
|
||||
// to retrieve the return address of the stack before sending control to the real
|
||||
// ClassifyLineBackpatchC() function. Since BACKPATCH shouldn't be defined on 64-bit builds,
|
||||
// we're okay that VC++ can't do inline assembly on that target.
|
||||
|
||||
extern "C" __declspec(noinline) __declspec(naked) int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
{
|
||||
// We store the return address in a global, so as not to need to mess with the parameter list.
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp]
|
||||
mov CallerOffset, eax
|
||||
jmp ClassifyLineBackpatchC
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -53,22 +53,6 @@ struct FSimpleVert
|
|||
fixed_t x, y;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int ClassifyLine2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
#ifndef DISABLE_SSE
|
||||
int ClassifyLineSSE1 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
#ifdef BACKPATCH
|
||||
#ifdef __GNUC__
|
||||
int ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]) __attribute__((noinline));
|
||||
#else
|
||||
int __declspec(noinline) ClassifyLineBackpatch (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2]);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
class FNodeBuilder
|
||||
{
|
||||
struct FPrivSeg
|
||||
|
@ -282,7 +266,7 @@ private:
|
|||
// 1 = seg is in back
|
||||
// -1 = seg cuts the node
|
||||
|
||||
inline int ClassifyLine (node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2]);
|
||||
int ClassifyLine (node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2]);
|
||||
|
||||
void FixSplitSharers (const node_t &node);
|
||||
double AddIntersection (const node_t &node, int vertex);
|
||||
|
@ -341,28 +325,3 @@ inline int FNodeBuilder::PointOnSide (int x, int y, int x1, int y1, int dx, int
|
|||
}
|
||||
return s_num > 0.0 ? -1 : 1;
|
||||
}
|
||||
|
||||
inline int FNodeBuilder::ClassifyLine (node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2])
|
||||
{
|
||||
#ifdef DISABLE_SSE
|
||||
return ClassifyLine2 (node, v1, v2, sidev);
|
||||
#else
|
||||
#if defined(__SSE2__) || defined(_M_X64)
|
||||
// If compiling with SSE2 support everywhere, just use the SSE2 version.
|
||||
return ClassifyLineSSE2 (node, v1, v2, sidev);
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1300
|
||||
// VC 6 does not support SSE optimizations.
|
||||
return ClassifyLine2 (node, v1, v2, sidev);
|
||||
#else
|
||||
// Select the routine based on our flag.
|
||||
#ifdef BACKPATCH
|
||||
return ClassifyLineBackpatch (node, v1, v2, sidev);
|
||||
#else
|
||||
if (CPU.bSSE2)
|
||||
return ClassifyLineSSE2 (node, v1, v2, sidev);
|
||||
else
|
||||
return ClassifyLine2 (node, v1, v2, sidev);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#define FAR_ENOUGH 17179869184.f // 4<<32
|
||||
|
||||
extern "C" int ClassifyLine2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
int FNodeBuilder::ClassifyLine(node_t &node, const FPrivVert *v1, const FPrivVert *v2, int sidev[2])
|
||||
{
|
||||
double d_x1 = double(node.x);
|
||||
double d_y1 = double(node.y);
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
#ifndef DISABLE_SSE
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "nodebuild.h"
|
||||
|
||||
#define FAR_ENOUGH 17179869184.f // 4<<32
|
||||
|
||||
// You may notice that this function is identical to ClassifyLine2.
|
||||
// The reason it is SSE2 is because this file is explicitly compiled
|
||||
// with SSE2 math enabled, but the other files are not.
|
||||
|
||||
extern "C" int ClassifyLineSSE2 (node_t &node, const FSimpleVert *v1, const FSimpleVert *v2, int sidev[2])
|
||||
{
|
||||
double d_x1 = double(node.x);
|
||||
double d_y1 = double(node.y);
|
||||
double d_dx = double(node.dx);
|
||||
double d_dy = double(node.dy);
|
||||
double d_xv1 = double(v1->x);
|
||||
double d_xv2 = double(v2->x);
|
||||
double d_yv1 = double(v1->y);
|
||||
double d_yv2 = double(v2->y);
|
||||
|
||||
double s_num1 = (d_y1 - d_yv1) * d_dx - (d_x1 - d_xv1) * d_dy;
|
||||
double s_num2 = (d_y1 - d_yv2) * d_dx - (d_x1 - d_xv2) * d_dy;
|
||||
|
||||
int nears = 0;
|
||||
|
||||
if (s_num1 <= -FAR_ENOUGH)
|
||||
{
|
||||
if (s_num2 <= -FAR_ENOUGH)
|
||||
{
|
||||
sidev[0] = sidev[1] = 1;
|
||||
return 1;
|
||||
}
|
||||
if (s_num2 >= FAR_ENOUGH)
|
||||
{
|
||||
sidev[0] = 1;
|
||||
sidev[1] = -1;
|
||||
return -1;
|
||||
}
|
||||
nears = 1;
|
||||
}
|
||||
else if (s_num1 >= FAR_ENOUGH)
|
||||
{
|
||||
if (s_num2 >= FAR_ENOUGH)
|
||||
{
|
||||
sidev[0] = sidev[1] = -1;
|
||||
return 0;
|
||||
}
|
||||
if (s_num2 <= -FAR_ENOUGH)
|
||||
{
|
||||
sidev[0] = -1;
|
||||
sidev[1] = 1;
|
||||
return -1;
|
||||
}
|
||||
nears = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nears = 2 | int(fabs(s_num2) < FAR_ENOUGH);
|
||||
}
|
||||
|
||||
if (nears)
|
||||
{
|
||||
double l = 1.f / (d_dx*d_dx + d_dy*d_dy);
|
||||
if (nears & 2)
|
||||
{
|
||||
double dist = s_num1 * s_num1 * l;
|
||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||
{
|
||||
sidev[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||
}
|
||||
if (nears & 1)
|
||||
{
|
||||
double dist = s_num2 * s_num2 * l;
|
||||
if (dist < SIDE_EPSILON*SIDE_EPSILON)
|
||||
{
|
||||
sidev[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sidev[0] = s_num1 > 0.0 ? -1 : 1;
|
||||
sidev[1] = s_num2 > 0.0 ? -1 : 1;
|
||||
}
|
||||
|
||||
if ((sidev[0] | sidev[1]) == 0)
|
||||
{ // seg is coplanar with the splitter, so use its orientation to determine
|
||||
// which child it ends up in. If it faces the same direction as the splitter,
|
||||
// it goes in front. Otherwise, it goes in back.
|
||||
|
||||
if (node.dx != 0)
|
||||
{
|
||||
if ((node.dx > 0 && v2->x > v1->x) || (node.dx < 0 && v2->x < v1->x))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((node.dy > 0 && v2->y > v1->y) || (node.dy < 0 && v2->y < v1->y))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sidev[0] <= 0 && sidev[1] <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (sidev[0] >= 0 && sidev[1] >= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -9423,7 +9423,10 @@ scriptwait:
|
|||
}
|
||||
|
||||
case PCD_SETMUGSHOTSTATE:
|
||||
if (!multiplayer || (activator != nullptr && activator->CheckLocalView(consoleplayer)))
|
||||
{
|
||||
StatusBar->SetMugShotState(FBehavior::StaticLookupString(STACK(1)));
|
||||
}
|
||||
sp--;
|
||||
break;
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
#include "math/cmath.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "r_utility.h"
|
||||
#include "sbar.h"
|
||||
|
||||
AActor *SingleActorFromTID(int tid, AActor *defactor);
|
||||
|
||||
|
@ -4602,6 +4603,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeCountFlags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum ERaise
|
||||
{
|
||||
RF_TRANSFERFRIENDLINESS = 1,
|
||||
RF_NOCHECKPOSITION = 2
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_RaiseMaster
|
||||
|
@ -4610,11 +4618,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeCountFlags)
|
|||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseMaster)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_BOOL_DEF(copy);
|
||||
PARAM_INT_DEF(flags);
|
||||
|
||||
bool copy = !!(flags & RF_TRANSFERFRIENDLINESS);
|
||||
if (self->master != NULL)
|
||||
{
|
||||
P_Thing_Raise(self->master, copy ? self : NULL);
|
||||
P_Thing_Raise(self->master, copy ? self : NULL, (flags & RF_NOCHECKPOSITION));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4627,16 +4636,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseMaster)
|
|||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseChildren)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_BOOL_DEF(copy);
|
||||
PARAM_INT_DEF(flags);
|
||||
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
|
||||
bool copy = !!(flags & RF_TRANSFERFRIENDLINESS);
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self)
|
||||
{
|
||||
P_Thing_Raise(mo, copy ? self : NULL);
|
||||
P_Thing_Raise(mo, copy ? self : NULL, (flags & RF_NOCHECKPOSITION));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -4650,18 +4660,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseChildren)
|
|||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseSiblings)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_BOOL_DEF(copy);
|
||||
PARAM_INT_DEF(flags);
|
||||
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
|
||||
bool copy = !!(flags & RF_TRANSFERFRIENDLINESS);
|
||||
if (self->master != NULL)
|
||||
{
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self->master && mo != self)
|
||||
{
|
||||
P_Thing_Raise(mo, copy ? self : NULL);
|
||||
P_Thing_Raise(mo, copy ? self : NULL, (flags & RF_NOCHECKPOSITION));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6922,3 +6933,20 @@ DEFINE_ACTION_FUNCTION(AActor, SetCamera)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SprayDecal)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_STRING(name);
|
||||
SprayDecal(self, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_SetMugshotState)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_STRING(name);
|
||||
if (self->CheckLocalView(consoleplayer))
|
||||
StatusBar->SetMugShotState(name);
|
||||
return 0;
|
||||
}
|
|
@ -205,6 +205,11 @@ void P_LoadStrifeConversations (MapData *map, const char *mapname)
|
|||
{
|
||||
if (!LoadScriptFile (scriptname_b, false, 1))
|
||||
{
|
||||
if (gameinfo.Dialogue.IsNotEmpty())
|
||||
{
|
||||
if (LoadScriptFile(gameinfo.Dialogue, false, 0)) return;
|
||||
}
|
||||
|
||||
LoadScriptFile ("SCRIPT00", false, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1162,6 +1162,38 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
|
|||
// any negative value means that something in the above chain has cancelled out all damage and all damage effects, including pain.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//[RC] Backported from the Zandronum source.. Mostly.
|
||||
if( target->player &&
|
||||
damage > 0 &&
|
||||
source &&
|
||||
mod != NAME_Reflection &&
|
||||
target != source)
|
||||
|
||||
{
|
||||
int reflectdamage = 0;
|
||||
for (auto p = target->player->mo->Inventory; p != nullptr; p = p->Inventory)
|
||||
{
|
||||
// This picks the reflection item with the maximum efficiency for the given damage type.
|
||||
if (p->IsKindOf(NAME_PowerReflection))
|
||||
{
|
||||
int mydamage = p->ApplyDamageFactor(mod, damage);
|
||||
if (mydamage > reflectdamage) reflectdamage = mydamage;
|
||||
}
|
||||
}
|
||||
|
||||
if (reflectdamage > 0)
|
||||
{
|
||||
// use the reflect item's damage factors to get the final value here.
|
||||
P_DamageMobj(source, nullptr, target, reflectdamage, NAME_Reflection );
|
||||
|
||||
// Reset means of death flag.
|
||||
MeansOfDeath = mod;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Push the target unless the source's weapon's kickback is 0.
|
||||
// (i.e. Gauntlets/Chainsaw)
|
||||
if (!plrDontThrust && inflictor && inflictor != target // [RH] Not if hurting own self
|
||||
|
@ -1417,13 +1449,24 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
|
|||
|
||||
// If the damaging player has the power of drain, give the player 50% of the damage
|
||||
// done in health.
|
||||
if ( source && source->player && source->player->cheats & CF_DRAIN && !(target->flags5 & MF5_DONTDRAIN))
|
||||
if ( source && source->player && !(target->flags5 & MF5_DONTDRAIN))
|
||||
{
|
||||
if (!target->player || target->player != source->player)
|
||||
{
|
||||
if ( P_GiveBody( source, damage / 2 ))
|
||||
double draindamage = 0;
|
||||
for (auto p = source->player->mo->Inventory; p != nullptr; p = p->Inventory)
|
||||
{
|
||||
S_Sound( source, CHAN_ITEM, "*drainhealth", 1, ATTN_NORM );
|
||||
// This picks the item with the maximum efficiency.
|
||||
if (p->IsKindOf(NAME_PowerDrain))
|
||||
{
|
||||
double mydamage = p->FloatVar(NAME_Strength);
|
||||
if (mydamage > draindamage) draindamage = mydamage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( P_GiveBody( source, int(draindamage * damage)))
|
||||
{
|
||||
S_Sound(source, CHAN_ITEM, "*drainhealth", 1, ATTN_NORM );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1729,7 +1772,8 @@ bool AActor::OkayToSwitchTarget (AActor *other)
|
|||
}
|
||||
|
||||
int infight;
|
||||
if (flags5 & MF5_NOINFIGHTING) infight=-1;
|
||||
if (flags7 & MF7_FORCEINFIGHTING) infight = 1;
|
||||
else if (flags5 & MF5_NOINFIGHTING) infight = -1;
|
||||
else infight = G_SkillProperty(SKILLP_Infight);
|
||||
|
||||
if (infight < 0 && other->player == NULL && !IsHostile (other))
|
||||
|
|
|
@ -1737,14 +1737,14 @@ FUNC(LS_Thing_SpawnFacing)
|
|||
}
|
||||
|
||||
FUNC(LS_Thing_Raise)
|
||||
// Thing_Raise(tid)
|
||||
// Thing_Raise(tid, nocheck)
|
||||
{
|
||||
AActor * target;
|
||||
bool ok = false;
|
||||
|
||||
if (arg0==0)
|
||||
{
|
||||
ok = P_Thing_Raise (it,NULL);
|
||||
ok = P_Thing_Raise (it,NULL, arg1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1752,7 +1752,7 @@ FUNC(LS_Thing_Raise)
|
|||
|
||||
while ( (target = iterator.Next ()) )
|
||||
{
|
||||
ok |= P_Thing_Raise(target,NULL);
|
||||
ok |= P_Thing_Raise(target,NULL, arg1);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
|
|
|
@ -151,7 +151,7 @@ bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog);
|
|||
int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type);
|
||||
void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setbob);
|
||||
void P_RemoveThing(AActor * actor);
|
||||
bool P_Thing_Raise(AActor *thing, AActor *raiser);
|
||||
bool P_Thing_Raise(AActor *thing, AActor *raiser, int nocheck = false);
|
||||
bool P_Thing_CanRaise(AActor *thing);
|
||||
PClassActor *P_GetSpawnableType(int spawnnum);
|
||||
void InitSpawnablesFromMapinfo();
|
||||
|
|
|
@ -1177,6 +1177,7 @@ static bool CanAttackHurt(AActor *victim, AActor *shooter)
|
|||
if (!victim->player && !shooter->player)
|
||||
{
|
||||
int infight = G_SkillProperty(SKILLP_Infight);
|
||||
if (infight < 0 && (victim->flags7 & MF7_FORCEINFIGHTING)) infight = 0; // This must override the 'no infight' setting to take effect.
|
||||
|
||||
if (infight < 0)
|
||||
{
|
||||
|
@ -5276,20 +5277,22 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
|
|||
// [RH] Check for things to talk with or use a puzzle item on
|
||||
if (!in->isaline)
|
||||
{
|
||||
if (usething == in->d.thing)
|
||||
AActor * const mobj = in->d.thing;
|
||||
|
||||
if (mobj == usething)
|
||||
continue;
|
||||
// Check thing
|
||||
|
||||
// Check for puzzle item use or USESPECIAL flag
|
||||
// Extended to use the same activationtype mechanism as BUMPSPECIAL does
|
||||
if (in->d.thing->flags5 & MF5_USESPECIAL || in->d.thing->special == UsePuzzleItem)
|
||||
if (mobj->flags5 & MF5_USESPECIAL || mobj->special == UsePuzzleItem)
|
||||
{
|
||||
if (P_ActivateThingSpecial(in->d.thing, usething))
|
||||
if (P_ActivateThingSpecial(mobj, usething))
|
||||
return true;
|
||||
}
|
||||
IFVIRTUALPTR(usething, AActor, Used)
|
||||
IFVIRTUALPTR(mobj, AActor, Used)
|
||||
{
|
||||
VMValue params[] = { usething, in->d.thing };
|
||||
VMValue params[] = { mobj, usething };
|
||||
int ret;
|
||||
VMReturn vret(&ret);
|
||||
GlobalVMStack.Call(func, params, 2, &vret, 1);
|
||||
|
|
|
@ -902,8 +902,7 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
|
|||
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
|
||||
// and infinite ammo is on
|
||||
if (notakeinfinite &&
|
||||
((dmflags & DF_INFINITE_AMMO) || (player && player->cheats & CF_INFINITEAMMO)) &&
|
||||
item->IsKindOf(NAME_Ammo))
|
||||
((dmflags & DF_INFINITE_AMMO) || (player && FindInventory(NAME_PowerInfiniteAmmo))) && item->IsKindOf(NAME_Ammo))
|
||||
{
|
||||
// Nothing to do here, except maybe res = false;? Would it make sense?
|
||||
result = false;
|
||||
|
|
|
@ -406,7 +406,7 @@ void P_RemoveThing(AActor * actor)
|
|||
|
||||
}
|
||||
|
||||
bool P_Thing_Raise(AActor *thing, AActor *raiser)
|
||||
bool P_Thing_Raise(AActor *thing, AActor *raiser, int nocheck)
|
||||
{
|
||||
FState * RaiseState = thing->GetRaiseState();
|
||||
if (RaiseState == NULL)
|
||||
|
@ -426,7 +426,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser)
|
|||
thing->flags |= MF_SOLID;
|
||||
thing->Height = info->Height; // [RH] Use real height
|
||||
thing->radius = info->radius; // [RH] Use real radius
|
||||
if (!P_CheckPosition (thing, thing->Pos()))
|
||||
if (!nocheck && !P_CheckPosition (thing, thing->Pos()))
|
||||
{
|
||||
thing->flags = oldflags;
|
||||
thing->radius = oldradius;
|
||||
|
|
|
@ -1393,7 +1393,7 @@ public:
|
|||
if (isTranslated) sec->special = P_TranslateSectorSpecial(sec->special);
|
||||
else if (namespc == NAME_Hexen)
|
||||
{
|
||||
if (sec->special < 0 || sec->special > 255 || !HexenSectorSpecialOk[sec->special])
|
||||
if (sec->special < 0 || sec->special > 140 || !HexenSectorSpecialOk[sec->special])
|
||||
sec->special = 0; // NULL all unknown specials
|
||||
}
|
||||
continue;
|
||||
|
|
|
@ -192,10 +192,15 @@ class USDFParser : public UDMFParserBase
|
|||
|
||||
case NAME_Special:
|
||||
reply->ActionSpecial = CheckInt(key);
|
||||
if (reply->ActionSpecial < 0 || reply->ActionSpecial > 255)
|
||||
if (reply->ActionSpecial < 0)
|
||||
reply->ActionSpecial = 0;
|
||||
break;
|
||||
|
||||
case NAME_SpecialName:
|
||||
if (namespace_bits == Zd)
|
||||
reply->ActionSpecial = P_FindLineSpecial(CheckString(key));
|
||||
break;
|
||||
|
||||
case NAME_Arg0:
|
||||
case NAME_Arg1:
|
||||
case NAME_Arg2:
|
||||
|
|
|
@ -2690,9 +2690,19 @@ void P_PlayerThink (player_t *player)
|
|||
else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0)
|
||||
{
|
||||
double jumpvelz = player->mo->JumpZ * 35 / TICRATE;
|
||||
double jumpfac = 0;
|
||||
|
||||
// [BC] If the player has the high jump power, double his jump velocity.
|
||||
if ( player->cheats & CF_HIGHJUMP ) jumpvelz *= 2;
|
||||
// (actually, pick the best factors from all active items.)
|
||||
for (auto p = player->mo->Inventory; p != nullptr; p = p->Inventory)
|
||||
{
|
||||
if (p->IsKindOf(NAME_PowerHighJump))
|
||||
{
|
||||
double f = p->FloatVar(NAME_Strength);
|
||||
if (f > jumpfac) jumpfac = f;
|
||||
}
|
||||
}
|
||||
if (jumpfac > 0) jumpvelz *= jumpfac;
|
||||
|
||||
player->mo->Vel.Z += jumpvelz;
|
||||
player->mo->flags2 &= ~MF2_ONMOBJ;
|
||||
|
|
|
@ -318,6 +318,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF7, NOSHIELDREFLECT, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FORCEZERORADIUSDMG, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, NOINFIGHTSPECIES, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, FORCEINFIGHTING, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
@ -917,7 +918,7 @@ void InitThingdef()
|
|||
fieldptr = new PField("gametic", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gametic);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("demoplayback", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback);
|
||||
fieldptr = new PField("demoplayback", TypeBool, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback);
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||
|
||||
fieldptr = new PField("BackbuttonTime", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&BackbuttonTime);
|
||||
|
|
|
@ -279,6 +279,10 @@ void MusInfo::TimidityVolumeChanged()
|
|||
{
|
||||
}
|
||||
|
||||
void MusInfo::GMEDepthChanged(float val)
|
||||
{
|
||||
}
|
||||
|
||||
void MusInfo::FluidSettingInt(const char *, int)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
virtual void FluidSettingNum(const char *setting, double value); // "
|
||||
virtual void FluidSettingStr(const char *setting, const char *value); // "
|
||||
virtual void WildMidiSetOption(int opt, int set);
|
||||
virtual void GMEDepthChanged(float val);
|
||||
|
||||
void Start(bool loop, float rel_vol = -1.f, int subsong = 0);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <gme/gme.h>
|
||||
#include "v_text.h"
|
||||
#include "files.h"
|
||||
#include "templates.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -67,6 +68,7 @@ protected:
|
|||
bool StartTrack(int track, bool getcritsec=true);
|
||||
bool GetTrackInfo();
|
||||
int CalcSongLength();
|
||||
void GMEDepthChanged(float val);
|
||||
|
||||
static bool Read(SoundStream *stream, void *buff, int len, void *userdata);
|
||||
};
|
||||
|
@ -84,6 +86,12 @@ protected:
|
|||
// Currently not used.
|
||||
CVAR (Float, spc_amp, 1.875f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
CUSTOM_CVAR(Float, gme_stereodepth, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (currSong != nullptr)
|
||||
currSong->GMEDepthChanged(self);
|
||||
}
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
@ -146,6 +154,7 @@ MusInfo *GME_OpenSong(FileReader &reader, const char *fmt)
|
|||
reader.Seek(fpos, SEEK_SET);
|
||||
return NULL;
|
||||
}
|
||||
gme_set_stereo_depth(emu, clamp(*gme_stereodepth, 0.f, 1.f));
|
||||
return new GMESong(emu, sample_rate);
|
||||
}
|
||||
|
||||
|
@ -189,6 +198,19 @@ GMESong::~GMESong()
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GMESong :: GMEDepthChanged
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GMESong::GMEDepthChanged(float val)
|
||||
{
|
||||
if (Emu != nullptr)
|
||||
gme_set_stereo_depth(Emu, clamp(val, 0.f, 1.f));
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GMESong :: Play
|
||||
|
|
|
@ -163,7 +163,7 @@ protected:
|
|||
class FSpecialFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump);
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
|
||||
void LoadTranslations();
|
||||
|
||||
|
@ -357,7 +357,7 @@ DEFINE_ACTION_FUNCTION(FFont, GetFont)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump, int spacewidth)
|
||||
FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump, int spacewidth, bool notranslate)
|
||||
{
|
||||
int i;
|
||||
FTextureID lump;
|
||||
|
@ -367,6 +367,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
|
||||
bool stcfn121 = false;
|
||||
|
||||
noTranslate = notranslate;
|
||||
Lump = fdlump;
|
||||
Chars = new CharData[count];
|
||||
charlumps = new FTexture *[count];
|
||||
|
@ -430,7 +431,8 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
|
||||
if (charlumps[i] != NULL)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
if (!noTranslate) Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
else Chars[i].Pic = charlumps[i];
|
||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||
}
|
||||
else
|
||||
|
@ -455,7 +457,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
|
||||
FixXMoves();
|
||||
|
||||
LoadTranslations();
|
||||
if (!noTranslate) LoadTranslations();
|
||||
|
||||
delete[] charlumps;
|
||||
}
|
||||
|
@ -472,6 +474,9 @@ FFont::~FFont ()
|
|||
{
|
||||
int count = LastChar - FirstChar + 1;
|
||||
|
||||
// A noTranslate font directly references the original textures.
|
||||
if (!noTranslate)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (Chars[i].Pic != NULL && Chars[i].Pic->Name[0] == 0)
|
||||
|
@ -479,6 +484,7 @@ FFont::~FFont ()
|
|||
delete Chars[i].Pic;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] Chars;
|
||||
Chars = NULL;
|
||||
}
|
||||
|
@ -752,7 +758,7 @@ void FFont::BuildTranslations (const double *luminosity, const BYTE *identity,
|
|||
|
||||
FRemapTable *FFont::GetColorTranslation (EColorRange range) const
|
||||
{
|
||||
if (ActiveColors == 0)
|
||||
if (ActiveColors == 0 || noTranslate)
|
||||
return NULL;
|
||||
else if (range >= NumTextColors)
|
||||
range = CR_UNTRANSLATED;
|
||||
|
@ -1005,6 +1011,7 @@ FFont::FFont (int lump)
|
|||
PatchRemap = NULL;
|
||||
FontName = NAME_None;
|
||||
Cursor = '_';
|
||||
noTranslate = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1964,7 +1971,7 @@ void FFontChar2::MakeTexture ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump) : FFont(lump)
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate) : FFont(lump)
|
||||
{
|
||||
int i;
|
||||
FTexture **charlumps;
|
||||
|
@ -1973,6 +1980,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
|
||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
||||
|
||||
noTranslate = donttranslate;
|
||||
FontName = name;
|
||||
Chars = new CharData[count];
|
||||
charlumps = new FTexture*[count];
|
||||
|
@ -2007,7 +2015,8 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
|
||||
if (charlumps[i] != NULL)
|
||||
{
|
||||
Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
if (!noTranslate) Chars[i].Pic = new FFontChar1 (charlumps[i]);
|
||||
else Chars[i].Pic = charlumps[i];
|
||||
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||
}
|
||||
else
|
||||
|
@ -2029,7 +2038,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
|||
|
||||
FixXMoves();
|
||||
|
||||
LoadTranslations();
|
||||
if (!noTranslate) LoadTranslations();
|
||||
|
||||
delete[] charlumps;
|
||||
}
|
||||
|
@ -2160,6 +2169,7 @@ void V_InitCustomFonts()
|
|||
FScanner sc;
|
||||
FTexture *lumplist[256];
|
||||
bool notranslate[256];
|
||||
bool donttranslate;
|
||||
FString namebuffer, templatebuf;
|
||||
int i;
|
||||
int llump,lastlump=0;
|
||||
|
@ -2177,6 +2187,7 @@ void V_InitCustomFonts()
|
|||
{
|
||||
memset (lumplist, 0, sizeof(lumplist));
|
||||
memset (notranslate, 0, sizeof(notranslate));
|
||||
donttranslate = false;
|
||||
namebuffer = sc.String;
|
||||
format = 0;
|
||||
start = 33;
|
||||
|
@ -2228,6 +2239,10 @@ void V_InitCustomFonts()
|
|||
spacewidth = sc.Number;
|
||||
format = 1;
|
||||
}
|
||||
else if (sc.Compare("DONTTRANSLATE"))
|
||||
{
|
||||
donttranslate = true;
|
||||
}
|
||||
else if (sc.Compare ("NOTRANSLATION"))
|
||||
{
|
||||
if (format == 1) goto wrong;
|
||||
|
@ -2258,7 +2273,7 @@ void V_InitCustomFonts()
|
|||
}
|
||||
if (format == 1)
|
||||
{
|
||||
FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump, spacewidth);
|
||||
FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump, spacewidth, donttranslate);
|
||||
fnt->SetCursor(cursor);
|
||||
}
|
||||
else if (format == 2)
|
||||
|
@ -2281,7 +2296,7 @@ void V_InitCustomFonts()
|
|||
}
|
||||
if (count > 0)
|
||||
{
|
||||
FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump);
|
||||
FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump, donttranslate);
|
||||
fnt->SetCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ extern int NumTextColors;
|
|||
class FFont
|
||||
{
|
||||
public:
|
||||
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1);
|
||||
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false);
|
||||
virtual ~FFont ();
|
||||
|
||||
virtual FTexture *GetChar (int code, int *const width) const;
|
||||
|
@ -100,6 +100,7 @@ public:
|
|||
int GetCharCode(int code, bool needpic) const;
|
||||
char GetCursor() const { return Cursor; }
|
||||
void SetCursor(char c) { Cursor = c; }
|
||||
bool NoTranslate() const { return noTranslate; }
|
||||
|
||||
protected:
|
||||
FFont (int lump);
|
||||
|
@ -116,6 +117,7 @@ protected:
|
|||
int FontHeight;
|
||||
int GlobalKerning;
|
||||
char Cursor;
|
||||
bool noTranslate;
|
||||
struct CharData
|
||||
{
|
||||
FTexture *Pic;
|
||||
|
|
|
@ -2020,7 +2020,10 @@ public:
|
|||
if (bcnt == 1)
|
||||
{
|
||||
// intermission music - use the defaults if none specified
|
||||
if (level.info->InterMusic.IsNotEmpty())
|
||||
auto mus = level.info->MapInterMusic.CheckKey(wbs->next);
|
||||
if (mus != nullptr)
|
||||
S_ChangeMusic(mus->first, mus->second);
|
||||
else if (level.info->InterMusic.IsNotEmpty())
|
||||
S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder);
|
||||
else
|
||||
S_ChangeMusic (gameinfo.intermissionMusic.GetChars(), gameinfo.intermissionOrder);
|
||||
|
|
|
@ -106,6 +106,7 @@ CMPTMNU_RENDERINGBEHAVIOR = "Rendering Behaviour";
|
|||
CMPTMNU_SOUNDBEHAVIOR = "Sound Behaviour";
|
||||
CMPTMNU_SECTORSOUNDS = "Sector sounds use centre as source";
|
||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only";
|
||||
OPTVAL_NODOORS = "All except doors";
|
||||
C_GRAY = "\ccgrey";
|
||||
C_DARKGRAY = "\cudark grey";
|
||||
|
||||
|
|
|
@ -1035,6 +1035,13 @@ OptionValue MapBackTypes
|
|||
2, "$OPTVAL_MAPDEFINEDCOLORSONLY"
|
||||
}
|
||||
|
||||
OptionValue MapTriggers
|
||||
{
|
||||
0, "$OPTVAL_OFF"
|
||||
1, "$OPTVAL_NO_DOORS"
|
||||
2, "$OPTVAL_ON"
|
||||
}
|
||||
|
||||
OptionMenu AutomapOptions
|
||||
{
|
||||
Title "$AUTOMAPMNU_TITLE"
|
||||
|
@ -1058,7 +1065,7 @@ OptionMenu AutomapOptions
|
|||
Option "$AUTOMAPMNU_SHOWMAPLABEL", "am_showmaplabel", "MaplabelTypes"
|
||||
Option "$AUTOMAPMNU_DRAWMAPBACK", "am_drawmapback", "MapBackTypes"
|
||||
Option "$AUTOMAPMNU_SHOWKEYS", "am_showkeys", "OnOff"
|
||||
Option "$AUTOMAPMNU_SHOWTRIGGERLINES", "am_showtriggerlines", "OnOff"
|
||||
Option "$AUTOMAPMNU_SHOWTRIGGERLINES", "am_showtriggerlines", "MapTriggers"
|
||||
Option "$AUTOMAPMNU_SHOWTHINGSPRITES", "am_showthingsprites", "STSTypes"
|
||||
}
|
||||
|
||||
|
|
|
@ -791,9 +791,9 @@ class Actor : Thinker native
|
|||
native void A_SetBlend(color color1, double alpha, int tics, color color2 = 0);
|
||||
deprecated native void A_ChangeFlag(string flagname, bool value);
|
||||
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);
|
||||
native void A_RaiseMaster(bool copy = 0);
|
||||
native void A_RaiseChildren(bool copy = 0);
|
||||
native void A_RaiseSiblings(bool copy = 0);
|
||||
native void A_RaiseMaster(int flags = 0);
|
||||
native void A_RaiseChildren(int flags = 0);
|
||||
native void A_RaiseSiblings(int flags = 0);
|
||||
deprecated native void A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, double missileheight);
|
||||
action native bool, Actor A_ThrowGrenade(class<Actor> itemtype, double zheight = 0, double xyvel = 0, double zvel = 0, bool useammo = true);
|
||||
native void A_Weave(int xspeed, int yspeed, double xdist, double ydist);
|
||||
|
@ -869,6 +869,8 @@ class Actor : Thinker native
|
|||
native bool A_SetVisibleRotation(double anglestart = 0, double angleend = 0, double pitchstart = 0, double pitchend = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetTranslation(name transname);
|
||||
native bool A_SetSize(double newradius, double newheight = -1, bool testpos = false);
|
||||
native void A_SprayDecal(String name);
|
||||
native void A_SetMugshotState(String name);
|
||||
|
||||
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
||||
|
|
|
@ -1000,6 +1000,12 @@ enum EFindFloorCeiling
|
|||
FFCF_NODROPOFF = 256, // Caller does not need a dropoff (saves some time when checking portals)
|
||||
};
|
||||
|
||||
enum ERaise
|
||||
{
|
||||
RF_TRANSFERFRIENDLINESS = 1,
|
||||
RF_NOCHECKPOSITION = 2
|
||||
}
|
||||
|
||||
enum ETeleport
|
||||
{
|
||||
TELF_DESTFOG = 1,
|
||||
|
@ -1092,17 +1098,21 @@ enum EPlayerCheats
|
|||
CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use
|
||||
CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted
|
||||
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
|
||||
CF_DRAIN = 1 << 16, // Player owns a drain powerup
|
||||
CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;)
|
||||
CF_REFLECTION = 1 << 19,
|
||||
CF_PROSPERITY = 1 << 20,
|
||||
CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact
|
||||
|
||||
CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.
|
||||
CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact
|
||||
|
||||
CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either.
|
||||
CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either.
|
||||
CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die
|
||||
CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip
|
||||
|
||||
// These flags no longer exist, but keep the names for some stray mod that might have used them.
|
||||
CF_DRAIN = 0,
|
||||
CF_HIGHJUMP = 0,
|
||||
CF_REFLECTION = 0,
|
||||
CF_PROSPERITY = 0,
|
||||
CF_DOUBLEFIRINGSPEED= 0,
|
||||
CF_INFINITEAMMO = 0,
|
||||
};
|
||||
|
||||
const TEXTCOLOR_BRICK = "\034A";
|
||||
|
|
|
@ -1783,32 +1783,9 @@ class PowerDrain : Powerup
|
|||
{
|
||||
Default
|
||||
{
|
||||
Powerup.Strength 0.5;
|
||||
Powerup.Duration -60;
|
||||
}
|
||||
|
||||
override void InitEffect()
|
||||
{
|
||||
Super.InitEffect();
|
||||
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Give the player the power to drain life from opponents when he damages them.
|
||||
Owner.player.cheats |= CF_DRAIN;
|
||||
}
|
||||
}
|
||||
|
||||
override void EndEffect()
|
||||
{
|
||||
Super.EndEffect();
|
||||
|
||||
// Nothing to do if there's no owner.
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Take away the drain power.
|
||||
Owner.player.cheats &= ~CF_DRAIN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1846,27 +1823,9 @@ class PowerRegeneration : Powerup
|
|||
|
||||
class PowerHighJump : Powerup
|
||||
{
|
||||
override void InitEffect()
|
||||
Default
|
||||
{
|
||||
Super.InitEffect();
|
||||
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Give the player the power to jump much higher.
|
||||
Owner.player.cheats |= CF_HIGHJUMP;
|
||||
}
|
||||
}
|
||||
|
||||
override void EndEffect()
|
||||
{
|
||||
Super.EndEffect();
|
||||
|
||||
// Nothing to do if there's no owner.
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Take away the high jump power.
|
||||
Owner.player.cheats &= ~CF_HIGHJUMP;
|
||||
}
|
||||
Powerup.Strength 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1878,27 +1837,9 @@ class PowerHighJump : Powerup
|
|||
|
||||
class PowerDoubleFiringSpeed : Powerup
|
||||
{
|
||||
override void InitEffect()
|
||||
Default
|
||||
{
|
||||
Super.InitEffect();
|
||||
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Give the player the power to shoot twice as fast.
|
||||
Owner.player.cheats |= CF_DOUBLEFIRINGSPEED;
|
||||
}
|
||||
}
|
||||
|
||||
override void EndEffect()
|
||||
{
|
||||
Super.EndEffect();
|
||||
|
||||
// Nothing to do if there's no owner.
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Take away the shooting twice as fast power.
|
||||
Owner.player.cheats &= ~CF_DOUBLEFIRINGSPEED;
|
||||
}
|
||||
Powerup.Duration -40;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1914,28 +1855,21 @@ class PowerInfiniteAmmo : Powerup
|
|||
{
|
||||
Powerup.Duration -30;
|
||||
}
|
||||
}
|
||||
|
||||
override void InitEffect()
|
||||
{
|
||||
Super.InitEffect();
|
||||
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Give the player infinite ammo
|
||||
Owner.player.cheats |= CF_INFINITEAMMO;
|
||||
}
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// InfiniteAmmo
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
override void EndEffect()
|
||||
class PowerReflection : Powerup
|
||||
{
|
||||
Default
|
||||
{
|
||||
Super.EndEffect();
|
||||
|
||||
// Nothing to do if there's no owner.
|
||||
if (Owner!= null && Owner.player != null)
|
||||
{
|
||||
// Take away the limitless ammo
|
||||
Owner.player.cheats &= ~CF_INFINITEAMMO;
|
||||
}
|
||||
Powerup.Duration -60;
|
||||
DamageFactor 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class MessageBoxMenu : Menu
|
|||
int mr2 = 170 + SmallFont.StringWidth(Stringtable.Localize("$TXT_NO"));
|
||||
mMouseRight = MAX(mr1, mr2);
|
||||
mParentMenu = parent;
|
||||
mMessage = SmallFont.BreakLines(message, 300);
|
||||
mMessage = SmallFont.BreakLines(Stringtable.Localize(message), 300);
|
||||
mMessageMode = messagemode;
|
||||
if (playsound)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue