Exemple #1
0
        static void fillOutMinimums(List <AbstractActor> units)
        {
            if (units.Count == 0)
            {
                return;
            }

            CombatGameConstants constants = units[0].Combat.Constants;

            // TODO be smarter about doing an assignment based on priority and by fit
            int constrainedMinimumCount = constants.DynamicAIRoleConstants.brawlerMinAbs +
                                          constants.DynamicAIRoleConstants.sniperMinAbs;

            if (units.Count < constrainedMinimumCount)
            {
                // this is where we'd fill out by priority

                for (int i = 0; i < units.Count; ++i)
                {
                    UnitRole role = getRoleByPriorityIndex(constants, i);
                    units[i].DynamicUnitRole = role;
                }
            }
            else
            {
                for (int i = 0; i < constrainedMinimumCount; ++i)
                {
                    UnitRole role = getRoleByPriorityIndex(constants, i);
                    units[i].DynamicUnitRole = role;
                }
            }
        }
Exemple #2
0
 public PrefabGrid(string prefabName, UnitType unitType, UnitRole unitRole)
 {
     PrefabName        = prefabName;
     UnitType          = unitType;
     UnitRole          = unitRole;
     InitialBeaconName = GetBeaconName(unitRole, unitType);
 }
Exemple #3
0
        static Dictionary <UnitRole, int> countRolesAfterAssignment(Dictionary <AbstractActor, UnitRole> unitAssignments, List <AbstractActor> allUnits)
        {
            Dictionary <UnitRole, int> counts = new Dictionary <UnitRole, int>();

            counts[UnitRole.Brawler] = 0;
            counts[UnitRole.Sniper]  = 0;

            for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
            {
                AbstractActor unit = allUnits[unitIndex];
                UnitRole      role = unit.DynamicUnitRole;
                if ((unitAssignments != null) && (unitAssignments.ContainsKey(unit)))
                {
                    role = unitAssignments[unit];
                }
                if (counts.ContainsKey(role))
                {
                    counts[role] += 1;
                }
                else
                {
                    counts[role] = 1;
                }
            }
            return(counts);
        }
Exemple #4
0
        static float getAbstractRoleTagMultiplier(CombatGameState combat, UnitRole role)
        {
            switch (role)
            {
            case UnitRole.Brawler:
                return(combat.Constants.DynamicAIRoleConstants.brawlerTagMultiplier);

            case UnitRole.Sniper:
                return(combat.Constants.DynamicAIRoleConstants.sniperTagMultiplier);

            case UnitRole.Spotter:
                Debug.LogError("spotter is deprecated");
                return(0.0f);

            case UnitRole.Flanker:
                Debug.LogError("flanker is deprecated");
                return(0.0f);

            case UnitRole.Scout:
                Debug.LogError("scouts do not use tag multipliers");
                return(0.0f);

            case UnitRole.LastManStanding:
                Debug.LogError("lastManStanding does not use tag multipliers");
                return(0.0f);

            default:
                Debug.LogError("unexpected role: " + role);
                return(1.0f);
            }
        }
Exemple #5
0
        static float evaluateAssignments(Dictionary <AbstractActor, UnitRole> unitAssignments, List <AbstractActor> allUnits, Dictionary <UnitRoleAssignmentRecord, float> roleAssignmentDictionary)
        {
            float penalty = getLegalTeamCountPenalty(countRolesAfterAssignment(unitAssignments, allUnits), allUnits);

            if (penalty > 0)
            {
                return(-penalty);
            }

            float score = 0.0f;

            for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
            {
                AbstractActor unit = allUnits[unitIndex];
                UnitRole      role = unit.DynamicUnitRole;
                if ((unitAssignments != null) && (unitAssignments.ContainsKey(unit)))
                {
                    role = unitAssignments[unit];
                }

                UnitRoleAssignmentRecord assignmentRecord = new UnitRoleAssignmentRecord(unit, role);
                // might not actually be there, e.g. if the unit is currently unassigned.
                if (roleAssignmentDictionary.ContainsKey(assignmentRecord))
                {
                    score += roleAssignmentDictionary[assignmentRecord];
                }
            }
            return(score);
        }
