1 | using System; |
---|
2 | using System.Collections.Generic; |
---|
3 | using System.Linq; |
---|
4 | using System.Text; |
---|
5 | using CastleMaster.Entities; |
---|
6 | using CastleMaster.World; |
---|
7 | using CastleMaster.Players; |
---|
8 | using CastleMaster.Physics; |
---|
9 | using Microsoft.Xna.Framework; |
---|
10 | using CastleMaster.Graphics; |
---|
11 | |
---|
12 | namespace CastleMaster.Units |
---|
13 | { |
---|
14 | public class Unit : Entity |
---|
15 | { |
---|
16 | protected bool isSelectable; |
---|
17 | protected BoundingRectangle screenRect; |
---|
18 | protected BoundingRectangle screenRectOffset; |
---|
19 | protected Vector2 highlightOffset = Vector2.Zero; |
---|
20 | protected Point spriteSize; |
---|
21 | private float timer = -MathHelper.TwoPi, arrowSpeed = 0.1F; |
---|
22 | private Vector2 arrowOffs = Vector2.Zero; |
---|
23 | private Player owner; |
---|
24 | private int immunityTimer = 0; |
---|
25 | protected int maxHealth, immunityTime; |
---|
26 | protected Color colorizer = Color.White; |
---|
27 | protected bool colorizeOnHit, wasHurt = false; |
---|
28 | |
---|
29 | public Unit(Level level, Player owner) |
---|
30 | : base(level) |
---|
31 | { |
---|
32 | this.owner = owner; |
---|
33 | |
---|
34 | spriteSize = new Point(32, 32); |
---|
35 | screenRectOffset = new BoundingRectangle(0, 0, spriteSize.X, spriteSize.Y, null); |
---|
36 | isSelectable = true; |
---|
37 | IsSelected = false; |
---|
38 | HasHealth = false; |
---|
39 | maxHealth = 10; |
---|
40 | colorizeOnHit = true; |
---|
41 | immunityTime = 0; |
---|
42 | } |
---|
43 | |
---|
44 | public int Health { get; protected set; } |
---|
45 | |
---|
46 | public bool HasHealth { get; protected set; } |
---|
47 | |
---|
48 | public bool IsSelectable { get { return isSelectable; } } |
---|
49 | |
---|
50 | public Player Owner { get { return owner; } } |
---|
51 | |
---|
52 | public bool IsSelected { get; set; } |
---|
53 | |
---|
54 | public override void Init() |
---|
55 | { |
---|
56 | base.Init(); |
---|
57 | Health = maxHealth; |
---|
58 | } |
---|
59 | |
---|
60 | public virtual bool CanBeHurtBy(Unit u) |
---|
61 | { |
---|
62 | return HasHealth && u.Owner != Owner; |
---|
63 | } |
---|
64 | |
---|
65 | public void Hit(Unit u, int damage, float dir, float pushPower) |
---|
66 | { |
---|
67 | if (u.CanBeHurtBy(this)) |
---|
68 | u.Damage(this, damage, dir, pushPower); |
---|
69 | } |
---|
70 | |
---|
71 | public virtual void Damage(Unit attacker, int damage, float dir, float pushPower) |
---|
72 | { |
---|
73 | Health -= damage; |
---|
74 | if (colorizeOnHit) |
---|
75 | colorizer = Color.Red; |
---|
76 | if (immunityTime > 0) |
---|
77 | { |
---|
78 | wasHurt = true; |
---|
79 | HasHealth = false; |
---|
80 | } |
---|
81 | if (Health <= 0) |
---|
82 | Remove(); |
---|
83 | } |
---|
84 | |
---|
85 | public virtual void OnFunctionClick(float x, float z, bool wasCalledBefore) { } |
---|
86 | |
---|
87 | public override void Update() |
---|
88 | { |
---|
89 | base.Update(); |
---|
90 | |
---|
91 | if (IsSelected) |
---|
92 | { |
---|
93 | timer += arrowSpeed; |
---|
94 | if (timer >= MathHelper.TwoPi) timer = -MathHelper.TwoPi; |
---|
95 | arrowOffs.Y = (float)Math.Sin(timer) * 2.0F; |
---|
96 | } |
---|
97 | |
---|
98 | if (wasHurt) |
---|
99 | { |
---|
100 | immunityTimer++; |
---|
101 | if (immunityTimer >= immunityTime) |
---|
102 | { |
---|
103 | wasHurt = false; |
---|
104 | immunityTimer = 0; |
---|
105 | colorizer = Color.White; |
---|
106 | HasHealth = true; |
---|
107 | } |
---|
108 | } |
---|
109 | } |
---|
110 | |
---|
111 | public override void OnRemoved() |
---|
112 | { |
---|
113 | level.RemoveUnit(this); |
---|
114 | } |
---|
115 | |
---|
116 | public bool IntersectsWithScreenSpace(float x0, float y0, float x1, float y1) |
---|
117 | { |
---|
118 | if (!isSelectable) return false; |
---|
119 | screenRect = new BoundingRectangle(screenPos.X, screenPos.Y, screenPos.X, screenPos.Y, this).AddSelf(screenRectOffset).Scale(Viewport.ZOOM); |
---|
120 | return screenRect.Intersects(x0, y0, x1, y1); |
---|
121 | } |
---|
122 | |
---|
123 | public float DistanceTo(float x, float z) |
---|
124 | { |
---|
125 | float xd = X - x; |
---|
126 | float zd = Z - z; |
---|
127 | |
---|
128 | return (float)(Math.Sqrt(xd * xd + zd * zd)); |
---|
129 | } |
---|
130 | |
---|
131 | public float DistanceToSqr(float x, float z) |
---|
132 | { |
---|
133 | float xd = X - x; |
---|
134 | float zd = Z - z; |
---|
135 | |
---|
136 | return xd * xd + zd * zd; |
---|
137 | } |
---|
138 | |
---|
139 | public float DistanceFromScreenSpaceSqr(float x, float y) |
---|
140 | { |
---|
141 | float dx = screenPos.X * Viewport.ZOOM - x; |
---|
142 | float dy = screenPos.Y * Viewport.ZOOM - y; |
---|
143 | |
---|
144 | return dx * dx + dy * dy; |
---|
145 | } |
---|
146 | |
---|
147 | public virtual void RenderHighLight(RenderHelper renderer) |
---|
148 | { |
---|
149 | renderer.Render((screenPos + highlightOffset + arrowOffs) * Viewport.ZOOM, 1, 0, Resources.SPRITESHEET_ICONS, Viewport.ZOOM); |
---|
150 | } |
---|
151 | |
---|
152 | public override void Render(RenderHelper renderer) |
---|
153 | { |
---|
154 | if (IsSelected) |
---|
155 | RenderHighLight(renderer); |
---|
156 | } |
---|
157 | } |
---|
158 | } |
---|