Commit 00a9daa6 authored by Momobako's avatar Momobako

merge

parents 0cc630ff 9a3e147a
...@@ -151,14 +151,14 @@ namespace WindBot.Game.AI ...@@ -151,14 +151,14 @@ namespace WindBot.Game.AI
return bestMonster; return bestMonster;
} }
public ClientCard GetOneEnemyBetterThanValue(int value, bool onlyATK = false) public ClientCard GetOneEnemyBetterThanValue(int value, bool onlyATK = false, bool canBeTarget = false)
{ {
ClientCard bestCard = null; ClientCard bestCard = null;
int bestValue = value; int bestValue = value;
for (int i = 0; i < 7; ++i) for (int i = 0; i < 7; ++i)
{ {
ClientCard card = Enemy.MonsterZone[i]; ClientCard card = Enemy.MonsterZone[i];
if (card == null || card.Data == null) continue; if (card == null || card.Data == null || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (onlyATK && card.IsDefense()) continue; if (onlyATK && card.IsDefense()) continue;
int enemyValue = card.GetDefensePower(); int enemyValue = card.GetDefensePower();
if (enemyValue >= bestValue) if (enemyValue >= bestValue)
...@@ -170,52 +170,52 @@ namespace WindBot.Game.AI ...@@ -170,52 +170,52 @@ namespace WindBot.Game.AI
return bestCard; return bestCard;
} }
public ClientCard GetOneEnemyBetterThanMyBest(bool onlyATK = false) public ClientCard GetOneEnemyBetterThanMyBest(bool onlyATK = false, bool canBeTarget = false)
{ {
int bestBotPower = GetBestPower(Bot, onlyATK); int bestBotPower = GetBestPower(Bot, onlyATK);
return GetOneEnemyBetterThanValue(bestBotPower, onlyATK); return GetOneEnemyBetterThanValue(bestBotPower, onlyATK, canBeTarget);
} }
public ClientCard GetProblematicEnemyCard(int attack = 0) public ClientCard GetProblematicEnemyCard(int attack = 0, bool canBeTarget = false)
{ {
ClientCard card = Enemy.MonsterZone.GetFloodgate(); ClientCard card = Enemy.MonsterZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.SpellZone.GetFloodgate(); card = Enemy.SpellZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetDangerousMonster(); card = Enemy.MonsterZone.GetDangerousMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetInvincibleMonster(); card = Enemy.MonsterZone.GetInvincibleMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
if (attack == 0) if (attack == 0)
attack = GetBestAttack(Bot); attack = GetBestAttack(Bot);
return GetOneEnemyBetterThanValue(attack, true); return GetOneEnemyBetterThanValue(attack, true, canBeTarget);
} }
public ClientCard GetProblematicEnemyMonster(int attack = 0) public ClientCard GetProblematicEnemyMonster(int attack = 0, bool canBeTarget = false)
{ {
ClientCard card = Enemy.MonsterZone.GetFloodgate(); ClientCard card = Enemy.MonsterZone.GetFloodgate(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetDangerousMonster(); card = Enemy.MonsterZone.GetDangerousMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetInvincibleMonster(); card = Enemy.MonsterZone.GetInvincibleMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
if (attack == 0) if (attack == 0)
attack = GetBestAttack(Bot); attack = GetBestAttack(Bot);
return GetOneEnemyBetterThanValue(attack, true); return GetOneEnemyBetterThanValue(attack, true, canBeTarget);
} }
public ClientCard GetProblematicEnemySpell() public ClientCard GetProblematicEnemySpell()
...@@ -224,9 +224,9 @@ namespace WindBot.Game.AI ...@@ -224,9 +224,9 @@ namespace WindBot.Game.AI
return card; return card;
} }
public ClientCard GetBestEnemyCard(bool onlyFaceup = false) public ClientCard GetBestEnemyCard(bool onlyFaceup = false, bool canBeTarget = false)
{ {
ClientCard card = GetBestEnemyMonster(onlyFaceup); ClientCard card = GetBestEnemyMonster(onlyFaceup, canBeTarget);
if (card != null) if (card != null)
return card; return card;
...@@ -237,20 +237,20 @@ namespace WindBot.Game.AI ...@@ -237,20 +237,20 @@ namespace WindBot.Game.AI
return null; return null;
} }
public ClientCard GetBestEnemyMonster(bool onlyFaceup = false) public ClientCard GetBestEnemyMonster(bool onlyFaceup = false, bool canBeTarget = false)
{ {
ClientCard card = GetProblematicEnemyMonster(); ClientCard card = GetProblematicEnemyMonster(0, canBeTarget);
if (card != null) if (card != null)
return card; return card;
card = Enemy.MonsterZone.GetHighestAttackMonster(); card = Enemy.MonsterZone.GetHighestAttackMonster(canBeTarget);
if (card != null) if (card != null)
return card; return card;
List<ClientCard> monsters = Enemy.GetMonsters(); List<ClientCard> monsters = Enemy.GetMonsters();
// after GetHighestAttackMonster, the left monsters must be face-down. // after GetHighestAttackMonster, the left monsters must be face-down.
if (monsters.Count > 0 && !onlyFaceup) if (monsters.Count > 0 && !onlyFaceup && (!canBeTarget || !card.IsShouldNotBeTarget()))
return monsters[0]; return monsters[0];
return null; return null;
......
...@@ -6,13 +6,13 @@ namespace WindBot.Game.AI ...@@ -6,13 +6,13 @@ namespace WindBot.Game.AI
{ {
public static class CardContainer public static class CardContainer
{ {
public static ClientCard GetHighestAttackMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetHighestAttackMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int highestAtk = 0; int highestAtk = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (card.HasType(CardType.Monster) && card.Attack > highestAtk) if (card.HasType(CardType.Monster) && card.Attack > highestAtk)
{ {
highestAtk = card.Attack; highestAtk = card.Attack;
...@@ -22,13 +22,13 @@ namespace WindBot.Game.AI ...@@ -22,13 +22,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetHighestDefenseMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetHighestDefenseMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int highestDef = 0; int highestDef = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (card.HasType(CardType.Monster) && card.Defense > highestDef) if (card.HasType(CardType.Monster) && card.Defense > highestDef)
{ {
highestDef = card.Defense; highestDef = card.Defense;
...@@ -38,13 +38,13 @@ namespace WindBot.Game.AI ...@@ -38,13 +38,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetLowestAttackMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetLowestAttackMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int lowestAtk = 0; int lowestAtk = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (lowestAtk == 0 && card.HasType(CardType.Monster) || if (lowestAtk == 0 && card.HasType(CardType.Monster) ||
card.HasType(CardType.Monster) && card.Attack < lowestAtk) card.HasType(CardType.Monster) && card.Attack < lowestAtk)
{ {
...@@ -55,13 +55,13 @@ namespace WindBot.Game.AI ...@@ -55,13 +55,13 @@ namespace WindBot.Game.AI
return selected; return selected;
} }
public static ClientCard GetLowestDefenseMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetLowestDefenseMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
int lowestDef = 0; int lowestDef = 0;
ClientCard selected = null; ClientCard selected = null;
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card == null || card.Data == null || card.IsFacedown()) continue; if (card == null || card.Data == null || card.IsFacedown() || (canBeTarget && card.IsShouldNotBeTarget())) continue;
if (lowestDef == 0 && card.HasType(CardType.Monster) || if (lowestDef == 0 && card.HasType(CardType.Monster) ||
card.HasType(CardType.Monster) && card.Defense < lowestDef) card.HasType(CardType.Monster) && card.Defense < lowestDef)
{ {
...@@ -149,31 +149,31 @@ namespace WindBot.Game.AI ...@@ -149,31 +149,31 @@ namespace WindBot.Game.AI
return cardlist; return cardlist;
} }
public static ClientCard GetInvincibleMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetInvincibleMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsMonsterInvincible() && card.IsFaceup()) if (card != null && card.IsMonsterInvincible() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
} }
public static ClientCard GetDangerousMonster(this IEnumerable<ClientCard> cards) public static ClientCard GetDangerousMonster(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsMonsterDangerous() && card.IsFaceup()) if (card != null && card.IsMonsterDangerous() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
} }
public static ClientCard GetFloodgate(this IEnumerable<ClientCard> cards) public static ClientCard GetFloodgate(this IEnumerable<ClientCard> cards, bool canBeTarget = false)
{ {
foreach (ClientCard card in cards) foreach (ClientCard card in cards)
{ {
if (card != null && card.IsFloodgate() && card.IsFaceup()) if (card != null && card.IsFloodgate() && card.IsFaceup() && (!canBeTarget || !card.IsShouldNotBeTarget()))
return card; return card;
} }
return null; return null;
......
...@@ -29,6 +29,38 @@ namespace WindBot.Game.AI ...@@ -29,6 +29,38 @@ namespace WindBot.Game.AI
return !card.IsDisabled() && Enum.IsDefined(typeof(PreventActivationEffectInBattle), card.Id); return !card.IsDisabled() && Enum.IsDefined(typeof(PreventActivationEffectInBattle), card.Id);
} }
/// <summary>
/// Is this card shouldn't be tried to be selected as target?
/// </summary>
public static bool IsShouldNotBeTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeTarget), card.Id);
}
/// <summary>
/// Is this card shouldn't be tried to be selected as target of monster?
/// </summary>
public static bool IsShouldNotBeMonsterTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeMonsterTarget), card.Id);
}
/// <summary>
/// Is this card shouldn't be tried to be selected as target of spell & trap?
/// </summary>
public static bool IsShouldNotBeSpellTrapTarget(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldNotBeSpellTrapTarget), card.Id);
}
/// <summary>
/// Is this monster should be disabled (with Breakthrough Skill) before it use effect and release or banish itself?
/// </summary>
public static bool IsMonsterShouldBeDisabledBeforeItUseEffect(this ClientCard card)
{
return !card.IsDisabled() && Enum.IsDefined(typeof(ShouldBeDisabledBeforeItUseEffectMonster), card.Id);
}
public static bool IsFloodgate(this ClientCard card) public static bool IsFloodgate(this ClientCard card)
{ {
return Enum.IsDefined(typeof(Floodgate), card.Id); return Enum.IsDefined(typeof(Floodgate), card.Id);
......
...@@ -292,7 +292,7 @@ namespace WindBot.Game.AI.Decks ...@@ -292,7 +292,7 @@ namespace WindBot.Game.AI.Decks
} }
if (CanDealWithUsedAlternativeWhiteDragon()) if (CanDealWithUsedAlternativeWhiteDragon())
{ {
target = AI.Utils.GetBestEnemyMonster(); target = AI.Utils.GetBestEnemyMonster(false, true);
AI.SelectCard(target); AI.SelectCard(target);
UsedAlternativeWhiteDragon.Add(Card); UsedAlternativeWhiteDragon.Add(Card);
return true; return true;
......
...@@ -497,7 +497,7 @@ namespace WindBot.Game.AI.Decks ...@@ -497,7 +497,7 @@ namespace WindBot.Game.AI.Decks
ClientCard target = AI.Utils.GetProblematicEnemyMonster(); ClientCard target = AI.Utils.GetProblematicEnemyMonster();
if (target == null && AI.Utils.IsChainTarget(Card)) if (target == null && AI.Utils.IsChainTarget(Card))
{ {
target = AI.Utils.GetBestEnemyMonster(); target = AI.Utils.GetBestEnemyMonster(true, true);
} }
if (target != null) if (target != null)
{ {
......
...@@ -527,7 +527,7 @@ namespace WindBot.Game.AI.Decks ...@@ -527,7 +527,7 @@ namespace WindBot.Game.AI.Decks
private bool FairyTailSnowsummon() private bool FairyTailSnowsummon()
{ {
ClientCard target = AI.Utils.GetBestEnemyMonster(true); ClientCard target = AI.Utils.GetBestEnemyMonster(true, true);
if(target != null) if(target != null)
{ {
return true; return true;
...@@ -541,7 +541,7 @@ namespace WindBot.Game.AI.Decks ...@@ -541,7 +541,7 @@ namespace WindBot.Game.AI.Decks
if (Card.Location == CardLocation.MonsterZone) if (Card.Location == CardLocation.MonsterZone)
{ {
AI.SelectCard(AI.Utils.GetBestEnemyMonster(true)); AI.SelectCard(AI.Utils.GetBestEnemyMonster(true, true));
return true; return true;
} }
else else
......
...@@ -310,15 +310,31 @@ namespace WindBot.Game.AI ...@@ -310,15 +310,31 @@ namespace WindBot.Game.AI
} }
/// <summary> /// <summary>
/// Chain the enemy monster. /// Chain the enemy monster, or disable monster like Rescue Rabbit.
/// </summary> /// </summary>
protected bool DefaultBreakthroughSkill() protected bool DefaultBreakthroughSkill()
{ {
if (!DefaultUniqueTrap())
return false;
if (Duel.Player == 1)
{
foreach (ClientCard target in Enemy.GetMonsters())
{
if (target.IsMonsterShouldBeDisabledBeforeItUseEffect())
{
AI.SelectCard(target);
return true;
}
}
}
ClientCard LastChainCard = AI.Utils.GetLastChainCard(); ClientCard LastChainCard = AI.Utils.GetLastChainCard();
if (LastChainCard == null) if (LastChainCard == null)
return false; return false;
if (LastChainCard.Controller != 1 || LastChainCard.Location != CardLocation.MonsterZone || !DefaultUniqueTrap()) if (LastChainCard.Controller != 1 || LastChainCard.Location != CardLocation.MonsterZone
|| LastChainCard.IsDisabled() || LastChainCard.IsShouldNotBeTarget() || LastChainCard.IsShouldNotBeSpellTrapTarget())
return false; return false;
AI.SelectCard(LastChainCard); AI.SelectCard(LastChainCard);
return true; return true;
......
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Monsters that release or banish itself to use effect. So them should be disabled (with Breakthrough Skill) before it use effect.
/// </summary>
public enum ShouldBeDisabledBeforeItUseEffectMonster
{
MachinaMegaform = 51617185,
DarkSummoningBeast = 87917187,
GemKnightAlexandrite = 90019393,
RedEyesRetroDragon = 53485634,
DeepSweeper = 8649148,
BeastWarriorPuma = 16796157,
ZefrasaberSwordmasteroftheNekroz = 84388461,
CipherWing = 81974607,
MadolcheAnjelly = 34680482,
PlanetPathfinder = 97526666,
RescueCat = 14878871,
RescueHamster = 50485594,
RescueFerret = 56343672,
RescueRabbit = 85138716,
GalaxyWizard = 98555327,
Backlinker = 71172240,
Merlin = 3580032,
CrystalVanguard = 87475570,
Kuribandit = 16404809,
PhotonLizard = 38973775,
SuperheavySamuraiFlutist = 27978707,
ConstellarRasalhague = 70624184,
CardcarD = 45812361,
UnifloraMysticalBeastoftheForest = 36318200,
BusterWhelpoftheDestructionSwordsman = 49823708,
GalaxyEyesCloudragon = 9260791,
SylvanPrincessprout = 20579538,
AltergeistPixiel = 57769391,
AbyssActorExtras = 88412339,
PerformapalTrumpWitch = 91584698,
RaidraptorLastStrix = 97219708,
TimeMaiden = 27107590,
SuperQuantalFairyAlphan = 58753372,
TheBlackStoneofLegend = 66574418,
PaladinofDarkDragon = 71408082,
PaladinofPhotonDragon = 85346853,
TwinPhotonLizard = 29455728
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target of monster's effect, or immuned to monster's effect.
/// So them shouldn't be tried to be selected as target of monster at most times.
/// </summary>
public enum ShouldNotBeMonsterTarget
{
TheLegendaryFishermanII = 19801646,
FirstoftheDragons = 10817524,
Tatsunoko = 55863245,
CXyzSimontheGreatMoralLeader = 41147577,
PaleozoicAnomalocaris = 61307542,
PaleozoicOpabinia = 37649320,
BorreloadDragon = 31833038
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target of spell&trap's effect, or immuned to spell&trap's effect.
/// So them shouldn't be tried to be selected as target of spell&trap at most times.
/// </summary>
public enum ShouldNotBeSpellTrapTarget
{
ApoqliphortTowers = 27279764,
ApoqliphortSkybase = 40061558,
TheLegendaryFishermanIII = 44968687,
ChaosAncientGearGiant = 51788412
}
}
namespace WindBot.Game.AI.Enums
{
/// <summary>
/// Cards that are can't be selected as target, or immuned to most effect.
/// So them shouldn't be tried to be selected as target at most times.
/// </summary>
public enum ShouldNotBeTarget
{
DivineSerpentGeh = 82103466,
ObelisktheTormentor = 10000000,
TheWingedDragonofRaSphereMode = 10000080,
TheWingedDragonofRaImmortalPhoenix = 10000090,
KozmoDarkPlanet = 85991529,
ZushintheSleepingGiant = 67547370,
TheLegendaryExodiaIncarnate = 58604027,
KozmoDarkEclipser = 64063868,
KozmoDarkDestroyer = 55885348,
KozmoForerunner = 20849090,
MajespecterUnicornKirin = 31178212,
WorldLegacyWorldShield = 55787576,
KiwiMagicianGirl = 82627406,
MajespecterFoxKyubi = 94784213,
MajespecterToadOgama = 645794,
MajespecterCrowYata = 68395509,
MajespecterRaccoonBunbuku = 31991800,
MajespecterCatNekomata = 5506791,
HazyFlameHydra = 8696773,
HazyFlameMantikor = 96051150,
HazyFlameHyppogrif = 31303283,
HazyFlameCerbereus = 38525760,
HazyFlameSphynx = 1409474,
HazyFlamePeryton = 37803172,
HazyFlameGriffin = 74010769,
BlueEyesChaosMAXDragon = 55410871,
SupremeKingZARC = 13331639,
CrimsonNovaTrinitytheDarkCubicLord = 72664875,
LunalightLeoDancer = 24550676,
TimaeustheKnightofDestiny = 53315891,
DantePilgrimoftheBurningAbyss = 18386170,
AncientGearHowitzer = 87182127,
InvokedCocytus = 85908279,
LyriluscIndependentNightingale = 76815942,
FlowerCardianLightshower = 42291297,
YaziEviloftheYangZing = 43202238,
RaidraptorUltimateFalcon = 86221741,
DisdainfulBirdofParadise = 27240101
}
}
...@@ -156,6 +156,12 @@ namespace WindBot.Game.AI ...@@ -156,6 +156,12 @@ namespace WindBot.Game.AI
return -1; return -1;
} }
public virtual int OnSelectPlace(int cardId, int player, int location, int available)
{
// For overriding
return 0;
}
public virtual CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions) public virtual CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions)
{ {
// Overrided in DefalultExecutor // Overrided in DefalultExecutor
......
namespace WindBot.Game.AI
{
public static class Zones
{
public const int z0 = 0x1,
z1 = 0x2,
z2 = 0x4,
z3 = 0x8,
z4 = 0x10,
z5 = 0x20,
z6 = 0x40,
MonsterZones = 0x7f,
MainMonsterZones = 0x1f,
ExtraMonsterZones = 0x60,
SpellZones = 0x1f,
PendulumZones = 0x3,
LinkedZones = 0x10000,
NotLinkedZones = 0x20000;
}
}
\ No newline at end of file
...@@ -23,6 +23,8 @@ namespace WindBot.Game ...@@ -23,6 +23,8 @@ namespace WindBot.Game
public int Defense { get; private set; } public int Defense { get; private set; }
public int LScale { get; private set; } public int LScale { get; private set; }
public int RScale { get; private set; } public int RScale { get; private set; }
public int Link { get; private set; }
public int LinkMarker { get; private set; }
public int BaseAttack { get; private set; } public int BaseAttack { get; private set; }
public int BaseDefense { get; private set; } public int BaseDefense { get; private set; }
public int RealPower { get; set; } public int RealPower { get; set; }
...@@ -132,6 +134,11 @@ namespace WindBot.Game ...@@ -132,6 +134,11 @@ namespace WindBot.Game
LScale = packet.ReadInt32(); LScale = packet.ReadInt32();
if ((flag & (int)Query.RScale) != 0) if ((flag & (int)Query.RScale) != 0)
RScale = packet.ReadInt32(); RScale = packet.ReadInt32();
if ((flag & (int)Query.Link) != 0)
{
Link = packet.ReadInt32();
LinkMarker = packet.ReadInt32();
}
} }
public bool HasType(CardType type) public bool HasType(CardType type)
......
...@@ -115,6 +115,36 @@ namespace WindBot.Game ...@@ -115,6 +115,36 @@ namespace WindBot.Game
} }
} }
public void AddCard(CardLocation loc, ClientCard card, int player, int zone, int pos)
{
card.Location = loc;
card.Position = pos;
switch (loc)
{
case CardLocation.Hand:
Fields[player].Hand.Add(card);
break;
case CardLocation.Grave:
Fields[player].Graveyard.Add(card);
break;
case CardLocation.Removed:
Fields[player].Banished.Add(card);
break;
case CardLocation.MonsterZone:
Fields[player].MonsterZone[zone] = card;
break;
case CardLocation.SpellZone:
Fields[player].SpellZone[zone] = card;
break;
case CardLocation.Deck:
Fields[player].Deck.Add(card);
break;
case CardLocation.Extra:
Fields[player].ExtraDeck.Add(card);
break;
}
}
public void RemoveCard(CardLocation loc, ClientCard card, int player, int zone) public void RemoveCard(CardLocation loc, ClientCard card, int player, int zone)
{ {
switch (loc) switch (loc)
......
...@@ -90,6 +90,7 @@ namespace WindBot.Game ...@@ -90,6 +90,7 @@ namespace WindBot.Game
m_option = -1; m_option = -1;
m_yesno = -1; m_yesno = -1;
m_position = CardPosition.FaceUpAttack; m_position = CardPosition.FaceUpAttack;
m_place = 0;
if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw) if (Duel.Player == 0 && Duel.Phase == DuelPhase.Draw)
{ {
_dialogs.SendNewTurn(); _dialogs.SendNewTurn();
...@@ -436,6 +437,23 @@ namespace WindBot.Game ...@@ -436,6 +437,23 @@ namespace WindBot.Game
return 0; // Always select the first option. return 0; // Always select the first option.
} }
public int OnSelectPlace(int cardId, int player, int location, int available)
{
int selector_selected = m_place;
m_place = 0;
int executor_selected = Executor.OnSelectPlace(cardId, player, location, available);
if ((executor_selected & available) > 0)
return executor_selected & available;
if ((selector_selected & available) > 0)
return selector_selected & available;
// TODO: LinkedZones
return 0;
}
/// <summary> /// <summary>
/// Called when the AI has to select a card position. /// Called when the AI has to select a card position.
/// </summary> /// </summary>
...@@ -680,6 +698,7 @@ namespace WindBot.Game ...@@ -680,6 +698,7 @@ namespace WindBot.Game
private CardSelector m_thirdSelector; private CardSelector m_thirdSelector;
private CardSelector m_materialSelector; private CardSelector m_materialSelector;
private CardPosition m_position = CardPosition.FaceUpAttack; private CardPosition m_position = CardPosition.FaceUpAttack;
private int m_place;
private int m_option; private int m_option;
private int m_number; private int m_number;
private int m_announce; private int m_announce;
...@@ -814,6 +833,11 @@ namespace WindBot.Game ...@@ -814,6 +833,11 @@ namespace WindBot.Game
m_position = pos; m_position = pos;
} }
public void SelectPlace(int zones)
{
m_place = zones;
}
public void SelectOption(int opt) public void SelectOption(int opt)
{ {
m_option = opt; m_option = opt;
......
...@@ -456,45 +456,41 @@ namespace WindBot.Game ...@@ -456,45 +456,41 @@ namespace WindBot.Game
private void OnMove(BinaryReader packet) private void OnMove(BinaryReader packet)
{ {
int cardId = packet.ReadInt32(); int cardId = packet.ReadInt32();
int pc = GetLocalPlayer(packet.ReadByte()); int previousControler = GetLocalPlayer(packet.ReadByte());
int pl = packet.ReadByte(); int previousLocation = packet.ReadByte();
int ps = packet.ReadSByte(); int previousSequence = packet.ReadSByte();
packet.ReadSByte(); // pp /*int previousPosotion = */packet.ReadSByte();
int cc = GetLocalPlayer(packet.ReadByte()); int currentControler = GetLocalPlayer(packet.ReadByte());
int cl = packet.ReadByte(); int currentLocation = packet.ReadByte();
int cs = packet.ReadSByte(); int currentSequence = packet.ReadSByte();
int cp = packet.ReadSByte(); int currentPosition = packet.ReadSByte();
packet.ReadInt32(); // reason packet.ReadInt32(); // reason
ClientCard card = _duel.GetCard(pc, (CardLocation)pl, ps); ClientCard card = _duel.GetCard(previousControler, (CardLocation)previousLocation, previousSequence);
if (card != null) Logger.DebugWriteLine("(" + pc.ToString() + "的" + (card.Name ?? "未知卡片") + "从" + (CardLocation)pl + "移动到了" + (CardLocation)cl + ")");
if ((pl & (int)CardLocation.Overlay) != 0) if ((previousLocation & (int)CardLocation.Overlay) != 0)
{ {
pl = pl & 0x7f; previousLocation = previousLocation & 0x7f;
card = _duel.GetCard(pc, (CardLocation)pl, ps); card = _duel.GetCard(previousControler, (CardLocation)previousLocation, previousSequence);
if (card != null) if (card != null)
card.Overlays.Remove(cardId); card.Overlays.Remove(cardId);
} }
else else
_duel.RemoveCard((CardLocation)pl, card, pc, ps); _duel.RemoveCard((CardLocation)previousLocation, card, previousControler, previousSequence);
if ((cl & (int)CardLocation.Overlay) != 0) if ((currentLocation & (int)CardLocation.Overlay) != 0)
{ {
cl = cl & 0x7f; currentLocation = currentLocation & 0x7f;
card = _duel.GetCard(cc, (CardLocation)cl, cs); card = _duel.GetCard(currentControler, (CardLocation)currentLocation, currentSequence);
if (card != null) if (card != null)
card.Overlays.Add(cardId); card.Overlays.Add(cardId);
} }
else else
{ {
_duel.AddCard((CardLocation)cl, cardId, cc, cs, cp); if (previousLocation == 0)
if ((pl & (int)CardLocation.Overlay) == 0 && card != null) _duel.AddCard((CardLocation)currentLocation, cardId, currentControler, currentSequence, currentPosition);
{ else
ClientCard newcard = _duel.GetCard(cc, (CardLocation)cl, cs); _duel.AddCard((CardLocation)currentLocation, card, currentControler, currentSequence, currentPosition);
if (newcard != null)
newcard.Overlays.AddRange(card.Overlays);
}
} }
} }
...@@ -1024,64 +1020,79 @@ namespace WindBot.Game ...@@ -1024,64 +1020,79 @@ namespace WindBot.Game
packet.ReadByte(); // min packet.ReadByte(); // min
int field = ~packet.ReadInt32(); int field = ~packet.ReadInt32();
byte[] resp = new byte[3]; const int LOCATION_MZONE = 0x4;
const int LOCATION_SZONE = 0x8;
bool pendulumZone = false; const int LOCATION_PZONE = 0x200;
int player;
int location;
int filter; int filter;
if ((field & 0x7f) != 0) if ((field & 0x7f) != 0)
{ {
resp[0] = (byte)GetLocalPlayer(0); player = 0;
resp[1] = 0x4; location = LOCATION_MZONE;
filter = field & 0x7f; filter = field & Zones.MonsterZones;
} }
else if ((field & 0x1f00) != 0) else if ((field & 0x1f00) != 0)
{ {
resp[0] = (byte)GetLocalPlayer(0); player = 0;
resp[1] = 0x8; location = LOCATION_SZONE;
filter = (field >> 8) & 0x1f; filter = (field >> 8) & Zones.SpellZones;
} }
else if ((field & 0xc000) != 0) else if ((field & 0xc000) != 0)
{ {
resp[0] = (byte)GetLocalPlayer(0); player = 0;
resp[1] = 0x8; location = LOCATION_PZONE;
filter = (field >> 14) & 0x3; filter = (field >> 14) & Zones.PendulumZones;
pendulumZone = true;
} }
else if ((field & 0x7f0000) != 0) else if ((field & 0x7f0000) != 0)
{ {
resp[0] = (byte)GetLocalPlayer(1); player = 1;
resp[1] = 0x4; location = LOCATION_MZONE;
filter = (field >> 16) & 0x7f; filter = (field >> 16) & Zones.MonsterZones;
} }
else if ((field & 0x1f000000) != 0) else if ((field & 0x1f000000) != 0)
{ {
resp[0] = (byte) GetLocalPlayer(1); player = 1;
resp[1] = 0x8; location = LOCATION_SZONE;
filter = (field >> 24) & 0x1f; filter = (field >> 24) & Zones.SpellZones;
} }
else else
{ {
resp[0] = (byte) GetLocalPlayer(1); player = 1;
resp[1] = 0x8; location = LOCATION_PZONE;
filter = (field >> 30) & 0x3; filter = (field >> 30) & Zones.PendulumZones;
pendulumZone = true;
} }
if (!pendulumZone) int selected = _ai.OnSelectPlace(_select_hint, player, location, filter);
_select_hint = 0;
byte[] resp = new byte[3];
resp[0] = (byte)GetLocalPlayer(player);
if (location != LOCATION_PZONE)
{ {
if ((filter & 0x40) != 0) resp[2] = 6; resp[1] = (byte)location;
else if ((filter & 0x20) != 0) resp[2] = 5; if ((selected & filter) > 0)
else if ((filter & 0x4) != 0) resp[2] = 2; filter &= selected;
else if ((filter & 0x2) != 0) resp[2] = 1;
else if ((filter & 0x8) != 0) resp[2] = 3; if ((filter & Zones.z6) != 0) resp[2] = 6;
else if ((filter & 0x1) != 0) resp[2] = 0; else if ((filter & Zones.z5) != 0) resp[2] = 5;
else if ((filter & 0x10) != 0) resp[2] = 4; else if ((filter & Zones.z2) != 0) resp[2] = 2;
else if ((filter & Zones.z1) != 0) resp[2] = 1;
else if ((filter & Zones.z3) != 0) resp[2] = 3;
else if ((filter & Zones.z0) != 0) resp[2] = 0;
else if ((filter & Zones.z4) != 0) resp[2] = 4;
} }
else else
{ {
if ((filter & 0x1) != 0) resp[2] = 6; resp[1] = (byte)LOCATION_SZONE;
if ((filter & 0x2) != 0) resp[2] = 7; if ((selected & filter) > 0)
filter &= selected;
if ((filter & Zones.z0) != 0) resp[2] = 6;
if ((filter & Zones.z1) != 0) resp[2] = 7;
} }
BinaryWriter reply = GamePacketFactory.Create(CtosMessage.Response); BinaryWriter reply = GamePacketFactory.Create(CtosMessage.Response);
......
...@@ -98,11 +98,16 @@ ...@@ -98,11 +98,16 @@
<Compile Include="Game\AI\Dialogs.cs" /> <Compile Include="Game\AI\Dialogs.cs" />
<Compile Include="Game\AI\Enums\DangerousMonster.cs" /> <Compile Include="Game\AI\Enums\DangerousMonster.cs" />
<Compile Include="Game\AI\Enums\FusionSpell.cs" /> <Compile Include="Game\AI\Enums\FusionSpell.cs" />
<Compile Include="Game\AI\Enums\ShouldBeDisabledBeforeItUseEffectMonster.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeSpellTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeMonsterTarget.cs" />
<Compile Include="Game\AI\Enums\ShouldNotBeTarget.cs" />
<Compile Include="Game\AI\Enums\PreventActivationEffectInBattle.cs" /> <Compile Include="Game\AI\Enums\PreventActivationEffectInBattle.cs" />
<Compile Include="Game\AI\Enums\OneForXyz.cs" /> <Compile Include="Game\AI\Enums\OneForXyz.cs" />
<Compile Include="Game\AI\Enums\InvincibleMonster.cs" /> <Compile Include="Game\AI\Enums\InvincibleMonster.cs" />
<Compile Include="Game\AI\Enums\Floodgate.cs" /> <Compile Include="Game\AI\Enums\Floodgate.cs" />
<Compile Include="Game\AI\Executor.cs" /> <Compile Include="Game\AI\Executor.cs" />
<Compile Include="Game\AI\Zones.cs" />
<Compile Include="Game\AI\ExecutorType.cs" /> <Compile Include="Game\AI\ExecutorType.cs" />
<Compile Include="Game\BattlePhase.cs" /> <Compile Include="Game\BattlePhase.cs" />
<Compile Include="Game\BattlePhaseAction.cs" /> <Compile Include="Game\BattlePhaseAction.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment