diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 88654141..7175d393 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -347,7 +347,7 @@ void CGarage::Update()
 						FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
 					}
 					else {
-						CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $1000 to respray!
+						CGarages::TriggerMessage("GA_3", -1, 4000, -1); // No more freebies. $100 to respray!
 						m_eGarageState = GS_OPENEDCONTAINSCAR;
 						DMAudio.PlayFrontEndSound(SOUND_GARAGE_NO_MONEY, 1);
 					}
@@ -1096,7 +1096,7 @@ bool CGarage::IsStaticPlayerCarEntirelyInside()
 {
 	if (!FindPlayerVehicle())
 		return false;
-	if (!FindPlayerVehicle()->IsCar())
+	if (!FindPlayerVehicle()->IsCar() && !FindPlayerVehicle()->IsBike())
 		return false;
 	if (FindPlayerPed()->GetPedState() != PED_DRIVING)
 		return false;
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index fb8f95fd..c3ca25a6 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -1636,7 +1636,8 @@ static void PrintToLog(const char* format, ...)
 	va_end(va);
 
 #if SCRIPT_LOG_FILE_LEVEL == 1 || SCRIPT_LOG_FILE_LEVEL == 2
-	fwrite(tmp, 1, strlen(tmp), dbg_log);
+	if (dbg_log)
+		fwrite(tmp, 1, strlen(tmp), dbg_log);
 #endif
 }
 
@@ -13605,10 +13606,14 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
 		ScriptParams[0] = 0;
 		if (pPed->m_objective == OBJECTIVE_NONE && !pPed->bHasAlreadyUsedAttractor) {
 			C2dEffect* pEffect = (C2dEffect*)GetPedAttractorManager()->GetEffectForIceCreamVan(pVehicle, pPed->GetPosition()); // has to be casted, because inner methods are const
-			if ((pPed->GetPosition() - pEffect->pos).MagnitudeSqr() < SQR(20.0f)) {
-				if (GetPedAttractorManager()->HasEmptySlot(pEffect) && GetPedAttractorManager()->IsApproachable(pEffect, pVehicle->GetMatrix(), 0, pPed)) {
-					if (GetPedAttractorManager()->RegisterPedWithAttractor(pPed, pEffect, pVehicle->GetMatrix()))
-						ScriptParams[0] = 1;
+			if (pEffect) {
+				CVector pos;
+				CPedAttractorManager::ComputeEffectPos(pEffect, pVehicle->GetMatrix(), pos);
+				if ((pPed->GetPosition() - pos).MagnitudeSqr() < SQR(20.0f)) {
+					if (GetPedAttractorManager()->HasEmptySlot(pEffect) && GetPedAttractorManager()->IsApproachable(pEffect, pVehicle->GetMatrix(), 0, pPed)) {
+						if (GetPedAttractorManager()->RegisterPedWithAttractor(pPed, pEffect, pVehicle->GetMatrix()))
+							ScriptParams[0] = 1;
+					}
 				}
 			}
 		}
@@ -13735,11 +13740,57 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
 		return 0;
 	}
 	case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA:
+	{
 		CollectParameters(&m_nIp, 7);
-		debug("GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA not implemented\n"); // TODO(MIAMI)
-		ScriptParams[0] = -1;
+		int ped_handle = -1;
+		CVector pos = FindPlayerCoors();
+		float x1 = *(float*)&ScriptParams[0];
+		float y1 = *(float*)&ScriptParams[1];
+		float x2 = *(float*)&ScriptParams[2];
+		float y2 = *(float*)&ScriptParams[3];
+		int i = CPools::GetPedPool()->GetSize();
+		while (--i && ped_handle == -1) {
+			CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+			if (!pPed)
+				continue;
+			if (CTheScripts::LastRandomPedId == CPools::GetPedPool()->GetIndex(pPed))
+				continue;
+			if (pPed->CharCreatedBy != RANDOM_CHAR)
+				continue;
+			if (!pPed->IsPedInControl())
+				continue;
+			if (pPed->bRemoveFromWorld)
+				continue;
+			if (pPed->bFadeOut)
+				continue;
+			if (pPed->m_nWaitState != WAITSTATE_FALSE)
+				continue;
+			if (pPed->bHasAlreadyUsedAttractor)
+				continue;
+			if (pPed->m_attractor)
+				continue;
+			if (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[4], ScriptParams[5], ScriptParams[6]))
+				continue;
+			if (pPed->bIsLeader || pPed->m_leader)
+				continue;
+			if (!pPed->IsWithinArea(x1, y1, x2, y2))
+				continue;
+			if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+				continue;
+			if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z)
+				continue;
+			ped_handle = CPools::GetPedPool()->GetIndex(pPed);
+			CTheScripts::LastRandomPedId = ped_handle;
+			pPed->CharCreatedBy = MISSION_CHAR;
+			pPed->bRespondsToThreats = false;
+			++CPopulation::ms_nTotalMissionPeds;
+			if (m_bIsMissionScript)
+				CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR);
+		}
+		ScriptParams[0] = ped_handle;
 		StoreParameters(&m_nIp, 1);
 		return 0;
+	}
 	//case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE:
 	case COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA:
 		CollectParameters(&m_nIp, 4);
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 807fd53e..a3672186 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -403,6 +403,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
 
 	bReachedAttractorHeadingTarget = false;
 	bTurnedAroundOnAttractor = false;
+	bHasAlreadyUsedAttractor = false;
 	bCarPassenger = false;
 	bMiamiViceCop = false;
 	bMoneyHasBeenGivenByScript = false;
@@ -8209,6 +8210,10 @@ CPed::Wait(void)
 					animAssoc->blendDelta = -4.0f;
 					animAssoc->flags |= ASSOC_DELETEFADEDOUT;
 				}
+				if (m_attractor && m_objective == OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN) {
+					GetPedAttractorManager()->BroadcastDeparture(this, m_attractor);
+					bBoughtIceCream = true;
+				}
 				ClearWaitState();
 			}
 #ifdef VC_PED_PORTS
@@ -15064,6 +15069,38 @@ CPed::ProcessObjective(void)
 					}
 				}
 				break;
+			case OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN:
+			{
+				SetIdle();
+				CVehicle* pIceCreamVan = GetPedAttractorManager()->GetIceCreamVanForEffect(m_attractor->GetEffect());
+				if (m_attractor && m_nWaitState != WAITSTATE_PLAYANIM_CHAT && pIceCreamVan && pIceCreamVan->pDriver && pIceCreamVan->pDriver->IsPlayer()) {
+					int time = 5000;
+					SetWaitState(WAITSTATE_PLAYANIM_CHAT, &time);
+					break;
+				}
+				if (!m_attractor)
+					break;
+				CVehicle* pVan = GetPedAttractorManager()->GetIceCreamVanForEffect(m_attractor->GetEffect());
+				if (!pVan)
+					break;
+				if (0.01f * CTimer::GetTimeStep() * 5.0f < pVan->m_fDistanceTravelled) {
+					GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+					break;
+				}
+				if (!pVan->pDriver || !pVan->pDriver->IsPlayer() || pVan->pDriver->GetPedState() == PED_ARRESTED || pVan->pDriver->GetPedState() == PED_DEAD) {
+					GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+					break;
+				}
+				if (!pVan->m_bSirenOrAlarm) {
+					GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+					return; // ???
+				}
+				if (pVan->GetStatus() == STATUS_WRECKED) {
+					GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
+					return; // ???
+				}
+				break;
+			}
 #endif
 		}
 		if (bObjectiveCompleted
@@ -18714,28 +18751,28 @@ CPed::SetObjective(eObjective newObj, CVector dest)
 			m_nextRoutePointPos = dest;
 			m_vecSeekPos = m_nextRoutePointPos;
 			m_distanceToCountSeekDone = 0.5f;
-			if (m_objective == OBJECTIVE_GOTO_ATM_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_ATM_ON_FOOT) {
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
 			}
-			if (m_objective == OBJECTIVE_GOTO_SEAT_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_SEAT_ON_FOOT) {
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
 			}
-			if (m_objective == OBJECTIVE_GOTO_BUS_STOP_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_BUS_STOP_ON_FOOT) {
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
 			}
-			if (m_objective == OBJECTIVE_GOTO_PIZZA_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_PIZZA_ON_FOOT) {
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
 			}
-			if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_SHELTER_ON_FOOT) {
 				bIsRunning = true;
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
 			}
-			if (m_objective == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) {
+			if (newObj == OBJECTIVE_GOTO_ICE_CREAM_VAN_ON_FOOT) {
 				bIsRunning = true;
 				m_distanceToCountSeekDone = m_attractor->GetDistanceToCountSeekDone();
 				m_acceptableHeadingOffset = m_attractor->GetAcceptableHeading();
diff --git a/src/peds/PedAttractor.cpp b/src/peds/PedAttractor.cpp
index 659a522b..db5f9e52 100644
--- a/src/peds/PedAttractor.cpp
+++ b/src/peds/PedAttractor.cpp
@@ -70,17 +70,17 @@ const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const
 	if (!m_pVehicle)
 		return nil;
 	if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) {
-		if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
-			return &m_effects[0];
-		else
-			return &m_effects[2];
-	}
-	else {
 		if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
 			return &m_effects[1];
 		else
 			return &m_effects[3];
 	}
+	else {
+		if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
+			return &m_effects[0];
+		else
+			return &m_effects[2];
+	}
 }
 
 bool CVehicleToEffect::HasThisEffect(C2dEffect* pEffect) const