diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c0a30ea07..fdb668b01b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -484,6 +484,9 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" ) set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" ) 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_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 () + # 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. # 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. diff --git a/src/actor.h b/src/actor.h index ea4d15ad96..93d2834a8f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -407,9 +407,12 @@ enum ActorRenderFlag RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types, not all implemented RF_FACESPRITE = 0x0000, // Face sprite RF_WALLSPRITE = 0x1000, // Wall sprite - RF_FLOORSPRITE = 0x2000, // Floor sprite + RF_FLATSPRITE = 0x2000, // Flat sprite RF_VOXELSPRITE = 0x3000, // Voxel object 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_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting) diff --git a/src/cmdlib.h b/src/cmdlib.h index 05e515374f..b035842cdf 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -16,7 +16,7 @@ #include // 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); bool FileExists (const char *filename); diff --git a/src/d_player.h b/src/d_player.h index 48649de7ad..e932223aaa 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -532,7 +532,10 @@ public: void TickPSprites(); void DestroyPSprites(); 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. diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 6b963f6d4d..a7f07247f2 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -1272,6 +1272,7 @@ void PFloat::WriteValue(FArchive &ar, const void *addr) const { ar.WriteByte(VAL_Float64); ar << doubleprecision; + return; } } else diff --git a/src/doomdata.h b/src/doomdata.h index 4e4976800a..f809f05eaf 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -334,7 +334,7 @@ struct mapthinghexen_t SWORD z; SWORD angle; SWORD type; - SWORD flags; + WORD flags; BYTE special; BYTE args[5]; }; diff --git a/src/farchive.cpp b/src/farchive.cpp index fc3d75bbbb..6697fd5b72 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -728,13 +728,13 @@ void FArchive::WriteByte(BYTE val) void FArchive::WriteInt16(WORD val) { - WORD out = LittleShort(val); + WORD out = SWAP_WORD(val); m_File->Write(&out, 2); } void FArchive::WriteInt32(DWORD val) { - int out = LittleLong(val); + int out = SWAP_DWORD(val); m_File->Write(&out, 4); } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index f8648808d1..f02843c899 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1573,7 +1573,7 @@ void FParser::SF_FloorHeight(void) sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest), crush? 10:-1, (dest > sectors[i].CenterFloor()) ? 1 : -1, - false) != EMoveResult::crushed) + false) == EMoveResult::crushed) { returnval = 0; } @@ -1662,7 +1662,7 @@ void FParser::SF_CeilingHeight(void) sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest), crush? 10:-1, (dest > sectors[i].CenterCeiling()) ? 1 : -1, - false) != EMoveResult::crushed) + false) == EMoveResult::crushed) { returnval = 0; } @@ -3473,12 +3473,7 @@ void FParser::SF_Resurrect() mo->SetState(state); mo->Height = mo->GetDefault()->Height; mo->radius = mo->GetDefault()->radius; - mo->flags = mo->GetDefault()->flags; - 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->Revive(); mo->target = NULL; } } @@ -3766,30 +3761,6 @@ void FParser::SF_SetCorona(void) 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 @@ -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!) @@ -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 @@ -4510,13 +4446,10 @@ void init_functions(void) // new for GZDoom gscr->NewFunction("spawnshot2", &FParser::SF_SpawnShot2); 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("objheight", &FParser::SF_MobjHeight); gscr->NewFunction("thingcount", &FParser::SF_ThingCount); gscr->NewFunction("killinsector", &FParser::SF_KillInSector); - gscr->NewFunction("changetag", &FParser::SF_ChangeTag); gscr->NewFunction("levelnum", &FParser::SF_LevelNum); // new inventory @@ -4525,8 +4458,6 @@ void init_functions(void) gscr->NewFunction("checkinventory", &FParser::SF_CheckInventory); gscr->NewFunction("setweapon", &FParser::SF_SetWeapon); - gscr->NewFunction("ls", &FParser::SF_Ls); // execute Hexen type line special - // Dummies - shut up warnings gscr->NewFunction("setcorona", &FParser::SF_SetCorona); } diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index 51ee77ff80..5d10e01382 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -147,7 +147,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) { 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); } diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index b70e4ff080..7f62d5f0e1 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -123,9 +123,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers) 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; } } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 786e496955..4dc1545338 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1128,12 +1128,27 @@ void APowerWeaponLevel2::InitEffect () assert (sister->SisterWeapon == weapon); - Owner->player->ReadyWeapon = sister; if (weapon->GetReadyState() != sister->GetReadyState()) { + Owner->player->ReadyWeapon = sister; 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; + } + } } //=========================================================================== diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index e7ebfc77b2..575914fe8d 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -642,7 +642,18 @@ void AWeapon::EndPowerup () } 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; + } } } } diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index a09c49303b..b4a011510b 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -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[] = { "drawimage", "drawnumber", "drawswitchableimage", @@ -3450,7 +3474,7 @@ static const char *SBarInfoCommandNames[] = "isselected", "usesammo", "usessecondaryammo", "hasweaponpiece", "inventorybarnotvisible", "weaponammo", "ininventory", "alpha", "ifhealth", - "ifinvulnerable", + "ifinvulnerable", "ifwaterlevel", NULL }; @@ -3464,7 +3488,7 @@ enum SBarInfoCommands SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO, SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH, - SBARINFO_IFINVULNERABLE, + SBARINFO_IFINVULNERABLE, SBARINFO_IFWATERLEVEL, }; SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) @@ -3499,6 +3523,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) case SBARINFO_ALPHA: return new CommandAlpha(script); case SBARINFO_IFHEALTH: return new CommandIfHealth(script); case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script); + case SBARINFO_IFWATERLEVEL: return new CommandIfWaterLevel(script); } sc.ScriptError("Unknown command '%s'.\n", sc.String); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 4bfe852719..46cf61d545 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -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_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_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 @@ -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) int def_width = ConFont->StringWidth("000/000"); - x-=def_width; 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--) { @@ -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_yellow) / 100) ? CR_GOLD : CR_GREEN ); - DrawHudText(ConFont, fontcolor, buf, x-tex_width, y+yadd, trans); - DrawImageToBox(TexMan[icon], x-20, y, 16, 8, trans); + DrawHudText(ConFont, fontcolor, buf, xtext-tex_width, y+yadd, trans); + DrawImageToBox(TexMan[icon], ximage, y, 16, 8, trans); y-=10; } return y; diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 8b5788d44e..4533016ec1 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -317,7 +317,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; double speed = (anglespeed % 10) / 16.; DAngle an = (anglespeed / 10) * (360 / 8.); - self->VelFromAngle(an, speed); + self->Thrust(an, speed); } } return 0; @@ -352,22 +352,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns) if (self->player != nullptr && self->player->mo == self) { - FState *firehands = 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; - } + P_SetPsprite(self->player, PSP_STRIFEHANDS, self->FindState("FireHands")); - self->player->ReadyWeapon = nullptr; - self->player->PendingWeapon = WP_NOCHANGE; - self->player->playerstate = PST_LIVE; - self->player->extralight = 3; - } + self->player->ReadyWeapon = nullptr; + self->player->PendingWeapon = WP_NOCHANGE; + self->player->playerstate = PST_LIVE; + self->player->extralight = 3; } return 0; } @@ -388,14 +378,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer) if (self->player != nullptr && self->player->mo == self) { - self->player->playerstate = PST_DEAD; - DPSprite *psp; psp = self->player->GetPSprite(PSP_STRIFEHANDS); + FState *firehandslower = self->FindState("FireHandsLower"); FState *firehands = self->FindState("FireHands"); - if (firehandslower != NULL && firehands != NULL && firehands < firehandslower) - psp->SetState(psp->GetState() + (firehandslower - firehands)); + FState *state = psp->GetState(); + + 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; } @@ -407,13 +405,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) if (self->player != nullptr) { DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS); + + if (psp->GetState() == nullptr) + { + psp->SetState(nullptr); + return 0; + } + psp->y += 9; if (psp->y > WEAPONBOTTOM*2) { psp->SetState(nullptr); } + if (self->player->extralight > 0) self->player->extralight--; } return 0; } - diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index d1753c4057..1948153e4c 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -306,7 +306,15 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) int y = sc.Number; sc.MustGetStringName(","); 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); } 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) { sc.MustGetStringName("{"); @@ -784,12 +807,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) { sc.MustGetString(); FString label = sc.String; - bool cr = false; - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - cr = !!sc.Number; - } + EColorRange cr = ParseOptionColor(sc, desc); FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr); desc->mItems.Push(it); } @@ -803,12 +821,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) sc.MustGetStringName(","); sc.MustGetString(); FName action = sc.String; - bool cr = false; - if (sc.CheckString(",")) - { - sc.MustGetNumber(); - cr = !!sc.Number; - } + EColorRange cr = ParseOptionColor(sc, desc); FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr); desc->mItems.Push(it); } diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 8a1840027a..3131e35f71 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -483,7 +483,13 @@ public: FOptionMenuItemStaticText(const char *label, bool header) : 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) @@ -512,10 +518,10 @@ class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem int mCurrent; 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) { - mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor; + mColor = cr; mAltText = label2; mCurrent = 0; } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7cbfd69b48..919834a067 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5712,8 +5712,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) argCount > 11 ? ACSToDouble(args[11]) : 1.0, argCount > 12 ? args[12] : 0, argCount > 13 ? args[13] : 0, - argCount > 14 ? args[14] : 0, - argCount > 15 ? args[15] : 0); + argCount > 14 ? ACSToDouble(args[14]) : 0, + argCount > 15 ? ACSToDouble(args[15]) : 0); } case ACSF_SetLineActivation: diff --git a/src/p_doors.cpp b/src/p_doors.cpp index d6a5f3a44c..ab551de1b3 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -688,14 +688,11 @@ void DAnimatedDoor::Tick () //============================================================================ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) - : DMovingCeiling (sec) + : DMovingCeiling (sec, false) { double topdist; 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_Line1 = line; diff --git a/src/p_local.h b/src/p_local.h index ac6b264d92..42b4da7e7f 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -325,7 +325,8 @@ enum // P_LineAttack flags { LAF_ISMELEEATTACK = 1, 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); diff --git a/src/p_map.cpp b/src/p_map.cpp index cf7655917c..1684ee5341 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4096,6 +4096,7 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) { + bool nointeract = !!(flags & LAF_NOINTERACT); DVector3 direction; double shootz; FTraceResults trace; @@ -4185,26 +4186,32 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } 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; if (!Trace(t1->PosAtZ(shootz), t1->Sector, direction, distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData)) { // hit nothing - if (puffDefaults == NULL) - { - } - else if (puffDefaults->ActiveSound) + if (!nointeract && puffDefaults && puffDefaults->ActiveSound) { // Play miss sound 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 puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget, 2, puffFlags); + + if (nointeract) + { + return puff; + } } else { - return NULL; + return nullptr; } } else @@ -4212,12 +4219,17 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, if (trace.HitType != TRACE_HitActor) { // 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); puff = P_SpawnPuff(t1, pufftype, DVector3(pos, trace.HitPos.Z - trace.HitVector.Z * 4), trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 0, puffFlags); puff->radius = 1/65536.; + + if (nointeract) + { + return puff; + } } // [RH] Spawn a decal @@ -4255,14 +4267,6 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } 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 DVector3 bleedpos = trace.HitPos; // 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. - if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) || + if (nointeract || (puffDefaults && puffDefaults->flags3 & MF3_PUFFONACTORS) || (trace.Actor->flags & MF_NOBLOOD) || (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 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. @@ -4320,6 +4329,14 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, } 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 && !(trace.Actor->flags & MF_NOBLOOD) && !(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); - thing->floorz = tm.floorz; - thing->ceilingz = tm.ceilingz; - thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs - thing->floorpic = tm.floorpic; - thing->floorterrain = tm.floorterrain; - thing->floorsector = tm.floorsector; - thing->ceilingpic = tm.ceilingpic; - thing->ceilingsector = tm.ceilingsector; + if (!(thing->flags4 & MF4_ACTLIKEBRIDGE)) + { + thing->floorz = tm.floorz; + thing->ceilingz = tm.ceilingz; + thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs + thing->floorpic = tm.floorpic; + thing->floorterrain = tm.floorterrain; + 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. thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2; diff --git a/src/p_maputl.h b/src/p_maputl.h index e5a8a5f4ff..81d3c9d133 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -38,18 +38,17 @@ struct intercept_t 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) { - 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) { extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line); - return i_compatflags2 & COMPATF2_POINTONLINE ? 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) { - 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) { - 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; } //========================================================================== diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index ebfc14da33..bad9c2d736 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -216,15 +216,29 @@ DPSprite *player_t::GetPSprite(PSPLayers layer) } // 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; 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) { // 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; @@ -1071,9 +1085,8 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower) } if (player->playerstate == PST_DEAD) { // Player is dead, so don't bring up a pending weapon - psp->y = WEAPONBOTTOM; - // Player is dead, so keep the weapon off screen + P_SetPsprite(player, PSP_FLASH, nullptr); psp->SetState(nullptr); return 0; } @@ -1157,41 +1170,39 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ClearOverlays) PARAM_INT_OPT(stop) { stop = 0; } PARAM_BOOL_OPT(safety) { safety = true; } - if (!self->player) + if (self->player == nullptr) ACTION_RETURN_INT(0); - player_t *player = self->player; if (!start && !stop) { start = INT_MIN; stop = safety ? PSP_TARGETCENTER - 1 : INT_MAX; } - int count = 0; - DPSprite *pspr = player->psprites; - while (pspr != nullptr) - { - int id = pspr->GetID(); + unsigned int count = 0; + int id; - //Do not wipe out layer 0. Ever. - if (!id || id < start) + for (DPSprite *pspr = self->player->psprites; pspr != nullptr; pspr = pspr->GetNext()) + { + id = pspr->GetID(); + + if (id < start || id == 0) continue; - if (id > stop) + else if (id > stop) break; if (safety) { if (id >= PSP_TARGETCENTER) break; - else if ((id >= PSP_STRIFEHANDS && id <= PSP_WEAPON) || (id == PSP_FLASH)) + else if (id == PSP_STRIFEHANDS || id == PSP_WEAPON || id == PSP_FLASH) continue; } - // [MC]Don't affect non-hardcoded layers unless it's really desired. pspr->SetState(nullptr); count++; - pspr = pspr->GetNext(); } + ACTION_RETURN_INT(count); } diff --git a/src/p_pspr.h b/src/p_pspr.h index 2c7a36518d..41d258df83 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -42,7 +42,7 @@ class FArchive; // drawn directly on the 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_WEAPON = 1, @@ -76,6 +76,7 @@ public: FState* GetState() const { return State; } DPSprite* GetNext() { return Next; } AActor* GetCaller() { return Caller; } + void SetCaller(AActor *newcaller) { Caller = newcaller; } double x, y; double oldx, oldy; diff --git a/src/portal.cpp b/src/portal.cpp index f180a4fbfa..bf919f09a4 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -288,7 +288,7 @@ static void SetRotation(FLinePortal *port) } else { - port->mFlags &= PORTF_POLYOBJ; + port->mFlags &= ~PORTF_POLYOBJ; } } else diff --git a/src/posix/cocoa/i_main.mm b/src/posix/cocoa/i_main.mm index 5729a3716b..bbe3448097 100644 --- a/src/posix/cocoa/i_main.mm +++ b/src/posix/cocoa/i_main.mm @@ -220,8 +220,8 @@ int OriginalMain(int argc, char** argv) @interface ApplicationController : NSResponder -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 + #endif { } diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 75826d3289..e25812fbd4 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -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. cosine = cos(planeang), sine = sin(planeang); 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_sv = p ^ n; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 7a9ac1ce0a..63ba6ec302 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -329,13 +329,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance) // 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) { if (numret > 0) { assert(ret != NULL); PARAM_SELF_PROLOGUE(AActor); - PARAM_BOOL(relative); + PARAM_INT(flags); PARAM_INT_OPT(ptr) { ptr = AAPTR_TARGET; } AActor *target = COPY_AAPTR(self, ptr); @@ -346,9 +352,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetAngle) } else { - DVector3 diff = self->Vec3To(target); + DVector3 diff = (flags & GAF_SWITCH) ? target->Vec3To(self) : self->Vec3To(target); 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); } return 1; @@ -1615,8 +1622,13 @@ enum CBA_Flags CBAF_EXPLICITANGLE = 4, CBAF_NOPITCH = 8, 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) { PARAM_SELF_PROLOGUE(AActor); @@ -1628,6 +1640,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) PARAM_FLOAT_OPT (range) { range = 0; } PARAM_INT_OPT (flags) { flags = 0; } 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); @@ -1672,7 +1687,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) if (!(flags & CBAF_NORANDOM)) 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; @@ -1801,8 +1839,46 @@ enum FB_Flags FBF_NOPITCH = 8, FBF_NOFLASH = 16, 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) { PARAM_ACTION_PROLOGUE; @@ -1810,9 +1886,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) PARAM_ANGLE (spread_z); PARAM_INT (numbullets); 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_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; @@ -1851,7 +1930,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) if (!(flags & FBF_NORANDOM)) 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 { @@ -1878,7 +1974,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) if (!(flags & FBF_NORANDOM)) 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; @@ -5669,7 +5782,9 @@ enum RadiusGiveFlags RGF_MONSTERS | RGF_OBJECTS | 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) @@ -7068,3 +7183,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) } ACTION_RETURN_BOOL(true); } + diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index efb7be0c25..a86e98566b 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -265,6 +265,12 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags), DEFINE_FLAG(RF, FORCEYBILLBOARD, 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 DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags), diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index ca812e2e5b..35932e0be1 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -331,11 +331,11 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls) } else if (sc.CheckToken(TK_True)) { - return new FxConstant(1, scpos); + return new FxConstant(true, scpos); } else if (sc.CheckToken(TK_False)) { - return new FxConstant(0, scpos); + return new FxConstant(false, scpos); } else if (sc.CheckToken(TK_IntConst)) { diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index ac6b7eda3c..58820ea153 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -203,7 +203,6 @@ protected: public: virtual ~FxExpression() {} virtual FxExpression *Resolve(FCompileContext &ctx); - FxExpression *ResolveAsBoolean(FCompileContext &ctx); virtual bool isConstant() const; virtual void RequestAddress(); @@ -280,6 +279,13 @@ class FxConstant : public FxExpression ExpVal value; 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) { 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 { FxExpression *basex; @@ -384,18 +403,6 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; -class FxCastStateToBool : public FxExpression -{ - FxExpression *basex; - -public: - FxCastStateToBool(FxExpression *x); - ~FxCastStateToBool(); - FxExpression *Resolve(FCompileContext&); - - ExpEmit Emit(VMFunctionBuilder *build); -}; - //========================================================================== // // FxSign diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 04410189a0..b4a0b3fda1 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -177,38 +177,6 @@ FxExpression *FxExpression::Resolve(FCompileContext &ctx) 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(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) : 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) : FxExpression(operand->ScriptPosition) { @@ -765,10 +770,9 @@ FxExpression *FxUnaryNotBitwise::Resolve(FCompileContext& ctx) ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build) { - assert(ValueType == Operand->ValueType); - assert(ValueType == TypeSInt32); + assert(Operand->ValueType->GetRegType() == REGT_INT); ExpEmit from = Operand->Emit(build); - assert(from.Konst == 0); + assert(!from.Konst); // Do it in-place. build->Emit(OP_NOT, from.RegNum, from.RegNum, 0); return from; @@ -806,33 +810,23 @@ FxUnaryNotBoolean::~FxUnaryNotBoolean() FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (Operand) + SAFE_RESOLVE(Operand, ctx); + + if (Operand->ValueType != TypeBool) { - Operand = Operand->ResolveAsBoolean(ctx); - } - if (!Operand) - { - delete this; - return NULL; + Operand = new FxBoolCast(Operand); + SAFE_RESOLVE(Operand, ctx); } - if (Operand->IsNumeric() || Operand->IsPointer()) + if (Operand->isConstant()) { - if (Operand->isConstant()) - { - bool result = !static_cast(Operand)->GetValue().GetBool(); - FxExpression *e = new FxConstant(result, ScriptPosition); - delete this; - return e; - } - } - else - { - ScriptPosition.Message(MSG_ERROR, "Numeric type expected"); + bool result = !static_cast(Operand)->GetValue().GetBool(); + FxExpression *e = new FxConstant(result, ScriptPosition); delete this; - return NULL; + return e; } - ValueType = TypeSInt32; + + ValueType = TypeBool; return this; } @@ -844,32 +838,14 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx) ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build) { + assert(Operand->ValueType == ValueType); + assert(ValueType == TypeBool); ExpEmit from = Operand->Emit(build); assert(!from.Konst); - ExpEmit to(build, REGT_INT); - from.Free(build); - - // Preload result with 0. - 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; + // ~x & 1 + build->Emit(OP_NOT, from.RegNum, from.RegNum, 0); + build->Emit(OP_AND_RK, from.RegNum, from.RegNum, build->GetConstantInt(1)); + return from; } //========================================================================== @@ -914,6 +890,10 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric) return false; } + if (left->ValueType == TypeBool && right->ValueType == TypeBool) + { + ValueType = TypeBool; + } if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT) { ValueType = TypeSInt32; @@ -1276,7 +1256,7 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx) return e; } Promote(ctx); - ValueType = TypeSInt32; + ValueType = TypeBool; return this; } @@ -1327,7 +1307,7 @@ ExpEmit FxCompareRel::Emit(VMFunctionBuilder *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(instr, check, op1.RegNum, op2.RegNum); build->Emit(OP_JMP, 1); @@ -1392,7 +1372,7 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx) return e; } Promote(ctx); - ValueType = TypeSInt32; + ValueType = TypeBool; return this; } @@ -1600,7 +1580,7 @@ FxBinaryLogical::FxBinaryLogical(int o, FxExpression *l, FxExpression *r) Operator=o; left=l; right=r; - ValueType = TypeSInt32; + ValueType = TypeBool; } //========================================================================== @@ -1624,16 +1604,22 @@ FxBinaryLogical::~FxBinaryLogical() FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (left) left = left->ResolveAsBoolean(ctx); - if (right) right = right->ResolveAsBoolean(ctx); - if (!left || !right) + RESOLVE(left, ctx); + RESOLVE(right, ctx); + ABORT(right && left); + + if (left->ValueType != TypeBool) { - delete this; - return NULL; + left = new FxBoolCast(left); + SAFE_RESOLVE(left, ctx); + } + if (right->ValueType != TypeBool) + { + right = new FxBoolCast(right); + SAFE_RESOLVE(right, ctx); } int b_left=-1, b_right=-1; - if (left->isConstant()) b_left = static_cast(left)->GetValue().GetBool(); if (right->isConstant()) b_right = static_cast(right)->GetValue().GetBool(); @@ -1643,13 +1629,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { if (b_left==0 || b_right==0) { - FxExpression *x = new FxConstant(0, ScriptPosition); + FxExpression *x = new FxConstant(true, ScriptPosition); delete this; return x; } else if (b_left==1 && b_right==1) { - FxExpression *x = new FxConstant(1, ScriptPosition); + FxExpression *x = new FxConstant(false, ScriptPosition); delete this; return x; } @@ -1672,13 +1658,13 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) { if (b_left==1 || b_right==1) { - FxExpression *x = new FxConstant(1, ScriptPosition); + FxExpression *x = new FxConstant(true, ScriptPosition); delete this; return x; } if (b_left==0 && b_right==0) { - FxExpression *x = new FxConstant(0, ScriptPosition); + FxExpression *x = new FxConstant(false, ScriptPosition); delete this; return x; } @@ -1697,14 +1683,6 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx) return x; } } - if (left->ValueType->GetRegType() != REGT_INT) - { - left = new FxIntCast(left); - } - if (right->ValueType->GetRegType() != REGT_INT) - { - right = new FxIntCast(right); - } return this; } @@ -1804,17 +1782,25 @@ FxConditional::~FxConditional() FxExpression *FxConditional::Resolve(FCompileContext& ctx) { CHECKRESOLVED(); - if (condition) condition = condition->ResolveAsBoolean(ctx); + RESOLVE(condition, ctx); RESOLVE(truex, ctx); RESOLVE(falsex, ctx); 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; else if (truex->IsNumeric() && falsex->IsNumeric()) ValueType = TypeFloat64; //else if (truex->ValueType != falsex->ValueType) + if (condition->ValueType != TypeBool) + { + condition = new FxBoolCast(condition); + SAFE_RESOLVE(condition, ctx); + } + if (condition->isConstant()) { ExpVal condval = static_cast(condition)->GetValue(); @@ -1852,6 +1838,7 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx) ExpEmit FxConditional::Emit(VMFunctionBuilder *build) { + size_t truejump, falsejump; ExpEmit out; // The true and false expressions ought to be assigned to the @@ -1862,7 +1849,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) // Test condition. 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. if (truex->isConstant() && truex->ValueType->GetRegType() == REGT_INT) @@ -1886,9 +1873,11 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) out = trueop; } } + // Make sure to skip the false path. + truejump = build->Emit(OP_JMP, 0); // Evaluate false expression. - build->BackpatchToHere(patchspot); + build->BackpatchToHere(falsejump); if (falsex->isConstant() && falsex->ValueType->GetRegType() == REGT_INT) { build->EmitLoadInt(out.RegNum, static_cast(falsex)->GetValue().GetInt()); @@ -1918,6 +1907,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build) } } } + build->BackpatchToHere(truejump); return out; } @@ -3735,23 +3725,32 @@ FxIfStatement::~FxIfStatement() FxExpression *FxIfStatement::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); - if (WhenTrue == NULL && WhenFalse == NULL) + + if (WhenTrue == nullptr && WhenFalse == nullptr) { // We don't do anything either way, so disappear delete this; - return NULL; + return nullptr; } - Condition = Condition->ResolveAsBoolean(ctx); - ABORT(Condition); - if (WhenTrue != NULL) + + SAFE_RESOLVE(Condition, ctx); + + if (Condition->ValueType != TypeBool) + { + Condition = new FxBoolCast(Condition); + SAFE_RESOLVE(Condition, ctx); + } + + if (WhenTrue != nullptr) { WhenTrue = WhenTrue->Resolve(ctx); ABORT(WhenTrue); } - if (WhenFalse != NULL) + if (WhenFalse != nullptr) { WhenFalse = WhenFalse->Resolve(ctx); ABORT(WhenFalse); } + ValueType = TypeVoid; if (Condition->isConstant()) @@ -3766,6 +3765,7 @@ FxExpression *FxIfStatement::Resolve(FCompileContext &ctx) delete this; return e; } + return this; } diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index e4488de45c..c979302775 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -77,7 +77,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c sc.MustGetString(); 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); 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."); FScriptPosition::ErrorCounter++; } - // Do automatic coercion between ints and floats. - if (type == TypeSInt32) + // Do automatic coercion between bools, ints and floats. + if (type == TypeBool) + { + x = new FxBoolCast(x); + } + else if (type == TypeSInt32) { x = new FxIntCast(x); } @@ -306,6 +310,9 @@ static void ParseArgListDef(FScanner &sc, PClassActor *cls, switch (sc.TokenType) { case TK_Bool: + type = TypeBool; + break; + case TK_Int: type = TypeSInt32; break; @@ -477,8 +484,11 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls) sc.MustGetAnyToken(); switch (sc.TokenType) { - case TK_Int: case TK_Bool: + rets.Push(TypeBool); + break; + + case TK_Int: rets.Push(TypeSInt32); break; @@ -1064,7 +1074,11 @@ static void ParseActionDef (FScanner &sc, PClassActor *cls) // check for a return value 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); } diff --git a/strifehelp.acs b/strifehelp.acs index 9176ca006e..495893edf5 100644 --- a/strifehelp.acs +++ b/strifehelp.acs @@ -1,6 +1,7 @@ +#library "strfhelp" + #include "zcommon.acs" -#library "strfhelp" #define VDOORSPEED 16 #define VDOORWAIT 150 @@ -69,6 +70,7 @@ script << 0 >> (int type, int tag) case 230: i = GetLineRowOffset() & 31; + if (i == 0) break; if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Open (tag, VDOORSPEED); @@ -78,6 +80,7 @@ script << 0 >> (int type, int tag) case 227: i = GetLineRowOffset() & 31; + if (i == 0) break; if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Close (tag, VDOORSPEED); @@ -126,6 +129,7 @@ script << 0 >> (int type, int tag) case 193: i = GetLineRowOffset() & 31; + if (i == 0) break; if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Floor_LowerToLowest (tag, 8); @@ -158,6 +162,7 @@ script << 0 >> (int type, int tag) case 187: i = GetLineRowOffset() & 31; + if (i == 0) break; if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { ClearForceField (tag); @@ -203,6 +208,7 @@ script << 0 >> (int type, int tag) case 216: i = GetLineRowOffset() & 31; + if (i == 0) break; if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Raise (tag, VDOORSPEED, VDOORWAIT); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index a531838d03..8c35df21bb 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -34,15 +34,14 @@ ACTOR Actor native //: Thinker DefThreshold 100 BloodType "Blood", "BloodSplatter", "AxeBlood" ExplosionDamage 128 - MissileHeight 32 - + MissileHeight 32 // Functions native bool CheckClass(class checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false); native bool IsPointerEqual(int ptr_select1, int ptr_select2); native int CountInv(class itemtype, int ptr_select = 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 int GetSpawnHealth(); 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 state A_Jump(int chance = 256, state label, ...); native void A_CustomMissile(class 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 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 pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET, class 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 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 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_JumpIfCloser(float distance, state label, bool noz = false); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 7b75b481d1..05049e5984 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -38,6 +38,9 @@ const int CBAF_NORANDOM = 2; const int CBAF_EXPLICITANGLE = 4; const int CBAF_NOPITCH = 8; const int CBAF_NORANDOMPUFFZ = 16; +const int CBAF_PUFFTARGET = 32; +const int CBAF_PUFFMASTER = 64; +const int CBAF_PUFFTRACER = 128; // Flags for A_GunFlash const int GFF_NOEXTCHANGE = 1; @@ -210,6 +213,9 @@ const int CPF_STEALARMOR = 32; const int FPF_AIMATANGLE = 1; const int FPF_TRANSFERTRANSLATION = 2; const int FPF_NOAUTOAIM = 4; +const int FBF_PUFFTARGET = 64; +const int FBF_PUFFMASTER = 128; +const int FBF_PUFFTRACER = 256; // Flags for A_Teleport enum @@ -652,3 +658,9 @@ enum BT_USER3 = 1<<23, BT_USER4 = 1<<24, }; +// Flags for GetAngle +enum +{ + GAF_RELATIVE = 1, + GAF_SWITCH = 1 << 1, +}; \ No newline at end of file diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index a49dfd14cf..43a33f93aa 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -9,7 +9,7 @@ ACTOR Inventory native action native state A_JumpIfNoAmmo(state label); action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = ""); - action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class 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 pufftype = "BulletPuff", int flags = 1, float range = 0, class missile = "", float Spawnheight = 32, float Spawnofs_xy = 0); action native A_FireCustomMissile(class 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 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 spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0); action native A_Light(int extralight); diff --git a/wadsrc/static/filter/game-strife/acs/strfhelp.o b/wadsrc/static/filter/game-strife/acs/strfhelp.o index 45664cbc4e..521d887145 100644 Binary files a/wadsrc/static/filter/game-strife/acs/strfhelp.o and b/wadsrc/static/filter/game-strife/acs/strfhelp.o differ diff --git a/wadsrc/static/language.eng b/wadsrc/static/language.eng index ca27bf80ad..ed0f95a9ae 100644 --- a/wadsrc/static/language.eng +++ b/wadsrc/static/language.eng @@ -108,3 +108,5 @@ CMPTMNU_SECTORSOUNDS = "Sector sounds use centre as source"; OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only"; C_GRAY = "\ccgrey"; C_DARKGRAY = "\cudark grey"; +DSPLYMNU_MOVEBOB = "View bob amount while moving"; +DSPLYMNU_STILLBOB = "View bob amount while not moving"; diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 0bb3a84fdf..b0cbf4d911 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1839,6 +1839,7 @@ ALTHUDMNU_SHOWAMMO = "Show ammo for"; ALTHUDMNU_SHOWTIME = "Show time"; ALTHUDMNU_TIMECOLOR = "Time color"; ALTHUDMNU_SHOWLAG = "Show network latency"; +ALTHUDMNU_AMMOORDER = "Ammo display order"; ALTHUDMNU_AMMORED = "Red ammo display below %"; ALTHUDMNU_AMMOYELLOW = "Yellow ammo display below %"; ALTHUDMNU_HEALTHRED = "Red health display below"; @@ -2214,6 +2215,8 @@ OPTVAL_SYSTEMSECONDS = "System, seconds"; OPTVAL_SYSTEM = "System"; OPTVAL_NETGAMESONLY = "Netgames only"; OPTVAL_ALWAYS = "Always"; +OPTVAL_AMMOIMAGETEXT = "Image and Text"; +OPTVAL_AMMOTEXTIMAGE = "Text and Image"; OPTVAL_SCRIPTSONLY = "Scripts Only"; OPTVAL_NEVER = "Never"; OPTVAL_ALL = "All"; diff --git a/wadsrc/static/lockdefs.txt b/wadsrc/static/lockdefs.txt index 2167f935d8..04e4902244 100644 --- a/wadsrc/static/lockdefs.txt +++ b/wadsrc/static/lockdefs.txt @@ -5,6 +5,7 @@ ClearLocks Lock 1 Doom { + //$Title "Red key card" RedCard Message "$PD_REDC" RemoteMessage "$PD_REDCO" @@ -14,6 +15,7 @@ Lock 1 Doom Lock 2 Doom { + //$Title "Blue key card" BlueCard Message "$PD_BLUEC" RemoteMessage "$PD_BLUECO" @@ -23,6 +25,7 @@ Lock 2 Doom Lock 3 Doom { + //$Title "Yellow key card" YellowCard Message "$PD_YELLOWC" RemoteMessage "$PD_YELLOWCO" @@ -32,6 +35,7 @@ Lock 3 Doom Lock 4 Doom { + //$Title "Red skull" RedSkull Message "$PD_REDS" RemoteMessage "$PD_REDSO" @@ -41,6 +45,7 @@ Lock 4 Doom Lock 5 Doom { + //$Title "Blue skull" BlueSkull Message "$PD_BLUES" RemoteMessage "$PD_BLUESO" @@ -50,6 +55,7 @@ Lock 5 Doom Lock 6 Doom { + //$Title "Yellow skull" YellowSkull Message "$PD_YELLOWS" RemoteMessage "$PD_YELLOWSO" @@ -59,6 +65,7 @@ Lock 6 Doom Lock 129 Doom { + //$Title "Any red key" Any { RedCard RedSkull KeyGreen } Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -68,6 +75,7 @@ Lock 129 Doom Lock 130 Doom { + //$Title "Any blue key" Any { BlueCard BlueSkull KeyBlue } Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -77,6 +85,7 @@ Lock 130 Doom Lock 131 Doom { + //$Title "Any yellow key" Any { YellowCard YellowSkull KeyYellow } Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" @@ -86,6 +95,7 @@ Lock 131 Doom Lock 132 Doom { + //$Title "Red card or skull" Any { RedCard RedSkull } Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -95,6 +105,7 @@ Lock 132 Doom Lock 133 Doom { + //$Title "Blue card or skull" Any { BlueCard BlueSkull } Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -104,6 +115,7 @@ Lock 133 Doom Lock 134 Doom { + //$Title "Yellow card or skull" Any { YellowCard YellowSkull } Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" @@ -112,6 +124,7 @@ Lock 134 Doom Lock 100 { + //$Title "Any key" Message "$PD_ANY" RemoteMessage "$PD_ANYOBJ" Mapcolor 128 128 255 @@ -119,6 +132,7 @@ Lock 100 Lock 228 { + //$Title "Any key" Message "$PD_ANY" RemoteMessage "$PD_ANYOBJ" Mapcolor 128 128 255 @@ -126,6 +140,7 @@ Lock 228 Lock 229 Doom { + //$Title "One of each color" Any { BlueCard BlueSkull KeyBlue} Any { YellowCard YellowSkull KeyYellow} Any { RedCard RedSkull KeyGreen} @@ -135,6 +150,7 @@ Lock 229 Doom Lock 101 Doom { + //$Title "All keys" BlueCard BlueSkull YellowCard @@ -151,6 +167,7 @@ Lock 101 Doom Lock 1 Heretic { + //$Title "Green key" KeyGreen Message "$TXT_NEEDGREENKEY" Mapcolor 0 255 0 @@ -159,6 +176,7 @@ Lock 1 Heretic Lock 2 Heretic { + //$Title "Blue key" KeyBlue Message "$TXT_NEEDBLUEKEY" Mapcolor 0 0 255 @@ -167,6 +185,7 @@ Lock 2 Heretic Lock 3 Heretic { + //$Title "Yellow key" KeyYellow Message "$TXT_NEEDYELLOWKEY" Mapcolor 255 255 0 @@ -175,6 +194,7 @@ Lock 3 Heretic Lock 129 Heretic { + //$Title "Green key" KeyGreen Message "$TXT_NEEDGREENKEY" Mapcolor 0 255 0 @@ -183,6 +203,7 @@ Lock 129 Heretic Lock 130 Heretic { + //$Title "Blue key" KeyBlue Message "$TXT_NEEDBLUEKEY" Mapcolor 0 0 255 @@ -191,6 +212,7 @@ Lock 130 Heretic Lock 131 Heretic { + //$Title "Yellow key" KeyYellow Message "$TXT_NEEDYELLOWKEY" Mapcolor 255 255 0 @@ -199,6 +221,7 @@ Lock 131 Heretic Lock 229 Heretic { + //$Title "All keys" KeyGreen KeyYellow KeyBlue @@ -208,6 +231,7 @@ Lock 229 Heretic Lock 101 Heretic { + //$Title "All keys" KeyGreen KeyYellow KeyBlue @@ -222,6 +246,7 @@ Lock 101 Heretic Lock 1 Hexen { + //$Title "Steel key" KeySteel Message "$TXT_NEED_KEY_STEEL" Mapcolor 150 150 150 @@ -230,6 +255,7 @@ Lock 1 Hexen Lock 2 Hexen { + //$Title "Cave key" KeyCave Message "$TXT_NEED_KEY_CAVE" Mapcolor 255 218 0 @@ -238,6 +264,7 @@ Lock 2 Hexen Lock 3 Hexen { + //$Title "Axe key" KeyAxe Message "$TXT_NEED_KEY_AXE" Mapcolor 64 64 255 @@ -246,6 +273,7 @@ Lock 3 Hexen Lock 4 Hexen { + //$Title "Fire key" KeyFire Message "$TXT_NEED_KEY_FIRE" Mapcolor 255 128 0 @@ -254,6 +282,7 @@ Lock 4 Hexen Lock 5 Hexen { + //$Title "Emerald key" KeyEmerald Message "$TXT_NEED_KEY_EMERALD" Mapcolor 0 255 0 @@ -262,6 +291,7 @@ Lock 5 Hexen Lock 6 Hexen { + //$Title "Dungeon key" KeyDungeon Message "$TXT_NEED_KEY_DUNGEON" Mapcolor 47 151 255 @@ -270,6 +300,7 @@ Lock 6 Hexen Lock 7 Hexen { + //$Title "Silver key" KeySilver Message "$TXT_NEED_KEY_SILVER" Mapcolor 154 152 188 @@ -278,6 +309,7 @@ Lock 7 Hexen Lock 8 Hexen { + //$Title "Rusted key" KeyRusted Message "$TXT_NEED_KEY_RUSTED" Mapcolor 156 76 0 @@ -286,6 +318,7 @@ Lock 8 Hexen Lock 9 Hexen { + //$Title "Horn key" KeyHorn Message "$TXT_NEED_KEY_HORN" Mapcolor 255 218 0 @@ -294,6 +327,7 @@ Lock 9 Hexen Lock 10 Hexen { + //$Title "Swamp key" KeySwamp Message "$TXT_NEED_KEY_SWAMP" Mapcolor 64 255 64 @@ -302,6 +336,7 @@ Lock 10 Hexen Lock 11 Hexen { + //$Title "Castle key" KeyCastle Message "$TXT_NEED_KEY_CASTLE" Mapcolor 255 64 64 @@ -310,6 +345,7 @@ Lock 11 Hexen Lock 101 Hexen { + //$Title "All keys" KeySteel KeyCave KeyAxe @@ -326,6 +362,7 @@ Lock 101 Hexen Lock 229 Hexen { + //$Title "All keys" KeySteel KeyCave KeyAxe @@ -345,14 +382,16 @@ Lock 229 Hexen Lock 1 Strife { + //$Title "Base key" BaseKey - Message "You don't have the key" + Message "$TXT_NEEDKEY" Mapcolor 150 150 150 } Lock 2 Strife { + //$Title "Governor's key" GovsKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -361,6 +400,7 @@ Lock 2 Strife Lock 3 Strife { + //$Title "Travel passcard" Passcard RemoteMessage "$TXT_NEED_PASSCARD" Message "$TXT_NEED_PASSCARD_DOOR" @@ -370,6 +410,7 @@ Lock 3 Strife Lock 4 Strife { + //$Title "ID badge" IDBadge Message "$TXT_NEED_IDCARD" Mapcolor 255 128 0 @@ -378,6 +419,7 @@ Lock 4 Strife Lock 5 Strife { + //$Title "Prison key" PrisonKey Message "$TXT_NEED_PRISONKEY" Mapcolor 0 255 0 @@ -386,6 +428,7 @@ Lock 5 Strife Lock 6 Strife { + //$Title "Severed hand" SeveredHand Message "$TXT_NEED_HANDPRINT" Mapcolor 255 151 100 @@ -394,6 +437,7 @@ Lock 6 Strife Lock 7 Strife { + //$Title "Power key 1" Power1Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -402,6 +446,7 @@ Lock 7 Strife Lock 8 Strife { + //$Title "Power key 2" Power2Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -410,6 +455,7 @@ Lock 8 Strife Lock 9 Strife { + //$Title "Power key 3" Power3Key Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -418,6 +464,7 @@ Lock 9 Strife Lock 10 Strife { + //$Title "Gold key" GoldKey Message "$TXT_NEED_GOLDKEY" Mapcolor 255 200 0 @@ -426,6 +473,7 @@ Lock 10 Strife Lock 11 Strife { + //$Title "ID card" IDCard RemoteMessage "$TXT_NEED_IDBADGE" Message "$TXT_NEED_IDBADGE_DOOR" @@ -434,6 +482,7 @@ Lock 11 Strife Lock 12 Strife { + //$Title "Silver key" SilverKey Message "$TXT_NEED_SILVERKEY" Mapcolor 150 150 150 @@ -441,6 +490,7 @@ Lock 12 Strife Lock 13 Strife { + //$Title "Oracle key" OracleKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -448,6 +498,7 @@ Lock 13 Strife Lock 14 Strife { + //$Title "Military key" MilitaryID Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -455,6 +506,7 @@ Lock 14 Strife Lock 15 Strife { + //$Title "Order key" OrderKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -462,6 +514,7 @@ Lock 15 Strife Lock 16 Strife { + //$Title "Warehouse key" WarehouseKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -469,6 +522,7 @@ Lock 16 Strife Lock 17 Strife { + //$Title "Brass key" BrassKey Message "$TXT_NEED_BRASSKEY" Mapcolor 150 75 0 @@ -476,6 +530,7 @@ Lock 17 Strife Lock 18 Strife { + //$Title "Red crystal key" RedCrystalKey Message "$TXT_NEED_REDCRYSTAL" Mapcolor 150 150 150 @@ -483,6 +538,7 @@ Lock 18 Strife Lock 19 Strife { + //$Title "Blue crystal key" BlueCrystalKey Message "$TXT_NEED_BLUECRYSTAL" Mapcolor 150 150 150 @@ -490,6 +546,7 @@ Lock 19 Strife Lock 20 Strife { + //$Title "Chapel key" ChapelKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -497,6 +554,7 @@ Lock 20 Strife Lock 21 Strife { + //$Title "Catacomb key" CatacombKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -504,6 +562,7 @@ Lock 21 Strife Lock 22 Strife { + //$Title "Security key" SecurityKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -511,6 +570,7 @@ Lock 22 Strife Lock 23 Strife { + //$Title "Core key" CoreKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -518,6 +578,7 @@ Lock 23 Strife Lock 24 Strife { + //$Title "Mauler key" MaulerKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -525,6 +586,7 @@ Lock 24 Strife Lock 25 Strife { + //$Title "Factory key" FactoryKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -532,6 +594,7 @@ Lock 25 Strife Lock 26 Strife { + //$Title "Mine key" MineKey Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -539,6 +602,7 @@ Lock 26 Strife Lock 27 Strife { + //$Title "New key 5" NewKey5 Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -546,6 +610,7 @@ Lock 27 Strife Lock 50 Strife { + //$Title "Prison key" PrisonPass Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -553,6 +618,7 @@ Lock 50 Strife Lock 51 Strife { + //$Title "Oracle pass" OraclePass Message "$TXT_NEEDKEY" Mapcolor 150 150 150 @@ -564,6 +630,7 @@ Lock 51 Strife Lock 1 Chex { + //$Title "Red key card" ChexRedCard Message "$PD_REDC" RemoteMessage "$PD_REDCO" @@ -573,6 +640,7 @@ Lock 1 Chex Lock 2 Chex { + //$Title "Blue key card" ChexBlueCard Message "$PD_BLUEC" RemoteMessage "$PD_BLUECO" @@ -582,6 +650,7 @@ Lock 2 Chex Lock 3 Chex { + //$Title "Yellow key card" ChexYellowCard Message "$PD_YELLOWC" RemoteMessage "$PD_YELLOWCO" @@ -590,6 +659,7 @@ Lock 3 Chex Lock 129 Chex { + //$Title "Red key" ChexRedCard Message "$PD_REDK" RemoteMessage "$PD_REDO" @@ -599,6 +669,7 @@ Lock 129 Chex Lock 130 Chex { + //$Title "Blue key" ChexBlueCard Message "$PD_BLUEK" RemoteMessage "$PD_BLUEO" @@ -608,6 +679,7 @@ Lock 130 Chex Lock 131 Chex { + //$Title "Yellow key" ChexYellowCard Message "$PD_YELLOWK" RemoteMessage "$PD_YELLOWO" diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 679db909b5..c1f6fd8051 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -692,6 +692,8 @@ OptionMenu "VideoOptions" Option "$DSPLYMNU_NOMONSTERINTERPOLATION", "nomonsterinterpolation", "NoYes" Slider "$DSPLYMNU_MENUDIM", "dimamount", 0, 1.0, 0.05, 2 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" } +OptionValue "AltHUDAmmoOrder" +{ + 0, "$OPTVAL_AMMOIMAGETEXT" + 1, "$OPTVAL_AMMOTEXTIMAGE" +} + OptionMenu "AltHUDOptions" { Title "$ALTHUDMNU_TITLE" @@ -839,6 +847,7 @@ OptionMenu "AltHUDOptions" Option "$ALTHUDMNU_SHOWTIME", "hud_showtime", "AltHUDTime" Option "$ALTHUDMNU_TIMECOLOR", "hud_timecolor", "TextColors" 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_AMMOYELLOW", "hud_ammo_yellow", 0, 100, 1, 0 Slider "$ALTHUDMNU_HEALTHRED", "hud_health_red", 0, 100, 1, 0 diff --git a/wadsrc/static/xlat/eternity.txt b/wadsrc/static/xlat/eternity.txt index bc5159d11b..4db96f2da5 100644 --- a/wadsrc/static/xlat/eternity.txt +++ b/wadsrc/static/xlat/eternity.txt @@ -234,3 +234,20 @@ enum 447 = 0, Exit_Normal(0) 448 = 0, Exit_Secret(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)