From 6e2b0bc961125b9a72606893c5b6233ba54ed2ed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 19:32:44 +0100 Subject: [PATCH 01/12] - renamed the internal InpuEvent to deconflict from the version in the event system. --- wadsrc/static/zscript/base.txt | 2 +- wadsrc/static/zscript/menu/listmenu.txt | 2 +- wadsrc/static/zscript/menu/menu.txt | 2 +- wadsrc/static/zscript/menu/optionmenu.txt | 8 ++++---- wadsrc/static/zscript/menu/optionmenuitems.txt | 6 +++--- wadsrc/static/zscript/menu/videomenu.txt | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index e354fe594..22bbcc790 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -1,4 +1,4 @@ -struct InputEvent native +struct InputEventData native { native uint8 type; native uint8 subtype; diff --git a/wadsrc/static/zscript/menu/listmenu.txt b/wadsrc/static/zscript/menu/listmenu.txt index 742089a39..d920dc26c 100644 --- a/wadsrc/static/zscript/menu/listmenu.txt +++ b/wadsrc/static/zscript/menu/listmenu.txt @@ -86,7 +86,7 @@ class ListMenu : Menu native return NULL; } - //bool Responder (InputEvent ev); + //bool Responder (InputEventData ev); //bool MenuEvent (int mkey, bool fromcontroller); //bool MouseEvent(int type, int x, int y); //void Ticker (); diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index f0dacb017..1640e9d35 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -105,7 +105,7 @@ class Menu : Object native virtual void ReleaseFocus() {} virtual void ResetColor() {} - native virtual bool Responder(InputEvent ev); + native virtual bool Responder(InputEventData ev); native virtual bool MenuEvent (int mkey, bool fromcontroller); native virtual bool MouseEvent(int type, int mx, int my); native virtual void Ticker(); diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index 9eb26ac86..5b06f3020 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -120,17 +120,17 @@ class OptionMenu : Menu // //============================================================================= - override bool Responder (InputEvent ev) + override bool Responder (InputEventData ev) { - if (ev.type == InputEvent.GUI_Event) + if (ev.type == InputEventData.GUI_Event) { - if (ev.subtype == InputEvent.GUI_WheelUp) + if (ev.subtype == InputEventData.GUI_WheelUp) { int scrollamt = MIN(2, mDesc.mScrollPos); mDesc.mScrollPos -= scrollamt; return true; } - else if (ev.subtype == InputEvent.GUI_WheelDown) + else if (ev.subtype == InputEventData.GUI_WheelDown) { if (CanScrollDown) { diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index ad4e45677..8efe0cfb9 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -396,16 +396,16 @@ class EnterKey : Menu } } - override bool Responder(InputEvent ev) + override bool Responder(InputEventData ev) { // This checks raw keys, not GUI keys. - if (ev.type == InputEvent.KeyDown) + if (ev.type == InputEventData.KeyDown) { mOwner.SendKey(ev.data1); menuactive = Menu.On; SetMenuMessage(0); Close(); - mParentMenu.MenuEvent((ev.data1 == InputEvent.KEY_ESCAPE)? Menu.MKEY_Abort : Menu.MKEY_Input, 0); + mParentMenu.MenuEvent((ev.data1 == InputEventData.KEY_ESCAPE)? Menu.MKEY_Abort : Menu.MKEY_Input, 0); return true; } return false; diff --git a/wadsrc/static/zscript/menu/videomenu.txt b/wadsrc/static/zscript/menu/videomenu.txt index a162781eb..1377f528e 100644 --- a/wadsrc/static/zscript/menu/videomenu.txt +++ b/wadsrc/static/zscript/menu/videomenu.txt @@ -57,9 +57,9 @@ class VideoModeMenu : OptionMenu return Super.MenuEvent(mkey, fromcontroller); } - override bool Responder(InputEvent ev) + override bool Responder(InputEventData ev) { - if (ev.type == InputEvent.GUI_Event && ev.subtype == InputEvent.GUI_KeyDown && (ev.data1 == 0x54 || ev.data1 == 0x74)) + if (ev.type == InputEventData.GUI_Event && ev.subtype == InputEventData.GUI_KeyDown && (ev.data1 == 0x54 || ev.data1 == 0x74)) { if (SetSelectedSize()) { From 9e769f29c33fe6e025e888911ed4020ad2ebc7b3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 19:34:01 +0100 Subject: [PATCH 02/12] - the native part wasn't saved. --- src/d_main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index d5c6867ac..04fd24d76 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2838,10 +2838,10 @@ void FStartupScreen::NetMessage(char const *,...) {} void FStartupScreen::NetDone(void) {} bool FStartupScreen::NetLoop(bool (*)(void *),void *) { return false; } -DEFINE_FIELD_X(InputEvent, event_t, type) -DEFINE_FIELD_X(InputEvent, event_t, subtype) -DEFINE_FIELD_X(InputEvent, event_t, data1) -DEFINE_FIELD_X(InputEvent, event_t, data2) -DEFINE_FIELD_X(InputEvent, event_t, data3) -DEFINE_FIELD_X(InputEvent, event_t, x) -DEFINE_FIELD_X(InputEvent, event_t, y) +DEFINE_FIELD_X(InputEventData, event_t, type) +DEFINE_FIELD_X(InputEventData, event_t, subtype) +DEFINE_FIELD_X(InputEventData, event_t, data1) +DEFINE_FIELD_X(InputEventData, event_t, data2) +DEFINE_FIELD_X(InputEventData, event_t, data3) +DEFINE_FIELD_X(InputEventData, event_t, x) +DEFINE_FIELD_X(InputEventData, event_t, y) From b7b0e644716858928a2f7812cbd3f2f51d7e4b7b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 20:11:30 +0100 Subject: [PATCH 03/12] - separated splash detection from water level setting. This could cause problems if 3D floors with different properties for slashing and waterlevel were occupied at the same time. By keeping the slash code separate both parts can be handled without having to look out for the other. --- src/actor.h | 1 + src/p_mobj.cpp | 130 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 24 deletions(-) diff --git a/src/actor.h b/src/actor.h index 77c7f81a4..a973c101a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1230,6 +1230,7 @@ public: bool InStateSequence(FState * newstate, FState * basestate); int GetTics(FState * newstate); bool SetState (FState *newstate, bool nofunction=false); + virtual void SplashCheck(); virtual bool UpdateWaterLevel (bool splash=true); bool isFast(); bool isSlow(); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d879d206d..81fab5733 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4540,23 +4540,22 @@ void AActor::CheckSectorTransition(sector_t *oldsec) //========================================================================== // -// AActor::UpdateWaterLevel +// AActor::SplashCheck // // Returns true if actor should splash // //========================================================================== -bool AActor::UpdateWaterLevel (bool dosplash) +void AActor::SplashCheck() { - BYTE lastwaterlevel = waterlevel; double fh = -FLT_MAX; - bool reset=false; + bool reset = false; waterlevel = 0; if (Sector == NULL) { - return false; + return; } if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK @@ -4568,7 +4567,7 @@ bool AActor::UpdateWaterLevel (bool dosplash) const sector_t *hsec = Sector->GetHeightSec(); if (hsec != NULL) { - fh = hsec->floorplane.ZatPoint (this); + fh = hsec->floorplane.ZatPoint(this); //if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors { if (Z() < fh) @@ -4584,7 +4583,7 @@ bool AActor::UpdateWaterLevel (bool dosplash) } } } - else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint (this))) + else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this))) { waterlevel = 3; } @@ -4593,29 +4592,23 @@ bool AActor::UpdateWaterLevel (bool dosplash) waterlevel = 0; } } - // even non-swimmable deep water must be checked here to do the splashes correctly - // But the water level must be reset when this function returns - if (!(hsec->MoreFlags&SECF_UNDERWATERMASK)) - { - reset = true; - } } else { // Check 3D floors as well! - for(auto rover : Sector->e->XFloor.ffloors) + for (auto rover : Sector->e->XFloor.ffloors) { if (!(rover->flags & FF_EXISTS)) continue; if (rover->flags & FF_SOLID) continue; - reset = !(rover->flags & FF_SWIMMABLE); + bool reset = !(rover->flags & FF_SWIMMABLE); if (reset && rover->alpha == 0) continue; - double ff_bottom=rover->bottom.plane->ZatPoint(this); - double ff_top=rover->top.plane->ZatPoint(this); + double ff_bottom = rover->bottom.plane->ZatPoint(this); + double ff_top = rover->top.plane->ZatPoint(this); - if(ff_top <= Z() || ff_bottom > (Center())) continue; - - fh=ff_top; + if (ff_top <= Z() || ff_bottom > (Center())) continue; + + fh = ff_top; if (Z() < fh) { waterlevel = 1; @@ -4634,17 +4627,106 @@ bool AActor::UpdateWaterLevel (bool dosplash) } } } - + // some additional checks to make deep sectors like Boom's splash without setting // the water flags. - if (boomwaterlevel == 0 && waterlevel != 0 && dosplash) + if (boomwaterlevel == 0 && waterlevel != 0) { P_HitWater(this, Sector, PosAtZ(fh), true); } boomwaterlevel = waterlevel; - if (reset) + return; +} + +//========================================================================== +// +// AActor::UpdateWaterLevel +// +// Returns true if actor should splash +// +//========================================================================== + +bool AActor::UpdateWaterLevel(bool dosplash) +{ + if (dosplash) SplashCheck(); + + double fh = -FLT_MAX; + bool reset = false; + + waterlevel = 0; + + if (Sector == NULL) { - waterlevel = lastwaterlevel; + return false; + } + + if (Sector->MoreFlags & SECF_UNDERWATER) // intentionally not SECF_UNDERWATERMASK + { + waterlevel = 3; + } + else + { + const sector_t *hsec = Sector->GetHeightSec(); + if (hsec != NULL) + { + fh = hsec->floorplane.ZatPoint(this); + if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors + { + if (Z() < fh) + { + waterlevel = 1; + if (Center() < fh) + { + waterlevel = 2; + if ((player && Z() + player->viewheight <= fh) || + (Top() <= fh)) + { + waterlevel = 3; + } + } + } + else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this))) + { + waterlevel = 3; + } + else + { + waterlevel = 0; + } + } + } + else + { + // Check 3D floors as well! + for (auto rover : Sector->e->XFloor.ffloors) + { + if (!(rover->flags & FF_EXISTS)) continue; + if (rover->flags & FF_SOLID) continue; + if (!(rover->flags & FF_SWIMMABLE)) continue; + + double ff_bottom = rover->bottom.plane->ZatPoint(this); + double ff_top = rover->top.plane->ZatPoint(this); + + if (ff_top <= Z() || ff_bottom > (Center())) continue; + + fh = ff_top; + if (Z() < fh) + { + waterlevel = 1; + if (Center() < fh) + { + waterlevel = 2; + if ((player && Z() + player->viewheight <= fh) || + (Top() <= fh)) + { + waterlevel = 3; + } + } + } + + break; + } + } } return false; // we did the splash ourselves } From dd0f55e8d85c4ca4c2b79944c4dd5c36f7b5e6e6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 14 Feb 2017 22:02:47 +0200 Subject: [PATCH 04/12] Fixed compilation of Cocoa backend --- src/posix/cocoa/i_input.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/posix/cocoa/i_input.mm b/src/posix/cocoa/i_input.mm index 5f4aec801..cb39c049a 100644 --- a/src/posix/cocoa/i_input.mm +++ b/src/posix/cocoa/i_input.mm @@ -91,13 +91,15 @@ size_t s_skipMouseMoves; void CheckGUICapture() { - const bool wantCapture = (MENU_Off == menuactive) + bool wantCapture = (MENU_Off == menuactive) ? (c_down == ConsoleState || c_falling == ConsoleState || chatmodeon) : (MENU_On == menuactive || MENU_OnNoPause == menuactive); // [ZZ] check active event handlers that want the UI processing if (!wantCapture && E_CheckUiProcessors()) + { wantCapture = true; + } if (wantCapture != GUICapture) { From a9f650c3f22fa35bd18807db7df1222cadee48e0 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 14 Feb 2017 22:13:31 +0200 Subject: [PATCH 05/12] Fixed compilation warnings reported by GCC/Clang src/events.cpp:167:66: warning: format specifies type 'char *' but the argument has type 'char' [-Wformat] src/events.cpp:167:84: warning: data argument not used by format string [-Wformat-extra-args] src/events.cpp:1036:20: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare] --- src/events.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/events.cpp b/src/events.cpp index 95a5af587..4522f1989 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -164,7 +164,7 @@ static void E_InitStaticHandler(PClass* type, FString typestring, bool map) { if (type == nullptr) { - I_Error("Fatal: unknown event handler class %s in MAPINFO!\n", TEXTCOLOR_ESCAPE, typestring.GetChars()); + I_Error("Fatal: unknown event handler class %s in MAPINFO!\n", typestring.GetChars()); return; } @@ -1033,7 +1033,7 @@ static DConsoleEvent* E_SetupConsoleEvent() if (!e) e = (DConsoleEvent*)RUNTIME_CLASS(DConsoleEvent)->CreateNew(); e->Player = -1; e->Name = ""; - for (int i = 0; i < countof(e->Args); i++) + for (size_t i = 0; i < countof(e->Args); i++) e->Args[i] = 0; return e; } @@ -1114,4 +1114,4 @@ CCMD(netevent) for (int i = 0; i < argn; i++) Net_WriteLong(arg[i]); } -} \ No newline at end of file +} From 3170591e32402a595332b73d2a3fdfa360c57a33 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 21:08:48 +0100 Subject: [PATCH 06/12] - restated some weird number manipulation in SBARINFO for powerup time. This appears to be needed to distinguish between non-expiring items and non-present items. --- src/g_statusbar/sbarinfo_commands.cpp | 2 +- wadsrc/static/zscript/shared/player.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 6e6b55bec..ae6ba5b00 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -1442,7 +1442,7 @@ class CommandDrawNumber : public CommandDrawString int retv; VMReturn ret(&retv); GlobalVMStack.Call(func, params, 2, &ret, 1); - num = retv / TICRATE + 1; + num = retv < 0? 0 : retv / TICRATE + 1; break; } case INVENTORY: diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 7b8ba8f30..9039b37b6 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -130,7 +130,7 @@ class PlayerPawn : Actor native return powerup.EffectTics, maxtics; } } - return 0, 0; + return -1, -1; } native int GetMaxHealth(); From a6156297ce3602dce73f1caa0805a23294b4799e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 22:03:46 +0100 Subject: [PATCH 07/12] - don't adjust sprite offsets of IWAD sprites in sequences which have been replaced partially. This can be overridden by specifying 'iwadforced' in the SPROFS lump. --- src/gl/data/gl_data.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index bd185f76f..93e4d5697 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -97,6 +97,28 @@ void gl_CreateSections(); void AdjustSpriteOffsets() { int lump, lastlump = 0; + int sprid; + TMap donotprocess; + + int numtex = Wads.GetNumLumps(); + + for (int i = 0; i < numtex; i++) + { + if (Wads.GetLumpFile(i) > 1) break; // we are past the IWAD + if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == FWadCollection::IWAD_FILENUM) + { + char str[9]; + Wads.GetLumpName(str, i); + FTextureID texid = TexMan.CheckForTexture(str, FTexture::TEX_Sprite, 0); + if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > FWadCollection::IWAD_FILENUM) + { + // This texture has been replaced by some PWAD. + memcpy(&sprid, str, 4); + donotprocess[sprid] = true; + } + } + } + while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1) { FScanner sc; @@ -108,6 +130,7 @@ void AdjustSpriteOffsets() { int x,y; bool iwadonly = false; + bool forced = false; FTextureID texno = TexMan.CheckForTexture(sc.String, FTexture::TEX_Sprite); sc.MustGetStringName(","); sc.MustGetNumber(); @@ -119,6 +142,7 @@ void AdjustSpriteOffsets() { sc.MustGetString(); if (sc.Compare("iwad")) iwadonly = true; + if (sc.Compare("iwadforced")) forced = iwadonly = true; } if (texno.isValid()) { @@ -131,6 +155,11 @@ void AdjustSpriteOffsets() int wadno = Wads.GetLumpFile(lumpnum); if ((iwadonly && wadno==FWadCollection::IWAD_FILENUM) || (!iwadonly && wadno == ofslumpno)) { + if (wadno == FWadCollection::IWAD_FILENUM && !forced && iwadonly) + { + memcpy(&sprid, &tex->Name[0], 4); + if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced. + } tex->LeftOffset=x; tex->TopOffset=y; tex->KillNative(); From c5204f34ca18b03d3daf70f6cc51e582177a5b07 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 22:51:53 +0100 Subject: [PATCH 08/12] - fixed: The code to play the mage lightning's attack sound was converted wrong, because it used the same structure as looping sounds normally so, but doesn't actually loop. --- src/p_actionfunctions.cpp | 5 ++++- src/s_sound.h | 1 + wadsrc/static/zscript/constants.txt | 3 ++- wadsrc/static/zscript/hexen/magelightning.txt | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 69ca13f16..40629bfcb 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1021,7 +1021,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlaySound) if (!looping) { - S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local); + if (!(channel & CHAN_NOSTOP) || !S_IsActorPlayingSomething(self, channel & 7, soundid)) + { + S_PlaySound(self, channel, soundid, (float)volume, (float)attenuation, local); + } } else { diff --git a/src/s_sound.h b/src/s_sound.h index d6d2a5403..00c7d0587 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -284,6 +284,7 @@ void S_PlaySound(AActor *a, int chan, FSoundID sid, float vol, float atten, bool #define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet. #define CHAN_ABSTIME 1024// internal: Start time is absolute and does not depend on current time. #define CHAN_VIRTUAL 2048// internal: Channel is currently virtual +#define CHAN_NOSTOP 4096// only for A_PlaySound. Does not start if channel is playing something. // sound attenuation values #define ATTN_NONE 0.f // full volume the entire level diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index ef2c4521f..6996da6cc 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -413,7 +413,8 @@ enum ESoundFlags CHAN_MAYBE_LOCAL = 16, CHAN_UI = 32, CHAN_NOPAUSE = 64, - CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL) + CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL), + CHAN_NOSTOP = 4096 }; diff --git a/wadsrc/static/zscript/hexen/magelightning.txt b/wadsrc/static/zscript/hexen/magelightning.txt index 343c96012..d45162d49 100644 --- a/wadsrc/static/zscript/hexen/magelightning.txt +++ b/wadsrc/static/zscript/hexen/magelightning.txt @@ -124,7 +124,7 @@ class Lightning : Actor if ((!thing.player && !thing.bBoss) || !(level.time&1)) { thing.DamageMobj(self, target, 3, 'Electric'); - A_PlaySound(AttackSound, CHAN_WEAPON, 1, true); + A_PlaySound(AttackSound, CHAN_WEAPON|CHAN_NOSTOP, 1, false); if (thing.bIsMonster && random[LightningHit]() < 64) { thing.Howl (); From 2f1b5c375ecd28285536774d95b971fd8d85367f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 23:13:29 +0100 Subject: [PATCH 09/12] - fixed: Line_SetPortal crashed with one-way portals. --- src/portal.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/portal.cpp b/src/portal.cpp index f354faa65..4ba334225 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -225,7 +225,7 @@ static line_t *FindDestination(line_t *src, int tag) } } } - return NULL; + return nullptr; } @@ -275,7 +275,7 @@ static void SetRotation(FLinePortal *port) void P_SpawnLinePortal(line_t* line) { // portal destination is special argument #0 - line_t* dst = NULL; + line_t* dst = nullptr; if (line->args[2] >= PORTT_VISUAL && line->args[2] <= PORTT_LINKED) { @@ -304,7 +304,7 @@ void P_SpawnLinePortal(line_t* line) port->mType = PORTT_TELEPORT; } } - if (port->mDestination != NULL) + if (port->mDestination != nullptr) { port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE; } @@ -357,7 +357,7 @@ void P_SpawnLinePortal(line_t* line) void P_UpdatePortal(FLinePortal *port) { - if (port->mDestination == NULL) + if (port->mDestination == nullptr) { // Portal has no destination: switch it off port->mFlags = 0; @@ -442,16 +442,16 @@ static bool ChangePortalLine(line_t *line, int destid) if (line->portalindex >= linePortals.Size()) return false; FLinePortal *port = &linePortals[line->portalindex]; if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed. - if (destid == 0) port->mDestination = NULL; + if (destid == 0) port->mDestination = nullptr; port->mDestination = FindDestination(line, destid); - if (port->mDestination == NULL) + if (port->mDestination == nullptr) { port->mFlags = 0; } else if (port->mType == PORTT_INTERACTIVE) { - FLinePortal *portd = &linePortals[port->mDestination->portalindex]; - if (portd != NULL && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line) + FLinePortal *portd = port->mDestination->portalindex < linePortals.Size()? &linePortals[port->mDestination->portalindex] : nullptr; + if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line) { // this is a 2-way interactive portal port->mFlags = port->mDefFlags | PORTF_INTERACTIVE; @@ -662,7 +662,7 @@ void P_TranslatePortalZ(line_t* src, double& z) unsigned P_GetSkyboxPortal(AActor *actor) { - if (actor == NULL) return 1; // this means a regular sky. + if (actor == nullptr) return 1; // this means a regular sky. for (unsigned i = 0;iLines) { sector_t *other = line->frontsector == sec ? line->backsector : line->frontsector; - if (other != NULL && other != sec && other->PortalGroup != groupid) + if (other != nullptr && other != sec && other->PortalGroup != groupid) { other->PortalGroup = groupid; list.Push(other); @@ -1098,10 +1098,10 @@ void P_CreateLinkedPortals() } // reject would just get in the way when checking sight through portals. - if (Displacements.size > 1 && rejectmatrix != NULL) + if (Displacements.size > 1 && rejectmatrix != nullptr) { delete[] rejectmatrix; - rejectmatrix = NULL; + rejectmatrix = nullptr; } // finally we must flag all planes which are obstructed by the sector's own ceiling or floor. for (auto &sec : level.sectors) From c01289e9993345c6fcd362e5bb41c321d87ace86 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 14 Feb 2017 23:28:49 +0100 Subject: [PATCH 10/12] - added ZScript property handling for names, sounds and colors. --- src/scripting/decorate/thingdef_parse.cpp | 15 +++++++++++++++ src/scripting/zscript/zcc_compile.cpp | 14 +++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index 23ffc48e8..991577f68 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -840,6 +840,21 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul bool val = sc.CheckNumber() ? !!sc.Number : true; static_cast(f->Type)->SetValue(addr, !!val); } + else if (f->Type == TypeName) + { + sc.MustGetString(); + *(FName*)addr = sc.String; + } + else if (f->Type == TypeSound) + { + sc.MustGetString(); + *(FSoundID*)addr = sc.String; + } + else if (f->Type == TypeColor) + { + if (sc.CheckNumber()) *(int*)addr = sc.Number; + else *(PalEntry*)addr = V_GetColor(nullptr, sc); + } else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt))) { sc.MustGetNumber(); diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 65d08fb92..a240c1973 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1720,7 +1720,19 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop { static_cast(f->Type)->SetValue(addr, !!GetIntConst(ex, ctx)); } - if (f->Type->IsKindOf(RUNTIME_CLASS(PInt))) + else if (f->Type == TypeName) + { + *(FName*)addr = GetStringConst(ex, ctx); + } + else if (f->Type == TypeSound) + { + *(FSoundID*)addr = GetStringConst(ex, ctx); + } + else if (f->Type == TypeColor && ex->ValueType == TypeString) // colors can also be specified as ints. + { + *(PalEntry*)addr = V_GetColor(nullptr, GetStringConst(ex, ctx).GetChars(), &ex->ScriptPosition); + } + else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt))) { static_cast(f->Type)->SetValue(addr, GetIntConst(ex, ctx)); } From 8d7a64bd17d2688ba05e2196f438c3b038cadd10 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Feb 2017 00:43:30 +0100 Subject: [PATCH 11/12] - added a virtual 'used' method that gets called when the player presses use on an actor. This method will only be called if the actor does not have the USESPECIAL flag - that one will be handled as before. --- src/p_map.cpp | 8 ++++++++ wadsrc/static/zscript/actor.txt | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index e46c441db..da84855fd 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -5287,6 +5287,14 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end, if (P_ActivateThingSpecial(in->d.thing, usething)) return true; } + IFVIRTUALPTR(usething, AActor, Used) + { + VMValue params[] = { usething, in->d.thing }; + int ret; + VMReturn vret(&ret); + GlobalVMStack.Call(func, params, 2, &vret, 1); + if (ret) return true; + } continue; } diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index ceda20bd8..5e2454ed2 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -329,7 +329,12 @@ class Actor : Thinker native { return -1; } - + + // Called when the player presses 'use' and an actor is found + virtual bool Used(Actor user) + { + return false; + } native static class GetReplacement(class cls); native static class GetReplacee(class cls); From 6fef653aa14e997df796da3b08e63d21eb773e08 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Feb 2017 01:03:47 +0100 Subject: [PATCH 12/12] - exported GetUDMF methods to scripting. --- src/p_setup.h | 4 +-- src/p_udmf.cpp | 48 +++++++++++++++++++++++++++++-- wadsrc/static/zscript/base.txt | 13 +++++++++ wadsrc/static/zscript/mapdata.txt | 41 ++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/p_setup.h b/src/p_setup.h index 3d8c021a7..13bfad72e 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -118,8 +118,8 @@ void P_LoadTranslator(const char *lumpname); void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1); int P_TranslateSectorSpecial (int); -int GetUDMFInt(int type, int index, const char *key); -double GetUDMFFloat(int type, int index, const char *key); +int GetUDMFInt(int type, int index, FName key); +double GetUDMFFloat(int type, int index, FName key); bool P_LoadGLNodes(MapData * map); bool P_CheckNodes(MapData * map, bool rebuilt, int buildtime); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 515905b27..a13c24e63 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -342,7 +342,7 @@ FUDMFKey *FUDMFKeys::Find(FName key) // //=========================================================================== -int GetUDMFInt(int type, int index, const char *key) +int GetUDMFInt(int type, int index, FName key) { assert(type >=0 && type <=3); @@ -359,7 +359,16 @@ int GetUDMFInt(int type, int index, const char *key) return 0; } -double GetUDMFFloat(int type, int index, const char *key) +DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFInt) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(type); + PARAM_INT(index); + PARAM_NAME(key); + ACTION_RETURN_INT(GetUDMFInt(type, index, key)); +} + +double GetUDMFFloat(int type, int index, FName key) { assert(type >=0 && type <=3); @@ -376,6 +385,41 @@ double GetUDMFFloat(int type, int index, const char *key) return 0; } +DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFFloat) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(type); + PARAM_INT(index); + PARAM_NAME(key); + ACTION_RETURN_FLOAT(GetUDMFFloat(type, index, key)); +} + +FString GetUDMFString(int type, int index, FName key) +{ + assert(type >= 0 && type <= 3); + + FUDMFKeys *pKeys = UDMFKeys[type].CheckKey(index); + + if (pKeys != NULL) + { + FUDMFKey *pKey = pKeys->Find(key); + if (pKey != NULL) + { + return pKey->StringVal; + } + } + return ""; +} + +DEFINE_ACTION_FUNCTION(FLevelLocals, GetUDMFString) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(type); + PARAM_INT(index); + PARAM_NAME(key); + ACTION_RETURN_STRING(GetUDMFString(type, index, key)); +} + //=========================================================================== // diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 22bbcc790..bffee91f0 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -418,6 +418,14 @@ class SpotState : Object native struct LevelLocals native { + enum EUDMF + { + UDMF_Line, + UDMF_Side, + UDMF_Sector, + //UDMF_Thing // not implemented + }; + native readonly int time; native readonly int maptime; native readonly int totaltime; @@ -457,6 +465,11 @@ struct LevelLocals native native bool frozen; native bool infinite_flight; // level_info_t *info cannot be done yet. + + native String GetUDMFString(int type, int index, Name key); + native int GetUDMFInt(int type, int index, Name key); + native double GetUDMFFloat(int type, int index, Name key); + } struct StringTable native diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index b7589f8d4..5a216ea5e 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -84,6 +84,20 @@ struct Side native native Vertex V2(); native int Index(); + + int GetUDMFInt(Name nm) + { + return Level.GetUDMFInt(LevelLocals.UDMF_Side, Index(), nm); + } + double GetUDMFFloat(Name nm) + { + return Level.GetUDMFFloat(LevelLocals.UDMF_Side, Index(), nm); + } + String GetUDMFString(Name nm) + { + return Level.GetUDMFString(LevelLocals.UDMF_Side, Index(), nm); + } + }; struct Line native @@ -142,6 +156,19 @@ struct Line native native Line getPortalDestination(); native int getPortalAlignment(); native int Index(); + + int GetUDMFInt(Name nm) + { + return Level.GetUDMFInt(LevelLocals.UDMF_Line, Index(), nm); + } + double GetUDMFFloat(Name nm) + { + return Level.GetUDMFFloat(LevelLocals.UDMF_Line, Index(), nm); + } + String GetUDMFString(Name nm) + { + return Level.GetUDMFString(LevelLocals.UDMF_Line, Index(), nm); + } } struct SecPlane native @@ -398,4 +425,18 @@ struct Sector native { Flags &= ~SECF_SECRET; } + + int GetUDMFInt(Name nm) + { + return Level.GetUDMFInt(LevelLocals.UDMF_Sector, Index(), nm); + } + double GetUDMFFloat(Name nm) + { + return Level.GetUDMFFloat(LevelLocals.UDMF_Sector, Index(), nm); + } + String GetUDMFString(Name nm) + { + return Level.GetUDMFString(LevelLocals.UDMF_Sector, Index(), nm); + } + }