private void _UpdateCardUsageStatus()
{
if (_updateCardUsageRecurvieLock || currentUsageVerifier == null)
{
return;
}
_updateCardUsageRecurvieLock = true;
List<Card> cards = _GetSelectedNonEquipCards();
List<Player> players = _GetSelectedPlayers();
ISkill skill = null;
bool isEquipCommand;
SkillCommand command = _GetSelectedSkillCommand(out isEquipCommand);
if (currentUsageVerifier.Helper.IsActionStage)
{
cancelCardUsageCommand.CanExecuteStatus = (cards.Count != 0 || players.Count != 0 || command != null);
}
if (command != null)
{
skill = command.Skill;
}
// are we really able to use this equip as command?
if (isEquipCommand)
{
Trace.Assert(skill != null);
if (currentUsageVerifier.Verify(HostPlayer, skill, new List<Card>(), new List<Player>()) == VerifierResult.Fail)
{
//nope, not really
isEquipCommand = false;
skill = null;
}
}
string prompt = null;
if (skill != null)
{
prompt = Application.Current.TryFindResource(string.Format("Skill.{0}.Prompt", skill.GetType().Name)) as string;
}
if (prompt == null)
{
prompt = LogFormatter.Translate(CurrentPrompt);
}
CurrentPromptString = prompt;
if (!isEquipCommand)
{
foreach (var equipCommand in EquipCommands)
{
if (equipCommand.IsSelected)
cards.Add(equipCommand.Card);
}
}
var sc = new List<SkillCommand>(ActiveSkillCommands);
// Handle skill down
bool hideSpecialDeck = true;
if (currentUsageVerifier != null && currentUsageVerifier.Helper != null &&
currentUsageVerifier.Helper.OtherDecksUsed != null &&
currentUsageVerifier.Helper.OtherDecksUsed.Count > 0)
{
hideSpecialDeck = false;
}
foreach (var skillCommand in sc)
{
// Handle kurou, luanwu and yeyan
if (skillCommand.Skill != null && skillCommand.IsSelected)
{
var helper = skillCommand.Skill.Helper;
// Handle KuRou, LuanWu
if (helper.HasNoConfirmation)
{
SubmitAnswerCommand.Execute(null);
_updateCardUsageRecurvieLock = false;
return;
}
// Handle YeYan
foreach (var player in _game.PlayerModels)
{
if (player.IsSelectionRepeatable == helper.IsPlayerRepeatable)
{
break;
}
player.IsSelectionRepeatable = helper.IsPlayerRepeatable;
}
// Handle JiXi, PaiYi
if (helper.OtherDecksUsed.Count > 0)
{
hideSpecialDeck = false;
if (helper.OtherDecksUsed.Count != 1)
{
_updateCardUsageRecurvieLock = false;
throw new NotImplementedException("Currently using more than one private decks is not supported");
}
var deck = helper.OtherDecksUsed[0];
var deckModel = PrivateDecks.FirstOrDefault(d => d.Name == deck.Name);
Trace.Assert(deckModel != null);
if (deckModel != CurrentSpecialDeck)
{
if (CurrentSpecialDeck != null)
{
foreach (var card in CurrentSpecialDeck.Cards)
{
card.IsSelectionMode = false;
card.OnSelectedChanged -= _OnCardSelected;
}
}
foreach (var card in deckModel.Cards)
{
card.IsSelectionMode = true;
card.OnSelectedChanged += _OnCardSelected;
}
CurrentSpecialDeck = deckModel;
}
}
else if (helper.OtherGlobalCardDeckUsed.Count > 0)
{
hideSpecialDeck = false;
if (helper.OtherGlobalCardDeckUsed.Count != 1)
{
_updateCardUsageRecurvieLock = false;
throw new NotImplementedException("Currently using more than one private decks is not supported");
}
var deck = helper.OtherGlobalCardDeckUsed.First().Key;
var numShown = helper.OtherGlobalCardDeckUsed.First().Value;
if (CurrentSpecialDeck == null || CurrentSpecialDeck.DeckPlace != deck ||
CurrentSpecialDeck.NumberOfCardsLimit != numShown)
{
var deckModel = new SpecialDeckViewModel() { DeckPlace = deck, NumberOfCardsLimit = numShown };
int total;
var deckCards = Game.CurrentGame.Decks[deck];
if (CurrentSpecialDeck != null)
{
foreach (var card in CurrentSpecialDeck.Cards)
{
card.IsSelectionMode = false;
card.OnSelectedChanged -= _OnCardSelected;
}
}
if (numShown == null)
{
total = deckCards.Count;
}
else
{
total = Math.Min((int)numShown, deckCards.Count);
}
for (int t = 0; t < total; t++)
{
var card = new CardViewModel() { Card = deckCards[t] };
card.IsSelectionMode = true;
card.OnSelectedChanged += _OnCardSelected;
deckModel.Cards.Add(card);
}
CurrentSpecialDeck = deckModel;
}
}
else
{
CurrentSpecialDeck = null;
}
}
// Handler GuHuo, QiCe
GuHuoSkillCommand cmdGuhuo = skillCommand as GuHuoSkillCommand;
if (cmdGuhuo != null)
{
if (skillCommand.IsEnabled)
{
if (cmdGuhuo.GuHuoTypes.Count == 0 && cmdGuhuo.GuHuoChoice == null)
{
var trySkill = Activator.CreateInstance(cmdGuhuo.Skill.GetType()) as IAdditionalTypedSkill;
trySkill.Owner = cmdGuhuo.Skill.Owner;
foreach (var c in Game.CurrentGame.AvailableCards)
{
trySkill.AdditionalType = c;
if (currentUsageVerifier.Verify(HostPlayer, trySkill, new List<Card>(), new List<Player>()) != VerifierResult.Fail)
{
cmdGuhuo.GuHuoTypes.Add(c);
}
}
}
}
}
}
if (hideSpecialDeck) CurrentSpecialDeck = null;
var status = currentUsageVerifier.Verify(HostPlayer, skill, cards, players);
if (status == VerifierResult.Fail)
{
submitCardUsageCommand.CanExecuteStatus = false;
foreach (var playerModel in _game.PlayerModels)
{
playerModel.IsSelected = false;
}
players.Clear();
_lastSelectedPlayers.Clear();
}
else if (status == VerifierResult.Partial)
{
submitCardUsageCommand.CanExecuteStatus = false;
}
else if (status == VerifierResult.Success)
{
submitCardUsageCommand.CanExecuteStatus = true;
}
if (skill == null || (skill is CardTransformSkill) || (skill is ActiveSkill))
{
// cards to be passed to verifier
List<Card> attempt = new List<Card>(cards);
// contains cards that doesn't pass the verifier when added to selected cards,
// but can pass the verifier if current card selection is rejected.
_cardsInSwitchMode.Clear();
bool allowCardSwitch = (attempt.Count == 1);
var cardsToTry = CurrentSpecialDeck == null ? HandCards : HandCards.Concat(CurrentSpecialDeck.Cards);
foreach (var card in cardsToTry)
{
if (card.IsSelected)
{
continue;
}
attempt.Add(card.Card);
bool disabled = (currentUsageVerifier.Verify(HostPlayer, skill, attempt, players) == VerifierResult.Fail);
if (disabled && allowCardSwitch)
{
if (currentUsageVerifier.Verify(HostPlayer, skill, new List<Card>() { card.Card }, players) != VerifierResult.Fail)
{
disabled = false;
_cardsInSwitchMode.Add(card);
}
}
else
{
allowCardSwitch = false;
foreach (var c in _cardsInSwitchMode)
{
c.IsEnabled = false;
}
_cardsInSwitchMode.Clear();
}
card.IsEnabled = !disabled;
attempt.Remove(card.Card);
}
foreach (var equipCommand in EquipCommands)
{
bool enabledAsSkill = false;
if (skill == null && equipCommand.SkillCommand.Skill != null && (equipCommand.SkillCommand.Skill is CardTransformSkill || equipCommand.SkillCommand.Skill is ActiveSkill))
{
enabledAsSkill = (currentUsageVerifier.Verify(HostPlayer, equipCommand.SkillCommand.Skill, new List<Card>(), new List<Player>()) != VerifierResult.Fail);
}
if (!equipCommand.IsSelected)
{
attempt.Add(equipCommand.Card);
bool disabled = (currentUsageVerifier.Verify(HostPlayer, skill, attempt, players) == VerifierResult.Fail);
equipCommand.IsEnabled = (!disabled) | enabledAsSkill;
}
attempt.Remove(equipCommand.Card);
}
}
// Invalidate target selection
List<Player> attempt2 = new List<Player>(players);
int validCount = 0;
bool[] enabledMap = new bool[_game.PlayerModels.Count];
int i = 0;
foreach (var playerModel in _game.PlayerModels)
{
enabledMap[i] = false;
if (playerModel.IsSelected && !playerModel.IsSelectionRepeatable)
{
i++;
continue;
}
attempt2.Add(playerModel.Player);
bool disabled = (currentUsageVerifier.Verify(HostPlayer, skill, cards, attempt2) == VerifierResult.Fail);
if (!disabled)
{
validCount++;
enabledMap[i] = true;
}
attempt2.RemoveAt(attempt2.Count - 1);
i++;
}
i = 0;
bool allowSelection = (cards.Count != 0 || validCount != 0 || skill != null);
foreach (var playerModel in _game.PlayerModels)
{
if (playerModel.IsSelected && !playerModel.IsSelectionRepeatable)
{
i++;
continue;
}
playerModel.IsSelectionMode = allowSelection;
if (allowSelection)
{
if (playerModel.IsSelected)
{
playerModel.CanBeSelectedMore = enabledMap[i];
}
else
{
playerModel.IsEnabled = enabledMap[i];
}
}
i++;
}
_updateCardUsageRecurvieLock = false;
}