/// <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); }
/// <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! } }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <Entity> entitiesToHandle, RCSet <Entity> fullEntitySet, string parameter) { if (entitiesToHandle.Count != 1) { return(AvailabilityEnum.Unavailable); } Entity producerEntity = entitiesToHandle.First(); return(producerEntity.Biometrics.IsUnderConstruction ? AvailabilityEnum.Enabled : AvailabilityEnum.Unavailable); }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <Entity> entitiesToHandle, RCSet <Entity> fullEntitySet, string parameter) { if (entitiesToHandle.Count != 1) { return(AvailabilityEnum.Unavailable); } Entity producerEntity = entitiesToHandle.First(); return(producerEntity.ActiveProductionLine != null ? AvailabilityEnum.Enabled : AvailabilityEnum.Unavailable); }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <Entity> entitiesToHandle, RCSet <Entity> fullEntitySet, string parameter) { if (entitiesToHandle.Count != 1) { return(AvailabilityEnum.Unavailable); } Entity recipientEntity = entitiesToHandle.First(); return(!recipientEntity.Biometrics.IsUnderConstruction && recipientEntity.MotionControl.IsFlying && recipientEntity.ActiveProductionLine == null ? AvailabilityEnum.Enabled : AvailabilityEnum.Unavailable); }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <Entity> entitiesToHandle, RCSet <Entity> fullEntitySet, string parameter) { if (!this.productTypes.Contains(parameter)) { return(AvailabilityEnum.Unavailable); } if (entitiesToHandle.Count != 1) { return(AvailabilityEnum.Unavailable); } Entity producerEntity = entitiesToHandle.First(); if (!producerEntity.IsProductAvailable(parameter)) { return(AvailabilityEnum.Unavailable); } return(producerEntity.IsProductEnabled(parameter) ? AvailabilityEnum.Enabled : AvailabilityEnum.Disabled); }
/// <see cref="CommandExecutionFactoryBase.GetCommandAvailability"/> protected override AvailabilityEnum GetCommandAvailability(RCSet <T> entitiesToHandle, RCSet <Entity> fullEntitySet, string parameter) { /// Check if all the entities to handle are owned by the same player. Player owner = entitiesToHandle.First().Owner; if (entitiesToHandle.Any(entity => entity.Owner != owner)) { throw new InvalidOperationException("Entities with different player sent to SpecialAbilityExecutionFactory!"); } /// If the entities to handle are neutral -> the command is unavailable. if (owner == null) { return(AvailabilityEnum.Unavailable); } /// Enable the special ability execution if the owner player has the necessary research. return(owner.GetUpgradeStatus(this.CommandType) == UpgradeStatus.Researched ? AvailabilityEnum.Enabled : AvailabilityEnum.Disabled); }
/// <see cref="CommandExecutionFactoryBase.CreateCommandExecutions"/> protected override IEnumerable <CmdExecutionBase> CreateCommandExecutions(RCSet <Entity> entitiesToHandle, RCSet <Entity> fullEntitySet, RCNumVector targetPosition, int targetEntityID, string parameter) { Entity recipientEntity = entitiesToHandle.First(); switch (this.commandType) { case DefenseCommandEnum.Stop: return(new List <CmdExecutionBase> { new DefensiveStopExecution(recipientEntity) }); case DefenseCommandEnum.Attack: return(new List <CmdExecutionBase> { new DefensiveAttackExecution(recipientEntity, targetEntityID) }); default: return(new List <CmdExecutionBase> { new DefensiveAttackExecution(recipientEntity, targetEntityID) }); } }
/// <summary> /// Checks the availability of the Build command for the given SCVs. /// </summary> /// <param name="scvsToHandle">The SCVs to check.</param> /// <param name="fullEntitySet">The set of selected entities.</param> /// <param name="buildingTypeName">The name of the type of the building or null if no building is specified.</param> /// <returns>The availability of the Build command for the given SCVs.</returns> private AvailabilityEnum CheckBuildAvailability(RCSet <SCV> scvsToHandle, RCSet <Entity> fullEntitySet, string buildingTypeName) { if (scvsToHandle.Count != fullEntitySet.Count || scvsToHandle.Count != 1) { return(AvailabilityEnum.Unavailable); } /// If the selected SCV is currently constructing -> unavailable. SCV scv = scvsToHandle.First(); if (scv.IsConstructing) { return(AvailabilityEnum.Unavailable); } /// If building type is not specified -> it is the parent build button availability check -> enable. if (buildingTypeName == null) { return(AvailabilityEnum.Enabled); } /// Check the requirements of the building. IBuildingType buildingType = scv.Owner.Metadata.GetBuildingType(buildingTypeName); foreach (IRequirement requirement in buildingType.Requirements) { if (!scv.Owner.HasBuilding(requirement.RequiredBuildingType.Name)) { return(AvailabilityEnum.Disabled); } if (requirement.RequiredAddonType != null && !scv.Owner.HasAddon(requirement.RequiredAddonType.Name)) { return(AvailabilityEnum.Disabled); } } return(AvailabilityEnum.Enabled); }
/// <summary> /// Creates repair executions for the given SCVs. /// </summary> /// <param name="scvsToHandle">The reapiring SCVs.</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> CreateRepairExecutions(RCSet <SCV> scvsToHandle, RCNumVector targetPosition, int targetEntityID) { MagicBox magicBox = new MagicBox(new RCSet <Entity>(scvsToHandle), targetPosition); Entity targetEntity = scvsToHandle.First().Scenario.GetElementOnMap <Entity>(targetEntityID, MapObjectLayerEnum.GroundObjects, MapObjectLayerEnum.AirObjects); if (targetEntity == null) { /// If there is no target entity -> create simple move executions. foreach (SCV scv in scvsToHandle.Where(scv => !scv.IsConstructing)) { yield return(new MoveExecution(scv, magicBox.GetTargetPosition(scv), targetEntityID)); } } /// Create the repair command executions if the target is valid for a repair command. if (this.IsValidTargetForRepair(targetEntity)) { foreach (SCV scv in scvsToHandle.Where(scv => !scv.IsConstructing)) { yield return(new SCVRepairExecution(scv, targetPosition, targetEntityID)); } } }