internal void OnDeserializedMethod(StreamingContext context) { if (Code == null) { Code = Name; } CodeCrc32 = AnimationMetaData.GetCrc32(Code); }
public static AnimationMetaData FromBytes(BinaryReader reader, string version) { AnimationMetaData animdata = new AnimationMetaData(); animdata.Code = reader.ReadString(); animdata.Animation = reader.ReadString(); animdata.Weight = reader.ReadSingle(); int weightCount = reader.ReadInt32(); for (int i = 0; i < weightCount; i++) { animdata.ElementWeight[reader.ReadString()] = reader.ReadSingle(); } animdata.AnimationSpeed = reader.ReadSingle(); animdata.EaseInSpeed = reader.ReadSingle(); animdata.EaseOutSpeed = reader.ReadSingle(); bool haveTrigger = reader.ReadBoolean(); if (haveTrigger) { animdata.TriggeredBy = new AnimationTrigger(); animdata.TriggeredBy.MatchExact = reader.ReadBoolean(); weightCount = reader.ReadInt32(); animdata.TriggeredBy.OnControls = new EnumEntityActivity[weightCount]; for (int i = 0; i < weightCount; i++) { animdata.TriggeredBy.OnControls[i] = (EnumEntityActivity)reader.ReadInt32(); } animdata.TriggeredBy.DefaultAnim = reader.ReadBoolean(); } animdata.BlendMode = (EnumAnimationBlendMode)reader.ReadInt32(); weightCount = reader.ReadInt32(); for (int i = 0; i < weightCount; i++) { animdata.ElementBlendMode[reader.ReadString()] = (EnumAnimationBlendMode)reader.ReadInt32(); } animdata.MulWithWalkSpeed = reader.ReadBoolean(); if (GameVersion.IsAtLeastVersion(version, "1.12.5-dev.1")) { animdata.StartFrameOnce = reader.ReadSingle(); } if (GameVersion.IsAtLeastVersion(version, "1.13.0-dev.3")) { animdata.HoldEyePosAfterEasein = reader.ReadSingle(); } animdata.Init(); return(animdata); }
protected virtual void AnimNowActive(RunningAnimation anim, AnimationMetaData animData) { anim.Running = true; anim.Active = true; anim.meta = animData; anim.ShouldRewind = false; anim.ShouldPlayTillEnd = false; anim.CurrentFrame = animData.StartFrameOnce; animData.StartFrameOnce = 0; }
protected override void AnimNowActive(RunningAnimation anim, AnimationMetaData animData) { base.AnimNowActive(anim, animData); if (anim.Animation.PrevNextKeyFrameByFrame == null) { anim.Animation.GenerateAllFrames(rootElements, jointsById); } anim.LoadWeights(rootElements); }
/// <summary> /// Loads the entity from a stored byte array from the SaveGame /// </summary> /// <param name="tree"></param> public virtual void FromAttributes(ITreeAttribute tree, string version) { foreach (var val in tree) { byte[] data = (val.Value as ByteArrayAttribute).value; using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(ms)) { ActiveAnimationsByAnimCode[val.Key] = AnimationMetaData.FromBytes(reader, version); } } } }
/// <summary> /// Start a new animation defined in the entity config file. If it's not defined, it won't play. /// Use StartAnimation(AnimationMetaData animdata) to circumvent the entity config anim data. /// </summary> /// <param name="configCode">Anim config code, not the animation code!</param> public virtual bool StartAnimation(string configCode) { if (configCode == null) { return(false); } AnimationMetaData animdata = null; if (entity.Properties.Client.AnimationsByMetaCode.TryGetValue(configCode, out animdata)) { StartAnimation(animdata); return(true); } return(false); }
/// <summary> /// Client: Starts given animation /// Server: Sends all active anims to all connected clients then purges the ActiveAnimationsByAnimCode list /// </summary> /// <param name="animdata"></param> public virtual bool StartAnimation(AnimationMetaData animdata) { AnimationMetaData activeAnimdata; // Already active, won't do anything if (ActiveAnimationsByAnimCode.TryGetValue(animdata.Animation, out activeAnimdata) && activeAnimdata == animdata) { return(false); } if (animdata.Code == null) { throw new Exception("anim meta data code cannot be null!"); } AnimationsDirty = true; ActiveAnimationsByAnimCode[animdata.Animation] = animdata; entity.UpdateDebugAttributes(); return(true); }
public virtual void LoadConfig(JsonObject taskConfig, JsonObject aiConfig) { this.priority = taskConfig["priority"].AsFloat(); this.priorityForCancel = taskConfig["priorityForCancel"].AsFloat(priority); this.Id = taskConfig["id"].AsString(); this.slot = (int)taskConfig["slot"]?.AsInt(0); this.mincooldown = (int)taskConfig["mincooldown"]?.AsInt(0); this.maxcooldown = (int)taskConfig["maxcooldown"]?.AsInt(100); this.mincooldownHours = (double)taskConfig["mincooldownHours"]?.AsDouble(0); this.maxcooldownHours = (double)taskConfig["maxcooldownHours"]?.AsDouble(0); int initialmincooldown = (int)taskConfig["initialMinCoolDown"]?.AsInt(mincooldown); int initialmaxcooldown = (int)taskConfig["initialMaxCoolDown"]?.AsInt(maxcooldown); if (taskConfig["animation"].Exists) { animMeta = new AnimationMetaData() { Code = taskConfig["animation"].AsString()?.ToLowerInvariant(), Animation = taskConfig["animation"].AsString()?.ToLowerInvariant(), AnimationSpeed = taskConfig["animationSpeed"].AsFloat(1f) }.Init(); } this.whenInEmotionState = taskConfig["whenInEmotionState"].AsString(); this.whenNotInEmotionState = taskConfig["whenNotInEmotionState"].AsString(); if (taskConfig["sound"].Exists) { sound = AssetLocation.Create(taskConfig["sound"].AsString(), entity.Code.Domain).WithPathPrefixOnce("sounds/"); soundRange = taskConfig["soundRange"].AsFloat(16); soundStartMs = taskConfig["soundStartMs"].AsInt(0); soundRepeatMs = taskConfig["soundRepeatMs"].AsInt(0); } cooldownUntilMs = entity.World.ElapsedMilliseconds + initialmincooldown + entity.World.Rand.Next(initialmaxcooldown - initialmincooldown); }
/// <summary> /// Attempts to resolve all references within the shape. Logs missing references them to the errorLogger /// </summary> /// <param name="errorLogger"></param> /// <param name="shapeNameForLogging"></param> public void ResolveReferences(ILogger errorLogger, string shapeNameForLogging) { Dictionary <string, ShapeElement> elementsByName = new Dictionary <string, ShapeElement>(); CollectElements(Elements, elementsByName); for (int i = 0; Animations != null && i < Animations.Length; i++) { Animation anim = Animations[i]; for (int j = 0; j < anim.KeyFrames.Length; j++) { AnimationKeyFrame keyframe = anim.KeyFrames[j]; ResolveReferences(errorLogger, shapeNameForLogging, elementsByName, keyframe); foreach (AnimationKeyFrameElement kelem in keyframe.Elements.Values) { kelem.Frame = keyframe.Frame; } } if (anim.Code == null || anim.Code.Length == 0) { anim.Code = anim.Name.ToLowerInvariant().Replace(" ", ""); } AnimationsByCrc32[AnimationMetaData.GetCrc32(anim.Code)] = anim; } for (int i = 0; i < Elements.Length; i++) { ShapeElement elem = Elements[i]; elem.ResolveRefernces(); CollectAttachmentPoints(elem); } }
public override void OnGameTick(float dt) { if (World.Side == EnumAppSide.Client) { bool alive = Alive; if (alive) { CurrentControls = (servercontrols.TriesToMove || ((servercontrols.Jump || servercontrols.Sneak) && servercontrols.IsClimbing) ? EnumEntityActivity.Move : EnumEntityActivity.Idle) | (Swimming && !servercontrols.FloorSitting ? EnumEntityActivity.Swim : 0) | (servercontrols.FloorSitting ? EnumEntityActivity.FloorSitting : 0) | (servercontrols.Sneak && !servercontrols.IsClimbing && !servercontrols.FloorSitting && !Swimming ? EnumEntityActivity.SneakMode : 0) | (servercontrols.Sprint && !Swimming && !servercontrols.Sneak ? EnumEntityActivity.SprintMode : 0) | (servercontrols.IsFlying ? EnumEntityActivity.Fly : 0) | (servercontrols.IsClimbing ? EnumEntityActivity.Climb : 0) | (servercontrols.Jump && OnGround ? EnumEntityActivity.Jump : 0) | (!OnGround && !Swimming && !FeetInLiquid && !servercontrols.IsClimbing && !servercontrols.IsFlying && SidedPos.Motion.Y < -0.05 ? EnumEntityActivity.Fall : 0) ; } else { CurrentControls = EnumEntityActivity.Dead; } CurrentControls = CurrentControls == 0 ? EnumEntityActivity.Idle : CurrentControls; } HandleHandAnimations(); if (World.Side == EnumAppSide.Client) { AnimationMetaData defaultAnim = null; bool anyAverageAnimActive = false; bool skipDefaultAnim = false; AnimationMetaData[] animations = Properties.Client.Animations; for (int i = 0; animations != null && i < animations.Length; i++) { AnimationMetaData anim = animations[i]; bool wasActive = AnimManager.ActiveAnimationsByAnimCode.ContainsKey(anim.Animation); bool nowActive = anim.Matches((int)CurrentControls); bool isDefaultAnim = anim?.TriggeredBy?.DefaultAnim == true; anyAverageAnimActive |= nowActive || (wasActive && !anim.WasStartedFromTrigger); skipDefaultAnim |= (nowActive || (wasActive && !anim.WasStartedFromTrigger)) && anim.SupressDefaultAnimation; if (isDefaultAnim) { defaultAnim = anim; } if (!wasActive && nowActive) { anim.WasStartedFromTrigger = true; AnimManager.StartAnimation(anim); } if (wasActive && !nowActive && (anim.WasStartedFromTrigger || isDefaultAnim)) { anim.WasStartedFromTrigger = false; AnimManager.StopAnimation(anim.Animation); } } if (!anyAverageAnimActive && defaultAnim != null && Alive && !skipDefaultAnim) { defaultAnim.WasStartedFromTrigger = true; AnimManager.StartAnimation(defaultAnim); } if ((!Alive || skipDefaultAnim) && defaultAnim != null) { AnimManager.StopAnimation(defaultAnim.Code); } ICoreClientAPI capi = (Api as ICoreClientAPI); bool isSelf = capi.World.Player.Entity.EntityId == EntityId; EntityPos herepos = (isSelf ? Pos : ServerPos); bool moving = herepos.Motion.LengthSq() > 0.0000 && !servercontrols.NoClip; // Snow particles if (insideBlock?.GetBlockMaterial(capi.World.BlockAccessor, insidePos) == EnumBlockMaterial.Snow && isSelf) { double hormot = Pos.Motion.X * Pos.Motion.X + Pos.Motion.Z * Pos.Motion.Z; float val = (float)Math.Sqrt(hormot); if (Api.World.Rand.NextDouble() < 10 * val) { var rand = capi.World.Rand; Vec3f velo = new Vec3f(1f - 2 * (float)rand.NextDouble() + GameMath.Clamp((float)Pos.Motion.X * 15, -5, 5), 0.5f + 3.5f * (float)rand.NextDouble(), 1f - 2 * (float)rand.NextDouble() + GameMath.Clamp((float)Pos.Motion.Z * 15, -5, 5)); float radius = Math.Min(SelectionBox.XSize, SelectionBox.ZSize) * 0.9f; World.SpawnCubeParticles(herepos.AsBlockPos, herepos.XYZ.Add(0, 0, 0), radius, 2 + (int)(rand.NextDouble() * val * 5), 0.5f + (float)rand.NextDouble() * 0.5f, null, velo); } } if ((FeetInLiquid || Swimming) && moving) { double width = SelectionBox.XSize * 0.75f; SplashParticleProps.BasePos.Set(herepos.X - width / 2, herepos.Y + 0, herepos.Z - width / 2); SplashParticleProps.AddPos.Set(width, 0.5, width); float mot = (float)herepos.Motion.Length(); SplashParticleProps.AddVelocity.Set((float)herepos.Motion.X * 20f, 0, (float)herepos.Motion.Z * 20f); float f = Properties.Attributes?["extraSplashParticlesMul"].AsFloat(1) ?? 1; SplashParticleProps.QuantityMul = 0.15f * mot * 5 * 2 * f; World.SpawnParticles(SplashParticleProps); SpawnWaterMovementParticles((float)Math.Max(Swimming ? 0.04f : 0, mot * 5)); } } if (Properties.RotateModelOnClimb && World.Side == EnumAppSide.Server) { if (!OnGround && Alive && Controls.IsClimbing && ClimbingOnFace != null && ClimbingOnCollBox.Y2 > 0.2 /* cheap hax so that locusts don't climb on very flat collision boxes */) { ServerPos.Pitch = ClimbingOnFace.HorizontalAngleIndex * GameMath.PIHALF; } else { ServerPos.Pitch = 0; } } base.OnGameTick(dt); }
public override bool Equals(object obj) { AnimationMetaData other = obj as AnimationMetaData; return(other != null && other.Animation == Animation && other.AnimationSpeed == AnimationSpeed && other.BlendMode == BlendMode); }
public bool StartAnimation(AnimationMetaData animdata) { return(false); }
/// <summary> /// The event fired when the manager recieves the server animations. /// </summary> /// <param name="activeAnimations"></param> /// <param name="activeAnimationsCount"></param> /// <param name="activeAnimationSpeeds"></param> public virtual void OnReceivedServerAnimations(int[] activeAnimations, int activeAnimationsCount, float[] activeAnimationSpeeds) { HashSet <string> toKeep = new HashSet <string>(); string active = ""; int mask = ~(1 << 31); // Because I fail to get the sign bit transmitted correctly over the network T_T for (int i = 0; i < activeAnimationsCount; i++) { uint crc32 = (uint)(activeAnimations[i] & mask); AnimationMetaData animmetadata; if (entity.Properties.Client.AnimationsByCrc32.TryGetValue(crc32, out animmetadata)) { toKeep.Add(animmetadata.Animation); if (ActiveAnimationsByAnimCode.ContainsKey(animmetadata.Code)) { continue; } animmetadata.AnimationSpeed = activeAnimationSpeeds[i]; ActiveAnimationsByAnimCode[animmetadata.Animation] = animmetadata; continue; } Animation anim; if (entity.Properties.Client.LoadedShapeForEntity.AnimationsByCrc32.TryGetValue(crc32, out anim)) { toKeep.Add(anim.Code); if (ActiveAnimationsByAnimCode.ContainsKey(anim.Code)) { continue; } string code = anim.Code == null?anim.Name.ToLowerInvariant() : anim.Code; active += ", " + code; AnimationMetaData animmeta; entity.Properties.Client.AnimationsByMetaCode.TryGetValue(code, out animmeta); if (animmeta == null) { animmeta = new AnimationMetaData() { Code = code, Animation = code, CodeCrc32 = anim.CodeCrc32 }; } animmeta.AnimationSpeed = activeAnimationSpeeds[i]; ActiveAnimationsByAnimCode[anim.Code] = animmeta; } } if (entity.EntityId != (entity.World as IClientWorldAccessor).Player.Entity.EntityId) { string[] keys = ActiveAnimationsByAnimCode.Keys.ToArray(); for (int i = 0; i < keys.Length; i++) { if (!toKeep.Contains(keys[i])) { AnimationMetaData animmetadata; if (entity.Properties.Client.AnimationsByMetaCode.TryGetValue(keys[i], out animmetadata)) { if (animmetadata.TriggeredBy != null && animmetadata.WasStartedFromTrigger) { continue; } } ActiveAnimationsByAnimCode.Remove(keys[i]); } } } }
protected override void AnimNowActive(RunningAnimation anim, AnimationMetaData animData) { base.AnimNowActive(anim, animData); anim.LoadWeights(rootElements); }