Merge remote-tracking branch 'upstream/master' into truecolor

This commit is contained in:
Magnus Norddahl 2016-07-17 23:36:35 +02:00
commit 421cd2f403
43 changed files with 730 additions and 393 deletions

View file

@ -484,6 +484,9 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" ) set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" )
endif() endif()
if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set( CMAKE_CXX_FLAGS "-Wno-inconsistent-missing-override ${CMAKE_CXX_FLAGS}" )
endif()
set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_C_FLAGS}" ) set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_C_FLAGS}" )
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_CXX_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_CXX_FLAGS}" )
@ -511,6 +514,13 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
endif () endif ()
endif () endif ()
# With standard Apple tools -stdlib=libc++ needs to be specified in order to get
# C++11 support using SDKs 10.7 and 10.8.
if ( APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
set( CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}" )
set( CMAKE_EXE_LINKER_FLAGS "-stdlib=libc++ ${CMAKE_EXE_LINKER_FLAGS}" )
endif ()
# Remove extra warnings when using the official DirectX headers. # Remove extra warnings when using the official DirectX headers.
# Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, # Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid,
# which is a royal pain. The previous version I had been using was fine with them. # which is a royal pain. The previous version I had been using was fine with them.

View file

@ -407,9 +407,12 @@ enum ActorRenderFlag
RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types, not all implemented RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types, not all implemented
RF_FACESPRITE = 0x0000, // Face sprite RF_FACESPRITE = 0x0000, // Face sprite
RF_WALLSPRITE = 0x1000, // Wall sprite RF_WALLSPRITE = 0x1000, // Wall sprite
RF_FLOORSPRITE = 0x2000, // Floor sprite RF_FLATSPRITE = 0x2000, // Flat sprite
RF_VOXELSPRITE = 0x3000, // Voxel object RF_VOXELSPRITE = 0x3000, // Voxel object
RF_INVISIBLE = 0x8000, // Don't bother drawing this actor RF_INVISIBLE = 0x8000, // Don't bother drawing this actor
RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard
RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind.
RF_ROLLCENTER = 0x100000, // Rotate from the center of sprite instead of offsets
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting) RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting) RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)

View file

@ -16,7 +16,7 @@
#include <stdarg.h> #include <stdarg.h>
// the dec offsetof macro doesnt work very well... // the dec offsetof macro doesnt work very well...
#define myoffsetof(type,identifier) ((size_t)&((type *)1)->identifier - 1) #define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type))
int Q_filelength (FILE *f); int Q_filelength (FILE *f);
bool FileExists (const char *filename); bool FileExists (const char *filename);

View file

@ -532,7 +532,10 @@ public:
void TickPSprites(); void TickPSprites();
void DestroyPSprites(); void DestroyPSprites();
DPSprite *FindPSprite(int layer); DPSprite *FindPSprite(int layer);
DPSprite *GetPSprite(PSPLayers layer); // Used ONLY for compatibility with the old hardcoded layers. // Used ONLY for compatibility with the old hardcoded layers.
// Make sure that a state is properly set after calling this unless
// you are 100% sure the context already implies the layer exists.
DPSprite *GetPSprite(PSPLayers layer);
}; };
// Bookkeeping on players - state. // Bookkeeping on players - state.

View file

@ -1272,6 +1272,7 @@ void PFloat::WriteValue(FArchive &ar, const void *addr) const
{ {
ar.WriteByte(VAL_Float64); ar.WriteByte(VAL_Float64);
ar << doubleprecision; ar << doubleprecision;
return;
} }
} }
else else

View file

@ -334,7 +334,7 @@ struct mapthinghexen_t
SWORD z; SWORD z;
SWORD angle; SWORD angle;
SWORD type; SWORD type;
SWORD flags; WORD flags;
BYTE special; BYTE special;
BYTE args[5]; BYTE args[5];
}; };

View file

@ -728,13 +728,13 @@ void FArchive::WriteByte(BYTE val)
void FArchive::WriteInt16(WORD val) void FArchive::WriteInt16(WORD val)
{ {
WORD out = LittleShort(val); WORD out = SWAP_WORD(val);
m_File->Write(&out, 2); m_File->Write(&out, 2);
} }
void FArchive::WriteInt32(DWORD val) void FArchive::WriteInt32(DWORD val)
{ {
int out = LittleLong(val); int out = SWAP_DWORD(val);
m_File->Write(&out, 4); m_File->Write(&out, 4);
} }

View file

@ -1573,7 +1573,7 @@ void FParser::SF_FloorHeight(void)
sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest), sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest),
crush? 10:-1, crush? 10:-1,
(dest > sectors[i].CenterFloor()) ? 1 : -1, (dest > sectors[i].CenterFloor()) ? 1 : -1,
false) != EMoveResult::crushed) false) == EMoveResult::crushed)
{ {
returnval = 0; returnval = 0;
} }
@ -1662,7 +1662,7 @@ void FParser::SF_CeilingHeight(void)
sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest), sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest),
crush? 10:-1, crush? 10:-1,
(dest > sectors[i].CenterCeiling()) ? 1 : -1, (dest > sectors[i].CenterCeiling()) ? 1 : -1,
false) != EMoveResult::crushed) false) == EMoveResult::crushed)
{ {
returnval = 0; returnval = 0;
} }
@ -3473,12 +3473,7 @@ void FParser::SF_Resurrect()
mo->SetState(state); mo->SetState(state);
mo->Height = mo->GetDefault()->Height; mo->Height = mo->GetDefault()->Height;
mo->radius = mo->GetDefault()->radius; mo->radius = mo->GetDefault()->radius;
mo->flags = mo->GetDefault()->flags; mo->Revive();
mo->flags2 = mo->GetDefault()->flags2;
mo->flags3 = mo->GetDefault()->flags3;
mo->flags4 = mo->GetDefault()->flags4;
mo->flags5 = mo->GetDefault()->flags5;
mo->health = mo->GetDefault()->health;
mo->target = NULL; mo->target = NULL;
} }
} }
@ -3766,30 +3761,6 @@ void FParser::SF_SetCorona(void)
t_return.value.i = 0; t_return.value.i = 0;
} }
//==========================================================================
//
// new for GZDoom: Call a Hexen line special (deprecated, superseded by direct use)
//
//==========================================================================
void FParser::SF_Ls()
{
int args[5]={0,0,0,0,0};
int spc;
if (CheckArgs(1))
{
spc=intvalue(t_argv[0]);
for(int i=0;i<5;i++)
{
if (t_argc>=i+2) args[i]=intvalue(t_argv[i+1]);
}
if (spc>=0 && spc<256)
P_ExecuteSpecial(spc, NULL,Script->trigger,false, args[0],args[1],args[2],args[3],args[4]);
}
}
//========================================================================== //==========================================================================
// //
// new for GZDoom: Gets the levelnum // new for GZDoom: Gets the levelnum
@ -4024,17 +3995,6 @@ void FParser::SF_KillInSector()
} }
} }
//==========================================================================
//
// new for GZDoom: Sets a sector's type
//
//==========================================================================
void FParser::SF_SectorType(void)
{
// I don't think this was ever used publicly so I'm not going to bother fixing it.
}
//========================================================================== //==========================================================================
// //
// new for GZDoom: Sets a new line trigger type (Doom format!) // new for GZDoom: Sets a new line trigger type (Doom format!)
@ -4069,30 +4029,6 @@ void FParser::SF_SetLineTrigger()
} }
//==========================================================================
//
//
//
//==========================================================================
void FParser::SF_ChangeTag()
{
// Development garbage!
}
//==========================================================================
//
//
//
//==========================================================================
void FParser::SF_WallGlow()
{
// Development garbage!
}
//========================================================================== //==========================================================================
// //
// new for GZDoom: Call a Hexen line special // new for GZDoom: Call a Hexen line special
@ -4510,13 +4446,10 @@ void init_functions(void)
// new for GZDoom // new for GZDoom
gscr->NewFunction("spawnshot2", &FParser::SF_SpawnShot2); gscr->NewFunction("spawnshot2", &FParser::SF_SpawnShot2);
gscr->NewFunction("setcolor", &FParser::SF_SetColor); gscr->NewFunction("setcolor", &FParser::SF_SetColor);
gscr->NewFunction("sectortype", &FParser::SF_SectorType);
gscr->NewFunction("wallglow", &FParser::SF_WallGlow);
gscr->NewFunction("objradius", &FParser::SF_MobjRadius); gscr->NewFunction("objradius", &FParser::SF_MobjRadius);
gscr->NewFunction("objheight", &FParser::SF_MobjHeight); gscr->NewFunction("objheight", &FParser::SF_MobjHeight);
gscr->NewFunction("thingcount", &FParser::SF_ThingCount); gscr->NewFunction("thingcount", &FParser::SF_ThingCount);
gscr->NewFunction("killinsector", &FParser::SF_KillInSector); gscr->NewFunction("killinsector", &FParser::SF_KillInSector);
gscr->NewFunction("changetag", &FParser::SF_ChangeTag);
gscr->NewFunction("levelnum", &FParser::SF_LevelNum); gscr->NewFunction("levelnum", &FParser::SF_LevelNum);
// new inventory // new inventory
@ -4525,8 +4458,6 @@ void init_functions(void)
gscr->NewFunction("checkinventory", &FParser::SF_CheckInventory); gscr->NewFunction("checkinventory", &FParser::SF_CheckInventory);
gscr->NewFunction("setweapon", &FParser::SF_SetWeapon); gscr->NewFunction("setweapon", &FParser::SF_SetWeapon);
gscr->NewFunction("ls", &FParser::SF_Ls); // execute Hexen type line special
// Dummies - shut up warnings // Dummies - shut up warnings
gscr->NewFunction("setcorona", &FParser::SF_SetCorona); gscr->NewFunction("setcorona", &FParser::SF_SetCorona);
} }

View file

@ -147,7 +147,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
{ {
spit->special2 = 0; spit->special2 = 0;
} }
else if (fabs(spit->Vel.X) > fabs(spit->Vel.Y)) else if (fabs(spit->Vel.Y) > fabs(spit->Vel.X))
{ {
spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y); spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y);
} }

View file

@ -123,9 +123,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
void P_UpdateBeak (AActor *self) void P_UpdateBeak (AActor *self)
{ {
if (self->player != nullptr) DPSprite *pspr;
if (self->player != nullptr && (pspr = self->player->FindPSprite(PSP_WEAPON)) != nullptr)
{ {
self->player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + self->player->chickenPeck / 2; pspr->y = WEAPONTOP + self->player->chickenPeck / 2;
} }
} }

View file

@ -1128,12 +1128,27 @@ void APowerWeaponLevel2::InitEffect ()
assert (sister->SisterWeapon == weapon); assert (sister->SisterWeapon == weapon);
Owner->player->ReadyWeapon = sister;
if (weapon->GetReadyState() != sister->GetReadyState()) if (weapon->GetReadyState() != sister->GetReadyState())
{ {
Owner->player->ReadyWeapon = sister;
P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState()); P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState());
} }
else
{
DPSprite *psp = Owner->player->FindPSprite(PSP_WEAPON);
if (psp != nullptr && psp->GetCaller() == Owner->player->ReadyWeapon)
{
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
psp->SetCaller(sister);
Owner->player->ReadyWeapon = sister;
}
else
{
// Something went wrong. Initiate a regular weapon change.
Owner->player->PendingWeapon = sister;
}
}
} }
//=========================================================================== //===========================================================================

View file

@ -642,7 +642,18 @@ void AWeapon::EndPowerup ()
} }
else else
{ {
Owner->player->ReadyWeapon = SisterWeapon; DPSprite *psp = Owner->player->FindPSprite(PSP_WEAPON);
if (psp != nullptr && psp->GetCaller() == Owner->player->ReadyWeapon)
{
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
psp->SetCaller(SisterWeapon);
Owner->player->ReadyWeapon = SisterWeapon;
}
else
{
// Something went wrong. Initiate a regular weapon change.
Owner->player->PendingWeapon = SisterWeapon;
}
} }
} }
} }

View file

