public group(bool own, VectorAI position, List <BoardObj> list, int lowHpLimit, bool recalcParams = false, int radius = 3000) { sum = false; this.own = own; this.Position = position; this.SquaredR = radius * radius; this.LowHPlimit = lowHpLimit; addToGroup(list, recalcParams); }
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 } } } }
public void SubtractYInDirection(Playfield p, int y = 1000) { VectorAI moveVector = new VectorAI(0, y); if (p.home) { this.Y += (y * 4); } else { this.Y -= y; } }
public void SubtractYInDirection(Playfield p, int y = 1000) { VectorAI moveVector = new VectorAI(0, y); //Logger.Debug("PlayerPosition: {0}", fieldPosition); if (p.home) { this.Y += (y * 4); } else { this.Y -= y; } }
public VectorAI getDeployPosition(VectorAI targetPosition, deployDirectionRelative relativeDirection = deployDirectionRelative.none, int deployDistance = 0) //for deployDistance you can use hc.card.DamageRadius; we use only for Absolute directions { //Relative directions int sign = this.home ? 1 : -1; int lineSign = targetPosition.X > 8700 ? 1 : -1; if (targetPosition == null) { Logger.Debug("!!![getDeployPosition]Error: Relative targetPosition == NULL"); return(new VectorAI(0, 0)); } switch (relativeDirection) { case deployDirectionRelative.Up: return(new VectorAI(targetPosition.X, targetPosition.Y + sign * (1000 + deployDistance))); case deployDirectionRelative.Down: return(new VectorAI(targetPosition.X, targetPosition.Y - sign * (1000 + deployDistance))); case deployDirectionRelative.RightUp: return(new VectorAI(targetPosition.X - sign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y + sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.Right: return(new VectorAI(targetPosition.X - sign * (1000 + deployDistance), targetPosition.Y)); case deployDirectionRelative.RightDown: return(new VectorAI(targetPosition.X - sign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y - sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.LeftDown: return(new VectorAI(targetPosition.X + sign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y - sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.Left: return(new VectorAI(targetPosition.X + sign * (1000 + deployDistance), targetPosition.Y)); case deployDirectionRelative.LeftUp: return(new VectorAI(targetPosition.X + sign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y + sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.borderSideUp: return(new VectorAI(targetPosition.X + lineSign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y + sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.borderSideMiddle: return(new VectorAI(targetPosition.X + lineSign * (1000 + deployDistance), targetPosition.Y)); case deployDirectionRelative.borderSideDown: return(new VectorAI(targetPosition.X + lineSign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y - sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.centerSideUp: return(new VectorAI(targetPosition.X - lineSign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y + sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.centerSideMiddle: return(new VectorAI(targetPosition.X - lineSign * (1000 + deployDistance), targetPosition.Y)); case deployDirectionRelative.centerSideDown: return(new VectorAI(targetPosition.X - lineSign * (1000 + deployDistance * 7071 / 10000), targetPosition.Y - sign * (1000 + deployDistance * 7071 / 10000))); case deployDirectionRelative.lineCorner: return((lineSign > 0) ? (home ? new VectorAI(17000, 2500) : new VectorAI(17450, 30080)) : (home ? new VectorAI(800, 2200) : new VectorAI(550, 30050))); default: return(new VectorAI(targetPosition)); } }
public int getDistanceToPointFromBorder(VectorAI Position) //TODO: get actual size fom game for Battlefield + bool CanDeploy { int retval = 0; if ((Position.Y > 15250) == home) { int line = Position.X > 8700 ? 2 : 1; foreach (BoardObj bo in this.enemyTowers) { if (bo.Line == line) { } else if (bo.Line == 3) { } } } return(retval); }
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; }
public bool isInGroup(VectorAI pos) { return((Position.X - pos.X) * (Position.X - pos.X) + (Position.Y - pos.Y) * (Position.Y - pos.Y) < SquaredR); }
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; //-переделать под реальные радиусы и учесть точку останова для радиусных } } }
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); }
//If ever will be is available real direction, speed, acceleration, then maybe all this can be changed to a Vector form public int getDistanceToTarget(VectorAI targetPosition) { return((int)Math.Sqrt((targetPosition.x - x) * (targetPosition.x - x) + (targetPosition.y - y) * (targetPosition.y - y))); }
public VectorAI(VectorAI copy) { x = copy.X; y = copy.Y; }
public Cast(string spellName, VectorAI position, Handcard handCard) { this.SpellName = spellName; this.Position = position; this.hc = handCard; }
public int getDistance(VectorAI v2) { return((int)Math.Sqrt((v2.x - x) * (v2.x - x) + (v2.y - y) * (v2.y - y))); }