-
Notifications
You must be signed in to change notification settings - Fork 0
/
TargetableEntity.cs
300 lines (243 loc) · 8.92 KB
/
TargetableEntity.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/*
Code for a physics-based flight sim shooter by Ian Snyder
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CodeStage.AntiCheat.ObscuredTypes;
using VSX.Vehicles;
// Attach this to anything that's targetable
public class TargetableEntity : MonoBehaviour {
public bool isPlayer = false; // Assume it's not the player
public bool isSegmentedShip = false; // Special case stuff for segmented ships
public Faction faction = Faction.Empire; // Assume it's an enemy until proven quilty
public bool flashWhenDamaged = true; // Flash when damaged!
private DamageFlash damageFlash = null;
public EnemyType.Type type;
#region Stats
public ObscuredFloat hp = 100f;
public ObscuredFloat dmgCausedByCollision = 10f; // How much damage this entity causes when it's run into
public ObscuredInt gold = 0;
[HideInInspector]
public ObscuredFloat maxHP;
public bool alive = true;
public bool escaped = false;
#endregion
#region What to say when I defeat the player
public string snarkString = "REPLACE!";
public Sprite portrait;
#endregion
#region Bounty Book stuff
public string enemyTypeDisplayName = "REPLACE DISPLAY NAME";
public string enemyBountyBookDescription = "DESCRIPTION BAD";
#endregion
public ParticleSystem muzzleFlashPS;
ParticleSystem[] muzzleFlashPSChildren;
public TrailRenderer[] wingTrails;
public Rigidbody rb;
public DemoTrackable myDemoTrackable;
void Awake(){
gameObject.tag = "TargetableEntity";
if(!isSegmentedShip)
{
Rigidbody hasRigidbody = GetComponent<Rigidbody>();
if (hasRigidbody)
{
rb = hasRigidbody;
}
else
{
rb = GetComponentInParent<Rigidbody>();
}
myDemoTrackable = GetComponent<DemoTrackable>();
}
else
{
myDemoTrackable = GetComponentInChildren<DemoTrackable>();
}
if (!isPlayer) maxHP = hp;
if (flashWhenDamaged) {
// Flash if we have the script on us
if (!damageFlash) {
damageFlash = gameObject.AddComponent<DamageFlash> ();
}
}
if( muzzleFlashPS)
{
muzzleFlashPSChildren = muzzleFlashPS.GetComponentsInChildren<ParticleSystem>();
}
}
void Start(){
StartCustom ();
}
// Override this for specific Start stuff (for enemies, allies, turrets, etc)
protected virtual void StartCustom(){
}
#region Health Management
public void TakeDamage( float amt, string dmgFromWhat = "a bullet", EnemyType.Type fromType = EnemyType.Type.Turret){
if (alive) {
amt = ModDamage (amt);
hp -= amt;
if (flashWhenDamaged) {
damageFlash.Flash ();
}
if (hp <= 0f && alive) {
Die (dmgFromWhat, fromType);
}
}
TakeDamageCustom (amt);
}
public void Heal( float amt){
if (alive) {
hp += amt;
if (hp > maxHP) {
hp = maxHP;
}
}
HealCustom (amt);
}
#endregion
#region Overrides
// Override this to mod damage
protected virtual float ModDamage(float amt){
float moddedDmg = amt;
return moddedDmg;
}
// Override this for specific damage stuff (for enemies, allies, turrets, etc)
protected virtual void TakeDamageCustom(float amt) {}
// Override this for specific healing stuff
protected virtual void HealCustom(float amt){}
// Override this for specific formation stuff (for enemies, allies, etc)
public virtual void FlyInFormation( GameObject formationPos ){}
#endregion
public void Escape(){
if (!escaped) {
escaped = true;
TargetableEntity[] childTEs = GetComponentsInChildren<TargetableEntity> ();
if (childTEs.Length > 0) {
foreach( TargetableEntity cTE in childTEs){
cTE.Escape ();
}
}
SFGameManager.instance.enemies.Remove(gameObject);
EscapeCustom ();
Destroy (gameObject);
}
}
protected virtual void EscapeCustom(){}
#region Death
public void Die( string dieFromWhat="a bullet", EnemyType.Type fromType = EnemyType.Type.Turret ){
if (alive) {
alive = false;
// Unregister from radar system
myDemoTrackable.TurnOffRadarTracking();
// For removing damage flame children
foreach (Transform c in transform.root)
{
if ( c.CompareTag("Pooled") )
{
c.GetComponent<ParticleSystem>().Stop();
}
}
if ( deathRBExplosion) RigidbodyExplosion ();
TargetableEntity[] childTEs = GetComponentsInChildren<TargetableEntity> ();
if (childTEs.Length > 0) {
foreach( TargetableEntity cTE in childTEs){
cTE.Die ();
}
}
gameObject.GetComponentInChildren<TargetableEntity> ().Die ();
DieCustom (dieFromWhat, fromType);
SFGameManager.instance.CheckForClear();
#region Update Bounty Book Save Data for a defeated enemy type
// ONLY COUNT IF PLAYER SHOT THEM
if(DDOL_MAIN.instance.skycadiaSaveData != null && !isPlayer)
{
if( fromType == EnemyType.Type.PLAYER)
{
// Update number defeated by player this time
SFGameManager.instance.numEnemiesDefeatedThisTime++;
DDOL_MAIN.instance.skycadiaSaveData.totalEnemiesDefeated++;
// If the key doesn't exist yet, create it!
if (!DDOL_MAIN.instance.skycadiaSaveData.HasKey(type.ToString()))
{
DDOL_MAIN.instance.skycadiaSaveData.SetKey(type.ToString(), "1");
}
else
{
// The string does exist, so we need to add to what we already have!
int currScore = int.Parse(DDOL_MAIN.instance.skycadiaSaveData.GetKey(type.ToString()));
currScore++;
DDOL_MAIN.instance.skycadiaSaveData.SetKey(type.ToString(), currScore.ToString());
}
}
}
#endregion
#region Update Bounty Book Save Data when the player is defeated
// We don't have turrets in-game anymore, so this is the default for dying from crashing and stuff
if (DDOL_MAIN.instance.skycadiaSaveData != null && isPlayer && fromType != EnemyType.Type.Turret)
{
// If the key doesn't exist yet, create it!
if (!DDOL_MAIN.instance.skycadiaSaveData.HasKey(fromType.ToString() + "GOTME"))
{
DDOL_MAIN.instance.skycadiaSaveData.SetKey(fromType.ToString() + "GOTME", "1");
}
else
{
// The string does exist, so we need to add to what we already have!
int currScore = int.Parse(DDOL_MAIN.instance.skycadiaSaveData.GetKey(fromType.ToString() + "GOTME"));
currScore++;
DDOL_MAIN.instance.skycadiaSaveData.SetKey(fromType.ToString() + "GOTME", currScore.ToString());
}
}
#endregion
}
}
// Override this for specific death stuff (for enemies, allies, turrets, etc)
protected virtual void DieCustom(string dieFromWhat="a bullet", EnemyType.Type fromType = EnemyType.Type.Turret){
}
// Death rigidbody explosion stuff
public bool deathRBExplosion = false;
public float deathRBExplosionRadius = 5.0F;
public float deathRBExplosionPower = 10.0F;
void RigidbodyExplosion()
{
Vector3 explosionPos = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, deathRBExplosionRadius);
foreach (Collider hit in colliders)
{
Rigidbody rb = hit.GetComponent<Rigidbody>();
if (rb != null)
rb.AddExplosionForce(deathRBExplosionPower * Random.Range(.3f, 1f), explosionPos, deathRBExplosionRadius, 0.0F);
}
}
#endregion
public void MuzzleFlash()
{
if (muzzleFlashPS)
{
//muzzleFlashPS.Emit(1);
foreach (ParticleSystem ps in muzzleFlashPSChildren)
{
ps.Play();
}
}
}
void OnCollisionEnter( Collision col){
Rigidbody colRB = col.gameObject.GetComponent<Rigidbody> ();
if (colRB) {
// NOTE Collisions to any child collider just register on the parent script, so to make the child take the damage (turret instead of the larger ship), we need to grab that specific child
TargetableEntity te = col.gameObject.GetComponentInParent<TargetableEntity> ();
if (te) {
if( te != this) // Prevent centipedes from killing themselves
{
te.TakeDamage(dmgCausedByCollision, snarkString, type);
}
}
}
if( col.gameObject.layer == 14) // This is a "collidable" and should just kill on impact?
{
TakeDamage(999999f, "That's... not gonna be cheap to fix.", EnemyType.Type.Terrain);
}
}
}