Skip to content

Instantly share code, notes, and snippets.

@SalehAce1
Last active July 8, 2020 22:08
Show Gist options
  • Save SalehAce1/0448a531e9d179dc5ef8910ccfebdc2b to your computer and use it in GitHub Desktop.
Save SalehAce1/0448a531e9d179dc5ef8910ccfebdc2b to your computer and use it in GitHub Desktop.
public class ArmorCtrl : MonoBehaviour
{
private GameObject _target;
private Animator _anim;
private SpriteRenderer _sr;
private Rigidbody2D _rb;
private BoxCollider2D _bc;
private System.Random _rand;
private HealthManager _hm;
private DamageHero _dh;
private InfectedEnemyEffects _iee;
private bool _attacking;
private Dictionary<Action, int> counter;
void Awake()
{
_anim = gameObject.GetComponent<Animator>();
_sr = gameObject.GetComponent<SpriteRenderer>();
_rb = gameObject.GetComponent<Rigidbody2D>();
_bc = gameObject.GetComponent<BoxCollider2D>();
_rand = new System.Random();
_target = HeroController.instance.gameObject;
_dh = gameObject.AddComponent<DamageHero>();
_hm = gameObject.AddComponent<HealthManager>();
_iee = gameObject.AddComponent<InfectedEnemyEffects>();
counter = new Dictionary<Action, int>()
{
[Sweep] = 0,
[Punch] = 0,
[Strike] = 0,
[Block] = 0
};
}
void Start()
{
AssignValues();
transform.position = _target.transform.position + new Vector3(8f, -1.5f);
_hm.OnDeath += HmOnOnDeath;
On.HealthManager.TakeDamage += HealthManagerOnTakeDamage;
StartCoroutine(AttackChoice());
}
private void HmOnOnDeath()
{
Logger.Log("Killing Enemy");
StopAllCoroutines();
Death();
}
private void HealthManagerOnTakeDamage(On.HealthManager.orig_TakeDamage orig, HealthManager self,
HitInstance hitinstance)
{
if (self.name.Contains("ArmorLord"))
{
// Spit out infection when hit
_iee.RecieveHitEffect(hitinstance.Direction);
}
orig(self, hitinstance);
}
private void AssignValues()
{
_dh.damageDealt = 2;
_hm.hp = 1000;
gameObject.layer = 11;
// Making it so that the boxcolliders damage you
foreach (Transform t in gameObject.transform)
{
if (t.name == "Fire") continue;
t.gameObject.AddComponent<DamageHero>().damageDealt = 2;
t.gameObject.layer = 22;
if (t.GetComponent<SpriteRenderer>() != null)
{
t.GetComponent<SpriteRenderer>().material = new Material(Shader.Find("Sprites/Default"));
}
}
// Setting fire attack stuff
foreach (Transform t in gameObject.transform.Find("Fire"))
{
t.gameObject.AddComponent<DamageHero>().damageDealt = 2;
t.gameObject.layer = 22;
t.GetComponent<SpriteRenderer>().material = new Material(Shader.Find("Sprites/Default"));
}
// I preloaded lost kin to use his healthmanager and hiteffect settings.
HealthManager hornHP = Tutorial.preloadedGO["Kin"].GetComponent<HealthManager>();
foreach (FieldInfo fi in typeof(HealthManager).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.Name.Contains("Prefab")))
{
fi.SetValue(_hm, fi.GetValue(hornHP));
}
InfectedEnemyEffects ogrimHitEffects = Tutorial.preloadedGO["Kin"].GetComponent<InfectedEnemyEffects>();
foreach (FieldInfo fi in typeof(InfectedEnemyEffects).GetFields(
BindingFlags.Instance | BindingFlags.NonPublic))
{
// Reposition where the hit effect comes from to be slightly higher
if (fi.Name == "effectOrigin")
{
fi.SetValue(_iee, new Vector3(0, 0.5f, 0f));
}
else fi.SetValue(_iee, fi.GetValue(ogrimHitEffects));
}
Logger.Log("Done Assigning");
}
private IEnumerator AttackChoice()
{
// Wait till last attack is done
yield return new WaitWhile(() => _attacking);
_anim.Play("Idle");
_attacking = true;
yield return new WaitForSeconds(0.1f);
Action curr = Walk;
// List of attack options
List<Action> atts = new List<Action>()
{
Sweep,
Punch,
Block,
Strike
};
// Choose attack randomly
curr = atts[_rand.Next(0, atts.Count)];
// Choose an attack that has not been repeated
while (counter[curr] > 0)
{
// Remove the old attack so we don't choose it again
atts.Remove(curr);
curr = atts[_rand.Next(0, atts.Count)];
}
// If player is far walk towards them
if (Vector2.Distance(_target.transform.position, transform.position) > 8f)
{
curr = Walk;
}
Logger.Log("Doing " + curr.Method.Name);
curr.Invoke();
// Reset attack counter
foreach (Action act in atts)
{
if (act == Walk) continue;
counter[act] = (act == curr) ? counter[act] + 1 : 0;
}
// Repeat
StartCoroutine(AttackChoice());
}
private void Sweep()
{
IEnumerator Sweep()
{
float dir = FaceHero();
_anim.Play("Sweep");
yield return null;
yield return new WaitWhile(() => _anim.GetCurrentFrame() < 6);
Vector3 f1O = gameObject.transform.Find("Fire").Find("F1").position;
for (int i = 0; i < 3; i++)
{
StartCoroutine(SpawnFire(f1O + new Vector3(dir * i * 6f, 0f, 0f)));
yield return new WaitForSeconds(0.05f);
}
yield return new WaitWhile(() => _anim.IsPlaying());
_attacking = false;
}
IEnumerator SpawnFire(Vector2 pos)
{
GameObject f1O = gameObject.transform.Find("Fire").Find("F1").gameObject;
GameObject f2O = gameObject.transform.Find("Fire").Find("F2").gameObject;
GameObject f1 = Instantiate(f1O);
f1.transform.position = pos;
f1.transform.localScale = new Vector3(5f, 5f);
f1.SetActive(true);
f1.GetComponent<BoxCollider2D>().enabled = false;
yield return new WaitForSeconds(0.2f);
Destroy(f1);
GameObject f2 = Instantiate(f2O);
f2.transform.position = pos;
f2.transform.localScale = new Vector3(8f, 8f);
f2.SetActive(true);
yield return new WaitForSeconds(0.1f);
Destroy(f2);
}
StartCoroutine(Sweep());
}
private void Punch()
{
IEnumerator Punch()
{
float dir = FaceHero();
_anim.Play("Punch");
yield return null;
yield return new WaitWhile(() => _anim.IsPlaying());
_anim.Play("PunchInt");
dir = FaceHero();
yield return new WaitForSeconds(0.5f);
_anim.Play("PunchEnd");
yield return null;
yield return new WaitWhile(() => _anim.IsPlaying());
_attacking = false;
}
StartCoroutine(Punch());
}
private void Block()
{
IEnumerator Block()
{
float dir = FaceHero();
_anim.Play("Block");
yield return null;
yield return new WaitWhile(() => _anim.GetCurrentFrame() < 2);
_hm.IsInvincible = true;
yield return new WaitWhile(() => _anim.IsPlaying());
_hm.IsInvincible = false;
_attacking = false;
}
StartCoroutine(Block());
}
private void Strike()
{
IEnumerator Strike()
{
float dir = FaceHero();
_anim.Play("Strike");
yield return null;
yield return new WaitWhile(() => _anim.IsPlaying());
_attacking = false;
}
StartCoroutine(Strike());
}
private void Walk()
{
IEnumerator Walk()
{
float dir = FaceHero();
_anim.Play("Walk");
_rb.velocity = new Vector2(dir * 10f, 0f);
yield return new WaitForSeconds(0.5f);
_rb.velocity = new Vector2(0f, 0f);
_attacking = false;
}
StartCoroutine(Walk());
}
private void Death()
{
IEnumerator Death()
{
_anim.Play("Death");
_bc.enabled = false;
yield return null;
yield return new WaitWhile(() => _anim.IsPlaying());
_attacking = false;
}
StartCoroutine(Death());
}
// Flips gameobject to face the hero and returns direction of go.
private float FaceHero(bool shouldRev)
{
float heroSignX = Mathf.Sign(_target.transform.position.x - gameObject.transform.position.x);
Vector3 pScale = gameObject.transform.localScale;
gameObject.transform.localScale = new Vector3(Mathf.Abs(pScale.x) * heroSignX, pScale.y, 1f);
return heroSignX;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment