public static TimeValue Seconds(fix value) => new TimeValue()
 {
     Value = value, Type = ValueType.Seconds
 };
    public static void RequestExplosion(ISimGameWorldReadWriteAccessor accessor, Entity instigator, fix2 position, fix radius, int damage, bool destroyTiles)
    {
        SystemRequestExplosion request = new SystemRequestExplosion()
        {
            Damage       = damage,
            Radius       = radius,
            Instigator   = instigator,
            Position     = position,
            DestroyTiles = destroyTiles
        };

        accessor.GetSingletonBuffer <SystemRequestExplosion>().Add(request);
    }
Beispiel #3
0
 /// <summary>
 /// Returns the higher value of the two parameters.
 /// </summary>
 /// <param name="a">First value.</param>
 /// <param name="b">Second value.</param>
 /// <returns>Higher value of the two parameters.</returns>
 internal static fix Max(fix a, fix b)
 {
     return(a > b ? a : b);
 }
    public static void RequestDamage(ISimGameWorldReadWriteAccessor accessor, Entity target, fix amount, uint effectGroupID = uint.MaxValue)
    {
        var request = new HealthChangeRequestData()
        {
            Amount = -amount, Target = target, EffectGroupID = effectGroupID
        };

        accessor.GetExistingSystem <ApplyDamageSystem>().RequestHealthChange(request);
    }
    private void ProcessHealthChange(Entity target, fix amount, uint effectGroupID)
    {
        fix shieldDelta    = 0;
        fix hpDelta        = 0;
        fix remainingDelta = amount;

        // find who should be really targetted if there is a HealthProxy component. This is notably used by players since they all share the same health pool
        while (HasComponent <HealthProxy>(target))
        {
            var newTarget = GetComponent <HealthProxy>(target);
            if (newTarget == Entity.Null)
            {
                break;
            }

            target = newTarget;
        }

        // prevents too many damage instance from the same source/group
        if (effectGroupID != uint.MaxValue)
        {
            DynamicBuffer <EffectGroupBufferSingleton> effectGroupBufferSingleton = GetSingletonBuffer <EffectGroupBufferSingleton>();
            for (int i = 0; i < effectGroupBufferSingleton.Length; i++)
            {
                if (effectGroupBufferSingleton[i].ID == effectGroupID && effectGroupBufferSingleton[i].Entity == target)
                {
                    // can't take damage when we already took damage from a same id effect Group
                    return;
                }
            }

            // hard coded cooldown for effect group 0.1 for now
            effectGroupBufferSingleton.Add(new EffectGroupBufferSingleton()
            {
                ID = effectGroupID, Entity = target, TimeStamp = Time.ElapsedTime, Delay = SimulationGameConstants.SameEffectGroupDamageCooldown
            });
        }

        // If delta is negative (damage), check for invincible
        if (remainingDelta < 0 && TryGetComponent(target, out InvincibleUntilTime invincibleUntilTime) && invincibleUntilTime.Time > Time.ElapsedTime)
        {
            remainingDelta = max(remainingDelta, 0);
        }

        // Shield
        if (remainingDelta != 0 && TryGetComponent(target, out Shield previousShield))
        {
            Shield newShield = clamp(previousShield + remainingDelta, 0, GetComponent <MaximumFix <Shield> >(target).Value);
            shieldDelta = newShield.Value - previousShield.Value;
            SetComponent(target, newShield);
            remainingDelta -= shieldDelta;

            if (HasComponent <ShieldLastHitTime>(target))
            {
                SetComponent <ShieldLastHitTime>(target, Time.ElapsedTime);
            }
        }

        // Health
        if (remainingDelta != 0 && TryGetComponent(target, out Health previousHP))
        {
            Health newHP = clamp(previousHP + remainingDelta, 0, GetComponent <MaximumFix <Health> >(target).Value);
            hpDelta = newHP.Value - previousHP.Value;
            SetComponent(target, newHP);
            remainingDelta -= hpDelta;

            if (HasComponent <HealthLastHitTime>(target))
            {
                SetComponent <HealthLastHitTime>(target, Time.ElapsedTime);
            }

            // If target is dead but has life points, regenerate all values and request special action
            if (newHP.Value == 0 && TryGetComponent(target, out LifePoints lifePoints) && lifePoints.Value > 0)
            {
                // recharge HP & shield
                if (HasComponent <Health>(target))
                {
                    SetComponent <Health>(target, GetComponent <MaximumFix <Health> >(target).Value);
                }
                if (HasComponent <Shield>(target))
                {
                    SetComponent <Shield>(target, GetComponent <MaximumFix <Shield> >(target).Value);
                }

                // decrement life points
                SetComponent <LifePoints>(target, lifePoints.Value - 1);

                if (EntityManager.TryGetBuffer(target, out DynamicBuffer <LifePointLostAction> lossActions))
                {
                    foreach (var item in lossActions)
                    {
                        _gameActionSystem.ActionRequestsManaged.Add(new GameActionRequestManaged()
                        {
                            ActionEntity = item.Value,
                            Instigator   = target,
                        });
                    }
                }

                // set invincible for a minimum of 0.5 seconds
                TryGetComponent(target, out InvincibleUntilTime invincible);
                invincible.Time = max(invincible.Time, Time.ElapsedTime + (fix)0.5);
                EntityManager.AddComponentData(target, invincible);
            }
        }

        // Trigger Signal on Damage
        if (hpDelta < 0 && shieldDelta < 0 && HasComponent <TriggerSignalOnDamage>(target) && TryGetComponent(target, out SignalEmissionType emissionType))
        {
            if (emissionType.Value == ESignalEmissionType.OnClick || emissionType.Value == ESignalEmissionType.ToggleOnClick)
            {
                World.GetOrCreateSystem <SetSignalSystem>().EmitterClickRequests.Add(target);
            }
        }

        // Handle damaged entity for feedbacks
        if (hpDelta != 0 || shieldDelta != 0)
        {
            PresentationEvents.HealthDeltaEvents.Push(new HealthDeltaEventData()
            {
                AffectedEntity     = target,
                TotalUncappedDelta = amount,
                HPDelta            = hpDelta,
                ShieldDelta        = shieldDelta,
                Position           = GetComponent <FixTranslation>(target)
            });
        }
    }
