Esempio n. 1
0
 public opposite(CardDB.cardName name, int value, BoardObj bo, BoardObj target)
 {
     this.name   = name;
     this.value  = value;
     this.bo     = bo;
     this.target = target;
 }
Esempio n. 2
0
 public opposite(CardDB.cardName name, int value, Handcard hc, BoardObj target)
 {
     this.name   = name;
     this.value  = value;
     this.hc     = hc;
     this.target = target;
 }
Esempio n. 3
0
        public Handcard getOppositeCard(Playfield p, BoardObj attacker, int canWaitMissingMana = 3)
        {
            Handcard bestCard = null;

            if (OppositeDB.ContainsKey(attacker.Name))
            {
                Dictionary <CardDB.cardName, int> tmp = OppositeDB[attacker.Name];
                int             bestCardVal           = -1;
                CardDB.cardName name;
                foreach (Handcard hc in p.ownHandCards)
                {
                    name = hc.card.name;
                    if (canWaitMissingMana >= hc.manacost - p.ownMana)
                    {
                        if (tmp.ContainsKey(name))
                        {
                            if (tmp[name] > bestCardVal)
                            {
                                bestCardVal          = tmp[name];
                                bestCard             = hc;
                                bestCard.val         = bestCardVal;
                                bestCard.missingMana = hc.manacost - p.ownMana;
                            }
                            if (bestCardVal == 100)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return(bestCard);
        }
Esempio n. 4
0
        public void setKingsLine(bool own)
        {
            BoardObj        tower = own ? this.ownKingsTower : this.enemyKingsTower;
            List <BoardObj> list  = own ? this.ownTowers : this.enemyTowers;
            int             i     = 0;

            foreach (BoardObj t in list)
            {
                if (t.Tower < 10)
                {
                    i += t.Line;
                }
            }
            tower.Line = 0;
            switch (i)
            {
            case 0: tower.Line = 3; break;

            case 1: tower.Line = 2; break;

            case 2: tower.Line = 1; break;
            }
            foreach (BoardObj t in list)
            {
                if (t.Tower > 9)
                {
                    t.Line = tower.Line;
                }
            }
        }
Esempio n. 5
0
        public Playfield(Playfield p, int timeShift = 0)
        {
            //this.pID = prozis.getPid();
            this.ownerIndex = p.ownerIndex;
            this.BattleTime = p.BattleTime;
            this.home       = p.home;
            this.ownMana    = p.ownMana;
            this.enemyMana  = p.enemyMana;

            copyCards(p.ownHandCards, p.nextCard);

            copyBoardObj(p.ownMinions, this.ownMinions);
            copyBoardObj(p.enemyMinions, this.enemyMinions);

            copyBoardObj(p.ownAreaEffects, this.ownAreaEffects);
            copyBoardObj(p.enemyAreaEffects, this.enemyAreaEffects);

            copyBoardObj(p.ownBuildings, this.ownBuildings);
            copyBoardObj(p.enemyBuildings, this.enemyBuildings);

            copyBoardObj(p.ownTowers, this.ownTowers);
            copyBoardObj(p.enemyTowers, this.enemyTowers);

            this.ownKingsTower     = new BoardObj(p.ownKingsTower);
            this.ownPrincessTower1 = new BoardObj(p.ownPrincessTower1);
            this.ownPrincessTower2 = new BoardObj(p.ownPrincessTower2);

            this.enemyKingsTower     = new BoardObj(p.enemyKingsTower);
            this.enemyPrincessTower1 = new BoardObj(p.enemyPrincessTower1);
            this.enemyPrincessTower2 = new BoardObj(p.enemyPrincessTower2);

            initTowers();

            this.ownDeck   = p.ownDeck;
            this.enemyDeck = p.enemyDeck;

            this.ownGroup   = p.ownGroup;
            this.enemyGroup = p.enemyGroup;
            //enemyHandCards = prozis.enemyHandCards;

            if (p.needPrint)
            {
                this.needPrint = true;
                this.pIdHistory.AddRange(p.pIdHistory);
                this.pIdHistory.Add(pID);
            }
            this.nextEntity = p.nextEntity;

            this.evaluatePenality = p.evaluatePenality;
            this.ruleWeight       = p.ruleWeight;
            this.rulesUsed        = p.rulesUsed;

            this.playactions.AddRange(p.playactions);

            if (timeShift != 0)
            {
                TimeMachine.Instance.setTimeShift(this, timeShift);
            }
        }
Esempio n. 6
0
        public void rotateLines()
        {
            //-Here we rotate towers and locking for nearest threat
            int i = ownTowers.Count;

            if (i < 1)
            {
                return;
            }
            List <attackDef> attackersList = new List <attackDef>();
            List <attackDef> tmp;
            attackDef        near = new attackDef();

            foreach (BoardObj t in this.ownTowers)
            {
                tmp = t.getImmediateAttackers(this);
                if (tmp.Count > 0 && (near.empty || near.time > tmp[0].time))
                {
                    near = tmp[0];
                }
            }
            if (!near.empty)
            {
                Playfield p     = new Playfield(this, near.time);
                BoardObj  myObj = near.attacker.own ? near.attacker : near.target;
                opposite  opp   = KnowledgeBase.Instance.getOppositeToAll(p, myObj);

                if (opp != null)
                {
                    if (opp.hc != null)
                    {
                        int callTime = near.time - opp.hc.card.DeployTime;
                        if (callTime < 0)
                        {
                            callTime = 0;
                        }
                        p = new Playfield(p, callTime);
                        VectorAI position = new VectorAI(0, 0);
                        //VectorAI position = p.getDeployPosition(opp); //TODO: this decision takes a behavior or a time machine

                        bestCast = new Cast(opp.hc.name, position, opp.hc);
                    }
                    else if (opp.bo != null)
                    {
                        if (opp.bo.TargetType == targetType.GROUND)
                        {
                            //TODO
                        }
                    }
                    else
                    {
                        //TODO automatic creation opposite list in getOppositeToAll or do something else
                    }
                }
            }
        }
Esempio n. 7
0
 public bool aheadOf(BoardObj bo, bool home)
 {
     if ((this.Position.Y > bo.Position.Y) == home)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 8
0
 public VectorAI getDeployPosition(BoardObj bo, deployDirectionRelative relativeDirection = deployDirectionRelative.none, int deployDistance = 0) //for deployDistance you can use hc.card.DamageRadius
 {
     if (bo == null)
     {
         Logger.Debug("!!![getDeployPosition]Error:BoardObj == NULL");
         return(new VectorAI(0, 0));
     }
     else
     {
         return(getDeployPosition(bo.Position, relativeDirection, deployDistance));
     }
 }
Esempio n. 9
0
        //TODO allCharsInAreaGetDamage

        private void LogBoardObject(BoardObj bo)
        {
            Logger.Information("{type} {ownerIndex} {Name} {GId} {Position} {level} {Atk} {HP} {Shield}", bo.type, bo.ownerIndex, bo.Name, bo.GId, bo.Position, bo.level, bo.Atk, bo.HP, bo.Shield);
            if (bo.frozen)
            {
                Logger.Information("frozen: {startFrozen}", bo.startFrozen);
            }
            if (bo.LifeTime > 0)
            {
                Logger.Information("LifeTime: {LifeTime}", bo.LifeTime);
            }
        }
Esempio n. 10
0
        public BoardObj getFrontMob()  //TODO: perhaps add for enemy minions
        {
            BoardObj retval = null;
            int      count  = ownMinions.Count;

            if (count > 0)
            {
                retval = ownMinions[0];
                for (int i = 1; i < count; i++)
                {
                    if (!retval.aheadOf(ownMinions[i], home))
                    {
                        retval = ownMinions[i];
                    }
                }
            }
            return(retval);
        }
Esempio n. 11
0
        public Handcard getPatnerForMobInPeace(BoardObj bo)
        {
            if (bo == null)
            {
                return(null);
            }

            Handcard        retval      = null;
            List <Handcard> air         = new List <Handcard>();
            List <Handcard> troops      = new List <Handcard>();
            bool            needDamager = false;
            bool            needAir     = false;

            if (bo.HP > 600)
            {
                needDamager = true;
            }
            if (bo.TargetType != targetType.ALL)
            {
                needAir = true;
            }
            foreach (Handcard hc in ownHandCards)
            {
                if (hc.card.type != boardObjType.MOB)
                {
                    continue;
                }
                troops.Add(hc);
                if (hc.card.Transport == transportType.AIR)
                {
                    air.Add(hc);
                }
            }
            if (needAir)
            {
                retval = getMobCardByCondition(air, needDamager);
            }
            if ((needAir && retval == null) || !needAir)
            {
                retval = getMobCardByCondition(troops, needDamager);
            }
            return(retval);
        }
Esempio n. 12
0
        private BoardObj getBOfromHeader(string[] line, int ownerIndex)
        {
            BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(line[2]));

            bo.ownerIndex = Convert.ToInt32(line[1]);
            bo.own        = bo.ownerIndex == ownerIndex ? true : false;
            bo.GId        = Convert.ToUInt32(line[3]);
            bo.Position   = new VectorAI(line[4]);
            bo.Line       = bo.Position.X > 8700 ? 1 : 2;
            bo.level      = Convert.ToInt32(line[5]);
            bo.Atk        = Convert.ToInt32(line[6]);
            bo.HP         = Convert.ToInt32(line[7]);
            bo.Shield     = Convert.ToInt32(line[8]);
            int len = line.Length;

            if (len > 9)
            {
                for (int i = 9; i < len; i++)
                {
                    string[] ss = line[i].Split(':');
                    switch (ss[0])
                    {
                    case "frozen":
                        bo.frozen      = true;
                        bo.startFrozen = Convert.ToInt32(ss[1]);
                        continue;

                    case "LifeTime":
                        bo.LifeTime = Convert.ToInt32(ss[1]);
                        continue;

                    case "extraData":
                        bo.extraData = ss[1];
                        continue;
                    }
                }
            }
            //this.attacking = c.attacking;
            //this.attacked = c.attacked;
            //this.attacker = c.attacker;
            //this.target = c.target;
            return(bo);
        }
Esempio n. 13
0
 public BoardObj(BoardObj bo)
 {
     this.Name                = bo.Name;
     this.card                = bo.card;
     this.type                = bo.type;
     this.Transport           = bo.Transport;
     this.affectOn            = bo.affectOn;
     this.Position            = bo.Position;
     this.own                 = bo.own;
     this.pID                 = bo.pID; //-????????
     this.Line                = bo.Line;
     this.GId                 = bo.GId;
     this.cost                = bo.cost;
     this.DeployTime          = bo.DeployTime;
     this.DamageRadius        = bo.DamageRadius;
     this.MaxHP               = bo.MaxHP;
     this.HP                  = bo.HP;
     this.Atk                 = bo.Atk;
     this.Shield              = bo.Shield;
     this.Speed               = bo.Speed;
     this.HitSpeed            = bo.HitSpeed;
     this.MinRange            = bo.MinRange;
     this.Range               = bo.Range;
     this.SightRange          = bo.SightRange;
     this.TargetType          = bo.TargetType;
     this.MaxTargets          = bo.MaxTargets;
     this.attacking           = bo.attacking;
     this.attacked            = bo.attacked;
     this.LifeTime            = bo.LifeTime;
     this.SpawnNumber         = bo.SpawnNumber;
     this.SpawnInterval       = bo.SpawnInterval;
     this.SpawnTime           = bo.SpawnTime;
     this.SpawnCharacterLevel = bo.SpawnCharacterLevel;
     this.frozen              = bo.frozen;
     this.clone               = bo.clone;
     this.startFrozen         = bo.startFrozen;
     this.attacker            = bo.attacker;
     this.target              = bo.target;
     this.DeathEffect         = bo.DeathEffect;
     this.Tower               = bo.Tower;
     this.extraData           = bo.extraData;
 }
Esempio n. 14
0
 private void addTower(BoardObj tower)
 {
     //maybe add duplicate check (todo) - depending on the performance
     if (tower.own)
     {
         ownTowers.Add(tower);
         if (tower.Tower < 9)
         {
             ownPrincessTowers.Add(tower);
         }
     }
     else
     {
         enemyTowers.Add(tower);
         if (tower.Tower < 9)
         {
             enemyPrincessTowers.Add(tower);
         }
     }
 }
Esempio n. 15
0
 public void collectCardInfo(BoardObj bo)
 {
     if (cardNameToCardList.ContainsKey(bo.Name))
     {
         Card c = cardNameToCardList[bo.Name];
         if (c.needUpdate)
         {
             c.type                = bo.type;
             c.Transport           = bo.Transport;
             c.TargetType          = bo.TargetType;
             c.affectType          = bo.affectOn;
             c.cost                = bo.cost;
             c.DeployTime          = bo.DeployTime;
             c.DamageRadius        = bo.DamageRadius;
             c.MaxHP               = bo.MaxHP;
             c.Atk                 = bo.Atk;
             c.Shield              = bo.Shield;
             c.Speed               = bo.Speed;
             c.HitSpeed            = bo.HitSpeed;
             c.MinRange            = bo.MinRange;
             c.MaxRange            = bo.Range;
             c.SightRange          = bo.SightRange;
             c.MultipleTargets     = bo.MaxTargets;
             c.DeathEffect         = bo.DeathEffect;
             c.Level               = bo.level;
             c.LifeTime            = bo.LifeTime;
             c.SpawnNumber         = bo.SpawnNumber;
             c.SpawnPause          = bo.SpawnTime;
             c.SpawnInterval       = bo.SpawnInterval;
             c.SpawnCharacterLevel = bo.SpawnCharacterLevel;
             c.needUpdate          = false;
         }
     }
     else
     {
         //numDuplicates = 0;
         //numDifferences = 0;
     }
 }
Esempio n. 16
0
        public sealed override CastRequest GetNextCast()
        {
            Logger.Debug("");
            if (statNumSuccessfulEntrances > 0)
            {
                statTimeOutsideRoutine = DateTime.Now - statTimerRoutine;
            }
            statTimerRoutine = DateTime.Now;

            List <BoardObj> ownMinions   = new List <BoardObj>();
            List <BoardObj> enemyMinions = new List <BoardObj>();

            List <BoardObj> ownAreaEffects   = new List <BoardObj>();
            List <BoardObj> enemyAreaEffects = new List <BoardObj>();

            List <BoardObj> ownBuildings   = new List <BoardObj>();
            List <BoardObj> enemyBuildings = new List <BoardObj>();

            BoardObj ownKingsTower       = new BoardObj();
            BoardObj ownPrincessTower1   = new BoardObj();
            BoardObj ownPrincessTower2   = new BoardObj();
            BoardObj enemyKingsTower     = new BoardObj();
            BoardObj enemyPrincessTower1 = new BoardObj();
            BoardObj enemyPrincessTower2 = new BoardObj();

            List <Handcard> ownHandCards = new List <Handcard>();
            Handcard        prevHandCard = new Handcard();

            Logger.Debug("#####Stats##### Inint BO {0}", (statTimerRoutine - DateTime.Now).TotalSeconds);

            var battle = ClashEngine.Instance.Battle;

            if (battle == null || !battle.IsValid)
            {
                return(null);
            }
            var om = ClashEngine.Instance.ObjectManager;

            if (om == null)
            {
                return(null);
            }
            var lp = ClashEngine.Instance.LocalPlayer;

            if (lp == null || !lp.IsValid)
            {
                return(null);
            }
            var spellButtons = ClashEngine.Instance.AvailableSpellButtons;

            if (spellButtons == null)
            {
                return(null);
            }
            var spells = ClashEngine.Instance.AvailableSpells;

            if (spells == null)
            {
                return(null);
            }

            if (ownKingsTowerPos.Y == -1)
            {
                List <Tuple <int, int> > towersIndY = new List <Tuple <int, int> >();
                bool needFriendlyIndex = false;
                var  chars             = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>();
                foreach (var @char in chars)
                {
                    if ([email protected])
                    {
                        continue;
                    }
                    var data = @char.LogicGameObjectData;
                    if (data == null || !data.IsValid)
                    {
                        continue;
                    }
                    var name = data.Name;
                    if ((MemPtr)name == MemPtr.Zero)
                    {
                        continue;
                    }

                    switch (CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "0"))
                    {
                    case CardDB.cardName.kingtower:
                        int OwnerIndex = (int)@char.OwnerIndex;
                        int charY      = @char.StartPosition.Y;
                        towersIndY.Add(new Tuple <int, int>(OwnerIndex, charY));
                        if (OwnerIndex == lp.OwnerIndex)
                        {
                            ownKingsTowerPos.Y = charY;
                        }
                        break;

                    case CardDB.cardName.kingtowermiddle:
                        ownKingsTowerPos.X = @char.StartPosition.X;
                        needFriendlyIndex  = true;
                        break;
                    }
                }

                if (needFriendlyIndex)
                {
                    foreach (var t in towersIndY)
                    {
                        if (ownKingsTowerPos.Y == t.Item2 && lp.OwnerIndex != t.Item1)
                        {
                            friendlyOwnerIndex = t.Item1;
                        }
                    }
                }
            }

            Logger.Debug("#####Stats##### Inint BO+engine {0}", (statTimerRoutine - DateTime.Now).TotalSeconds);

            using (new PerformanceTimer("GetNextCast entrance"))
            {
                Handcard Mirror = null;
                Dictionary <string, int> AvailableSpells = new Dictionary <string, int>();
                foreach (var spell in spells)
                {
                    if (spell == null || !spell.IsValid)
                    {
                        continue;
                    }
                    var name = spell.Name;
                    if ((MemPtr)name == MemPtr.Zero)
                    {
                        continue;
                    }
                    AvailableSpells.Add(name.Value.ToString(), 0);
                }
                foreach (var spellBtn in spellButtons)
                {
                    if (spellBtn == null || !spellBtn.IsValid)
                    {
                        continue;
                    }
                    if (spellBtn.SpellDeckSpell == null || !spellBtn.SpellDeckSpell.IsValid)
                    {
                        continue;
                    }
                    if (spellBtn.SpellDeckSpell.Spell == null || !spellBtn.SpellDeckSpell.Spell.IsValid)
                    {
                        continue;
                    }

                    var name = spellBtn.SpellDeckSpell.Spell.Name;
                    if ((MemPtr)name == MemPtr.Zero)
                    {
                        continue;
                    }

                    if (!AvailableSpells.ContainsKey(name.Value.ToString()))
                    {
                        continue;
                    }

                    int      lvl = spellBtn.SpellDeckSpell.LevelIndex;
                    Handcard hc  = new Handcard(name.Value.ToString(), lvl);
                    if (hc.card.name == CardDB.cardName.unknown)
                    {
                        CardDB.Instance.collectNewCards(spellBtn);
                    }
                    hc.manacost = spellBtn.SpellDeckSpell.Spell.ManaCost;
                    if (hc.card.name == CardDB.cardName.mirror)
                    {
                        Mirror = hc;
                    }
                    //if (hc.card.needUpdate) CardDB.Instance.cardsAdjustment(spell);

                    ownHandCards.Add(hc);
                }
                if (ownHandCards.Count == 4)
                {
                    if (prevHandCards.Count != 4)
                    {
                        prevHandCards = new List <Handcard>(ownHandCards);
                    }
                    else
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            if (ownHandCards[i].card.name == prevHandCards[i].card.name)
                            {
                                continue;
                            }
                            if (ownHandCards[i].card.name == CardDB.cardName.unknown)
                            {
                                continue;
                            }
                            prevHandCard = prevHandCards[i];
                            if (Mirror != null)
                            {
                                Mirror.transformTo(prevHandCard);
                                Mirror.mirror = true;
                            }
                            break;
                        }
                    }
                }

                var qSpells = ClashEngine.Instance.QueuedSpells;
                if (qSpells != null)
                {
                    if (qSpells.Count() == 0)
                    {
                        if (CastRequestDB.Count != 0)
                        {
                            CastRequestDB.Clear();
                        }
                    }
                    else
                    {
                        if (CastRequest != null && !CastRequestDB.ContainsKey(CastRequest.SpellName))
                        {
                            CastRequestDB.Add(CastRequest.SpellName, CastRequest);
                        }

                        if (CastRequestDBtmp.Count != 0)
                        {
                            CastRequestDBtmp.Clear();
                        }
                        foreach (var qs in qSpells)
                        {
                            if (qs == null || !qs.IsValid)
                            {
                                continue;
                            }
                            string name = qs.Name.Value.ToString();
                            if (!CastRequestDBtmp.ContainsKey(name))
                            {
                                CastRequestDBtmp.Add(name, 0);
                            }
                            if (CastRequestDB.ContainsKey(name))
                            {
                                //add to pf //TODO: real lvl
                                BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name, "21"), 6);
                                bo.Position   = new VectorAI(CastRequestDB[name].Position);
                                bo.ownerIndex = (int)lp.OwnerIndex;
                                bo.frozen     = true;
                                bo.GId        = getNextGId();
                                switch (bo.type)
                                {
                                case boardObjType.MOB:
                                    int nums = bo.card.SummonNumber;
                                    if (nums == 0)
                                    {
                                        nums = 1;
                                    }
                                    else
                                    {
                                        if (bo.card.SpawnCharacter != "")
                                        {
                                            bo            = new BoardObj(CardDB.Instance.cardNamestringToEnum(bo.card.SpawnCharacter, "22"), 6);
                                            bo.Position   = new VectorAI(CastRequestDB[name].Position);
                                            bo.ownerIndex = (int)lp.OwnerIndex;
                                            bo.frozen     = true;
                                            bo.GId        = getNextGId();
                                        }
                                    }
                                    for (int i = 0; i < nums; i++)
                                    {
                                        ownMinions.Add(bo);
                                        if (nums > 1)
                                        {
                                            bo     = new BoardObj(bo);
                                            bo.GId = getNextGId();
                                        }
                                    }
                                    break;

                                case boardObjType.BUILDING:
                                    ownBuildings.Add(bo);
                                    break;

                                case boardObjType.AOE:
                                    break;
                                }
                            }
                        }
                        foreach (var kvp in CastRequestDB.ToArray())
                        {
                            if (!CastRequestDBtmp.ContainsKey(kvp.Key))
                            {
                                CastRequestDB.Remove(kvp.Key);
                            }
                        }
                    }
                }

                //var projs = om.OfType<Clash.Engine.NativeObjects.Logic.GameObjects.Projectile>();
                //foreach (var proj in projs)
                //{
                //    if (proj != null && proj.IsValid)
                //    {
                //        //TODO: get static data for all objects
                //        //Here we get dynamic data only

                //        CardDB.Instance.collectNewCards(proj);
                //    }
                //}

                var aoes = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.AreaEffectObject>();
                foreach (var aoe in aoes)
                {
                    if (!aoe.IsValid)
                    {
                        continue;
                    }
                    var data = aoe.LogicGameObjectData;
                    if (data == null || !data.IsValid)
                    {
                        continue;
                    }
                    var name = data.Name;
                    if ((MemPtr)name == MemPtr.Zero)
                    {
                        continue;
                    }

                    BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "1"));
                    //if (bo.card.needUpdate) CardDB.Instance.cardsAdjustment(aoe);
                    if (bo.card.name == CardDB.cardName.unknown)
                    {
                        CardDB.Instance.collectNewCards(aoe);
                    }
                    bo.GId      = aoe.GlobalId;
                    bo.Position = new VectorAI(aoe.StartPosition);
                    bo.Line     = bo.Position.X > 8700 ? 2 : 1;
                    //bo.level = TODO real value
                    //bo.Atk = TODO real value
                    bo.LifeTime = aoe.HealthComponent.RemainingTime;

                    //bo.extraData = data.Field10.ToString();//!!TEST

                    bo.ownerIndex = (int)aoe.OwnerIndex;
                    bool own = bo.ownerIndex == lp.OwnerIndex ? true : (bo.ownerIndex == friendlyOwnerIndex ? true : false);
                    bo.own = own;

                    if (own)
                    {
                        ownAreaEffects.Add(bo);
                    }
                    else
                    {
                        enemyAreaEffects.Add(bo);
                    }
                }

                var chars = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>();
                foreach (var @char in chars)
                {
                    if ([email protected])
                    {
                        continue;
                    }
                    var data = @char.LogicGameObjectData;
                    if (data == null || !data.IsValid)
                    {
                        continue;
                    }
                    var name = data.Name;
                    if ((MemPtr)name == MemPtr.Zero)
                    {
                        continue;
                    }

                    BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(name.Value.ToString(), "2"), (int)@char.TowerLevel);
                    bo.ownerIndex = (int)@char.OwnerIndex;
                    bool own = bo.ownerIndex == lp.OwnerIndex ? true : (bo.ownerIndex == friendlyOwnerIndex ? true : false);
                    bo.own = own;

                    if (bo.card.name == CardDB.cardName.unknown)
                    {
                        CardDB.Instance.collectNewCards(@char);
                    }
                    else if (bo.ownerIndex == lp.OwnerIndex && bo.card.needUpdate)
                    {
                        CardDB.Instance.cardsAdjustment(@char);
                    }
                    bo.GId      = @char.GlobalId;
                    bo.Position = new VectorAI(@char.StartPosition);
                    bo.Line     = bo.Position.X > 8700 ? 2 : 1;
                    bo.level    = 1 + (int)@char.TowerLevel;
                    //this.frozen = TODO
                    //this.startFrozen = TODO
                    bo.HP       = @char.HealthComponent.CurrentHealth;
                    bo.Shield   = @char.HealthComponent.CurrentShieldHealth;
                    bo.LifeTime = @char.HealthComponent.LifeTime - @char.HealthComponent.RemainingTime; //TODO: - find real value for battle stage

                    int tower = 0;
                    switch (bo.Name)
                    {
                    case CardDB.cardName.princesstower:
                        CardDB.Instance.setPrincessTowerMaxHP(bo);
                        tower = bo.Line;
                        if (bo.own)
                        {
                            if (tower == 1)
                            {
                                ownPrincessTower1 = bo;
                            }
                            else
                            {
                                ownPrincessTower2 = bo;
                            }
                        }
                        else
                        {
                            if (tower == 1)
                            {
                                enemyPrincessTower1 = bo;
                            }
                            else
                            {
                                enemyPrincessTower2 = bo;
                            }
                        }
                        break;

                    case CardDB.cardName.kingtower:
                        CardDB.Instance.setKingsTowerMaxHP(bo);
                        tower = 10 + bo.Line;
                        if (bo.own)
                        {
                            if (ownKingsTower.HP == 0)
                            {
                                ownKingsTower = bo;
                            }
                            else if (bo.HP < ownKingsTower.HP)
                            {
                                ownKingsTower = bo;
                            }
                            if (ownKingsTowerPos.X != -1)
                            {
                                ownKingsTower.Position.X = ownKingsTowerPos.X;
                            }
                            ownKingsTower.ownerIndex = (int)lp.OwnerIndex;
                        }
                        else
                        {
                            if (enemyKingsTower.HP == 0)
                            {
                                enemyKingsTower = bo;
                            }
                            else if (bo.HP < enemyKingsTower.HP)
                            {
                                enemyKingsTower = bo;
                            }
                            if (ownKingsTowerPos.X != -1)
                            {
                                enemyKingsTower.Position.X = ownKingsTowerPos.X;
                            }
                        }
                        break;

                    case CardDB.cardName.kingtowermiddle:
                        tower = 100;
                        break;

                    default:
                        bo.Atk = (int)(bo.card.Atk * lvlToCoef[bo.level]);     //TODO: need value from core
                        if (own)
                        {
                            switch (bo.type)
                            {
                            case boardObjType.MOB:
                                ownMinions.Add(bo);
                                break;

                            case boardObjType.BUILDING:
                                ownBuildings.Add(bo);
                                break;
                            }
                        }
                        else
                        {
                            switch (bo.type)
                            {
                            case boardObjType.MOB:
                                enemyMinions.Add(bo);
                                break;

                            case boardObjType.BUILDING:
                                enemyBuildings.Add(bo);
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            Playfield p;

            Logger.Debug("#####Stats##### before Initialize playfield {0}", (statTimerRoutine - DateTime.Now).TotalSeconds);

            using (new PerformanceTimer("Initialize playfield."))
            {
                Logger.Debug("################################Routine v.0.8.6 Behavior:{Name:l} v.{Version:l}", Name, Version);
                p = new Playfield
                {
                    BattleTime          = battle.BattleTime,
                    suddenDeath         = battle.BattleTime.TotalSeconds > 180,
                    ownerIndex          = (int)lp.OwnerIndex,
                    ownMana             = (int)(lp.Mana - lp.ReservedMana),
                    ownHandCards        = ownHandCards,
                    ownAreaEffects      = ownAreaEffects,
                    ownMinions          = ownMinions,
                    ownBuildings        = ownBuildings,
                    ownKingsTower       = ownKingsTower,
                    ownPrincessTower1   = ownPrincessTower1,
                    ownPrincessTower2   = ownPrincessTower2,
                    enemyAreaEffects    = enemyAreaEffects,
                    enemyMinions        = enemyMinions,
                    enemyBuildings      = enemyBuildings,
                    enemyKingsTower     = enemyKingsTower,
                    enemyPrincessTower1 = enemyPrincessTower1,
                    enemyPrincessTower2 = enemyPrincessTower2,

                    prevCard = prevHandCard,
                    //nextCard = //TODO: Add next card
                };

                p.home = p.ownKingsTower.Position.Y < 15250 ? true : false;

                if (p.ownPrincessTower1.Position == null)
                {
                    p.ownPrincessTower1.Position = p.getDeployPosition(deployDirectionAbsolute.ownPrincessTowerLine1);
                }
                if (p.ownPrincessTower2.Position == null)
                {
                    p.ownPrincessTower2.Position = p.getDeployPosition(deployDirectionAbsolute.ownPrincessTowerLine2);
                }
                if (p.enemyPrincessTower1.Position == null)
                {
                    p.enemyPrincessTower1.Position = p.getDeployPosition(deployDirectionAbsolute.enemyPrincessTowerLine1);
                }
                if (p.enemyPrincessTower2.Position == null)
                {
                    p.enemyPrincessTower2.Position = p.getDeployPosition(deployDirectionAbsolute.enemyPrincessTowerLine2);
                }

                p.initTowers();

                p.print();
                battleLogs.Add(p);
            }

            Logger.Debug("#####Stats##### after Initialize playfield {0}", (statTimerRoutine - DateTime.Now).TotalSeconds);
            statTimeInitPlayfield = DateTime.Now - statTimerRoutine;
            statTimerRoutine      = DateTime.Now;

            Cast bc;

            using (new PerformanceTimer("GetBestCast"))
            {
                //DateTime statBehaviorCalcStart = DateTime.Now;
                bc = this.GetBestCast(p);

                CastRequest = null;
                if (bc != null && bc.Position != null)
                {
                    if (p.ownMana + 1 >= bc.hc.manacost)
                    {
                        CastRequest = new CastRequest(bc.SpellName, bc.Position.ToVector2f(true));
                    }
                    Logger.Debug("CastRequest {SpellName:l} {Position:l}", bc.SpellName, CastRequest == null ? bc.Position?.ToString() : CastRequest.Position.ToString());
                }
                else
                {
                    Logger.Debug("Waiting for cast, maybe next tick...");
                }
                statTimeInsideBehavior = DateTime.Now - statTimerRoutine;

                //stat info

                statSumTimeOutsideRoutine += statTimeOutsideRoutine;
                statSumTimeInitPlayfield  += statTimeInitPlayfield;
                statSumTimeInsideBehavior += statTimeInsideBehavior;
                statNumSuccessfulEntrances++;
                int objsCount = ownAreaEffects.Count + enemyAreaEffects.Count + ownMinions.Count + enemyMinions.Count + ownBuildings.Count + enemyBuildings.Count; //without HandCards
                if (objsCount == 0)
                {
                    objsCount = 2;
                }

                Logger.Debug("Hint: ne:NumberEntrances  CT:CalculationTime  aCT:AverageCalculationTimePer1Game  tpo:TimePer1Object  ToR:TimeOutsideRoutine");
                Logger.Debug("#####Stats### ne:{NumberEntrances} Behavior(CT/aCT/tpo):{BehaviorCalcTime}/{averageBCT}/{timePer1Object} Playfield(CT/aCT/tpo):{PlayfieldCreationTime}/{averagePCT}/{timePer1Object} outsideRoutine(ToR/aToR/tpo):{timeOutsideRoutine}/{averageToR}/{timePer1Object}",
                             statNumSuccessfulEntrances, statTimeInsideBehavior.TotalSeconds, (statSumTimeInsideBehavior / statNumSuccessfulEntrances).TotalSeconds, (statTimeInsideBehavior / objsCount).TotalSeconds,
                             statTimeInitPlayfield.TotalSeconds, (statSumTimeInitPlayfield / statNumSuccessfulEntrances).TotalSeconds, (statTimeInitPlayfield / objsCount).TotalSeconds,
                             statTimeOutsideRoutine.TotalSeconds, (statSumTimeOutsideRoutine / (statNumSuccessfulEntrances > 1 ? statNumSuccessfulEntrances - 1 : 1)).TotalSeconds, (statTimeOutsideRoutine / objsCount).TotalSeconds);

                statTimerRoutine = DateTime.Now;

                return(CastRequest);
            }
        }
Esempio n. 17
0
 public abstract int GetBoValue(BoardObj bo, Playfield p);
Esempio n. 18
0
        private VectorAI getDeployPosition(opposite opp)
        {
            VectorAI retval = new VectorAI(0, 0);

            //TODO:

            /*
             * 1.Исходя из Радиуса атаки высчитываем точку его призыва.
             * а)учесть, он дамагер или отвлекатель
             * если дамагер - то так что бы сразу был на линии своей атаки
             * если отвлекатель - то так чтобы башни или другие минионы дамажили как можно дольше + подальше от других вражеских
             * distractor
             * */

            if (noEnemiesOnMySide())
            {
                return(getBackPosition(opp.hc));
            }

            BoardObj enemy         = opp.target;
            bool     enemyMelee    = (opp.target.Range < 1000) ? true : false;          //TODO: set real value
            bool     defenderMelee = (opp.target.attacker.Range < 1000) ? true : false; //TODO: set real value
            bool     attackerMelee = (opp.hc.card.MaxRange < 3) ? true : false;         //TODO: set real value

            VectorAI centerPos = new VectorAI(0, 0);
            int      kingLine  = 0;

            foreach (BoardObj tower in this.ownTowers)
            {
                if (tower.Tower < 10)
                {
                    continue;
                }
                kingLine  = tower.Line;
                centerPos = tower.Position;
                break;
            }

            if (enemyMelee)
            {
                if (attackerMelee)
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            retval = enemy.Position;
                        }
                        else
                        {
                            //0.TODO: ставить так что бы сагрился именно на оппозит + максимально увести вбок под башни
                            //или других юнитов с радиусом атаки и не вывести из под текущего дефендера(того кто ща атакует)
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        retval = enemy.Position;
                    }
                    else
                    {
                        //1.TODO: выбрать:
                        //а)если на линии есть R атакер - то поближе к нему
                        //б)прям на врага
                        //с)если отвлекатель - то увести вбок меж башен
                        retval = enemy.Position;
                    }
                }
                else
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            //2.TODO: max R + под башни если не сдержит или поближе (но не слишком близко на случай аое) и
                            //в бок паралельно 1 башне что бы она доставала если сдержит (что бы потом войска настакались)
                            retval = centerPos;
                        }
                        else
                        {
                            //3.TODO: выбрать кто ценнее - дефендер или атакер и поставить на max R + под башни
                            //если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                        //что бы потом войска настакались но небыли слишком близко на случай аое
                        retval = centerPos;
                    }
                    else
                    {
                        //6.TODO: выбрать:
                        //а)если есть рэндж атакер на поле который сможет его атаковать - выбрать кто ценнее и поставить
                        //так что бы сагрился на менее ценного (не забываем уводить под башни и max R)
                        //б) //2.
                        retval = centerPos;
                    }
                }
            }
            else
            {
                if (attackerMelee)
                {
                    if (enemy.attacked)
                    {
                        retval = enemy.Position;
                    }
                    else if (enemy.attacking)
                    {
                        retval = enemy.Position;
                    }
                    else
                    {
                        //4.TODO: выбрать:
                        //а)если есть рэндж атакер на поле который сможет его атаковать и сам не будет атакован
                        //то выбать что лучше подставить под дефендера и позволить врагу атаковать юнитов пока они
                        //топают к нему (отвлекатель, нельзя дамагера) или поставить сразу на врага (дамагер или отвлекатель)
                        //б)поставить сразу на врага
                        retval = enemy.Position;
                    }
                }
                else
                {
                    if (enemy.attacked)
                    {
                        if (defenderMelee)
                        {
                            //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                        else
                        {
                            //3.TODO: выбрать кто ценнее - дефендер или атакер и поставить на max R + под башни
                            //если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                            //что бы потом войска настакались но небыли слишком близко на случай аое
                            retval = centerPos;
                        }
                    }
                    else if (enemy.attacking)
                    {
                        //2.TODO: max R + под башни если не сдержит или в бок паралельно 1 башне что бы она доставала если сдержит
                        //что бы потом войска настакались но небыли слишком близко на случай аое
                        retval = centerPos;
                    }
                    else
                    {
                        //5.TODO: выбрать:
                        //а)если ток башня - выбрать кто ценнее и поставить на max R
                        //б) //2.
                        retval = centerPos;
                    }
                }
            }

            return(retval);
        }
