コード例 #1
0
ファイル: Segment.cs プロジェクト: wwarnick/Sever
 /// <summary>Clones the provided segment.  All references to other nodes or segments are deep.</summary>
 /// <param name="toClone">The segment to clone.</param>
 public Segment(Segment toClone)
     : this(toClone.InWorld)
 {
     this.ID = toClone.ID;
     this.EndLoc = (VectorF[])toClone.EndLoc.Clone();
     this.CurLength = toClone.CurLength;
     this.State = (SegState[])toClone.State.Clone();
     this.owner = toClone.Owner;
     this.Length = toClone.Length;
     this.EndLength = (FInt[])toClone.EndLength.Clone();
     this.Nodes = (Node[])toClone.Nodes.Clone();
     this.People[0] = toClone.People[0].Clone();
     this.People[1] = toClone.People[1].Clone();
     this.NumPeople = toClone.NumPeople;
     this.Capacity = toClone.Capacity;
     this.CurCapacity = toClone.CurCapacity;
     this.curLaneCapacity = toClone.CurLaneCapacity;
     this.Direction = toClone.Direction;
     this.DirectionPerp = toClone.DirectionPerp;
     this.Angle = toClone.Angle;
     this.Destroyed = toClone.Destroyed;
 }
コード例 #2
0
ファイル: WorldLoader.cs プロジェクト: wwarnick/Sever
        private static void readSegmentVars1(List<string[]> commands, World map, List<Segment> segList, Dictionary<string, Segment> segments, Dictionary<string, Player> players)
        {
            double tempDbl = 0d;
            int tempInt = 0;
            Segment segment = new Segment(map);

            for (int j = 1; j < commands.Count; j++)
            {
                string value = translateValue(commands[j][2], "[Segment]", map, segment);
                bool valueValid = true;
                switch (commands[j][0])
                {
                    case "ID":
                        segment.ID = value;
                        segments.Add(value, segment);
                        break;
                    case "Node":
                    case "EndLength":
                        // do nothing until next step
                        break;
                    case "Owner":
                        segment.Owner = players[value];
                        break;
                    case "State":
                        valueValid = int.TryParse(commands[j][1], out tempInt);
                        switch (value)
                        {
                            case "Complete":
                                segment.State[tempInt] = Segment.SegState.Complete;
                                break;
                            case "Retracting":
                                segment.State[tempInt] = Segment.SegState.Retracting;
                                break;
                            case "Building":
                                segment.State[tempInt] = Segment.SegState.Building;
                                break;
                            default:
                                throw new Exception("Unrecognized segment lane state: " + value);
                        }
                        break;
                    case "Person":
                        valueValid = int.TryParse(commands[j][1], out tempInt);
                        string[] people = value.Split(',');
                        foreach (string p in people)
                        {
                            if (double.TryParse(p, out tempDbl))
                                segment.People[tempInt].AddLast((FInt)tempDbl);
                        }
                        break;
                    default:
                        throw new Exception("Segment variable not recognized: " + commands[j][0]);
                }

                if (!valueValid)
                    throw new Exception("Value '" + commands[j][2] + "' not valid for variable '" + commands[j][0] + "'.");
            }

            segList.Add(segment);
        }
コード例 #3
0
ファイル: LevelEditorMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Removes the selected segment from the world.</summary>
        private void removeSelSeg()
        {
            int index = selectedSeg.Nodes[0].getSegIndex(selectedSeg);
            if (index != -1)
                selectedSeg.Nodes[0].removeSegment(index, false, false);

            index = selectedSeg.Nodes[1].getSegIndex(selectedSeg);
            if (index != -1)
                selectedSeg.Nodes[1].removeSegment(index, false, false);

            world.removeSegment(selectedSeg);
            selectedSeg = null;
            loadObjectEditor();
        }
コード例 #4
0
ファイル: LevelEditorMode.cs プロジェクト: wwarnick/Sever
 /// <summary>Creates a new instance of LevelEditorMode.</summary>
 /// <param name="graphics">The graphics device manager to use.</param>
 /// <param name="content">The content manager to use.</param>
 /// <param name="batch">The sprite batch to use.</param>
 /// <param name="bEffect">The basic effect to use.</param>
 public LevelEditorMode(GraphicsDeviceManager graphics, ContentManager content, SpriteBatch batch, BasicEffect bEffect)
     : base(graphics, content, batch, bEffect)
 {
     world = new World(true);
     world.Grid = new GridManager(1, 1, world);
     hoveredNode = null;
     selectedNode = null;
     hoveredSeg = null;
     selectedSeg = null;
     hoveredSegEnd = null;
     hoveredSegEndOwner = null;
     selectedSegEnd = null;
     hoveredGeo = null;
     hoveredGeoVertex = -1;
     hoveredGeoIsLine = false;
     selectedGeo = null;
     selectedGeoVertex = -1;
     selectedGeoIsLine = false;
     desktop = new Desktop();
     lastClickedPoint = new VectorF();
     dragOffset = new VectorF();
     isDragging = false;
 }
コード例 #5
0
ファイル: World.cs プロジェクト: wwarnick/Sever
        /// <summary>Adds the specified segment to the world.</summary>
        /// <param name="segment">The segment to add.</param>
        public void addSegment(Segment segment)
        {
            if (segment.ID == null)
                segment.ID = getNextSegID();
            SegByID.Add(segment.ID, segment);
            Segments.Add(segment);
            Grid.Line(segment.Nodes[0].Pos, segment.Nodes[1].Pos, segment, gridAddSegment);

            if (segment.Owner.Type == Player.PlayerType.Human)
                segment.Visible = segment.Owner.Fog.isVisible(segment);

            if (!EditorMode)
                addEvent(segment.ID, WorldEvent.EventType.AddSeg);
        }
コード例 #6
0
ファイル: FogOfWar.cs プロジェクト: wwarnick/Sever
        /// <summary>Determines whether or not the provided segment is visible.</summary>
        /// <param name="seg">The segment to test.</param>
        /// <returns>Whether or not the provided segment is visible.</returns>
        public bool isVisible(Segment seg)
        {
            if (seg.Owner == Owner)
                return true;

            return isVisible((SegmentSkel)seg);
        }
コード例 #7
0
ファイル: Segment.cs プロジェクト: wwarnick/Sever
        /// <summary>Splits this segment into two pieces, and retracts them away from the split point.</summary>
        /// <param name="splitPoint">The distance from Node[0] to perform the split.</param>
        public void split(FInt splitPoint)
        {
            // prepare to update densities
            int[] nodePpl = new int[2];
            FInt[] nodeCap = new FInt[2];
            for (int i = 0; i < 2; i++)
            {
                if (State[i] == SegState.Complete)
                {
                    int oppLane = 1 - i;
                    int index = 0;
                    while (Nodes[oppLane].Segments[index] != this) { index++; }

                    // prepare densities
                    nodePpl[oppLane] = Nodes[oppLane].SegNumPeople[index];
                    nodeCap[oppLane] = Nodes[oppLane].SegCapacity[index];
                }
            }

            // prepare to update parentage
            List<Node>[] nodePar = new List<Node>[2];
            if (State[0] == SegState.Complete && State[1] == SegState.Complete)
            {
                nodePar[0] = new List<Node>(Nodes[1].Parents.Count + ((Nodes[1].IsParent) ? 1 : 0));
                nodePar[1] = new List<Node>(Nodes[0].Parents.Count + ((Nodes[0].IsParent) ? 1 : 0));

                if (Nodes[1].IsParent)
                    nodePar[0].Add(Nodes[1]);

                int segIndex = 0;
                while (Nodes[1].Segments[segIndex] != this) { segIndex++; }

                for (int i = 0; i < Nodes[1].Parents.Count; i++)
                {
                    if (Nodes[1].ParentFromSeg[i] == segIndex)
                        nodePar[1].Add(Nodes[1].Parents[i]);
                    else
                        nodePar[0].Add(Nodes[1].Parents[i]);
                }
            }

            // create new segment
            Segment newSeg = new Segment(InWorld);
            newSeg.Angle = Angle;
            newSeg.Capacity = Capacity;
            newSeg.Destroyed = Destroyed;
            newSeg.Direction = Direction;
            newSeg.DirectionPerp = DirectionPerp;
            newSeg.Length = Length;
            newSeg.Nodes[0] = Nodes[0];
            newSeg.Nodes[1] = Nodes[1];
            newSeg.Owner = Owner;
            newSeg.State[0] = State[0];
            newSeg.State[1] = SegState.Retracting;
            newSeg.EndLength[0] = EndLength[0];
            newSeg.EndLength[1] = Length - splitPoint;
            newSeg.EndLoc[1] = EndLoc[1];
            newSeg.refreshEndLoc(0);

            // divvy up the people

            // first lane
            for (LListNode<FInt> p = People[0].Last; p != null && p.Value >= splitPoint; p = People[0].Last)
            {
                People[0].RemoveLast();
                newSeg.People[0].AddFirst(p);
            }

            // second lane
            for (LListNode<FInt> p = People[1].First; p != null && p.Value <= newSeg.EndLength[1]; p = People[1].First)
            {
                People[1].RemoveFirst();
                newSeg.People[1].AddLast(p);
            }

            NumPeople = People[0].Count + People[1].Count;
            newSeg.NumPeople = newSeg.People[0].Count + newSeg.People[1].Count;

            nodePpl[0] -= NumPeople;
            nodePpl[1] -= newSeg.NumPeople;

            // update densities and parentage
            for (int i = 0; i < 2; i++)
            {
                if (State[i] == SegState.Complete)
                {
                    int oppLane = 1 - i;
                    Nodes[oppLane].alterDensity(-nodePpl[oppLane], -nodeCap[oppLane], this);

                    // only update parentage if both sides are complete
                    if (State[1 - i] == SegState.Complete)
                        Nodes[i].removeParents(this, nodePar[i]);
                }
            }

            // update the node connections
            if (State[0] == SegState.Complete)
            {
                for (int i = 0; i < Nodes[1].Segments.Length; i++)
                {
                    if (Nodes[1].Segments[i] == this)
                    {
                        Nodes[1].Segments[i] = newSeg;
                        InWorld.addEvent(Nodes[1].ID, WorldEvent.EventType.NodeChangeState);
                        break;
                    }
                }
            }

            // update this segment's values
            State[0] = SegState.Retracting;
            EndLength[0] = splitPoint;
            refreshEndLoc(1);

            // add segments to the player and world
            InWorld.addSegment(newSeg);

            // add event
            InWorld.addEvent(ID, WorldEvent.EventType.SegChangeState);
        }
