/// <summary> /// Creates and activates a NPCUnitRegulator instance for a unit prefab. /// </summary> /// <param name="unit">The <c>Unit</c> prefab for which NPCUnitRegulator instance will be created.</param> /// <returns>The created and active NPCUnitRegulator instance.</returns> public NPCUnitRegulator ActivateUnitRegulator(Unit unit) { NPCUnitRegulatorData data = unit.GetRegulatorData(factionMgr.Slot.GetTypeInfo(), npcMgr.NPCType.GetCode()); //get the regulator data if (data == null) //invalid regulator data? { return(null); //do not proceed } //see if the unit regulator is already active or not NPCUnitRegulator activeInstance = GetActiveUnitRegulator(unit.GetCode()); if (activeInstance != null) //if it is { return(activeInstance); //return the already active instance. } ActiveUnitRegulator newUnitRegulator = new ActiveUnitRegulator() { //create new instance instance = new NPCUnitRegulator(data, unit, gameMgr, npcMgr, this), //initial spawning timer: regular spawn reload + start creating after value spawnTimer = data.GetCreationDelayTime() }; //add it to the active unit regulators list: activeUnitRegulators.Add(unit.GetCode(), newUnitRegulator); //whenever a new regulator is added to the active regulators list, then move the unit creator into the active state Activate(); return(newUnitRegulator.instance); }
//a method to add a new instance of a unit regulator public NPCUnitRegulator ActivateUnitRegulator(NPCUnitRegulator unitRegulator) { //see if the unit regulator is already active or not ActiveUnitRegulator aue = IsUnitRegulatorActive(unitRegulator); if (aue != null) //if it is { return(aue.instance); //return the already active instance. } //default ActiveUnitRegulator newUnitRegulator = new ActiveUnitRegulator() { //create new instance instance = Instantiate(unitRegulator), source = unitRegulator, //set the prefab/resource //initial spawning timer: regular spawn reload + start creating after value spawnTimer = unitRegulator.spawnReloadRange.getRandomValue() + unitRegulator.startCreatingAfter.getRandomValue() }; //add it to the active unit regulators list: activeUnitRegulators.Add(newUnitRegulator); newUnitRegulator.instance.Init(npcMgr, this); //initialize the unit regulator. //whenever a new regulator is added to the active regulators list, then move the unit creator into the active state isActive = true; return(newUnitRegulator.instance); }
//method that attempts to create the unit from a regulator public void OnCreateUnitRequest(NPCUnitRegulator instance, bool auto, int maxAmount) { //if this attempt is done automatically (from the NPC Unit Creator itself) and the regulator doesn't allow it if (auto == true && instance.autoCreate == false) { return; //do not proceed. } //if this has been requested from another NPC component and the regulator doesn't allow it if (auto == false && instance.createOnDemand == false) { return; //do not proceed. } int createAmount = maxAmount; //this will be the amount that we aim to spawn if (!instance.HasReachedMaxAmount() && createAmount > 0) //as long as we haven't reached the max amount { if (instance.GetUnitCreatorList().Count > 0) //if there are task launchers assigned to this regulator: { //go through the task launchers that this unit regulator uses: foreach (NPCUnitRegulator.UnitCreatorInfo uci in instance.GetUnitCreatorList()) { TaskManager.AddTaskMsg addTaskMsg = TaskManager.AddTaskMsg.Success; //as long as launching the unit creation task is successful and we still have units to create while (addTaskMsg == TaskManager.AddTaskMsg.Success && createAmount > 0) { addTaskMsg = taskMgr.AddTask(uci.taskLauncher, uci.taskID, TaskManager.TaskTypes.CreateUnit); //handle cases: switch (addTaskMsg) { case TaskManager.AddTaskMsg.Success: //in case of success createAmount--; //decrease amount required break; case TaskManager.AddTaskMsg.MaxPopulationReached: //in case of failure due to max population reach. //ask the NPC population manager to add a new population building and stop the whole process: npcMgr.populationManager_NPC.OnAddPopulationRequest(); return; default: break; //FUTURE FEATURE: HANLDE OTHER FAILURE MESSAGES SUCH AS: sending builders to fix low health buildings, //... or asking resource manager to collect resource in case of missing resource. } } //as soon we create all the required units then stop this whole thing: if (createAmount == 0) { return; } } } else { //FUTURE FEATURE: Communicate with the NPC Building Creator in order to ask to spawn one of the task launchers. } } }
public bool isActive = true; //is this component active? void Start() { //activate the collector unit regulator: collectorRegulatorIns = npcMgr.unitCreator_NPC.ActivateUnitRegulator(collectorRegulator); //start collection timer: collectionTimer = collectionTimerRange.getRandomValue(); //add event listeners: CustomEvents.UnitStopCollecting += OnUnitStopCollecting; CustomEvents.UnitStartCollecting += OnUnitStartCollecting; CustomEvents.ResourceEmpty += OnResourceEmpty; CustomEvents.UnitCreated += OnUnitCreated; }
//a method to check if a unit regulator is already active or not. public ActiveUnitRegulator IsUnitRegulatorActive(NPCUnitRegulator unitRegulator) { //go through all active unit regulators: foreach (ActiveUnitRegulator aur in activeUnitRegulators) { if (aur.source == unitRegulator) //if the source matches the input unit regulator { //then return this active unit regulator. return(aur); } } return(null); }
//activates the collector regulator public void ActivateCollectorRegulator() { //Go ahead and add the builder regulator (if there's one).. if (collectorRegulator != null) { //.. to the NPC Unit Creator component collectorRegulatorIns = npcMgr.unitCreator_NPC.ActivateUnitRegulator(collectorRegulator); } else { //Error to user, because builder regulator hasn't been assigned and it is required: Debug.LogError("[NPC Resource Collector] NPC Faction ID: " + factionMgr.FactionID + " NPC Resource Collector component doesn't have a collector regulator assigned!"); } }
//a method that removes one active instance by providing its source/prefab regulator: public void DestroyActiveRegulator(NPCUnitRegulator nur) { //go through the active regulators for (int i = 0; i < activeUnitRegulators.Count; i++) { //if this is the building regulator we're looking for: ActiveUnitRegulator aur = activeUnitRegulators[i]; if (nur == aur.source) { //destroy the active instance: Destroy(aur.instance); //remove from list: activeUnitRegulators.RemoveAt(i); break; //leave loop } } }
//a method called that configures NPC faction components in case of a unit upgrade: private void LaunchNPCUnitUpgrade(NPCManager npcMgrIns, Unit source, Unit target) { //we need access to the NPC Unit Creator in order to find the active regulator instance that manages the unit type to be upgraded: NPCUnitCreator unitCreator_NPC = npcMgrIns.unitCreator_NPC; NPCUnitRegulator unitRegulator = npcMgrIns.GetUnitRegulatorAsset(source); //will hold the unit's regulator that is supposed to be upgraded. NPCUnitRegulator targetUnitRegulator = npcMgrIns.GetUnitRegulatorAsset(target);; //will hold the target unit's regulator //we expect both above regulators to be valid: if (unitRegulator == null) { Debug.LogError("[Upgrade Manager] Can not find a valid NPC Unit Regulator for the upgrade source."); return; } if (targetUnitRegulator == null) { Debug.LogError("[Upgrade Manager] Can not find a valid NPC Unit Regulator for the upgrade target."); return; } //destroy the old building regulator unitCreator_NPC.DestroyActiveRegulator(unitRegulator); //if the unit to be upgraded was either, the main builder, collector or one of the army units //then we'll update that as well. if (unitRegulator == npcMgrIns.buildingConstructor_NPC.builderRegulator) { npcMgrIns.buildingConstructor_NPC.builderRegulator = unitRegulator; npcMgrIns.buildingConstructor_NPC.ActivateBuilderRegulator(); //activate the new unit regulator } if (unitRegulator == npcMgrIns.resourceCollector_NPC.collectorRegulator) { npcMgrIns.resourceCollector_NPC.collectorRegulator = unitRegulator; npcMgrIns.resourceCollector_NPC.ActivateCollectorRegulator(); //activate the new unit regulator } if (npcMgrIns.armyCreator_NPC.armyUnitRegulators.Contains(unitRegulator)) //is the unit to upgrade an army unit? { npcMgrIns.armyCreator_NPC.armyUnitRegulators.Remove(unitRegulator); //remove old regulator from list npcMgrIns.armyCreator_NPC.armyUnitRegulators.Add(targetUnitRegulator); //add new regulator asset npcMgrIns.armyCreator_NPC.ActivateArmyUnitRegulators(); //activate army regulators. } //activate the new regulator: unitCreator_NPC.ActivateUnitRegulator(targetUnitRegulator); }
void Start() { //Go ahead and add the builder regulator (if there's one).. if (builderRegulator != null) { //.. to the NPC Unit Creator component builderRegulatorIns = npcMgr.unitCreator_NPC.ActivateUnitRegulator(builderRegulator); } else { //Error to user, because builder regulator hasn't been assigned and it is required: Debug.LogError("NPC Faction ID: " + factionMgr.FactionID + " NPC Building Constructor component doesn't have a builder regulator assigned!"); } //add event listeners for following delegate events: CustomEvents.BuildingPlaced += OnBuildingPlaced; CustomEvents.BuildingHealthUpdated += OnBuildingHealthUpdated; }
/// <summary> /// Activates the main NPCUnitRegulator instance for the main builder unit. /// </summary> private void ActivateBuilderRegulator() { builderMonitor.Init(factionMgr); //Go ahead and add the builder regulator (if there's one).. foreach (Builder builder in builders) { Assert.IsNotNull(builder, $"[NPCBuildingConstructor] NPC Faction ID: {factionMgr.FactionID} 'Builders' list has some unassigned elements."); NPCUnitRegulator nextRegulator = null; //as soon a builder prefab produces a valid builder regulator instance (matches the faction type and faction npc manager), add it to be monitored: if ((nextRegulator = npcMgr.GetNPCComp <NPCUnitCreator>().ActivateUnitRegulator(builder.GetComponent <Unit>())) != null) { builderMonitor.Replace("", nextRegulator.Code); } } Assert.IsTrue(builderMonitor.GetCount() > 0, $"[NPCBuildingConstructor] NPC Faction ID: {factionMgr.FactionID} doesn't have a builder regulator assigned!"); }
/// <summary> /// Activates the NPCUnitRegulator instances for the NPC faction's army units. /// </summary> public void ActivateArmyUnitRegulators() { armyUnitsMonitor.Init(factionMgr); //Go ahead and add the army units regulators (if there are valid ones) foreach (UnitAttack armyUnit in armyUnits) { Assert.IsNotNull(armyUnit, $"[NPCArmyCreator] NPC Faction ID: {factionMgr.FactionID} 'Army Unit' list has some unassigned elements."); NPCUnitRegulator nextRegulator = null; //only add the army unit regulators that match this NPC faction's type if ((nextRegulator = npcMgr.GetNPCComp <NPCUnitCreator>().ActivateUnitRegulator(armyUnit.GetComponent <Unit>())) != null) { armyUnitsMonitor.Replace("", nextRegulator.Code); } } Assert.IsTrue(armyUnitsMonitor.GetCount() > 0, $"[NPCArmyCreator] NPC Faction ID: {factionMgr.FactionID} doesn't have any active NPCUnitRegulator instance for army units!"); }
/// <summary> /// Activates the main NPCUnitRegulator instance for the main resource collector unit. /// </summary> /// <param name="resourceType"></param> /// <param name="collectorMonitor"></param> private void ActivateCollectorRegulator(ResourceTypeInfo resourceType, NPCActiveRegulatorMonitor collectorMonitor) { collectorMonitor.Init(factionMgr); //Go ahead and add the resource collector regulator (if there's one).. foreach (ResourceCollector collector in collectors) { Assert.IsNotNull(collector, $"[NPCResourceCollector] NPC Faction ID: {factionMgr.FactionID} 'Collectors' list has some unassigned elements."); NPCUnitRegulator nextRegulator = null; //as soon a collector prefab produces a valid unit regulator instance (matches the faction type and faction npc manager), add it to monitor component if (collector.CanCollectResourceType(resourceType, false) && //also make sure the resource collector can collect this resource type. (nextRegulator = npcMgr.GetNPCComp <NPCUnitCreator>().ActivateUnitRegulator(collector.GetComponent <Unit>())) != null) { collectorMonitor.Replace("", nextRegulator.Code); } } Assert.IsTrue(collectorMonitor.GetCount() > 0, $"[NPCBuildingConstructor] NPC Faction ID: {factionMgr.FactionID} doesn't have a resource collector regulator assigned for resource type: {resourceType.GetName()}!"); }
/// <summary> /// Actively monitors forced army units creation. /// </summary> protected override void OnActiveUpdate() { base.OnActiveUpdate(); Deactivate(); //go through the active instances of the army unit regulators: foreach (string unitCode in armyUnitsMonitor.GetAll()) { NPCUnitRegulator unitRegulator = npcMgr.GetNPCComp <NPCUnitCreator>().GetActiveUnitRegulator(unitCode); //get the regulator instance for the unit code if (unitRegulator == null) { print(unitCode); } //if the minimum amount hasn't hit the actual max amount if (unitRegulator.MaxAmount > unitRegulator.MinAmount) { Activate(); //keep component active. //increment the minimum amount to put pressure on creating a new instance for the army unit. unitRegulator.IncMinAmount(); } } }
/// <summary> /// Launches the next unit creation task if all requirements are met. /// </summary> /// <param name="instance">The NPCUnitRegulator instance that will be creating the next unit.</param> /// <param name="auto">True if this has been called from the NPCUnitCreator component, false if called from another NPC component.</param> /// <param name="requestedAmount">The amount of unit instances requested to create.</param> public void OnCreateUnitRequest(NPCUnitRegulator instance, bool auto, int requestedAmount) { if (instance == null //if the instance is invalid //if this has been requested from another NPC component and the regulator doesn't allow it || (!auto && !instance.Data.CanCreateOnDemand()) //or if this attempt is done automatically (from the NPC Unit Creator itself) and the regulator doesn't allow it || (auto && !instance.Data.CanAutoCreate()) //if we have raeched the maximum allowed amount or the requested amount is invalid || instance.HasReachedMaxAmount() || requestedAmount <= 0) { return; //do not proceed. } if (instance.GetTaskLauncherCount() == 0) //if there are no task launchers assigned to this regulator: { //FUTURE FEATURE: Communicate with the NPC Building Creator in order to ask to spawn one of the task launchers. return; } //enough task launchers that can create this unit? go through the task launchers that this unit regulator uses: foreach (TaskLauncher taskLauncher in instance.GetTaskLaunchers()) { foreach (int taskID in instance.GetUnitCreationTasks(taskLauncher)) { ErrorMessage addTaskMsg = ErrorMessage.none; //as long as launching the unit creation task is successful and we still have units to create while (addTaskMsg == ErrorMessage.none && requestedAmount > 0) { //attempt to add new unit creation task addTaskMsg = gameMgr.TaskMgr.AddTask(new TaskUIAttributes { taskLauncher = taskLauncher, ID = taskID, type = TaskTypes.createUnit }); //handle cases: switch (addTaskMsg) { case ErrorMessage.none: //in case of success requestedAmount--; //decrease amount required break; case ErrorMessage.maxPopulationReached: //in case of failure due to max population reach. //ask the NPC population manager to add a new population building and stop the whole process: npcMgr.GetNPCComp <NPCPopulationManager>().OnAddPopulationRequest(false); return; default: break; //FUTURE FEATURE: HANLDE OTHER FAILURE MESSAGES SUCH AS: sending builders to fix low health buildings, //... or asking resource manager to collect resource in case of missing resource. } } //as soon we create all the required units then stop this whole thing: if (requestedAmount == 0) { return; } } } }