@ -3440,6 +3440,30 @@ class CommandIfInvulnerable : public SBarInfoNegatableFlowControl
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandIfWaterLevel : public SBarInfoNegatableFlowControl
{
public:
CommandIfWaterLevel(SBarInfo *script) : SBarInfoNegatableFlowControl(script)
{
}
void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
{
sc.MustGetToken(TK_IntConst);
value = sc.Number;
}
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{
SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
SetTruth(statusBar->CPlayer->mo->waterlevel >= value, block, statusBar);
}
protected:
int value;
};
////////////////////////////////////////////////////////////////////////////////
static const char *SBarInfoCommandNames[] = static const char *SBarInfoCommandNames[] =
{ {
"drawimage", "drawnumber", "drawswitchableimage", "drawimage", "drawnumber", "drawswitchableimage",
@ -3450,7 +3474,7 @@ static const char *SBarInfoCommandNames[] =
"isselected", "usesammo", "usessecondaryammo", "isselected", "usesammo", "usessecondaryammo",
"hasweaponpiece", "inventorybarnotvisible", "hasweaponpiece", "inventorybarnotvisible",
"weaponammo", "ininventory", "alpha", "ifhealth", "weaponammo", "ininventory", "alpha", "ifhealth",
"ifinvulnerable", "ifinvulnerable", "ifwaterlevel",
NULL NULL
}; };
@ -3464,7 +3488,7 @@ enum SBarInfoCommands
SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO, SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO,
SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE, SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE,
SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH,
SBARINFO_IFINVULNERABLE, SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL,
}; };
SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
@ -3499,6 +3523,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
case SBARINFO_ALPHA: return new CommandAlpha(script); case SBARINFO_ALPHA: return new CommandAlpha(script);
case SBARINFO_IFHEALTH: return new CommandIfHealth(script); case SBARINFO_IFHEALTH: return new CommandIfHealth(script);
case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script); case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script);
case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script);
} }
sc.ScriptError("Unknown command '%s'.\n", sc.String); sc.ScriptError("Unknown command '%s'.\n", sc.String);

View file

@ -81,6 +81,7 @@ CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD
CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD
CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference) CVAR (Int , hud_showlag, 0, CVAR_ARCHIVE); // Show input latency (maketic - gametic difference)
CVAR (Int, hud_ammo_order, 0, CVAR_ARCHIVE); // ammo image and text order
CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red CVAR (Int, hud_ammo_red, 25, CVAR_ARCHIVE) // ammo percent less than which status is red
CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green CVAR (Int, hud_ammo_yellow, 50, CVAR_ARCHIVE) // ammo percent less is yellow more green
CVAR (Int, hud_health_red, 25, CVAR_ARCHIVE) // health amount less than which status is red CVAR (Int, hud_health_red, 25, CVAR_ARCHIVE) // health amount less than which status is red
@ -586,9 +587,21 @@ static int DrawAmmo(player_t *CPlayer, int x, int y)
// ok, we got all ammo types. Now draw the list back to front (bottom to top) // ok, we got all ammo types. Now draw the list back to front (bottom to top)
int def_width = ConFont->StringWidth("000/000"); int def_width = ConFont->StringWidth("000/000");
x-=def_width;
int yadd = ConFont->GetHeight(); int yadd = ConFont->GetHeight();
int xtext = x - def_width;
int ximage = x;
if (hud_ammo_order > 0)
{
xtext -= 24;
ximage -= 20;
}
else
{
ximage -= def_width + 20;
}
for(i=orderedammos.Size()-1;i>=0;i--) for(i=orderedammos.Size()-1;i>=0;i--)
{ {
@ -613,8 +626,8 @@ static int DrawAmmo(player_t *CPlayer, int x, int y)
ammo < ( (maxammo * hud_ammo_red) / 100) ? CR_RED : ammo < ( (maxammo * hud_ammo_red) / 100) ? CR_RED :
ammo < ( (maxammo * hud_ammo_yellow) / 100) ? CR_GOLD : CR_GREEN ); ammo < ( (maxammo * hud_ammo_yellow) / 100) ? CR_GOLD : CR_GREEN );
DrawHudText(ConFont, fontcolor, buf, x-tex_width, y+yadd, trans); DrawHudText(ConFont, fontcolor, buf, xtext-tex_width, y+yadd, trans);
DrawImageToBox(TexMan[icon], x-20, y, 16, 8, trans); DrawImageToBox(TexMan[icon], ximage, y, 16, 8, trans);
y-=10; y-=10;
} }
return y; return y;

View file

@ -317,7 +317,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain)
int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; int anglespeed = tagManager.GetFirstSectorTag(sec) - 100;
double speed = (anglespeed % 10) / 16.; double speed = (anglespeed % 10) / 16.;
DAngle an = (anglespeed / 10) * (360 / 8.); DAngle an = (anglespeed / 10) * (360 / 8.);
self->VelFromAngle(an, speed); self->Thrust(an, speed);
} }
} }
return 0; return 0;
@ -352,22 +352,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns)
if (self->player != nullptr && self->player->mo == self) if (self->player != nullptr && self->player->mo == self)
{ {
FState *firehands = self->FindState("FireHands"); P_SetPsprite(self->player, PSP_STRIFEHANDS, self->FindState("FireHands"));
if (firehands != NULL)
{
DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS);
if (psp != nullptr)
{
psp->SetState(firehands);
psp->Flags &= PSPF_ADDWEAPON | PSPF_ADDBOB;
psp->y = WEAPONTOP;
}
self->player->ReadyWeapon = nullptr; self->player->ReadyWeapon = nullptr;
self->player->PendingWeapon = WP_NOCHANGE; self->player->PendingWeapon = WP_NOCHANGE;
self->player->playerstate = PST_LIVE; self->player->playerstate = PST_LIVE;
self->player->extralight = 3; self->player->extralight = 3;
}
} }
return 0; return 0;
} }
@ -388,14 +378,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer)
if (self->player != nullptr && self->player->mo == self) if (self->player != nullptr && self->player->mo == self)
{ {
self->player->playerstate = PST_DEAD;
DPSprite *psp; DPSprite *psp;
psp = self->player->GetPSprite(PSP_STRIFEHANDS); psp = self->player->GetPSprite(PSP_STRIFEHANDS);
FState *firehandslower = self->FindState("FireHandsLower"); FState *firehandslower = self->FindState("FireHandsLower");
FState *firehands = self->FindState("FireHands"); FState *firehands = self->FindState("FireHands");
if (firehandslower != NULL && firehands != NULL && firehands < firehandslower) FState *state = psp->GetState();
psp->SetState(psp->GetState() + (firehandslower - firehands));
if (state != nullptr && firehandslower != nullptr && firehands != nullptr && firehands < firehandslower)
{
self->player->playerstate = PST_DEAD;
psp->SetState(state + (firehandslower - firehands));
}
else if (state == nullptr)
{
psp->SetState(nullptr);
}
} }
return 0; return 0;
} }
@ -407,13 +405,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower)
if (self->player != nullptr) if (self->player != nullptr)
{ {
DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS); DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS);
if (psp->GetState() == nullptr)
{
psp->SetState(nullptr);
return 0;
}
psp->y += 9; psp->y += 9;
if (psp->y > WEAPONBOTTOM*2) if (psp->y > WEAPONBOTTOM*2)
{ {
psp->SetState(nullptr); psp->SetState(nullptr);
} }
if (self->player->extralight > 0) self->player->extralight--; if (self->player->extralight > 0) self->player->extralight--;
} }
return 0; return 0;
} }

View file

@ -306,7 +306,15 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
int y = sc.Number; int y = sc.Number;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
FListMenuItem *it = new FListMenuItemStaticText(x, y, sc.String, desc->mFont, desc->mFontColor, centered); FString label = sc.String;
EColorRange cr = desc->mFontColor;
if (sc.CheckString(","))
{
sc.MustGetString();
cr = V_FindFontColor(sc.String);
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated")) cr = desc->mFontColor;
}
FListMenuItem *it = new FListMenuItemStaticText(x, y, label, desc->mFont, cr, centered);
desc->mItems.Push(it); desc->mItems.Push(it);
} }
else if (sc.Compare("PatchItem")) else if (sc.Compare("PatchItem"))
@ -648,6 +656,21 @@ static void ParseOptionSettings(FScanner &sc)
// //
//============================================================================= //=============================================================================
static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc)
{
EColorRange cr = OptionSettings.mFontColor;
if (sc.CheckString(","))
{
sc.MustGetString();
cr = V_FindFontColor(sc.String);
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated") && isdigit(sc.String[0]))
{
if (strtol(sc.String, NULL, 0)) cr = OptionSettings.mFontColorHeader;
}
}
return cr;
}
static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
{ {
sc.MustGetStringName("{"); sc.MustGetStringName("{");
@ -784,12 +807,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
{ {
sc.MustGetString(); sc.MustGetString();
FString label = sc.String; FString label = sc.String;
bool cr = false; EColorRange cr = ParseOptionColor(sc, desc);
if (sc.CheckString(","))
{
sc.MustGetNumber();
cr = !!sc.Number;
}
FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr); FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr);
desc->mItems.Push(it); desc->mItems.Push(it);
} }
@ -803,12 +821,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
FName action = sc.String; FName action = sc.String;
bool cr = false; EColorRange cr = ParseOptionColor(sc, desc);
if (sc.CheckString(","))
{
sc.MustGetNumber();
cr = !!sc.Number;
}
FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr); FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr);
desc->mItems.Push(it); desc->mItems.Push(it);
} }

View file

@ -483,7 +483,13 @@ public:
FOptionMenuItemStaticText(const char *label, bool header) FOptionMenuItemStaticText(const char *label, bool header)
: FOptionMenuItem(label, NAME_None, true) : FOptionMenuItem(label, NAME_None, true)
{ {
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; mColor = header ? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
}
FOptionMenuItemStaticText(const char *label, EColorRange cr)
: FOptionMenuItem(label, NAME_None, true)
{
mColor = cr;
} }
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
@ -512,10 +518,10 @@ class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem
int mCurrent; int mCurrent;
public: public:
FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, bool header) FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, EColorRange cr)
: FOptionMenuItem(label, action, true) : FOptionMenuItem(label, action, true)
{ {
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; mColor = cr;
mAltText = label2; mAltText = label2;
mCurrent = 0; mCurrent = 0;
} }

View file

@ -5712,8 +5712,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
argCount > 11 ? ACSToDouble(args[11]) : 1.0, argCount > 11 ? ACSToDouble(args[11]) : 1.0,
argCount > 12 ? args[12] : 0, argCount > 12 ? args[12] : 0,
argCount > 13 ? args[13] : 0, argCount > 13 ? args[13] : 0,
argCount > 14 ? args[14] : 0, argCount > 14 ? ACSToDouble(args[14]) : 0,
argCount > 15 ? args[15] : 0); argCount > 15 ? ACSToDouble(args[15]) : 0);
} }
case ACSF_SetLineActivation: case ACSF_SetLineActivation:

View file

