/// <summary> /// Gets the transition cells of this region into the given other region to the given direction. /// </summary> /// <param name="targetRegion">The given target region.</param> /// <param name="direction">The given direction.</param> /// <returns>The transition cells of this region into the given other region to the given direction.</returns> public RCSet <Cell> GetTransitionCells(Region targetRegion, int direction) { int oppositeDir = (direction + GridDirections.DIRECTION_COUNT / 2) % GridDirections.DIRECTION_COUNT; Region rootOfThis = this.Root; Region rootOfTarget = targetRegion.Root; if (rootOfThis.edgeCells[direction].Count == 0) { return(new RCSet <Cell>()); } if (rootOfTarget.edgeCells[oppositeDir].Count == 0) { return(new RCSet <Cell>()); } RCSet <Cell> transitionCells = new RCSet <Cell>(); foreach (Cell edgeCell in rootOfThis.edgeCells[direction]) { Cell straightNeighbour = edgeCell.GetNeighbour(direction); if (straightNeighbour == null) { continue; } if (rootOfTarget.edgeCells[oppositeDir].Contains(straightNeighbour)) { transitionCells.Add(edgeCell); continue; } if (direction == GridDirections.NORTH || direction == GridDirections.EAST || direction == GridDirections.SOUTH || direction == GridDirections.WEST) { Cell leftStraightNeighbour = edgeCell.GetNeighbour((direction + GridDirections.DIRECTION_COUNT - 1) % GridDirections.DIRECTION_COUNT); if (leftStraightNeighbour == null) { continue; } if (rootOfTarget.edgeCells[oppositeDir].Contains(leftStraightNeighbour)) { transitionCells.Add(edgeCell); continue; } Cell rightStraightNeighbour = edgeCell.GetNeighbour((direction + 1) % GridDirections.DIRECTION_COUNT); if (rightStraightNeighbour == null) { continue; } if (rootOfTarget.edgeCells[oppositeDir].Contains(rightStraightNeighbour)) { transitionCells.Add(edgeCell); continue; } } } return(transitionCells); }
/// <summary> /// Creates the given components from the given assembly. /// </summary> /// <param name="assembly">The assembly of the components.</param> /// <param name="components">The components to create.</param> private static void CreateComponentsFromAssembly(string assembly, RCSet <string> components) { TraceManager.WriteAllTrace(string.Format("Creating components of assembly '{0}'.", assembly), ComponentManager.COMPONENT_MGR_INFO); Assembly asm = Assembly.Load(assembly); if (asm != null) { Type[] types = asm.GetTypes(); foreach (Type type in types) { ComponentAttribute compAttr = GetComponentAttribute(type); if (compAttr == null) { continue; } if (createdComponents.ContainsKey(compAttr.Name)) { continue; } if (components.Contains(compAttr.Name)) { CreateComponentInstance(compAttr.Name, type); } } } else { throw new ComponentModelException(string.Format("Unable to load assembly '{0}'!", assembly)); } }
/// <summary> /// Constructs a MagicBox instance for the given recipient entities and target position. /// </summary> /// <param name="recipientEntities">The recipient entities.</param> /// <param name="targetPosition">The target position.</param> public MagicBox(RCSet <Entity> recipientEntities, RCNumVector targetPosition) { this.commonTargetPosition = RCNumVector.Undefined; this.targetPositions = new Dictionary <Entity, RCNumVector>(); /// Check if we shall keep formation of the recipient entities. RCNumRectangle boundingBox = this.CalculateBoundingBox(recipientEntities); if (!boundingBox.Contains(targetPosition)) { RCNumVector boundingBoxCenter = (2 * boundingBox.Location + boundingBox.Size) / 2; foreach (Entity entity in recipientEntities) { RCNumVector boxLocationToEntityVector = entity.MotionControl.PositionVector.Read() - boundingBox.Location; RCNumVector magicBox = entity.MotionControl.IsFlying ? AIR_MAGIC_BOX : GROUND_MAGIC_BOX; if (boxLocationToEntityVector.X > magicBox.X || boxLocationToEntityVector.Y > magicBox.Y) { /// Entity is outside of the magic box -> don't keep formation. this.commonTargetPosition = targetPosition; break; } /// Calculate the target position of the entity. this.targetPositions[entity] = targetPosition + entity.MotionControl.PositionVector.Read() - boundingBoxCenter; } } else { /// Target position is inside the bounding box -> don't keep formation. this.commonTargetPosition = targetPosition; } }
/// <summary> /// Creates hold executions for the given entities. /// </summary> /// <param name="entitiesToHandle">The entities to hold.</param> private IEnumerable <CmdExecutionBase> CreateHoldExecutions(RCSet <Entity> entitiesToHandle) { foreach (Entity entity in entitiesToHandle) { yield return(new HoldExecution(entity)); } }
/// <see cref="IGraph<Region>.GetNeighbours"/> public IEnumerable <Region> GetNeighbours(Region node) { if (!this.transitionCells.ContainsKey(node)) { this.transitionCells.Add(node, new Dictionary <Region, RCSet <Cell> >()); for (int direction = 0; direction < GridDirections.DIRECTION_COUNT; direction++) { Sector neighbourSector = node.Subdivision.Sector.GetNeighbour(direction); if (neighbourSector == null) { continue; } SectorSubdivision neighbourSubdivision = neighbourSector.GetSubdivisionForAgent(this.agent); foreach (Region neighbourRegion in neighbourSubdivision.Regions) { RCSet <Cell> transitionCells = node.GetTransitionCells(neighbourRegion, direction); if (transitionCells.Count > 0) { this.transitionCells[node][neighbourRegion] = transitionCells; } } } } return(this.transitionCells[node].Keys); }
/// <summary> /// Steps the given agent towards the given direction. /// </summary> /// <param name="agent">The agent to be stepped.</param> /// <param name="stepDirection">The direction of the step.</param> /// <param name="collidingAgents">The output list of colliding agents if the step failed; otherwise an empty set.</param> /// <returns>True if the agent has been stepped successfully; otherwise false.</returns> public bool StepAgent(Agent agent, int stepDirection, out RCSet <Agent> collidingAgents) { if (agent == null) { throw new ArgumentNullException("agent"); } if (!this.agents.Contains(agent)) { throw new InvalidOperationException("The given agent is not placed on the pathfinding grid!"); } if (agent.MovingStatus != AgentMovingStatusEnum.Moving) { throw new InvalidOperationException("The moving status of the given agent is not Moving!"); } if (stepDirection < 0 || stepDirection >= GridDirections.DIRECTION_COUNT) { throw new ArgumentOutOfRangeException("stepDirection"); } /// Validate the desired new top-left cell of the agent and collect the colliding agents. Cell desiredNewTopLeftCell = this[agent.Area.X, agent.Area.Y].GetNeighbour(stepDirection); if (!this.ValidatePositionForAgent(agent, desiredNewTopLeftCell, out collidingAgents)) { return(false); } /// Step the agent towards the given direction. this.RemoveAgentFromGrid(agent); agent.Step(stepDirection); this.PlaceAgentOnGrid(agent); return(true); }
/// <summary> /// Gets the subdivision that is calculated for the given agent. /// </summary> /// <param name="agent">The given agent.</param> /// <returns>The subdivision that is calculated for the given agent.</returns> public SectorSubdivision GetSubdivisionForAgent(Agent agent) { /// Collect the overlap enabled agents. RCSet <Agent> overlapEnabledAgents = new RCSet <Agent>(); RCSet <Agent> currentlyOverlappingAgents = this.grid[agent.Area.X, agent.Area.Y].GetAgents(agent.MovingSize); foreach (Agent staticAgent in this.staticAgents[agent.MovingSize]) { if (currentlyOverlappingAgents.Contains(staticAgent) || staticAgent.Client.IsOverlapEnabled(agent.Client) || agent.Client.IsOverlapEnabled(staticAgent.Client)) { overlapEnabledAgents.Add(staticAgent); } } /// Try to find an already existing sector subdivision for the agent. SectorSubdivision subdivisionForAgent = this.subdivisions.FirstOrDefault(subdivision => subdivision.MovingSize == agent.MovingSize && subdivision.OverlapEnabledAgents.SetEquals(overlapEnabledAgents)); if (subdivisionForAgent == null) { /// Create a new one if not found. subdivisionForAgent = new SectorSubdivision(this, agent.MovingSize, overlapEnabledAgents); this.subdivisions.Add(subdivisionForAgent); } return(subdivisionForAgent); }
/// <see cref="IFogOfWarBC.CheckPlacementConstraints"/> public RCSet <RCIntVector> CheckPlacementConstraints(Building building, RCIntVector position, IAddonType addonType, RCSet <Entity> entitiesToIgnore) { if (this.ActiveScenario == null) { throw new InvalidOperationException("No active scenario!"); } RCIntVector objectQuadraticSize = this.ActiveScenario.Map.CellToQuadSize(building.ElementType.Area.Read().Size); RCSet <RCIntVector> violatingQuadCoords = building.CheckPlacementConstraints(position, addonType, entitiesToIgnore); for (int x = 0; x < objectQuadraticSize.X; x++) { for (int y = 0; y < objectQuadraticSize.Y; y++) { RCIntVector relativeQuadCoords = new RCIntVector(x, y); RCIntVector absQuadCoords = position + relativeQuadCoords; if (absQuadCoords.X < 0 || absQuadCoords.X >= this.ActiveScenario.Map.Size.X || absQuadCoords.Y < 0 || absQuadCoords.Y >= this.ActiveScenario.Map.Size.Y || this.GetFullFowTileFlags(absQuadCoords).HasFlag(FOWTileFlagsEnum.Current)) { violatingQuadCoords.Add(relativeQuadCoords); } } } return(violatingQuadCoords); }
/// <see cref="IFogOfWarBC.GetPlacementSuggestions"/> public RCSet <RCIntRectangle> GetPlacementSuggestions(IBuildingType buildingType) { if (this.ActiveScenario == null) { throw new InvalidOperationException("No active scenario!"); } RCIntRectangle quadWindow = this.mapWindowBC.AttachedWindow.QuadTileWindow; RCSet <Tuple <RCIntRectangle, RCIntVector> > suggestions = buildingType.GetPlacementSuggestions(this.ActiveScenario, quadWindow); RCSet <RCIntRectangle> retList = new RCSet <RCIntRectangle>(); foreach (Tuple <RCIntRectangle, RCIntVector> suggestion in suggestions) { RCIntRectangle areaToCheck = suggestion.Item1; RCIntVector suggestionTranslation = suggestion.Item2; for (int x = areaToCheck.Left; x < areaToCheck.Right; x++) { for (int y = areaToCheck.Top; y < areaToCheck.Bottom; y++) { RCIntVector quadCoordToCheck = new RCIntVector(x, y); if (quadCoordToCheck.X >= 0 && quadCoordToCheck.X < this.ActiveScenario.Map.Size.X && quadCoordToCheck.Y >= 0 && quadCoordToCheck.Y < this.ActiveScenario.Map.Size.Y && this.GetFowState(quadCoordToCheck) == FOWTypeEnum.None) { RCIntVector buildingQuadSize = this.ActiveScenario.Map.CellToQuadSize(buildingType.Area.Read().Size); retList.Add(new RCIntRectangle(areaToCheck.Location + suggestionTranslation, buildingQuadSize)); } } } } return(retList); }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <SCV> scvsToHandle, RCSet <Entity> fullEntitySet, string parameter) { switch (this.commandType) { case SCVCommandEnum.Repair: return(this.CheckRepairAvailability(scvsToHandle, fullEntitySet)); case SCVCommandEnum.Gather: return(this.CheckGatherAvailability(scvsToHandle, fullEntitySet)); case SCVCommandEnum.Return: return(this.CheckReturnAvailability(scvsToHandle, fullEntitySet)); case SCVCommandEnum.Build: return(this.CheckBuildAvailability(scvsToHandle, fullEntitySet, parameter)); case SCVCommandEnum.StopBuild: return(this.CheckStopBuildAvailability(scvsToHandle, fullEntitySet)); case SCVCommandEnum.Move: case SCVCommandEnum.Stop: case SCVCommandEnum.Attack: case SCVCommandEnum.Patrol: case SCVCommandEnum.Hold: return(this.CheckBasicCommandAvailability(scvsToHandle)); default: return(AvailabilityEnum.Unavailable); } }
/// <see cref="ITerrainObjectConstraint.Check"/> public RCSet <RCIntVector> Check(IMapAccess map, RCIntVector position) { if (map == null) { throw new ArgumentNullException("map"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); RCIntVector absQuadCoords = position + this.quadCoords; if (absQuadCoords.X >= 0 && absQuadCoords.X < map.Size.X && absQuadCoords.Y >= 0 && absQuadCoords.Y < map.Size.Y) { IQuadTile checkedQuadTile = map.GetQuadTile(absQuadCoords); IIsoTile checkedIsoTile = checkedQuadTile.PrimaryIsoTile; if (checkedIsoTile.Type.TerrainA != this.terrainA || checkedIsoTile.Type.TerrainB != this.terrainB || !this.allowedCombinations.Contains(checkedIsoTile.Type.Combination)) { retList.Add(this.quadCoords); foreach (IQuadTile neighbour in checkedQuadTile.Neighbours) { if (neighbour.PrimaryIsoTile == checkedIsoTile) { retList.Add(neighbour.MapCoords - position); } } } } return(retList); }
/// <summary> /// Creates command executions for undefined command type. /// </summary> /// <param name="scvsToHandle">The SCVs to order.</param> /// <param name="fullEntitySet">The set of selected entities.</param> /// <param name="targetPosition">The target position.</param> /// <param name="targetEntityID">The ID of the target entity or -1 if undefined.</param> private IEnumerable <CmdExecutionBase> CreateUndefinedExecutions(RCSet <SCV> scvsToHandle, RCSet <Entity> fullEntitySet, RCNumVector targetPosition, int targetEntityID) { Entity targetEntity = scvsToHandle.First().Scenario.GetElementOnMap <Entity>(targetEntityID, MapObjectLayerEnum.GroundObjects); TerranBuilding targetBuilding = targetEntity as TerranBuilding; MagicBox magicBox = new MagicBox(fullEntitySet, targetPosition); foreach (SCV scv in scvsToHandle.Where(scv => !scv.IsConstructing)) { if (targetBuilding != null && targetBuilding.Owner == scv.Owner && targetBuilding.ConstructionJob != null && !targetBuilding.ConstructionJob.IsFinished && targetBuilding.ConstructionJob.AttachedSCV == null) { /// The target entity is a friendly Terran building that is under construction but its construction is /// not currently in progress -> start a continue build command. yield return(new SCVContinueBuildExecution(scv, targetPosition, targetBuilding.ID.Read())); } else if (targetEntity != null && targetEntity.Owner == scv.Owner && this.IsValidTargetForRepair(targetEntity)) { /// The target entity is a friendly entity and is valid for a repair command -> start a repair command. yield return(new SCVRepairExecution(scv, targetPosition, targetEntityID)); } else if (targetEntity != null && targetEntity.Owner != null && targetEntity.Owner != scv.Owner) { /// The target entity is an enemy entity -> start an attack execution. yield return(new AttackExecution(scv, magicBox.GetTargetPosition(scv), targetEntityID)); } else { /// In any other cases -> start a move execution. yield return(new MoveExecution(scv, magicBox.GetTargetPosition(scv), targetEntityID)); } /// TODO: Handle the cases for Repair, Gather and Return commands! } }
/// <summary> /// Creates hold executions for the given SCVs. /// </summary> /// <param name="scvsToHandle">The SCVs to hold.</param> private IEnumerable <CmdExecutionBase> CreateHoldExecutions(RCSet <SCV> scvsToHandle) { foreach (SCV scv in scvsToHandle.Where(scv => !scv.IsConstructing)) { yield return(new HoldExecution(scv)); } }
/// <summary> /// Creates build executions for the given SCVs. /// </summary> /// <param name="scvsToHandle">The SCVs to build.</param> /// <param name="topLeftQuadTile">The coordinates of the top-left quadratic tile of the building.</param> /// <param name="buildingType">The type of the building.</param> private IEnumerable <CmdExecutionBase> CreateBuildExecutions(RCSet <SCV> scvsToHandle, RCIntVector topLeftQuadTile, string buildingType) { foreach (SCV scv in scvsToHandle.Where(scv => !scv.IsConstructing)) { yield return(new SCVStartBuildExecution(scv, buildingType, topLeftQuadTile)); } }
/// <see cref="ScenarioElement.AttachToMap"/> public override bool AttachToMap(RCNumVector position, params ScenarioElement[] elementsToIgnore) { /// Check if the position of this Refinery would align with a VespeneGeyser. RCSet <VespeneGeyser> vespeneGeysersAtPos = this.Scenario.GetElementsOnMap <VespeneGeyser>(position, MapObjectLayerEnum.GroundObjects); if (vespeneGeysersAtPos.Count != 1) { return(false); } VespeneGeyser vespeneGeyserAtPos = vespeneGeysersAtPos.First(); if (this.CalculateArea(position) != vespeneGeyserAtPos.Area) { return(false); } /// Save the VespeneGeyser and detach it from the map. this.underlyingVespeneGeyser.Write(vespeneGeyserAtPos); this.underlyingVespeneGeyser.Read().DetachFromMap(); /// Try to attach the Refinery. bool refineryAttached = base.AttachToMap(position, elementsToIgnore); if (!refineryAttached) { /// If the Refinery could not be attached -> reattach the underlying VespeneGeyser. this.underlyingVespeneGeyser.Read().AttachToMap(position); this.underlyingVespeneGeyser.Write(null); } return(refineryAttached); }
/// <see cref="EntityPlacementConstraint.CheckImpl"/> protected override RCSet <RCIntVector> CheckImpl(Scenario scenario, RCIntVector position, RCSet <Entity> entitiesToIgnore) { RCIntRectangle objArea = new RCIntRectangle(position, scenario.Map.CellToQuadSize(this.EntityType.Area.Read().Size)); RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); VespeneGeyser foundVespeneGeyser = null; bool isOK = true; for (int absY = objArea.Top; absY < objArea.Bottom; absY++) { for (int absX = objArea.Left; absX < objArea.Right; absX++) { RCIntVector absQuadCoords = new RCIntVector(absX, absY); if (absQuadCoords.X >= 0 && absQuadCoords.X < scenario.Map.Size.X && absQuadCoords.Y >= 0 && absQuadCoords.Y < scenario.Map.Size.Y) { retList.Add(absQuadCoords - position); VespeneGeyser vespeneGeyserAtCoords = scenario.GetFixedEntity <VespeneGeyser>(absQuadCoords); if (vespeneGeyserAtCoords == null || (foundVespeneGeyser != null && foundVespeneGeyser != vespeneGeyserAtCoords)) { /// There is no VespeneGeyser at the given coordinates OR /// the VespeneGeyser at the given coordinates is another VespeneGeyser. isOK = false; continue; } foundVespeneGeyser = vespeneGeyserAtCoords; } } } if (isOK) { retList.Clear(); } return(retList); }
/// <summary> /// Checks whether this placement constraint allows placing an entity of the corresponding type to the given scenario at the given /// quadratic position and collects all the violating quadratic coordinates relative to the given position. /// </summary> /// <param name="scenario">Reference to the given scenario.</param> /// <param name="position">The position to be checked.</param> /// <param name="entitiesToIgnore"> /// The list of entities to be ignored during the check. All entities in this list shall belong to the given scenario. /// </param> /// <returns> /// The list of the quadratic coordinates (relative to the given position) violating this placement constraint. /// </returns> public RCSet <RCIntVector> Check(Scenario scenario, RCIntVector position, RCSet <Entity> entitiesToIgnore) { if (this.entityType == null) { throw new SimulatorException("Entity type has not yet been set for this constraint!"); } if (scenario == null) { throw new ArgumentNullException("scenario"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } if (entitiesToIgnore == null) { throw new ArgumentNullException("entitiesToIgnore"); } if (entitiesToIgnore.Any(entityToIgnore => entityToIgnore.Scenario != scenario)) { throw new ArgumentException("All entities to be ignored shall belong to the given scenario!", "entitiesToIgnore"); } return(this.CheckImpl(scenario, position, entitiesToIgnore)); }
/// <summary> /// Uninitializes the player with the given index. /// Uninitializing a player is only allowed if players have not yet been finalized. /// Players can be finalized using the Scenario.FinalizePlayers method. /// </summary> /// <param name="index">The index of the player to uninitialize.</param> public void UninitializePlayer(int index) { if (this.playersFinalized.Read() != 0x00) { throw new InvalidOperationException("Players already finalized!"); } if (index < 0 || index >= Player.MAX_PLAYERS) { throw new ArgumentOutOfRangeException("index"); } if (this.players[index].Read() == null) { throw new SimulatorException(string.Format("Player with index {0} has not yet been initialized!", index)); } StartLocation startLoc = this.players[index].Read().StartLocation; startLoc.AttachToMap(this.map.GetQuadTile(this.players[index].Read().QuadraticStartPosition.Location)); RCSet <Entity> entitiesOfPlayer = new RCSet <Entity>(this.players[index].Read().Entities); this.players[index].Read().Dispose(); this.players[index].Write(null); /// Destroy entities of the player. foreach (Entity entity in entitiesOfPlayer) { if (entity.HasMapObject(MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects)) { entity.DetachFromMap(); } this.RemoveElementFromScenario(entity); entity.Dispose(); } }
/// <see cref="ITerrainObjectType.CheckTerrainObjectIntersections"/> public RCSet <RCIntVector> CheckTerrainObjectIntersections(IMapAccess map, RCIntVector position) { if (map == null) { throw new ArgumentNullException("map"); } if (position == RCIntVector.Undefined) { throw new ArgumentNullException("position"); } RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); 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) { /// Check intersection with other terrain object at the current quadratic tile. ITerrainObject objToCheck = map.GetQuadTile(absQuadCoords).TerrainObject; if (objToCheck != null && !this.IsExcluded(relQuadCoords) && objToCheck.GetQuadTile(absQuadCoords - objToCheck.MapCoords) != null) { retList.Add(relQuadCoords); } } } } return(retList); }
/// <summary> /// Gets all of the scenario elements of the given type added to this scenario. /// </summary> /// <typeparam name="T">The type of the scenario elements to get.</typeparam> /// <returns>A list that contains all of the scenario elements of the given type added to this scenario.</returns> public RCSet <T> GetAllElements <T>() where T : ScenarioElement { RCSet <T> retList = new RCSet <T>(); foreach (ScenarioElement element in this.scenarioElements) { if (this.elementsToRemoveAfterUpdate.Contains(element)) { continue; } T elementAsT = element as T; if (elementAsT != null) { retList.Add(elementAsT); } } foreach (ScenarioElement element in this.elementsToAddAfterUpdate) { T elementAsT = element as T; if (elementAsT != null) { retList.Add(elementAsT); } } return(retList); }
/// <summary> /// Internal implementation of ComputeFieldOffsets. /// </summary> /// <param name="types">The list of the types.</param> /// <param name="triedTypeIDs">Used to avoid infinite loop.</param> private void ComputeFieldOffsetsInternal(List <HeapType> types, ref RCSet <short> triedTypeIDs) { if (this.fieldIndices == null) { return; } if (!triedTypeIDs.Add(this.id)) { throw new HeapException(string.Format("Infinite cycle found in the layout of element '{0}'!", this.name)); } int allocationSize = 0; for (int fieldIdx = 0; fieldIdx < this.fieldTypeIDs.Count; fieldIdx++) { this.fieldOffsets[fieldIdx] = allocationSize; short fieldTypeID = this.fieldTypeIDs[fieldIdx]; HeapType fieldType = types[fieldTypeID]; if (fieldType.AllocationSize == -1) { /// Compute the allocation size of the field type first. fieldType.ComputeFieldOffsetsInternal(types, ref triedTypeIDs); } allocationSize += fieldType.AllocationSize; } this.allocationSize = allocationSize; triedTypeIDs.Remove(this.id); }
/// <summary> /// Gets the scenario elements of the given type that are attached to at least one of the given layers of the map inside the given area. /// </summary> /// <typeparam name="T">The type of the scenario elements to get.</typeparam> /// <param name="area"> /// <param name="firstLayer">The first layer to search in.</param> /// <param name="furtherLayers">List of the further layers to search in.</param> /// The area to search. /// </param> /// <returns> /// A list that contains the scenario elements of the given type that are attached to at least one of the given layers of the map inside /// the given area. /// </returns> public RCSet <T> GetElementsOnMap <T>(RCNumRectangle area, MapObjectLayerEnum firstLayer, params MapObjectLayerEnum[] furtherLayers) where T : ScenarioElement { if (area == RCNumRectangle.Undefined) { throw new ArgumentNullException("area"); } if (furtherLayers == null) { throw new ArgumentNullException("furtherLayers"); } RCSet <T> retList = new RCSet <T>(); foreach (MapObject mapObj in this.mapObjects[firstLayer].GetContents(area)) { T elementAsT = mapObj.Owner as T; if (elementAsT != null) { retList.Add(elementAsT); } } foreach (MapObjectLayerEnum furtherLayer in furtherLayers) { foreach (MapObject mapObj in this.mapObjects[furtherLayer].GetContents(area)) { T elementAsT = mapObj.Owner as T; if (elementAsT != null) { retList.Add(elementAsT); } } } return(retList); }
/// <summary> /// Updates the current and the saved selections. /// </summary> private void Update() { /// Collect the IDs to be removed. RCSet <int> idsToRemove = new RCSet <int>(); foreach (int id in this.currentSelection) { Entity entity = this.ActiveScenario.GetElementOnMap <Entity>(id, MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects); if (entity == null) { idsToRemove.Add(id); } } foreach (RCSet <int> savedSelection in this.savedSelections) { foreach (int id in savedSelection) { Entity entity = this.ActiveScenario.GetElementOnMap <Entity>(id, MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects); if (entity == null) { idsToRemove.Add(id); } } } /// Remove the collected IDs. foreach (int idToRemove in idsToRemove) { this.currentSelection.Remove(idToRemove); foreach (RCSet <int> savedSelection in this.savedSelections) { savedSelection.Remove(idToRemove); } } }
/// <see cref="EntityPlacementConstraint.CheckImpl"/> protected override RCSet <RCIntVector> CheckImpl(Scenario scenario, RCIntVector position, RCSet <Entity> entitiesToIgnore) { RCIntRectangle objArea = new RCIntRectangle(position, scenario.Map.CellToQuadSize(this.EntityType.Area.Read().Size)); RCSet <RCIntVector> retList = new RCSet <RCIntVector>(); for (int absY = objArea.Top; absY < objArea.Bottom; absY++) { for (int absX = objArea.Left; absX < objArea.Right; absX++) { RCIntVector absQuadCoords = new RCIntVector(absX, absY); if (absQuadCoords.X >= 0 && absQuadCoords.X < scenario.Map.Size.X && absQuadCoords.Y >= 0 && absQuadCoords.Y < scenario.Map.Size.Y) { /// Collect all the entities that are on the ground, are too close and not to be ignored. RCIntRectangle checkedQuadRect = new RCIntRectangle(absQuadCoords - this.minimumDistance, this.checkedQuadRectSize); RCNumRectangle checkedArea = (RCNumRectangle)scenario.Map.QuadToCellRect(checkedQuadRect) - new RCNumVector(1, 1) / 2; RCSet <T> entitiesTooClose = scenario.GetElementsOnMap <T>(checkedArea, MapObjectLayerEnum.GroundObjects); if (entitiesTooClose.Any(entityTooClose => !entitiesToIgnore.Contains(entityTooClose))) { retList.Add(absQuadCoords - position); } } } } return(retList); }
/// <summary> /// Checks the parameters when a thread is being attached to the Petri-network. /// </summary> /// <exception cref="PetriNetException">If the parameters are wrong.</exception> private void CheckThreadAttachParameters(RCSet <PNTransition> extTransitions, Dictionary <PNTransition, PetriNet.PNCallback> callbacks) { /// All given external transitions have to exist in this transition group. foreach (PNTransition tr in extTransitions) { if (!this.transitions.ContainsKey(tr) || this.transitions[tr] != PetriNet.PNTransitionType.EXTERNAL) { throw new PetriNetException("The external transition was not registered at the transition group!"); } } /// All given callback transitions have to exist in this transition group. foreach (KeyValuePair <PNTransition, PetriNet.PNCallback> item in callbacks) { if (!this.transitions.ContainsKey(item.Key) || this.transitions[item.Key] != PetriNet.PNTransitionType.CALLBACK) { throw new PetriNetException("The callback transition was not registered at the transition group!"); } } /// Callback functions must be assigned to each callback transitions in this transition group. foreach (KeyValuePair <PNTransition, PetriNet.PNTransitionType> item in this.transitions) { if (item.Value == PetriNet.PNTransitionType.CALLBACK && (!callbacks.ContainsKey(item.Key) || callbacks[item.Key] == null)) { throw new PetriNetException("No callback function assigned for a callback transition!"); } } }
/// <see cref="BuildingPlacementSuggestionProvider.GetSuggestionsImpl"/> protected override RCSet <Tuple <RCIntRectangle, RCIntVector> > GetSuggestionsImpl(Scenario scenario, RCIntRectangle area) { RCSet <Tuple <RCIntRectangle, RCIntVector> > retList = new RCSet <Tuple <RCIntRectangle, RCIntVector> >(); RCSet <Addon> processedAddons = new RCSet <Addon>(); for (int x = area.Left; x < area.Right; x++) { for (int y = area.Top; y < area.Bottom; y++) { RCIntVector quadCoords = new RCIntVector(x, y); Addon addon = scenario.GetFixedEntity <Addon>(quadCoords); if (addon == null || processedAddons.Contains(addon) || addon.CurrentMainBuilding != null || !this.BuildingType.HasAddonType(addon.AddonType.Name)) { continue; } retList.Add(Tuple.Create( addon.MapObject.QuadraticPosition, (-1) * this.BuildingType.GetRelativeAddonPosition(scenario.Map, addon.AddonType))); processedAddons.Add(addon); } } return(retList); }
/// <see cref="ObjectPlacementView.CheckObjectConstraints"/> protected override RCSet <RCIntVector> CheckObjectConstraints(RCIntVector topLeftQuadCoords) { RCSet <RCIntVector> violatingQuadCoords = this.terrainObjectType.CheckConstraints(this.Map, topLeftQuadCoords); violatingQuadCoords.UnionWith(this.terrainObjectType.CheckTerrainObjectIntersections(this.Map, topLeftQuadCoords)); return(violatingQuadCoords); }
/// <summary> /// Launches the next group of missiles to the given target entity if it's possible in the current simulation frame. /// </summary> /// <param name="targetEntity">The target entity.</param> /// <returns> /// True if the target entity is still in attack range; otherwise false. /// </returns> public bool LaunchMissiles(Entity targetEntity) { if (!this.IsEntityInRange(targetEntity)) { return(false); } if (!this.CanLaunchMissiles()) { return(true); } /// Launch the missiles. RCSet <Missile> launchedMissiles = new RCSet <Missile>(); foreach (IMissileData missileData in this.missilesPerShot) { Missile missile = new Missile(missileData, this.owner.Read(), targetEntity); this.owner.Read().Scenario.AddElementToScenario(missile); launchedMissiles.Add(missile); } /// Subscribe to missile events and register the group of the launched missiles. foreach (Missile missile in launchedMissiles) { missile.LaunchCancel += this.OnMissileLaunchCancel; missile.Launch += this.OnMissileLaunch; missile.Impact += this.OnMissileImpact; this.missileGroups.Add(missile, launchedMissiles); } return(true); }
private void Form1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right && this.currentMode == Mode.None) { this.beginPos = new RCNumVector(e.X, e.Y); this.currentPos = new RCNumVector(e.X, e.Y); this.currentMode = Mode.Creating; } else if (e.Button == MouseButtons.Left && this.currentMode == Mode.None) { this.beginPos = new RCNumVector(e.X, e.Y); this.currentPos = new RCNumVector(e.X, e.Y); this.stopwatch.Reset(); this.stopwatch.Start(); RCSet <TestContent> draggedContents = this.contentManager.GetContents(this.beginPos); this.stopwatch.Stop(); this.avgGetContentAtPos.NewItem((int)this.stopwatch.ElapsedMilliseconds); bool isDragging = false; foreach (TestContent item in draggedContents) { if (this.selectedContents.Contains(item)) { isDragging = true; break; } } this.currentMode = isDragging ? Mode.Dragging : Mode.Selecting; } }
/// <summary> /// Searches the entities that are in a rectangular area around the owner entity with the given radius. /// </summary> /// <param name="searchAreaRadius">The radius of the search area given in quadratic tiles.</param> /// <returns>The entities that are in the search area.</returns> public RCSet <Entity> SearchNearbyEntities(int searchAreaRadius) { RCSet <Entity> nearbyEntities = this.owner.Read().Scenario.GetElementsOnMap <Entity>(this.owner.Read().MotionControl.PositionVector.Read(), searchAreaRadius, MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects); nearbyEntities.Remove(this.owner.Read()); return(nearbyEntities); }