I would've thought that:
%x = getWord(%eyeVector, 0) + (%spread * getRandom());
%y = getWord(%eyeVector, 1) + (%spread * getRandom());
%z = getWord(%eyeVector, 2) + (%spread * getRandom());
%z = mClampF(%z, -0.4, 0.6);
%muzzleVector = vectorNormalize(%x SPC %y SPC %z);
%velocity = vectorScale(%muzzleVector, 200);
Would do the trick, but as soon as the vector is normalized, the vertical component just returns to whatever the eye vector is. Clamping it after you've normalized it does not work either, and clamping the z value to 120 in the actual velocity vector once it's been scaled by 200 does not work either.
So obviously there's some kind of tricky vector math required here in order to get this sort of thing to work. Anyone know what that might be?