@ -688,14 +688,11 @@ void DAnimatedDoor::Tick ()
//============================================================================ //============================================================================
DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim)
: DMovingCeiling (sec) : DMovingCeiling (sec, false)
{ {
double topdist; double topdist;
FTextureID picnum; FTextureID picnum;
// The DMovingCeiling constructor automatically sets up an interpolation for us.
// Stop it, since the ceiling is moving instantly here.
StopInterpolation();
m_DoorAnim = anim; m_DoorAnim = anim;
m_Line1 = line; m_Line1 = line;

View file

@ -325,7 +325,8 @@ enum // P_LineAttack flags
{ {
LAF_ISMELEEATTACK = 1, LAF_ISMELEEATTACK = 1,
LAF_NORANDOMPUFFZ = 2, LAF_NORANDOMPUFFZ = 2,
LAF_NOIMPACTDECAL = 4 LAF_NOIMPACTDECAL = 4,
LAF_NOINTERACT = 8,
}; };
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);

View file

@ -4096,6 +4096,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata)
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage)
{ {
bool nointeract = !!(flags & LAF_NOINTERACT);
DVector3 direction; DVector3 direction;
double shootz; double shootz;
FTraceResults trace; FTraceResults trace;
@ -4185,26 +4186,32 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
} }
int tflags; int tflags;
if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky; if (nointeract || (puffDefaults && puffDefaults->flags6 & MF6_NOTRIGGER)) tflags = TRACE_NoSky;
else tflags = TRACE_NoSky | TRACE_Impact; else tflags = TRACE_NoSky | TRACE_Impact;
if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE, if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE,
ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData)) ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData))
{ // hit nothing { // hit nothing
if (puffDefaults == NULL) if (!nointeract && puffDefaults && puffDefaults->ActiveSound)
{
}
else if (puffDefaults->ActiveSound)
{ // Play miss sound { // Play miss sound
S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM); S_Sound(t1, CHAN_WEAPON, puffDefaults->ActiveSound, 1, ATTN_NORM);
} }
if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
// [MC] LAF_NOINTERACT guarantees puff spawning and returns it directly to the calling function.
// No damage caused, no sounds played, no blood splatters.
if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_ALWAYSPUFF))
{ // Spawn the puff anyway { // Spawn the puff anyway
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags); puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags);
if (nointeract)
{
return puff;
}
} }
else else
{ {
return NULL; return nullptr;
} }
} }
else else
@ -4212,12 +4219,17 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
if (trace.HitType != TRACE_HitActor) if (trace.HitType != TRACE_HitActor)
{ {
// position a bit closer for puffs // position a bit closer for puffs
if (trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky)) if (nointeract || trace.HitType != TRACE_HitWall || ((trace.Line->special != Line_Horizon) || spawnSky))
{ {
DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4); DVector2 pos = P_GetOffsetPosition(trace.HitPos.X, trace.HitPos.Y, -trace.HitVector.X * 4, -trace.HitVector.Y * 4);
puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget, puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget,
trace.SrcAngleFromTarget - 90, 0, puffFlags); trace.SrcAngleFromTarget - 90, 0, puffFlags);
puff->radius = 1/65536.; puff->radius = 1/65536.;
if (nointeract)
{
return puff;
}
} }
// [RH] Spawn a decal // [RH] Spawn a decal
@ -4255,14 +4267,6 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
} }
else else
{ {
bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) ||
(t1->player != NULL && t1->player->ReadyWeapon != NULL &&
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
bool axeBlood = (t1->player != NULL &&
t1->player->ReadyWeapon != NULL &&
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
// Hit a thing, so it could be either a puff or blood // Hit a thing, so it could be either a puff or blood
DVector3 bleedpos = trace.HitPos; DVector3 bleedpos = trace.HitPos;
// position a bit closer for puffs/blood if using compatibility mode. // position a bit closer for puffs/blood if using compatibility mode.
@ -4275,7 +4279,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
} }
// Spawn bullet puffs or blood spots, depending on target type. // Spawn bullet puffs or blood spots, depending on target type.
if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) || if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
(trace.Actor->flags & MF_NOBLOOD) || (trace.Actor->flags & MF_NOBLOOD) ||
(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) (trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
{ {
@ -4284,6 +4288,11 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
// We must pass the unreplaced puff type here // We must pass the unreplaced puff type here
puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor); puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor);
if (nointeract)
{
return puff;
}
} }
// Allow puffs to inflict poison damage, so that hitscans can poison, too. // Allow puffs to inflict poison damage, so that hitscans can poison, too.
@ -4320,6 +4329,14 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
} }
if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT)) if (!(puffDefaults != NULL && puffDefaults->flags3&MF3_BLOODLESSIMPACT))
{ {
bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) ||
(t1->player != nullptr && t1->player->ReadyWeapon != nullptr &&
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
bool axeBlood = (t1->player != nullptr &&
t1->player->ReadyWeapon != nullptr &&
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
if (!bloodsplatter && !axeBlood && if (!bloodsplatter && !axeBlood &&
!(trace.Actor->flags & MF_NOBLOOD) && !(trace.Actor->flags & MF_NOBLOOD) &&
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) !(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
@ -5466,14 +5483,25 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos)
} }
bool isgood = P_CheckPosition(thing, thing->Pos(), tm); bool isgood = P_CheckPosition(thing, thing->Pos(), tm);
thing->floorz = tm.floorz; if (!(thing->flags4 & MF4_ACTLIKEBRIDGE))
thing->ceilingz = tm.ceilingz; {
thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs thing->floorz = tm.floorz;
thing->floorpic = tm.floorpic; thing->ceilingz = tm.ceilingz;
thing->floorterrain = tm.floorterrain; thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs
thing->floorsector = tm.floorsector; thing->floorpic = tm.floorpic;
thing->ceilingpic = tm.ceilingpic; thing->floorterrain = tm.floorterrain;
thing->ceilingsector = tm.ceilingsector; thing->floorsector = tm.floorsector;
thing->ceilingpic = tm.ceilingpic;
thing->ceilingsector = tm.ceilingsector;
}
else
{
// Bridges only keep the info at their spawn position
// This is necessary to prevent moving sectors from altering the bridge's z-position.
// The bridge should remain at its current z, even if the sector change would cause
// floorz or ceilingz to be changed in a way that would make P_ZMovement adjust the bridge.
P_FindFloorCeiling(thing, FFCF_ONLYSPAWNPOS);
}
// restore the PASSMOBJ flag but leave the other flags alone. // restore the PASSMOBJ flag but leave the other flags alone.
thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2; thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2;

View file

@ -38,18 +38,17 @@ struct intercept_t
inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line)
{ {
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON; return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > EQUAL_EPSILON;
} }
inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line)
{ {
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON; return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON;
} }
inline int P_PointOnLineSide (double x, double y, const line_t *line) inline int P_PointOnLineSide (double x, double y, const line_t *line)
{ {
extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line); extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line);
return i_compatflags2 & COMPATF2_POINTONLINE return i_compatflags2 & COMPATF2_POINTONLINE
? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line); ? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line);
} }
@ -73,12 +72,12 @@ inline int P_PointOnLineSide(const DVector2 & p, const line_t *line)
inline int P_PointOnDivlineSide(double x, double y, const divline_t *line) inline int P_PointOnDivlineSide(double x, double y, const divline_t *line)
{ {
return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON; return (y - line->y) * line->dx + (line->x - x) * line->dy > EQUAL_EPSILON;
} }
inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line) inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line)
{ {
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON; return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > EQUAL_EPSILON;
} }
//========================================================================== //==========================================================================

View file

@ -216,15 +216,29 @@ DPSprite *player_t::GetPSprite(PSPLayers layer)
} }
// Always update the caller here in case we switched weapon // Always update the caller here in case we switched weapon
// or if the layer was being used by an inventory item before. // or if the layer was being used by something else before.
pspr->Caller = newcaller; pspr->Caller = newcaller;
if (newcaller != oldcaller) if (newcaller != oldcaller)
{ // Only change the flags if this layer was created now or if we updated the caller. { // Only reset stuff if this layer was created now or if it was being used before.
if (layer >= PSP_TARGETCENTER) if (layer >= PSP_TARGETCENTER)
{ // The targeter layers were affected by those. { // The targeter layers were affected by those.
pspr->Flags |= (PSPF_CVARFAST|PSPF_POWDOUBLE); pspr->Flags = (PSPF_CVARFAST|PSPF_POWDOUBLE);
} }
else
{
pspr->Flags = (PSPF_ADDWEAPON|PSPF_ADDBOB|PSPF_CVARFAST|PSPF_POWDOUBLE);
}
if (layer == PSP_STRIFEHANDS)
{
// Some of the old hacks rely on this layer coming from the FireHands state.
// This is the ONLY time a psprite's state is actually null.
pspr->State = nullptr;
pspr->y = WEAPONTOP;
}
pspr->oldx = pspr->x;
pspr->oldy = pspr->y;
} }
return pspr; return pspr;
@ -1071,9 +1085,8 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower)
} }
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ // Player is dead, so don't bring up a pending weapon { // Player is dead, so don't bring up a pending weapon
psp->y = WEAPONBOTTOM;
// Player is dead, so keep the weapon off screen // Player is dead, so keep the weapon off screen
P_SetPsprite(player, PSP_FLASH, nullptr);
psp->SetState(nullptr); psp->SetState(nullptr);
return 0; return 0;
} }
@ -1157,41 +1170,39 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ClearOverlays)
PARAM_INT_OPT(stop) { stop = 0; } PARAM_INT_OPT(stop) { stop = 0; }
PARAM_BOOL_OPT(safety) { safety = true; } PARAM_BOOL_OPT(safety) { safety = true; }
if (!self->player) if (self->player == nullptr)
ACTION_RETURN_INT(0); ACTION_RETURN_INT(0);
player_t *player = self->player;
if (!start && !stop) if (!start && !stop)
{ {
start = INT_MIN; start = INT_MIN;
stop = safety ? PSP_TARGETCENTER - 1 : INT_MAX; stop = safety ? PSP_TARGETCENTER - 1 : INT_MAX;
} }
int count = 0; unsigned int count = 0;
DPSprite *pspr = player->psprites; int id;
while (pspr != nullptr)
{
int id = pspr->GetID();
//Do not wipe out layer 0. Ever. for (DPSprite *pspr = self->player->psprites; pspr != nullptr; pspr = pspr->GetNext())
if (!id || id < start) {
id = pspr->GetID();
if (id < start || id == 0)
continue; continue;
if (id > stop) else if (id > stop)
break; break;
if (safety) if (safety)
{ {
if (id >= PSP_TARGETCENTER) if (id >= PSP_TARGETCENTER)
break; break;
else if ((id >= PSP_STRIFEHANDS && id <= PSP_WEAPON) || (id == PSP_FLASH)) else if (id == PSP_STRIFEHANDS || id == PSP_WEAPON || id == PSP_FLASH)
continue; continue;
} }
// [MC]Don't affect non-hardcoded layers unless it's really desired.
pspr->SetState(nullptr); pspr->SetState(nullptr);
count++; count++;
pspr = pspr->GetNext();
} }
ACTION_RETURN_INT(count); ACTION_RETURN_INT(count);
} }

View file

@ -42,7 +42,7 @@ class FArchive;
// drawn directly on the view screen, // drawn directly on the view screen,
// coordinates are given for a 320*200 view screen. // coordinates are given for a 320*200 view screen.
// //
enum PSPLayers // These are all called by the owner's ReadyWeapon. enum PSPLayers
{ {
PSP_STRIFEHANDS = -1, PSP_STRIFEHANDS = -1,
PSP_WEAPON = 1, PSP_WEAPON = 1,
@ -76,6 +76,7 @@ public:
FState* GetState() const { return State; } FState* GetState() const { return State; }
DPSprite* GetNext() { return Next; } DPSprite* GetNext() { return Next; }
AActor* GetCaller() { return Caller; } AActor* GetCaller() { return Caller; }
void SetCaller(AActor *newcaller) { Caller = newcaller; }
double x, y; double x, y;
double oldx, oldy; double oldx, oldy;

View file

@ -288,7 +288,7 @@ static void SetRotation(FLinePortal *port)
} }
else else
{ {
port->mFlags &= PORTF_POLYOBJ; port->mFlags &= ~PORTF_POLYOBJ;
} }
} }
else else

View file

@ -220,8 +220,8 @@ int OriginalMain(int argc, char** argv)
@interface ApplicationController : NSResponder @interface ApplicationController : NSResponder
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
<NSFileManagerDelegate> <NSApplicationDelegate>
#endif #endif
{ {
} }

View file

@ -1791,7 +1791,7 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t
// the textures a constant size across the surface's plane instead. // the textures a constant size across the surface's plane instead.
cosine = cos(planeang), sine = sin(planeang); cosine = cos(planeang), sine = sin(planeang);
m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sine, ViewPos.Y + yscale * cosine) - zeroheight; m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sine, ViewPos.Y + yscale * cosine) - zeroheight;
n[1] = pl->height.ZatPoint(ViewPos.X - xscale * cosine, ViewPos.Y + xscale * sine) - zeroheight; n[1] = -(pl->height.ZatPoint(ViewPos.X - xscale * cosine, ViewPos.Y + xscale * sine) - zeroheight);
plane_su = p ^ m; plane_su = p ^ m;
plane_sv = p ^ n; plane_sv = p ^ n;

View file