コード例 #8
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>2ndst step recurring method that runs through all nodes and updates densities.  Must be called right after the 1st step on the same beginning node.</summary>
        /// <param name="fromSeg">The segment that called this method.</param>
        /// <param name="people">The total number of people in the branch that called this method.</param>
        /// <param name="capacity">The total capacity of the branch that called this method.</param>
        private void updateDensity2ndStep(Segment fromSeg, int people, FInt capacity)
        {
            // the second step updates densities of all branches lead away from the first node

            int totPeople = PeopleToSort;
            FInt totCapacity = FInt.F0;

            // get sum of all branches
            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] != null)
                {
                    // update from segment vars
                    if (Segments[i] == fromSeg)
                    {
                        SegNumPeople[i] = people;
                        SegCapacity[i] = capacity;
                    }

                    totPeople += SegNumPeople[i];
                    totCapacity += SegCapacity[i];
                }
            }

            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] != null && Segments[i] != fromSeg)
                {
                    int lane = Segments[i].getNodeIndex(this);

                    // if connected to the next node...
                    if (Segments[i].State[i] == Segment.SegState.Complete)
                        Segments[i].Nodes[1 - lane].updateDensity2ndStep(Segments[i], totPeople - SegNumPeople[i], totCapacity - SegCapacity[i] + Segments[i].Capacity);
                }
            }
        }
コード例 #9
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
 /// <summary>Adds a person to the node from the specified segment.</summary>
 /// <param name="fromSeg">The segment that the person came from.</param>
 public void addPerson(Segment fromSeg)
 {
     PeopleToSort++;
     SegNumPeople[getSegIndex(fromSeg)]--;
 }
コード例 #10
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Adds the specified parents to this node and all branches.</summary>
        /// <param name="fromSeg">The segment that called this method.</param>
        /// <param name="parents">The parents to add.</param>
        public void addParents(Segment fromSeg, IEnumerable<Node> parents)
        {
            Parents.AddRange(parents);

            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] != null)
                {
                    if (Segments[i] == fromSeg)
                    {
                        foreach (Node parent in parents)
                        {
                            ParentFromSeg.Add(i);
                        }
                    }
                    else
                    {
                        int lane = Segments[i].getNodeIndex(this);
                        Node oppNode = Segments[i].Nodes[1 - lane];

                        if (Segments[i].State[lane] == Segment.SegState.Complete)
                            oppNode.addParents(Segments[i], parents);
                    }
                }
            }
        }