Beispiel #6
0
 /// <summary>
 /// Scales a vector.
 /// </summary>
 /// <param name="v">Vector to scale.</param>
 /// <param name="scale">Amount to scale.</param>
 /// <param name="result">Scaled vector.</param>
 public static void Multiply(fix2 v, fix scale, out fix2 result)
 {
     result.x = v.x * scale;
     result.y = v.y * scale;
 }
Beispiel #7
0
 /// <summary> Returns a value between min and max</summary>
 public fix NextFix(fix min, fix max) => (NextFixRatio() * (max - min)) + min;
Beispiel #8
0
    public static void ModifyStatFix <T>(ISimGameWorldReadWriteAccessor accessor, Entity entity, fix value)
        where T : struct, IComponentData, IStatFix
    {
        fix currentValue = accessor.GetComponent <T>(entity).Value;
        fix newValue     = currentValue + value;

        SetStatFix(accessor, entity, new T {
            Value = newValue
        });
    }
Beispiel #9
0
        public static NativeList <DistanceHit> OverlapCircle(ISimGameWorldReadWriteAccessor accessor, fix2 position, fix radius, Entity ignoreEntity = default)
        {
            NativeList <DistanceHit> outHits = new NativeList <DistanceHit>(Allocator.Temp);

            OverlapCircle(accessor, position, radius, outHits, ignoreEntity);

            return(outHits);
        }
 public Description(fix rangeFromInstigator) : this((int)rangeFromInstigator)
 {
 }