Esempio n. 19
0
        public sealed override CastRequest GetNextCast()
        {
            List <BoardObj> ownMinions   = new List <BoardObj>();
            List <BoardObj> enemyMinions = new List <BoardObj>();

            List <BoardObj> ownAreaEffects   = new List <BoardObj>();
            List <BoardObj> enemyAreaEffects = new List <BoardObj>();

            List <BoardObj> ownBuildings   = new List <BoardObj>();
            List <BoardObj> enemyBuildings = new List <BoardObj>();

            BoardObj ownKingsTower       = new BoardObj();
            BoardObj ownPrincessTower1   = new BoardObj();
            BoardObj ownPrincessTower2   = new BoardObj();
            BoardObj enemyKingsTower     = new BoardObj();
            BoardObj enemyPrincessTower1 = new BoardObj();
            BoardObj enemyPrincessTower2 = new BoardObj();

            List <Handcard> ownHandCards = new List <Handcard>();

            var battle = ClashEngine.Instance.Battle;

            if (battle == null || !battle.IsValid)
            {
                return(null);
            }
            var om = ClashEngine.Instance.ObjectManager;

            if (om == null)
            {
                return(null);
            }
            var lp = ClashEngine.Instance.LocalPlayer;

            if (lp == null || !lp.IsValid)
            {
                return(null);
            }
            var spells = ClashEngine.Instance.AvailableSpells;

            if (spells == null)
            {
                return(null);
            }

            StringBuilder sb = new StringBuilder();

            using (new PerformanceTimer("GetNextCast entrance"))
            {
                foreach (var spell in spells)
                {
                    if (spell != null && spell.IsValid)
                    {
                        int      lvl = 1;
                        Handcard hc  = new Handcard(spell.Name.Value, lvl);                        //hc.lvl = ??? TODO
                        hc.manacost = spell.ManaCost;
                        //hc.position = ??? TODO
                        //TODO:for all objects - if (new name) get actual params
                        ownHandCards.Add(hc);
                    }
                }

                var aoes = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.AreaEffectObject>();
                foreach (var aoe in aoes)
                {
                    if (aoe != null && aoe.IsValid)
                    {
                        //TODO: get static data for all objects
                        //Here we get dynamic data only
                        BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(aoe.LogicGameObjectData.Name.Value));
                        bo.GId      = aoe.GlobalId;
                        bo.Position = new VectorAI(aoe.StartPosition);
                        bo.Line     = bo.Position.X > 8700 ? 1 : 2;
                        //bo.level = TODO real value
                        //bo.Atk = TODO real value
                        bo.LifeTime = aoe.HealthComponent.RemainingTime;                         //TODO check this value

                        bo.ownerIndex = (int)aoe.OwnerIndex;
                        bool own = bo.ownerIndex == lp.OwnerIndex ? true : false;                         //TODO: replace it on Friendly (for 2x2 mode)
                        bo.own = own;
                        if (own)
                        {
                            ownAreaEffects.Add(bo);
                        }
                        else
                        {
                            enemyAreaEffects.Add(bo);
                        }
                        //hc.position = ??? TODO
                    }
                }

                var chars = om.OfType <Clash.Engine.NativeObjects.Logic.GameObjects.Character>();
                foreach (var @char in chars)
                {
                    //sb.Clear();
                    //i++;
                    //BoardObj bo = new BoardObj();

                    var data = @char.LogicGameObjectData;

                    if (data != null && data.IsValid)
                    {
                        //TODO: get static data for all objects
                        //Here we get dynamic data only
                        BoardObj bo = new BoardObj(CardDB.Instance.cardNamestringToEnum(data.Name.Value));
                        bo.GId      = @char.GlobalId;
                        bo.Position = new VectorAI(@char.StartPosition);
                        bo.Line     = bo.Position.X > 8700 ? 1 : 2;
                        //bo.level = TODO real value
                        //bo.Atk = TODO real value
                        //this.frozen = TODO
                        //this.startFrozen = TODO
                        bo.HP       = @char.HealthComponent.CurrentHealth;                   //TODO: check it
                        bo.Shield   = @char.HealthComponent.CurrentShieldHealth;             //TODO: check it
                        bo.LifeTime =
                            @char.HealthComponent.LifeTime -
                            @char.HealthComponent.RemainingTime;                             //TODO: check it of data.LifeTime, - find real value for battle stage

                        bo.ownerIndex = (int)@char.OwnerIndex;
                        bool own = bo.ownerIndex == lp.OwnerIndex ? true : false;                         //TODO: replace it on Friendly (for 2x2 mode)

                        int tower = 0;
                        switch (bo.Name)
                        {
                        case CardDB.cardName.princesstower:
                            tower = bo.Line;
                            if (bo.own)
                            {
                                if (tower == 1)
                                {
                                    ownPrincessTower1 = bo;
                                }
                                else
                                {
                                    ownPrincessTower2 = bo;
                                }
                            }
                            else
                            {
                                if (tower == 1)
                                {
                                    enemyPrincessTower1 = bo;
                                }
                                else
                                {
                                    enemyPrincessTower2 = bo;
                                }
                            }
                            break;

                        case CardDB.cardName.kingtower:
                            tower = 10 + bo.Line;
                            if (bo.own)
                            {
                                if (lp.OwnerIndex == bo.ownerIndex)
                                {
                                    ownKingsTower = bo;
                                }
                            }
                            else
                            {
                                enemyKingsTower = bo;
                            }
                            break;

                        case CardDB.cardName.kingtowermiddle:
                            tower = 100;
                            break;
                        }
                        if (tower == 0)
                        {
                            if (bo.own)
                            {
                                ownBuildings.Add(bo);
                            }
                            else
                            {
                                enemyBuildings.Add(bo);
                            }
                        }

                        bo.own = own;
                        if (own)
                        {
                            switch (bo.type)
                            {
                            case boardObjType.MOB:
                                ownMinions.Add(bo);
                                break;

                            case boardObjType.BUILDING:
                                if (bo.Tower > 0)
                                {
                                    if (bo.Tower > 9 && bo.ownerIndex == lp.OwnerIndex)
                                    {
                                        ownKingsTower = bo;
                                    }
                                }
                                else
                                {
                                    ownBuildings.Add(bo);
                                }
                                break;
                            }
                        }
                        else
                        {
                            switch (bo.type)
                            {
                            case boardObjType.MOB:
                                enemyMinions.Add(bo);
                                continue;

                            case boardObjType.BUILDING:
                                if (bo.Tower == 0)
                                {
                                    if (bo.Tower > 9)
                                    {
                                        enemyKingsTower = bo;
                                    }
                                }
                                else
                                {
                                    enemyBuildings.Add(bo);
                                }
                                break;
                            }
                        }
                    }
                }
            }

            Playfield p;

            using (new PerformanceTimer("Initialize playfield."))
            {
                p = new Playfield
                {
                    BattleTime          = ClashEngine.Instance.Battle.BattleTime,
                    ownerIndex          = (int)lp.OwnerIndex,
                    ownMana             = (int)lp.Mana,
                    ownHandCards        = ownHandCards,
                    ownAreaEffects      = ownAreaEffects,
                    ownMinions          = ownMinions,
                    ownBuildings        = ownBuildings,
                    ownKingsTower       = ownKingsTower,
                    ownPrincessTower1   = ownPrincessTower1,
                    ownPrincessTower2   = ownPrincessTower2,
                    enemyAreaEffects    = enemyAreaEffects,
                    enemyMinions        = enemyMinions,
                    enemyBuildings      = enemyBuildings,
                    enemyKingsTower     = enemyKingsTower,
                    enemyPrincessTower1 = enemyPrincessTower1,
                    enemyPrincessTower2 = enemyPrincessTower2,
                    //TODO: Add next card
                    //nextCard =
                };

                p.home = p.ownKingsTower.Position.Y < 15250 ? true : false;

                p.initTowers();

                int i = 0;
                foreach (BoardObj t in p.ownTowers)
                {
                    if (t.Tower < 10)
                    {
                        i += t.Line;
                    }
                }
                int kingsLine = 0;
                switch (i)
                {
                case 0:
                    kingsLine = 3;
                    break;

                case 1:
                    kingsLine = 2;
                    break;

                case 2:
                    kingsLine = 1;
                    break;
                }
                foreach (BoardObj t in p.ownTowers)
                {
                    if (t.Tower > 9)
                    {
                        t.Line = kingsLine;
                    }
                }

                p.print();
            }

            Cast bc;

            using (new PerformanceTimer("GetBestCast"))
            {
                bc = this.GetBestCast(p);

                CastRequest retval = null;
                if (bc != null && bc.Position != null)
                {
                    Logger.Information("Cast {bc}", bc.ToString());
                    retval = new CastRequest(bc.SpellName, bc.Position.ToVector2());
                }
                else
                {
                    Logger.Information("Waiting for cast, maybe next tick...");
                }

                return(retval);
            }
        }