@ -329,13 +329,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance)
// NON-ACTION function to get the angle in degrees (normalized to -180..180) // NON-ACTION function to get the angle in degrees (normalized to -180..180)
// //
//========================================================================== //==========================================================================
enum GAFlags
{
GAF_RELATIVE = 1,
GAF_SWITCH = 1 << 1,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetAngle) DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetAngle)
{ {
if (numret > 0) if (numret > 0)
{ {
assert(ret != NULL); assert(ret != NULL);
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
PARAM_BOOL(relative); PARAM_INT(flags);
PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; } PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; }
AActor *target = COPY_AAPTR(self, ptr); AActor *target = COPY_AAPTR(self, ptr);
@ -346,9 +352,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetAngle)
} }
else else
{ {
DVector3 diff = self->Vec3To(target); DVector3 diff = (flags & GAF_SWITCH) ? target->Vec3To(self) : self->Vec3To(target);
DAngle angto = diff.Angle(); DAngle angto = diff.Angle();
if (relative) angto = deltaangle(self->Angles.Yaw, angto); DAngle yaw = (flags & GAF_SWITCH) ? target->Angles.Yaw : self->Angles.Yaw;
if (flags & GAF_RELATIVE) angto = deltaangle(yaw, angto);
ret->SetFloat(angto.Degrees); ret->SetFloat(angto.Degrees);
} }
return 1; return 1;
@ -1615,8 +1622,13 @@ enum CBA_Flags
CBAF_EXPLICITANGLE = 4, CBAF_EXPLICITANGLE = 4,
CBAF_NOPITCH = 8, CBAF_NOPITCH = 8,
CBAF_NORANDOMPUFFZ = 16, CBAF_NORANDOMPUFFZ = 16,
CBAF_PUFFTARGET = 32,
CBAF_PUFFMASTER = 64,
CBAF_PUFFTRACER = 128,
}; };
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba);
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
{ {
PARAM_SELF_PROLOGUE(AActor); PARAM_SELF_PROLOGUE(AActor);
@ -1628,6 +1640,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FLOAT_OPT (range) { range = 0; }
PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (flags) { flags = 0; }
PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; } PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; }
PARAM_CLASS_OPT (missile, AActor) { missile = nullptr; }
PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 32; }
PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; }
AActor *ref = COPY_AAPTR(self, ptr); AActor *ref = COPY_AAPTR(self, ptr);
@ -1672,7 +1687,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
if (!(flags & CBAF_NORANDOM)) if (!(flags & CBAF_NORANDOM))
damage *= ((pr_cabullet()%3)+1); damage *= ((pr_cabullet()%3)+1);
P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags); AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
if (missile != nullptr && pufftype != nullptr)
{
double x = Spawnofs_xy * angle.Cos();
double y = Spawnofs_xy * angle.Sin();
DVector3 pos = self->Pos();
self->SetXYZ(self->Vec3Offset(x, y, 0.));
AActor *proj = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + Spawnheight, missile, self->Angles.Yaw, 0, GetDefaultByType(missile)->Speed, self, false);
self->SetXYZ(pos);
if (proj)
{
bool temp = (puff == nullptr);
if (!puff)
{
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
}
if (puff)
{
AimBulletMissile(proj, puff, flags, temp, true);
}
}
}
} }
} }
return 0; return 0;
@ -1801,8 +1839,46 @@ enum FB_Flags
FBF_NOPITCH = 8, FBF_NOPITCH = 8,
FBF_NOFLASH = 16, FBF_NOFLASH = 16,
FBF_NORANDOMPUFFZ = 32, FBF_NORANDOMPUFFZ = 32,
FBF_PUFFTARGET = 64,
FBF_PUFFMASTER = 128,
FBF_PUFFTRACER = 256,
}; };
static void AimBulletMissile(AActor *proj, AActor *puff, int flags, bool temp, bool cba)
{
if (proj && puff)
{
if (proj)
{
// FAF_BOTTOM = 1
// Aim for the base of the puff as that's where blood puffs will spawn... roughly.
A_Face(proj, puff, 0., 0., 0., 0., 1);
proj->Vel3DFromAngle(-proj->Angles.Pitch, proj->Speed);
if (!temp)
{
if (cba)
{
if (flags & CBAF_PUFFTARGET) proj->target = puff;
if (flags & CBAF_PUFFMASTER) proj->master = puff;
if (flags & CBAF_PUFFTRACER) proj->tracer = puff;
}
else
{
if (flags & FBF_PUFFTARGET) proj->target = puff;
if (flags & FBF_PUFFMASTER) proj->master = puff;
if (flags & FBF_PUFFTRACER) proj->tracer = puff;
}
}
}
}
if (puff && temp)
{
puff->Destroy();
}
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
@ -1810,9 +1886,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
PARAM_ANGLE (spread_z); PARAM_ANGLE (spread_z);
PARAM_INT (numbullets); PARAM_INT (numbullets);
PARAM_INT (damageperbullet); PARAM_INT (damageperbullet);
PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = nullptr; }
PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; } PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; }
PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FLOAT_OPT (range) { range = 0; }
PARAM_CLASS_OPT (missile, AActor) { missile = nullptr; }
PARAM_FLOAT_OPT (Spawnheight) { Spawnheight = 0; }
PARAM_FLOAT_OPT (Spawnofs_xy) { Spawnofs_xy = 0; }
if (!self->player) return 0; if (!self->player) return 0;
@ -1851,7 +1930,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
if (!(flags & FBF_NORANDOM)) if (!(flags & FBF_NORANDOM))
damage *= ((pr_cwbullet()%3)+1); damage *= ((pr_cwbullet()%3)+1);
P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags); AActor *puff = P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
if (missile != nullptr)
{
bool temp = false;
DAngle ang = self->Angles.Yaw - 90;
DVector2 ofs = ang.ToVector(Spawnofs_xy);
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, bangle, nullptr, nullptr, false, true);
if (proj)
{
if (!puff)
{
temp = true;
puff = P_LineAttack(self, bangle, range, bslope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
}
AimBulletMissile(proj, puff, flags, temp, false);
}
}
} }
else else
{ {
@ -1878,7 +1974,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
if (!(flags & FBF_NORANDOM)) if (!(flags & FBF_NORANDOM))
damage *= ((pr_cwbullet()%3)+1); damage *= ((pr_cwbullet()%3)+1);
P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags); AActor *puff = P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
if (missile != nullptr)
{
bool temp = false;
DAngle ang = self->Angles.Yaw - 90;
DVector2 ofs = ang.ToVector(Spawnofs_xy);
AActor *proj = P_SpawnPlayerMissile(self, ofs.X, ofs.Y, Spawnheight, missile, angle, nullptr, nullptr, false, true);
if (proj)
{
if (!puff)
{
temp = true;
puff = P_LineAttack(self, angle, range, slope, 0, NAME_Hitscan, pufftype, laflags | LAF_NOINTERACT);
}
AimBulletMissile(proj, puff, flags, temp, false);
}
}
} }
} }
return 0; return 0;
@ -5669,7 +5782,9 @@ enum RadiusGiveFlags
RGF_MONSTERS | RGF_MONSTERS |
RGF_OBJECTS | RGF_OBJECTS |
RGF_VOODOO | RGF_VOODOO |
RGF_CORPSES | RGF_MISSILES, RGF_CORPSES |
RGF_MISSILES |
RGF_ITEMS,
}; };
static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, double distance, int flags, PClassActor *filter, FName species, double mindist) static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amount, double distance, int flags, PClassActor *filter, FName species, double mindist)
@ -7068,3 +7183,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection)
} }
ACTION_RETURN_BOOL(true); ACTION_RETURN_BOOL(true);
} }

View file

@ -265,6 +265,12 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags), DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags),
DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags), DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags),
DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags), DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags),
DEFINE_FLAG(RF, ROLLSPRITE, AActor, renderflags), // [marrub] roll the sprite billboard
// [fgsfds] Flat sprites
DEFINE_FLAG(RF, FLATSPRITE, AActor, renderflags),
DEFINE_FLAG(RF, WALLSPRITE, AActor, renderflags),
DEFINE_FLAG(RF, DONTFLIP, AActor, renderflags),
DEFINE_FLAG(RF, ROLLCENTER, AActor, renderflags),
// Bounce flags // Bounce flags
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),

View file