コード例 #11
0
ファイル: PlayMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Updates all game variables in this mode.</summary>
        /// <param name="gameTime">The current game time.</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            FInt elapsed = (FInt)gameTime.ElapsedGameTime.TotalSeconds;
            hoveredNode = null;
            hoveredSeg = null;
            hoveredHotspot = null;
            Player hPlayer = null;
            Player cPlayer = null;

            foreach (Player p in map.Players)
            {
                if (p.Type == Player.PlayerType.Human)
                {
                    hPlayer = p;
                    break;
                }
            }

            foreach (Player p in map.Players)
            {
                if (p.Type == Player.PlayerType.Computer)
                {
                    cPlayer = p;
                    break;
                }
            }

            // prepare grid manager
            map.Grid.startNewUpdate(gameTime);

            // move camera
            if (Inp.Key.IsKeyDown(Keys.OemPlus))
                map.Cam.Zoom += map.Cam.Zoom * elapsed;

            if (Inp.Key.IsKeyDown(Keys.OemMinus))
                map.Cam.Zoom -= map.Cam.Zoom * elapsed;

            if (Inp.Key.IsKeyDown(Keys.A))
                map.Cam.CenterX -= (700 / map.Cam.Zoom) * elapsed;

            if (Inp.Key.IsKeyDown(Keys.D))
                map.Cam.CenterX += (700 / map.Cam.Zoom) * elapsed;

            if (Inp.Key.IsKeyDown(Keys.W))
                map.Cam.CenterY -= (700 / map.Cam.Zoom) * elapsed;

            if (Inp.Key.IsKeyDown(Keys.S))
                map.Cam.CenterY += (700 / map.Cam.Zoom) * elapsed;

            map.Cam.Zoom += (FInt)(Inp.Mse.ScrollWheelValue - Inp.OldMse.ScrollWheelValue) / (FInt)120 * (FInt).1d * map.Cam.Zoom;

            map.Cam.refreshCorners();

            // get cursor world coordinates
            VectorF cursorPos = map.Cam.screenToWorld(new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y));

            /*/ find path
            if (!tempBool)
            {
                Node fromNode = cPlayer.Nodes[cPlayer.Nodes.Count - 1];
                VectorF fromPos = fromNode.Pos;

                // find path
                VectorF nde = fromPos / cPlayer.Path.NodeSpacing;
                nde.X = (FInt)Math.Round((double)nde.X);
                nde.Y = (FInt)Math.Round((double)nde.Y);
                int srcNode = (int)nde.Y * cPlayer.Path.NumCols + (int)nde.X;

                nde = (hPlayer.Nodes[0].Pos + hPlayer.Nodes[1].Pos) / FInt.F2 / cPlayer.Path.NodeSpacing;
                nde.X = (FInt)Math.Round((double)nde.X);
                nde.Y = (FInt)Math.Round((double)nde.Y);
                int destNode = (int)nde.Y * cPlayer.Path.NumCols + (int)nde.X;

                shortest = cPlayer.Path.search(cPlayer.Path.Nodes[srcNode], cPlayer.Path.Nodes[destNode]);

                tempBool = true;
            }*/

            if (Inp.OldMse.Position != Inp.Mse.Position)
                desktop.mouseMove(Inp.Mse.Position);

            GUI.Desktop.Event evnt = Desktop.Event.MouseRightUp;
            bool evntHappened = true;
            if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released)
                evnt = Desktop.Event.MouseLeftUp;
            else if (Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed)
                evnt = Desktop.Event.MouseLeftDown;
            else if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released)
                evnt = Desktop.Event.MouseRightUp;
            else if (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed)
                evnt = Desktop.Event.MouseRightUp;
            else
                evntHappened = false;

            if (selectedNode != null)
                hoveredHotspot = map.HotspotAtPoint(cursorPos);

            if (selectedNode == null && evntHappened && desktop.PerformMouseEvent(evnt, Inp.Mse.Position, Inp))
            {
                hoveredNode = null;
            }
            else
            {
                // check for hovered node and segment
                hoveredNode = map.NodeAtPoint(cursorPos, true);
                hoveredSeg = (hoveredNode == null) ? map.segmentAtPoint(cursorPos, hPlayer) : null;

                // if node is selected, determine which node type may be built at the selected distance
                selNodeType = (selectedNode == null) ? null : map.getNodeType(selectedNode.Pos, cursorPos);

                // if the user just released the left mouse button
                if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released)
                {
                    if (selectedNode != null)
                    {
                        if (hoveredNode == null)
                        {
                            if (hoveredHotspot != null)
                                map.PlayerActions.Add(new PlayerAction(hPlayer, PlayerAction.ActionType.BuildSeg, selectedNode.ID, true, hoveredHotspot.ID));
                            else if (selNodeType != null)
                                map.PlayerActions.Add(new PlayerAction(hPlayer, PlayerAction.ActionType.BuildSeg, selectedNode.ID, false, cursorPos));
                        }
                        else if (hoveredNode != selectedNode)
                        {
                            map.PlayerActions.Add(new PlayerAction(hPlayer, PlayerAction.ActionType.ClaimNode, selectedNode.ID, hoveredNode.ID));
                        }

                        selectedNode = null;
                    }
                }
                // user just pressed the left mouse button
                else if ((Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed)
                    || (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed))
                {
                    if (hoveredNode != null && hoveredNode.Owner == hPlayer && (Inp.Mse.RightButton == ButtonState.Pressed || hoveredNode.NumSegments < hoveredNode.Segments.Length))
                        selectedNode = hoveredNode;
                }
                // if the left mouse button is still pressed
                else if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Pressed)
                {
                    if (selectedNode != null && cursorPos.Y >= FInt.F0 && cursorPos.X >= FInt.F0 && cursorPos.X < map.Width && cursorPos.Y < map.Height)
                    {
                        List<SegmentSkel> ignoreSeg = new List<SegmentSkel>(selectedNode.Segments.Length);
                        foreach (Segment seg in selectedNode.Segments)
                        {
                            if (seg != null)
                                ignoreSeg.Add(seg);
                        }

                        List<NodeSkel> ignoreNode = new List<NodeSkel>(1) { selectedNode };

                        SegmentSkel segColl;
                        NodeSkel nodeColl;
                        GeoSkel geoColl;

                        map.Collision.segCollisionIntPoint(selectedNode.Pos, cursorPos, ignoreSeg, ignoreNode, out segColl, out nodeColl, out geoColl, out intersectPoint);
                    }
                }
                // if the player just released the right mouse button
                else if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released)
                {
                    if (selectedNode != null && hoveredNode == selectedNode)
                    {
                        map.PlayerActions.Add(new PlayerAction(hPlayer, PlayerAction.ActionType.DestroyNode, selectedNode.ID));
                    }
                    else if (hoveredSeg != null)
                    {
                        map.PlayerActions.Add(new PlayerAction(hPlayer, PlayerAction.ActionType.SplitSeg, hoveredSeg.ID, cursorPos));
                        hoveredSeg = null;
                    }

                    selectedNode = null;
                }

                // if the player just pressed the spacebar
                else if (!Inp.OldKey.IsKeyDown(Keys.Space) && Inp.Key.IsKeyDown(Keys.Space))
                {
                    paused = !paused;
                }
            }

            // update world
            if (!paused && !cntMsgBox.Visible)
                map.update(gameTime);

            // execute action queue
            if (map.FrontEndActions.Count > 0 && !cntMsgBox.Visible)
            {
                FrontEndAction action = map.FrontEndActions.Dequeue();

                switch (action.Action)
                {
                    case FrontEndAction.ActionType.LoadMap:
                        loadWorld((string)action.Params[0]);
                        break;
                    case FrontEndAction.ActionType.Message:
                        showMsg((string)action.Params[0]);
                        break;
                }
            }
        }
コード例 #12
0
ファイル: PlayMode.cs プロジェクト: wwarnick/Sever
 /// <summary>Loads the specified world.</summary>
 /// <param name="path">The path of the world to load.</param>
 public void loadWorld(string path)
 {
     hoveredNode = null;
     selectedNode = null;
     hoveredSeg = null;
     map = WorldLoader.loadWorld(path.ToString(), Graphics);
 }
コード例 #13
0
ファイル: PlayMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Creates a new instance of PlayMode.</summary>
        /// <param name="graphics">The graphics device manager to use.</param>
        /// <param name="content">The content manager to use.</param>
        /// <param name="batch">The sprite batch to use.</param>
        /// <param name="bEffect">The basic effect to use.</param>
        public PlayMode(GraphicsDeviceManager graphics, ContentManager content, SpriteBatch batch, BasicEffect bEffect)
            : base(graphics, content, batch, bEffect)
        {
            hoveredNode = null;
            hoveredSeg = null;
            hoveredHotspot = null;
            selectedNode = null;
            desktop = new Desktop();

            lblCursorPos = new Label();
            lblCursorPos.Left = 0;
            lblCursorPos.Top = 0;
            lblCursorPos.Width = 0;
            lblCursorPos.Height = 0;
            lblCursorPos.ForeColor = Color.White;
            desktop.Controls.Add(lblCursorPos);

            /* TEMPORARY */
            loadWorld(@"..\..\..\testscripting.txt");//testLevel.txt");
            //map = WorldLoader.loadWorld(@"..\..\..\testLevel.txt", Graphics);
            /* TEMPORARY */
        }
コード例 #14
0
ファイル: WorldLoader.cs プロジェクト: wwarnick/Sever
        private static void readSegmentVars3(List<string[]> commands, World map, Segment segment, List<Segment> segNoID)
        {
            double tempDbl = 0d;
            int tempInt = 0;

            for (int j = 1; j < commands.Count; j++)
            {
                string value = translateValue(commands[j][2], "[Segment]", map, segment);
                bool valueValid = true;
                switch (commands[j][0])
                {
                    case "ID":
                    case "Node":
                        // do nothing
                        break;
                    case "EndLength":
                        valueValid = int.TryParse(commands[j][1], out tempInt);
                        valueValid &= double.TryParse(value, out tempDbl);
                        segment.EndLength[tempInt] = (FInt)tempDbl;
                        segment.refreshEndLoc(1 - tempInt);
                        break;
                    case "Owner":
                    case "State":
                    case "Person":
                        // do nothing
                        break;
                    default:
                        throw new Exception("Segment variable not recognized: " + commands[j][0]);
                }

                if (!valueValid)
                    throw new Exception("Value '" + commands[j][2] + "' not valid for variable '" + commands[j][0] + "'.");
            }

            if (segment.ID != null)
                map.addSegment(segment);
            else
                segNoID.Add(segment);
        }
コード例 #15
0
ファイル: WorldLoader.cs プロジェクト: wwarnick/Sever
        private static void readSegmentVars2(List<string[]> commands, World map, Segment segment, Dictionary<string, Node> nodes)
        {
            int tempInt = 0;
            double tempDbl = 0d;

            for (int j = 1; j < commands.Count; j++)
            {
                string value = translateValue(commands[j][2], "[Segment]", map, segment);
                bool valueValid = true;
                switch (commands[j][0])
                {
                    case "ID":
                        // do nothing
                        break;
                    case "Node":
                        valueValid = int.TryParse(commands[j][1], out tempInt);
                        segment.Nodes[tempInt] = nodes[value];
                        break;
                    case "End":
                        valueValid = int.TryParse(commands[j][1], out tempInt);
                        Node newNode = new Node(map);
                        string[] coords = value.Split(',');
                        if (valueValid && coords.Length == 2 && double.TryParse(coords[0], out tempDbl))
                        {
                            newNode.X = (FInt)tempDbl;

                            if (double.TryParse(coords[1], out tempDbl))
                                newNode.Y = (FInt)tempDbl;
                            else
                                valueValid = false;
                        }
                        else
                            valueValid = false;
                        if (valueValid)
                            segment.Nodes[tempInt] = newNode;
                        break;
                    case "EndLength":
                    case "Owner":
                    case "State":
                    case "Person":
                        // do nothing
                        break;
                    default:
                        throw new Exception("Segment variable not recognized: " + commands[j][0]);
                }

                if (!valueValid)
                    throw new Exception("Value '" + commands[j][2] + "' not valid for variable '" + commands[j][0] + "'.");
            }

            segment.refreshMath();
        }
