191 lines
5.3 KiB
C#
191 lines
5.3 KiB
C#
|
using RoR2;
|
||
|
using RoR2.Projectile;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Networking;
|
||
|
|
||
|
namespace EntityStates.LaserTurbine;
|
||
|
|
||
|
public class FireMainBeamState : LaserTurbineBaseState
|
||
|
{
|
||
|
public static float baseDuration;
|
||
|
|
||
|
public static float mainBeamDamageCoefficient;
|
||
|
|
||
|
public static float mainBeamProcCoefficient;
|
||
|
|
||
|
public static float mainBeamForce;
|
||
|
|
||
|
public static float mainBeamRadius;
|
||
|
|
||
|
public static float mainBeamMaxDistance;
|
||
|
|
||
|
public static GameObject forwardBeamTracerEffect;
|
||
|
|
||
|
public static GameObject backwardBeamTracerEffect;
|
||
|
|
||
|
public static GameObject mainBeamImpactEffect;
|
||
|
|
||
|
public static GameObject secondBombPrefab;
|
||
|
|
||
|
public static float secondBombDamageCoefficient;
|
||
|
|
||
|
private Ray initialAimRay;
|
||
|
|
||
|
private Vector3 beamHitPosition;
|
||
|
|
||
|
private bool isCrit;
|
||
|
|
||
|
protected override bool shouldFollow => true;
|
||
|
|
||
|
public override void OnEnter()
|
||
|
{
|
||
|
base.OnEnter();
|
||
|
if (base.isAuthority)
|
||
|
{
|
||
|
initialAimRay = GetAimRay();
|
||
|
}
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
isCrit = base.ownerBody.RollCrit();
|
||
|
FireBeamServer(initialAimRay, forwardBeamTracerEffect, mainBeamMaxDistance, isInitialBeam: true);
|
||
|
}
|
||
|
base.laserTurbineController.showTurbineDisplay = false;
|
||
|
}
|
||
|
|
||
|
public override void Update()
|
||
|
{
|
||
|
base.Update();
|
||
|
if (base.isAuthority && base.fixedAge >= baseDuration)
|
||
|
{
|
||
|
outer.SetNextState(new RechargeState());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void OnExit()
|
||
|
{
|
||
|
if (NetworkServer.active && !outer.destroying)
|
||
|
{
|
||
|
Vector3 direction = initialAimRay.origin - beamHitPosition;
|
||
|
Ray aimRay = new Ray(beamHitPosition, direction);
|
||
|
FireBeamServer(aimRay, backwardBeamTracerEffect, direction.magnitude, isInitialBeam: false);
|
||
|
}
|
||
|
base.laserTurbineController.showTurbineDisplay = true;
|
||
|
base.OnExit();
|
||
|
}
|
||
|
|
||
|
private void FireBeamServer(Ray aimRay, GameObject tracerEffectPrefab, float maxDistance, bool isInitialBeam)
|
||
|
{
|
||
|
bool didHit = false;
|
||
|
BulletAttack obj = new BulletAttack
|
||
|
{
|
||
|
origin = aimRay.origin,
|
||
|
aimVector = aimRay.direction,
|
||
|
bulletCount = 1u,
|
||
|
damage = GetDamage() * mainBeamDamageCoefficient,
|
||
|
damageColorIndex = DamageColorIndex.Item,
|
||
|
damageType = DamageType.Generic,
|
||
|
falloffModel = BulletAttack.FalloffModel.None,
|
||
|
force = mainBeamForce,
|
||
|
hitEffectPrefab = mainBeamImpactEffect,
|
||
|
HitEffectNormal = false,
|
||
|
hitMask = LayerIndex.entityPrecise.mask,
|
||
|
isCrit = isCrit,
|
||
|
maxDistance = maxDistance,
|
||
|
minSpread = 0f,
|
||
|
maxSpread = 0f,
|
||
|
muzzleName = "",
|
||
|
owner = base.ownerBody.gameObject,
|
||
|
procChainMask = default(ProcChainMask),
|
||
|
procCoefficient = mainBeamProcCoefficient,
|
||
|
queryTriggerInteraction = QueryTriggerInteraction.UseGlobal,
|
||
|
radius = mainBeamRadius,
|
||
|
smartCollision = true,
|
||
|
sniper = false,
|
||
|
spreadPitchScale = 1f,
|
||
|
spreadYawScale = 1f,
|
||
|
stopperMask = LayerIndex.world.mask,
|
||
|
tracerEffectPrefab = (isInitialBeam ? tracerEffectPrefab : null),
|
||
|
weapon = base.gameObject
|
||
|
};
|
||
|
TeamIndex teamIndex = base.ownerBody.teamComponent.teamIndex;
|
||
|
obj.hitCallback = delegate(BulletAttack _bulletAttack, ref BulletAttack.BulletHit info)
|
||
|
{
|
||
|
bool flag = BulletAttack.defaultHitCallback(_bulletAttack, ref info);
|
||
|
if (!isInitialBeam)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
if (flag)
|
||
|
{
|
||
|
HealthComponent healthComponent = (info.hitHurtBox ? info.hitHurtBox.healthComponent : null);
|
||
|
if ((bool)healthComponent && healthComponent.alive && info.hitHurtBox.teamIndex != teamIndex)
|
||
|
{
|
||
|
flag = false;
|
||
|
}
|
||
|
}
|
||
|
if (!flag)
|
||
|
{
|
||
|
didHit = true;
|
||
|
beamHitPosition = info.point;
|
||
|
}
|
||
|
return flag;
|
||
|
};
|
||
|
obj.filterCallback = delegate(BulletAttack _bulletAttack, ref BulletAttack.BulletHit info)
|
||
|
{
|
||
|
return (!info.entityObject || (object)info.entityObject != _bulletAttack.owner) && BulletAttack.defaultFilterCallback(_bulletAttack, ref info);
|
||
|
};
|
||
|
obj.Fire();
|
||
|
if (!didHit)
|
||
|
{
|
||
|
if (Physics.Raycast(aimRay, out var hitInfo, mainBeamMaxDistance, LayerIndex.world.mask, QueryTriggerInteraction.Ignore))
|
||
|
{
|
||
|
didHit = true;
|
||
|
beamHitPosition = hitInfo.point;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
beamHitPosition = aimRay.GetPoint(mainBeamMaxDistance);
|
||
|
}
|
||
|
}
|
||
|
if (didHit && isInitialBeam)
|
||
|
{
|
||
|
FireProjectileInfo fireProjectileInfo = default(FireProjectileInfo);
|
||
|
fireProjectileInfo.projectilePrefab = secondBombPrefab;
|
||
|
fireProjectileInfo.owner = base.ownerBody.gameObject;
|
||
|
fireProjectileInfo.position = beamHitPosition - aimRay.direction * 0.5f;
|
||
|
fireProjectileInfo.rotation = Quaternion.identity;
|
||
|
fireProjectileInfo.damage = GetDamage() * secondBombDamageCoefficient;
|
||
|
fireProjectileInfo.damageColorIndex = DamageColorIndex.Item;
|
||
|
fireProjectileInfo.crit = isCrit;
|
||
|
ProjectileManager.instance.FireProjectile(fireProjectileInfo);
|
||
|
}
|
||
|
if (!isInitialBeam)
|
||
|
{
|
||
|
EffectData effectData = new EffectData
|
||
|
{
|
||
|
origin = aimRay.origin,
|
||
|
start = base.transform.position
|
||
|
};
|
||
|
effectData.SetNetworkedObjectReference(base.gameObject);
|
||
|
EffectManager.SpawnEffect(tracerEffectPrefab, effectData, transmit: true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void OnSerialize(NetworkWriter writer)
|
||
|
{
|
||
|
base.OnSerialize(writer);
|
||
|
Vector3 origin = initialAimRay.origin;
|
||
|
Vector3 direction = initialAimRay.direction;
|
||
|
writer.Write(origin);
|
||
|
writer.Write(direction);
|
||
|
}
|
||
|
|
||
|
public override void OnDeserialize(NetworkReader reader)
|
||
|
{
|
||
|
base.OnDeserialize(reader);
|
||
|
Vector3 origin = reader.ReadVector3();
|
||
|
Vector3 direction = reader.ReadVector3();
|
||
|
initialAimRay = new Ray(origin, direction);
|
||
|
}
|
||
|
}
|