Exemple #6
0
        public async Task <IActionResult> NewUnit(NewUnitView model, IFormCollection form, CancellationToken cancellationToken)
        {
            model.Types = await _unitsService.GetUnitTypesForDepartmentAsync(DepartmentId);

            model.Stations = await _departmentGroupsService.GetAllStationGroupsForDepartmentAsync(DepartmentId);

            if ((await _unitsService.GetUnitByNameDepartmentIdAsync(DepartmentId, model.Unit.Name)) != null)
            {
                ModelState.AddModelError("Name", "Unit with that name already exists.");
            }

            var unitRoleNames = (from object key in form.Keys where key.ToString().StartsWith("unitRole_") select form[key.ToString()]).ToList();

            if (ModelState.IsValid)
            {
                model.Unit.DepartmentId = DepartmentId;

                if (model.Unit.StationGroupId.HasValue && model.Unit.StationGroupId.Value == 0)
                {
                    model.Unit.StationGroupId = null;
                }

                model.Unit = await _unitsService.SaveUnitAsync(model.Unit, cancellationToken);

                var roles = new List <UnitRole>();
                if (unitRoleNames.Count > 0)
                {
                    foreach (var roleName in unitRoleNames)
                    {
                        var role = new UnitRole();
                        role.Name   = roleName;
                        role.UnitId = model.Unit.UnitId;

                        roles.Add(role);
                    }
                }

                if (roles.Count > 0)
                {
                    await _unitsService.SetRolesForUnitAsync(model.Unit.UnitId, roles, cancellationToken);
                }

                var auditEvent = new AuditEvent();
                auditEvent.DepartmentId = DepartmentId;
                auditEvent.UserId       = UserId;
                auditEvent.Type         = AuditLogTypes.UnitAdded;
                auditEvent.After        = model.Unit.CloneJson();
                _eventAggregator.SendMessage <AuditEvent>(auditEvent);

                _eventAggregator.SendMessage <UnitAddedEvent>(new UnitAddedEvent()
                {
                    DepartmentId = DepartmentId, Unit = model.Unit
                });

                return(RedirectToAction("Index"));
            }

            return(View(model));
        }
Exemple #7
0
 public BehaviorVariableScope GetScopeForRole(UnitRole role)
 {
     if (scopesByRole.ContainsKey(role))
     {
         return(scopesByRole[role]);
     }
     return(null);
 }
Exemple #8
0
        private void GenerateUnit(UnitBuilder unit, UnitRole role, double value, double techProgressionFraction)
        {
            unit.AllocateName(UsedNames);

            unit.VisionRange = UnitVisionRange;

            unit.MoveRange = BaseUnitMoveRange;

            // standard health, armor, mana, cost, supply cost and build time values for its value

            unit.BuildTime = Math.Max(1, Random.Next(value * 0.75, value * 0.95));

            var overallCost = (int)value * Random.Next(25, 40);

            unit.Cost = SplitResourceCosts(overallCost, techProgressionFraction);

            unit.Cost[GameModels.Definitions.ResourceType.Supply] = Math.Max(1, Random.Next(value * 0.75, value * 0.95));

            unit.Health = Random.Next(value * 20, value * 35)
                          .RoundNearest(5);

            unit.Mana = Random.Next(value * 40, value * 60)
                        .RoundNearest(5);

            unit.Armor = Random.Next(value * 0.25, value * 0.9);

            switch (role)
            {
            case UnitRole.AllRounder:
            default:
                unit.Mana = 0;
                GenerateAllRounder(unit, value);
                break;

            case UnitRole.DamageDealer:
                unit.Mana = 0;
                GenerateDamageDealer(unit, value);
                break;

            case UnitRole.Scout:
                unit.Mana = 0;
                GenerateScout(unit, value);
                break;

            case UnitRole.MeatShield:
                unit.Mana = 0;
                GenerateMeatShield(unit, value);
                break;

            case UnitRole.SupportCaster:
                GenerateSupportCaster(unit, value);
                break;

            case UnitRole.OffensiveCaster:
                GenerateOffensiveCaster(unit, value);
                break;
            }
        }
Exemple #9
0
            public ScopeDesc(string name, AIMood mood)
            {
                this.Name          = name;
                this.ScopeKind     = ScopeKind.Global;
                this.UnitRole      = UnitRole.Undefined;
                this.AIPersonality = AIPersonality.Undefined;
                this.AISkillID     = AISkillID.Undefined;
                this.Mood          = mood;

                privateFactionValue = FactionEnumeration.GetInvalidUnsetFactionValue();
                FactionID           = privateFactionValue.Name;
            }