コード例 #16
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
 /// <summary>Removes the specified segment from this node.</summary>
 /// <param name="segment">The segment to remove.</param>
 /// <param name="disassociate">Whether or not to disassociate densities and parentage as well.</param>
 /// <param name="addEvent">Whether or not to add an event.</param>
 public void removeSegment(Segment segment, bool disassociate, bool addEvent)
 {
     int segIndex = 0;
     while (Segments[segIndex] != segment) { segIndex++; }
     removeSegment(segIndex, disassociate, addEvent);
 }
コード例 #17
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>1st step recurring method that runs through all nodes and updates densities.  Must first be called on a node with only one segment attached.</summary>
        /// <param name="fromSeg">The segment that called this method.</param>
        /// <param name="setLastCheckToMax">Whether or not to set LastCheck to the maximum value.</param>
        private void updateDensity1stStep(Segment fromSeg, bool setLastCheckToMax)
        {
            // the first step sets densities of all branches leading back to the first node

            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] != null && Segments[i] != fromSeg)
                {
                    int lane = Segments[i].getNodeIndex(this);

                    // don't include density of retracting segment
                    SegNumPeople[i] = 0;
                    SegCapacity[i] = FInt.F0;
                    if (!Segments[i].IsRetracting())
                    {
                        SegNumPeople[i] = Segments[i].NumPeople;
                        SegCapacity[i] = Segments[i].Capacity;
                    }

                    // if connected to the next node...
                    if (Segments[i].State[lane] == Segment.SegState.Complete)
                    {
                        Node oppNode = Segments[i].Nodes[1 - lane];
                        oppNode.updateDensity1stStep(Segments[i], setLastCheckToMax);

                        SegNumPeople[i] += oppNode.PeopleToSort;

                        for (int j = 0; j < oppNode.Segments.Length; j++)
                        {
                            if (oppNode.Segments[j] != null && oppNode.Segments[j] != Segments[i])
                            {
                                SegNumPeople[i] += oppNode.SegNumPeople[j];
                                SegCapacity[i] += oppNode.SegCapacity[j];
                            }
                        }
                    }
                }
            }

            if (setLastCheckToMax)
                LastCheck = TimeSpan.MaxValue;
        }
コード例 #18
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Adds the provided segment to this node.</summary>
        /// <param name="segment">The segment to add.</param>
        /// <returns>The index of the added segment.</returns>
        /// <param name="addEvent">Whether or not to add an event.</param>
        public int addSegment(Segment segment, bool addEvent)
        {
            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] == null)
                {
                    Segments[i] = segment;
                    SegNumPeople[i] = 0;
                    SegCapacity[i] = FInt.F0;
                    NumSegments++;

                    if (addEvent)
                        InWorld.addEvent(ID, WorldEvent.EventType.NodeChangeState);
                    return i;
                }
            }

            throw new Exception("Cannot add segment because node is already filled to capacity.");
        }
コード例 #19
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Alters the densities in this node and all branches.</summary>
        /// <param name="people">The number of people to add.</param>
        /// <param name="capacity">The capacity to add.</param>
        /// <param name="fromSeg">The segment that called this method.  null is valid.</param>
        public void alterDensity(int people, FInt capacity, Segment fromSeg)
        {
            #if DEBUG
            bool found = fromSeg == null;
            #endif
            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] != null)
                {
                    if (Segments[i] == fromSeg)
                    {
                        SegNumPeople[i] += people;
                        SegCapacity[i] += capacity;
            #if DEBUG
                        found = true;
            #endif
                    }
                    else
                    {
                        int lane = Segments[i].getNodeIndex(this);

                        if (Segments[i].State[lane] == Segment.SegState.Complete)
                            Segments[i].Nodes[1 - lane].alterDensity(people, capacity, Segments[i]);
                    }
                }
            }
            #if DEBUG
            if (!found)
                throw new Exception("The specified segment is not connected to this node.");
            #endif
        }
コード例 #20
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Attempt to claim this node for the specified segment.</summary>
        /// <param name="segment">The segment attempting to claim the node.</param>
        /// <returns>Whether or not the claim was successful.</returns>
        public bool claim(Segment segment)
        {
            bool claimed = false;
            int relSegIndex = -1;
            int lane = segment.getNodeIndex(this);
            int oppLane = 1 - lane;
            Node oppNode = segment.Nodes[oppLane];

            // Determine whether or not the claim is successful
            if (Destroyed || Owner != segment.Owner)
            {
                // can't claim destroyed nodes or nodes owned by someone else
            }
            else if (!Active) // if the node is inactive...
            {
                if (InWorld.Collision.nodeCollision(Pos, Radius, new List<SegmentSkel>(1) { segment }, new List<NodeSkel>(1) { this })
                    || InWorld.Collision.nodeCollNodeSpacing(Pos, Radius, Spacing, Owner, new List<NodeSkel>(1) { this }, false))
                    destroy();
                else
                    claimed = true;
            }
            else if ((relSegIndex = relatedSeg(oppNode)) != -1) // if the node is related
            {
                claimed = true;

                // make sure the connection is more than one segment away
                foreach (Segment seg in Segments)
                {
                    if (seg != null && seg.getOppNode(this) == oppNode)
                    {
                        claimed = false;
                        break;
                    }
                }

                if (claimed)
                    severSegment(relSegIndex);
            }
            else if (NumSegments < Segments.Length) // if same owner, but unrelated
            {
                claimed = true;
            }

            if (!claimed)
            {
                segment.State[oppLane] = Segment.SegState.Retracting;
            }
            else
            {
                // complete the segment
                segment.State[oppLane] = Segment.SegState.Complete;

                // prepare to invalidate visibility for old owner
                // and apply new visibility to new owner
                Player invalOwner = (Active && Owner != segment.Owner && Owner.Type == Player.PlayerType.Human) ? Owner : null;
                bool applyVisibility = (!Active || Owner != segment.Owner) && segment.Owner.Type == Player.PlayerType.Human;

                Active = true;
                addSegment(segment, true);
                Owner = segment.Owner;

                // exchange parentage and density
                if (segment.State[lane] == Segment.SegState.Complete)
                {
                    // exchange density
                    int peopleToSend = 0;
                    FInt capacityToSend = FInt.F0;
                    for (int i = 0; i < Segments.Length; i++)
                    {
                        if (Segments[i] != null)
                        {
                            peopleToSend += SegNumPeople[i];
                            capacityToSend += SegCapacity[i];
                        }
                    }

                    int peopleToReceive = oppNode.PeopleToSort;
                    FInt capacityToReceive = FInt.F0;
                    for (int i = 0; i < oppNode.Segments.Length; i++)
                    {
                        if (oppNode.Segments[i] != null)
                        {
                            peopleToReceive += oppNode.SegNumPeople[i];
                            capacityToReceive += oppNode.SegCapacity[i];
                        }
                    }

                    alterDensity(peopleToReceive, capacityToReceive, segment);
                    oppNode.alterDensity(peopleToSend, capacityToSend, segment);

                    // exchange parentage
                    Node[] parentsToSend = null;

                    if (Parents.Count > 0 || IsParent)
                    {
                        parentsToSend = new Node[Parents.Count + (IsParent ? 1 : 0)];
                        Parents.CopyTo(parentsToSend);
                        if (IsParent)
                            parentsToSend[parentsToSend.Length - 1] = this;
                    }

                    if (oppNode.Parents.Count > 0 || oppNode.IsParent)
                    {
                        if (!oppNode.IsParent)
                        {
                            addParents(segment, oppNode.Parents);
                        }
                        else
                        {
                            List<Node> parentsToReceive = new List<Node>(oppNode.Parents.Count + 1);
                            parentsToReceive.AddRange(oppNode.Parents);
                            parentsToReceive.Add(oppNode);
                            addParents(segment, parentsToReceive);
                        }
                    }

                    if (parentsToSend != null)
                        oppNode.addParents(segment, parentsToSend);
                }
                else // get segment's density
                {
                    int peopleToReceive = segment.NumPeople;
                    FInt capacityToReceive = (segment.State[lane] != Segment.SegState.Retracting) ? segment.Capacity : FInt.F0;

                    alterDensity(peopleToReceive, capacityToReceive, segment);
                }

                // update visibility
                if (invalOwner != null)
                {
                    invalOwner.Fog.invalidate(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + SightDistance, Y + SightDistance));
                    InWorld.refreshVisibility(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + Radius, Y + Radius));
                }

                if (applyVisibility)
                {
                    Owner.Fog.applyVisibility(this);
                    InWorld.refreshVisibility(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + SightDistance, Y + SightDistance));
                }

                Visible = Owner.Type == Player.PlayerType.Human || (Active && InWorld.HumanPlayer.Fog.isVisible(this));

                // add event
                InWorld.addEvent(ID, WorldEvent.EventType.NodeChangeState);

                // run script if on hotspot
                if (OwnsHotspot != null && !string.IsNullOrWhiteSpace(OwnsHotspot.Script))
                    InWorld.Script.runScript(OwnsHotspot.Script);
            }

            // add event
            if (!Destroyed)
                InWorld.addEvent(segment.ID, WorldEvent.EventType.SegChangeState);

            return claimed;
        }
