Example #1
0
        /// <see cref="ITerrainObjectType.CheckConstraints"/>
        public RCSet <RCIntVector> CheckConstraints(IMapAccess map, RCIntVector position)
        {
            if (map == null)
            {
                throw new ArgumentNullException("map");
            }
            if (position == RCIntVector.Undefined)
            {
                throw new ArgumentNullException("position");
            }

            /// Check against the constraints defined by this terrain object type.
            RCSet <RCIntVector> retList = new RCSet <RCIntVector>();

            foreach (ITerrainObjectConstraint contraint in this.constraints)
            {
                retList.UnionWith(contraint.Check(map, position));
            }

            for (int quadX = 0; quadX < this.quadraticSize.X; quadX++)
            {
                for (int quadY = 0; quadY < this.quadraticSize.Y; quadY++)
                {
                    RCIntVector relQuadCoords = new RCIntVector(quadX, quadY);
                    RCIntVector absQuadCoords = position + relQuadCoords;
                    if (absQuadCoords.X < 0 || absQuadCoords.X >= map.Size.X ||
                        absQuadCoords.Y < 0 || absQuadCoords.Y >= map.Size.Y)
                    {
                        /// Intersection with the boundaries of the map.
                        retList.Add(relQuadCoords);
                    }
                }
            }

            return(retList);
        }
