Ejemplo n.º 1
0
        protected List <Parsed.Object> MultiDivert()
        {
            Whitespace();

            List <Parsed.Object> diverts = null;

            // Try single thread first
            var threadDivert = Parse(StartThread);

            if (threadDivert)
            {
                diverts = new List <Object> ();
                diverts.Add(threadDivert);
                return(diverts);
            }

            // Normal diverts and tunnels
            var arrowsAndDiverts = Interleave <object> (
                ParseDivertArrowOrTunnelOnwards,
                DivertIdentifierWithArguments);

            if (arrowsAndDiverts == null)
            {
                return(null);
            }

            diverts = new List <Parsed.Object> ();

            // Possible patterns:
            //  ->                   -- explicit gather
            //  ->->                 -- tunnel onwards
            //  -> div               -- normal divert
            //  ->-> div             -- tunnel onwards, followed by override divert
            //  -> div ->            -- normal tunnel
            //  -> div ->->          -- tunnel then tunnel continue
            //  -> div -> div        -- tunnel then divert
            //  -> div -> div ->     -- tunnel then tunnel
            //  -> div -> div ->->
            //  -> div -> div ->-> div    (etc)

            // Look at the arrows and diverts
            for (int i = 0; i < arrowsAndDiverts.Count; ++i)
            {
                bool isArrow = (i % 2) == 0;

                // Arrow string
                if (isArrow)
                {
                    // Tunnel onwards
                    if ((string)arrowsAndDiverts [i] == "->->")
                    {
                        bool tunnelOnwardsPlacementValid = (i == 0 || i == arrowsAndDiverts.Count - 1 || i == arrowsAndDiverts.Count - 2);
                        if (!tunnelOnwardsPlacementValid)
                        {
                            Error("Tunnel onwards '->->' must only come at the begining or the start of a divert");
                        }

                        var tunnelOnwards = new TunnelOnwards();
                        if (i < arrowsAndDiverts.Count - 1)
                        {
                            var tunnelOnwardDivert = arrowsAndDiverts [i + 1] as Parsed.Divert;
                            tunnelOnwards.divertAfter = tunnelOnwardDivert;
                        }

                        diverts.Add(tunnelOnwards);

                        // Not allowed to do anything after a tunnel onwards.
                        // If we had anything left it would be caused in the above Error for
                        // the positioning of a ->->
                        break;
                    }
                }

                // Divert
                else
                {
                    var divert = arrowsAndDiverts [i] as Divert;

                    // More to come? (further arrows) Must be tunnelling.
                    if (i < arrowsAndDiverts.Count - 1)
                    {
                        divert.isTunnel = true;
                    }

                    diverts.Add(divert);
                }
            }

            // Single -> (used for default choices)
            if (diverts.Count == 0 && arrowsAndDiverts.Count == 1)
            {
                var gatherDivert = new Divert((Parsed.Object)null);
                gatherDivert.isEmpty = true;
                diverts.Add(gatherDivert);

                if (!_parsingChoice)
                {
                    Error("Empty diverts (->) are only valid on choices");
                }
            }

            return(diverts);
        }
Ejemplo n.º 2
0
 public DivertTarget(Divert divert)
 {
     this.divert = AddContent(divert);
 }