Exemple #10
0
        internal static RoleAndUnitType?GetRoleAndUnitType(IMyCubeGrid grid)
        {
            var slimBlocks = new List <IMySlimBlock>();

            grid.GetBlocks(slimBlocks, b => b.FatBlock is IMyBeacon);
            foreach (var slim in slimBlocks)
            {
                var beacon     = slim.FatBlock as IMyBeacon;
                var beaconName = beacon.CustomName;
//		ModLog.Error("Checking spawn of beacon Name:" + beaconName);

                if (beaconName.Contains(Unitialised))
                {
                    UnitRole ur = UnitRole.Backup;                     // default
                    if (beaconName.Contains(EscortRole))
                    {
                        ur = UnitRole.Escort;
                    }
                    else if (beaconName.Contains(CargoRole))
                    {
                        ur = UnitRole.Delivery;
                    }
                    else if (beaconName.Contains(PoliceRole))
                    {
                        ur = UnitRole.Police;
                    }
                    else if (beaconName.Contains(BackupRole))
                    {
                        ur = UnitRole.Backup;
                    }

                    UnitType ut = UnitType.Air;                     // default;
                    if (beaconName.Contains(UnitTypeSpace))
                    {
                        ut = UnitType.Space;
                    }
                    else if (beaconName.Contains(UnitTypeAir))
                    {
                        ut = UnitType.Air;
                    }
                    else if (beaconName.Contains(UnitTypeGround))
                    {
                        ut = UnitType.Ground;
                    }

                    return(new RoleAndUnitType {
                        UnitRole = ur, UnitType = ut
                    });
                }
            }
            return(null);            // Not one of ours perhaps?
        }
Exemple #11
0
        private static string GetBeaconName(UnitRole unitRole, UnitType unitType)
        {
            string s = Unitialised;

            switch (unitRole)
            {
            case UnitRole.Delivery:
                s += CargoRole;
                break;

            case UnitRole.Escort:
                s += EscortRole;
                break;

            case UnitRole.Backup:
                s += BackupRole;
                break;

            case UnitRole.Police:
                s += PoliceRole;
                break;

            default:
                throw new ArgumentException(unitRole + " not recognised!");
            }
            switch (unitType)
            {
            case UnitType.Air:
                s += UnitTypeAir;
                break;

            case UnitType.Ground:
                s += UnitTypeGround;
                break;

            case UnitType.Space:
                s += UnitTypeSpace;
                break;

            default:
                throw new ArgumentException(unitType + " not recognised!");
            }
//		ModLog.Error("Spawning with beacon Name:" + s);
            return(s);
        }
Exemple #12
0
        static float getRoleTagMultiplierForUnit(AbstractActor unit, UnitRole role)
        {
            bool   match    = false;
            string roleName = ROLE_TAG_PREFIX + role.ToString().ToLower();

            if (unit.GetTags().Contains(roleName))
            {
                match = true;
            }
            Mech mech = unit as Mech;

            if ((mech != null) && (mech.MechDef.MechTags.Contains(roleName)))
            {
                match = true;
            }

            return(match ? getAbstractRoleTagMultiplier(unit.Combat, role) : 1.0f);
        }
Exemple #13
0
        private static string GetBeaconName(UnitRole unitRole, UnitType unitType)
        {
            switch (unitRole)
            {
            case UnitRole.Delivery:
                return(unitType == UnitType.Air ? CargoAir : CargoGround);

            case UnitRole.Escort:
                return(unitType == UnitType.Air ? EscortAir : EscortGround);

            case UnitRole.Backup:
                return(BackupAir);  // Currently all backup is air, ground is tricky to place at random

            case UnitRole.Bomb:     // V26
                return(Bomb);

            default:
                throw new ArgumentException(unitRole + " not recognised!");
            }
        }
Exemple #14
0
        static float EvaluateAssignmentForUnit(AbstractActor unit, UnitRole role)
        {
            if (unit.IsDead)
            {
                return(0.0f);
            }

            switch (role)
            {
            case UnitRole.Brawler: return(1.0f);

            case UnitRole.Sniper: return(EvaluateSniper(unit));

            case UnitRole.Scout: return(0.0f);                    // handled separately

            case UnitRole.LastManStanding: return(0.0f);          // handled separately

            default:
                // don't know what to do with this
                return(0.0f);
            }
        }
