From 147dca44fa9c759b0d576cb8d4f9575720fc937b Mon Sep 17 00:00:00 2001
From: Sergeanur <s.anureev@yandex.ua>
Date: Fri, 5 Jun 2020 11:27:33 +0300
Subject: [PATCH] ProcessTrainAnnouncements

---
 src/audio/AudioLogic.cpp |  6 +++---
 src/audio/soundlist.h    |  4 ++--
 src/vehicles/Train.cpp   | 43 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index b6fb5a86..01b074ed 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -6536,9 +6536,9 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
 		m_sQueueSample.m_bIs2D = false;
 		emittingVolume = m_anRandomTable[2] % 20 + 90;
 		break;
-	case SCRIPT_SOUND_110:
-	case SCRIPT_SOUND_111:
-		if (SampleManager.IsSampleBankLoaded(0) != 1)
+	case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1:
+	case SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2:
+		if (!SampleManager.IsSampleBankLoaded(0))
 			return;
 		m_sQueueSample.m_fSoundIntensity = 80.0f;
 		m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE;
diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h
index 08a1631e..c88229a2 100644
--- a/src/audio/soundlist.h
+++ b/src/audio/soundlist.h
@@ -284,8 +284,8 @@ enum eScriptSounds : uint16 {
 	SCRIPT_SOUND_BULLET_HIT_GROUND_2,
 	SCRIPT_SOUND_BULLET_HIT_GROUND_3,
 	SCRIPT_SOUND_BULLET_HIT_WATER, // no sound
-	SCRIPT_SOUND_110,
-	SCRIPT_SOUND_111,
+	SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1,
+	SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2,
 	SCRIPT_SOUND_PAYPHONE_RINGING,
 	SCRIPT_SOUND_113,
 	SCRIPT_SOUND_GLASS_BREAK_L,
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index 21cde17f..38bb1300 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -13,6 +13,7 @@
 #include "DMAudio.h"
 #include "HandlingMgr.h"
 #include "Train.h"
+#include "AudioScriptObject.h"
 
 static CTrainNode* pTrackNodes;
 static int16 NumTrackNodes;
@@ -35,6 +36,8 @@ static float EngineTrackSpeed_S[4];
 CVector CTrain::aStationCoors[3];
 CVector CTrain::aStationCoors_S[4];
 
+static bool bTrainArrivalAnnounced[3] = {false, false, false};
+
 CTrain::CTrain(int32 id, uint8 CreatedBy)
  : CVehicle(CreatedBy)
 {
@@ -618,10 +621,48 @@ CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int1
 	interpLines[j].time = *totalDuration;
 }
 
+void
+PlayAnnouncement(uint8 sound, uint8 station)
+{
+	// this was gone in a PC version but inlined on PS2
+	cAudioScriptObject *obj = new cAudioScriptObject;
+	obj->AudioId = sound;
+	obj->Posn = CTrain::aStationCoors[station];
+	obj->AudioEntity = AEHANDLE_NONE;
+	DMAudio.CreateOneShotScriptObject(obj);
+}
+
 void
 ProcessTrainAnnouncements(void)
 {
-	// TODO but unused
+	for (int i = 0; i < 3; i++) {
+		for (int j = 0; j < 3; j++) {
+			if (!bTrainArrivalAnnounced[i]) {
+				float preDist = StationDist[i] - 100.0f;
+				if (preDist < 0.0f)
+					preDist += TotalLengthOfTrack;
+				if (EngineTrackPosition[j] > preDist && EngineTrackPosition[j] < StationDist[i]) {
+					bTrainArrivalAnnounced[i] = true;
+					PlayAnnouncement(SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1, i);
+					break;
+				}
+			} else {
+				float postDist = StationDist[i] + 10.0f;
+#ifdef FIX_BUGS
+				if (postDist > TotalLengthOfTrack)
+					postDist -= TotalLengthOfTrack;
+#else
+				if (postDist < 0.0f) // does this even make sense here?
+					postDist += TotalLengthOfTrack;
+#endif
+				if (EngineTrackPosition[j] > StationDist[i] && EngineTrackPosition[j] < postDist) {
+					bTrainArrivalAnnounced[i] = false;
+					PlayAnnouncement(SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2, i);
+					break;
+				}
+			}
+		}
+	}
 }
 
 void