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; } } }
public PrefabGrid(string prefabName, UnitType unitType, UnitRole unitRole) { PrefabName = prefabName; UnitType = unitType; UnitRole = unitRole; InitialBeaconName = GetBeaconName(unitRole, unitType); }
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); }
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); } }
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); }
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)); }
public BehaviorVariableScope GetScopeForRole(UnitRole role) { if (scopesByRole.ContainsKey(role)) { return(scopesByRole[role]); } return(null); }
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; } }
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; }
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? }
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); }
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); }
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!"); } }
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); } }
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()); }
public void SetRole(UnitRole _eRole) { m_eRole = _eRole; }
public ScopeDesc(string name, AIMood mood, UnitRole unitRole) : this(name, mood) { this.UnitRole = unitRole; this.ScopeKind = ScopeKind.UnitRole; }
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); } }
public UnitRoleAssignmentRecord(AbstractActor unit, UnitRole role) { this.unit = unit; this.role = role; }