using Theriapolis.Core.Rules.Character; using Theriapolis.Core.Util; namespace Theriapolis.Core.Entities; /// /// Base actor record. Position is in world-pixel space and is meaningful in /// both the world-map view and the tactical view (see Section 5 of the /// implementation plan — one canonical coordinate system). /// /// Phase 5 adds the optional attachment carrying all /// gameplay state (stats, inventory, HP, conditions). The renderer layer /// stays ignorant of the gameplay layer — Camera2D doesn't need to know HP. /// public class Actor { /// Stable id assigned by . public int Id { get; init; } /// World-pixel position. Reused at both zoom scales. public Vec2 Position { get; set; } /// Facing angle in radians (0 = east, π/2 = south). public float FacingAngleRad { get; set; } /// Continuous-time travel speed on the world map, in world pixels per real second. public float SpeedWorldPxPerSec { get; set; } = C.PLAYER_TRAVEL_PX_PER_SEC; /// /// Phase 5: gameplay state. Null when this actor isn't combat-capable /// (cosmetic NPCs, future-phase additions). PlayerActor and NpcActor /// always carry one. /// public Character? Character { get; set; } /// Whose side this actor is on. Drives encounter triggering and AI targeting. public Allegiance Allegiance { get; set; } = Allegiance.Neutral; /// /// True if this actor still has positive HP (or is downed but not dead). /// Subclasses (e.g. ) override to use direct HP /// fields instead of a reference. /// public virtual bool IsAlive => Character is null ? true : Character.IsAlive; }