コード例 #21
0
ファイル: GridManager.cs プロジェクト: wwarnick/Sever
        /// <summary>Gets a skeleton version of this grid manager.</summary>
        /// <param name="forPlayer">The player that will use it.  His nodes and segments are full instead of skeletons.</param>
        /// <param name="playerNodes">A list of all of the player's nodes.</param>
        /// <param name="playerSegs">A list of all of the player's segments.</param>
        /// <param name="allSegs">A list of all segments.</param>
        /// <param name="allNodes">A list of all nodes.</param>
        /// <returns>A skeleton version of this grid manager.</returns>
        public GridManager getSkeleton(Player forPlayer, out Node[] playerNodes, out Segment[] playerSegs, out NodeSkel[] allNodes, out SegmentSkel[] allSegs)
        {
            playerNodes = new Node[forPlayer.Nodes.Count];
            playerSegs = new Segment[forPlayer.Segments.Count];
            allNodes = new NodeSkel[InWorld.Nodes.Count];
            allSegs = new SegmentSkel[InWorld.Segments.Count];
            int nextPlyrNode = 0;
            int nextPlyrSeg = 0;
            int nextAllNode = 0;
            int nextAllSeg = 0;

            GridManager skeleton = new GridManager(NumCols, NumRows, InWorld, false);
            Dictionary<string, NodeSkel> nodes = new Dictionary<string, NodeSkel>(InWorld.Nodes.Count);
            Dictionary<string, SegmentSkel> segments = new Dictionary<string, SegmentSkel>(InWorld.Segments.Count);
            Dictionary<string, GeoSkel> geos = new Dictionary<string, GeoSkel>(InWorld.Geos.Count);

            // add nodes, segments, and geos to dictionary

            foreach (Node node in InWorld.Nodes)
            {
                if (node.Owner == forPlayer)
                {
                    Node clone = new Node(node);
                    nodes.Add(clone.ID, clone);
                    playerNodes[nextPlyrNode] = clone;
                    nextPlyrNode++;
                    allNodes[nextAllNode] = clone;
                }
                else if (!node.Destroyed)
                {
                    NodeSkel skel = node.getSkeleton();
                    nodes.Add(node.ID, skel);
                    allNodes[nextAllNode] = skel;
                }

                nextAllNode++;
            }

            foreach (Segment seg in InWorld.Segments)
            {
                if (seg.Owner == forPlayer)
                {
                    Segment clone = new Segment(seg);
                    segments.Add(clone.ID, clone);
                    playerSegs[nextPlyrSeg] = clone;
                    nextPlyrSeg++;
                    allSegs[nextAllSeg] = clone;
                    nextAllSeg++;
                }
                else if (!seg.Destroyed)
                {
                    SegmentSkel skel = seg.getSkeleton();
                    segments.Add(seg.ID, skel);
                    allSegs[nextAllSeg] = skel;
                    nextAllSeg++;
                }
            }

            foreach (Geo geo in InWorld.Geos)
            {
                geos.Add(geo.ID, geo.getSkeleton());
            }

            // connect cloned nodes and segments to each other

            foreach (Node node in playerNodes)
            {
                for (int i = 0; i < node.Segments.Length; i++)
                {
                    Segment seg = node.Segments[i];
                    if (seg != null)
                        node.Segments[i] = (Segment)segments[seg.ID];
                }

                for (int i = 0; i < node.Parents.Count; i++)
                {
                    Node n = node.Parents[i];
                    node.Parents[i] = (Node)nodes[n.ID];
                }
            }

            foreach (Segment seg in playerSegs)
            {
                for (int i = 0; i < seg.Nodes.Length; i++)
                {
                    Node node = seg.Nodes[i];

                    if (!node.Destroyed)
                        seg.Nodes[i] = (Node)nodes[node.ID];
                    else
                        seg.Nodes[i] = new Node(node);
                }
            }

            // build grid

            skeleton.SqrSize = this.SqrSize;

            for (int row = 0; row < NumRows; row++)
            {
                for (int col = 0; col < NumRows; col++)
                {
                    GridSqr sqr = Squares[row, col];
                    skeleton.Squares[row, col] = new GridSqr(new List<NodeSkel>(sqr.Nodes.Count), new List<SegmentSkel>(sqr.Segments.Count), new List<GeoSkel>(sqr.Geos.Count), new List<Hotspot>(sqr.Hotspots.Count), false);

                    foreach (NodeSkel node in sqr.Nodes)
                    {
                        if (((Node)node).Active && !((Node)node).Destroyed)
                            skeleton.Squares[row, col].Nodes.Add(nodes[node.ID]);
                    }

                    foreach (SegmentSkel seg in sqr.Segments)
                    {
                        if (!((Segment)seg).Destroyed)
                            skeleton.Squares[row, col].Segments.Add(segments[seg.ID]);
                    }

                    foreach (GeoSkel geo in sqr.Geos)
                    {
                        skeleton.Squares[row, col].Geos.Add(geos[geo.ID]);
                    }
                }
            }

            return skeleton;
        }
コード例 #22
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Creates a segment to connect to the specified node.</summary>
        /// <param name="node">The node to connect to.</param>
        public void createSegment(Node node)
        {
            Segment segment = new Segment(InWorld);

            segment.Owner = Owner;
            segment.Nodes[0] = this;
            segment.Nodes[1] = node;
            segment.refreshMath();
            segment.EndLength[1] = segment.Length;
            segment.refreshEndLoc(0);
            segment.State[0] = Segment.SegState.Building;
            segment.State[1] = Segment.SegState.Complete;

            InWorld.addSegment(segment);
            addSegment(segment, true);
            alterDensity(0, segment.Capacity, segment);
        }
コード例 #23
0
ファイル: World.cs プロジェクト: wwarnick/Sever
 /// <summary>Removes the specified segment from the world.</summary>
 /// <param name="segment">The segment to remove.</param>
 public void removeSegment(Segment segment)
 {
     removeSegment(Segments.IndexOf(segment));
 }
コード例 #24
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Gets the index of the specified segment within this node.</summary>
        /// <param name="segment">The segment to search for.</param>
        /// <returns>The index of the specified segment within this node.</returns>
        public int getSegIndex(Segment segment)
        {
            for (int i = 0; i < Segments.Length; i++)
            {
                if (Segments[i] == segment)
                    return i;
            }

            return -1;
        }
