public void FakeMeltTicking(object sender, PlayerEventArgs playerEventArgs) { Log.Debug("Ticking ... "); PlayerMob mob = (PlayerMob)sender; //Log.Warn("Done. De-register tick."); //mob.Ticking -= FakeMeltTicking; //return; if (CurrentModel == null) { return; } try { bool stillMoving = false; foreach (var geometry in CurrentModel.Values) { foreach (var bone in geometry.Bones) { if (bone.NeverRender) { continue; } if (bone.Cubes == null || bone.Cubes.Count == 0) { continue; } foreach (var cube in bone.Cubes) { if (cube.Origin[1] <= 0.05f && cube.Velocity.Y <= 0.01) { cube.Origin[1] = 0f; cube.Velocity = Vector3.Zero; continue; } stillMoving = true; float x = cube.Origin[0]; float y = cube.Origin[1]; float z = cube.Origin[2]; cube.Origin = new[] { x + cube.Velocity.X, Math.Max(0f, y + cube.Velocity.Y), z + cube.Velocity.Z }; cube.Velocity -= new Vector3(0, Gravity, 0); cube.Velocity *= 1 - Drag; } } } if (!stillMoving) { Log.Warn("Done. De-register tick."); mob.Ticking -= FakeMeltTicking; // Reset? if (ResetOnEnd) { Skin skin = mob.Skin; McpePlayerSkin updateSkin = McpePlayerSkin.CreateObject(); updateSkin.NoBatch = true; updateSkin.uuid = mob.ClientUuid; updateSkin.skin = skin; mob.Level.RelayBroadcast(updateSkin); } } else { Skin skin = mob.Skin; var geometry = CurrentModel.FindGeometry(skin.GeometryName); geometry.Name = $"geometry.{DateTime.UtcNow.Ticks}.{mob.ClientUuid}"; CurrentModel.Clear(); CurrentModel.Add(geometry.Name, geometry); skin.GeometryName = geometry.Name; McpePlayerSkin updateSkin = McpePlayerSkin.CreateObject(); updateSkin.NoBatch = true; updateSkin.uuid = mob.ClientUuid; updateSkin.skin = skin; mob.Level.RelayBroadcast(updateSkin); } } catch (Exception e) { mob.Ticking -= FakeMeltTicking; Log.Error(e); } }