private byte PlayWalkingSound(byte cubeId, DynamicEntitySoundTrack entityTrack) { List <SoundMetaData> sounds; byte soundIndex = 0; // play a water sound if (_stepsSounds.TryGetValue(cubeId, out sounds)) { // choose another sound to avoid playing the same sound one after another while (sounds.Count > 1 && entityTrack.LastSound == soundIndex) { soundIndex = (byte)_rnd.Next(0, sounds.Count); } if (entityTrack.isLocalSound) { _soundEngine.StartPlay2D(sounds[soundIndex].Alias, SourceCategory.FX); } else { _soundEngine.StartPlay3D(sounds[soundIndex].Alias, new Vector3((float)entityTrack.Entity.Position.X, (float)entityTrack.Entity.Position.Y, (float)entityTrack.Entity.Position.Z), SourceCategory.FX); } } return(soundIndex); }
private void WalkingSoundProcessing() { // foreach dynamic entity for (int i = 0; i < _stepsTracker.Count; i++) { DynamicEntitySoundTrack entityTrack = _stepsTracker[i]; IDynamicEntity entity = entityTrack.Entity; // first let's detect if the entity is in air Vector3D underTheFeets = entity.Position; underTheFeets.Y -= 0.01f; var result = _singleArray.GetCube(underTheFeets); if (result.IsValid == false) { return; } BlockProfile cubeUnderFeet = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[result.Cube.Id]; // no need to play step if the entity is in air or not in walking displacement mode if (cubeUnderFeet.Id == WorldConfiguration.CubeId.Air || _stepsTracker[i].Entity.DisplacementMode != Shared.Entities.EntityDisplacementModes.Walking) { var item = new DynamicEntitySoundTrack { Entity = _stepsTracker[i].Entity, Position = entity.Position, isLocalSound = _stepsTracker[i].isLocalSound }; //Save the position of the entity _stepsTracker[i] = item; continue; } // possible that entity just landed after the jump, so we need to check if the entity was in the air last time to play the landing sound Vector3D prevUnderTheFeets = entityTrack.Position; //Containing the previous DynamicEntity Position prevUnderTheFeets.Y -= 0.01f; //Compute the distance between the previous and current position, set to double distance = Vector3D.Distance(entityTrack.Position, entity.Position); // do we need to play the step sound? //Trigger only if the difference between previous memorize position and current is > 1.5 meters //Or if the previous position was in the air if (distance >= 1.5f || _singleArray.CheckCube(prevUnderTheFeets, WorldConfiguration.CubeId.Air)) { byte soundIndex = 0; var cubeResult = _singleArray.GetCube(entity.Position); if (cubeResult.IsValid) //Valid cube retrieved { BlockProfile currentCube = _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[cubeResult.Cube.Id]; //If walking on the ground, but with Feets and legs inside water block if (currentCube.CubeFamilly == Shared.Enums.enuCubeFamilly.Liquid && cubeUnderFeet.IsSolidToEntity) { //If my Head is not inside a Water block (Meaning = I've only the feet inside water) if (_singleArray.CheckCube(entity.Position + new Vector3D(0, entity.DefaultSize.Y, 0), WorldConfiguration.CubeId.Air)) { soundIndex = PlayWalkingSound(currentCube.Id, entityTrack); } } else { //Play a foot step sound only if the block under feet is solid to entity. (No water, no air, ...) if (_visualWorldParameters.WorldParameters.Configuration.BlockProfiles[cubeUnderFeet.Id].IsSolidToEntity) { soundIndex = PlayWalkingSound(cubeUnderFeet.Id, entityTrack); } } } //Save the Entity last position. var item = new DynamicEntitySoundTrack { Entity = _stepsTracker[i].Entity, Position = entity.Position, LastSound = soundIndex, isLocalSound = _stepsTracker[i].isLocalSound }; _stepsTracker[i] = item; } } }