コード例 #25
0
ファイル: LevelEditorMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Called when btnEditorNodeApply is clicked.</summary>
        private void btnEditorNodeApply_MouseLeftUp(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtEditorNodeID.Text))
            {
                showMsg("The \"ID\" value cannot be blank.");
                return;
            }

            int numSegs = int.Parse(txtEditorNodeNumSegs.Text);
            if (numSegs < selectedNode.NumSegments)
            {
                showMsg("The \"NumSeg\" value must be greater than or equal to the number of segments already attached to the selected node.");
                return;
            }
            if (!string.IsNullOrWhiteSpace(txtEditorNodeOwnsHotspot.Text) && !world.HotspotByID.ContainsKey(txtEditorNodeOwnsHotspot.Text))
            {
                showMsg("The \"OwnsHotspot\" value must either be empty or be equal to an existing hotspot's ID.");
                return;
            }

            // make sure the node ID is not a duplicate
            foreach (Node n in world.Nodes)
            {
                if (n.ID == txtEditorNodeID.Text && n != selectedNode)
                {
                    showMsg("A node with that ID already exists.");
                    return;
                }
            }

            selectedNode.Owner = (cmbEditorNodeOwner.SelectedIndex == 0)
                ? null
                : world.Players[cmbEditorNodeOwner.SelectedIndex - 1];

            if (selectedNode.NType != world.NodeTypes[cmbEditorNodeType.SelectedIndex])
                selectedNode.setNodeType(world.NodeTypes[cmbEditorNodeType.SelectedIndex]);

            selectedNode.IsParent = btnEditorNodeIsParent.Pressed;
            selectedNode.Radius = (FInt)double.Parse(txtEditorNodeRadius.Text);
            selectedNode.Spacing = (FInt)double.Parse(txtEditorNodeSpacing.Text);
            selectedNode.GenSpacing = (FInt)double.Parse(txtEditorNodeGenSpacing.Text);
            selectedNode.GenCountDown = (FInt)double.Parse(txtEditorNodeGenCountDown.Text);
            selectedNode.SightDistance = (FInt)double.Parse(txtEditorNodeSightDist.Text);
            selectedNode.Active = btnEditorNodeActive.Pressed;

            if (!string.IsNullOrWhiteSpace(txtEditorNodeOwnsHotspot.Text))
                selectedNode.OwnsHotspot = world.HotspotByID[txtEditorNodeOwnsHotspot.Text];

            if (numSegs != selectedNode.Segments.Length)
            {
                Segment[] segs = new Segment[numSegs];
                int[] segNumPpl = new int[numSegs];
                FInt[] segCap = new FInt[numSegs];

                int index = 0;
                for (int i = 0; i < selectedNode.Segments.Length; i++)
                {
                    if (selectedNode.Segments[i] != null)
                    {
                        segs[index] = selectedNode.Segments[i];
                        segNumPpl[index] = selectedNode.SegNumPeople[i];
                        segCap[index] = selectedNode.SegCapacity[i];

                        index++;
                    }
                }
            }

            // move node
            if (selectedNode.X.ToString() != txtEditorNodeX.Text
                || selectedNode.Y.ToString() != txtEditorNodeY.Text)
            {
                VectorF moveTo = new VectorF((FInt)double.Parse(txtEditorNodeX.Text), (FInt)double.Parse(txtEditorNodeY.Text));
                moveNode(selectedNode, moveTo);
            }

            // apply node ID
            if (selectedNode.ID != txtEditorNodeID.Text)
            {
                selectedNode.ID = txtEditorNodeID.Text;
                world.refreshNextGenIDs();
            }
        }
コード例 #26
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
 /// <summary>Initializes the segment arrays with the specified number of elements.</summary>
 /// <param name="NumSegments">The number of segments that may be attached to this node.</param>
 public void initSegArrays(int NumSegments)
 {
     Segments = new Segment[NumSegments];
     SegNumPeople = new int[NumSegments];
     SegCapacity = new FInt[NumSegments];
 }
コード例 #27
0
ファイル: LevelEditorMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Loads the currently selected file in lsbLoadSaveFile into the editor.</summary>
        private void loadSelectedFile()
        {
            StringBuilder path = new StringBuilder();
            foreach (ButtonText b in btnSaveLoadPath)
            {
                path.Append(b.Text);
                path.Append('\\');
            }
            path.Append(lsbSaveLoadFiles.SelectedItem);

            hoveredNode = null;
            selectedNode = null;
            hoveredSeg = null;
            selectedSeg = null;
            hoveredSegEnd = null;
            hoveredSegEndOwner = null;
            selectedSegEnd = null;
            hoveredGeo = null;
            selectedGeo = null;
            world = WorldLoader.loadWorld(path.ToString(), Graphics);

            refreshSideBar();
        }
コード例 #28
0
ファイル: Node.cs プロジェクト: wwarnick/Sever
        /// <summary>Removes the specified parents from this node and all branches.</summary>
        /// <param name="fromSeg">The segment that called this method.</param>
        /// <param name="parents">The parents to add.</param>
        public void removeParents(Segment fromSeg, IEnumerable<Node> parents)
        {
            #if	DEBUG
            // get fromSeg's index in Segments
            int fromSegIndex = 0;
            while (Segments[fromSegIndex] != fromSeg && fromSegIndex < Segments.Length) { fromSegIndex++; }
            if (fromSegIndex == Segments.Length)
                throw new Exception("fromSeg is not connected to this node.");
            #endif
            // remove the parents from this node
            bool spreadFurther = false; // if false, then 'parents' is empty and shouldn't be passed on to connected nodes
            foreach (Node parent in parents)
            {
                int index = Parents.IndexOf(parent);
            #if DEBUG
                if (index == -1)
                    throw new Exception("This node does not contain the specified parent.");
                else if (ParentFromSeg[index] != fromSegIndex)
                    throw new Exception("The parent to remove comes from a different segment than the one that called this method.");
            #endif
                Parents.RemoveAt(index);
                ParentFromSeg.RemoveAt(index);

                spreadFurther = true;
            }

            if (spreadFurther)
            {
                foreach (Segment seg in Segments)
                {
                    if (seg != null && seg != fromSeg)
                    {
                        int lane = seg.getNodeIndex(this);
                        Node oppNode = seg.Nodes[1 - lane];

                        if (seg.State[lane] == Segment.SegState.Complete)
                            oppNode.removeParents(seg, parents);
                    }
                }
            }
        }