@ -331,11 +331,11 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
} }
else if (sc.CheckToken(TK_True)) else if (sc.CheckToken(TK_True))
{ {
return new FxConstant(1, scpos); return new FxConstant(true, scpos);
} }
else if (sc.CheckToken(TK_False)) else if (sc.CheckToken(TK_False))
{ {
return new FxConstant(0, scpos); return new FxConstant(false, scpos);
} }
else if (sc.CheckToken(TK_IntConst)) else if (sc.CheckToken(TK_IntConst))
{ {

View file

@ -203,7 +203,6 @@ protected:
public: public:
virtual ~FxExpression() {} virtual ~FxExpression() {}
virtual FxExpression *Resolve(FCompileContext &ctx); virtual FxExpression *Resolve(FCompileContext &ctx);
FxExpression *ResolveAsBoolean(FCompileContext &ctx);
virtual bool isConstant() const; virtual bool isConstant() const;
virtual void RequestAddress(); virtual void RequestAddress();
@ -280,6 +279,13 @@ class FxConstant : public FxExpression
ExpVal value; ExpVal value;
public: public:
FxConstant(bool val, const FScriptPosition &pos) : FxExpression(pos)
{
ValueType = value.Type = TypeBool;
value.Int = val;
isresolved = true;
}
FxConstant(int val, const FScriptPosition &pos) : FxExpression(pos) FxConstant(int val, const FScriptPosition &pos) : FxExpression(pos)
{ {
ValueType = value.Type = TypeSInt32; ValueType = value.Type = TypeSInt32;
@ -358,6 +364,19 @@ public:
// //
//========================================================================== //==========================================================================
class FxBoolCast : public FxExpression
{
FxExpression *basex;
public:
FxBoolCast(FxExpression *x);
~FxBoolCast();
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
};
class FxIntCast : public FxExpression class FxIntCast : public FxExpression
{ {
FxExpression *basex; FxExpression *basex;
@ -384,18 +403,6 @@ public:
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
class FxCastStateToBool : public FxExpression
{
FxExpression *basex;
public:
FxCastStateToBool(FxExpression *x);
~FxCastStateToBool();
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
};
//========================================================================== //==========================================================================
// //
// FxSign // FxSign

View file

@ -177,38 +177,6 @@ FxExpression *FxExpression::Resolve(FCompileContext &ctx)
return this; return this;
} }
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxExpression::ResolveAsBoolean(FCompileContext &ctx)
{
///FIXME: Use an actual boolean type
FxExpression *x = Resolve(ctx);
if (x != NULL)
{
if (x->ValueType->GetRegType() == REGT_INT)
{
x->ValueType = TypeSInt32;
}
else if (x->ValueType == TypeState)
{
x = new FxCastStateToBool(x);
x = x->Resolve(ctx);
}
else
{
ScriptPosition.Message(MSG_ERROR, "Not an integral type");
delete this;
return NULL;
}
}
return x;
}
//========================================================================== //==========================================================================
// //
// //
@ -327,6 +295,104 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build)
// //
//========================================================================== //==========================================================================
FxBoolCast::FxBoolCast(FxExpression *x)
: FxExpression(x->ScriptPosition)
{
basex = x;
ValueType = TypeBool;
}
//==========================================================================
//
//
//
//==========================================================================
FxBoolCast::~FxBoolCast()
{
SAFE_DELETE(basex);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxBoolCast::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(basex, ctx);
if (basex->ValueType == TypeBool)
{
FxExpression *x = basex;
basex = nullptr;
delete this;
return x;
}
else if (basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER)
{
if (basex->isConstant())
{
assert(basex->ValueType != TypeState && "We shouldn't be able to generate a constant state ref");
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
FxExpression *x = new FxConstant(constval.GetBool(), ScriptPosition);
delete this;
return x;
}
return this;
}
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
delete this;
return nullptr;
}
//==========================================================================
//
//
//
//==========================================================================
ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
{
ExpEmit from = basex->Emit(build);
assert(!from.Konst);
assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER);
ExpEmit to(build, REGT_INT);
from.Free(build);
// Preload result with 0.
build->Emit(OP_LI, to.RegNum, 0);
// Check source against 0.
if (from.RegType == REGT_INT)
{
build->Emit(OP_EQ_R, 1, from.RegNum, to.RegNum);
}
else if (from.RegType == REGT_FLOAT)
{
build->Emit(OP_EQF_K, 1, from.RegNum, build->GetConstantFloat(0.));
}
else if (from.RegNum == REGT_POINTER)
{
build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
}
build->Emit(OP_JMP, 1);
// Reload result with 1 if the comparison fell through.
build->Emit(OP_LI, to.RegNum, 1);
return to;
}
//==========================================================================
//
//
//
//==========================================================================
FxIntCast::FxIntCast(FxExpression *x) FxIntCast::FxIntCast(FxExpression *x)
: FxExpression(x->ScriptPosition) : FxExpression(x->ScriptPosition)
{ {
@ -504,67 +570,6 @@ ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build)
// //
//========================================================================== //==========================================================================
FxCastStateToBool::FxCastStateToBool(FxExpression *x)
: FxExpression(x->ScriptPosition)
{
basex = x;
ValueType = TypeSInt32;
}
//==========================================================================
//
//
//
//==========================================================================
FxCastStateToBool::~FxCastStateToBool()
{
SAFE_DELETE(basex);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxCastStateToBool::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(basex, ctx);
assert(basex->ValueType == TypeState);
assert(!basex->isConstant() && "We shouldn't be able to generate a constant state ref");
return this;
}
//==========================================================================
//
//
//
//==========================================================================
ExpEmit FxCastStateToBool::Emit(VMFunctionBuilder *build)
{
ExpEmit from = basex->Emit(build);
assert(from.RegType == REGT_POINTER);
from.Free(build);
ExpEmit to(build, REGT_INT);
// If from is NULL, produce 0. Otherwise, produce 1.
build->Emit(OP_LI, to.RegNum, 0);
build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(NULL, ATAG_GENERIC));
build->Emit(OP_JMP, 1);
build->Emit(OP_LI, to.RegNum, 1);
return to;
}
//==========================================================================
//
//
//
//==========================================================================
FxPlusSign::FxPlusSign(FxExpression *operand) FxPlusSign::FxPlusSign(FxExpression *operand)
: FxExpression(operand->ScriptPosition) : FxExpression(operand->ScriptPosition)
{ {
@ -765,10 +770,9 @@ FxExpression *FxUnaryNotBitwise::Resolve(FCompileContext& ctx)
ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build) ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build)
{ {
assert(ValueType == Operand->ValueType); assert(Operand->ValueType->GetRegType() == REGT_INT);
assert(ValueType == TypeSInt32);
ExpEmit from = Operand->Emit(build); ExpEmit from = Operand->Emit(build);
assert(from.Konst == 0); assert(!from.Konst);
// Do it in-place. // Do it in-place.
build->Emit(OP_NOT, from.RegNum, from.RegNum, 0); build->Emit(OP_NOT, from.RegNum, from.RegNum, 0);
return from; return from;
@ -806,33 +810,23 @@ FxUnaryNotBoolean::~FxUnaryNotBoolean()
FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx)
{ {
CHECKRESOLVED(); CHECKRESOLVED();
if (Operand) SAFE_RESOLVE(Operand, ctx);
if (Operand->ValueType != TypeBool)
{ {
Operand = Operand->ResolveAsBoolean(ctx); Operand = new FxBoolCast(Operand);
} SAFE_RESOLVE(Operand, ctx);
if (!Operand)
{
delete this;
return NULL;
} }
if (Operand->IsNumeric() || Operand->IsPointer()) if (Operand->isConstant())
{ {
if (Operand->isConstant()) bool result = !static_cast<FxConstant *>(Operand)->GetValue().GetBool();
{ FxExpression *e = new FxConstant(result, ScriptPosition);
bool result = !static_cast<FxConstant *>(Operand)->GetValue().GetBool();
FxExpression *e = new FxConstant(result, ScriptPosition);
delete this;
return e;
}
}
else
{
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
delete this; delete this;
return NULL; return e;
} }
ValueType = TypeSInt32;
ValueType = TypeBool;
return this; return this;
} }
@ -844,32 +838,14 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx)
ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build) ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build)
{ {
assert(Operand->ValueType == ValueType);
assert(ValueType == TypeBool);
ExpEmit from = Operand->Emit(build); ExpEmit from = Operand->Emit(build);
assert(!from.Konst); assert(!from.Konst);
ExpEmit to(build, REGT_INT); // ~x & 1
from.Free(build); build->Emit(OP_NOT, from.RegNum, from.RegNum, 0);
build->Emit(OP_AND_RK, from.RegNum, from.RegNum, build->GetConstantInt(1));
// Preload result with 0. return from;
build->Emit(OP_LI, to.RegNum, 0, 0);
// Check source against 0.
if (from.RegType == REGT_INT)
{
build->Emit(OP_EQ_R, 0, from.RegNum, to.RegNum);
}
else if (from.RegType == REGT_FLOAT)
{
build->Emit(OP_EQF_K, 0, from.RegNum, build->GetConstantFloat(0));
}
else if (from.RegNum == REGT_POINTER)
{
build->Emit(OP_EQA_K, 0, from.RegNum, build->GetConstantAddress(NULL, ATAG_GENERIC));
}
build->Emit(OP_JMP, 1);
// Reload result with 1 if the comparison fell through.
build->Emit(OP_LI, to.RegNum, 1);
return to;
} }
//========================================================================== //==========================================================================
@ -914,6 +890,10 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric)
return false; return false;
} }
if (left->ValueType == TypeBool && right->ValueType == TypeBool)
{
ValueType = TypeBool;
}
if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT) if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT)
{ {
ValueType = TypeSInt32; ValueType = TypeSInt32;
@ -1276,7 +1256,7 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
return e; return e;
} }
Promote(ctx); Promote(ctx);
ValueType = TypeSInt32; ValueType = TypeBool;
return this; return this;
} }
@ -1327,7 +1307,7 @@ ExpEmit FxCompareRel::Emit(VMFunctionBuilder *build)
op1.Free(build); op1.Free(build);
} }
// See FxUnaryNotBoolean for comments, since it's the same thing. // See FxBoolCast for comments, since it's the same thing.
build->Emit(OP_LI, to.RegNum, 0, 0); build->Emit(OP_LI, to.RegNum, 0, 0);
build->Emit(instr, check, op1.RegNum, op2.RegNum); build->Emit(instr, check, op1.RegNum, op2.RegNum);
build->Emit(OP_JMP, 1); build->Emit(OP_JMP, 1);
@ -1392,7 +1372,7 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx)
return e; return e;
} }
Promote(ctx); Promote(ctx);
ValueType = TypeSInt32; ValueType = TypeBool;
return this; return this;
} }
@ -1600,7 +1580,7 @@ FxBinaryLogical::FxBinaryLogical(int o, FxExpression *l, FxExpression *r)
Operator=o; Operator=o;
left=l; left=l;
right=r; right=r;
ValueType = TypeSInt32; ValueType = TypeBool;
} }
//========================================================================== //==========================================================================
@ -1624,16 +1604,22 @@ FxBinaryLogical::~FxBinaryLogical()
FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
{ {
CHECKRESOLVED(); CHECKRESOLVED();
if (left) left = left->ResolveAsBoolean(ctx); RESOLVE(left, ctx);
if (right) right = right->ResolveAsBoolean(ctx); RESOLVE(right, ctx);
if (!left || !right) ABORT(right && left);
if (left->ValueType != TypeBool)
{ {
delete this; left = new FxBoolCast(left);
return NULL; SAFE_RESOLVE(left, ctx);
}
if (right->ValueType != TypeBool)
{
right = new FxBoolCast(right);
SAFE_RESOLVE(right, ctx);
} }
int b_left=-1, b_right=-1; int b_left=-1, b_right=-1;
if (left->isConstant()) b_left = static_cast<FxConstant *>(left)->GetValue().GetBool(); if (left->isConstant()) b_left = static_cast<FxConstant *>(left)->GetValue().GetBool();
if (right->isConstant()) b_right = static_cast<FxConstant *>(right)->GetValue().GetBool(); if (right->isConstant()) b_right = static_cast<FxConstant *>(right)->GetValue().GetBool();
@ -1643,13 +1629,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
{ {
if (b_left==0 || b_right==0) if (b_left==0 || b_right==0)
{ {
FxExpression *x = new FxConstant(0, ScriptPosition); FxExpression *x = new FxConstant(true, ScriptPosition);
delete this; delete this;
return x; return x;
} }
else if (b_left==1 && b_right==1) else if (b_left==1 && b_right==1)
{ {
FxExpression *x = new FxConstant(1, ScriptPosition); FxExpression *x = new FxConstant(false, ScriptPosition);
delete this; delete this;
return x; return x;
} }
@ -1672,13 +1658,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
{ {
if (b_left==1 || b_right==1) if (b_left==1 || b_right==1)
{ {
FxExpression *x = new FxConstant(1, ScriptPosition); FxExpression *x = new FxConstant(true, ScriptPosition);
delete this; delete this;
return x; return x;
} }
if (b_left==0 && b_right==0) if (b_left==0 && b_right==0)
{ {
FxExpression *x = new FxConstant(0, ScriptPosition); FxExpression *x = new FxConstant(false, ScriptPosition);
delete this; delete this;
return x; return x;
} }
@ -1697,14 +1683,6 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
return x; return x;
} }
} }
if (left->ValueType->GetRegType() != REGT_INT)
{
left = new FxIntCast(left);
}
if (right->ValueType->GetRegType() != REGT_INT)
{
right = new FxIntCast(right);
}
return this; return this;
} }
@ -1804,17 +1782,25 @@ FxConditional::~FxConditional()
FxExpression *FxConditional::Resolve(FCompileContext& ctx) FxExpression *FxConditional::Resolve(FCompileContext& ctx)
{ {
CHECKRESOLVED(); CHECKRESOLVED();
if (condition) condition = condition->ResolveAsBoolean(ctx); RESOLVE(condition, ctx);
RESOLVE(truex, ctx); RESOLVE(truex, ctx);
RESOLVE(falsex, ctx); RESOLVE(falsex, ctx);
ABORT(condition && truex && falsex); ABORT(condition && truex && falsex);
if (truex->ValueType->GetRegType() == REGT_INT && falsex->ValueType->GetRegType() == REGT_INT) if (truex->ValueType == TypeBool && falsex->ValueType == TypeBool)
ValueType = TypeBool;
else if (truex->ValueType->GetRegType() == REGT_INT && falsex->ValueType->GetRegType() == REGT_INT)
ValueType = TypeSInt32; ValueType = TypeSInt32;
else if (truex->IsNumeric() && falsex->IsNumeric()) else if (truex->IsNumeric() && falsex->IsNumeric())
ValueType = TypeFloat64; ValueType = TypeFloat64;
//else if (truex->ValueType != falsex->ValueType) //else if (truex->ValueType != falsex->ValueType)
if (condition->ValueType != TypeBool)
{
condition = new FxBoolCast(condition);
SAFE_RESOLVE(condition, ctx);
}
if (condition->isConstant()) if (condition->isConstant())
{ {
ExpVal condval = static_cast<FxConstant *>(condition)->GetValue(); ExpVal condval = static_cast<FxConstant *>(condition)->GetValue();
@ -1852,6 +1838,7 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx)
ExpEmit FxConditional::Emit(VMFunctionBuilder *build) ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
{ {
size_t truejump, falsejump;
ExpEmit out; ExpEmit out;
// The true and false expressions ought to be assigned to the // The true and false expressions ought to be assigned to the
@ -1862,7 +1849,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
// Test condition. // Test condition.
build->Emit(OP_EQ_K, 1, cond.RegNum, build->GetConstantInt(0)); build->Emit(OP_EQ_K, 1, cond.RegNum, build->GetConstantInt(0));
size_t patchspot = build->Emit(OP_JMP, 0); falsejump = build->Emit(OP_JMP, 0);
// Evaluate true expression. // Evaluate true expression.
if (truex->isConstant() && truex->ValueType->GetRegType() == REGT_INT) if (truex->isConstant() && truex->ValueType->GetRegType() == REGT_INT)
@ -1886,9 +1873,11 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
out = trueop; out = trueop;
} }
} }
// Make sure to skip the false path.
truejump = build->Emit(OP_JMP, 0);
// Evaluate false expression. // Evaluate false expression.
build->BackpatchToHere(patchspot); build->BackpatchToHere(falsejump);
if (falsex->isConstant() && falsex->ValueType->GetRegType() == REGT_INT) if (falsex->isConstant() && falsex->ValueType->GetRegType() == REGT_INT)
{ {
build->EmitLoadInt(out.RegNum, static_cast<FxConstant *>(falsex)->GetValue().GetInt()); build->EmitLoadInt(out.RegNum, static_cast<FxConstant *>(falsex)->GetValue().GetInt());
@ -1918,6 +1907,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
} }
} }
} }
build->BackpatchToHere(truejump);
return out; return out;
} }
@ -3735,23 +3725,32 @@ FxIfStatement::~FxIfStatement()
FxExpression *FxIfStatement::Resolve(FCompileContext &ctx) FxExpression *FxIfStatement::Resolve(FCompileContext &ctx)
{ {
CHECKRESOLVED(); CHECKRESOLVED();
if (WhenTrue == NULL && WhenFalse == NULL)
if (WhenTrue == nullptr && WhenFalse == nullptr)
{ // We don't do anything either way, so disappear { // We don't do anything either way, so disappear
delete this; delete this;
return NULL; return nullptr;
} }
Condition = Condition->ResolveAsBoolean(ctx);
ABORT(Condition); SAFE_RESOLVE(Condition, ctx);
if (WhenTrue != NULL)
if (Condition->ValueType != TypeBool)
{
Condition = new FxBoolCast(Condition);
SAFE_RESOLVE(Condition, ctx);
}
if (WhenTrue != nullptr)
{ {
WhenTrue = WhenTrue->Resolve(ctx); WhenTrue = WhenTrue->Resolve(ctx);
ABORT(WhenTrue); ABORT(WhenTrue);
} }
if (WhenFalse != NULL) if (WhenFalse != nullptr)
{ {
WhenFalse = WhenFalse->Resolve(ctx); WhenFalse = WhenFalse->Resolve(ctx);
ABORT(WhenFalse); ABORT(WhenFalse);
} }
ValueType = TypeVoid; ValueType = TypeVoid;
if (Condition->isConstant()) if (Condition->isConstant())
@ -3766,6 +3765,7 @@ FxExpression *FxIfStatement::Resolve(FCompileContext &ctx)
delete this; delete this;
return e; return e;
} }
return this; return this;
} }

