#region Copyright & License Information /* * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. For more * information, see COPYING. */ #endregion using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA.Mods.Common.Graphics { public interface IActorPreview { void Tick(); IEnumerable Render(WorldRenderer wr, WPos pos); IEnumerable RenderUI(WorldRenderer wr, int2 pos, float scale); IEnumerable ScreenBounds(WorldRenderer wr, WPos pos); } public class ActorPreviewInitializer : IActorInitializer { public readonly ActorInfo Actor; public readonly WorldRenderer WorldRenderer; public World World { get { return WorldRenderer.World; } } readonly TypeDictionary dict; public ActorPreviewInitializer(ActorInfo actor, WorldRenderer worldRenderer, TypeDictionary dict) { Actor = actor; WorldRenderer = worldRenderer; this.dict = dict; } public T GetOrDefault(TraitInfo info) where T : ActorInit { return dict.GetOrDefault(); } public T Get(TraitInfo info) where T : ActorInit { var init = GetOrDefault(info); if (init == null) throw new InvalidOperationException("TypeDictionary does not contain instance of type `{0}`".F(typeof(T))); return init; } public U GetValue(TraitInfo info) where T : ValueActorInit { return Get(info).Value; } public U GetValue(TraitInfo info, U fallback) where T : ValueActorInit { var init = GetOrDefault(info); return init != null ? init.Value : fallback; } public bool Contains(TraitInfo info) where T : ActorInit { return GetOrDefault(info) != null; } public Func GetOrientation() { var facingInfo = Actor.TraitInfoOrDefault(); if (facingInfo == null) return () => WRot.Zero; // Dynamic facing takes priority var dynamicInit = dict.GetOrDefault(); if (dynamicInit != null) { // TODO: Account for terrain slope var getFacing = dynamicInit.Value; return () => WRot.FromFacing(getFacing()); } // Fall back to initial actor facing if an Init isn't available var facingInit = dict.GetOrDefault(); var facing = facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing(); var orientation = WRot.FromFacing(facing); return () => orientation; } public Func GetFacing() { var facingInfo = Actor.TraitInfoOrDefault(); if (facingInfo == null) return () => WAngle.Zero; // Dynamic facing takes priority var dynamicInit = dict.GetOrDefault(); if (dynamicInit != null) { var getFacing = dynamicInit.Value; return () => WAngle.FromFacing(getFacing()); } // Fall back to initial actor facing if an Init isn't available var facingInit = dict.GetOrDefault(); var facing = WAngle.FromFacing(facingInit != null ? facingInit.Value : facingInfo.GetInitialFacing()); return () => facing; } public DamageState GetDamageState() { var health = dict.GetOrDefault(); if (health == null) return DamageState.Undamaged; var hf = health.Value; if (hf <= 0) return DamageState.Dead; if (hf < 25) return DamageState.Critical; if (hf < 50) return DamageState.Heavy; if (hf < 75) return DamageState.Medium; if (hf < 100) return DamageState.Light; return DamageState.Undamaged; } } }