コード例 #29
0
ファイル: LevelEditorMode.cs プロジェクト: wwarnick/Sever
        /// <summary>Updates all variables in this mode.</summary>
        /// <param name="gameTime">The current game time.</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            FInt elapsed = (FInt)gameTime.ElapsedGameTime.TotalSeconds;

            // update gui
            if (Inp.OldMse.Position != Inp.Mse.Position)
                desktop.mouseMove(Inp.Mse.Position);

            GUI.Desktop.Event evnt = Desktop.Event.MouseRightUp;
            bool guiOwnedInput = false;

            if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released)
                guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseLeftUp, Inp.Mse.Position, Inp);
            if (Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed)
                guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseLeftDown, Inp.Mse.Position, Inp);
            if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released)
                guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseRightUp, Inp.Mse.Position, Inp);
            if (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed)
                guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseRightUp, Inp.Mse.Position, Inp);

            Keys[] newKeys = Inp.Key.GetPressedKeys();

            if (newKeys.Length != 0)
                guiOwnedInput |= desktop.PerformKeyEvent(newKeys, Inp);

            if (guiOwnedInput)
            {
                hoveredNode = null;
                hoveredSeg = null;
                hoveredSegEnd = null;
                hoveredSegEndOwner = null;
                hoveredGeo = null;
                hoveredHotspot = null;
                isDragging = false;
            }
            else
            {
                // prepare grid manager
                world.Grid.startNewUpdate(gameTime);

                // move camera
                if (Inp.Key.IsKeyDown(Keys.OemPlus))
                    world.Cam.Zoom += world.Cam.Zoom * elapsed;

                if (Inp.Key.IsKeyDown(Keys.OemMinus))
                    world.Cam.Zoom -= world.Cam.Zoom * elapsed;

                if (Inp.Key.IsKeyDown(Keys.A))
                    world.Cam.CenterX -= (700 / world.Cam.Zoom) * elapsed;

                if (Inp.Key.IsKeyDown(Keys.D))
                    world.Cam.CenterX += (700 / world.Cam.Zoom) * elapsed;

                if (Inp.Key.IsKeyDown(Keys.W))
                    world.Cam.CenterY -= (700 / world.Cam.Zoom) * elapsed;

                if (Inp.Key.IsKeyDown(Keys.S))
                    world.Cam.CenterY += (700 / world.Cam.Zoom) * elapsed;

                world.Cam.Zoom += (FInt)(Inp.Mse.ScrollWheelValue - Inp.OldMse.ScrollWheelValue) / (FInt)120 * (FInt).1d * world.Cam.Zoom;

                world.Cam.refreshCorners();

                // get cursor world coordinates
                VectorF cursorPos = world.Cam.screenToWorld(new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y));

                // check for hovered node, segment, segment end, and hotspot
                hoveredNode = world.NodeAtPoint(cursorPos, false);
                hoveredSeg = (hoveredNode == null) ? world.segmentAtPoint(cursorPos, null) : null;
                hoveredSegEnd = world.SegmentEndAtPoint(cursorPos);

                if (hoveredSegEnd != null)
                {
                    foreach (Segment seg in world.Segments)
                    {
                        if (seg.Nodes[0] == hoveredSegEnd || seg.Nodes[1] == hoveredSegEnd)
                        {
                            hoveredSegEndOwner = seg.Owner;
                            break;
                        }
                    }
                }
                else
                {
                    hoveredSegEndOwner = null;
                }

                hoveredHotspot = world.HotspotAtPoint(cursorPos);

                // test geo vertices
                hoveredGeo = world.geoAtPoint(cursorPos, out hoveredGeoVertex, true);

                // test geo lines
                if (hoveredGeo == null)
                {
                    hoveredGeo = world.geoAtPoint(cursorPos, out hoveredGeoVertex, false);
                    hoveredGeoIsLine = true;
                }
                else
                {
                    hoveredGeoIsLine = false;
                }

                // if the user just released the left mouse button
                if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released)
                {
                    if (selectedSegEnd != null)
                    {
                        // do nothing
                    }
                    // add node
                    else if (btnAddNode.Pressed && cmbNodeTypes.SelectedIndex != -1 && selectedGeo == null && (selectedNode == null || isDragging) && selectedSeg == null && selectedHotspot == null)
                    {
                        bool useHoveredEnd = (hoveredSegEnd != null && (selectedNode == null || selectedNode.Owner == hoveredSegEndOwner));

                        // add node
                        Node node = new Node(world, world.NodeTypes[cmbEditorAddNodeType.SelectedIndex]);
                        node.Pos = useHoveredEnd ? hoveredSegEnd.Pos : cursorPos;
                        node.Active = true;

                        if (selectedNode != null && isDragging)
                        {
                            node.Owner = selectedNode.Owner;

                            if (selectedNode.NumSegments < selectedNode.Segments.Length) // add segment too
                            {
                                Segment seg = new Segment(world);
                                seg.Owner = selectedNode.Owner;
                                seg.Nodes[0] = selectedNode;
                                seg.Nodes[1] = node;
                                selectedNode.addSegment(seg, false);
                                node.addSegment(seg, false);
                                seg.refreshMath();
                                seg.EndLength[0] = seg.Length;
                                seg.EndLength[1] = seg.Length;
                                seg.refreshEndLocs();
                                world.addSegment(seg);
                            }
                        }
                        else if (selectedNode == null && hoveredSegEnd != null)
                        {
                            node.Owner = hoveredSegEndOwner;
                        }
                        else if (cmbEditorAddNodeOwner.SelectedIndex != 0)
                        {
                            node.Owner = world.Players[cmbEditorAddNodeOwner.SelectedIndex - 1];
                        }

                        if (useHoveredEnd)
                        {
                            // link segments to it
                            foreach (Segment seg in (hoveredSegEndOwner == null ? world.Segments : hoveredSegEndOwner.Segments))
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    if (seg.Nodes[i] == hoveredSegEnd)
                                    {
                                        seg.Nodes[i] = node;
                                        break;
                                    }
                                }
                            }
                        }

                        world.addNode(node);
                        selectedNode = node;
                        selectedSeg = null;
                        loadObjectEditor();
                    }
                    // add segment
                    else if (btnAddSeg.Pressed && isDragging && selectedSeg == null && selectedGeo == null && (selectedNode == null || selectedNode.NumSegments < selectedNode.Segments.Length) && selectedHotspot == null)
                    {
                        Segment seg = new Segment(world);
                        seg.Owner = (selectedNode != null) ? selectedNode.Owner
                            : (hoveredNode != null) ? hoveredNode.Owner
                            : (cmbEditorAddSegOwner.SelectedIndex > 0) ? world.Players[cmbEditorAddSegOwner.SelectedIndex - 1]
                            : null;

                        if (selectedNode != null)
                        {
                            seg.Nodes[0] = selectedNode;
                            seg.Owner = selectedNode.Owner;
                            selectedNode.addSegment(seg, false);
                        }
                        else
                        {
                            seg.State[1] = SegmentSkel.SegState.Retracting;
                            seg.Nodes[0] = new Node(world);
                            seg.Nodes[0].Pos = lastClickedPoint;
                            seg.Nodes[0].Active = false;
                            seg.Nodes[0].Destroyed = true;
                            seg.Nodes[0].initSegArrays(0);
                        }

                        if (hoveredNode != null && hoveredNode.NumSegments != hoveredNode.Segments.Length && (selectedNode == null || (hoveredNode != selectedNode && hoveredNode.Owner == selectedNode.Owner && hoveredNode.relatedSeg(selectedNode) == -1)))
                        {
                            seg.Nodes[1] = hoveredNode;
                            hoveredNode.addSegment(seg, false);
                        }
                        else
                        {
                            seg.State[0] = SegmentSkel.SegState.Building;
                            seg.Nodes[1] = new Node(world);
                            seg.Nodes[1].Pos = cursorPos;
                            seg.Nodes[1].Active = false;
                            seg.Nodes[1].Destroyed = true;
                            seg.Nodes[1].initSegArrays(0);
                        }

                        seg.refreshMath();
                        seg.EndLength[0] = seg.Length;
                        seg.EndLength[1] = seg.Length;
                        seg.refreshEndLocs();
                        world.addSegment(seg);

                        selectedNode = null;
                        selectedSeg = seg;
                        loadObjectEditor();
                    }
                    // add geo vertex
                    else if (btnAddGeo.Pressed && selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedHotspot == null)
                    {
                        // add vertex to existing geo
                        if (selectedGeo != null && !selectedGeoIsLine && isDragging && (selectedGeoVertex == 0 || selectedGeoVertex == selectedGeo.Vertices.Length - 1))
                        {
                            VectorF[] vertices;
                            if (selectedGeo.Vertices.Length == 1)
                            {
                                vertices = new VectorF[selectedGeo.Vertices.Length + 1];
                                vertices[0] = cursorPos;
                                vertices[1] = selectedGeo.Vertices[0];
                            }
                            else if (selectedGeoVertex == 0)
                            {
                                vertices = new VectorF[selectedGeo.Vertices.Length + 2];
                                selectedGeo.Vertices.CopyTo(vertices, 2);
                                vertices[0] = cursorPos;
                                vertices[1] = selectedGeo.Vertices[0];
                            }
                            else
                            {
                                vertices = new VectorF[selectedGeo.Vertices.Length + 2];
                                selectedGeo.Vertices.CopyTo(vertices, 0);
                                vertices[selectedGeo.Vertices.Length] = selectedGeo.Vertices[selectedGeo.Vertices.Length - 1];
                                vertices[selectedGeo.Vertices.Length + 1] = cursorPos;
                                selectedGeoVertex = vertices.Length - 1;
                            }

                            world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridRemoveGeo);
                            selectedGeo.Vertices = vertices;
                            selectedGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height));
                            world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridAddGeo);

                            selectedGeoIsLine = false;
                            loadObjectEditor();
                        }
                        // add vertex in the middle of a line
                        else if (hoveredGeo != null && hoveredGeoIsLine)
                        {
                            VectorF[] vertices = new VectorF[hoveredGeo.Vertices.Length + 2];
                            int v2 = (hoveredGeoVertex == hoveredGeo.Vertices.Length - 1) ? 0 : hoveredGeoVertex + 1;
                            float dist = (float)Calc.getAdj(VectorF.Distance(cursorPos, hoveredGeo.Vertices[hoveredGeoVertex]), Calc.LinePointDistance(cursorPos, hoveredGeo.Vertices[hoveredGeoVertex], hoveredGeo.Vertices[v2]));
                            Vector2 dir = Vector2.Normalize((Vector2)(hoveredGeo.Vertices[v2] - hoveredGeo.Vertices[hoveredGeoVertex]));
                            VectorF pos = (VectorF)((Vector2)hoveredGeo.Vertices[hoveredGeoVertex] + (dir * dist));

                            for (int i = 0; i <= hoveredGeoVertex; i++)
                            {
                                vertices[i] = hoveredGeo.Vertices[i];
                            }

                            if (hoveredGeoVertex == selectedGeo.Vertices.Length - 1)
                            {
                                vertices[hoveredGeoVertex + 1] = selectedGeo.Vertices[selectedGeo.Vertices.Length - 1];
                                vertices[hoveredGeoVertex + 2] = pos;
                            }
                            else
                            {
                                vertices[hoveredGeoVertex + 1] = pos;
                                vertices[hoveredGeoVertex + 2] = pos;

                                for (int i = hoveredGeoVertex + 1; i < hoveredGeo.Vertices.Length; i++)
                                {
                                    vertices[i + 2] = hoveredGeo.Vertices[i];
                                }
                            }

                            world.Grid.Rect(hoveredGeo.UpperLeft, hoveredGeo.LowerRight, hoveredGeo, world.gridRemoveGeo);
                            hoveredGeo.Vertices = vertices;
                            hoveredGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height));
                            world.Grid.Rect(hoveredGeo.UpperLeft, hoveredGeo.LowerRight, hoveredGeo, world.gridAddGeo);

                            hoveredGeoIsLine = false;
                            hoveredGeoVertex += 2;
                            selectedGeo = hoveredGeo;
                            selectedGeoIsLine = false;
                            selectedGeoVertex = hoveredGeoVertex;
                            loadObjectEditor();
                        }
                        // add new geo
                        else if (hoveredGeo == null)
                        {
                            Geo geo = new Geo(world);
                            geo.Vertices = new VectorF[] { cursorPos };
                            geo.CloseLoop = false;
                            geo.Display = false;
                            geo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height));
                            world.addGeo(geo);

                            selectedGeo = geo;
                            selectedGeoIsLine = false;
                            selectedGeoVertex = 0;
                            loadObjectEditor();
                        }
                    }
                    else if (btnAddHotspot.Pressed && selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedGeo == null)
                    {
                        // add hotspot
                        Hotspot hotspot = new Hotspot(world);
                        hotspot.Pos = cursorPos;

                        world.addHotspot(hotspot);
                        selectedHotspot = hotspot;
                        loadObjectEditor();
                    }

                    selectedSegEnd = null;
                    isDragging = false;
                }
                // if the player just released the right mouse button
                else if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released)
                {

                }
                // user just pressed the left mouse button
                else if (Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed)
                {
                    lastClickedPoint = world.Cam.screenToWorld(new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y));
                    isDragging = false;

                    // check for selected node
                    selectedNode = hoveredNode;

                    // check for selected segment end
                    selectedSegEnd = (selectedNode == null)
                        ? hoveredSegEnd
                        : null;

                    // check for selected segment
                    selectedSeg = (selectedNode == null && selectedSegEnd == null)
                        ? hoveredSeg
                        : null;

                    // check for selected hotspot
                    selectedHotspot = (selectedNode == null && selectedSegEnd == null && selectedSeg == null)
                        ? hoveredHotspot
                        : null;

                    // check for selected geo
                    if (selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedHotspot == null)
                    {
                        selectedGeo = hoveredGeo;
                        selectedGeoIsLine = hoveredGeoIsLine;
                        selectedGeoVertex = hoveredGeoVertex;
                    }
                    else
                    {
                        selectedGeo = null;
                    }

                    loadObjectEditor();
                }
                // user just pressed the right mouse button
                else if (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed)
                {

                }
                // if the left mouse button is still pressed
                else if (desktop.Focused == null && Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Pressed)
                {
                    if (!isDragging && Vector2.Distance(world.Cam.worldToScreen(lastClickedPoint), new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y)) >= distToDrag)
                    {
                        isDragging = true;

                        if (selectedNode != null)
                            dragOffset = selectedNode.Pos - lastClickedPoint;
                        else if (selectedSegEnd != null)
                            dragOffset = selectedSegEnd.Pos - lastClickedPoint;
                        else if (selectedSeg != null)
                            dragOffset = selectedSeg.Nodes[0].Pos - lastClickedPoint;
                        else if (selectedHotspot != null)
                            dragOffset = selectedHotspot.Pos - lastClickedPoint;
                        else if (selectedGeo != null)
                        {
                            if (selectedGeoVertex == -1)
                                dragOffset = selectedGeo.Center - lastClickedPoint;
                            else
                                dragOffset = selectedGeo.Vertices[selectedGeoVertex] - lastClickedPoint;
                        }
                    }
                }
                // if [Del] key is pressed
                else if (!Inp.OldKey.IsKeyDown(Keys.Delete) && Inp.Key.IsKeyDown(Keys.Delete))
                {
                    if (selectedNode != null)
                        removeSelNode();
                    else if (selectedSeg != null)
                        removeSelSeg();
                    else if (selectedHotspot != null)
                        removeSelHotspot();
                    else if (selectedGeo != null)
                        removeSelGeo();
                }

                // drag
                if (isDragging)
                {
                    // move node
                    if (selectedNode != null && !btnAddSeg.Pressed && (!btnAddNode.Pressed || cmbEditorAddNodeType.SelectedIndex < 0))
                    {
                        moveNode(selectedNode, cursorPos + dragOffset);
                    }
                    // move segment end
                    else if (selectedSegEnd != null)
                    {
                        moveNode(selectedSegEnd, cursorPos + dragOffset);
                    }
                    // move segment
                    else if (selectedSeg != null)
                    {
                        VectorF moveVect = cursorPos + dragOffset - selectedSeg.Nodes[0].Pos;
                        moveNode(selectedSeg.Nodes[0], selectedSeg.Nodes[0].Pos + moveVect);
                        moveNode(selectedSeg.Nodes[1], selectedSeg.Nodes[1].Pos + moveVect);
                    }
                    // move hotspot
                    else if (selectedHotspot != null)
                    {
                        moveHotspot(selectedHotspot, cursorPos + dragOffset);
                    }
                    // move geo/vertex
                    else if (selectedGeo != null && !btnAddGeo.Pressed)
                    {
                        world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridRemoveGeo);
                        if (selectedGeoIsLine)
                        {
                            if (selectedGeoVertex == selectedGeo.Vertices.Length - 1)
                            {
                                selectedGeo.Vertices[0] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex];
                            }
                            else
                            {
                                if (selectedGeoVertex != 0)
                                    selectedGeo.Vertices[selectedGeoVertex - 1] = cursorPos + dragOffset;

                                selectedGeo.Vertices[selectedGeoVertex + 1] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex];

                                if (selectedGeoVertex != selectedGeo.Vertices.Length - 2)
                                    selectedGeo.Vertices[selectedGeoVertex + 2] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex];
                            }
                            selectedGeo.Vertices[selectedGeoVertex] = cursorPos + dragOffset;
                        }
                        else if (selectedGeoVertex == -1)
                        {
                            VectorF toMove = cursorPos + dragOffset - selectedGeo.Center;
                            for (int i = 0; i < selectedGeo.Vertices.Length; i++)
                            {
                                selectedGeo.Vertices[i] += toMove;
                            }
                        }
                        else
                        {
                            if (selectedGeoVertex != 0 && selectedGeoVertex != selectedGeo.Vertices.Length - 1)
                                selectedGeo.Vertices[selectedGeoVertex - 1] = cursorPos + dragOffset;
                            selectedGeo.Vertices[selectedGeoVertex] = cursorPos + dragOffset;
                        }
                        selectedGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height));
                        world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridAddGeo);
                    }
                }
            }
        }
