public static ActionChosen SendPlayerInput(CombatChoicesAndTargets choicesAndTargets) { var keysToActions = GetKeysToActions(choicesAndTargets); var keysToMeleeTargets = GetKeysToTargets(choicesAndTargets, SampleGame.Vals.CombatCategory.MeleeTarget); var keysToRangedTargets = GetKeysToTargets(choicesAndTargets, SampleGame.Vals.CombatCategory.RangedTarget); return(GetHeroAction(keysToActions, keysToMeleeTargets, keysToRangedTargets)); }
//oh god this is terrible, but i just want to move on from it for now. // we need keys to be unique FOR THE SAME GROUP of actions, but they don't need to be unique globally. static List <ConsoleKeyAndChoice> GetKeysToActions(CombatChoicesAndTargets choicesAndTargets) { var keysAndChoices = new List <ConsoleKeyAndChoice>(); //for now (probably always) we support only a single agent at a time. long agentId = choicesAndTargets.Choices.Select(c => c.AgentId).Distinct().Single(); if (!_agentToActionMappings.ContainsKey(agentId)) { _agentToActionMappings[agentId] = new List <ConsoleKeyAndChoice>(); } var establishedKeysAndChoices = _agentToActionMappings[agentId]; //ugh, should have a better way of dealing with presets, but this is getting thrown away anyway. var presetChars = new HashSet <char>(new char[] { 'm', 'f', 'n', 'r', 'c', 's' }); foreach (var choice in choicesAndTargets.Choices) { ConsoleKeyAndChoice presetCkiAndChoice = GetPresetCkiAndChoice(choice); if (presetCkiAndChoice != null) { keysAndChoices.Add(presetCkiAndChoice); continue; } ConsoleKeyAndChoice matchingCkiAndChoice = GetEstablishedKeyAndChoice(establishedKeysAndChoices, choice); if (matchingCkiAndChoice != null) { keysAndChoices.Add(matchingCkiAndChoice); continue; } var sameLevelChars = new HashSet <char>(establishedKeysAndChoices.Where(c => c.Choice.Category == choice.Category).Select(c => c.Cki.KeyChar)); var openConsoleKey = GetNextOpenConsoleKey(presetChars, sameLevelChars); var newCkiAndChoice = new ConsoleKeyAndChoice { Cki = openConsoleKey, Choice = choice }; establishedKeysAndChoices.Add(newCkiAndChoice); keysAndChoices.Add(newCkiAndChoice); } return(keysAndChoices); }
private static List <ConsoleKeyToTarget> GetKeysToTargets(CombatChoicesAndTargets choicesAndTargets, string meleeOrRanged) { long agentId = choicesAndTargets.Choices.Select(c => c.AgentId).Distinct().Single(); if (!_agentToTargetMappings.ContainsKey(agentId)) { _agentToTargetMappings[agentId] = new Dictionary <long, ConsoleKeyToTarget>(); } var establishedTargets = _agentToTargetMappings[agentId]; var ckiToTarget = new List <ConsoleKeyToTarget>(); var targetList = meleeOrRanged == SampleGame.Vals.CombatCategory.MeleeTarget ? choicesAndTargets.MeleeTargets : choicesAndTargets.RangedTargets; foreach (var kvp in targetList) { if (establishedTargets.ContainsKey(kvp.Key)) { ckiToTarget.Add(new ConsoleKeyToTarget { Cki = establishedTargets[kvp.Key].Cki, TargetId = kvp.Key, TargetDescription = kvp.Value }); } else { var sameLevelChars = new HashSet <char>(establishedTargets.Select(et => et.Value.Cki.KeyChar)); var nextOpenConsoleKey = GetNextOpenConsoleKey(new HashSet <char>(), sameLevelChars); var newCki = new ConsoleKeyToTarget { Cki = nextOpenConsoleKey, TargetId = kvp.Key, TargetDescription = kvp.Value }; ckiToTarget.Add(newCki); establishedTargets.Add(kvp.Key, newCki); } } return(ckiToTarget); }
public static CombatChoicesAndTargets GetPossibleActions(EcsRegistrar rgs, long globalId, long agentId, List <long> battlefieldEntityIds) { var possibleCombatActions = new CombatChoicesAndTargets(); var naturalWeaponsMap = rgs.GetPartSingle <Parts.NaturalWeaponsMap>(globalId); var agentAnatomy = rgs.GetPartSingle <Parts.Anatomy>(agentId); //var agentWieldingDisabled = agentAnatomyModifers // .Where(m => m.EquipmentSlotDisabled == Vals.BodyEquipmentSlots.WieldObjectAppendage) // .Select(m => m.EquipmentSlotDisabled) // .ToList(); var agentWieldedIds = agentAnatomy.SlotsEquipped .Where(s => s.Key == Vals.BodySlots.WieldHandLeft || s.Key == Vals.BodySlots.WieldHandRight || s.Key == Vals.BodySlots.WieldTwoHanded) .Select(s => s.Value) .ToList(); var agentWieldedIdToWeaponEntityName = agentWieldedIds .Where(id => id != 0) .Distinct() .Select(id => new { Id = id, Name = rgs.GetPartSingle <Parts.EntityName>(id) }) .ToDictionary(n => n.Id, n => n.Name); var agentNaturalWeaponSlots = naturalWeaponsMap.NaturalWeaponSets[agentAnatomy.NaturalWeaponsCategory]; //MWCTODO: some magic happens here and we find out a wristblade or a laser eye has been equipped, and add that to the slots. // also any quickslots that might have attack items in them. we want quickslots. maybe a wristblade or a laser eye automatically adds a new, fixed quickslot for itself? i like this idea upon first think! var recordedIds = new HashSet <long>(); foreach (var slot in agentNaturalWeaponSlots.Keys) { var weaponId = agentAnatomy.SlotsEquipped[slot]; if (weaponId == 0L) { weaponId = agentNaturalWeaponSlots[slot]; } if (recordedIds.Contains(weaponId)) { continue; } var weapon = Bundle.GetWeaponBundle(rgs, weaponId); var choice = new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.TopLevelAction, Description = $"Melee {weapon.EntityName.GeneralName}", Action = Vals.CombatAction.AttackWeaponMelee, WeaponBodySlot = slot, WeaponEntityId = weaponId, NextCategory = Vals.CombatCategory.MeleeTarget }; possibleCombatActions.Choices.Add(choice); recordedIds.Add(weaponId); } foreach (long id in battlefieldEntityIds) { if (id == agentId) { continue; } var entityName = rgs.GetPartSingleOrDefault <Parts.EntityName>(id); var entityAgent = rgs.GetPartSingleOrDefault <Parts.Agent>(id); if (entityName == null || entityAgent == null) { continue; } if (entityAgent.CombatStatusTags.Intersect(Vals.CombatStatusTag.CombatTerminalStatuses).Any()) { continue; } possibleCombatActions.MeleeTargets.Add(id, entityName.ProperName); } //add stances possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.AllStances, Description = "Stance (Defensive)", Action = Vals.CombatAction.StanceDefensive }); possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.AllStances, Description = "Stance (Stand Ground)", Action = Vals.CombatAction.StanceStandGround }); possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.AllStances, Description = "Stance (Aggressive)", Action = Vals.CombatAction.StanceAggressive }); //add top-level choices that we know are present: note that we already did NextCategory = primary-melee because the description there is context dependent. possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.TopLevelAction, Description = "All Melee Options", NextCategory = Vals.CombatCategory.AllMelee }); possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.TopLevelAction, Description = "Change Stance", NextCategory = Vals.CombatCategory.AllStances }); possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.TopLevelAction, Description = "Run Away", Action = Vals.CombatAction.RunAway }); possibleCombatActions.Choices.Add(new AgentActionChoice { AgentId = agentId, Category = Vals.CombatCategory.TopLevelAction, Description = "Do Nothing", Action = Vals.CombatAction.DoNothing }); return(possibleCombatActions); }