From ccc694bbcd3f159d3b098fb2cface3ebc1ce4c17 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 7 Jan 2016 17:09:02 -0600 Subject: [PATCH 01/10] - Added the following flags, all affixed with CPXF_: - NODISTANCE: Disables distance checking. - CHECKSIGHT: The qualifying actor must be in sight in order to count. - SET: Gets the first qualifying actor and sets the calling actor's specified pointer to it. - SETONPTR: If the function is being aimed at another actor other than the caller, sets that actor's pointers instead. Requires a SET* flag to work. - FARTHEST: The actor farthest from the checking actor is set as the pointer. Requires a SET* flag to work. - CLOSEST: The closest qualifying actor is set as the pointer. Requires a SET* flag to work. --- src/thingdef/thingdef_codeptr.cpp | 83 ++++++++++++++++++++++++++---- wadsrc/static/actors/constants.txt | 8 +++ 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 89299e0fa..5dac7adbe 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5908,6 +5908,14 @@ enum CPXFflags CPXF_COUNTDEAD = 1 << 3, CPXF_DEADONLY = 1 << 4, CPXF_EXACT = 1 << 5, + CPXF_SETTARGET = 1 << 6, + CPXF_SETMASTER = 1 << 7, + CPXF_SETTRACER = 1 << 8, + CPXF_FARTHEST = 1 << 9, + CPXF_CLOSEST = 1 << 10, + CPXF_SETONPTR = 1 << 11, + CPXF_NODISTANCE = 1 << 12, + CPXF_CHECKSIGHT = 1 << 13, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) { @@ -5920,17 +5928,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) ACTION_PARAM_INT(ptr, 5); ACTION_SET_RESULT(false); //No inventory chain results please. + + if (!jump) + { + if (!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER))) + return; + } AActor *ref = COPY_AAPTR(self, ptr); //We need these to check out. - if (!ref || !jump || !classname || distance <= 0) + if (!ref || !classname || ((distance <= 0) && !(flags & CPXF_NODISTANCE))) return; int counter = 0; bool result = false; + const double distsquared = (double)distance * (double)distance; + double closer, farther = 0, current = closer = distsquared; + const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)); + const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST)); + TThinkerIterator it; - AActor * mo; + AActor *mo, *dist = NULL; //[MC] Process of elimination, I think, will get through this as quickly and //efficiently as possible. @@ -5949,12 +5968,37 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) else if (classname != mo->GetClass()) continue; - //Make sure it's in range and respect the desire for Z or not. - if (P_AproxDistance(ref->x - mo->x, ref->y - mo->y) < distance && - ((flags & CPXF_NOZ) || - ((ref->z > mo->z && ref->z - (mo->z + mo->height) < distance) || - (ref->z <= mo->z && mo->z - (ref->z + ref->height) < distance)))) + //[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use + //Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. + //Ripped from sphere checking in A_RadiusGive (along with a number of things). + + TVector3 spos(ref->x, ref->y, ((flags & CPXF_NOZ) ? 0 : (ref->z + ref->height / 2))); + TVector3 tpos(mo->x, mo->y, ((flags & CPXF_NOZ) ? 0 : (mo->z + mo->height / 2))); + if ((flags & CPXF_NODISTANCE) || (tpos - spos).LengthSquared() <= distsquared) { + if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))) + continue; + + if (ptrWillChange && ptrDistPref) + { + spos.Z = ref->z + ref->height / 2; //This one cannot have NOZ checking. + tpos.Z = mo->z + mo->height / 2; + current = (tpos - spos).LengthSquared(); + + if ((flags & CPXF_CLOSEST) && ((current < closer) || !closer)) + { + dist = mo; + closer = current; //This actor's closer. Set the new standard. + } + else if ((flags & CPXF_FARTHEST) && (current > farther)) + { + dist = mo; + farther = current; + } + else if (!dist) + dist = mo; //Just get the last one and call it quits if there's nothing selected. + } + if (mo->flags6 & MF6_KILLED) { if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY))) @@ -5972,17 +6016,38 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) if (counter > count) { result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? false : true; - break; + + //However, if we have one SET* flag and either the closest or farthest flags, keep the funcion going. + if (ptrWillChange && ptrDistPref) + continue; + else + break; } } } + if (ptrWillChange && dist != NULL) + { + if (flags & CPXF_SETONPTR) + { + if (flags & CPXF_SETTARGET) ref->target = dist; + if (flags & CPXF_SETMASTER) ref->master = dist; + if (flags & CPXF_SETTRACER) ref->tracer = dist; + } + else + { + if (flags & CPXF_SETTARGET) self->target = dist; + if (flags & CPXF_SETMASTER) self->master = dist; + if (flags & CPXF_SETTRACER) self->tracer = dist; + } + } + if (counter == count) result = true; else if (counter < count) result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT)); - + if (!jump) return; if (result) { diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 213e2109d..835e73dbf 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -497,6 +497,14 @@ enum CPXF_COUNTDEAD = 1 << 3, CPXF_DEADONLY = 1 << 4, CPXF_EXACT = 1 << 5, + CPXF_SETTARGET = 1 << 6, + CPXF_SETMASTER = 1 << 7, + CPXF_SETTRACER = 1 << 8, + CPXF_FARTHEST = 1 << 9, + CPXF_CLOSEST = 1 << 10, + CPXF_SETONPTR = 1 << 11, + CPXF_NODISTANCE = 1 << 12, + CPXF_CHECKSIGHT = 1 << 13, }; // Flags for A_CheckBlock From b51bbf66b0ef421738c3516b17f0ad73518b0733 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 21 Jan 2016 21:15:50 -0600 Subject: [PATCH 02/10] - Fixed pointer setting not working due to requiring more than the SET* flags. - Changed search algorithm to be square and utilize fixed_t instead. --- src/thingdef/thingdef_codeptr.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f10497711..f7cad3a5e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5996,8 +5996,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) int counter = 0; bool result = false; - const double distsquared = (double)distance * (double)distance; - double closer, farther = 0, current = closer = distsquared; + if (flags & CPXF_NODISTANCE) distance = (FIXED_MAX/2); + fixed_t closer = distance, farther = 0, current = distance; const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)); const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST)); @@ -6027,20 +6027,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) fixedvec3 diff = ref->Vec3To(mo); diff.z += (ref->height - mo->height) / 2; - double lengthsquared = TVector3(diff.x, diff.y, (flags & CPXF_NOZ) ? 0 : diff.z).LengthSquared(); - if ((flags & CPXF_NODISTANCE) || lengthsquared <= distsquared) + if ((flags & CPXF_NODISTANCE) || (ref->AproxDistance(mo) < distance && + ((flags & CPXF_NOZ) || + ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || + (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))) { if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))) continue; - if (ptrWillChange && ptrDistPref) + if (ptrWillChange) { - //Saves on needless recalculation as we already included Z above, so don't do it again - //if we did not use the flag the first time. - if (flags & CPXF_NOZ) - lengthsquared = TVector3(diff.x, diff.y, diff.z).LengthSquared(); - - current = lengthsquared; //This one cannot have NOZ checking. + current = ref->AproxDistance(mo); if ((flags & CPXF_CLOSEST) && ((current < closer) || !closer)) { From 823edc4a690e51c0fc8d6ca796342f4a62f72f39 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 21 Jan 2016 21:23:43 -0600 Subject: [PATCH 03/10] - Cleaned up leftovers. --- src/thingdef/thingdef_codeptr.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f7cad3a5e..28a7dfcf6 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6024,9 +6024,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) //[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use //Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. //Ripped from sphere checking in A_RadiusGive (along with a number of things). - - fixedvec3 diff = ref->Vec3To(mo); - diff.z += (ref->height - mo->height) / 2; if ((flags & CPXF_NODISTANCE) || (ref->AproxDistance(mo) < distance && ((flags & CPXF_NOZ) || ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || From ced35e98fbb8f327729970d107f3a431eb9c6495 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Mon, 25 Jan 2016 10:07:00 -0600 Subject: [PATCH 04/10] Remove needless check. --- src/thingdef/thingdef_codeptr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 28a7dfcf6..37f228eb1 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6036,7 +6036,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) { current = ref->AproxDistance(mo); - if ((flags & CPXF_CLOSEST) && ((current < closer) || !closer)) + if ((flags & CPXF_CLOSEST) && (current < closer)) { dist = mo; closer = current; //This actor's closer. Set the new standard. From 1c0ef1d367f99941181b3e585445e6f9d4d12d4e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 26 Jan 2016 10:00:20 -0600 Subject: [PATCH 05/10] Removed CPXF_NODISTANCE. --- src/thingdef/thingdef_codeptr.cpp | 8 +++----- wadsrc/static/actors/constants.txt | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 37f228eb1..4349c4b39 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5968,8 +5968,7 @@ enum CPXFflags CPXF_FARTHEST = 1 << 9, CPXF_CLOSEST = 1 << 10, CPXF_SETONPTR = 1 << 11, - CPXF_NODISTANCE = 1 << 12, - CPXF_CHECKSIGHT = 1 << 13, + CPXF_CHECKSIGHT = 1 << 12, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) { @@ -5991,12 +5990,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) AActor *ref = COPY_AAPTR(self, ptr); //We need these to check out. - if (!ref || !classname || ((distance <= 0) && !(flags & CPXF_NODISTANCE))) + if (!ref || !classname || (distance <= 0)) return; int counter = 0; bool result = false; - if (flags & CPXF_NODISTANCE) distance = (FIXED_MAX/2); fixed_t closer = distance, farther = 0, current = distance; const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER)); const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST)); @@ -6024,7 +6022,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) //[MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use //Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. //Ripped from sphere checking in A_RadiusGive (along with a number of things). - if ((flags & CPXF_NODISTANCE) || (ref->AproxDistance(mo) < distance && + if ((ref->AproxDistance(mo) < distance && ((flags & CPXF_NOZ) || ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))) diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 090a1330d..23694fda7 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -504,8 +504,7 @@ enum CPXF_FARTHEST = 1 << 9, CPXF_CLOSEST = 1 << 10, CPXF_SETONPTR = 1 << 11, - CPXF_NODISTANCE = 1 << 12, - CPXF_CHECKSIGHT = 1 << 13, + CPXF_CHECKSIGHT = 1 << 12, }; // Flags for A_CheckBlock From d2beec4585df28c9ccae94c35f2bbe9fe4afb73d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Jan 2016 00:56:40 +0100 Subject: [PATCH 06/10] - ensure that AInventory::Touch attributes everything to the correct player, even if the touching action results in a morph. --- src/g_shared/a_pickups.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 9fe31db22..0d67489b6 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -979,10 +979,12 @@ static void PrintPickupMessage (const char *str) void AInventory::Touch (AActor *toucher) { + player_t *player = toucher->player; + // If a voodoo doll touches something, pretend the real player touched it instead. - if (toucher->player != NULL) + if (player != NULL) { - toucher = toucher->player->mo; + toucher = player->mo; } bool localview = toucher->CheckLocalView(consoleplayer); @@ -1010,12 +1012,12 @@ void AInventory::Touch (AActor *toucher) // Special check so voodoo dolls picking up items cause the // real player to make noise. - if (toucher->player != NULL) + if (player != NULL) { - PlayPickupSound (toucher->player->mo); + PlayPickupSound (player->mo); if (!(ItemFlags & IF_NOSCREENFLASH)) { - toucher->player->bonuscount = BONUSADD; + player->bonuscount = BONUSADD; } } else @@ -1029,16 +1031,16 @@ void AInventory::Touch (AActor *toucher) if (flags & MF_COUNTITEM) { - if (toucher->player != NULL) + if (player != NULL) { - toucher->player->itemcount++; + player->itemcount++; } level.found_items++; } if (flags5 & MF5_COUNTSECRET) { - P_GiveSecret(toucher, true, true, -1); + P_GiveSecret(player != NULL? (AActor*)player->mo : toucher, true, true, -1); } //Added by MC: Check if item taken was the roam destination of any bot From f2666f70dd73da00d0b499923dfb8d7943fd00c8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Jan 2016 09:56:40 +0100 Subject: [PATCH 07/10] - removed unneeded check for 'listenactor' in S_UpdateSounds. --- src/s_sound.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index c05ef1036..ec94117e4 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1917,32 +1917,29 @@ void S_UpdateSounds (AActor *listenactor) S_ActivatePlayList(false); } - if (listenactor != NULL) + // should never happen + S_SetListener(listener, listenactor); + + for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) { - // should never happen - S_SetListener(listener, listenactor); - - for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) + if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D) { - if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D) - { - CalcPosVel(chan, &pos, &vel); - GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHAN_AREA), pos, vel); - } - chan->ChanFlags &= ~CHAN_JUSTSTARTED; + CalcPosVel(chan, &pos, &vel); + GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHAN_AREA), pos, vel); } + chan->ChanFlags &= ~CHAN_JUSTSTARTED; + } - SN_UpdateActiveSequences(); + SN_UpdateActiveSequences(); - GSnd->UpdateListener(&listener); - GSnd->UpdateSounds(); + GSnd->UpdateListener(&listener); + GSnd->UpdateSounds(); - if (level.time >= RestartEvictionsAt) - { - RestartEvictionsAt = 0; - S_RestoreEvictedChannels(); - } + if (level.time >= RestartEvictionsAt) + { + RestartEvictionsAt = 0; + S_RestoreEvictedChannels(); } } From c3047f448ef153fe6badc55a80c0c4bcfa93dfa4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Jan 2016 10:39:21 +0100 Subject: [PATCH 08/10] - fixed: When MIDI->Open returns failure, the MIDI device needs to be deleted. Otherwise the dead device object can trigger an assert later. --- src/sound/music_midistream.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 579fd7851..dd9e0e0ec 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -344,6 +344,11 @@ void MIDIStreamer::Play(bool looping, int subsong) if (MIDI == NULL || 0 != MIDI->Open(Callback, this)) { Printf(PRINT_BOLD, "Could not open MIDI out device\n"); + if (MIDI != NULL) + { + delete MIDI; + MIDI = NULL; + } return; } From 4eb38f03819e7534fd87d48cae5f65ffd58bad0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Jan 2016 11:01:38 +0100 Subject: [PATCH 09/10] - fixed: plane heighr calculations for Floor_Lower/RaiseByValue should be done at a point that's actually near the affected sector, not at (0,0), otherwise there's a risk of fixed point overflow. --- src/p_floor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index e3763e677..013f0a78f 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -342,16 +342,16 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, floor->m_Speed = height; case DFloor::floorLowerByValue: floor->m_Direction = -1; - newheight = sec->floorplane.ZatPoint (0, 0) - height; - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight); + newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) - height; + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight); break; case DFloor::floorRaiseInstant: floor->m_Speed = height; case DFloor::floorRaiseByValue: floor->m_Direction = 1; - newheight = sec->floorplane.ZatPoint (0, 0) + height; - floor->m_FloorDestDist = sec->floorplane.PointToDist (0, 0, newheight); + newheight = sec->floorplane.ZatPoint (sec->soundorg[0], sec->soundorg[1]) + height; + floor->m_FloorDestDist = sec->floorplane.PointToDist (sec->soundorg[0], sec->soundorg[1], newheight); break; case DFloor::floorMoveToValue: From 7c6e07024436032169ba522e358a03f606ae1491 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Jan 2016 11:19:30 +0100 Subject: [PATCH 10/10] - fixed: line spacing was taken from a different variable in conversation display and mouse coordinate code. --- src/p_conversation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index ab6cf5883..3111bc2d6 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -848,7 +848,7 @@ public: bool MouseEvent(int type, int x, int y) { int sel = -1; - int fh = SmallFont->GetHeight(); + int fh = OptionSettings.mLinespacing; // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160;