コード例 #30
0
ファイル: WorldLoader.cs プロジェクト: wwarnick/Sever
        private static string translateValue(string val, string context, World map, Node node, Segment segment)
        {
            string result = null;

            switch (context)
            {
                case "[World]":
                    switch (val)
                    {
                        case "WindowWidth":
                            result = Graphics.PreferredBackBufferWidth.ToString();
                            break;
                        case "WindowHeight":
                            result = Graphics.PreferredBackBufferHeight.ToString();
                            break;
                        default:
                            result = val;
                            break;
                    }
                    break;
                case "[Camera]":
                    switch (val)
                    {
                        case "CenterX":
                            result = ((double)(map.Width / FInt.F2)).ToString();
                            break;
                        case "CenterY":
                            result = ((double)(map.Height / FInt.F2)).ToString();
                            break;
                        case "WindowWidth":
                            result = Graphics.PreferredBackBufferWidth.ToString();
                            break;
                        case "WindowHeight":
                            result = Graphics.PreferredBackBufferHeight.ToString();
                            break;
                        default:
                            result = val;
                            break;
                    }
                    break;
                case "[Grid]":
                case "[FogOfWar]":
                case "[Geo]":
                case "[Player]":
                case "[NodeType]":
                case "[PathFinder]":
                case "[Hotspot]":
                    result = val;
                    break;
                case "[Node]":
                    switch (val)
                    {
                        case "GenSpacing":
                            result = node.GenSpacing.DblValue.ToString();
                            break;
                        case "GenCountDown":
                            result = node.GenCountDown.DblValue.ToString();
                            break;
                        default:
                            result = val;
                            break;
                    }
                    break;
                case "[Segment]":
                    switch (val)
                    {
                        case "Length":
                            result = segment.Length.DblValue.ToString();
                            break;
                        default:
                            result = val;
                            break;
                    }
                    break;
                default:
                    throw new Exception("Unrecognized context: " + context);
            }

            return result;
        }