Esempio n. 20
0
        public opposite getOppositeToAll(Playfield p, BoardObj defender, int canWaitMissingMana = 3)
        {
            opposite         bestOpposite  = null;
            List <attackDef> attackersList = defender.getPossibleAttackers(p);

            if (attackersList.Count < 1)
            {
                return(bestOpposite);
            }

            List <attackDef> defendersList;

            CardDB.cardName aName;
            CardDB.cardName dName;
            Dictionary <CardDB.cardName, int> aopp;

            Dictionary <CardDB.cardName, opposite> allOpposite = new Dictionary <CardDB.cardName, opposite>();

            foreach (attackDef ad in attackersList)
            {
                if (OppositeDB.ContainsKey(ad.attacker.Name))
                {
                    aopp = OppositeDB[ad.attacker.Name];
                    //-1.Get all obj on board
                    defendersList = ad.attacker.getPossibleAttackers(p);
                    foreach (var def in defendersList)
                    {
                        dName = def.attacker.Name;
                        if (aopp.ContainsKey(dName))
                        {
                            if (!allOpposite.ContainsKey(dName))
                            {
                                allOpposite.Add(dName, new opposite(dName, aopp[dName], def.attacker, ad.attacker));
                            }
                            else
                            {
                                allOpposite[dName].value += aopp[dName];
                            }
                        }
                    }

                    //-2.Get all cards
                    //TODO - enemy have opposite - it depends on his mana
                    if (defender.own)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            dName = hc.card.name;
                            if (canWaitMissingMana >= hc.manacost - p.ownMana && aopp.ContainsKey(dName))
                            {
                                hc.missingMana = hc.manacost - p.ownMana;
                                if (!allOpposite.ContainsKey(dName))
                                {
                                    allOpposite.Add(dName, new opposite(dName, aopp[dName], hc, ad.attacker));
                                }
                                else
                                {
                                    allOpposite[dName].value += aopp[dName];
                                }
                            }
                        }
                    }
                }
                else
                {
                    Handcard tmp   = null;
                    int      count = p.ownHandCards.Count;
                    //TODO automatic creation opposite list
                    if (ad.attacker.Transport == transportType.AIR)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            if (canWaitMissingMana >= hc.manacost - p.ownMana)
                            {
                                if (hc.card.TargetType == targetType.ALL)
                                {
                                    if (ad.attacker.card.DamageRadius > 1000)
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk)
                                        {
                                            if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                            {
                                                tmp = hc;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                        {
                                            tmp = hc;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (ad.attacker.TargetType == targetType.ALL)
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (ad.attacker.card.DamageRadius > 1000 && hc.card.MaxHP > ad.attacker.Atk)
                                    {
                                        if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                        {
                                            tmp = hc;
                                        }
                                    }
                                    else
                                    {
                                        if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                        {
                                            tmp = hc;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else if (ad.attacker.TargetType == targetType.BUILDINGS)
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (hc.card.Atk > ad.attacker.HP * 5 || hc.card.SpawnNumber > 3)
                                    {
                                        tmp = hc;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            foreach (Handcard hc in p.ownHandCards)
                            {
                                if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                {
                                    if (hc.card.Transport == transportType.AIR)
                                    {
                                        if (tmp == null || tmp.card.SpawnNumber < hc.card.SpawnNumber || tmp.card.SummonNumber < hc.card.SummonNumber)
                                        {
                                            tmp = hc;
                                        }
                                    }
                                }
                            }
                            if (tmp == null)
                            {
                                foreach (Handcard hc in p.ownHandCards)
                                {
                                    if (canWaitMissingMana >= hc.manacost - p.ownMana)
                                    {
                                        if (ad.attacker.card.DamageRadius > 1000)
                                        {
                                            if (hc.card.MaxHP > ad.attacker.Atk)
                                            {
                                                if (tmp == null || tmp.card.MaxHP < hc.card.MaxHP)
                                                {
                                                    tmp = hc;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (hc.card.MaxHP > ad.attacker.Atk * 4 || hc.card.SpawnNumber > 3 || hc.card.SummonNumber > 3)
                                            {
                                                tmp = hc;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (tmp == null)
                    {
                        foreach (Handcard hc in p.ownHandCards)
                        {
                            if (hc.card.type == boardObjType.PROJECTILE)
                            {
                                if (tmp == null || tmp.card.Atk < hc.card.Atk)
                                {
                                    tmp = hc;
                                }
                            }
                        }
                    }
                    if (tmp == null && p.ownMana >= 9)
                    {
                        tmp = p.getCheapestCard(boardObjType.NONE, targetType.NONE);
                    }
                    if (tmp != null && !allOpposite.ContainsKey(tmp.card.name))
                    {
                        tmp.missingMana = tmp.manacost - p.ownMana;
                        allOpposite.Add(tmp.card.name, new opposite(tmp.card.name, 10, tmp, ad.attacker));
                    }
                }
            }

            int oppCount = allOpposite.Count;

            if (oppCount > 0)
            {
                foreach (opposite opp in allOpposite.Values)
                {
                    if (OppositeDB.ContainsKey(opp.name))
                    {
                        aopp = OppositeDB[opp.name];
                        foreach (attackDef ad in attackersList)
                        {
                            aName = ad.attacker.Name;
                            if (aopp.ContainsKey(aName))
                            {
                                opp.value -= aopp[aName];
                                //TODO: test - repeat for each or break;
                            }
                        }
                    }
                    else
                    {
                        Logger.Debug("!OppositeDB.ContainsKey");
                    }
                    if (bestOpposite != null)
                    {
                        if (bestOpposite.value < opp.value)
                        {
                            bestOpposite = opp;
                        }
                    }
                    else
                    {
                        bestOpposite = opp;
                    }
                }

                if (bestOpposite != null && bestOpposite.target != null && bestOpposite.hc != null && bestOpposite.hc.card != null)
                {
                    bestOpposite.target.attacker = new BoardObj(bestOpposite.hc.card.name, bestOpposite.hc.lvl);
                }
            }
            return(bestOpposite);
        }
Esempio n. 21
0
        //TODO allCharsInAreaGetDamage

        private void LogBoardObject(BoardObj bo)
        {
            string extrainfo = (bo.frozen ? " frozen:" + bo.startFrozen : "") + (bo.LifeTime > 0 ? " LifeTime:" + bo.LifeTime : "") + (bo.extraData != "" ? " ed:" + bo.extraData : "");

            Logger.Debug("{type} {own:l} {ownerIndex} {Name} {GId} {Position:l} {level} {Atk} {HP} {Shield}{extrainfo:l}", bo.type, bo.own ? "o" : "e", bo.ownerIndex, bo.Name, bo.GId, bo.Position, bo.level, bo.Atk, bo.HP, bo.Shield, extrainfo);
        }
Esempio n. 22
0
        public attackDef(BoardObj att, BoardObj tgt)
        {
            if (att.Line != tgt.Line && tgt.Tower < 10)
            {
                return;
            }
            if (att.Atk == 0)
            {
                return;
            }
            switch (att.TargetType)
            {
            case targetType.GROUND:
                if (tgt.Transport == transportType.AIR)
                {
                    return;
                }
                break;

            case targetType.NONE: return;
            }

            this.attacker = att;
            this.target   = tgt;
            this.empty    = false;

            //TODO: here we calc attackPos based on range and collision radius and speed both bo - просто добавить учёт радиуса коллизий
            if (att.type == boardObjType.BUILDING || att.frozen)
            {
                att.Speed = 0;
            }
            if (tgt.type == boardObjType.BUILDING || tgt.frozen)
            {
                tgt.Speed = 0;
            }

            //TODO: find how to calc it without Math
            int fullDistance   = (int)Math.Sqrt((att.Position.X - tgt.Position.X) * (att.Position.X - tgt.Position.X) + (att.Position.Y - tgt.Position.Y) * (att.Position.Y - tgt.Position.Y));
            int attackDistance = fullDistance - att.Range;

            if (attackDistance <= 0)
            {
                this.time = 0;
            }
            else
            {
                //TODO: get real direction
                //-TODO: переделать с учётом того что цель может двигаться а может и нет и вообще у неё тоже есть радиус атаки и она может остановиться...
                //-тут мы учли обе скорости, но это не правильно
                if (att.Speed + tgt.Speed == 0)
                {
                    this.empty = true;
                    return;
                }
                this.time = attackDistance / (att.Speed + tgt.Speed);
            }


            int distanceAtt = att.Speed * this.time;
            int distanceTgt = tgt.Speed * this.time;

            this.attPos = new VectorAI(att.Position);
            this.tgtPos = new VectorAI(tgt.Position);
            if (this.time > 0)
            {
                if (att.Speed > 0)
                {
                    this.attPos.X = ((fullDistance - distanceAtt) * att.Position.X + distanceAtt * tgt.Position.X) / fullDistance;
                    this.attPos.Y = ((fullDistance - distanceAtt) * att.Position.Y + distanceAtt * tgt.Position.Y) / fullDistance;
                }
                if (tgt.Speed > 0)
                {
                    this.tgtPos.X = ((fullDistance - distanceTgt) * tgt.Position.X + distanceTgt * att.Position.X) / fullDistance;
                    this.tgtPos.Y = ((fullDistance - distanceTgt) * tgt.Position.Y + distanceTgt * att.Position.Y) / fullDistance; //-переделать под реальные радиусы и учесть точку останова для радиусных
                }
            }
        }