View file

@ -77,7 +77,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
sc.MustGetString(); sc.MustGetString();
x = new FxConstant(FSoundID(sc.String), sc); x = new FxConstant(FSoundID(sc.String), sc);
} }
else if (type == TypeSInt32 || type == TypeFloat64) else if (type == TypeBool || type == TypeSInt32 || type == TypeFloat64)
{ {
x = ParseExpression (sc, cls, constant); x = ParseExpression (sc, cls, constant);
if (constant && !x->isConstant()) if (constant && !x->isConstant())
@ -85,8 +85,12 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
sc.ScriptMessage("Default parameter must be constant."); sc.ScriptMessage("Default parameter must be constant.");
FScriptPosition::ErrorCounter++; FScriptPosition::ErrorCounter++;
} }
// Do automatic coercion between ints and floats. // Do automatic coercion between bools, ints and floats.
if (type == TypeSInt32) if (type == TypeBool)
{
x = new FxBoolCast(x);
}
else if (type == TypeSInt32)
{ {
x = new FxIntCast(x); x = new FxIntCast(x);
} }
@ -306,6 +310,9 @@ static void ParseArgListDef(FScanner &sc, PClassActor *cls,
switch (sc.TokenType) switch (sc.TokenType)
{ {
case TK_Bool: case TK_Bool:
type = TypeBool;
break;
case TK_Int: case TK_Int:
type = TypeSInt32; type = TypeSInt32;
break; break;
@ -477,8 +484,11 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls)
sc.MustGetAnyToken(); sc.MustGetAnyToken();
switch (sc.TokenType) switch (sc.TokenType)
{ {
case TK_Int:
case TK_Bool: case TK_Bool:
rets.Push(TypeBool);
break;
case TK_Int:
rets.Push(TypeSInt32); rets.Push(TypeSInt32);
break; break;
@ -1064,7 +1074,11 @@ static void ParseActionDef (FScanner &sc, PClassActor *cls)
// check for a return value // check for a return value
do do
{ {
if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Bool)) if (sc.CheckToken(TK_Bool))
{
rets.Push(TypeBool);
}
else if (sc.CheckToken(TK_Int))
{ {
rets.Push(TypeSInt32); rets.Push(TypeSInt32);
} }

View file

@ -1,6 +1,7 @@
#library "strfhelp"
#include "zcommon.acs" #include "zcommon.acs"
#library "strfhelp"
#define VDOORSPEED 16 #define VDOORSPEED 16
#define VDOORWAIT 150 #define VDOORWAIT 150
@ -69,6 +70,7 @@ script << 0 >> (int type, int tag)
case 230: case 230:
i = GetLineRowOffset() & 31; i = GetLineRowOffset() & 31;
if (i == 0) break;
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
{ {
Door_Open (tag, VDOORSPEED); Door_Open (tag, VDOORSPEED);
@ -78,6 +80,7 @@ script << 0 >> (int type, int tag)
case 227: case 227:
i = GetLineRowOffset() & 31; i = GetLineRowOffset() & 31;
if (i == 0) break;
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
{ {
Door_Close (tag, VDOORSPEED); Door_Close (tag, VDOORSPEED);
@ -126,6 +129,7 @@ script << 0 >> (int type, int tag)
case 193: case 193:
i = GetLineRowOffset() & 31; i = GetLineRowOffset() & 31;
if (i == 0) break;
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
{ {
Floor_LowerToLowest (tag, 8); Floor_LowerToLowest (tag, 8);
@ -158,6 +162,7 @@ script << 0 >> (int type, int tag)
case 187: case 187:
i = GetLineRowOffset() & 31; i = GetLineRowOffset() & 31;
if (i == 0) break;
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
{ {
ClearForceField (tag); ClearForceField (tag);
@ -203,6 +208,7 @@ script << 0 >> (int type, int tag)
case 216: case 216:
i = GetLineRowOffset() & 31; i = GetLineRowOffset() & 31;
if (i == 0) break;
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
{ {
Door_Raise (tag, VDOORSPEED, VDOORWAIT); Door_Raise (tag, VDOORSPEED, VDOORWAIT);

View file

@ -34,15 +34,14 @@ ACTOR Actor native //: Thinker
DefThreshold 100 DefThreshold 100
BloodType "Blood", "BloodSplatter", "AxeBlood" BloodType "Blood", "BloodSplatter", "AxeBlood"
ExplosionDamage 128 ExplosionDamage 128
MissileHeight 32 MissileHeight 32
// Functions // Functions
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false); native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
native bool IsPointerEqual(int ptr_select1, int ptr_select2); native bool IsPointerEqual(int ptr_select1, int ptr_select2);
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT); native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
native float GetDistance(bool checkz, int ptr = AAPTR_DEFAULT); native float GetDistance(bool checkz, int ptr = AAPTR_DEFAULT);
native float GetAngle(bool relative, int ptr = AAPTR_DEFAULT); native float GetAngle(int flags, int ptr = AAPTR_DEFAULT);
native float GetZAt(float px = 0, float py = 0, float angle = 0, int flags = 0, int pick_pointer = AAPTR_DEFAULT); native float GetZAt(float px = 0, float py = 0, float angle = 0, int flags = 0, int pick_pointer = AAPTR_DEFAULT);
native int GetSpawnHealth(); native int GetSpawnHealth();
native int GetGibHealth(); native int GetGibHealth();
@ -190,7 +189,7 @@ ACTOR Actor native //: Thinker
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
native state A_Jump(int chance = 256, state label, ...); native state A_Jump(int chance = 256, state label, ...);
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET); native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0); native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT); native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
native state A_JumpIfCloser(float distance, state label, bool noz = false); native state A_JumpIfCloser(float distance, state label, bool noz = false);

View file

@ -38,6 +38,9 @@ const int CBAF_NORANDOM = 2;
const int CBAF_EXPLICITANGLE = 4; const int CBAF_EXPLICITANGLE = 4;
const int CBAF_NOPITCH = 8; const int CBAF_NOPITCH = 8;
const int CBAF_NORANDOMPUFFZ = 16; const int CBAF_NORANDOMPUFFZ = 16;
const int CBAF_PUFFTARGET = 32;
const int CBAF_PUFFMASTER = 64;
const int CBAF_PUFFTRACER = 128;
// Flags for A_GunFlash // Flags for A_GunFlash
const int GFF_NOEXTCHANGE = 1; const int GFF_NOEXTCHANGE = 1;
@ -210,6 +213,9 @@ const int CPF_STEALARMOR = 32;
const int FPF_AIMATANGLE = 1; const int FPF_AIMATANGLE = 1;
const int FPF_TRANSFERTRANSLATION = 2; const int FPF_TRANSFERTRANSLATION = 2;
const int FPF_NOAUTOAIM = 4; const int FPF_NOAUTOAIM = 4;
const int FBF_PUFFTARGET = 64;
const int FBF_PUFFMASTER = 128;
const int FBF_PUFFTRACER = 256;
// Flags for A_Teleport // Flags for A_Teleport
enum enum
@ -652,3 +658,9 @@ enum
BT_USER3 = 1<<23, BT_USER3 = 1<<23,
BT_USER4 = 1<<24, BT_USER4 = 1<<24,
}; };
// Flags for GetAngle
enum
{
GAF_RELATIVE = 1,
GAF_SWITCH = 1 << 1,
};

View file

@ -9,7 +9,7 @@ ACTOR Inventory native
action native state A_JumpIfNoAmmo(state label); action native state A_JumpIfNoAmmo(state label);
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = ""); action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0); action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0, class<Actor> missile = "", float Spawnheight = 32, float Spawnofs_xy = 0);
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0); action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0); action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
action native A_Light(int extralight); action native A_Light(int extralight);

View file

@ -108,3 +108,5 @@ CMPTMNU_SECTORSOUNDS = "Sector sounds use centre as source";
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only"; OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only";
C_GRAY = "\ccgrey"; C_GRAY = "\ccgrey";
C_DARKGRAY = "\cudark grey"; C_DARKGRAY = "\cudark grey";
DSPLYMNU_MOVEBOB = "View bob amount while moving";
DSPLYMNU_STILLBOB = "View bob amount while not moving";

View file

@ -1839,6 +1839,7 @@ ALTHUDMNU_SHOWAMMO = "Show ammo for";
ALTHUDMNU_SHOWTIME = "Show time"; ALTHUDMNU_SHOWTIME = "Show time";
ALTHUDMNU_TIMECOLOR = "Time color"; ALTHUDMNU_TIMECOLOR = "Time color";
ALTHUDMNU_SHOWLAG = "Show network latency"; ALTHUDMNU_SHOWLAG = "Show network latency";
ALTHUDMNU_AMMOORDER = "Ammo display order";
ALTHUDMNU_AMMORED = "Red ammo display below %"; ALTHUDMNU_AMMORED = "Red ammo display below %";
ALTHUDMNU_AMMOYELLOW = "Yellow ammo display below %"; ALTHUDMNU_AMMOYELLOW = "Yellow ammo display below %";
ALTHUDMNU_HEALTHRED = "Red health display below"; ALTHUDMNU_HEALTHRED = "Red health display below";
@ -2214,6 +2215,8 @@ OPTVAL_SYSTEMSECONDS = "System, seconds";
OPTVAL_SYSTEM = "System"; OPTVAL_SYSTEM = "System";
OPTVAL_NETGAMESONLY = "Netgames only"; OPTVAL_NETGAMESONLY = "Netgames only";
OPTVAL_ALWAYS = "Always"; OPTVAL_ALWAYS = "Always";
OPTVAL_AMMOIMAGETEXT = "Image and Text";
OPTVAL_AMMOTEXTIMAGE = "Text and Image";
OPTVAL_SCRIPTSONLY = "Scripts Only"; OPTVAL_SCRIPTSONLY = "Scripts Only";
OPTVAL_NEVER = "Never"; OPTVAL_NEVER = "Never";
OPTVAL_ALL = "All"; OPTVAL_ALL = "All";

View file

@ -5,6 +5,7 @@ ClearLocks
Lock 1 Doom Lock 1 Doom
{ {
//$Title "Red key card"
RedCard RedCard
Message "$PD_REDC" Message "$PD_REDC"
RemoteMessage "$PD_REDCO" RemoteMessage "$PD_REDCO"
@ -14,6 +15,7 @@ Lock 1 Doom
Lock 2 Doom Lock 2 Doom
{ {
//$Title "Blue key card"
BlueCard BlueCard
Message "$PD_BLUEC" Message "$PD_BLUEC"
RemoteMessage "$PD_BLUECO" RemoteMessage "$PD_BLUECO"
@ -23,6 +25,7 @@ Lock 2 Doom
Lock 3 Doom Lock 3 Doom
{ {
//$Title "Yellow key card"
YellowCard YellowCard
Message "$PD_YELLOWC" Message "$PD_YELLOWC"
RemoteMessage "$PD_YELLOWCO" RemoteMessage "$PD_YELLOWCO"
@ -32,6 +35,7 @@ Lock 3 Doom
Lock 4 Doom Lock 4 Doom
{ {
//$Title "Red skull"
RedSkull RedSkull
Message "$PD_REDS" Message "$PD_REDS"
RemoteMessage "$PD_REDSO" RemoteMessage "$PD_REDSO"
@ -41,6 +45,7 @@ Lock 4 Doom
Lock 5 Doom Lock 5 Doom
{ {
//$Title "Blue skull"
BlueSkull BlueSkull
Message "$PD_BLUES" Message "$PD_BLUES"
RemoteMessage "$PD_BLUESO" RemoteMessage "$PD_BLUESO"
@ -50,6 +55,7 @@ Lock 5 Doom
Lock 6 Doom Lock 6 Doom
{ {
//$Title "Yellow skull"
YellowSkull YellowSkull
Message "$PD_YELLOWS" Message "$PD_YELLOWS"
RemoteMessage "$PD_YELLOWSO" RemoteMessage "$PD_YELLOWSO"
@ -59,6 +65,7 @@ Lock 6 Doom
Lock 129 Doom Lock 129 Doom
{ {
//$Title "Any red key"
Any { RedCard RedSkull KeyGreen } Any { RedCard RedSkull KeyGreen }
Message "$PD_REDK" Message "$PD_REDK"
RemoteMessage "$PD_REDO" RemoteMessage "$PD_REDO"
@ -68,6 +75,7 @@ Lock 129 Doom
Lock 130 Doom Lock 130 Doom
{ {
//$Title "Any blue key"
Any { BlueCard BlueSkull KeyBlue } Any { BlueCard BlueSkull KeyBlue }
Message "$PD_BLUEK" Message "$PD_BLUEK"
RemoteMessage "$PD_BLUEO" RemoteMessage "$PD_BLUEO"
@ -77,6 +85,7 @@ Lock 130 Doom
Lock 131 Doom Lock 131 Doom
{ {
//$Title "Any yellow key"
Any { YellowCard YellowSkull KeyYellow } Any { YellowCard YellowSkull KeyYellow }
Message "$PD_YELLOWK" Message "$PD_YELLOWK"
RemoteMessage "$PD_YELLOWO" RemoteMessage "$PD_YELLOWO"
@ -86,6 +95,7 @@ Lock 131 Doom
Lock 132 Doom Lock 132 Doom
{ {
//$Title "Red card or skull"
Any { RedCard RedSkull } Any { RedCard RedSkull }
Message "$PD_REDK" Message "$PD_REDK"
RemoteMessage "$PD_REDO" RemoteMessage "$PD_REDO"
@ -95,6 +105,7 @@ Lock 132 Doom
Lock 133 Doom Lock 133 Doom
{ {
//$Title "Blue card or skull"
Any { BlueCard BlueSkull } Any { BlueCard BlueSkull }
Message "$PD_BLUEK" Message "$PD_BLUEK"
RemoteMessage "$PD_BLUEO" RemoteMessage "$PD_BLUEO"
@ -104,6 +115,7 @@ Lock 133 Doom
Lock 134 Doom Lock 134 Doom
{ {
//$Title "Yellow card or skull"
Any { YellowCard YellowSkull } Any { YellowCard YellowSkull }
Message "$PD_YELLOWK" Message "$PD_YELLOWK"
RemoteMessage "$PD_YELLOWO" RemoteMessage "$PD_YELLOWO"
@ -112,6 +124,7 @@ Lock 134 Doom
Lock 100 Lock 100
{ {
//$Title "Any key"
Message "$PD_ANY" Message "$PD_ANY"
RemoteMessage "$PD_ANYOBJ" RemoteMessage "$PD_ANYOBJ"
Mapcolor 128 128 255 Mapcolor 128 128 255
@ -119,6 +132,7 @@ Lock 100
Lock 228 Lock 228
{ {
//$Title "Any key"
Message "$PD_ANY" Message "$PD_ANY"
RemoteMessage "$PD_ANYOBJ" RemoteMessage "$PD_ANYOBJ"
Mapcolor 128 128 255 Mapcolor 128 128 255
@ -126,6 +140,7 @@ Lock 228
Lock 229 Doom Lock 229 Doom
{ {
//$Title "One of each color"
Any { BlueCard BlueSkull KeyBlue} Any { BlueCard BlueSkull KeyBlue}
Any { YellowCard YellowSkull KeyYellow} Any { YellowCard YellowSkull KeyYellow}
Any { RedCard RedSkull KeyGreen} Any { RedCard RedSkull KeyGreen}
@ -135,6 +150,7 @@ Lock 229 Doom
Lock 101 Doom Lock 101 Doom
{ {
//$Title "All keys"
BlueCard BlueCard
BlueSkull BlueSkull
YellowCard YellowCard
@ -151,6 +167,7 @@ Lock 101 Doom
Lock 1 Heretic Lock 1 Heretic
{ {
//$Title "Green key"
KeyGreen KeyGreen
Message "$TXT_NEEDGREENKEY" Message "$TXT_NEEDGREENKEY"
Mapcolor 0 255 0 Mapcolor 0 255 0
@ -159,6 +176,7 @@ Lock 1 Heretic
Lock 2 Heretic Lock 2 Heretic
{ {
//$Title "Blue key"
KeyBlue KeyBlue
Message "$TXT_NEEDBLUEKEY" Message "$TXT_NEEDBLUEKEY"
Mapcolor 0 0 255 Mapcolor 0 0 255
@ -167,6 +185,7 @@ Lock 2 Heretic
Lock 3 Heretic Lock 3 Heretic
{ {
//$Title "Yellow key"
KeyYellow KeyYellow
Message "$TXT_NEEDYELLOWKEY" Message "$TXT_NEEDYELLOWKEY"
Mapcolor 255 255 0 Mapcolor 255 255 0
@ -175,6 +194,7 @@ Lock 3 Heretic
Lock 129 Heretic Lock 129 Heretic
{ {
//$Title "Green key"
KeyGreen KeyGreen
Message "$TXT_NEEDGREENKEY" Message "$TXT_NEEDGREENKEY"
Mapcolor 0 255 0 Mapcolor 0 255 0
@ -183,6 +203,7 @@ Lock 129 Heretic
Lock 130 Heretic Lock 130 Heretic
{ {
//$Title "Blue key"
KeyBlue KeyBlue
Message "$TXT_NEEDBLUEKEY" Message "$TXT_NEEDBLUEKEY"
Mapcolor 0 0 255 Mapcolor 0 0 255
@ -191,6 +212,7 @@ Lock 130 Heretic
Lock 131 Heretic Lock 131 Heretic
{ {
//$Title "Yellow key"
KeyYellow KeyYellow
Message "$TXT_NEEDYELLOWKEY" Message "$TXT_NEEDYELLOWKEY"
Mapcolor 255 255 0 Mapcolor 255 255 0
@ -199,6 +221,7 @@ Lock 131 Heretic
Lock 229 Heretic Lock 229 Heretic
{ {
//$Title "All keys"
KeyGreen KeyGreen
KeyYellow KeyYellow
KeyBlue KeyBlue
@ -208,6 +231,7 @@ Lock 229 Heretic
Lock 101 Heretic Lock 101 Heretic
{ {
//$Title "All keys"
KeyGreen KeyGreen
KeyYellow KeyYellow
KeyBlue KeyBlue
@ -222,6 +246,7 @@ Lock 101 Heretic
Lock 1 Hexen Lock 1 Hexen
{ {
//$Title "Steel key"
KeySteel KeySteel
Message "$TXT_NEED_KEY_STEEL" Message "$TXT_NEED_KEY_STEEL"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -230,6 +255,7 @@ Lock 1 Hexen
Lock 2 Hexen Lock 2 Hexen
{ {
//$Title "Cave key"
KeyCave KeyCave
Message "$TXT_NEED_KEY_CAVE" Message "$TXT_NEED_KEY_CAVE"
Mapcolor 255 218 0 Mapcolor 255 218 0
@ -238,6 +264,7 @@ Lock 2 Hexen
Lock 3 Hexen Lock 3 Hexen
{ {
//$Title "Axe key"
KeyAxe KeyAxe
Message "$TXT_NEED_KEY_AXE" Message "$TXT_NEED_KEY_AXE"
Mapcolor 64 64 255 Mapcolor 64 64 255
@ -246,6 +273,7 @@ Lock 3 Hexen
Lock 4 Hexen Lock 4 Hexen
{ {
//$Title "Fire key"
KeyFire KeyFire
Message "$TXT_NEED_KEY_FIRE" Message "$TXT_NEED_KEY_FIRE"
Mapcolor 255 128 0 Mapcolor 255 128 0
@ -254,6 +282,7 @@ Lock 4 Hexen
Lock 5 Hexen Lock 5 Hexen
{ {
//$Title "Emerald key"
KeyEmerald KeyEmerald
Message "$TXT_NEED_KEY_EMERALD" Message "$TXT_NEED_KEY_EMERALD"
Mapcolor 0 255 0 Mapcolor 0 255 0
@ -262,6 +291,7 @@ Lock 5 Hexen
Lock 6 Hexen Lock 6 Hexen
{ {
//$Title "Dungeon key"
KeyDungeon KeyDungeon
Message "$TXT_NEED_KEY_DUNGEON" Message "$TXT_NEED_KEY_DUNGEON"
Mapcolor 47 151 255 Mapcolor 47 151 255
@ -270,6 +300,7 @@ Lock 6 Hexen
Lock 7 Hexen Lock 7 Hexen
{ {
//$Title "Silver key"
KeySilver KeySilver
Message "$TXT_NEED_KEY_SILVER" Message "$TXT_NEED_KEY_SILVER"
Mapcolor 154 152 188 Mapcolor 154 152 188
@ -278,6 +309,7 @@ Lock 7 Hexen
Lock 8 Hexen Lock 8 Hexen
{ {
//$Title "Rusted key"
KeyRusted KeyRusted
Message "$TXT_NEED_KEY_RUSTED" Message "$TXT_NEED_KEY_RUSTED"
Mapcolor 156 76 0 Mapcolor 156 76 0
@ -286,6 +318,7 @@ Lock 8 Hexen
Lock 9 Hexen Lock 9 Hexen
{ {
//$Title "Horn key"
KeyHorn KeyHorn
Message "$TXT_NEED_KEY_HORN" Message "$TXT_NEED_KEY_HORN"
Mapcolor 255 218 0 Mapcolor 255 218 0
@ -294,6 +327,7 @@ Lock 9 Hexen
Lock 10 Hexen Lock 10 Hexen
{ {
//$Title "Swamp key"
KeySwamp KeySwamp
Message "$TXT_NEED_KEY_SWAMP" Message "$TXT_NEED_KEY_SWAMP"
Mapcolor 64 255 64 Mapcolor 64 255 64
@ -302,6 +336,7 @@ Lock 10 Hexen
Lock 11 Hexen Lock 11 Hexen
{ {
//$Title "Castle key"
KeyCastle KeyCastle
Message "$TXT_NEED_KEY_CASTLE" Message "$TXT_NEED_KEY_CASTLE"
Mapcolor 255 64 64 Mapcolor 255 64 64
@ -310,6 +345,7 @@ Lock 11 Hexen
Lock 101 Hexen Lock 101 Hexen
{ {
//$Title "All keys"
KeySteel KeySteel
KeyCave KeyCave
KeyAxe KeyAxe
@ -326,6 +362,7 @@ Lock 101 Hexen
Lock 229 Hexen Lock 229 Hexen
{ {
//$Title "All keys"
KeySteel KeySteel
KeyCave KeyCave
KeyAxe KeyAxe
@ -345,14 +382,16 @@ Lock 229 Hexen
Lock 1 Strife Lock 1 Strife
{ {
//$Title "Base key"
BaseKey BaseKey
Message "You don't have the key" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
} }
Lock 2 Strife Lock 2 Strife
{ {
//$Title "Governor's key"
GovsKey GovsKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -361,6 +400,7 @@ Lock 2 Strife
Lock 3 Strife Lock 3 Strife
{ {
//$Title "Travel passcard"
Passcard Passcard
RemoteMessage "$TXT_NEED_PASSCARD" RemoteMessage "$TXT_NEED_PASSCARD"
Message "$TXT_NEED_PASSCARD_DOOR" Message "$TXT_NEED_PASSCARD_DOOR"
@ -370,6 +410,7 @@ Lock 3 Strife
Lock 4 Strife Lock 4 Strife
{ {
//$Title "ID badge"
IDBadge IDBadge
Message "$TXT_NEED_IDCARD" Message "$TXT_NEED_IDCARD"
Mapcolor 255 128 0 Mapcolor 255 128 0
@ -378,6 +419,7 @@ Lock 4 Strife
Lock 5 Strife Lock 5 Strife
{ {
//$Title "Prison key"
PrisonKey PrisonKey
Message "$TXT_NEED_PRISONKEY" Message "$TXT_NEED_PRISONKEY"
Mapcolor 0 255 0 Mapcolor 0 255 0
@ -386,6 +428,7 @@ Lock 5 Strife
Lock 6 Strife Lock 6 Strife
{ {
//$Title "Severed hand"
SeveredHand SeveredHand
Message "$TXT_NEED_HANDPRINT" Message "$TXT_NEED_HANDPRINT"
Mapcolor 255 151 100 Mapcolor 255 151 100
@ -394,6 +437,7 @@ Lock 6 Strife
Lock 7 Strife Lock 7 Strife
{ {
//$Title "Power key 1"
Power1Key Power1Key
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -402,6 +446,7 @@ Lock 7 Strife
Lock 8 Strife Lock 8 Strife
{ {
//$Title "Power key 2"
Power2Key Power2Key
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -410,6 +455,7 @@ Lock 8 Strife
Lock 9 Strife Lock 9 Strife
{ {
//$Title "Power key 3"
Power3Key Power3Key
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -418,6 +464,7 @@ Lock 9 Strife
Lock 10 Strife Lock 10 Strife
{ {
//$Title "Gold key"
GoldKey GoldKey
Message "$TXT_NEED_GOLDKEY" Message "$TXT_NEED_GOLDKEY"
Mapcolor 255 200 0 Mapcolor 255 200 0
@ -426,6 +473,7 @@ Lock 10 Strife
Lock 11 Strife Lock 11 Strife
{ {
//$Title "ID card"
IDCard IDCard
RemoteMessage "$TXT_NEED_IDBADGE" RemoteMessage "$TXT_NEED_IDBADGE"
Message "$TXT_NEED_IDBADGE_DOOR" Message "$TXT_NEED_IDBADGE_DOOR"
@ -434,6 +482,7 @@ Lock 11 Strife
Lock 12 Strife Lock 12 Strife
{ {
//$Title "Silver key"
SilverKey SilverKey
Message "$TXT_NEED_SILVERKEY" Message "$TXT_NEED_SILVERKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -441,6 +490,7 @@ Lock 12 Strife
Lock 13 Strife Lock 13 Strife
{ {
//$Title "Oracle key"
OracleKey OracleKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -448,6 +498,7 @@ Lock 13 Strife
Lock 14 Strife Lock 14 Strife
{ {
//$Title "Military key"
MilitaryID MilitaryID
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -455,6 +506,7 @@ Lock 14 Strife
Lock 15 Strife Lock 15 Strife
{ {
//$Title "Order key"
OrderKey OrderKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -462,6 +514,7 @@ Lock 15 Strife
Lock 16 Strife Lock 16 Strife
{ {
//$Title "Warehouse key"
WarehouseKey WarehouseKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -469,6 +522,7 @@ Lock 16 Strife
Lock 17 Strife Lock 17 Strife
{ {
//$Title "Brass key"
BrassKey BrassKey
Message "$TXT_NEED_BRASSKEY" Message "$TXT_NEED_BRASSKEY"
Mapcolor 150 75 0 Mapcolor 150 75 0
@ -476,6 +530,7 @@ Lock 17 Strife
Lock 18 Strife Lock 18 Strife
{ {
//$Title "Red crystal key"
RedCrystalKey RedCrystalKey
Message "$TXT_NEED_REDCRYSTAL" Message "$TXT_NEED_REDCRYSTAL"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -483,6 +538,7 @@ Lock 18 Strife
Lock 19 Strife Lock 19 Strife
{ {
//$Title "Blue crystal key"
BlueCrystalKey BlueCrystalKey
Message "$TXT_NEED_BLUECRYSTAL" Message "$TXT_NEED_BLUECRYSTAL"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -490,6 +546,7 @@ Lock 19 Strife
Lock 20 Strife Lock 20 Strife
{ {
//$Title "Chapel key"
ChapelKey ChapelKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -497,6 +554,7 @@ Lock 20 Strife
Lock 21 Strife Lock 21 Strife
{ {
//$Title "Catacomb key"
CatacombKey CatacombKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -504,6 +562,7 @@ Lock 21 Strife
Lock 22 Strife Lock 22 Strife
{ {
//$Title "Security key"
SecurityKey SecurityKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -511,6 +570,7 @@ Lock 22 Strife
Lock 23 Strife Lock 23 Strife
{ {
//$Title "Core key"
CoreKey CoreKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -518,6 +578,7 @@ Lock 23 Strife
Lock 24 Strife Lock 24 Strife
{ {
//$Title "Mauler key"
MaulerKey MaulerKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -525,6 +586,7 @@ Lock 24 Strife
Lock 25 Strife Lock 25 Strife
{ {
//$Title "Factory key"
FactoryKey FactoryKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -532,6 +594,7 @@ Lock 25 Strife
Lock 26 Strife Lock 26 Strife
{ {
//$Title "Mine key"
MineKey MineKey
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -539,6 +602,7 @@ Lock 26 Strife
Lock 27 Strife Lock 27 Strife
{ {
//$Title "New key 5"
NewKey5 NewKey5
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -546,6 +610,7 @@ Lock 27 Strife
Lock 50 Strife Lock 50 Strife
{ {
//$Title "Prison key"
PrisonPass PrisonPass
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -553,6 +618,7 @@ Lock 50 Strife
Lock 51 Strife Lock 51 Strife
{ {
//$Title "Oracle pass"
OraclePass OraclePass
Message "$TXT_NEEDKEY" Message "$TXT_NEEDKEY"
Mapcolor 150 150 150 Mapcolor 150 150 150
@ -564,6 +630,7 @@ Lock 51 Strife
Lock 1 Chex Lock 1 Chex
{ {
//$Title "Red key card"
ChexRedCard ChexRedCard
Message "$PD_REDC" Message "$PD_REDC"
RemoteMessage "$PD_REDCO" RemoteMessage "$PD_REDCO"
@ -573,6 +640,7 @@ Lock 1 Chex
Lock 2 Chex Lock 2 Chex
{ {
//$Title "Blue key card"
ChexBlueCard ChexBlueCard
Message "$PD_BLUEC" Message "$PD_BLUEC"
RemoteMessage "$PD_BLUECO" RemoteMessage "$PD_BLUECO"
@ -582,6 +650,7 @@ Lock 2 Chex
Lock 3 Chex Lock 3 Chex
{ {
//$Title "Yellow key card"
ChexYellowCard ChexYellowCard
Message "$PD_YELLOWC" Message "$PD_YELLOWC"
RemoteMessage "$PD_YELLOWCO" RemoteMessage "$PD_YELLOWCO"
@ -590,6 +659,7 @@ Lock 3 Chex
Lock 129 Chex Lock 129 Chex
{ {
//$Title "Red key"
ChexRedCard ChexRedCard
Message "$PD_REDK" Message "$PD_REDK"
RemoteMessage "$PD_REDO" RemoteMessage "$PD_REDO"
@ -599,6 +669,7 @@ Lock 129 Chex
Lock 130 Chex Lock 130 Chex
{ {
//$Title "Blue key"
ChexBlueCard ChexBlueCard
Message "$PD_BLUEK" Message "$PD_BLUEK"
RemoteMessage "$PD_BLUEO" RemoteMessage "$PD_BLUEO"
@ -608,6 +679,7 @@ Lock 130 Chex
Lock 131 Chex Lock 131 Chex
{ {
//$Title "Yellow key"
ChexYellowCard ChexYellowCard
Message "$PD_YELLOWK" Message "$PD_YELLOWK"
RemoteMessage "$PD_YELLOWO" RemoteMessage "$PD_YELLOWO"

View file

@ -692,6 +692,8 @@ OptionMenu "VideoOptions"
Option "$DSPLYMNU_NOMONSTERINTERPOLATION", "nomonsterinterpolation", "NoYes" Option "$DSPLYMNU_NOMONSTERINTERPOLATION", "nomonsterinterpolation", "NoYes"
Slider "$DSPLYMNU_MENUDIM", "dimamount", 0, 1.0, 0.05, 2 Slider "$DSPLYMNU_MENUDIM", "dimamount", 0, 1.0, 0.05, 2
ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor" ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor"
Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2
Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2
} }
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
@ -823,6 +825,12 @@ OptionValue "AltHUDLag"
2, "$OPTVAL_ALWAYS" 2, "$OPTVAL_ALWAYS"
} }
OptionValue "AltHUDAmmoOrder"
{
0, "$OPTVAL_AMMOIMAGETEXT"
1, "$OPTVAL_AMMOTEXTIMAGE"
}
OptionMenu "AltHUDOptions" OptionMenu "AltHUDOptions"
{ {
Title "$ALTHUDMNU_TITLE" Title "$ALTHUDMNU_TITLE"
@ -839,6 +847,7 @@ OptionMenu "AltHUDOptions"
Option "$ALTHUDMNU_SHOWTIME", "hud_showtime", "AltHUDTime" Option "$ALTHUDMNU_SHOWTIME", "hud_showtime", "AltHUDTime"
Option "$ALTHUDMNU_TIMECOLOR", "hud_timecolor", "TextColors" Option "$ALTHUDMNU_TIMECOLOR", "hud_timecolor", "TextColors"
Option "$ALTHUDMNU_SHOWLAG", "hud_showlag", "AltHUDLag" Option "$ALTHUDMNU_SHOWLAG", "hud_showlag", "AltHUDLag"
Option "$ALTHUDMNU_AMMOORDER", "hud_ammo_order", "AltHUDAmmoOrder"
Slider "$ALTHUDMNU_AMMORED", "hud_ammo_red", 0, 100, 1, 0 Slider "$ALTHUDMNU_AMMORED", "hud_ammo_red", 0, 100, 1, 0
Slider "$ALTHUDMNU_AMMOYELLOW", "hud_ammo_yellow", 0, 100, 1, 0 Slider "$ALTHUDMNU_AMMOYELLOW", "hud_ammo_yellow", 0, 100, 1, 0
Slider "$ALTHUDMNU_HEALTHRED", "hud_health_red", 0, 100, 1, 0 Slider "$ALTHUDMNU_HEALTHRED", "hud_health_red", 0, 100, 1, 0

View file

@ -234,3 +234,20 @@ enum
447 = 0, Exit_Normal(0) 447 = 0, Exit_Normal(0)
448 = 0, Exit_Secret(0) 448 = 0, Exit_Secret(0)
449 = 0, Teleport_NewMap(0) 449 = 0, Teleport_NewMap(0)
450 = 0, Line_Horizon(0)
451 = 0, Floor_RaiseAndCrush(0)
452 = 0, Floor_CrushStop(0)
453 = 0, FloorAndCeiling_LowerByValue(0)
454 = 0, FloorAndCeiling_RaiseByValue(0)
457 = 0, Door_LockedOpen(0)
458 = 0, Elevator_RaiseToNearest(0)
459 = 0, Elevator_LowerToNearest(0)
460 = 0, Elevator_MoveToFloor(0)
461 = 0, Light_MaxNeighbor(0)
462 = 0, ChangeSkill(0)
463 = 0, Light_StrobeDoom(0)
464 = 0, Generic_Floor(0)
465 = 0, Generic_Ceiling(0)
466 = 0, Floor_TransferTrigger(0)
467 = 0, Floor_TransferNumeric(0)
468 = 0, FloorAndCeiling_LowerRaise(0)