Beispiel #11
0
 public static void AddStatFix <T>(ISimGameWorldReadWriteAccessor accessor, Entity entity, fix value)
     where T : struct, IComponentData, IStatFix
 {
     if (!accessor.HasComponent <T>(entity))
     {
         accessor.AddComponent(entity, new T {
             Value = value
         });
     }
 }
Beispiel #12
0
 private static void register(fix f)
 {
     fixes = append(fixes, f);
 }
 public static TimeValue Rounds(fix value) => new TimeValue()
 {
     Value = value, Type = ValueType.Rounds
 };
 public static TimeValue Turns(fix value) => new TimeValue()
 {
     Value = value, Type = ValueType.Turns
 };
Beispiel #15
0
 /// <summary>
 /// Constructs a new two dimensional vector.
 /// </summary>
 public fix2(fix v)
 {
     this.x = v;
     this.y = v;
 }
Beispiel #16
0
        public static bool OverlapCircle(ISimGameWorldReadWriteAccessor accessor, fix2 position, fix radius, NativeList <DistanceHit> outHits, Entity ignoreEntity = default)
        {
            var physicsSystem = accessor.GetExistingSystem <PhysicsWorldSystem>();

            PointDistanceInput pointDistanceInput = PointDistanceInput.Default;

            pointDistanceInput.MaxDistance = (float)radius;
            pointDistanceInput.Position    = (float2)position;

            if (ignoreEntity != Entity.Null)
            {
                pointDistanceInput.Ignore = new IgnoreHit(physicsSystem.GetPhysicsBodyIndex(ignoreEntity));
            }

            return(physicsSystem.PhysicsWorld.CalculateDistance(pointDistanceInput, ref outHits));
        }
Beispiel #17
0
 public static fix2 FromAngle(fix radians)
 {
     return(new fix2(
                fixMath.cos(radians),   // x
                fixMath.sin(radians))); // y
 }
Beispiel #18
0
 /// <summary>
 /// Computes the dot product of two vectors.
 /// </summary>
 /// <param name="a">First vector in the product.</param>
 /// <param name="b">Second vector in the product.</param>
 /// <param name="product">Resulting dot product.</param>
 public static void Dot(fix4 a, fix4 b, out fix product)
 {
     product = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
 }
Beispiel #19
0
 /// <summary> Returns a value between 0 and max</summary>
 public fix NextFix(fix max) => NextFixRatio() * max;
Beispiel #20
0
    /// <summary>
    /// Computes an intermediate location using hermite interpolation.
    /// </summary>
    /// <param name="value1">First position.</param>
    /// <param name="tangent1">Tangent associated with the first position.</param>
    /// <param name="value2">Second position.</param>
    /// <param name="tangent2">Tangent associated with the second position.</param>
    /// <param name="interpolationAmount">Amount of the second point to use.</param>
    /// <param name="result">Interpolated intermediate state.</param>
    public static void Hermite(fix4 value1, fix4 tangent1, fix4 value2, fix4 tangent2, fix interpolationAmount, out fix4 result)
    {
        fix weightSquared = interpolationAmount * interpolationAmount;
        fix weightCubed   = interpolationAmount * weightSquared;
        fix value1Blend   = F64.C2 * weightCubed - F64.C3 * weightSquared + F64.C1;
        fix tangent1Blend = weightCubed - F64.C2 * weightSquared + interpolationAmount;
        fix value2Blend   = -2 * weightCubed + F64.C3 * weightSquared;
        fix tangent2Blend = weightCubed - weightSquared;

        result.x = value1.x * value1Blend + value2.x * value2Blend + tangent1.x * tangent1Blend + tangent2.x * tangent2Blend;
        result.y = value1.y * value1Blend + value2.y * value2Blend + tangent1.y * tangent1Blend + tangent2.y * tangent2Blend;
        result.z = value1.z * value1Blend + value2.z * value2Blend + tangent1.z * tangent1Blend + tangent2.z * tangent2Blend;
        result.w = value1.w * value1Blend + value2.w * value2Blend + tangent1.w * tangent1Blend + tangent2.w * tangent2Blend;
    }
    public static void RequestDamage(ISimGameWorldReadWriteAccessor accessor, NativeArray <Entity> targets, fix amount, uint effectGroupID = uint.MaxValue)
    {
        var sys = accessor.GetExistingSystem <ApplyDamageSystem>();

        for (int i = 0; i < targets.Length; i++)
        {
            var request = new HealthChangeRequestData()
            {
                Amount = -amount, Target = targets[i], EffectGroupID = effectGroupID
            };
            sys.RequestHealthChange(request);
        }
    }
