/// <summary>
        /// Call if this entity is relevant for the pathfinder
        /// </summary>
        /// <param name="entity"></param>
        /// TODO: These 2 methods currently don't account for a bunch of changes (e.g. airlock unpowered, wrenching, etc.)
        /// TODO: Could probably optimise this slightly more.
        public void AddEntity(IEntity entity, IPhysicsComponent physicsComponent)
        {
            // If we're a door
            if (entity.HasComponent <AirlockComponent>() || entity.HasComponent <ServerDoorComponent>())
            {
                // If we need access to traverse this then add to readers, otherwise no point adding it (except for maybe tile costs in future)
                // TODO: Check for powered I think (also need an event for when it's depowered
                // AccessReader calls this whenever opening / closing but it can seem to get called multiple times
                // Which may or may not be intended?
                if (entity.TryGetComponent(out AccessReader accessReader) && !_accessReaders.ContainsKey(entity))
                {
                    _accessReaders.Add(entity, accessReader);
                    ParentChunk.Dirty();
                }
                return;
            }

            DebugTools.Assert((PathfindingSystem.TrackedCollisionLayers & physicsComponent.CollisionLayer) != 0);

            if (!physicsComponent.Anchored)
            {
                _physicsLayers.Add(entity, physicsComponent.CollisionLayer);
            }
            else
            {
                _blockedCollidables.Add(entity, physicsComponent.CollisionLayer);
                GenerateMask();
                ParentChunk.Dirty();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Returns information about given voxel face which is then used in meshing algorithm
        /// </summary>
        /// <param name="x">Chunk segment relative block X coordinate.</param>
        /// <param name="y">Chunk segment relative block Y coordinate.</param>
        /// <param name="z">Chunk segment relative block Z coordinate.</param>
        /// <param name="side">Face side we want to get, is one of constants in the beginning of this file</param>
        /// <returns>Face data about the block</returns>
        /// <remarks>
        /// Currently returns only block data since face data are not yet implemented
        /// X, Y, Z are in the range of -1 to 16 (chunk +- 1 block from neighbor)
        /// </remarks>
        private Block GetVoxelFace(int x, int y, int z, int side)
        {
            var xValid = x >= 0 && x < VoxelWorld.Configuration.ChunkSegmentSize;
            var yValid = y >= 0 && y < VoxelWorld.Configuration.ChunkSegmentSize;
            var zValid = z >= 0 && z < VoxelWorld.Configuration.ChunkSegmentSize;

            // Current segment
            if (xValid && yValid && zValid)
            {
                return(Blocks[x, y, z]);
            }

            // Get world absolute Y coordinate
            var absY = VoxelWorld.Configuration.ChunkSegmentSize * _segmentIndex + y;

            // Current chunk (this is faster then performing chunk lookup)
            if (!yValid && xValid && zValid)
            {
                return(ParentChunk.GetBlock(x, absY, z));
            }

            // Perform world-wide block lookup
            var absX = VoxelWorld.Configuration.ChunkSegmentSize * ParentChunk.WorldPosition.X + x;
            var absZ = VoxelWorld.Configuration.ChunkSegmentSize * ParentChunk.WorldPosition.Y + z;

            return(ParentChunk.World.GetBlock(absX, absY, absZ));
        }
        /// <summary>
        /// Starts the generation of a <see cref="TagHelperChunk"/>.
        /// </summary>
        /// <param name="target">
        /// The <see cref="Block"/> responsible for this <see cref="TagHelperChunkGenerator"/>.
        /// </param>
        /// <param name="context">A <see cref="ChunkGeneratorContext"/> instance that contains information about
        /// the current chunk generation process.</param>
        public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
        {
            var tagHelperBlock = target as TagHelperBlock;

            Debug.Assert(
                tagHelperBlock != null,
                $"A {nameof(TagHelperChunkGenerator)} must only be used with {nameof(TagHelperBlock)}s.");

            var attributes = new List <TagHelperAttributeTracker>();

            // We need to create a chunk generator to create chunks for each of the attributes.
            var chunkGenerator = context.Host.CreateChunkGenerator(
                context.ClassName,
                context.RootNamespace,
                context.SourceFile);

            foreach (var attribute in tagHelperBlock.Attributes)
            {
                ParentChunk attributeChunkValue = null;

                if (attribute.Value != null)
                {
                    // Populates the chunk tree with chunks associated with attributes
                    attribute.Value.Accept(chunkGenerator);

                    var chunks = chunkGenerator.Context.ChunkTreeBuilder.Root.Children;
                    var first  = chunks.FirstOrDefault();

                    attributeChunkValue = new ParentChunk
                    {
                        Association = first?.Association,
                        Children    = chunks,
                        Start       = first == null ? SourceLocation.Zero : first.Start
                    };
                }

                var attributeChunk = new TagHelperAttributeTracker(
                    attribute.Name,
                    attributeChunkValue,
                    attribute.ValueStyle);

                attributes.Add(attributeChunk);

                // Reset the chunk tree builder so we can build a new one for the next attribute
                chunkGenerator.Context.ChunkTreeBuilder = new ChunkTreeBuilder();
            }

            var unprefixedTagName = tagHelperBlock.TagName.Substring(_tagHelperDescriptors.First().Prefix.Length);

            context.ChunkTreeBuilder.StartParentChunk(
                new TagHelperChunk(
                    unprefixedTagName,
                    tagHelperBlock.TagMode,
                    attributes,
                    _tagHelperDescriptors),
                target,
                topLevel: false);
        }
        /// <summary>
        /// Starts the generation of a <see cref="TagHelperChunk"/>.
        /// </summary>
        /// <param name="target">
        /// The <see cref="Block"/> responsible for this <see cref="TagHelperChunkGenerator"/>.
        /// </param>
        /// <param name="context">A <see cref="ChunkGeneratorContext"/> instance that contains information about
        /// the current chunk generation process.</param>
        public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
        {
            var tagHelperBlock = target as TagHelperBlock;

            Debug.Assert(
                tagHelperBlock != null,
                $"A {nameof(TagHelperChunkGenerator)} must only be used with {nameof(TagHelperBlock)}s.");

            var attributes = new List<KeyValuePair<string, Chunk>>();

            // We need to create a chunk generator to create chunks for each of the attributes.
            var chunkGenerator = context.Host.CreateChunkGenerator(
                context.ClassName,
                context.RootNamespace,
                context.SourceFile);

            foreach (var attribute in tagHelperBlock.Attributes)
            {
                ParentChunk attributeChunkValue = null;

                if (attribute.Value != null)
                {
                    // Populates the chunk tree with chunks associated with attributes
                    attribute.Value.Accept(chunkGenerator);

                    var chunks = chunkGenerator.Context.ChunkTreeBuilder.ChunkTree.Chunks;
                    var first = chunks.FirstOrDefault();

                    attributeChunkValue = new ParentChunk
                    {
                        Association = first?.Association,
                        Children = chunks,
                        Start = first == null ? SourceLocation.Zero : first.Start
                    };
                }

                attributes.Add(new KeyValuePair<string, Chunk>(attribute.Key, attributeChunkValue));

                // Reset the chunk tree builder so we can build a new one for the next attribute
                chunkGenerator.Context.ChunkTreeBuilder = new ChunkTreeBuilder();
            }

            var unprefixedTagName = tagHelperBlock.TagName.Substring(_tagHelperDescriptors.First().Prefix.Length);

            context.ChunkTreeBuilder.StartParentChunk(
                new TagHelperChunk(
                    unprefixedTagName,
                    tagHelperBlock.TagMode,
                    attributes,
                    _tagHelperDescriptors),
                target,
                topLevel: false);
        }
Esempio n. 5
0
        /// <summary>
        /// Writes code for the given <paramref name="chunk"/>.
        /// </summary>
        /// <param name="chunk">The <see cref="ParentChunk"/> to render.</param>
        /// <remarks>
        /// Tracks code mappings for all children while writing.
        /// </remarks>
        protected override void Visit(ParentChunk chunk)
        {
            // Line mappings are captured in RenderCode(), not this method.
            _firstChild = true;
            Accept(chunk.Children);

            if (_firstChild)
            {
                // Attribute value was empty.
                Context.ErrorSink.OnError(
                    chunk.Association.Start,
                    RazorResources.TagHelpers_AttributeExpressionRequired,
                    chunk.Association.Length);
            }
        }
        /// <summary>
        /// Return our neighboring nodes (even across chunks)
        /// </summary>
        /// <returns></returns>
        public IEnumerable <PathfindingNode> GetNeighbors()
        {
            List <PathfindingChunk> neighborChunks = null;

            if (ParentChunk.OnEdge(this))
            {
                neighborChunks = ParentChunk.RelevantChunks(this).ToList();
            }

            for (var x = -1; x <= 1; x++)
            {
                for (var y = -1; y <= 1; y++)
                {
                    if (x == 0 && y == 0)
                    {
                        continue;
                    }
                    var indices = new Vector2i(TileRef.X + x, TileRef.Y + y);
                    if (ParentChunk.InBounds(indices))
                    {
                        var(relativeX, relativeY) = (indices.X - ParentChunk.Indices.X,
                                                     indices.Y - ParentChunk.Indices.Y);
                        yield return(ParentChunk.Nodes[relativeX, relativeY]);
                    }
                    else
                    {
                        DebugTools.AssertNotNull(neighborChunks);
                        // Get the relevant chunk and then get the node on it
                        foreach (var neighbor in neighborChunks)
                        {
                            // A lot of edge transitions are going to have a single neighboring chunk
                            // (given > 1 only affects corners)
                            // So we can just check the count to see if it's inbound
                            if (neighborChunks.Count > 0 && !neighbor.InBounds(indices))
                            {
                                continue;
                            }
                            var(relativeX, relativeY) = (indices.X - neighbor.Indices.X,
                                                         indices.Y - neighbor.Indices.Y);
                            yield return(neighbor.Nodes[relativeX, relativeY]);

                            break;
                        }
                    }
                }
            }
        }
Esempio n. 7
0
 public bool FindSuccessNode()
 {
     if (SuccessNode == null)
     {
         ActionNodeState successState = null;
         if (ParentChunk.GetNode(State.SuccessActionNodeName, false, out successState))
         {
             SuccessNode = successState.actionNode;
             if (SuccessNode == null)
             {
                 //Debug.Log ("Couldn't find success node in " + name + " but it doesn't matter, still returning true");
                 return(false);
             }
         }
     }
     return(true);
 }
Esempio n. 8
0
        public override bool OnPlayerEnter()
        {
            if (mDimmingLanterns)
            {
                return(false);
            }

            if (LanternsToDim.Count == 0)
            {
                WorldItem lanternWorldItem = null;
                for (int i = 0; i < State.LanternsToDim.Count; i++)
                {
                    MobileReference mr = State.LanternsToDim[i];
                    if (WIGroups.FindChildItem(mr.GroupPath, mr.FileName, out lanternWorldItem))
                    {
                        LanternsToDim.Add(lanternWorldItem);
                    }
                }
                if (State.LanternsToDim.Count == 0)
                {
                    return(false);
                }
            }

            if (GuardInterventionTrigger == null)
            {
                WorldTriggerState wts = null;
                if (ParentChunk.GetTriggerState(State.GuardInterventionTriggerName, out wts))
                {
                    GuardInterventionTrigger = wts.trigger as TriggerGuardIntervention;
                }
                else
                {
                    return(false);
                }
            }

            mDimmingLanterns = true;
            mStartTime       = WorldClock.AdjustedRealTime;
            StartCoroutine(DimLanternsOverTime());

            return(true);
        }
 /// <summary>
 /// Remove the entity from this node.
 /// Will check each category and remove it from the applicable one
 /// </summary>
 /// <param name="entity"></param>
 public void RemoveEntity(IEntity entity)
 {
     // There's no guarantee that the entity isn't deleted
     // 90% of updates are probably entities moving around
     // Entity can't be under multiple categories so just checking each once is fine.
     if (_physicsLayers.ContainsKey(entity))
     {
         _physicsLayers.Remove(entity);
     }
     else if (_accessReaders.ContainsKey(entity))
     {
         _accessReaders.Remove(entity);
         ParentChunk.Dirty();
     }
     else if (_blockedCollidables.ContainsKey(entity))
     {
         _blockedCollidables.Remove(entity);
         GenerateMask();
         ParentChunk.Dirty();
     }
 }
Esempio n. 10
0
 public bool FindGuardNode()
 {
     if (GuardNode == null)
     {
         ActionNodeState guardNodeState = null;
         if (ParentChunk.GetNode(State.GuardActionNodeName, false, out guardNodeState))
         {
             guardNodeState.OccupantIsDead = State.GuardIsDead;
             GuardNode = guardNodeState.actionNode;
             if (GuardNode == null)
             {
                 //Debug.Log ("Couldn't get guard node from action node state, quitting in " + name);
                 return(false);
             }
         }
         else
         {
             //Debug.Log ("Couldn't get guard node from parent chunk, quitting in " + name);
             return(false);
         }
     }
     return(true);
 }
Esempio n. 11
0
        public override bool OnPlayerEnter()
        {
            if (AvailableSpawnNodes.Count == 0)
            {
                ParentChunk.GetNodes(State.AvailableSpawnNodes, true, AvailableSpawnNodes);
            }
            //now get the node we want to spawn at
            if (AvailableSpawnNodes.Count == 0)
            {
                Debug.Log("NO SPAWN NODES AVAILBLE in " + name);
                return(false);
            }

            if (mSpawningOverTime)
            {
                return(false);
            }
            else
            {
                mSpawningOverTime = true;
                StartCoroutine(SpawnOverTime());
                return(true);
            }
        }
 public void UpdateTile(TileRef newTile)
 {
     TileRef = newTile;
     ParentChunk.Dirty();
 }
        public PathfindingNode GetNeighbor(Direction direction)
        {
            var      chunkXOffset = TileRef.X - ParentChunk.Indices.X;
            var      chunkYOffset = TileRef.Y - ParentChunk.Indices.Y;
            Vector2i neighborVector2i;

            switch (direction)
            {
            case Direction.East:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.NorthEast:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.North:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.NorthWest:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.West:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.SouthWest:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.South:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.SouthEast:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            default:
                throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
            }
        }
 protected virtual void Visit(ParentChunk chunk)
 {
     Accept(chunk.Children);
 }
 protected abstract void Visit(ParentChunk chunk);
Esempio n. 16
0
        protected IEnumerator DimLanternsOverTime()
        {
            Debug.Log("Dimming lanterns!");

            GUI.GUIManager.PostIntrospection(State.IntrospectionBeforeStarting, true);

            double waitUntil = WorldClock.AdjustedRealTime + State.InitialDelay;

            while (WorldClock.AdjustedRealTime < waitUntil)
            {
                yield return(null);
            }

            GuardInterventionTrigger.SuspendGuard();
            //GuardInterventionTrigger.gameObject.SetActive (false);

            for (int i = 0; i < LanternsToDim.Count; i++)
            {
                LanternDimmer ld = LanternsToDim[i].Get <LanternDimmer>();
                ld.StartDimming();
                waitUntil = WorldClock.AdjustedRealTime + 0.5f;
            }

            if (State.UseReactivationTrigger)
            {
                WorldTriggerState reactivationTriggerState = null;
                if (ParentChunk.GetTriggerState(State.ReactivationTriggerName, out reactivationTriggerState))
                {
                    int numTimesTriggeredOnStart = reactivationTriggerState.NumTimesTriggered;
                    while (reactivationTriggerState.NumTimesTriggered == numTimesTriggeredOnStart)
                    {
                        //wait until it's been triggered again
                        waitUntil = WorldClock.AdjustedRealTime + 0.5f;
                        while (WorldClock.AdjustedRealTime < waitUntil)
                        {
                            yield return(null);
                        }
                    }
                }
            }
            else
            {
                while (WorldClock.AdjustedRealTime < mStartTime + State.RTDimDuration)
                {
                    yield return(null);
                }
            }

            for (int i = 0; i < LanternsToDim.Count; i++)
            {
                LanternDimmer ld = LanternsToDim[i].Get <LanternDimmer>();
                ld.StopDimming();
                waitUntil = WorldClock.AdjustedRealTime + 0.5f;
                while (WorldClock.AdjustedRealTime < waitUntil)
                {
                    yield return(null);
                }
            }

            //GuardInterventionTrigger.gameObject.SetActive (true);
            GuardInterventionTrigger.ResumeGuard(false);

            mDimmingLanterns = false;
            yield break;
        }
Esempio n. 17
0
 protected override void Visit(ParentChunk chunk)
 {
     Accept(chunk.Children);
 }
Esempio n. 18
0
 protected override void Visit(ParentChunk chunk)
 {
 }