Esempio n. 1
0
        /// <summary>
        ///     Throw an entity at the position of <paramref name="targetLoc"/> from <paramref name="sourceLoc"/>,
        ///     without overshooting.
        /// </summary>
        /// <param name="thrownEnt">The entity to throw.</param>
        /// <param name="throwForceMax">
        /// The MAXIMUM force to throw the entity with.
        /// Throw force increases with distance to target, this is the maximum force allowed.
        /// </param>
        /// <param name="targetLoc">
        /// The target location to throw at.
        /// This function will try to land at this exact spot,
        /// if <paramref name="throwForceMax"/> is large enough to allow for it to be reached.
        /// </param>
        /// <param name="sourceLoc">
        /// The position to start the throw from.
        /// </param>
        /// <param name="spread">
        /// If true, slightly spread the actual throw angle.
        /// </param>
        /// <param name="throwSourceEnt">
        /// The entity that did the throwing. An opposite impulse will be applied to this entity if passed in.
        /// </param>
        public static void ThrowTo(this IEntity thrownEnt, float throwForceMax, EntityCoordinates targetLoc,
                                   EntityCoordinates sourceLoc, bool spread = false, IEntity throwSourceEnt = null)
        {
            var entityManager = IoCManager.Resolve <IEntityManager>();
            var timing        = IoCManager.Resolve <IGameTiming>();

            // Calculate the force necessary to land a throw based on throw duration, mass and distance.
            if (!targetLoc.TryDistance(entityManager, sourceLoc, out var distance))
            {
                return;
            }

            var throwDuration = ThrownItemComponent.DefaultThrowTime;
            var mass          = 1f;

            if (thrownEnt.TryGetComponent(out IPhysicsComponent physics))
            {
                mass = physics.Mass;
            }

            var velocityNecessary = distance / throwDuration;
            var impulseNecessary  = velocityNecessary * mass;
            var forceNecessary    = impulseNecessary * (1f / timing.TickRate);

            // Then clamp it to the max force allowed and call Throw().
            thrownEnt.Throw(MathF.Min(forceNecessary, throwForceMax), targetLoc, sourceLoc, spread, throwSourceEnt);
        }
        public void PingListeners(IEntity source, EntityCoordinates sourcePos, string message)
        {
            foreach (var listener in ComponentManager.EntityQuery <ListeningComponent>())
            {
                if (!sourcePos.TryDistance(EntityManager, listener.Owner.Transform.Coordinates, out var distance))
                {
                    return;
                }

                listener.PassSpeechData(message, source, distance);
            }
        }
        public void Update(float frameTime)
        {
            if (!Owner.TryGetComponent(out SolutionContainerComponent contents))
            {
                return;
            }

            if (!_running)
            {
                return;
            }

            _timer      += frameTime;
            _reactTimer += frameTime;

            if (_reactTimer >= ReactTime && Owner.TryGetComponent(out IPhysicsComponent physics))
            {
                _reactTimer = 0;
                var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID);

                var tile = mapGrid.GetTileRef(Owner.Transform.Coordinates.ToVector2i(Owner.EntityManager, _mapManager));
                foreach (var reagentQuantity in contents.ReagentList.ToArray())
                {
                    if (reagentQuantity.Quantity == ReagentUnit.Zero)
                    {
                        continue;
                    }
                    var reagent = _prototypeManager.Index <ReagentPrototype>(reagentQuantity.ReagentId);
                    contents.TryRemoveReagent(reagentQuantity.ReagentId, reagent.ReactionTile(tile, (reagentQuantity.Quantity / _transferAmount) * 0.25f));
                }
            }

            // Check if we've reached our target.
            if (!_reached && _target.TryDistance(Owner.EntityManager, Owner.Transform.Coordinates, out var distance) && distance <= 0.5f)
            {
                _reached = true;

                if (Owner.TryGetComponent(out IPhysicsComponent coll))
                {
                    var controller = coll.EnsureController <VaporController>();
                    controller.Stop();
                }
            }

            if (contents.CurrentVolume == 0 || _timer > _aliveTime)
            {
                // Delete this
                Owner.Delete();
            }
        }
Esempio n. 4
0
        /// <summary>
        ///     Throw an entity at the position of <paramref name="targetLoc"/> from <paramref name="sourceLoc"/>,
        ///     without overshooting.
        /// </summary>
        /// <param name="thrownEnt">The entity to throw.</param>
        /// <param name="throwForceMax">
        /// The MAXIMUM force to throw the entity with.
        /// Throw force increases with distance to target, this is the maximum force allowed.
        /// </param>
        /// <param name="targetLoc">
        /// The target location to throw at.
        /// This function will try to land at this exact spot,
        /// if <paramref name="throwForceMax"/> is large enough to allow for it to be reached.
        /// </param>
        /// <param name="sourceLoc">
        /// The position to start the throw from.
        /// </param>
        /// <param name="spread">
        /// If true, slightly spread the actual throw angle.
        /// </param>
        /// <param name="throwSourceEnt">
        /// The entity that did the throwing. An opposite impulse will be applied to this entity if passed in.
        /// </param>
        public static void ThrowTo(this IEntity thrownEnt, float throwForceMax, EntityCoordinates targetLoc,
                                   EntityCoordinates sourceLoc, bool spread = false, IEntity throwSourceEnt = null)
        {
            var entityManager = IoCManager.Resolve <IEntityManager>();
            var timing        = IoCManager.Resolve <IGameTiming>();

            // Calculate the force necessary to land a throw based on throw duration, mass and distance.
            if (!targetLoc.TryDistance(entityManager, sourceLoc, out var distance))
            {
                return;
            }

            var throwDuration = ThrownItemComponent.DefaultThrowTime;
            // TODO: Mass isn't even used on the system side yet for controllers so do that someday
            var velocityNecessary = distance / throwDuration;
            var forceNecessary    = velocityNecessary / timing.TickRate;

            // Then clamp it to the max force allowed and call Throw().
            thrownEnt.Throw(MathF.Min(forceNecessary, throwForceMax), targetLoc, sourceLoc, spread, throwSourceEnt);
        }