r2mods/ilspy_dump/ror2_csproj/EntityStates.Treebot.Treebo.../TreebotFlower2Projectile.cs

222 lines
6.0 KiB
C#

using System.Collections.Generic;
using RoR2;
using RoR2.Orbs;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.Networking;
namespace EntityStates.Treebot.TreebotFlower;
public class TreebotFlower2Projectile : BaseState
{
public static float yankIdealDistance;
public static AnimationCurve yankSuitabilityCurve;
public static float healthFractionYieldPerHit;
public static float radius;
public static float healPulseCount;
public static float duration;
public static float rootPulseCount;
public static string enterSoundString;
public static string exitSoundString;
public static GameObject enterEffectPrefab;
public static GameObject exitEffectPrefab;
private List<CharacterBody> rootedBodies;
private float healTimer;
private float rootPulseTimer;
private GameObject owner;
private ProcChainMask procChainMask;
private float procCoefficient;
private TeamIndex teamIndex = TeamIndex.None;
private float damage;
private DamageTypeCombo damageType;
private bool crit;
private float healPulseHealthFractionValue;
private static int SpawnToIdleStateHash = Animator.StringToHash("SpawnToIdle");
public override void OnEnter()
{
base.OnEnter();
ProjectileController component = GetComponent<ProjectileController>();
if ((bool)component)
{
owner = component.owner;
procChainMask = component.procChainMask;
procCoefficient = component.procCoefficient;
teamIndex = component.teamFilter.teamIndex;
}
ProjectileDamage component2 = GetComponent<ProjectileDamage>();
if ((bool)component2)
{
damage = component2.damage;
damageType = component2.damageType;
crit = component2.crit;
}
if (NetworkServer.active)
{
rootedBodies = new List<CharacterBody>();
}
PlayAnimation("Base", SpawnToIdleStateHash);
Util.PlaySound(enterSoundString, base.gameObject);
if ((bool)enterEffectPrefab)
{
EffectManager.SimpleEffect(enterEffectPrefab, base.transform.position, base.transform.rotation, transmit: false);
}
ChildLocator component3 = GetModelTransform().GetComponent<ChildLocator>();
if ((bool)component3)
{
Transform obj = component3.FindChild("AreaIndicator");
obj.localScale = new Vector3(radius, radius, radius);
obj.gameObject.SetActive(value: true);
}
}
public override void FixedUpdate()
{
base.FixedUpdate();
if (NetworkServer.active)
{
float deltaTime = GetDeltaTime();
rootPulseTimer -= deltaTime;
healTimer -= deltaTime;
if (rootPulseTimer <= 0f)
{
rootPulseTimer += duration / rootPulseCount;
RootPulse();
}
if (healTimer <= 0f)
{
healTimer += duration / healPulseCount;
HealPulse();
}
if (base.fixedAge >= duration)
{
EntityState.Destroy(base.gameObject);
}
}
}
private void RootPulse()
{
Vector3 position = base.transform.position;
HurtBox[] hurtBoxes = new SphereSearch
{
origin = position,
radius = radius,
mask = LayerIndex.entityPrecise.mask
}.RefreshCandidates().FilterCandidatesByHurtBoxTeam(TeamMask.GetEnemyTeams(teamIndex)).OrderCandidatesByDistance()
.FilterCandidatesByDistinctHurtBoxEntities()
.GetHurtBoxes();
foreach (HurtBox hurtBox in hurtBoxes)
{
CharacterBody body = hurtBox.healthComponent.body;
if (!rootedBodies.Contains(body))
{
rootedBodies.Add(body);
body.AddBuff(RoR2Content.Buffs.Entangle);
body.RecalculateStats();
Vector3 vector = hurtBox.transform.position - position;
float magnitude = vector.magnitude;
Vector3 vector2 = vector / magnitude;
Rigidbody component = hurtBox.healthComponent.GetComponent<Rigidbody>();
float num = (component ? component.mass : 1f);
float num2 = magnitude - yankIdealDistance;
float num3 = yankSuitabilityCurve.Evaluate(num);
Vector3 vector3 = (component ? component.velocity : Vector3.zero);
if (HGMath.IsVectorNaN(vector3))
{
vector3 = Vector3.zero;
}
Vector3 vector4 = -vector3;
if (num2 > 0f)
{
vector4 = vector2 * (0f - Trajectory.CalculateInitialYSpeedForHeight(num2, 0f - body.acceleration));
}
Vector3 force = vector4 * (num * num3);
DamageInfo damageInfo = new DamageInfo
{
attacker = owner,
inflictor = base.gameObject,
crit = crit,
damage = damage,
damageColorIndex = DamageColorIndex.Default,
damageType = damageType,
force = force,
position = hurtBox.transform.position,
procChainMask = procChainMask,
procCoefficient = procCoefficient
};
hurtBox.healthComponent.TakeDamage(damageInfo);
HurtBox hurtBoxReference = hurtBox;
HurtBoxGroup hurtBoxGroup = hurtBox.hurtBoxGroup;
for (int j = 0; (float)j < Mathf.Min(4f, body.radius * 2f); j++)
{
EffectData effectData = new EffectData
{
scale = 1f,
origin = position,
genericFloat = Mathf.Max(0.2f, duration - base.fixedAge)
};
effectData.SetHurtBoxReference(hurtBoxReference);
EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/OrbEffects/EntangleOrbEffect"), effectData, transmit: true);
hurtBoxReference = hurtBoxGroup.hurtBoxes[Random.Range(0, hurtBoxGroup.hurtBoxes.Length)];
}
}
}
}
public override void OnExit()
{
if (rootedBodies != null)
{
foreach (CharacterBody rootedBody in rootedBodies)
{
rootedBody.RemoveBuff(RoR2Content.Buffs.Entangle);
}
rootedBodies = null;
}
Util.PlaySound(exitSoundString, base.gameObject);
if ((bool)exitEffectPrefab)
{
EffectManager.SimpleEffect(exitEffectPrefab, base.transform.position, base.transform.rotation, transmit: false);
}
base.OnExit();
}
private void HealPulse()
{
HealthComponent healthComponent = (owner ? owner.GetComponent<HealthComponent>() : null);
if ((bool)healthComponent && rootedBodies.Count > 0)
{
float num = 1f / healPulseCount;
HealOrb healOrb = new HealOrb();
healOrb.origin = base.transform.position;
healOrb.target = healthComponent.body.mainHurtBox;
healOrb.healValue = num * healthFractionYieldPerHit * healthComponent.fullHealth * (float)rootedBodies.Count;
healOrb.overrideDuration = 0.3f;
OrbManager.instance.AddOrb(healOrb);
}
}
}