Exemplo n.º 1
0
        protected CardinalDirection AdjustForWalls(CardinalDirection dir)
        {
            if (!BlockedByWall(dir))
            {
                return(dir);
            }
            var scanDirection = Unit.Owner.MirrorDefault ? -1 : 1;

            for (var i = 1; i <= 5; i++)                // sweep side to side until first exit found
            {
                dir = dir.ArcClockwise(i * scanDirection);
                if (!BlockedByWall(dir))
                {
                    return(dir);
                }
                scanDirection *= -1;                            // swap scan direction
            }
                        #if DEBUG
            Debug.LogWarningFormat("Unit at {0} has no available exits!", Unit.Position);
                        #endif
            return(dir);                // should only happen if terrain changes behind unit
        }
Exemplo n.º 2
0
    // RELATIVE DIRECTION UTLITIES - use these where possible

    /// <summary>
    /// Find a direction relative to this one, using a RelativeDirection
    /// eg: North.Turn(ForwardRight) = Northeast
    ///     Southwest.Turn(BackLeft) = Southeast
    /// </summary>
    /// <param name="facing">the initial, forward-pointing direction</param>
    /// <param name="relative">a relative direction to be applied to it</param>
    /// <returns>the CardinalDirection that is 'relative' to 'facing'</returns>
    public static CardinalDirection Turn(this CardinalDirection facing, RelativeDirection relative)
    {
        return(facing.ArcClockwise((int)relative));
    }
Exemplo n.º 3
0
 public static void ArcClockwise(CardinalDirection init, int arc, CardinalDirection expected)
 {
     Assert.AreEqual(expected, init.ArcClockwise(arc));
 }
Exemplo n.º 4
0
    public static List <Spell> Invoke(Stage stage, TileVector pos, CardinalDirection dir)
    {
        var map     = stage.ToDictionary();
        var history = new List <Spell>();

        HashSet <Plantable> currentPlantableArea = null;

        while (map.ContainsKey(pos))
        {
            var space = map[pos];

            if (currentPlantableArea == null)
            {
                if (space.Plantable != null && space.Plantable.State == PlantableState.Vacant)
                {
                    currentPlantableArea = new HashSet <Plantable>();

                    var fringe = new Queue <TileVector>();
                    fringe.Enqueue(pos);

                    while (fringe.Count > 0)                            // find all adjacent plantables.
                    {
                        var fringePos = fringe.Dequeue();
                        if (!map.ContainsKey(fringePos))
                        {
                            continue;
                        }

                        var plantable = map[fringePos].Plantable;
                        if (plantable == null || currentPlantableArea.Contains(plantable))
                        {
                            continue;
                        }

                        currentPlantableArea.Add(plantable);
                        foreach (var adj in fringePos.Adjacent())
                        {
                            fringe.Enqueue(adj);
                        }
                    }
                }
            }
            else if (!currentPlantableArea.Contains(space.Plantable))                   // stepped out of the plant area
            {
                bool solved = currentPlantableArea.All(p =>
                {
                    var plant = map[p.TilePos].Occupant as Plant;
                    return(plant != null && plant.Hits > 0);
                });

                foreach (var plantable in currentPlantableArea)
                {
                    plantable.State = solved ? PlantableState.Solved : PlantableState.Imbued;
                }
                currentPlantableArea = null;
            }

            var spell = new Spell(pos, dir, currentPlantableArea);              // record this frame of the spell invocation
            history.Add(spell);

            if (space.HasTile && !space.Tile.BlockSpell)                // advance spell
            {
                var plant = space.Occupant as Plant;
                if (plant != null)
                {
                    spell.Plant = plant;                                        // add plant to record, for convinience

                    switch (plant.Type)                                         // trigger plant side effects
                    {
                    case PlantType.Twist:
                        dir = dir.ArcClockwise(1);
                        break;
                    }

                    if (currentPlantableArea != null)            // implies this area is being activated by this current spell
                    {
                        plant.Hits += 1;                         // make plant grow
                    }
                }
                pos = pos + dir;
            }
            else
            {
                if (currentPlantableArea != null)
                {
                    foreach (var plantable in currentPlantableArea)
                    {
                        plantable.State = PlantableState.Imbued;
                    }
                }
                break;                          // end the spell invocation
            }
        }
        return(history);
    }