Ejemplo n.º 3
0
        protected List <Parsed.Object> MultiDivert()
        {
            Whitespace();

            List <Parsed.Object> diverts = null;

            // Try single thread first
            var threadDivert = Parse(StartThread);

            if (threadDivert)
            {
                diverts = new List <Object> ();
                diverts.Add(threadDivert);
                return(diverts);
            }

            // Normal diverts and tunnels
            var arrowsAndDiverts = Interleave <object> (
                ParseDivertArrowOrTunnelOnwards,
                DivertIdentifierWithArguments);

            if (arrowsAndDiverts == null)
            {
                return(null);
            }

            diverts = new List <Parsed.Object> ();

            // Possible patterns:
            //  ->                   -- explicit gather
            //  ->->                 -- tunnel onwards
            //  -> div               -- normal divert
            //  ->-> div             -- tunnel onwards, followed by override divert
            //  -> div ->            -- normal tunnel
            //  -> div ->->          -- tunnel then tunnel continue
            //  -> div -> div        -- tunnel then divert
            //  -> div -> div ->     -- tunnel then tunnel
            //  -> div -> div ->->   (etc)

            bool hasInitialTunnelOnwards = false;
            bool hasFinalTunnelOnwards   = false;

            // Look at the arrows and diverts
            for (int i = 0; i < arrowsAndDiverts.Count; ++i)
            {
                bool isArrow = (i % 2) == 0;

                // Arrow string
                if (isArrow)
                {
                    string arrow = arrowsAndDiverts [i] as string;
                    if (arrow == "->->")
                    {
                        if (i == 0)
                        {
                            hasInitialTunnelOnwards = true;
                        }
                        else if (i == arrowsAndDiverts.Count - 1)
                        {
                            hasFinalTunnelOnwards = true;
                        }
                        else
                        {
                            Error("Tunnel onwards '->->' must only come at the begining or the start of a divert");
                        }
                    }
                }

                // Divert
                else
                {
                    var divert = arrowsAndDiverts [i] as Divert;

                    // More to come? (further arrows) Must be tunnelling.
                    if (i < arrowsAndDiverts.Count - 1)
                    {
                        divert.isTunnel = true;
                    }

                    diverts.Add(divert);
                }
            }

            // ->-> (with optional override divert)
            if (hasInitialTunnelOnwards)
            {
                if (arrowsAndDiverts.Count > 2)
                {
                    Error("Tunnel onwards '->->' must either be on its own or followed by a single target");
                }

                var tunnelOnwards = new TunnelOnwards();

                // Optional override target to divert to after tunnel onwards?
                // Replace divert with the tunnel onwards to that target.
                if (arrowsAndDiverts.Count > 1)
                {
                    var overrideDivert = diverts [0] as Parsed.Divert;
                    tunnelOnwards.overrideReturnPath = overrideDivert.target;
                    diverts.RemoveAt(0);
                }

                diverts.Add(tunnelOnwards);
            }

            // Single ->
            else if (diverts.Count == 0 && arrowsAndDiverts.Count == 1)
            {
                var gatherDivert = new Divert((Parsed.Object)null);
                gatherDivert.isToGather = true;
                diverts.Add(gatherDivert);
            }

            // Divert that terminates in ->->
            else if (hasFinalTunnelOnwards)
            {
                diverts.Add(new TunnelOnwards());
            }

            return(diverts);
        }
Ejemplo n.º 4
0
        protected List <Parsed.Object> MultiStepTunnelDivert()
        {
            Whitespace();

            var arrowsAndDiverts = Interleave <object> (
                ParseDivertArrowOrTunnelOnwards,
                DivertIdentifierWithArguments);

            if (arrowsAndDiverts == null)
            {
                return(null);
            }

            var diverts = new List <Parsed.Object> ();

            // Divert arrow only:
            // ->
            // ->->
            // (with no target)
            if (arrowsAndDiverts.Count == 1)
            {
                // Single:
                // ->
                // Assume if there are no target components, it must be a divert to a gather point
                if ((string)arrowsAndDiverts [0] == "->")
                {
                    var gatherDivert = new Divert((Parsed.Object)null);
                    gatherDivert.isToGather = true;
                    diverts.Add(gatherDivert);
                }

                // Double: (tunnel onwards)
                // ->->
                else
                {
                    diverts.Add(new TunnelOnwards());
                }
            }

            // Possible patterns:
            //  -> div               -- normal divert
            //  -> div ->            -- normal tunnel
            //  -> div ->->          -- tunnel then tunnel continue
            //  -> div -> div        -- tunnel then divert
            //  -> div -> div ->     -- tunnel then tunnel
            //  -> div -> div ->->   (etc)
            else
            {
                bool hasFinalTunnelOnwards = false;

                // Look at the arrows and diverts
                for (int i = 0; i < arrowsAndDiverts.Count; ++i)
                {
                    bool isArrow = (i % 2) == 0;

                    // Arrow string
                    if (isArrow)
                    {
                        string arrow = arrowsAndDiverts [i] as string;
                        if (arrow == "->->")
                        {
                            if (i == arrowsAndDiverts.Count - 1)
                            {
                                hasFinalTunnelOnwards = true;
                            }
                            else
                            {
                                Error("Unexpected content after a '->->' tunnel onwards");
                            }
                        }
                    }

                    // Divert
                    else
                    {
                        var divert = arrowsAndDiverts [i] as Divert;

                        // More to come? (further arrows) Must be tunnelling.
                        if (i < arrowsAndDiverts.Count - 1)
                        {
                            divert.isTunnel = true;
                        }

                        diverts.Add(divert);
                    }
                }

                if (hasFinalTunnelOnwards)
                {
                    diverts.Add(new TunnelOnwards());
                }
            }

            return(diverts);
        }
Ejemplo n.º 5
0
 public DivertTarget(Divert divert)
 {
     this.divert = AddContent(divert);
 }