Beispiel #22
0
    /// <summary>
    /// Computes an intermediate location using hermite interpolation.
    /// </summary>
    /// <param name="value1">First position.</param>
    /// <param name="tangent1">Tangent associated with the first position.</param>
    /// <param name="value2">Second position.</param>
    /// <param name="tangent2">Tangent associated with the second position.</param>
    /// <param name="interpolationAmount">Amount of the second point to use.</param>
    /// <returns>Interpolated intermediate state.</returns>
    public static fix4 Hermite(fix4 value1, fix4 tangent1, fix4 value2, fix4 tangent2, fix interpolationAmount)
    {
        fix4 toReturn;

        Hermite(value1, tangent1, value2, tangent2, interpolationAmount, out toReturn);
        return(toReturn);
    }
 public static void RequestHeal(ISimGameWorldReadWriteAccessor accessor, Entity target, fix amount, uint effectGroupID = uint.MaxValue)
 {
     // for now a heal request is a negative damage request
     RequestDamage(accessor, target, -amount, effectGroupID);
 }
    private void UpdatePlatformVelocities()
    {
        var deltaTime = GetDeltaTime();

        // move along path
        Entities.ForEach(
            (Entity entity,
             DynamicBuffer <PathPosition> pathPositions,
             ref PhysicsVelocity velocity,
             ref FixTranslation translation,
             ref MovingPlatformState state,
             in MoveSpeed moveSpeed,
             in MovingPlatformSettings settings) =>
        {
            if (pathPositions.Length == 0)
            {
                velocity.Linear = fix2.zero;
                return;
            }

            if (HasComponent <Signal>(entity))
            {
                Signal signal = GetComponent <Signal>(entity);
                if (!signal.Value)
                {
                    velocity.Linear = fix2.zero;
                    return;
                }
            }

            if (state.RemainingWaitTime > TimeValue.Zero)
            {
                velocity.Linear          = fix2.zero;
                state.RemainingWaitTime -= deltaTime.GetValue(state.RemainingWaitTime.Type);
                return;
            }

            var pathAccessor = new PathAccessor(pathPositions, settings.MoveMode == PlatformMoveMode.Yoyo);

            fix actualMoveSpeed = moveSpeed.Value;

            if (settings.SlowDownNearNodes)
            {
                // If the platform is near the past or next node, clamp speed to smaller value
                fix nodeDist = sqrt(sqrt(min(
                                             lengthsq(translation.Value - pathAccessor[state.NextStep - 1]),
                                             lengthsq(translation.Value - pathAccessor[state.NextStep]))));

                fix maximumSpeed = MovingPlatformSettings.SLOW_DOWN_MINIMUM_SPEED + (nodeDist * MovingPlatformSettings.SLOW_DOWN_FACTOR_INV);

                actualMoveSpeed = min(maximumSpeed, moveSpeed.Value);
            }

            fix moveDist = actualMoveSpeed * deltaTime.Seconds.Value;

            fix2 a      = translation.Value;
            fix2 b      = translation.Value;
            fix2 v      = fix2(0);
            fix vLength = 0;

            bool incrementStep = false;
            int beginIndex     = state.NextStep % pathAccessor.Length;

            while (moveDist > vLength)
            {
                moveDist -= vLength;
                a         = b;

                if (incrementStep)
                {
                    state.NextStep++;

                    if (beginIndex == state.NextStep % pathAccessor.Length)     // if we've done a full loop, stop here. This prevents infinite while loops.
                    {
                        break;
                    }

                    if (settings.MoveMode == PlatformMoveMode.LoopTeleport && pathAccessor.IsStart(state.NextStep))
                    {
                        a = pathAccessor[state.NextStep];
                        translation.Value = pathAccessor[state.NextStep];
                        state.NextStep++;
                    }

                    if (settings.PauseOnNodesDuration > TimeValue.Zero)
                    {
                        state.RemainingWaitTime = settings.PauseOnNodesDuration;
                    }
                }

                incrementStep = true;
                b             = pathAccessor[state.NextStep];

                v       = b - a;
                vLength = length(v);
            }

            fix2 dir            = (vLength == 0 ? fix2(0) : (v / vLength));
            fix2 targetPosition = a + (dir * min(moveDist, vLength));
            fix2 targetVelocity = (targetPosition - translation.Value) / deltaTime.Seconds.Value;
            velocity.Linear     = targetVelocity;
        }).Run();
 /// <summary>
 /// Remove every element from the lottery
 /// </summary>
 public void Clear()
 {
     _list.Clear();
     TotalWeight = 0;
 }
Beispiel #26
0
 /// <summary>
 /// Computes the dot product of the two vectors.
 /// </summary>
 /// <param name="a">First vector of the dot product.</param>
 /// <param name="b">Second vector of the dot product.</param>
 /// <param name="dot">Dot product of the two vectors.</param>
 public static void Dot(fix2 a, fix2 b, out fix dot)
 {
     dot = a.x * b.x + a.y * b.y;
 }
 public static bool IsInRange(ISimWorldReadAccessor accessor, Entity entityA, Entity entityB, fix rangeMax)
 {
     return(fixMath.distancesq(
                accessor.GetComponent <FixTranslation>(entityB),
                accessor.GetComponent <FixTranslation>(entityA)) < rangeMax * rangeMax);
 }
Beispiel #28
0
 /// <summary>
 /// Constructs a new two dimensional vector.
 /// </summary>
 /// <param name="x">X component of the vector.</param>
 /// <param name="y">Y component of the vector.</param>
 public fix2(fix x, fix y)
 {
     this.x = x;
     this.y = y;
 }
Beispiel #29
0
 /// <summary>
 /// Returns the lower value of the two parameters.
 /// </summary>
 /// <param name="a">First value.</param>
 /// <param name="b">Second value.</param>
 /// <returns>Lower value of the two parameters.</returns>
 internal static fix Min(fix a, fix b)
 {
     return(a < b ? a : b);
 }
Beispiel #30
0
 /// <summary>
 /// Constructs a new 3 row, 3 column matrix.
 /// </summary>
 /// <param name="m11">Value at row 1, column 1 of the matrix.</param>
 /// <param name="m12">Value at row 1, column 2 of the matrix.</param>
 /// <param name="m13">Value at row 1, column 3 of the matrix.</param>
 /// <param name="m21">Value at row 2, column 1 of the matrix.</param>
 /// <param name="m22">Value at row 2, column 2 of the matrix.</param>
 /// <param name="m23">Value at row 2, column 3 of the matrix.</param>
 /// <param name="m31">Value at row 3, column 1 of the matrix.</param>
 /// <param name="m32">Value at row 3, column 2 of the matrix.</param>
 /// <param name="m33">Value at row 3, column 3 of the matrix.</param>
 public fix3x3(fix m11, fix m12, fix m13, fix m21, fix m22, fix m23, fix m31, fix m32, fix m33)
 {
     M11 = m11;
     M12 = m12;
     M13 = m13;
     M21 = m21;
     M22 = m22;
     M23 = m23;
     M31 = m31;
     M32 = m32;
     M33 = m33;
 }