Example #1
0
        /// <summary>
        /// Populates the NeedGroupUIs with all the needed elements
        /// </summary>
        public void DisplayObjects()
        {
            if (lastShownMapElement != selectedMapElement)
            {
                lastShownMapElement = selectedMapElement;

                List <PropertyOwnership> needs = selectedMapElement.propertyManager.GetPropertiesWithPriority(Property.NeedPriority.None);

                if (needs == null)
                {
                    return;
                }

                Debug.Log($"Setting up UI for group of needs (Properties) with length {needs.Count}:\n    ● {needs.ToStringAllElements("\n    ● ")}\n", gameObject);

                // Instantiate missing UI elements
                int missingUIElements = needs.Count - propertyUIs.Count;
                for (int e = 0; e < missingUIElements; e++)
                {
                    GameObject spawnedPropertyUI = Instantiate(propertyUIPrefab, propertiesArea.transform);
                    PropertyUI propertyUI        = spawnedPropertyUI.GetComponentRequired <PropertyUI>();
                    propertyUIs.Add(propertyUI);
                }

                // Configure the UI elements
                for (int e = 0; e < propertyUIs.Count; e++)
                {
                    PropertyOwnership propertyOwnershipToDisplay = needs.Count > e ? needs[e] : null;
                    propertyUIs[e].Setup(propertyOwnershipToDisplay);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Displays the given Property as the objective in the UI
        /// </summary>
        /// <param name="newObjectiveProperty">The PropertyOwnership that is the objective Property to display in the UI.</param>
        public void DisplayObjectiveProperty(PropertyOwnership newObjectiveProperty)
        {
            bool showObjectivePropertyUI = newObjectiveProperty != null;

            objectivePropertyUI.gameObject.SetActive(showObjectivePropertyUI);
            if (showObjectivePropertyUI)
            {
                objectivePropertyUI.Setup(newObjectiveProperty);
            }
        }
        public PropertyOwnershipViewModel(PropertyOwnership entity, Action <PropertyOwnershipViewModel> act = null)
        {
            if (entity == null)
            {
                return;
            }

            Entity = entity;
            act?.Invoke(this);
        }
Example #4
0
        /// <summary>
        /// Displays the given Property in the UI. Disables the GameObject if the Property is null.
        /// </summary>
        /// <param name="propertyOwnershipp">The PropertyOwnership to display in the UI.</param>
        public void Setup(PropertyOwnership propertyOwnership)
        {
            bool display = propertyOwnership != null;

            gameObject.SetActive(display);

            this.propertyOwnership = propertyOwnership;

            if (display)
            {
                propertyName.text = propertyOwnership.property.name;
            }
        }
Example #5
0
        /// <summary>
        /// Indicates if the consequences of the execution of this event will increase the value of an property owned by a map element.
        /// </summary>
        /// <param name="propertyOwnershipToCover">PropertyOwnership to cover.</param>
        /// <param name="executer">The MapElement that is going to execute/trigger the event.</param>
        /// <param name="target">The MapElement target of the execution of the event.</param>
        /// <param name="owner">The MapElement that owns the event.</param>
        /// <param name="containerProperty">The Property containing the MapEvent</param>
        /// <returns>True, if the execution of this MapEvent with this target, executer and owner would increase the value of the given property. False, otherwise.</returns>
        public bool ConsequencesCover(PropertyOwnership propertyOwnershipToCover, MapElement target, MapElement executer, MapElement owner, Property containerProperty)
        {
            bool consequenceCoversOwnerOfProperty = false;

            // Debug.Log($"$$$$$ Checking if consequences of '{name}' cover '{propertyOwnershipToCover.property}'. target = {target}, executer = {executer}, owner = {owner}\n");
            foreach (Consequence consequence in consequences)
            {
                // Debug.Log($"    $$$$$ Current consequence's property = '{consequence.property}'. Delta value = {consequence.deltaValue}. Covers desired property? {(consequence.property == propertyOwnershipToCover.property && consequence.deltaValue > 0)}\n");
                if (consequence.GetProperty(containerProperty) == propertyOwnershipToCover.property && consequence.deltaValue > 0)
                {
                    switch (consequence.affectedMapElement)
                    {
                    case AffectedMapElement.eventOwner:
                        consequenceCoversOwnerOfProperty = propertyOwnershipToCover.owner == owner;
                        break;

                    case AffectedMapElement.eventExecuter:
                        consequenceCoversOwnerOfProperty = propertyOwnershipToCover.owner == executer;
                        break;

                    case AffectedMapElement.eventTarget:
                        consequenceCoversOwnerOfProperty = propertyOwnershipToCover.owner == target;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    if (consequenceCoversOwnerOfProperty)
                    {
                        if (consequence.affectedMapElement == AffectedMapElement.eventTarget)
                        {
                            // The 'target' must not be the 'executer' neither the 'owner'
                            if (target == executer || target == owner)
                            {
                                return(false);
                            }
                            return(true);
                        }
                        else
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Example #6
0
        /// <summary>
        /// Returns a list of the requirements that are not met at the moment to execute the event, it and outputs a list of the value missing for each one of the requirements that are not met (in the same order).
        /// </summary>
        /// <param name="containerProperty">The Property containing the MapEvent</param>
        /// <param name="executer">The MapElement that is going to execute/trigger the event.</param>
        /// <param name="target">The MapElement target of the execution of the event.</param>
        /// <param name="owner">The MapElement that owns the event.</param>
        /// <param name="executionTimes">The amount of times that is desired to execute the event.</param>
        /// <returns>A list of the requirements that are not met at the moment to execute the event (the keys), each one of them related to the value missing (value to cover)</returns>
        public Dictionary <PropertyOwnership, float> GetRequirementsNotMet(Property containerProperty, MapElement executer, MapElement target, MapElement owner, int executionTimes)
        {
            Dictionary <PropertyOwnership, float> requirementsNotMet = new Dictionary <PropertyOwnership, float>();

            foreach (Requirement requirement in requirements)
            {
                //if (requirement.property == null)
                //    Debug.LogWarning($"Found a requirement without a property linked to it. Requirement: {requirement.ToString()}");
                //OwnedProperty propertyThatMostCloselyMeetsTheRequirement;
                float remainingValueToCoverRequirementNotMet;
                bool  meets = true;

                switch (requirement.affectedMapElement)
                {
                case AffectedMapElement.eventOwner:
                    meets = owner.propertyManager.CanCover(containerProperty, requirement, executionTimes, out remainingValueToCoverRequirementNotMet);
                    if (!meets)
                    {
                        PropertyOwnership req = (owner.propertyManager.GetOwnedPropertyAndAddItIfNotFound(requirement.GetProperty(containerProperty)));
                        requirementsNotMet.Add(req, remainingValueToCoverRequirementNotMet);
                    }
                    break;

                case AffectedMapElement.eventExecuter:
                    meets = executer.propertyManager.CanCover(containerProperty, requirement, executionTimes, out remainingValueToCoverRequirementNotMet);
                    if (!meets)
                    {
                        PropertyOwnership req = (executer.propertyManager.GetOwnedPropertyAndAddItIfNotFound(requirement.GetProperty(containerProperty)));
                        requirementsNotMet.Add(req, remainingValueToCoverRequirementNotMet);
                    }
                    break;

                case AffectedMapElement.eventTarget:
                    meets = target.propertyManager.CanCover(containerProperty, requirement, executionTimes, out remainingValueToCoverRequirementNotMet);
                    if (!meets)
                    {
                        PropertyOwnership req = (target.propertyManager.GetOwnedPropertyAndAddItIfNotFound(requirement.GetProperty(containerProperty)));
                        requirementsNotMet.Add(req, remainingValueToCoverRequirementNotMet);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(requirementsNotMet);
        }
Example #7
0
        /// <summary>
        /// Recursively look for all MapEvents available in the game's map that, as consequence of the event, they make a desired property value increase for the owner/executer/target (the needed participant).
        /// </summary>
        /// <param name="propertyOwnershipToCover">PropertyOwnership to increase the value of.</param>
        /// <param name="valueToCover">The amount of value needed to be covered (increased).</param>
        /// <param name="executer">Map element that is going to execute the list of ExecutionPlans.</param>
        /// <param name="mapEventsToExecute">Execution plans wanted to be executed previously to the ones to cover the propertyToCover.</param>
        /// <param name="iteration">The iteration number of the this method's recursive execution. Should start as 0.</param>
        /// <returns>An ordered list of the Execution Plans needed to achieve the goal (to increase the value of the propertyToCover by valueToCover)</returns>
        public List<ExecutionPlan> GetExecutionPlanToCover(PropertyOwnership propertyOwnershipToCover, float valueToCover, MapElement executer, List<ExecutionPlan> mapEventsToExecute = null, int iteration = 0)
        {
            if (iteration >= 50)
            {
                Debug.LogWarning($" ◙ Stopping the search of an execution plan to cover '{valueToCover}' of '{propertyOwnershipToCover.property}' after {iteration} iterations.\n");
                mapEventsToExecute.DebugLog("\n - ", " ◙ So far, the execution path found was: \n");
                return null;
            }
            
            Debug.Log($" ◌ Searching for an execution plan to cover '{valueToCover}' of '{propertyOwnershipToCover.property}' owned by '{propertyOwnershipToCover.owner}' executed by '{executer}'.    Iteration {iteration}.\n");
            
            if (mapEventsToExecute == null) 
                mapEventsToExecute = new List<ExecutionPlan>();

            ExecutionPlan lastExecutionPlan = mapManager.GetExecutionPlanToCover(propertyOwnershipToCover, valueToCover, executer);
            
            //if (lastExecutionPlan != null) Debug.Log($" ◍ Execution plan for covering '{ownedProperty.property}' in '{ownedProperty.ownerMapElement}' is -> {lastExecutionPlan}\n");
            //else Debug.LogWarning($" ◍ No execution plan for covering '{ownedProperty.property}' in '{ownedProperty.ownerMapElement}' could be found using the 'Map.GetExecutionPlanToTakeCareOf()'.\n");
            //Debug.Log($" ◍ Found Execution Plan: {lastExecutionPlan}\n");
            if (lastExecutionPlan != null)
            {
                mapEventsToExecute.Add(lastExecutionPlan);

                Dictionary<PropertyOwnership, float> requirementsNotMet = lastExecutionPlan.GetRequirementsNotMet();
                if (!requirementsNotMet.IsNullOrEmpty())
                {
                    KeyValuePair<PropertyOwnership, float> reqNotMet = requirementsNotMet.ElementAt(0);
                    mapEventsToExecute = GetExecutionPlanToCover(reqNotMet.Key, reqNotMet.Value, executer, mapEventsToExecute, iteration+1);
                }
            }
            else
            {
                Debug.LogWarning($" ◙ An execution plan to cover '{valueToCover}' of '{propertyOwnershipToCover.property}' was not found (at the iteration: {iteration}).   The previously found execution plans were:\n    ● {mapEventsToExecute.ToStringAllElements("\n    ● ")}\n", gameObject);
                return null;
            }

            return mapEventsToExecute;
        }
Example #8
0
        /// <summary>
        /// Look for all MapEvents available in the map that, as consequence of a MapEvent in an Property they own, they make a desired PropertyOwnership's value increase for the owner/executer/target (the needed participant).
        /// </summary>
        /// <param name="propertyOwnershipToCoverr"> The PropertyOwnership to increase the value of.</param>
        /// <param name="valueToCover">The amount of value needed to be covered (increased).</param>
        /// <param name="executer">Map element that is going to execute the ExecutionPlan.</param>
        /// <returns>The Execution Plan needed to achieve the goal (to increase the value of the propertyToCover by valueToCover)</returns>
        public ExecutionPlan GetExecutionPlanToCover([NotNull] PropertyOwnership propertyOwnershipToCover, float valueToCover, MapElement executer)
        {
            ExecutionPlan foundExecutionPlan = null;

            //Trying to cover with an property/mapEvent in the target
            foundExecutionPlan = propertyOwnershipToCover.owner.propertyManager.GetExecutionPlanToCover(propertyOwnershipToCover, valueToCover, executer);

            //Trying to cover with an property/mapEvent in the caregiver/executer
            if (foundExecutionPlan == null)
            {
                foundExecutionPlan = executer.propertyManager.GetExecutionPlanToCover(propertyOwnershipToCover, valueToCover, executer);
            }

            //Trying to cover with an property/mapEvent in any map element
            if (foundExecutionPlan == null)
            {
                List <MapElement> alreadyScanned = new List <MapElement>();
                while (alreadyScanned.Count < existentMapElements.Count)
                {
                    MapElement    scanning      = GetClosestMapElementTo(propertyOwnershipToCover.owner.transform.position, alreadyScanned);
                    ExecutionPlan foundMapEvent = scanning.propertyManager.GetExecutionPlanToCover(propertyOwnershipToCover, valueToCover, executer);
                    if (foundMapEvent != null)
                    {
                        return(foundMapEvent);
                    }
                    else
                    {
                        alreadyScanned.Add(scanning);
                        // Todo: Do something to delay the process and reduce the load on the CPU due to the search with sorting by proximity
                        //Wait(30f/existentMapElements.Count); // Para que siempre, si tuviera que pensar en TODOS los MapELements del mapa, tardaria 30s en pensarselo indiferentemente de la cantidad de MapElements existentes
                    }
                }
            }

            return(foundExecutionPlan);
        }
Example #9
0
 void Start()
 {
     Instance = this;
 }
Example #10
0
 /// <summary>
 /// Sets the amount of times remaining to execute this plan's MapEvent to the same amount needed to to cover a given property (to increase its value a defined amount).
 /// </summary>
 /// <param name="propertyOwnershipToCoverr">PropertyOwnership that is desired to cover (to increase its value in the MapElement's PropertyManager)</param>
 /// <param name="remainingValueToCover">The remaining value to cover for the given Property.</param>
 public void SetExecutionTimesToCover(PropertyOwnership propertyOwnershipToCover, float remainingValueToCover)
 {
     this.executionTimes = CalculateExecutionsNeededToCover(propertyOwnershipToCover, remainingValueToCover);
 }
Example #11
0
        /// <summary>
        /// Calculates the amount of times that the execution of this ExecutionPlan's MapElement is needed to cover a given property (to increase its value a defined amount).
        /// </summary>
        /// <param name="propertyOwnershipToCover">PropertyOwnership that is desired to cover (to increase its value in the MapElement's PropertyManager)</param>
        /// <param name="remainingValueToCover">The remaining value to cover for the given Property.</param>
        /// <returns></returns>
        private int CalculateExecutionsNeededToCover(PropertyOwnership propertyOwnershipToCover, float remainingValueToCover)
        {
            float coveredPerExecution = 0;

            //Debug.LogWarning($"Calculating how many times '{this.mapEvent}' must be executed to cover '{ownedPropertyToCover.property}'...");

            foreach (Consequence consequence in mapEvent.consequences)
            {
                //Debug.Log($"CHECKING {consequence.property} against {ownedPropertyToCover.property}");
                if (consequence.GetProperty(this.property) == propertyOwnershipToCover.property)
                {
                    switch (consequence.affectedMapElement)
                    {
                    case AffectedMapElement.eventOwner:
                        if (this.eventOwner == propertyOwnershipToCover.owner)
                        {
                            coveredPerExecution += consequence.deltaValue;
                        }

                        break;

                    case AffectedMapElement.eventExecuter:
                        if (this.executer == propertyOwnershipToCover.owner)
                        {
                            coveredPerExecution += consequence.deltaValue;
                        }

                        break;

                    case AffectedMapElement.eventTarget:
                        if (this.target == propertyOwnershipToCover.owner)
                        {
                            coveredPerExecution += consequence.deltaValue;
                        }

                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
            int result = -1;

            if (coveredPerExecution > 0)
            {
                result = (int)Math.Ceiling(((double)remainingValueToCover) / ((double)coveredPerExecution));
            }

            //Debug.LogWarning($"It needs to be executed {result} times to cover {remainingValueToCover} of remaining value. It covers {coveredPerExecution} per execution.");

            if (coveredPerExecution >= remainingValueToCover)
            {
                return(1);
            }

            if (coveredPerExecution > 0)
            {
                return(result);
            }

            // Debug.LogWarning($"'{this}' can not cover '{ownedPropertyToCover}'.");
            return(-1);
        }