public override void OnUse(Room room, CardUseStruct use) { Player player = use.From; if (use.To.Count == 0) { use.To.Add(player); } object data = use; RoomThread thread = room.RoomThread; thread.Trigger(TriggerEvent.PreCardUsed, room, player, ref data); CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, player.Name) { CardString = RoomLogic.CardToString(room, use.Card) }; room.MoveCardTo(use.Card, player, Place.PlaceTable, reason, true); Thread.Sleep(300); room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, use.From, ref data); room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, use.From, ref data); thread.Trigger(TriggerEvent.CardUsed, room, player, ref data); thread.Trigger(TriggerEvent.CardFinished, room, player, ref data); }
public override List <WrappedCard> GetViewAsCards(TrustedAI ai, string pattern, Player player) { Room room = ai.Room; Player jiaozhu = ai.FindPlayerBySkill("hongfa"); List <WrappedCard> result = new List <WrappedCard>(); if (jiaozhu != null && RoomLogic.WillBeFriendWith(room, player, jiaozhu) && pattern == Slash.ClassName) { foreach (int id in jiaozhu.GetPile("heavenly_army")) { WrappedCard hongfa = new WrappedCard("HongfaCard") { Skill = "hongfa" }; hongfa.AddSubCard(id); WrappedCard slash = new WrappedCard(Slash.ClassName) { Skill = "hongfa" }; slash.AddSubCard(id); slash = RoomLogic.ParseUseCard(room, slash); slash.UserString = RoomLogic.CardToString(room, hongfa); result.Add(slash); } } return(result); }
public override void Use(Room room, CardUseStruct card_use) { List <Player> targets = card_use.To; string str = RoomLogic.CardToString(room, card_use.Card); if (targets.Count == 0 || RoomLogic.PlayerContainsTrick(room, targets[0], Name)) { /* * if (movable) * { * OnNullified(room, card_use.From, card_use.Card); * if (room.GetCardOwner(card_use.Card.GetEffectiveId()) != card_use.From) return; * } */ CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_USE, card_use.From.Name, null, card_use.Card.Skill, null) { Card = card_use.Card }; room.MoveCardTo(card_use.Card, null, Place.DiscardPile, reason, true); return; } if (room.GetCardIdsOnTable(room.GetSubCards(card_use.Card)).Count == 0) { return; } CardMoveReason reason2 = new CardMoveReason(MoveReason.S_REASON_USE, card_use.From.Name, targets[0].Name, card_use.Card.Skill, null) { Card = card_use.Card }; room.MoveCardTo(card_use.Card, null, targets[0], Place.PlaceDelayedTrick, reason2, true); }
public override List <WrappedCard> GetViewAsCards(TrustedAI ai, string pattern, Player player) { List <WrappedCard> result = new List <WrappedCard>(); Room room = ai.Room; WrappedCard hujia = new WrappedCard(HujiaCard.ClassName) { Skill = Name }; if (pattern == "Jink" && !player.HasFlag(string.Format("hujia_{0}", room.GetRoomState().GetCurrentResponseID()))) { foreach (Player p in room.GetOtherPlayers(player)) { if (p.Kingdom == "wei" && ai.HasArmorEffect(p, EightDiagram.ClassName)) { WrappedCard jink = new WrappedCard(Jink.ClassName) { Skill = Name, UserString = RoomLogic.CardToString(room, hujia) }; return(new List <WrappedCard> { jink }); } } List <int> ids = player.GetCards("he"); ids.AddRange(player.GetHandPile()); int jink_count = 0; foreach (int id in ids) { if (ai.IsCard(id, pattern, player)) { jink_count++; } } if (jink_count == 0) { foreach (Player p in room.GetOtherPlayers(player)) { if (ai.IsFriend(p) && p.Kingdom == "wei") { WrappedCard jink = new WrappedCard(Jink.ClassName) { Skill = Name, UserString = RoomLogic.CardToString(room, hujia) }; return(new List <WrappedCard> { jink }); } } } } return(result); }
public override List <WrappedCard> GetTurnUse(TrustedAI ai, Player player) { Room room = ai.Room; List <int> ids = player.GetCards("h"); ids.AddRange(player.GetHandPile()); List <int> spades = new List <int>(); foreach (int id in ids) { if (room.GetCard(id).Suit == WrappedCard.CardSuit.Spade) { spades.Add(id); } } List <WrappedCard> result = new List <WrappedCard>(); if (spades.Count > 0) { ai.SortByUseValue(ref spades, false); WrappedCard card = new WrappedCard(GuishuCard.ClassName) { Skill = Name, ShowSkill = Name }; card.AddSubCard(spades[0]); if (player.GetMark(Name) == 0 || player.GetMark(Name) == 1) { card.UserString = BefriendAttacking.ClassName; WrappedCard ba = new WrappedCard(BefriendAttacking.ClassName) { Skill = Name, ShowSkill = Name, }; ba.AddSubCard(card); ba = RoomLogic.ParseUseCard(room, ba); ba.UserString = RoomLogic.CardToString(room, card); result.Add(ba); } else if (spades.Count > 1) { card.UserString = KnownBoth.ClassName; result.Add(card); } } return(result); }
public virtual void DoRecast(Room room, CardUseStruct use) { WrappedCard card = use.Card; CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_RECAST, use.From.Name) { SkillName = card.Skill }; room.RecordSubCards(use.Card); room.MoveCardTo(card, null, Place.PlaceTable, reason, true); if (!string.IsNullOrEmpty(reason.SkillName)) { room.BroadcastSkillInvoke(use.From, use.Card); } else { room.BroadcastSkillInvoke("@recast", use.From.IsMale() ? "male" : "female", -1); } if (!string.IsNullOrEmpty(card.Skill) && !card.Skill.StartsWith("-") && use.IsOwnerUse && RoomLogic.PlayerHasSkill(room, use.From, card.Skill)) { room.NotifySkillInvoked(use.From, card.Skill); } LogMessage log = new LogMessage("#Card_Recast") { From = use.From.Name, Card_str = RoomLogic.CardToString(room, card) }; room.SendLog(log); List <int> table_cardids = room.GetCardIdsOnTable(room.GetSubCards(card)); if (table_cardids.Count > 0) { CardsMoveStruct move = new CardsMoveStruct(table_cardids, use.From, null, Place.PlaceTable, Place.DiscardPile, reason); room.MoveCardsAtomic(new List <CardsMoveStruct>() { move }, true); room.RemoveSubCards(use.Card); } room.DrawCards(use.From, 1, "recast"); }
public override void Use(Room room, CardUseStruct card_use) { List <Player> targets = card_use.To; string str = RoomLogic.CardToString(room, card_use.Card); List <string> nullified_list = room.ContainsTag("CardUseNullifiedList") ? (List <string>)room.GetTag("CardUseNullifiedList") : new List <string>(); bool all_nullified = nullified_list.Contains("_ALL_TARGETS"); if (all_nullified || targets.Count == 0) { if (movable) { OnNullified(room, card_use.From, card_use.Card); if (room.GetCardOwner(card_use.Card.GetEffectiveId()) != card_use.From) { return; } } CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card_use.Card.Skill, null) { CardString = str }; room.MoveCardTo(card_use.Card, null, Place.DiscardPile, reason, true); return; } if (room.GetCardIdsOnTable(card_use.Card).Count == 0) { return; } CardMoveReason reason2 = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, targets[0].Name, card_use.Card.Skill, null) { CardString = str }; room.MoveCardTo(card_use.Card, null, targets[0], Place.PlaceDelayedTrick, reason2, true); }
public override void OnUse(Room room, CardUseStruct use) { string str = RoomLogic.CardToString(room, use.Card); object data = use; RoomThread thread = room.RoomThread; thread.Trigger(TriggerEvent.PreCardUsed, room, use.From, ref data); CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, use.From.Name, use.To[0].Name, use.Card.Skill, null) { CardString = str, General = RoomLogic.GetGeneralSkin(room, use.From, use.Card.Skill, use.Card.SkillPosition) }; room.MoveCardTo(use.Card, use.From, Place.PlaceTable, reason, true); LogMessage log = new LogMessage { From = use.From.Name, To = new List <string>(), Type = "#DelayedTrick", Card_str = str }; foreach (Player to in use.To) { log.To.Add(to.Name); } room.SendLog(log); Thread.Sleep(300); room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, use.From, ref data); room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, use.From, ref data); thread.Trigger(TriggerEvent.CardUsed, room, use.From, ref data); thread.Trigger(TriggerEvent.CardFinished, room, use.From, ref data); }
public override bool Effect(TriggerEvent triggerEvent, Room room, Player player, ref object data, Player target, TriggerStruct trigger_info) { if (room.SkipGameRule) { room.SkipGameRule = false; return(false); } // Handle global events if (player == null) { if (triggerEvent == TriggerEvent.GameStart) { OnGameStart(room, ref data); } if (triggerEvent != TriggerEvent.BeforeCardsMove && triggerEvent != TriggerEvent.CardsMoveOneTime) { return(false); } } switch (triggerEvent) { case TriggerEvent.TurnStart: OnTurnStart(room, player, ref data); break; case TriggerEvent.EventPhaseProceeding: OnPhaseProceed(room, player, ref data); break; case TriggerEvent.EventPhaseEnd: OnPhaseEnd(room, player, ref data); break; case TriggerEvent.EventPhaseChanging: OnPhaseChanging(room, player, ref data); break; case TriggerEvent.PreCardUsed: OnPreCardUsed(room, player, ref data); break; case TriggerEvent.CardUsed: OnCardUsed(room, player, ref data); break; case TriggerEvent.CardFinished: CardUseStruct use = (CardUseStruct)data; //room.ClearCardFlag(use.Card); use.Card.ClearFlags(); //RoomCard会在其移动后自动清除flag room.RemoveSubCards(use.Card); //以askforcard形式使用的卡牌没有onUse的trigger,但有finish if (use.Reason != CardUseStruct.CardUseReason.CARD_USE_REASON_RESPONSE) { room.RemoveUseOnFinish(); } if (Engine.GetFunctionCard(use.Card.Name).IsNDTrick()) { room.RemoveHegNullification(use.Card); } foreach (Client p in room.Clients) { room.DoNotify(p, CommandType.S_COMMAND_NULLIFICATION_ASKED, new List <string> { "." }); } break; case TriggerEvent.EventAcquireSkill: case TriggerEvent.EventLoseSkill: InfoStruct info = (InfoStruct)data; string skill_name = info.Info; Skill skill = Engine.GetSkill(skill_name); bool refilter = skill is FilterSkill; if (!refilter && skill is TriggerSkill) { TriggerSkill trigger = (TriggerSkill)skill; ViewAsSkill vsskill = trigger.ViewAsSkill; if (vsskill != null && (vsskill is FilterSkill)) { refilter = true; } } if (refilter) { room.FilterCards(player, player.GetCards("he"), triggerEvent == TriggerEvent.EventLoseSkill); } CheckBigKingdoms(room); break; case TriggerEvent.PostHpReduced: if (player.Hp > 0 || player.HasFlag("Global_Dying")) // newest GameRule -- a player cannot enter dying when it is dying. { break; } if (data is DamageStruct damage) { room.EnterDying(player, damage); } else { room.EnterDying(player, new DamageStruct()); } break; case TriggerEvent.AskForPeaches: OnAskforPeach(room, player, ref data); break; case TriggerEvent.AskForPeachesDone: { if (player.Hp <= 0 && player.Alive) { DyingStruct dying = (DyingStruct)data; room.KillPlayer(player, dying.Damage); } break; } case TriggerEvent.ConfirmDamage: { break; } case TriggerEvent.DamageDone: { damage = (DamageStruct)data; if (damage.From != null && !damage.From.Alive) { damage.From = null; } room.SendDamageLog(damage); if (damage.Nature != DamageNature.Normal && player.Chained && !damage.Chain && !damage.ChainStarter) { damage.ChainStarter = true; } data = damage; bool reduce = !room.ApplyDamage(player, damage); if (reduce) { room.RoomThread.Trigger(TriggerEvent.PostHpReduced, room, player, ref data); } break; } case TriggerEvent.DamageComplete: { damage = (DamageStruct)data; if (damage.Prevented) { return(false); } /* * if (damage.Nature != DamageNature.Normal && player.Chained) * { * room.ChainedRemoveOnDamageDone(player, damage); * } */ if (damage.Nature != DamageNature.Normal && !damage.Chain && damage.ChainStarter) // iron chain effect { List <Player> chained_players = new List <Player>(); if (!room.Current.Alive) { chained_players = room.GetOtherPlayers(room.Current); } else { chained_players = room.GetAllPlayers(); } chained_players.Remove(damage.To); foreach (Player chained_player in chained_players) { if (chained_player.Chained) { Thread.Sleep(500); LogMessage log = new LogMessage { Type = "#IronChainDamage", From = chained_player.Name }; room.SendLog(log); DamageStruct chain_damage = damage; chain_damage.To = chained_player; chain_damage.Chain = true; chain_damage.Transfer = false; chain_damage.TransferReason = null; room.Damage(chain_damage); } } } foreach (Player p in room.GetAllPlayers()) { if (p.HasFlag("Global_DFDebut")) { p.SetFlags("-Global_DFDebut"); room.RoomThread.Trigger(TriggerEvent.DFDebut, room, p); } } break; } case TriggerEvent.CardEffect: { if (data is CardEffectStruct effect) { if (Engine.GetFunctionCard(effect.Card.Name) is DelayedTrick) { CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_DELAYTRICK_EFFECT, effect.To.Name, effect.Card.Skill, effect.Card.Name) { Card = effect.Card }; room.MoveCardTo(effect.Card, effect.To, Place.PlaceTable, reason, true); Thread.Sleep(500); } } break; } case TriggerEvent.CardEffected: { if (data is CardEffectStruct effect) { FunctionCard fcard = Engine.GetFunctionCard(effect.Card.Name); if (!(fcard is Slash) && effect.BasicEffect.Nullified) { LogMessage log = new LogMessage { Type = "#Cardnullified", From = effect.To.Name, Arg = effect.Card.Name }; room.SendLog(log); return(true); } else if (fcard.TypeID == CardType.TypeTrick && room.IsCanceled(effect)) { effect.To.SetFlags("Global_NonSkillnullify"); return(true); } object _effect = effect; room.RoomThread.Trigger(TriggerEvent.CardEffectConfirmed, room, effect.To, ref _effect); if (effect.To.Alive || fcard is Slash) { fcard.OnEffect(room, effect); } } break; } case TriggerEvent.SlashEffected: { SlashEffectStruct effect = (SlashEffectStruct)data; if (effect.Nullified) { LogMessage log = new LogMessage { Type = "#Cardnullified", From = effect.To.Name, Arg = effect.Slash.Name }; room.SendLog(log); return(true); } if (effect.Jink_num > 0) { room.RoomThread.Trigger(TriggerEvent.SlashProceed, room, effect.From, ref data); } else { room.SlashResult(effect, null); } break; } case TriggerEvent.SlashProceed: { SlashEffectStruct effect = (SlashEffectStruct)data; string slasher = effect.From.Name; if (!effect.To.Alive) { break; } if (effect.Jink_num == 1) { CardResponseStruct resp = room.AskForCard(effect.To, Slash.ClassName, Jink.ClassName, string.Format("slash-jink:{0}::{1}", slasher, effect.Slash.Name), data, HandlingMethod.MethodUse, null, effect.From, false, false); room.SlashResult(effect, room.IsJinkEffected(effect.To, resp) ? resp.Card : null); } else { WrappedCard jink = new WrappedCard(DummyCard.ClassName); for (int i = effect.Jink_num; i > 0; i--) { string prompt = string.Format("@multi-jink{0}:{1}::{2}:{3}", i == effect.Jink_num ? "-start" : string.Empty, slasher, i, effect.Slash.Name); CardResponseStruct resp = room.AskForCard(effect.To, Slash.ClassName, Jink.ClassName, prompt, data, HandlingMethod.MethodUse, null, effect.From, false, false); if (!room.IsJinkEffected(effect.To, resp)) { //delete jink; room.SlashResult(effect, null); return(false); } else { jink.AddSubCard(resp.Card); } } room.SlashResult(effect, jink); } break; } case TriggerEvent.SlashHit: { SlashEffectStruct effect = (SlashEffectStruct)data; if (effect.Drank > 0) { LogMessage log = new LogMessage { Type = "#AnalepticBuff", From = effect.From.Name, To = new List <string> { effect.To.Name }, Arg = (1 + effect.ExDamage).ToString(), Arg2 = (1 + effect.ExDamage + effect.Drank).ToString() }; room.SendLog(log); } DamageStruct slash_damage = new DamageStruct(effect.Slash, effect.From, effect.To, 1 + effect.ExDamage + effect.Drank, effect.Nature) { Drank = effect.Drank > 0 }; room.Damage(slash_damage); break; } case TriggerEvent.BeforeGameOverJudge: { if (!player.General1Showed) { room.ShowGeneral(player, true, false, false); } if (!player.General2Showed) { room.ShowGeneral(player, false, false, false); } break; } case TriggerEvent.GameOverJudge: { string winner = GetWinner(room); if (!string.IsNullOrEmpty(winner)) { room.GameOver(winner); return(true); } break; } case TriggerEvent.BuryVictim: { OnBuryVictim(room, player, ref data); break; } case TriggerEvent.StartJudge: { int card_id = room.GetNCards(1)[0]; JudgeStruct judge_struct = (JudgeStruct)data; judge_struct.Card = room.GetCard(card_id); LogMessage log = new LogMessage { Type = "$InitialJudge", From = judge_struct.Who.Name, Card_str = card_id.ToString() }; room.SendLog(log); room.MoveCardTo(judge_struct.Card, null, judge_struct.Who, Place.PlaceJudge, new CardMoveReason(MoveReason.S_REASON_JUDGE, judge_struct.Who.Name, null, null, judge_struct.Reason), true); Thread.Sleep(500); bool effected = judge_struct.Good == Engine.MatchExpPattern(room, judge_struct.Pattern, judge_struct.Who, judge_struct.Card); judge_struct.UpdateResult(effected); data = judge_struct; break; } case TriggerEvent.JudgeResult: { JudgeStruct judge = (JudgeStruct)data; LogMessage log = new LogMessage { Type = "$JudgeResult", From = player.Name, Card_str = RoomLogic.CardToString(room, judge.Card) }; room.SendLog(log); //Thread.Sleep(500); if (judge.PlayAnimation) { room.SendJudgeResult(judge); Thread.Sleep(800); } break; } case TriggerEvent.FinishJudge: { JudgeStruct judge = (JudgeStruct)data; if (room.GetCardPlace(judge.Card.Id) == Place.PlaceJudge) { CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_JUDGEDONE, judge.Who.Name, null, judge.Reason); room.MoveCardTo(judge.Card, judge.Who, null, Place.DiscardPile, reason, true); } break; } case TriggerEvent.ChoiceMade: { foreach (Player p in room.GetAlivePlayers()) { List <string> flags = new List <string>(p.Flags); foreach (string flag in flags) { if (flag.StartsWith("Global_") && flag.EndsWith("Failed")) { p.SetFlags("-" + flag); } } } break; } case TriggerEvent.GeneralShown: { string winner = GetWinner(room); if (!string.IsNullOrEmpty(winner)) { room.GameOver(winner); // if all hasShownGenreal, and they are all friend, game over. return(true); } if (!room.ContainsTag("TheFirstToShowRewarded")) { room.SetTag("TheFirstToShowRewarded", true); room.SetPlayerMark(player, "@pioneer", 1); room.AttachSkillToPlayer(player, "pioneer"); } if (player.Alive && player.HasShownAllGenerals()) { if (player.GetMark("CompanionEffect") > 0) { room.RemovePlayerMark(player, "CompanionEffect"); room.DoSuperLightbox(player, string.Empty, "companion"); room.SetPlayerMark(player, "@companion", 1); room.AttachSkillToPlayer(player, "companion"); } if (player.GetMark("HalfMaxHpLeft") > 0) { room.RemovePlayerMark(player, "HalfMaxHpLeft"); room.SetPlayerMark(player, "@megatama", 1); room.AttachSkillToPlayer(player, "megatama"); } } CheckBigKingdoms(room); break; } case TriggerEvent.BeforeCardsMove: { if (data is CardsMoveOneTimeStruct move) { bool should_find_io = false; if (move.To_place == Place.DiscardPile) { if (move.Reason.Reason != MoveReason.S_REASON_USE) { should_find_io = true; // not use } else if (move.Card_ids.Count > 1) { should_find_io = true; // use card isn't IO } else { WrappedCard card = room.GetCard(move.Card_ids[0]); if (card.Name == Edict.ClassName && !card.HasFlag("edict_normal_use")) { should_find_io = true; // use card isn't IO } } } if (should_find_io) { foreach (int id in move.Card_ids) { WrappedCard card = room.GetCard(id); if (card.Name == Edict.ClassName) { room.MoveCardTo(card, null, Place.PlaceTable, true); room.AddToPile(room.Players[0], "#edict", card, false); LogMessage log = new LogMessage { Type = "#RemoveEdict", Arg = Edict.ClassName }; room.SendLog(log); room.SetTag("EdictInvoke", true); room.SetTag("EdictCard", card); int i = move.Card_ids.IndexOf(id); move.From_places.RemoveAt(i); move.Open.RemoveAt(i); move.From_pile_names.RemoveAt(i); move.Card_ids.Remove(id); data = move; break; } } } } break; } case TriggerEvent.Death: { OnDeath(room, player, ref data); break; } case TriggerEvent.CardsMoveOneTime: { if (data is CardsMoveOneTimeStruct move) { if (move.From != null && move.From_places.Contains(Place.PlaceEquip)) { foreach (int id in move.Card_ids) { WrappedCard card = room.GetCard(id); if (card.Name == JadeSeal.ClassName) { CheckBigKingdoms(room); break; } } } if (move.To != null && move.To_place == Place.PlaceEquip) { foreach (int id in move.Card_ids) { WrappedCard card = room.GetCard(id); if (card.Name == JadeSeal.ClassName) { CheckBigKingdoms(room); break; } } } } break; } default: break; } return(false); }
public override NulliResult OnNullification(TrustedAI ai, Player from, Player to, WrappedCard trick, bool positive, bool keep) { NulliResult result = new NulliResult(); Room room = ai.Room; Player player = ai.Self; List <Player> delete = (List <Player>)room.GetTag("targets" + RoomLogic.CardToString(room, trick)); List <Player> targets = new List <Player>(delete); foreach (Player p in delete) { if (delete.IndexOf(p) < delete.IndexOf(to)) { targets.Remove(p); } } double good = 0; if (positive) { if (ai.IsEnemy(to)) { good += 4; if (ai.HasSkill(TrustedAI.MasochismSkill, to)) { good += 3; } if (ai.IsWeak(to) && to.Hp <= 1) { good += 5; } if (good > 8) { result.Null = true; } } } else { if (ai.IsFriend(to)) { good += 4; if (ai.HasSkill(TrustedAI.MasochismSkill, to)) { good += 3; } if (ai.IsWeak(to) && to.Hp <= 1) { good += 5; } if (good > 8) { result.Null = true; } } } return(result); }
public override void Use(Room room, CardUseStruct card_use) { WrappedCard card = card_use.Card; if (card_use.To.Count == 0) { CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card.Skill, null) { CardString = RoomLogic.CardToString(room, card_use.Card) }; room.MoveCardTo(card, room.GetCardOwner(card.GetEffectiveId()), null, Place.DiscardPile, reason, true); } if (room.GetCardIdsOnTable(card).Count == 0) { return; } int equipped_id = -1; Player target = card_use.To[0]; if (target.HasEquip((int)EquipLocation())) { equipped_id = target.GetEquip((int)EquipLocation()); } List <CardsMoveStruct> exchangeMove = new List <CardsMoveStruct> { }; CardsMoveStruct move1 = new CardsMoveStruct(card.GetEffectiveId(), target, Place.PlaceEquip, new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, target.Name)); move1.Reason.CardString = RoomLogic.CardToString(room, card_use.Card); exchangeMove.Add(move1); if (equipped_id != -1) { CardsMoveStruct move2 = new CardsMoveStruct(equipped_id, target, Place.PlaceTable, new CardMoveReason(CardMoveReason.MoveReason.S_REASON_CHANGE_EQUIP, target.Name)); exchangeMove.Add(move2); } room.MoveCardsAtomic(exchangeMove, true); LogMessage log = new LogMessage { From = target.Name, Type = "$Install", Card_str = card.GetEffectiveId().ToString() }; room.SendLog(log); if (equipped_id != -1) { if (room.GetCardPlace(equipped_id) == Place.PlaceTable) { CardsMoveStruct move3 = new CardsMoveStruct(equipped_id, null, Place.DiscardPile, new CardMoveReason(CardMoveReason.MoveReason.S_REASON_CHANGE_EQUIP, target.Name)); room.MoveCardsAtomic(new List <CardsMoveStruct> { move3 }, true); } } }
public override void OnNullified(Room room, Player target, WrappedCard card) { RoomThread thread = room.RoomThread; string card_str = RoomLogic.CardToString(room, card); bool move = false; Player p = null; if (movable) { List <Player> players = new List <Player>(); List <Player> count_players = new List <Player>(room.Players); Player starter = target; int index = count_players.IndexOf(starter); for (int i = index + 1; i < count_players.Count; i++) { if (count_players[i].Alive) { players.Add(count_players[i]); } } for (int i = 0; i <= index; i++) { if (count_players[i].Alive) { players.Add(count_players[i]); } } foreach (Player player in players) { if (RoomLogic.PlayerContainsTrick(room, player, Name)) { continue; } Skill skill = RoomLogic.IsProhibited(room, null, player, card); if (skill != null) { skill = Engine.GetMainSkill(skill.Name); LogMessage log = new LogMessage { Type = "#SkillAvoid", From = player.Name, Arg = skill.Name, Arg2 = Name }; room.SendLog(log); room.BroadcastSkillInvoke(skill.Name, player); continue; } if (player.HasFlag(card_str + "_delay_trick_cancel")) { continue; } CardUseStruct use = new CardUseStruct(room.GetCard(card.GetEffectiveId()), null, player); object data = use; thread.Trigger(TriggerEvent.TargetConfirming, room, player, ref data); CardUseStruct new_use = (CardUseStruct)data; if (new_use.To.Count == 0) { p = player; player.SetFlags(card_str + "_delay_trick_cancel"); break; } CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_TRANSFER, string.Empty) { CardString = RoomLogic.CardToString(room, card) }; room.MoveCardTo(card, null, player, Place.PlaceDelayedTrick, reason, true); move = true; foreach (Player p2 in room.GetAllPlayers()) { thread.Trigger(TriggerEvent.TargetChosen, room, p2, ref data); } foreach (Player p2 in room.GetAllPlayers()) { thread.Trigger(TriggerEvent.TargetConfirmed, room, p2, ref data); } break; } } if (p != null) { OnNullified(room, p, card); } else if (!move) { foreach (Player player in room.GetAllPlayers()) { if (player.HasFlag(RoomLogic.CardToString(room, card) + "_delay_trick_cancel")) { player.SetFlags(string.Format("-{0}{1}", card_str, "_delay_trick_cancel")); } } CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_NATURAL_ENTER, string.Empty); room.MoveCardTo(card, null, Place.DiscardPile, reason, true); } }
public virtual void Use(Room room, CardUseStruct card_use) { WrappedCard card = card_use.Card; List <Player> targets = card_use.To; List <string> nullified_list = room.GetTag("CardUseNullifiedList") != null ? (List <string>)room.GetTag("CardUseNullifiedList") : new List <string>(); bool all_nullified = nullified_list.Contains("_ALL_TARGETS"); foreach (Player target in targets) { CardEffectStruct effect = new CardEffectStruct { Card = card, From = card_use.From, To = target, Multiple = (targets.Count > 1), Nullified = (all_nullified || nullified_list.Contains(target.Name)), Drank = card_use.Drank, }; if (card_use.EffectCount != null) { foreach (EffctCount count in new List <EffctCount>(card_use.EffectCount)) { if ((count.From == card_use.From && count.To == target && count.Index == targets.IndexOf(target)) || (count.To == card_use.From && count.From == target) && count.Index == targets.IndexOf(target)) { card_use.EffectCount.Remove(count); if (effect.EffectCount != null) { effect.EffectCount.Add(count); } else { effect.EffectCount = new List <EffctCount> { count } }; break; } } } List <Player> players = new List <Player>(); for (int i = targets.IndexOf(target); i < targets.Count; i++) { if (!nullified_list.Contains(targets[i].Name) && !all_nullified) { players.Add(targets[i]); } } room.SetTag("targets" + RoomLogic.CardToString(room, card), players); effect.StackPlayers = players; room.CardEffect(effect); } List <int> table_cardids = room.GetCardIdsOnTable(card); if (table_cardids.Count > 0) { CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card.Skill, null) { CardString = RoomLogic.CardToString(room, card) }; if (targets.Count == 1) { reason.TargetId = targets[0].Name; } CardsMoveStruct move = new CardsMoveStruct(table_cardids, card_use.From, null, Place.PlaceTable, Place.DiscardPile, reason); room.MoveCardsAtomic(new List <CardsMoveStruct> { move }, true); } }
public virtual void OnUse(Room room, CardUseStruct card_use) { Player player = card_use.From; room.SortByActionOrder(ref card_use); List <Player> targets = card_use.To; bool hidden = (TypeID == CardType.TypeSkill && !WillThrow); LogMessage log = new LogMessage("#UseCard") { From = player.Name, To = new List <string>(), Card_str = RoomLogic.CardToString(room, card_use.Card) }; if (!TargetFixed(card_use.Card) || card_use.To.Count > 1 || !card_use.To.Contains(card_use.From)) { log.SetTos(card_use.To); } List <int> used_cards = new List <int>(); List <CardsMoveStruct> moves = new List <CardsMoveStruct>(); used_cards.AddRange(card_use.Card.SubCards); RoomThread thread = room.RoomThread; object data = card_use; thread.Trigger(TriggerEvent.PreCardUsed, room, player, ref data); card_use = (CardUseStruct)data; if (TypeID != CardType.TypeSkill) { CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, player.Name, null, card_use.Card.Skill, null) { CardString = RoomLogic.CardToString(room, card_use.Card), General = RoomLogic.GetGeneralSkin(room, player, card_use.Card.Skill, card_use.Card.SkillPosition) }; if (card_use.To.Count == 1) { reason.TargetId = card_use.To[0].Name; } foreach (int id in used_cards) { CardsMoveStruct move = new CardsMoveStruct(id, null, Place.PlaceTable, reason); moves.Add(move); } room.MoveCardsAtomic(moves, true); if (used_cards.Count == 0) { //show virtual card on table CardsMoveStruct move = new CardsMoveStruct(-1, player, Place.PlaceTable, reason) { From_place = Place.PlaceUnknown, From = player.Name, Is_last_handcard = false, }; room.NotifyUsingVirtualCard(RoomLogic.CardToString(room, card_use.Card), move); } room.SendLog(log); if (this is Collateral) { // put it here for I don't wanna repeat these codes in Card::onUse Player victim = room.FindPlayer((string)card_use.To[0].GetTag("collateralVictim"), true); if (victim != null) { log = new LogMessage("#CollateralSlash") { From = card_use.From.Name, To = new List <string> { victim.Name }, }; room.SendLog(log); room.DoAnimate(AnimateType.S_ANIMATE_INDICATE, card_use.To[0].Name, victim.Name); } } } else { CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_THROW, card_use.From.Name, null, card_use.Card.Skill, null) { CardString = RoomLogic.CardToString(room, card_use.Card), General = RoomLogic.GetGeneralSkin(room, player, card_use.Card.Skill, card_use.Card.SkillPosition) }; FunctionCard card = Engine.GetFunctionCard(card_use.Card.Name); if (card is SkillCard && WillThrow) { room.MoveCardTo(card_use.Card, card_use.From, null, Place.PlaceTable, reason, true); } room.SendLog(log); if (WillThrow) { List <int> table_cardids = room.GetCardIdsOnTable(card_use.Card); if (table_cardids.Count > 0) { CardsMoveStruct move = new CardsMoveStruct(table_cardids, player, null, Place.PlaceTable, Place.DiscardPile, reason); room.MoveCardsAtomic(new List <CardsMoveStruct> { move }, true); } } } room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, player, ref data); room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, player, ref data); room.RoomThread.Trigger(TriggerEvent.CardUsed, room, player, ref data); room.RoomThread.Trigger(TriggerEvent.CardFinished, room, player, ref data); }
public override void OnNullified(Room room, Player target, WrappedCard card) { RoomThread thread = room.RoomThread; string card_str = RoomLogic.CardToString(room, card); bool move = false; Player p = null; if (movable) { List <Player> players = new List <Player>(); List <Player> count_players = new List <Player>(room.Players); Player starter = target; int index = count_players.IndexOf(starter); for (int i = index + 1; i < count_players.Count; i++) { if (count_players[i].Alive) { players.Add(count_players[i]); } } for (int i = 0; i <= index; i++) { if (count_players[i].Alive) { players.Add(count_players[i]); } } foreach (Player player in players) { if (RoomLogic.PlayerContainsTrick(room, player, Name) || !player.JudgingAreaAvailable) { continue; } Skill skill = RoomLogic.IsProhibited(room, null, player, card); if (skill != null) { skill = Engine.GetMainSkill(skill.Name); LogMessage log = new LogMessage { Type = "#SkillAvoid", From = player.Name, Arg = skill.Name, Arg2 = Name }; room.SendLog(log); if (RoomLogic.PlayerHasShownSkill(room, player, skill)) { room.NotifySkillInvoked(player, skill.Name); GeneralSkin gsk = RoomLogic.GetGeneralSkin(room, player, skill.Name); string genral = gsk.General; int skin_id = gsk.SkinId; string skill_name = skill.Name; int audio = -1; skill.GetEffectIndex(room, player, card, ref audio, ref skill_name, ref genral, ref skin_id); if (audio >= -1) { room.BroadcastSkillInvoke(skill_name, "male", audio, genral, skin_id); } } continue; } //if (player.HasFlag(card_str + "_delay_trick_cancel")) continue; /* * CardUseStruct use = new CardUseStruct(room.GetCard(card.GetEffectiveId()), null, player) * { * EffectCount = new List<CardBasicEffect> { FillCardBasicEffct(room, player) } * }; * object data = use; * thread.Trigger(TriggerEvent.TargetConfirming, room, player, ref data); * CardUseStruct new_use = (CardUseStruct)data; * if (new_use.To.Count == 0) * { * p = player; * player.SetFlags(card_str + "_delay_trick_cancel"); * break; * } * * thread.Trigger(TriggerEvent.TargetChosen, room, null, ref data); * thread.Trigger(TriggerEvent.TargetConfirmed, room, player, ref data); */ CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_TRANSFER, string.Empty) { Card = card }; room.MoveCardTo(card, null, player, Place.PlaceDelayedTrick, reason, true); move = true; break; } } if (p != null) { OnNullified(room, p, card); } else if (!move) { //foreach (Player player in room.GetAllPlayers()) //if (player.HasFlag(RoomLogic.CardToString(room, card) + "_delay_trick_cancel")) //player.SetFlags(string.Format("-{0}{1}", card_str, "_delay_trick_cancel")); CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_NATURAL_ENTER, string.Empty); room.MoveCardTo(card, null, Place.DiscardPile, reason, true); } }