AnimatedVehicle.updateAnimation = function(self, anim, dtToUse, stopAnim, allowRestart)
	local spec = self.spec_animatedVehicle
	local numParts = table.getn(anim.parts)
	local parts = anim.parts

	if anim.currentSpeed < 0 then
		parts = anim.partsReverse
	end

	if dtToUse > 0 then
		local hasChanged = false
		local nothingToChangeYet = false

		for partI = anim.currentPartIndex, numParts do
			local part = parts[partI]
			local isInRange = true

			if part.requiredAnimation ~= nil then
				local time = self:getAnimationTime(part.requiredAnimation)

				if time < part.requiredAnimationRange[1] or part.requiredAnimationRange[2] < time then
					isInRange = false
				end
			end

			if (part.direction == 0 or part.direction > 0 == (anim.currentSpeed >= 0)) and isInRange then
				local durationToEnd = AnimatedVehicle.getDurationToEndOfPart(part, anim)

				if part.duration < durationToEnd then
					nothingToChangeYet = true

					break
				end

				local realDt = dtToUse

				if anim.currentSpeed > 0 then
					local startT = anim.currentTime - dtToUse

					if startT < part.startTime then
						realDt = dtToUse - part.startTime + startT
					end
				else
					local startT = anim.currentTime + dtToUse
					local endTime = part.startTime + part.duration

					if startT > endTime then
						realDt = dtToUse - (startT - endTime)
					end
				end

				durationToEnd = durationToEnd + realDt

				if self:updateAnimationPart(anim, part, durationToEnd, dtToUse, realDt) then
					if self.setMovingToolDirty ~= nil then
						self:setMovingToolDirty(part.node)
					end

					hasChanged = true
				end
			end

			if partI == anim.currentPartIndex and (anim.currentSpeed > 0 and part.startTime + part.duration < anim.currentTime or anim.currentSpeed <= 0 and anim.currentTime < part.startTime) then
				self:resetAnimationPartValues(part)

				anim.currentPartIndex = anim.currentPartIndex + 1
			end
		end

		if not nothingToChangeYet and not hasChanged and numParts <= anim.currentPartIndex then
			if anim.currentSpeed > 0 then
				anim.currentTime = anim.duration
			else
				anim.currentTime = 0
			end

			stopAnim = true
		end
	end

	if stopAnim or numParts < anim.currentPartIndex or anim.currentPartIndex < 1 then
		if not stopAnim then
			if anim.currentSpeed > 0 then
				anim.currentTime = anim.duration
			else
				anim.currentTime = 0
			end
		end

		anim.currentTime = math.min(math.max(anim.currentTime, 0), anim.duration)
		anim.stopTime = nil

		if spec.activeAnimations[anim.name] ~= nil then
			spec.numActiveAnimations = spec.numActiveAnimations - 1

			if self.isClient then
				g_soundManager:stopSample(spec.activeAnimations[anim.name].sample)
			end

			spec.activeAnimations[anim.name] = nil

			SpecializationUtil.raiseEvent(self, "onFinishAnimation", anim.name)
		end

		if (allowRestart == nil or allowRestart) and anim.looping then
			self:setAnimationTime(anim.name, math.abs(anim.currentTime - anim.duration - 1), true)
			self:playAnimation(anim.name, anim.currentSpeed, nil, true)
		end
	end
end