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 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; 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: 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(); } } 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; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 94aa922c0..be53efbb9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5995,6 +5995,13 @@ 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_CHECKSIGHT = 1 << 12, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) { @@ -6007,17 +6014,26 @@ 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)) return; int counter = 0; bool result = false; + 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)); TThinkerIterator it; - AActor * mo; + AActor *mo, *dist = NULL; //[MC] Process of elimination, I think, will get through this as quickly and //efficiently as possible. @@ -6036,12 +6052,35 @@ 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 (ref->AproxDistance(mo) < 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). + if ((ref->AproxDistance(mo) < distance && ((flags & CPXF_NOZ) || - ((ref->Z() > mo->Z() && ref->Top() < distance) || - (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance)))) + ((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) + { + current = ref->AproxDistance(mo); + + if ((flags & CPXF_CLOSEST) && (current < 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 first one and call it quits if there's nothing selected. + } + if (mo->flags6 & MF6_KILLED) { if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY))) @@ -6059,17 +6098,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 function 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 b2d641b69..cecac6f0b 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -498,6 +498,13 @@ 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_CHECKSIGHT = 1 << 12, }; // Flags for A_CheckBlock