Example #2
0
        /// <summary>
        /// Adds the given map object and all of its cutting quadratic tiles into the update lists.
        /// </summary>
        /// <param name="mapObj">The map object to add.</param>
        /// <param name="mapObjectUpdateList">The map object update list.</param>
        /// <param name="quadTileUpdateList">The quadratic update list.</param>
        private void AddMapObjectToUpdate(MapObject mapObj, RCSet <MapObject> mapObjectUpdateList, RCSet <IQuadTile> quadTileUpdateList)
        {
            if (mapObj != null && mapObjectUpdateList.Add(mapObj))
            {
                for (int col = mapObj.QuadraticPosition.Left; col < mapObj.QuadraticPosition.Right; col++)
                {
                    for (int row = mapObj.QuadraticPosition.Top; row < mapObj.QuadraticPosition.Bottom; row++)
                    {
                        IQuadTile quadTileToUpdate = this.ActiveScenario.Map.GetQuadTile(new RCIntVector(col, row));
                        if (quadTileToUpdate != null &&
                            (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                             this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                        {
                            quadTileUpdateList.Add(quadTileToUpdate);
                        }
                    }
                }

                if (mapObj.QuadraticShadowPosition != RCIntRectangle.Undefined)
                {
                    for (int col = mapObj.QuadraticShadowPosition.Left; col < mapObj.QuadraticShadowPosition.Right; col++)
                    {
                        for (int row = mapObj.QuadraticShadowPosition.Top; row < mapObj.QuadraticShadowPosition.Bottom; row++)
                        {
                            IQuadTile quadTileToUpdate = this.ActiveScenario.Map.GetQuadTile(new RCIntVector(col, row));
                            if (quadTileToUpdate != null &&
                                (this.fowCacheMatrix.GetFullFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None ||
                                 this.fowCacheMatrix.GetPartialFowFlagsAtQuadTile(quadTileToUpdate.MapCoords) != FOWTileFlagsEnum.None))
                            {
                                quadTileUpdateList.Add(quadTileToUpdate);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Calculates the velocity graph.
        /// </summary>
        private static Dictionary <RCNumVector, RCSet <RCNumVector> > CalculateVelocityGraph(List <RCNumVector> basisVectors, RCNumber maxSpeed, int accelerationDuration)
        {
            if (basisVectors == null)
            {
                throw new ArgumentNullException("basisVectors");
            }
            if (basisVectors.Count == 0)
            {
                throw new ArgumentException("Empty basis vector list!", "basisVectors");
            }
            if (maxSpeed < 0)
            {
                throw new ArgumentOutOfRangeException("maxSpeed", "Maximum speed cannot be negative!");
            }
            if (accelerationDuration < 1)
            {
                throw new ArgumentOutOfRangeException("accelerationDuration", "Acceleration duration must be at least 1!");
            }

            if (maxSpeed == 0)
            {
                /// Trivial case.
                return(new Dictionary <RCNumVector, RCSet <RCNumVector> > {
                    { new RCNumVector(0, 0), new RCSet <RCNumVector>() }
                });
            }

            /// First we calculate every possible velocity vectors and put them into a 2D array where the first coordinate
            /// is the index of the corresponding speed and the second coordinate is the index of the corresponding
            /// basis vector. In parallel we put the calculated vectors into the velocity graph with empty reachability
            /// lists. Those lists will be filled in a second step.
            Dictionary <RCNumVector, RCSet <RCNumVector> > velocityGraph = new Dictionary <RCNumVector, RCSet <RCNumVector> >();

            RCNumVector[,] velocityVectors = new RCNumVector[accelerationDuration + 1, basisVectors.Count];
            velocityVectors[0, 0]          = new RCNumVector(0, 0);
            velocityGraph.Add(new RCNumVector(0, 0), new RCSet <RCNumVector>());
            RCNumber speedIncrement = maxSpeed / accelerationDuration;

            for (int spdIdx = 1; spdIdx <= accelerationDuration; spdIdx++)
            {
                RCNumber speed = speedIncrement * spdIdx;
                for (int basisVectIdx = 0; basisVectIdx < basisVectors.Count; basisVectIdx++)
                {
                    RCNumVector velocityVector = basisVectors[basisVectIdx] * speed;
                    velocityVectors[spdIdx, basisVectIdx] = velocityVector;
                    velocityGraph.Add(velocityVector, new RCSet <RCNumVector>());
                }
            }

            /// Collect the velocities reachable from the (0, 0) vector.
            velocityGraph[velocityVectors[0, 0]].Add(velocityVectors[0, 0]);
            for (int basisVectIdx = 0; basisVectIdx < basisVectors.Count; basisVectIdx++)
            {
                velocityGraph[velocityVectors[0, 0]].Add(velocityVectors[1, basisVectIdx]);
            }

            /// Collect the velocities reachable from the longest velocities.
            for (int basisVectIdx = 0; basisVectIdx < basisVectors.Count; basisVectIdx++)
            {
                RCSet <RCNumVector> reachableVelocityList = velocityGraph[velocityVectors[accelerationDuration, basisVectIdx]];
                reachableVelocityList.Add(velocityVectors[accelerationDuration, basisVectIdx]);
                reachableVelocityList.Add(velocityVectors[accelerationDuration, (basisVectIdx + 1) % basisVectors.Count]);
                reachableVelocityList.Add(velocityVectors[accelerationDuration, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);

                if (accelerationDuration == 1)
                {
                    reachableVelocityList.Add(velocityVectors[0, 0]);
                }
                else
                {
                    reachableVelocityList.Add(velocityVectors[accelerationDuration - 1, basisVectIdx]);
                    reachableVelocityList.Add(velocityVectors[accelerationDuration - 1, (basisVectIdx + 1) % basisVectors.Count]);
                    reachableVelocityList.Add(velocityVectors[accelerationDuration - 1, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                }
            }

            if (accelerationDuration > 1)
            {
                /// Collect the velocities reachable from the shortest velocities.
                for (int basisVectIdx = 0; basisVectIdx < basisVectors.Count; basisVectIdx++)
                {
                    RCSet <RCNumVector> reachableVelocityList = velocityGraph[velocityVectors[1, basisVectIdx]];
                    reachableVelocityList.Add(velocityVectors[0, 0]);
                    reachableVelocityList.Add(velocityVectors[1, basisVectIdx]);
                    reachableVelocityList.Add(velocityVectors[1, (basisVectIdx + 1) % basisVectors.Count]);
                    reachableVelocityList.Add(velocityVectors[1, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                    reachableVelocityList.Add(velocityVectors[2, basisVectIdx]);
                    reachableVelocityList.Add(velocityVectors[2, (basisVectIdx + 1) % basisVectors.Count]);
                    reachableVelocityList.Add(velocityVectors[2, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                }

                /// Collect the velocities reachable from any other velocities.
                for (int spdIdx = 2; spdIdx < accelerationDuration; spdIdx++)
                {
                    for (int basisVectIdx = 0; basisVectIdx < basisVectors.Count; basisVectIdx++)
                    {
                        RCSet <RCNumVector> reachableVelocityList = velocityGraph[velocityVectors[spdIdx, basisVectIdx]];
                        reachableVelocityList.Add(velocityVectors[spdIdx - 1, basisVectIdx]);
                        reachableVelocityList.Add(velocityVectors[spdIdx - 1, (basisVectIdx + 1) % basisVectors.Count]);
                        reachableVelocityList.Add(velocityVectors[spdIdx - 1, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                        reachableVelocityList.Add(velocityVectors[spdIdx, basisVectIdx]);
                        reachableVelocityList.Add(velocityVectors[spdIdx, (basisVectIdx + 1) % basisVectors.Count]);
                        reachableVelocityList.Add(velocityVectors[spdIdx, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                        reachableVelocityList.Add(velocityVectors[spdIdx + 1, basisVectIdx]);
                        reachableVelocityList.Add(velocityVectors[spdIdx + 1, (basisVectIdx + 1) % basisVectors.Count]);
                        reachableVelocityList.Add(velocityVectors[spdIdx + 1, (basisVectIdx - 1 + basisVectors.Count) % basisVectors.Count]);
                    }
                }
            }

            return(velocityGraph);
        }
        /// <see cref="CommandInputListener.TryComplete"/>
        public override CommandInputListener.CompletionResultEnum TryComplete()
        {
            if (this.CommandBuilder.TargetPosition == RCNumVector.Undefined)
            {
                /// No target position selected -> completion failed!
                return(CompletionResultEnum.FailedAndCancel);
            }

            if (this.placeSelectedBuilding)
            {
                /// Target position selected for the selected building -> validate the selected position.
                int[] currentSelection = this.selectionManagerBC.CurrentSelection.ToArray();
                if (currentSelection.Length != 1)
                {
                    throw new InvalidOperationException("The number of the currently selected entities must be 1!");
                }

                Building selectedBuilding = this.scenarioManagerBC.ActiveScenario.GetElement <Building>(currentSelection[0]);
                if (selectedBuilding == null)
                {
                    throw new InvalidOperationException("The currently selected entity doesn't exist or is not a building!");
                }

                if (this.addonTypeName == null)
                {
                    /// There is no additional addon type.
                    if (this.fogOfWarBC.CheckPlacementConstraints(selectedBuilding, (RCIntVector)this.CommandBuilder.TargetPosition, new RCSet <Entity>()).Count == 0)
                    {
                        /// Selected position is OK.
                        return(CommandInputListener.CompletionResultEnum.Succeeded);
                    }
                    else
                    {
                        /// Selected position is invalid -> completion failed!
                        this.CommandBuilder.TargetPosition = RCNumVector.Undefined;
                        return(CommandInputListener.CompletionResultEnum.FailedButContinue);
                    }
                }
                else
                {
                    /// Additional addon type has to be checked as well.
                    IAddonType addonType = this.scenarioManagerBC.Metadata.GetAddonType(this.addonTypeName);
                    if (addonType == null)
                    {
                        throw new InvalidOperationException(string.Format("Addon type '{0}' is not defined in the metadata!", this.addonTypeName));
                    }
                    if (this.fogOfWarBC.CheckPlacementConstraints(selectedBuilding, (RCIntVector)this.CommandBuilder.TargetPosition, addonType, new RCSet <Entity>()).Count == 0)
                    {
                        /// Selected position is OK.
                        return(CommandInputListener.CompletionResultEnum.Succeeded);
                    }
                    else
                    {
                        /// Selected position is invalid -> completion failed!
                        this.CommandBuilder.TargetPosition = RCNumVector.Undefined;
                        return(CommandInputListener.CompletionResultEnum.FailedButContinue);
                    }
                }
            }
            else if (this.buildingTypeName != null)
            {
                /// Target position selected for a given building type -> validate the selected position.
                IBuildingType buildingType = this.scenarioManagerBC.Metadata.GetBuildingType(this.buildingTypeName);
                if (buildingType == null)
                {
                    throw new InvalidOperationException(string.Format("Building type '{0}' is not defined in the metadata!", this.buildingTypeName));
                }

                RCSet <Entity> currentSelection = new RCSet <Entity>();
                foreach (int selectedEntityID in this.selectionManagerBC.CurrentSelection)
                {
                    currentSelection.Add(this.scenarioManagerBC.ActiveScenario.GetElement <Entity>(selectedEntityID));
                }


                if (this.addonTypeName == null)
                {
                    if (this.fogOfWarBC.CheckPlacementConstraints(buildingType, (RCIntVector)this.CommandBuilder.TargetPosition, currentSelection).Count == 0)
                    {
                        /// Selected position is OK.
                        return(CompletionResultEnum.Succeeded);
                    }
                    else
                    {
                        /// Selected position is invalid -> completion failed!
                        this.CommandBuilder.TargetPosition = RCNumVector.Undefined;
                        return(CompletionResultEnum.FailedButContinue);
                    }
                }
                else
                {
                    /// Additional addon type has to be checked as well.
                    IAddonType addonType = this.scenarioManagerBC.Metadata.GetAddonType(this.addonTypeName);
                    if (addonType == null)
                    {
                        throw new InvalidOperationException(string.Format("Addon type '{0}' is not defined in the metadata!", this.addonTypeName));
                    }
                    if (this.fogOfWarBC.CheckPlacementConstraints(buildingType, (RCIntVector)this.CommandBuilder.TargetPosition, addonType, currentSelection).Count == 0)
                    {
                        /// Selected position is OK.
                        return(CommandInputListener.CompletionResultEnum.Succeeded);
                    }
                    else
                    {
                        /// Selected position is invalid -> completion failed!
                        this.CommandBuilder.TargetPosition = RCNumVector.Undefined;
                        return(CommandInputListener.CompletionResultEnum.FailedButContinue);
                    }
                }
            }
            else
            {
                /// A point selected on the map -> validate the selected position.
                return(CommandInputListener.CompletionResultEnum.Succeeded);
            }
        }
        /// <see cref="IObjectPlacementView.GetObjectPlacementBox"/>
        public ObjectPlacementBox GetObjectPlacementBox(RCIntVector position)
        {
            /// Calculate the top-left quadratic coordinates based on the retrieved object rectangles relative to the quadratic tile at the incoming position.
            RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > objRectsRelativeToQuadTileAtPos = this.GetObjectRelativeQuadRectangles();

            if (objRectsRelativeToQuadTileAtPos.Count == 0)
            {
                return(new ObjectPlacementBox
                {
                    Sprites = new List <SpriteRenderInfo>(),
                    IllegalParts = new List <RCIntRectangle>(),
                    LegalParts = new List <RCIntRectangle>()
                });
            }
            RCIntVector navCellCoords     = this.MapWindowBC.AttachedWindow.WindowToMapCoords(position).Round();
            IQuadTile   quadTileAtPos     = this.Map.GetCell(navCellCoords).ParentQuadTile;
            RCIntVector topLeftQuadCoords = quadTileAtPos.MapCoords;

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToQuadTileAtPos)
            {
                RCIntVector rectTopLeftQuadCoords = topLeftQuadCoords + relativeRect.Item1.Location;
                if (rectTopLeftQuadCoords.X < topLeftQuadCoords.X && rectTopLeftQuadCoords.Y < topLeftQuadCoords.Y ||
                    rectTopLeftQuadCoords.X < topLeftQuadCoords.X && rectTopLeftQuadCoords.Y == topLeftQuadCoords.Y ||
                    rectTopLeftQuadCoords.X == topLeftQuadCoords.X && rectTopLeftQuadCoords.Y < topLeftQuadCoords.Y)
                {
                    topLeftQuadCoords = rectTopLeftQuadCoords;
                }
            }

            /// Calculate the object rectangles relative to the calculated top-left quadratic coordinates.
            RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > objRectsRelativeToTopLeftQuadTile = new RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> >();

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToQuadTileAtPos)
            {
                objRectsRelativeToTopLeftQuadTile.Add(Tuple.Create(
                                                          new RCIntRectangle(
                                                              relativeRect.Item1.Location + quadTileAtPos.MapCoords - topLeftQuadCoords,
                                                              relativeRect.Item1.Size),
                                                          relativeRect.Item2));
            }

            /// Get the sprites to be displayed, translate their DisplayCoordinates accordingly from the top-left quadratic tile,
            /// and collect the violating quadratic coordinates.
            ObjectPlacementBox placementBox = new ObjectPlacementBox
            {
                Sprites      = new List <SpriteRenderInfo>(),
                IllegalParts = new List <RCIntRectangle>(),
                LegalParts   = new List <RCIntRectangle>()
            };
            RCSet <RCIntVector> violatingQuadCoords = this.CheckObjectConstraints(topLeftQuadCoords);

            foreach (Tuple <RCIntRectangle, SpriteRenderInfo[]> relativeRect in objRectsRelativeToTopLeftQuadTile)
            {
                RCIntVector topLeftDisplayCoords =
                    this.MapWindowBC.AttachedWindow.QuadToWindowRect(new RCIntRectangle(topLeftQuadCoords + relativeRect.Item1.Location, new RCIntVector(1, 1))).Location;
                for (int i = 0; i < relativeRect.Item2.Length; i++)
                {
                    relativeRect.Item2[i].DisplayCoords += topLeftDisplayCoords;
                    placementBox.Sprites.Add(relativeRect.Item2[i]);
                }
                for (int x = relativeRect.Item1.Left; x < relativeRect.Item1.Right; x++)
                {
                    for (int y = relativeRect.Item1.Top; y < relativeRect.Item1.Bottom; y++)
                    {
                        RCIntVector    relativeQuadCoords = new RCIntVector(x, y);
                        RCIntVector    absQuadCoords      = topLeftQuadCoords + relativeQuadCoords;
                        RCIntRectangle partRect           =
                            this.MapWindowBC.AttachedWindow.QuadToWindowRect(new RCIntRectangle(absQuadCoords, new RCIntVector(1, 1)));
                        if (violatingQuadCoords.Contains(relativeQuadCoords))
                        {
                            placementBox.IllegalParts.Add(partRect);
                        }
                        else
                        {
                            placementBox.LegalParts.Add(partRect);
                        }
                    }
                }
            }

            return(placementBox);
        }
Example #6
0
        /// <summary>
        /// Call this function from a thread to attach that thread to the Petri-network. The Petri-network will automatically
        /// synchronize the attached threads depending on it's structure.
        /// </summary>
        /// <param name="externalTransitions">
        /// List of the external transitions that the thread wants to fire. The thread will be blocked until at least one
        /// of these transitions becomes fireable.
        /// </param>
        /// <param name="callbackFunctions">
        /// This map has to assign a callback function for each callback transitions.
        /// </param>
        /// <remarks>
        /// The caller thread will be blocked until at least one of the given external transitions becomes fireable. Then
        /// the Petri-network will synchronize the thread while a callback transition becomes fireable. Then this transition
        /// will be fired, the assigned callback function will be called, and the thread will be detached from the
        /// Petri-network.
        /// </remarks>
        public void AttachThread(int[] externalTransitions, Dictionary <int, PNCallback> callbackFunctions)
        {
            lock (this.disposeLock) { if (this.pnDisposed)
                                      {
                                          throw new ObjectDisposedException("PetriNet");
                                      }
            }
            if (!this.buildFinished)
            {
                throw new PetriNetException("Petri-network is under construction!");
            }
            if (externalTransitions == null || externalTransitions.Length == 0)
            {
                throw new ArgumentNullException("externalTransitions");
            }
            if (callbackFunctions == null || callbackFunctions.Count == 0)
            {
                throw new ArgumentNullException("callbackFunctions");
            }

            RCSet <PNTransition> extTransitions             = new RCSet <PNTransition>();
            Dictionary <PNTransition, PNCallback> callbacks = new Dictionary <PNTransition, PNCallback>();
            PNTransition firstExt = null;

            for (int i = 0; i < externalTransitions.Length; ++i)
            {
                int trIdx = externalTransitions[i];
                if (trIdx >= 0 && trIdx < this.transitions.Length)
                {
                    if (!callbackFunctions.ContainsKey(trIdx))
                    {
                        extTransitions.Add(this.transitions[trIdx]);
                        if (firstExt == null)
                        {
                            firstExt = this.transitions[trIdx];
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Transition " + trIdx + " already exists in externalTransitions[" + i + "]!", "callbackFunctions");
                    }
                }
                else
                {
                    throw new ArgumentException("Transition " + trIdx + " doesn't exist!", "externalTransitions[" + i + "]");
                }
            }

            foreach (KeyValuePair <int, PNCallback> item in callbackFunctions)
            {
                int trIdx = item.Key;
                if (trIdx >= 0 && trIdx < this.transitions.Length)
                {
                    callbacks.Add(this.transitions[trIdx], item.Value);
                }
                else
                {
                    throw new ArgumentException("Transition " + trIdx + " doesn't exist!", "callbackFunctions");
                }
            }

            firstExt.Group.AttachThread(extTransitions, callbacks);
        }
Example #7
0
        /// <summary>
        /// Processes the channel events and incoming answers arrived from the guests.
        /// </summary>
        private void ProcessGuestChannels(IDssGuestChannel[] channelsToGuests)
        {
            RCSet <int> newGuests = new RCSet <int>();

            /// First collect the new guests
            for (int i = 0; i < this.previousChannelStates.Length; i++)
            {
                if (this.previousChannelStates[i] != channelsToGuests[i].ChannelState)
                {
                    /// The state of a channel has changed
                    this.previousChannelStates[i] = channelsToGuests[i].ChannelState;
                    if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_OPENED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideOpened);
                    }
                    else if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_CLOSED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideClosed);
                    }
                    else if (channelsToGuests[i].ChannelState == DssChannelState.GUEST_CONNECTED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideEngaged);
                        this.simulator.GetPlayer(i + 1).Activate();
                        newGuests.Add(i);
                    }
                }
            }

            /// Then process the answers of any other guests.
            for (int i = 0; i < this.previousChannelStates.Length; i++)
            {
                if (!newGuests.Contains(i) && channelsToGuests[i].ChannelState == DssChannelState.GUEST_CONNECTED)
                {
                    /// If a guest is connected to this channel, process it's answer.
                    RCPackage[] answerFromGuest = channelsToGuests[i].AnswerFromGuest;
                    for (int j = 0; j < answerFromGuest.Length; j++)
                    {
                        if (answerFromGuest[j].PackageFormat.ID == TestClientMessages.COLOR_CHANGE_REQUEST)
                        {
                            /// Color change request arrived from the guest.
                            PlayerColor newColor = (PlayerColor)answerFromGuest[j].ReadByte(0);
                            this.simulator.GetPlayer(i + 1).Color = newColor;

                            /// Notify the other connected guests.
                            for (int k = 0; k < channelsToGuests.Length; k++)
                            {
                                if (!newGuests.Contains(k) && i != k && channelsToGuests[k].ChannelState == DssChannelState.GUEST_CONNECTED)
                                {
                                    RCPackage colorChgNotif =
                                        RCPackage.CreateNetworkControlPackage(TestClientMessages.COLOR_CHANGE_NOTIFICATION);
                                    colorChgNotif.WriteInt(0, i + 1);
                                    colorChgNotif.WriteByte(1, (byte)newColor);
                                    this.rqs[k].Add(colorChgNotif);
                                }
                            }

                            /// Notify the UI
                            this.uiCallMarshal.SelectNewGuestColor(i, newColor);
                            break;  /// Ignore the remaining messages
                        }
                    }
                }
            }

            /// Send a reset message to the new guests
            foreach (int newGuestIdx in newGuests)
            {
                byte[] colors  = new byte[this.simulator.MaxNumOfPlayers];
                int[]  xCoords = new int[this.simulator.MaxNumOfPlayers];
                int[]  yCoords = new int[this.simulator.MaxNumOfPlayers];
                for (int j = 0; j < colors.Length; j++)
                {
                    colors[j]  = (byte)this.simulator.GetPlayer(j).Color;
                    xCoords[j] = this.simulator.GetPlayer(j).Position.X;
                    yCoords[j] = this.simulator.GetPlayer(j).Position.Y;
                }
                RCPackage reset = RCPackage.CreateNetworkControlPackage(TestClientMessages.RESET);
                reset.WriteByteArray(0, colors);
                reset.WriteIntArray(1, xCoords);
                reset.WriteIntArray(2, yCoords);
                this.rqs[newGuestIdx].Add(reset);
            }
        }
Example #8
0
        /// <summary>
        /// Constructs a ColorPalette object.
        /// </summary>
        /// <param name="palette">See ColorPalette.palette for more informations.</param>
        /// <param name="paletteMask">See ColorPalette.paletteMask for more informations.</param>
        /// <param name="specialColors">See ColorPalette.specialColors for more informations.</param>
        /// <remarks>
        /// Only the first parameter is mandatory. You can give null references for the others.
        /// </remarks>
        public ColorPalette(Color[] palette,
                            Color[] paletteMask,
                            Color[] specialColors)
        {
            this.palette       = null;
            this.paletteMask   = null;
            this.specialColors = null;

            /// Checking arguments.
            if (null == palette || 0 == palette.Length)
            {
                throw new ArgumentException("You must define at least 1 color in the palette.", "palette");
            }
            if (null != paletteMask && palette.Length != paletteMask.Length)
            {
                throw new ArgumentException("The arrays palette and paletteMask must have the same length.");
            }

            /// Saving the color palette.
            RCSet <Color> paletteSet = new RCSet <Color>();

            foreach (Color c in palette)
            {
                if (!paletteSet.Contains(c))
                {
                    paletteSet.Add(c);
                }
                else
                {
                    throw new ArgumentException("All colors in the array palette must be unique.", "palette");
                }
            }
            this.palette = palette;

            /// Saving the paletteMask.
            this.paletteMask = new Dictionary <Color, int>();
            if (null != paletteMask)
            {
                int idx = 0;
                foreach (Color c in paletteMask)
                {
                    if (!this.paletteMask.ContainsKey(c))
                    {
                        this.paletteMask.Add(c, idx);
                        idx++;
                    }
                    else
                    {
                        throw new ArgumentException("All colors in the array paletteMask must be unique.", "paletteMask");
                    }
                }
            }
            else
            {
                /// If no palette mask defined, we simply create the inverse of this.palette
                for (int idx = 0; idx < this.palette.Length; ++idx)
                {
                    this.paletteMask.Add(this.palette[idx], idx);
                }
            }

            /// Saving the special colors.
            if (null != specialColors)
            {
                RCSet <Color> specColorSet = new RCSet <Color>();
                foreach (Color c in specialColors)
                {
                    if (!specColorSet.Contains(c))
                    {
                        if (!paletteSet.Contains(c) && !this.paletteMask.ContainsKey(c))
                        {
                            specColorSet.Add(c);
                        }
                        else
                        {
                            throw new ArgumentException("A color defined in the array specialColors has already been defined in the array palette or paletteMask.", "specialColors");
                        }
                    }
                    else
                    {
                        throw new ArgumentException("All colors in the array specialColors must be unique.", "specialColors");
                    }
                }
                this.specialColors = specialColors;
            }
        }
Example #9
0
        /// <see cref="ObjectPlacementView.GetObjectRelativeQuadRectangles"/>
        protected override RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > GetObjectRelativeQuadRectangles()
        {
            this.UpdatePlacementData();

            RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> > retList = new RCSet <Tuple <RCIntRectangle, SpriteRenderInfo[]> >();

            IBuildingType buildingType = this.buildingToBePlaced != null
                ? this.buildingToBePlaced.BuildingType
                : this.buildingTypeToBePlaced;

            if (buildingType == null)
            {
                return(retList);
            }

            /// Calculate the building rectangle and get sprites from the building preview animation if exists.
            RCIntVector    buildingQuadSize     = this.Scenario.Map.CellToQuadSize(buildingType.Area.Read().Size);
            RCIntRectangle buildingRelativeRect = new RCIntRectangle((-1) * buildingQuadSize / 2, buildingQuadSize);

            SpriteRenderInfo[] buildingSprites = new SpriteRenderInfo[0];
            if (this.buildingPreviewAnimation != null)
            {
                buildingSprites = new SpriteRenderInfo[this.buildingPreviewAnimation.CurrentFrame.Length];
                for (int i = 0; i < this.buildingPreviewAnimation.CurrentFrame.Length; i++)
                {
                    buildingSprites[i] = new SpriteRenderInfo()
                    {
                        SpriteGroup   = SpriteGroupEnum.MapObjectSpriteGroup,
                        Index         = buildingType.SpritePalette.Index,
                        DisplayCoords = buildingType.SpritePalette.GetOffset(this.buildingPreviewAnimation.CurrentFrame[i]),
                        Section       = buildingType.SpritePalette.GetSection(this.buildingPreviewAnimation.CurrentFrame[i])
                    };
                }
            }
            retList.Add(Tuple.Create(buildingRelativeRect, buildingSprites));

            if (this.addonTypeToBePlaced != null)
            {
                /// Calculate the addon rectangle and get sprites from the addon preview animation if exists.
                RCIntVector    addonQuadSize     = this.Scenario.Map.CellToQuadSize(this.addonTypeToBePlaced.Area.Read().Size);
                RCIntRectangle addonRelativeRect = new RCIntRectangle(
                    buildingRelativeRect.Location +
                    buildingType.GetRelativeAddonPosition(this.Scenario.Map, this.addonTypeToBePlaced),
                    addonQuadSize);
                SpriteRenderInfo[] addonSprites = new SpriteRenderInfo[0];
                if (this.addonPreviewAnimation != null)
                {
                    addonSprites = new SpriteRenderInfo[this.addonPreviewAnimation.CurrentFrame.Length];
                    for (int i = 0; i < this.addonPreviewAnimation.CurrentFrame.Length; i++)
                    {
                        addonSprites[i] = new SpriteRenderInfo()
                        {
                            SpriteGroup   = SpriteGroupEnum.MapObjectSpriteGroup,
                            Index         = this.addonTypeToBePlaced.SpritePalette.Index,
                            DisplayCoords = this.addonTypeToBePlaced.SpritePalette.GetOffset(this.addonPreviewAnimation.CurrentFrame[i]),
                            Section       = this.addonTypeToBePlaced.SpritePalette.GetSection(this.addonPreviewAnimation.CurrentFrame[i])
                        };
                    }
                }
                retList.Add(Tuple.Create(addonRelativeRect, addonSprites));
            }
            return(retList);
        }