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); }
/// <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) }); } }
/// <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; }
/// <summary> Returns a value between min and max</summary> public fix NextFix(fix min, fix max) => (NextFixRatio() * (max - min)) + min;
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 }); }
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) { }
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 }); } }
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 };
/// <summary> /// Constructs a new two dimensional vector. /// </summary> public fix2(fix v) { this.x = v; this.y = v; }
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)); }
public static fix2 FromAngle(fix radians) { return(new fix2( fixMath.cos(radians), // x fixMath.sin(radians))); // y }
/// <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; }
/// <summary> Returns a value between 0 and max</summary> public fix NextFix(fix max) => NextFixRatio() * max;
/// <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); } }
/// <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; }
/// <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); }
/// <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; }
/// <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); }
/// <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; }