public void CardPosition(int id, out double x, out double y) { Card c = Card.Find(id); x = c.X; y = c.Y; }
public void CardMoveTo(int cardId, int groupId, int?position) { Card card = Card.Find(cardId); Group group = Group.Find(groupId); if (card.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't move {1} to {2} because they don't control {1}.", Player.LocalPlayer.Name, card.Name, card.Name)); } if (group.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't move {1} to {2} because they don't control {1}.", Player.LocalPlayer.Name, card.Name, group.Name)); } if (card.Group != Program.GameEngine.Table && card.Group.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't move {1} from {2} because they don't control it.", Player.LocalPlayer.Name, card, card.Group)); } QueueAction(() => { //Program.GameEngine.EventProxy.MuteEvents = true; if (position == null) { card.MoveTo(group, true, true); } else { card.MoveTo(group, true, position.Value, true); } //Program.GameEngine.EventProxy.MuteEvents = false; }); }
public string CardSetId(int id) { Card c = Card.Find(id); string setId = c.Type.Model.SetId.ToString(); return(setId); }
public string CardSet(int id) { Card c = Card.Find(id); string set = c.Type.Model.GetSet().Name; return(set); }
public void AddMarker(Player player, Card card, Guid id, string name, ushort count, ushort oldCount, bool isScriptChange) { var model = Program.GameEngine.GetMarkerModel(id); model.Name = name; var marker = card.FindMarker(id, name); if (player != Player.LocalPlayer) { if (marker == null && oldCount != 0) { Program.GameMess.Warning("Inconsistent state. Cannot create a marker when that marker already exists."); return; } if (marker != null && oldCount != marker.Count) { Program.GameMess.Warning("Inconsistent state. Marker count invalid."); return; } card.AddMarker(model, count); } if (count != 0) { var newCount = oldCount + count; Program.GameMess.PlayerEvent(player, "adds {0} {1} marker(s) on {2}", count, model.Name, card); if (isScriptChange == false) { Program.GameEngine.EventProxy.OnMarkerChanged_3_1_0_0(card, model.ModelString(), oldCount, newCount, isScriptChange); Program.GameEngine.EventProxy.OnMarkerChanged_3_1_0_1(card, model.ModelString(), oldCount, newCount, isScriptChange); } Program.GameEngine.EventProxy.OnMarkerChanged_3_1_0_2(card, model.Name, model.Id.ToString(), oldCount, isScriptChange); } }
//Set's the card's index to idx. Enforces a TableOnly rule, since the index's on other piles/groups are inverted. //ralig98 public void CardSetIndex(int CardId, int idx, bool TableOnly = false) { if (idx < 0) { Program.GameMess.Warning("Cannot setIndex({0}), number is less than 0", idx); return; } Card card = Card.Find(CardId); if (card.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't set index of {1} to Table because they don't control {1}.", Player.LocalPlayer.Name, card.Name)); } if (card.Group != Program.GameEngine.Table && card.Group.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't set index of {1} in {2} because they don't control it.", Player.LocalPlayer.Name, card, card.Group)); } if (!TableOnly || (TableOnly && card.Group is Table)) { QueueAction( () => { //Program.GameEngine.EventProxy.MuteEvents = true; card.MoveToTable((int)card.X, (int)card.Y, card.FaceUp, idx, true); //Program.GameEngine.EventProxy.MuteEvents = false; }); } }
public void CardSetAnchored(int cardId, bool anchored) { var card = Card.Find(cardId); if (card == null) { return; } if (card.Group.Definition.Id != Program.GameEngine.Definition.Table.Id) { Program.GameMess.Warning(String.Format("You can't anchor a card that's not on the table.")); return; } if (card.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't anchor {1} to Table because they don't control it.", Player.LocalPlayer.Name, card.Name)); return; } QueueAction(() => { if (card == null) { return; } card.SetAnchored(false, anchored); }); }
public object CardAlternateProperty(int id, string alt, string property) { Card c = Card.Find(id); property = property.ToLowerInvariant(); return(c.GetProperty(property, "", StringComparison.InvariantCultureIgnoreCase, alt)); }
public void CardSwitchTo(Player player, Card card, string alternate) { if (player.Id != Player.LocalPlayer.Id) { card.SwitchTo(player, alternate); } }
/// <summary>Creates new Cards as well as the corresponding CardIdentities. All cards are created in the same group.</summary> /// <param name="id">An array with the new CardIdentity ids.</param> /// <param name="type">An array containing the corresponding CardModel guids (encrypted)</param> /// <param name="group">The group, in which the cards are added.</param> /// <seealso cref="CreateCard(int[], ulong[], Group[])"> to add cards to several groups</seealso> public void CreateCard(int[] id, Guid[] type, string[] size, Group group) { var who = Player.Find((byte)(id[0] >> 16)); WriteReplayAction(who.Id); if (IsLocalPlayer(who)) { return; } for (var i = 0; i < id.Length; i++) { var owner = group.Owner; if (owner == null) { Program.GameMess.Warning("[CreateCard] Player not found."); return; } var c = Card.Find(id[0]); Program.GameMess.PlayerEvent(owner, "{0} creates {1} {2} in {3}'s {4}", owner.Name, id.Length, c == null ? "card" : (object)c, group.Owner.Name, group.Name); // Ignore cards created by oneself var card = new Card(owner, id[i], Program.GameEngine.Definition.GetCardById(type[i]), false, size[i]); group.AddAt(card, group.Count); } }
public void AddMarkerReq(Card card, Guid id, string name, ushort count, ushort origCount, bool isScriptChange) { //Log.Info("[ProtOut] AddMarkerReq"); if(Program.Client == null)return; MemoryStream stream = new MemoryStream(512); stream.Seek(4, SeekOrigin.Begin); BinaryWriter writer = new BinaryWriter(stream); if (Program.Client.Muted != 0) writer.Write(Program.Client.Muted); else writer.Write(0); writer.Write((byte)59); writer.Write(card.Id); writer.Write(id.ToByteArray()); writer.Write(name); writer.Write(count); writer.Write(origCount); writer.Write(isScriptChange); writer.Flush(); writer.Seek(0, SeekOrigin.Begin); writer.Write((int)stream.Length); writer.Close(); Send(stream.ToArray()); }
public void AddMarker(Player player, Card card, Guid id, string name, ushort count, ushort oldCount, bool isScriptChange) { DataNew.Entities.Marker model = Program.GameEngine.GetMarkerModel(id); DefaultMarkerModel defaultMarkerModel = model as DefaultMarkerModel; if (defaultMarkerModel != null) (defaultMarkerModel).SetName(name); Marker marker = card.FindMarker(id, name); if (player != Player.LocalPlayer) { if (marker == null && oldCount != 0) { Program.GameMess.Warning("Inconsistent state. Cannot create a marker when that marker already exists."); return; } if (marker != null && oldCount != marker.Count) { Program.GameMess.Warning("Inconsistent state. Marker count invalid."); return; } card.AddMarker(model, count); } if (count != 0) { int newCount = oldCount + count; Program.GameMess.PlayerEvent(player, "adds {0} {1} marker(s) on {2}", count, model.Name, card); if (isScriptChange == false) { Program.GameEngine.EventProxy.OnMarkerChanged_3_1_0_0(card, model.ModelString(), oldCount, newCount, isScriptChange); Program.GameEngine.EventProxy.OnMarkerChanged_3_1_0_1(card, model.ModelString(), oldCount, newCount, isScriptChange); } } }
// TODO: Replace this hack with an actual delete function. public void CardDelete(int cardId) { Card c = Card.Find(cardId); var card = c; if (c == null) { return; } if (card.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't delete {1} to Table because they don't control {1}.", Player.LocalPlayer.Name, card.Name)); } if (card.Group != Program.GameEngine.Table && card.Group.Controller != Player.LocalPlayer) { Program.GameMess.Warning(String.Format("{0} Can't delete {1} from {2} because they don't control it.", Player.LocalPlayer.Name, card, card.Group)); } if (c.Controller != Player.LocalPlayer) { Program.GameMess.Warning("Cannot delete({0}), because you do not control it. ", cardId); return; } QueueAction(() => { if (c == null) { return; } Program.Client.Rpc.DeleteCard(c, Player.LocalPlayer); c.Group.Remove(c); }); }
public int MarkerGetCount(int cardId, string markerName, string markerId) { Card card = Card.Find(cardId); Marker marker = card.FindMarker(markerId, markerName); return(marker == null ? 0 : marker.Count); }
public void DeleteCard(Card card, Player player) { Program.GameMess.PlayerEvent(player, "deletes {0}", card); if (player != Player.LocalPlayer) { card.Group.Remove(card); } }
public void CardSwitchTo(Player player, Card card, string alternate) { WriteReplayAction(player.Id); if (!IsLocalPlayer(player)) { card.SwitchTo(player, alternate); } }
public void SetCardProperty(Card card, Player player, string name, string val, string valtype) { if (player == Player.LocalPlayer) { return; } card.SetProperty(name, val, false); }
public void ResetCardProperties(Card card, Player player) { if (player == Player.LocalPlayer) { return; } card.ResetProperties(false); }
public void Rotate(Player player, Card card, CardOrientation rot) { // Ignore the moves we made ourselves if (player == Player.LocalPlayer) { return; } new Rotate(player, card, rot).Do(); }
public void ResetCardProperties(Card card, Player player) { WriteReplayAction(player.Id); if (IsLocalPlayer(player)) { return; } card.ResetProperties(false); }
public void SetCardProperty(Card card, Player player, string name, string val, string valtype) { WriteReplayAction(player.Id); if (IsLocalPlayer(player)) { return; } card.SetProperty(name, val, false); }
public void DeleteCard(Card card, Player player) { WriteReplayAction(player.Id); Program.GameMess.PlayerEvent(player, "deletes {0}", card); if (!IsLocalPlayer(player)) { card.Group.Remove(card); } }
public void CardPeek(int id) { Card c = Card.Find(id); QueueAction(() => { c.Peek(); }); }
public string CardModel(int id) //Why is this public? I would expect the model to be private - (V)_V // Ur dumb that's why. { Card c = Card.Find(id); //if (!c.FaceUp || c.Type.Model == null) return null; return(c.Type.Model.Id.ToString()); }
public void End() { Program.GameEngine = null; Player.Reset(); Card.Reset(); CardIdentity.Reset(); History.Reset(); Selection.Clear(); }
public void Untarget(Player player, Card card, bool isScriptChange) { // Ignore the card we targeted ourselves if (player == Player.LocalPlayer) { return; } new Target(player, card, null, false, isScriptChange).Do(); }
public void TargetArrow(Player player, Card card, Card otherCard, bool isScriptChange) { // Ignore the card we targeted ourselves if (player == Player.LocalPlayer) { return; } new Target(player, card, otherCard, true, isScriptChange).Do(); }
/// <summary>Creates new cards on the table, as well as the corresponding CardIdentities.</summary> /// <param name="id">An array with the new CardIdentity ids</param> /// <param name="modelId"> </param> /// <param name="x">The x position of the cards on the table.</param> /// <param name="y">The y position of the cards on the table.</param> /// <param name="faceUp">Whether the cards are face up or not.</param> /// <param name="key"> </param> /// <param name="persist"> </param> public void CreateCardAt(int[] id, Guid[] modelId, int[] x, int[] y, bool faceUp, bool persist) { if (id.Length == 0) { Program.GameMess.Warning("[CreateCardAt] Empty id parameter."); return; } if (id.Length != x.Length || id.Length != y.Length || id.Length != modelId.Length) { Program.GameMess.Warning("[CreateCardAt] Inconsistent parameters length."); return; } var owner = Player.Find((byte)(id[0] >> 16)); if (owner == null) { Program.GameMess.Warning("[CreateCardAt] Player not found."); return; } WriteReplayAction(owner.Id); var table = Program.GameEngine.Table; // Bring cards created by oneself to top, for z-order consistency if (IsLocalPlayer(owner)) { for (var i = id.Length - 1; i >= 0; --i) { var card = Card.Find(id[i]); if (card == null) { Program.GameMess.Warning("[CreateCardAt] Card not found."); return; } table.SetCardIndex(card, table.Count + i - id.Length); } } else { for (var i = 0; i < id.Length; i++) { new CreateCard(owner, id[i], faceUp, Program.GameEngine.Definition.GetCardById(modelId[i]), x[i], y[i], !persist).Do(); } } if (modelId.All(m => m == modelId[0])) { Program.GameMess.PlayerEvent(owner, "creates {1} '{2}'", owner, modelId.Length, IsLocalPlayer(owner) || faceUp ? Program.GameEngine.Definition.GetCardById(modelId[0]).Name : "card"); } else { foreach (var m in modelId) { Program.GameMess.PlayerEvent(owner, "{0} creates a '{1}'", owner, IsLocalPlayer(owner) || faceUp ? Program.GameEngine.Definition.GetCardById(m).Name : "card"); } } }
public void Untarget(Player player, Card card, bool isScriptChange) { WriteReplayAction(player.Id); // Ignore the card we targeted ourselves if (IsLocalPlayer(player)) { return; } new Target(player, card, null, false, isScriptChange).Do(); }
public void TargetArrow(Player player, Card card, Card otherCard, bool isScriptChange) { WriteReplayAction(player.Id); // Ignore the card we targeted ourselves if (IsLocalPlayer(player)) { return; } new Target(player, card, otherCard, true, isScriptChange).Do(); }
public void Rotate(Player player, Card card, CardOrientation rot) { WriteReplayAction(player.Id); // Ignore the moves we made ourselves if (IsLocalPlayer(player)) { return; } new Rotate(player, card, rot).Do(); }
public void Turn(Player player, Card card, bool up) { // Ignore the card we turned ourselves if (player == Player.LocalPlayer) { card.MayBeConsideredFaceUp = false; // see comment on mayBeConsideredFaceUp return; } new Turn(player, card, up).Do(); }
public void AddMarker(Player player, Card card, Guid id, string name, ushort count) { Data.MarkerModel model = Program.Game.GetMarkerModel(id); if (model is DefaultMarkerModel) ((DefaultMarkerModel)model).SetName(name); // Ignore markers created by oneself (already created for responsiveness issues) if (player != Player.LocalPlayer) card.AddMarker(model, count); if (count != 0) Program.Trace.TraceEvent(TraceEventType.Information, EventIds.Event | EventIds.PlayerFlag(player), "{0} adds {1} {2} marker(s) on {3}", player, count, model, card); }
public void AddMarkerReq(Card card, Guid id, string name, ushort count) { StringBuilder sb = new StringBuilder(); XmlWriter writer = XmlWriter.Create(sb, xmlSettings); writer.WriteStartElement("AddMarkerReq"); if(Program.Client.Muted != 0) writer.WriteAttributeString("muted", Program.Client.Muted.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("card", card.Id.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("id", id.ToString()); writer.WriteElementString("name", name); writer.WriteElementString("count", count.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); writer.Close(); Send(sb.ToString()); }
public void OnCardDoubleClick(Card card, int mouseButton, string[] keysDown) { Log.Info("Firing event OnCardDoubleClick"); var args = new object[3]; args[0] = card; args[1] = mouseButton; args[2] = keysDown; if(Program.GameEngine.Definition.Events.ContainsKey("OnCardDoubleClick")) { foreach(var e in Program.GameEngine.Definition.Events["OnCardDoubleClick"]) { Log.InfoFormat("Firing event OnCardDoubleClick -> {0}",e.Name); engine.ExecuteFunction(e.PythonFunction,card, mouseButton, keysDown); } } }
public void CardSwitchTo(Player player, Card card, string alternate) { MemoryStream stream = new MemoryStream(512); stream.Seek(4, SeekOrigin.Begin); BinaryWriter writer = new BinaryWriter(stream); if (Program.Client.Muted != 0) writer.Write(Program.Client.Muted); else writer.Write(0); writer.Write((byte)87); writer.Write(player.Id); writer.Write(card.Id); writer.Write(alternate); writer.Flush(); writer.Seek(0, SeekOrigin.Begin); writer.Write((int)stream.Length); writer.Close(); Send(stream.ToArray()); }
public void AddMarkerReq(Card card, Guid id, string name, ushort count) { MemoryStream stream = new MemoryStream(512); stream.Seek(4, SeekOrigin.Begin); BinaryWriter writer = new BinaryWriter(stream); if (Program.Client.Muted != 0) writer.Write(Program.Client.Muted); else writer.Write(0); writer.Write((byte)56); writer.Write(card.Id); writer.Write(id.ToByteArray()); writer.Write(name); writer.Write(count); writer.Flush(); writer.Seek(0, SeekOrigin.Begin); writer.Write((int)stream.Length); writer.Close(); Send(stream.ToArray()); }
public void AnchorCard(Card id, Player player, bool anchor) { //Log.Info("[ProtOut] AnchorCard"); if(Program.Client == null)return; MemoryStream stream = new MemoryStream(512); stream.Seek(4, SeekOrigin.Begin); BinaryWriter writer = new BinaryWriter(stream); if (Program.Client.Muted != 0) writer.Write(Program.Client.Muted); else writer.Write(0); writer.Write((byte)97); writer.Write(id.Id); writer.Write(player.Id); writer.Write(anchor); writer.Flush(); writer.Seek(0, SeekOrigin.Begin); writer.Write((int)stream.Length); writer.Close(); Send(stream.ToArray()); }
public void IsAlternateImage(Card c, bool isAlternateImage) { c.IsAlternateImage = isAlternateImage; }
/// <summary>Creates new Cards as well as the corresponding CardIdentities. The cards may be in different groups.</summary> /// <param name="id">An array with the new CardIdentity ids.</param> /// <param name="type">An array containing the corresponding CardModel guids (encrypted)</param> /// <param name="groups">An array indicating the group the cards must be loaded into.</param> /// <seealso cref="CreateCard(int[], ulong[], Group)"> for a more efficient way to insert cards inside one group.</seealso> private static void CreateCard(IList<int> id, IList<ulong> type, IList<Group> groups) { Player owner = Player.Find((byte)(id[0] >> 16)); if (owner == null) { Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[CreateCard] Player not found."); return; } // Ignore cards created by oneself if (owner == Player.LocalPlayer) return; for (int i = 0; i < id.Count; i++) { Card c = new Card(owner, id[i], type[i], null, false); Group group = groups[i]; group.AddAt(c, group.Count); } }
/// <summary>Creates new Cards as well as the corresponding CardIdentities. All cards are created in the same group.</summary> /// <param name="id">An array with the new CardIdentity ids.</param> /// <param name="type">An array containing the corresponding CardModel guids (encrypted)</param> /// <param name="group">The group, in which the cards are added.</param> /// <seealso cref="CreateCard(int[], ulong[], Group[])"> to add cards to several groups</seealso> public void CreateCard(int[] id, ulong[] type, Group group) { Player owner = Player.Find((byte)(id[0] >> 16)); if (owner == null) { Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[CreateCard] Player not found."); return; } //var c = new Card(owner,id[0], type[0], Program.Game.Definition.CardDefinition, null, false); var c = Card.Find(id[0]); Program.TracePlayerEvent(owner, "{0} creates {1} {2} in {3}'s {4}", owner.Name, id.Length, c == null ? "card" : c.Name, group.Owner.Name,group.Name); // Ignore cards created by oneself if (owner == Player.LocalPlayer) return; for (int i = 0; i < id.Length; i++) { //Card c = new Card(owner, id[i], type[i], Program.Game.Definition.CardDefinition, null, false); //group.AddAt(c, group.Count); var card = new Card(owner,id[i], type[i], null, false); group.AddAt(card, group.Count); } }
public void Untarget(Player player, Card card) { // Ignore the card we targeted ourselves if (player == Player.LocalPlayer) return; new Target(player, card, null, false).Do(); }
public void MoveCardAt(Player player, Card card, int x, int y, int idx, bool faceUp) { // Get the table control Table table = Program.GameEngine.Table; // Because every player may manipulate the table at the same time, the index may be out of bound if (card.Group == table) { if (idx >= table.Count) idx = table.Count - 1; } else if (idx > table.Count) idx = table.Count; // Ignore cards moved by the local player (already done, for responsiveness) if (player == Player.LocalPlayer) { // See remark in MoveCard if (card.Group == table) card.SetIndex(idx); // This is done to preserve stack order consistency with other players (should be a noop most of the time) return; } // Find the old position on the table, if any //bool onTable = card.Group == table; //double oldX = card.X, oldY = card.Y; // Do the move new MoveCard(player, card, x, y, idx, faceUp).Do(); }
public void SetMarker(Player player, Card card, Guid id, string name, ushort count) { // Always perform this call (even if player == LocalPlayer) for consistency as markers aren't an exclusive resource card.SetMarker(player, id, name, count); }
public void OnMoveCards_3_1_0_1(Player player, Card[] cards, Group[] fromGroups, Group[] toGroups, int[] oldIndexs, int[] indexs, int[] oldX, int[] oldY, int[] x, int[] y, string[] highlights, string[] markers, bool[] faceups) { if(Player.LocalPlayer.Spectator)return; if(MuteEvents)return; if(gameEngine.Definition.ScriptVersion != C_3_1_0_1 ) return; var thisVersion = Version.Parse("3.1.0.1"); dynamic args = new System.Dynamic.ExpandoObject(); if(thisVersion >= BASEOBJECTVERSION) { args.player = player; args.cards = cards; args.fromGroups = fromGroups; args.toGroups = toGroups; args.oldIndexs = oldIndexs; args.indexs = indexs; args.oldX = oldX; args.oldY = oldY; args.x = x; args.y = y; args.highlights = highlights; args.markers = markers; args.faceups = faceups; } foreach(var e in eventCache["OnMoveCards"]) { if(thisVersion < BASEOBJECTVERSION) engine.ExecuteFunction(e.PythonFunction,player, cards, fromGroups, toGroups, oldIndexs, indexs, oldX, oldY, x, y, highlights, markers, faceups); else { engine.ExecuteFunction(e.PythonFunction, args); } } }
public void SwitchWithAlternate(Card c) { c.SwitchWithAlternate(); }
public void Rotate(Player player, Card card, CardOrientation rot) { // Ignore the moves we made ourselves if (player == Player.LocalPlayer) return; new Rotate(player, card, rot).Do(); }
public void Highlight(Card card, Color? color) { card.SetHighlight(color); }
/// <summary>Reveal one card's identity</summary> /// <param name="card">The card, whose identity is revealed</param> /// <param name="revealed">Either the salted CardIdentity id (in the case of an alias), or the salted, condensed Card GUID.</param> /// <param name="guid"> </param> public void Reveal(Card card, ulong revealed, Guid guid) { // Save old id CardIdentity oldType = card.Type; // Check if the card is rightfully revealed if (!card.Type.Revealing) Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "Someone tries to reveal a card which is not visible to everybody."); // Check if we can trust other clients if (!card.Type.MySecret) { if (guid != Guid.Empty && (uint)revealed != guid.Condense()) Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[Reveal] Alias and id aren't the same. One client is buggy or tries to cheat."); if (Crypto.ModExp(revealed) != card.Type.Key) Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[Reveal] Card identity doesn't match. One client is buggy or tries to cheat."); } else card.Type.MySecret = false; // Reveal an alias if (guid == Guid.Empty) { // Find the new type CardIdentity newId = CardIdentity.Find((int)revealed); // HACK: it is unclear to me how the CardIdentity could not be found and newId ends up null // see this bug report: https://octgn.16bugs.com/projects/3602/bugs/192070 // for now I'm just doing nothing (supposing that it means the type was already revealed). if (newId == null) { card.Reveal(); return; } // Possibly copy the model, if it was known and isn't anymore // (possible when the alias has beeen locally revealed) if (newId.Model == null) newId.Model = card.Type.Model; // Set the new type card.Type = newId; // Delete the old identity CardIdentity.Delete(oldType.Id); // Possibly reveal the alias further card.Reveal(); // Raise a notification oldType.OnRevealed(newId); } // Reveal a card's type else if (card.Type.Model == null) { card.SetModel(Program.GameEngine.Definition.GetCardById(guid)); // Raise a notification oldType.OnRevealed(oldType); } }
public void Peek(Player player, Card card) { if (!card.PeekingPlayers.Contains(player)) card.PeekingPlayers.Add(player); card.RevealTo(Enumerable.Repeat(player, 1)); if (player != Player.LocalPlayer) { Program.TracePlayerEvent(player, "{0} peeks at a card ({1}).", player, card.Group is Table ? "on table" : "in " + card.Group.FullName); } }
/// <summary>Creates new Cards as well as the corresponding CardIdentities. All cards are created in the same group.</summary> /// <param name="id">An array with the new CardIdentity ids.</param> /// <param name="type">An array containing the corresponding CardModel guids (encrypted)</param> /// <param name="group">The group, in which the cards are added.</param> /// <seealso cref="CreateCard(int[], ulong[], Group[])"> to add cards to several groups</seealso> public void CreateCard(int[] id, ulong[] type, Group group) { Player owner = Player.Find((byte)(id[0] >> 16)); if (owner == null) { Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.Event, "[CreateCard] Player not found."); return; } // Ignore cards created by oneself if (owner == Player.LocalPlayer) return; for (int i = 0; i < id.Length; i++) { Card c = new Card(owner, id[i], type[i], Program.Game.Definition.CardDefinition, null, false); group.AddAt(c, group.Count); } }
public void TargetArrow(Player player, Card card, Card otherCard) { // Ignore the card we targeted ourselves if (player == Player.LocalPlayer) return; new Target(player, card, otherCard, true).Do(); }
public void OnMoveCard_3_1_0_1(Player player, Card card, Group fromGroup, Group toGroup, int oldIndex, int index, int oldX, int oldY, int x, int y, bool faceup, string highlight, string markers) { if(Player.LocalPlayer.Spectator)return; if(MuteEvents)return; if(gameEngine.Definition.ScriptVersion != C_3_1_0_1 ) return; var thisVersion = Version.Parse("3.1.0.1"); dynamic args = new System.Dynamic.ExpandoObject(); if(thisVersion >= BASEOBJECTVERSION) { args.player = player; args.card = card; args.fromGroup = fromGroup; args.toGroup = toGroup; args.oldIndex = oldIndex; args.index = index; args.oldX = oldX; args.oldY = oldY; args.x = x; args.y = y; args.faceup = faceup; args.highlight = highlight; args.markers = markers; } foreach(var e in eventCache["OnMoveCard"]) { if(thisVersion < BASEOBJECTVERSION) engine.ExecuteFunction(e.PythonFunction,player, card, fromGroup, toGroup, oldIndex, index, oldX, oldY, x, y, faceup, highlight, markers); else { engine.ExecuteFunction(e.PythonFunction, args); } } }
public void TransferMarker(Player player, Card from, Card to, Guid id, string name, ushort count) { // Ignore markers moved by oneself (already moved for responsiveness issues) if (player != Player.LocalPlayer) { Marker marker = from.FindMarker(id, name); if (marker == null) { Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.NonGame, "Inconsistent state. Marker not found on card."); return; } if (marker.Count < count) Program.Trace.TraceEvent(TraceEventType.Warning, EventIds.NonGame, "Inconsistent state. Missing markers to remove"); from.RemoveMarker(marker, count); to.AddMarker(marker.Model, count); } Program.Trace.TraceEvent(TraceEventType.Information, EventIds.Event | EventIds.PlayerFlag(player), "{0} moves {1} {2} marker(s) from {3} to {4}", player, count, name, from, to); }
public void OnMarkerChanged_3_1_0_1(Card card, string markerName, int oldValue, int newValue, bool isScriptChange) { if(Player.LocalPlayer.Spectator)return; if(MuteEvents)return; if(gameEngine.Definition.ScriptVersion != C_3_1_0_1 ) return; var thisVersion = Version.Parse("3.1.0.1"); dynamic args = new System.Dynamic.ExpandoObject(); if(thisVersion >= BASEOBJECTVERSION) { args.card = card; args.markerName = markerName; args.oldValue = oldValue; args.newValue = newValue; args.isScriptChange = isScriptChange; } foreach(var e in eventCache["OnMarkerChanged"]) { if(thisVersion < BASEOBJECTVERSION) engine.ExecuteFunction(e.PythonFunction,card, markerName, oldValue, newValue, isScriptChange); else { engine.ExecuteFunction(e.PythonFunction, args); } } }
public void Turn(Player player, Card card, bool up) { // Ignore the card we turned ourselves if (player == Player.LocalPlayer) { card.MayBeConsideredFaceUp = false; // see comment on mayBeConsideredFaceUp return; } new Turn(player, card, up).Do(); }
public void CardSwitchTo(Player player, Card card, string alternate) { if(player.Id != Player.LocalPlayer.Id) card.SwitchTo(player, alternate); }
public void MoveCard(Player player, Card card, Group to, int idx, bool faceUp) { // Ignore cards moved by the local player (already done, for responsiveness) if (player != Player.LocalPlayer) new MoveCard(player, card, to, idx, faceUp).Do(); else { // Fix: cards may move quickly locally from one group to another one, before we get a chance // to execute this handler, during game actions scripts (e.g. Mulligan with one player - // shuffling happens locally). The result is that we are going to receive two messages, // one for the move to group A, then the move to group B; while the card already is in group B. // In this case, trying to set index inside group B with an index coming from the time the card // was in group A is just plain wrong and may crash depending on the index. if (card.Group == to) card.SetIndex(idx); // This is done to preserve stack order consistency with other players (should be a noop most of the time) } }
public void OnMarkerChanged_3_1_0_2(Card card, string marker, string id, int value, bool scripted) { if(Player.LocalPlayer.Spectator)return; if(MuteEvents)return; if(gameEngine.Definition.ScriptVersion != C_3_1_0_2 ) return; var thisVersion = Version.Parse("3.1.0.2"); dynamic args = new System.Dynamic.ExpandoObject(); if(thisVersion >= BASEOBJECTVERSION) { args.card = card; args.marker = marker; args.id = id; args.value = value; args.scripted = scripted; } foreach(var e in eventCache["OnMarkerChanged"]) { if(thisVersion < BASEOBJECTVERSION) engine.ExecuteFunction(e.PythonFunction,card, marker, id, value, scripted); else { engine.ExecuteFunction(e.PythonFunction, args); } } }
/// <summary>Reveal a card's identity to one player only.</summary> /// <param name="players"> </param> /// <param name="card">The card, whose identity is revealed.</param> /// <param name="encrypted">Either a ulong[2] containing an encrypted aliased CardIdentity id. Or a ulong[5] containing an encrypted CardModel guid.</param> public void RevealTo(Player[] players, Card card, ulong[] encrypted) { var oldType = card.Type; ulong alias = 0; Guid id = Guid.Empty; players = players.Where(x => x != null).ToArray(); switch (encrypted.Length) { case 2: alias = Crypto.Decrypt(encrypted); break; case 5: id = Crypto.DecryptGuid(encrypted); break; default: Program.TraceWarning("[RevealTo] Invalid data received."); return; } if (!players.All(p => (card.Group.Visibility == DataNew.Entities.GroupVisibility.Custom && card.Group.Viewers.Contains(p)) || card.PlayersLooking.Contains(p) || card.PeekingPlayers.Contains(p))) Program.TraceWarning("[RevealTo] Revealing a card to a player, who isn't allowed to see it. This indicates a bug or cheating."); // If it's an alias, we must revealed it to the final recipient bool sendToMyself = true; if (alias != 0) { sendToMyself = false; CardIdentity ci = CardIdentity.Find((int)alias); if (ci == null) { Program.TraceWarning("[RevealTo] Identity not found."); return; } // If the revealed type is an alias, pass it to the one who owns it to continue the RevealTo chain. if (ci.Alias) { Player p = Player.Find((byte)(ci.Key >> 16)); Program.Client.Rpc.RevealToReq(p, players, card, Crypto.Encrypt(ci.Key, p.PublicKey)); } // Else revealed the card model to the ones, who must see it else { Player[] pArray = new Player[1]; foreach (Player p in players) if (p != Player.LocalPlayer) { pArray[0] = p; Program.Client.Rpc.RevealToReq(p, pArray, card, Crypto.Encrypt(ci.Model.Id, p.PublicKey)); } else { sendToMyself = true; id = ci.Model.Id; } } } // Else it's a type and we are the final recipients if (!sendToMyself) return; if (card.Type.Model == null) card.SetModel(Program.GameEngine.Definition.GetCardById(id)); // Raise a notification oldType.OnRevealed(card.Type); }