public override bool Execute(float dt) { if (Entity.Target.Value != null) { var diff = Entity.Target.Value.Position - Entity.Position; if (_predictShots) { var targetHullData = Entity.ItemManager.GetData(Entity.Target.Value.Hull) as HullData; var targetVelocity = float3(Entity.Target.Value.Velocity.x, 0, Entity.Target.Value.Velocity.y); var predictedPosition = AetheriaMath.FirstOrderIntercept( Entity.Position, float3.zero, _shotSpeed, Entity.Target.Value.Position, targetVelocity ); predictedPosition.y = Entity.Zone.GetHeight(predictedPosition.xz) + targetHullData.GridOffset; Entity.LookDirection = normalize(predictedPosition - Entity.Position); } else { Entity.LookDirection = normalize(diff); } var dist = length(diff); foreach (var x in _weapons) { var data = x.Data as WeaponData; var fire = dot( x.Direction, Entity.LookDirection) > .99f; if (x.Evaluate(data.Range) > dist && fire) { x.Activate(); } else if (x.Firing) { x.Deactivate(); } } } else { foreach (var x in _weapons) { if (x.Firing) { x.Deactivate(); } } Entity.Target.Value = Entity.VisibleEnemies.FirstOrDefault(e => e is Ship); } return(true); }
void Update() { if (SourceEntity == null) { return; } var t = transform; if (_active) { if (TargetPosition == null && !Target) { StartCoroutine(FadeOut()); return; } var position = (float3)t.position; var targetPosition = TargetPosition?.Invoke() ?? Target.position; _targetVelocity = lerp(_targetVelocity, targetPosition - _previousTargetPosition, saturate(Time.deltaTime * 5)); _previousTargetPosition = targetPosition; targetPosition = AetheriaMath.FirstOrderIntercept(position, float3.zero, TopSpeed, targetPosition, _targetVelocity); var diff = targetPosition - transform.position; var targetDist = diff.magnitude; var sourceDist = length(StartPosition.xz - position.xz); if (sourceDist > Range || dot(diff, Velocity) < 0) { StartCoroutine(FadeOut()); if (HitEffect != null) { var ht = HitEffect.Instantiate <Transform>(); ht.position = t.position; } return; } _prevDist = targetDist; var targetDistFlat = diff.Flatland().magnitude; var curveLerp = 1 - targetDistFlat / (sourceDist + targetDistFlat); var dir = diff.normalized; var right = cross(dir, float3(0, 1, 0)); var up = cross(dir, right); if (Children > 0 && SplitTime < curveLerp) { for (int i = 0; i < Children; i++) { var child = ChildProjectile.Instantiate <GuidedProjectile>(); child.transform.position = t.position; child.StartPosition = StartPosition; var randomDirection = normalize(Random.insideUnitCircle); var perpendicularRandom = randomDirection.x * right + randomDirection.y * up; child.Velocity = normalize(lerp(perpendicularRandom, dir, SplitSeparationForwardness)) * length(Velocity) * SplitSeparationVelocity; child.Range = Range; child.Damage = Damage / Children; child.Penetration = Penetration; child.Spread = Spread; child.DamageType = DamageType; child.Source = Source; child.Target = Target; child.SourceEntity = SourceEntity; child.GuidanceCurve = GuidanceCurve; child.LiftCurve = LiftCurve; child.ThrustCurve = ThrustCurve; child.Thrust = Thrust; child.TopSpeed = TopSpeed; child.Frequency = Frequency; child.Thrust = Thrust; } StartCoroutine(Kill()); if (HitEffect != null) { var ht = HitEffect.Instantiate <Transform>(); ht.position = t.position; } } var dodge = normalize(lerp( normalize(right * noise(Time.time * Frequency + _phase) + up * noise(Time.time * Frequency + (100 + _phase))), Vector3.up, LiftCurve.Evaluate(curveLerp))); var desired = Vector3.Slerp(dodge, dir, GuidanceCurve.Evaluate(curveLerp)).normalized *TopSpeed; var thrustCurve = ThrustCurve.Evaluate(curveLerp); var thrust = Thrust * thrustCurve; var c = Color.white * thrustCurve; c.a = 1; Particles.startColor = c; Velocity += (desired - Velocity).normalized * (thrust * Time.deltaTime); } if (_alive) { var ray = new Ray(t.position, Velocity); foreach (var hit in Physics.RaycastAll(ray, Velocity.magnitude * Time.deltaTime, 1 | (1 << 17))) { var shield = hit.collider.GetComponent <ShieldManager>(); if (shield) { if (!(shield.Entity.Shield != null && shield.Entity.Shield.Item.Active.Value && shield.Entity.Shield.CanTakeHit(DamageType, Damage))) { continue; } if (shield.Entity != SourceEntity) { shield.Entity.Shield.TakeHit(DamageType, Damage); shield.ShowHit(hit.point, sqrt(Damage)); } } var hull = hit.collider.GetComponent <HullCollider>(); if (hull && !(hull.Entity.Shield != null && hull.Entity.Shield.Item.Active.Value && hull.Entity.Shield.CanTakeHit(DamageType, Damage))) { if (hull.Entity != SourceEntity) { hull.SendHit(Damage, Penetration, Spread, DamageType, SourceEntity, hit.textureCoord, transform.forward); transform.position = hit.point; StartCoroutine(Kill()); } } else// if (hit.transform.gameObject.layer == 1) { StartCoroutine(Kill()); return; } if (HitEffect != null) { var ht = HitEffect.Instantiate <Transform>(); ht.SetParent(hit.collider.transform); ht.position = hit.point; return; } } t.position += Velocity * Time.deltaTime; } }
public override bool Execute(float dt) { Entity.Velocity = AetheriaMath.Damp(Entity.Velocity, Entity.Direction * length(Entity.Velocity), Evaluate(_data.Lambda), dt); return(true); }
public override void Update(float delta) { if (_active && !_exitingWormhole && !_enteringWormhole) { RecalculateThrust(); foreach (var thruster in _allThrusters) { thruster.Axis = 0; } var rightThrusterTorqueCompensation = abs(RightStrafeTotalTorque) / RightStrafeTorqueThrusters.Count; foreach (var thruster in _rightThrusters) { var thrust = 0f; thrust += MovementDirection.x; if (RightStrafeTorqueThrusters.Contains(thruster)) { thrust -= MovementDirection.x * (rightThrusterTorqueCompensation / (abs(thruster.Torque) * thruster.Thrust)); } thruster.Axis = thrust; } var leftThrusterTorqueCompensation = abs(LeftStrafeTotalTorque) / LeftStrafeTorqueThrusters.Count; foreach (var thruster in _leftThrusters) { var thrust = 0f; thrust += -MovementDirection.x; if (LeftStrafeTorqueThrusters.Contains(thruster)) { thrust += MovementDirection.x * (leftThrusterTorqueCompensation / (abs(thruster.Torque) * thruster.Thrust)); } thruster.Axis = thrust; } foreach (var thruster in _forwardThrusters) { thruster.Axis += MovementDirection.y; } foreach (var thruster in _reverseThrusters) { thruster.Axis += -MovementDirection.y; } var look = normalize(LookDirection.xz); var deltaRot = dot(look, normalize(Direction).Rotate(ItemRotation.Clockwise)); if (abs(deltaRot) < .01f) { deltaRot = 0; Direction = lerp(Direction, look, min(delta, 1)); } deltaRot = pow(abs(deltaRot), .5f) * sign(deltaRot); foreach (var thruster in _clockwiseThrusters) { thruster.Axis += deltaRot; } foreach (var thruster in _counterClockwiseThrusters) { thruster.Axis += -deltaRot; } foreach (var drive in _aetherDrives) { drive.Axis = float3(MovementDirection.y, MovementDirection.x, deltaRot); } } var velocityMagnitude = length(Velocity); if (velocityMagnitude > .01f) { Velocity = normalize(Velocity) * AetheriaMath.Decay(velocityMagnitude, HullData.Drag, delta); } Position.xz += Velocity * delta; var normal = Zone.GetNormal(Position.xz); var force = new float2(normal.x, normal.z); var forceMagnitude = lengthsq(force); if (forceMagnitude > .001f) { var fa = 1 / (1 - forceMagnitude) - 1; Velocity += normalize(force) * Zone.Settings.GravityStrength * fa; } var shipRight = Direction.Rotate(ItemRotation.Clockwise); var forward = cross(float3(shipRight.x, 0, shipRight.y), normal); Rotation = quaternion.LookRotation(forward, normal); base.Update(delta); if (_exitingWormhole) { _wormholeAnimationProgress += delta / ItemManager.GameplaySettings.WormholeAnimationDuration; if (_wormholeAnimationProgress < 1) { if (_wormholeAnimationProgress < ItemManager.GameplaySettings.WormholeExitCurveStart) { Position.xz = _wormholePosition; Rotation = quaternion.LookRotation(float3(0, 1, 0), float3(-Direction.x, 0, -Direction.y)); } else { var exitLerp = (_wormholeAnimationProgress - ItemManager.GameplaySettings.WormholeExitCurveStart) / (1 - ItemManager.GameplaySettings.WormholeExitCurveStart); exitLerp = AetheriaMath.Smootherstep(exitLerp); // Square the interpolation variable to produce curve with zero slope at start Position.xz = _wormholePosition + normalize(_wormholeExitVelocity) * exitLerp * ItemManager.GameplaySettings.WormholeExitRadius; Rotation = quaternion.LookRotation( lerp(float3(0, 1, 0), forward, exitLerp), lerp(float3(-Direction.x, 0, -Direction.y), normal, exitLerp)); } Position.y = Position.y - lerp(ItemManager.GameplaySettings.WormholeDepth, 0, _wormholeAnimationProgress); } else { _exitingWormhole = false; OnExitedWormhole?.Invoke(); OnExitedWormhole = null; Velocity = _wormholeExitVelocity; } } if (_enteringWormhole) { _wormholeAnimationProgress += delta / ItemManager.GameplaySettings.WormholeAnimationDuration; if (_wormholeAnimationProgress < 1) { if (_wormholeAnimationProgress < 1 - ItemManager.GameplaySettings.WormholeExitCurveStart) { var enterLerp = _wormholeAnimationProgress / (1 - ItemManager.GameplaySettings.WormholeExitCurveStart); enterLerp = AetheriaMath.Smootherstep(enterLerp); // Square the interpolation variable to produce curve with zero slope at vertical Position.xz = lerp(_wormholeEntryPosition, _wormholePosition, enterLerp); Rotation = quaternion.LookRotation( lerp(forward, float3(0, -1, 0), enterLerp), lerp(normal, float3(-_wormholeEntryDirection.x, 0, -_wormholeEntryDirection.y), enterLerp)); } else { Position.xz = _wormholePosition; Rotation = quaternion.LookRotation(float3(0, -1, 0), float3(-_wormholeEntryDirection.x, 0, -_wormholeEntryDirection.y)); } Position.y = Position.y - lerp(0, ItemManager.GameplaySettings.WormholeDepth, _wormholeAnimationProgress); } else { _enteringWormhole = false; OnEnteredWormhole?.Invoke(); OnEnteredWormhole = null; } } }