Exemple #15
0
        public IActionResult EditUnit(NewUnitView model, IFormCollection form)
        {
            model.Types    = _unitsService.GetUnitTypesForDepartment(DepartmentId);
            model.Stations = _departmentGroupsService.GetAllStationGroupsForDepartment(DepartmentId);

            if (!_authorizationService.CanUserModifyUnit(UserId, model.Unit.UnitId))
            {
                Unauthorized();
            }

            if (_unitsService.GetUnitByNameDepartmentId(DepartmentId, model.Unit.Name) != null && _unitsService.GetUnitByNameDepartmentId(DepartmentId, model.Unit.Name).UnitId != model.Unit.UnitId)
            {
                ModelState.AddModelError("Name", "Unit with that name already exists.");
            }

            var unitRoleNames = (from object key in form.Keys where key.ToString().StartsWith("unitRole_") select form[key.ToString()]).ToList();

            var unit = _unitsService.GetUnitById(model.Unit.UnitId);

            var auditEvent = new AuditEvent();

            auditEvent.DepartmentId = DepartmentId;
            auditEvent.UserId       = UserId;
            auditEvent.Type         = AuditLogTypes.UnitChanged;
            auditEvent.Before       = unit.CloneJson();

            unit.Name = model.Unit.Name;
            unit.Type = model.Unit.Type;

            if (model.Unit.StationGroupId.HasValue && model.Unit.StationGroupId.Value != 0)
            {
                unit.StationGroupId = model.Unit.StationGroupId;
            }
            else
            {
                unit.StationGroupId = null;
            }

            if (ModelState.IsValid)
            {
                _unitsService.SaveUnit(unit);

                var roles = new List <UnitRole>();
                if (unitRoleNames.Count > 0)
                {
                    foreach (var roleName in unitRoleNames)
                    {
                        var role = new UnitRole();
                        role.Name   = roleName;
                        role.UnitId = unit.UnitId;

                        roles.Add(role);
                    }
                }

                if (roles.Count > 0)
                {
                    _unitsService.SetRolesForUnit(unit.UnitId, roles);
                }
                else
                {
                    _unitsService.ClearRolesForUnit(unit.UnitId);
                }

                auditEvent.After = unit.CloneJson();
                _eventAggregator.SendMessage <AuditEvent>(auditEvent);

                return(RedirectToAction("Index"));
            }

            return(View(model));
        }
        private static BehaviorVariableValue GetBehaviorVariableValueDirectly(BehaviorTree bTree, BehaviorVariableName name)
        {
            BehaviorVariableValue behaviorVariableValue = bTree.unitBehaviorVariables.GetVariable(name);

            if (behaviorVariableValue != null)
            {
                return(behaviorVariableValue);
            }

            Pilot pilot = bTree.unit.GetPilot();

            if (pilot != null)
            {
                BehaviorVariableScope scopeForAIPersonality = bTree.unit.Combat.BattleTechGame.BehaviorVariableScopeManager.GetScopeForAIPersonality(pilot.pilotDef.AIPersonality);
                if (scopeForAIPersonality != null)
                {
                    behaviorVariableValue = scopeForAIPersonality.GetVariableWithMood(name, bTree.unit.BehaviorTree.mood);
                    if (behaviorVariableValue != null)
                    {
                        return(behaviorVariableValue);
                    }
                }
            }

            if (bTree.unit.lance != null)
            {
                behaviorVariableValue = bTree.unit.lance.BehaviorVariables.GetVariable(name);
                if (behaviorVariableValue != null)
                {
                    return(behaviorVariableValue);
                }
            }

            if (bTree.unit.team != null)
            {
                Traverse bvT = Traverse.Create(bTree.unit.team).Field("BehaviorVariables");
                BehaviorVariableScope bvs = bvT.GetValue <BehaviorVariableScope>();
                behaviorVariableValue = bvs.GetVariable(name);
                if (behaviorVariableValue != null)
                {
                    return(behaviorVariableValue);
                }
            }

            UnitRole unitRole = bTree.unit.DynamicUnitRole;

            if (unitRole == UnitRole.Undefined)
            {
                unitRole = bTree.unit.StaticUnitRole;
            }

            BehaviorVariableScope scopeForRole = bTree.unit.Combat.BattleTechGame.BehaviorVariableScopeManager.GetScopeForRole(unitRole);

            if (scopeForRole != null)
            {
                behaviorVariableValue = scopeForRole.GetVariableWithMood(name, bTree.unit.BehaviorTree.mood);
                if (behaviorVariableValue != null)
                {
                    return(behaviorVariableValue);
                }
            }

            if (bTree.unit.CanMoveAfterShooting)
            {
                BehaviorVariableScope scopeForAISkill = bTree.unit.Combat.BattleTechGame.BehaviorVariableScopeManager.GetScopeForAISkill(AISkillID.Reckless);
                if (scopeForAISkill != null)
                {
                    behaviorVariableValue = scopeForAISkill.GetVariableWithMood(name, bTree.unit.BehaviorTree.mood);
                    if (behaviorVariableValue != null)
                    {
                        return(behaviorVariableValue);
                    }
                }
            }

            behaviorVariableValue = bTree.unit.Combat.BattleTechGame.BehaviorVariableScopeManager.GetGlobalScope().GetVariableWithMood(name, bTree.unit.BehaviorTree.mood);
            if (behaviorVariableValue != null)
            {
                return(behaviorVariableValue);
            }

            return(DefaultBehaviorVariableValue.GetSingleton());
        }
Exemple #17
0
 public void SetRole(UnitRole _eRole)
 {
     m_eRole = _eRole;
 }
Exemple #18
0
 public ScopeDesc(string name, AIMood mood, UnitRole unitRole) : this(name, mood)
 {
     this.UnitRole  = unitRole;
     this.ScopeKind = ScopeKind.UnitRole;
 }
Exemple #19
0
        public static void AssignRoleToUnit(AbstractActor unit, List <AbstractActor> otherUnits)
        {
            if (unit.BehaviorTree.HasPriorityTargets() ||
                (!unit.BehaviorTree.GetBehaviorVariableValue(BehaviorVariableName.Bool_UseDynamicLanceRoles).BoolVal))
            {
                // don't assign dynamic roles when there's a priority target
                unit.DynamicUnitRole = UnitRole.Undefined;
                return;
            }

            if ((unit.StaticUnitRole == UnitRole.Turret) || (unit.StaticUnitRole == UnitRole.Vehicle && (!UnitIsECMRole(unit) && !UnitIsActiveProbe(unit))))
            {
                // don't assign roles to turrets or vehicles, except if they are ECM vehicles - Allie
                return;
            }

            //Debug.Log("trying to assign role to " + unit.DisplayName);
            otherUnits = otherUnits.FindAll(x => (x != unit) &&
                                            (x.StaticUnitRole != UnitRole.Turret) &&
                                            (x.StaticUnitRole != UnitRole.Vehicle) &&
                                            (!x.IsDead));

            //Debug.Log("other unit count: " + otherUnits.Count);

            // and now a list of the other interesing units plus our selected unit
            List <AbstractActor> allUnits = new List <AbstractActor>();

            allUnits.Add(unit);
            for (int unitIndex = 0; unitIndex < otherUnits.Count; ++unitIndex)
            {
                allUnits.Add(otherUnits[unitIndex]);
            }

            // OK So we do want to give an ECM Carrier role to ECM carrying vehicles.. - Allie
            if (unit.StaticUnitRole == UnitRole.Vehicle)
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                if (UnitIsEWE(unit))
                {
                    assignmentDict[unit] = UnitRole.Ewe;
                }
                else if (UnitIsECMRole(unit))
                {
                    assignmentDict[unit] = UnitRole.EcmCarrier;
                }
                else if (UnitIsActiveProbe(unit))
                {
                    assignmentDict[unit] = UnitRole.ActiveProbe;
                }
                else
                {
                    return;
                }

                applyAssignments(assignmentDict, allUnits, true);
                return;
            }

            // lastManStanding is its own thing (sigh)
            if (UnitIsLastManStandingRole(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.LastManStanding;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            // noncombatant units are their own thing (sigh)
            if (UnitIsNonCombatantRole(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.NonCombatant;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            // melee only units are their own thing (sigh)
            if (UnitIsMeleeOnlyRole(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.MeleeOnly;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            if (UnitIsEWE(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.Ewe;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            if (UnitIsActiveProbe(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.ActiveProbe;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            if (UnitIsECMRole(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.EcmCarrier;
                applyAssignments(assignmentDict, allUnits);
                return;
            }


            // scouts are their own thing (sigh)
            if (UnitMustBeScout(unit))
            {
                Dictionary <AbstractActor, UnitRole> assignmentDict = new Dictionary <AbstractActor, UnitRole>();
                assignmentDict[unit] = UnitRole.Scout;
                applyAssignments(assignmentDict, allUnits);
                return;
            }

            // first check to see if we're meeting our minimums. e.g. at startup, we won't.
            if (!unitsMeetMinimums(allUnits))
            {
                fillOutMinimums(allUnits);
            }

            List <Dictionary <AbstractActor, UnitRole> > possibleAssignments = new List <Dictionary <AbstractActor, UnitRole> >();

            UnitRole[] dynamicRoles =
            {
                UnitRole.Brawler,
                UnitRole.Sniper,
                // UnitRole.Scout,   // scouts don't use the normal evaluation routines
            };

            // do the raw evaluation, without considering role tags
            Dictionary <UnitRoleAssignmentRecord, float> unNormalizedRoleEvaluations = new Dictionary <UnitRoleAssignmentRecord, float>();

            for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
            {
                AbstractActor assignUnit = allUnits[unitIndex];
                for (int roleIndex = 0; roleIndex < dynamicRoles.Length; ++roleIndex)
                {
                    UnitRole assignRole = dynamicRoles[roleIndex];

                    UnitRoleAssignmentRecord assignmentRecord = new UnitRoleAssignmentRecord(assignUnit, assignRole);
                    float evaluation = EvaluateAssignmentForUnit(assignUnit, assignRole);
                    unNormalizedRoleEvaluations[assignmentRecord] = evaluation;
                }
            }

            // normalize the evaluations across roles, so that 0.0 is the worst brawler and 1.0 is the best
            // do the raw evaluation, without considering role tags
            Dictionary <UnitRoleAssignmentRecord, float> normalizedRoleEvaluations = new Dictionary <UnitRoleAssignmentRecord, float>();

            for (int roleIndex = 0; roleIndex < dynamicRoles.Length; ++roleIndex)
            {
                UnitRole assignRole = dynamicRoles[roleIndex];

                float maxValue = float.MinValue;
                float minValue = float.MaxValue;

                for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
                {
                    AbstractActor assignUnit = allUnits[unitIndex];
                    float         val        = unNormalizedRoleEvaluations[new UnitRoleAssignmentRecord(assignUnit, assignRole)];
                    maxValue = Mathf.Max(maxValue, val);
                    minValue = Mathf.Min(minValue, val);
                }
                float valueRange = maxValue - minValue;
                for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
                {
                    AbstractActor assignUnit = allUnits[unitIndex];
                    float         val        = unNormalizedRoleEvaluations[new UnitRoleAssignmentRecord(assignUnit, assignRole)];

                    float normalized = valueRange == 0.0f ? 1.0f : (val - minValue) / valueRange;

                    normalizedRoleEvaluations[new UnitRoleAssignmentRecord(assignUnit, assignRole)] = normalized;
                }
            }

            // now add in the role tag multipliers
            Dictionary <UnitRoleAssignmentRecord, float> normalizedRoleEvaluationsWithTagMultipliers = new Dictionary <UnitRoleAssignmentRecord, float>();

            for (int roleIndex = 0; roleIndex < dynamicRoles.Length; ++roleIndex)
            {
                UnitRole assignRole = dynamicRoles[roleIndex];

                for (int unitIndex = 0; unitIndex < allUnits.Count; ++unitIndex)
                {
                    AbstractActor            assignUnit       = allUnits[unitIndex];
                    UnitRoleAssignmentRecord assignmentRecord = new UnitRoleAssignmentRecord(assignUnit, assignRole);
                    float val    = normalizedRoleEvaluations[assignmentRecord];
                    float scaled = val * getRoleTagMultiplierForUnit(assignUnit, assignRole);
                    normalizedRoleEvaluationsWithTagMultipliers[assignmentRecord] = scaled;
                }
            }


            // first, consider just assigning this unit to a new role (abandoning the old role)
            for (int roleIndex = 0; roleIndex < dynamicRoles.Length; ++roleIndex)
            {
                UnitRole newRole = dynamicRoles[roleIndex];
                if (newRole == unit.DynamicUnitRole)
                {
                    continue;
                }

                Dictionary <AbstractActor, UnitRole> newAssignment = new Dictionary <AbstractActor, UnitRole>();
                newAssignment[unit] = newRole;
                //Debug.LogFormat("Assignment {0} abandonOld", possibleAssignments.Count);
                //Debug.LogFormat("Assigning {0} to role {1})", unit.DisplayName, newRole);
                possibleAssignments.Add(newAssignment);
            }

            // now, try swapping with each of the other units
            if (unit.DynamicUnitRole != UnitRole.Undefined)
            {
                for (int otherUnitIndex = 0; otherUnitIndex < otherUnits.Count; ++otherUnitIndex)
                {
                    AbstractActor otherUnit = otherUnits[otherUnitIndex];
                    if ((otherUnit.DynamicUnitRole == unit.DynamicUnitRole) || (otherUnit.DynamicUnitRole == UnitRole.Undefined))
                    {
                        // can't swap with someone who's the same as me, and don't want to swap with an undefined role
                        continue;
                    }

                    Dictionary <AbstractActor, UnitRole> newAssignment = new Dictionary <AbstractActor, UnitRole>();
                    newAssignment[unit]      = otherUnit.DynamicUnitRole;
                    newAssignment[otherUnit] = unit.DynamicUnitRole;
                    //Debug.LogFormat("Assignment {0} swap", possibleAssignments.Count);
                    //Debug.LogFormat("Assigning {0} to role {1}", unit.DisplayName, otherUnit.DynamicUnitRole);
                    //Debug.LogFormat("Assigning {0} to role {1}", otherUnit.DisplayName, unit.DynamicUnitRole);
                    possibleAssignments.Add(newAssignment);
                }
            }

            // now, iterate over all the possible assignements and find the one with the highest value

            float bestNonPenaltyEvaluationScore = float.MinValue;
            int   bestNonPenaltyIndex           = -1;

            float bestPenaltyEvaluationScore = float.MinValue;
            int   bestPenaltyIndex           = -1;

            for (int assignmentIndex = 0; assignmentIndex < possibleAssignments.Count; ++assignmentIndex)
            {
                float assignmentEvaluationScore = evaluateAssignments(possibleAssignments[assignmentIndex], allUnits, normalizedRoleEvaluationsWithTagMultipliers);

                if (assignmentEvaluationScore > 0.0f)
                {
                    if (assignmentEvaluationScore > bestNonPenaltyEvaluationScore)
                    {
                        bestNonPenaltyIndex           = assignmentIndex;
                        bestNonPenaltyEvaluationScore = assignmentEvaluationScore;
                    }
                }
                else
                {
                    if (assignmentEvaluationScore > bestPenaltyEvaluationScore)
                    {
                        bestPenaltyIndex           = assignmentIndex;
                        bestPenaltyEvaluationScore = assignmentEvaluationScore;
                    }
                }
            }

            float statusQuoEvaluationScore = evaluateAssignments(null, allUnits, normalizedRoleEvaluationsWithTagMultipliers);

            bool isUnassigned = unit.DynamicUnitRole == UnitRole.Undefined;

            if (bestNonPenaltyIndex >= 0)
            {
                float ratio = statusQuoEvaluationScore <= 0 ? float.MaxValue : (bestNonPenaltyEvaluationScore - statusQuoEvaluationScore) / statusQuoEvaluationScore;

                if (isUnassigned || (ratio > unit.Combat.Constants.DynamicAIRoleConstants.hysteresis))
                {
                    //Debug.LogFormat("applying {0} nonpenalty", bestNonPenaltyIndex);
                    applyAssignments(possibleAssignments[bestNonPenaltyIndex], allUnits);
                }
            }
            else
            {
                if (isUnassigned || (bestPenaltyEvaluationScore > statusQuoEvaluationScore))
                {
                    //Debug.LogFormat("applying {0} penalty", bestPenaltyIndex);
                    applyAssignments(possibleAssignments[bestPenaltyIndex], allUnits);
                }
            }
            if (unit.DynamicUnitRole == UnitRole.Undefined)
            {
                Debug.LogError("Dynamic Role Assignment: chose to leave unit undefined");
                Debug.LogError("bestNonPenaltyIndex: " + bestNonPenaltyIndex);
                Debug.LogError("bestNonPenaltyEvaluationScore: " + bestNonPenaltyEvaluationScore);
                Debug.LogError("bestPenaltyIndex: " + bestPenaltyIndex);
                Debug.LogError("bestPenaltyEvaluationScore: " + bestPenaltyEvaluationScore);
            }
        }
Exemple #20
0
 public UnitRoleAssignmentRecord(AbstractActor unit, UnitRole role)
 {
     this.unit = unit;
     this.role = role;
 }