private void PlanDirectionDependent(PlanOfAttack poa) { Tile startTile = actor.tile; Directions startDirection = actor.dir; var list = new List <AttackOption>(); List <Tile> moveOptions = GetMoveOptions(); // Loop on the move options (movement range) for (int i = 0; i < moveOptions.Count; ++i) { Tile moveTile = moveOptions[i]; actor.Place(moveTile); // Loop on the directions. for (int j = 0; j < 4; ++j) { actor.dir = (Directions)j; var actionOption = new AttackOption(); actionOption.target = moveTile; actionOption.direction = actor.dir; RateFireLocation(poa, actionOption); actionOption.AddMoveTarget(moveTile); list.Add(actionOption); } } // Place the actor back to the initial tile. If we didn't do this, the // AI would be out of sync with the visuals. actor.Place(startTile); actor.dir = startDirection; PickBestOption(poa, list); }
//position and facing angle matter. checks every facing for best option void PlanDirectionDependent(PlanOfAttack poa) { Tile startTile = actor.tile; Directions startDirection = actor.dir; List <AttackOption> list = new List <AttackOption>(); List <Tile> moveOptions = GetMoveOptions(); for (int i = 0; i < moveOptions.Count; ++i) { Tile moveTile = moveOptions[i]; actor.Place(moveTile); for (int j = 0; j < 4; ++j) { actor.dir = (Directions)j; AttackOption ao = new AttackOption(); ao.target = moveTile; ao.direction = actor.dir; RateFireLocation(poa, ao); ao.AddMoveTarget(moveTile); list.Add(ao); } } actor.Place(startTile); actor.dir = startDirection; PickBestOption(poa, list); }
void RateFireLocation(PlanOfAttack poa, AttackOption option) { if (poa.ability != null) { AbilityRange range = poa.ability.GetComponent <AbilityRange>(); List <Tile> tiles = range.GetTilesInRange(owner.board); option.targets = tiles; for (int i = 0; i < tiles.Count; ++i) { Tile tile = tiles[i]; if (!poa.ability.GetComponent <AbilityEffectTarget>().IsTarget(tile)) { continue; } bool isMatch = IsAbilityTargetMatch(poa, tile); if (isMatch && poa.ability.GetComponent <BaseAbilityEffect>() is HealAbilityEffect) { if (tile.content.GetComponent <Health>().FullHP) { option.AddMark(tile, false); option.AddMark(tile, false); } else { option.AddMark(tile, isMatch); } } option.AddMark(tile, isMatch); } } }
private void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { server.GhostChanSay(fac.Shortcut, message); } var text = new StringBuilder(); try { var db = new ZkDataContext(); var playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); /*PlanetWarsTurnHandler.EndTurn(option.Map, * null, * db, * 0, * db.Accounts.Where(x => playerIds.Contains(x.Name) && (x.Faction != null)).ToList(), * text, * null, * db.Accounts.Where(x => option.Attackers.Contains(x.Name) && (x.Faction != null)).ToList(), * server.PlanetWarsEventCreator, server);*/ PlanetWarsTurnHandler.ResolveBattleOutcome(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && (x.Faction != null)).ToList(), db.Accounts.Where(x => option.Attackers.Contains(x.Name) && (x.Faction != null)).ToList(), text, null, server.PlanetWarsEventCreator, server); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } }
void PickBestOption(PlanOfAttack poa, List <AttackOption> list) { int bestScore = 1; List <AttackOption> bestOptions = new List <AttackOption>(); for (int i = 0; i < list.Count; ++i) { AttackOption option = list[i]; int score = option.GetScore(actor, poa.ability); if (score > bestScore) { bestScore = score; bestOptions.Clear(); bestOptions.Add(option); } else if (score == bestScore) { bestOptions.Add(option); } } if (bestOptions.Count == 0) { poa.ability = null; // Clear ability as a sign not to perform it return; } List <AttackOption> finalPicks = new List <AttackOption>(); bestScore = 0; for (int i = 0; i < bestOptions.Count; ++i) { AttackOption option = bestOptions[i]; int score = option.bestAngleBasedScore; if (score > bestScore) { bestScore = score; finalPicks.Clear(); finalPicks.Add(option); } else if (score == bestScore) { finalPicks.Add(option); } } AttackOption choice = finalPicks[UnityEngine.Random.Range(0, finalPicks.Count)]; poa.fireLocation = choice.target.pos; Debug.Log(choice.target.pos); poa.unit = choice.target.content; poa.attackDirection = choice.direction; poa.moveLocation = choice.bestMoveTile.pos; }
private async Task StartChallenge(AttackOption attackOption) { Challenge = attackOption; ChallengeTime = DateTime.UtcNow; AttackOptions.Clear(); await UpdateLobby(); await server.Broadcast(attackOption.Attackers, new PwAttackingPlanet() { PlanetID = attackOption.PlanetID }); }
public void Attack(Player player) { AttackOption attackOption = DetermineAttack(player, true); switch (attackOption.AttackCategory) { case AttackType.Physical: PhysicalAttack(player); break; case AttackType.Spell: switch (Spellbook[attackOption.AttackIndex].SpellCategory) { case SpellType.Fireball: Spellbook[attackOption.AttackIndex].CastFireOffense(this, player, attackOption.AttackIndex); break; case SpellType.Frostbolt: Spellbook[attackOption.AttackIndex].CastFrostOffense(this, player, attackOption.AttackIndex); break; case SpellType.Lightning: Spellbook[attackOption.AttackIndex].CastArcaneOffense(this, player, attackOption.AttackIndex); break; default: throw new ArgumentOutOfRangeException(); } break; case AttackType.Ability: switch (Abilities[attackOption.AttackIndex].AbilityCategory) { case Ability.PoisonBite: case Ability.TailWhip: Abilities[attackOption.AttackIndex].UseOffenseDamageAbility(this, player, attackOption.AttackIndex); break; case Ability.BloodLeech: Abilities[attackOption.AttackIndex].UseBloodLeechAbility(this, player, attackOption.AttackIndex); break; default: throw new ArgumentOutOfRangeException(); } break; default: throw new ArgumentOutOfRangeException(); } GearHelper.DecreaseArmorDurability(player); }
public void DetermineAttackUnitTest() { Player player = new Player("test", PlayerClassType.Mage) { HitPoints = 100, MaxHitPoints = 100 }; Monster monster = new Monster(3, MonsterType.Dragon); MonsterBuilder.BuildMonster(monster); OutputHelper.Display.ClearUserOutput(); AttackOption attackChoice = monster.DetermineAttack(player, false); Assert.AreEqual(AttackType.Spell, attackChoice.AttackCategory); monster.EnergyPoints = 0; attackChoice = monster.DetermineAttack(player, false); Assert.AreEqual(AttackType.Physical, attackChoice.AttackCategory); }
private void PlanDirectionIndependent(PlanOfAttack poa) { Tile startTile = actor.tile; var map = new Dictionary <Tile, AttackOption>(); AbilityRange abilityRange = poa.ability.GetComponent <AbilityRange>(); List <Tile> moveOptions = GetMoveOptions(); // Loop on the move options (movement range). for (int i = 0; i < moveOptions.Count; ++i) { Tile moveTile = moveOptions[i]; actor.Place(moveTile); List <Tile> fireOptions = abilityRange.GetTilesInRange(bc.board); // Loop on the fire options (ability range). for (int j = 0; j < fireOptions.Count; ++j) { Tile fireTile = fireOptions[j]; AttackOption attackOption = null; if (map.ContainsKey(fireTile)) { attackOption = map[fireTile]; } else { attackOption = new AttackOption(); attackOption.target = fireTile; attackOption.direction = actor.dir; map[fireTile] = attackOption; RateFireLocation(poa, attackOption); } attackOption.AddMoveTarget(moveTile); } } // Place the actor back to the initial tile. If we didn't do this, the // AI would be out of sync with the visuals. actor.Place(startTile); var list = new List <AttackOption>(map.Values); PickBestOption(poa, list); }
private void RateFireLocation(PlanOfAttack poa, AttackOption attackOption) { AbilityArea area = poa.ability.GetComponent <AbilityArea>(); List <Tile> tiles = area.GetTilesInArea(bc.board, attackOption.target.pos); attackOption.areaTargets = tiles; attackOption.isCasterMatch = IsAbilityTargetMatch(poa, actor.tile); for (int i = 0; i < tiles.Count; ++i) { Tile tile = tiles[i]; if (actor.tile == tiles[i] || !poa.ability.IsTarget(tile)) { continue; } bool isMatch = IsAbilityTargetMatch(poa, tile); attackOption.AddMark(tile, isMatch); } }
void PlanDirectionIndependent(PlanOfAttack poa) { Tile startTile = actor.tile; Dictionary <Tile, AttackOption> map = new Dictionary <Tile, AttackOption>(); AbilityRange ar = poa.ability.GetComponent <AbilityRange>(); List <Tile> moveOptions = GetMoveOptions(); for (int i = 0; i < moveOptions.Count; ++i) { Tile moveTile = moveOptions[i]; actor.Place(moveTile); List <Tile> fireOptions = ar.GetTilesInRange(bc.board); for (int j = 0; j < fireOptions.Count; ++j) { Tile fireTile = fireOptions[j]; AttackOption ao = null; if (map.ContainsKey(fireTile)) { ao = map[fireTile]; } else { ao = new AttackOption(); map[fireTile] = ao; ao.target = fireTile; ao.direction = actor.dir; RateFireLocation(poa, ao); } ao.AddMoveTarget(moveTile); } } actor.Place(startTile); List <AttackOption> list = new List <AttackOption>(map.Values); PickBestOption(poa, list); }
private List <Faction> GetDefendingFactions(AttackOption target) { if (target.OwnerFactionID != null) { var ret = new List <Faction>(); ret.Add(factions.Find(x => x.FactionID == target.OwnerFactionID)); // add allies as defenders using (var db = new ZkDataContext()) { var planet = db.Planets.Find(target.PlanetID); foreach (var of in db.Factions.Where(x => !x.IsDeleted && x.FactionID != target.OwnerFactionID && x.FactionID != AttackingFaction.FactionID)) { if (of.GaveTreatyRight(planet, x => x.EffectBalanceSameSide == true)) { ret.Add(of); } } } return(ret); } return(factions.Where(x => x != AttackingFaction).ToList()); }
/// <summary> /// Picks the best option from a list of attack options using the score of /// each option. /// - If a best option is found (score > 0), the plan of attack is updated /// with the necessary locations and direction. /// - If there is not best option, the plan of attack's ability is set /// to null and nothing else is done. /// </summary> /// /// <param name="poa">The plan of attack.</param> /// <param name="list">The list of options.</param> private void PickBestOption(PlanOfAttack poa, List <AttackOption> list) { int bestScore = 1; var bestOptions = new List <AttackOption>(); // Loop on all the options. for (int i = 0; i < list.Count; ++i) { AttackOption option = list[i]; int score = option.GetScore(actor, poa.ability); // If the option's score is better than the current best, replace the // best and keep only it in the best options list. if (score > bestScore) { bestScore = score; bestOptions.Clear(); bestOptions.Add(option); } // If the option's score is the same as the current best, simply add // it to the best options list. else if (score == bestScore) { bestOptions.Add(option); } } // If there is not best options, clear the plan of attack's ability and // stop here. if (bestOptions.Count == 0) { poa.ability = null; return; } var finalOptions = new List <AttackOption>(); bestScore = 0; // Loop on the best options. // TODO: Use the same method to get the best options and the final options (refactor). for (int i = 0; i < bestOptions.Count; ++i) { AttackOption option = bestOptions[i]; int score = option.bestAngleBasedScore; if (score > bestScore) { bestScore = score; finalOptions.Clear(); finalOptions.Add(option); } else if (score == bestScore) { finalOptions.Add(option); } } // Pick a random option and use it to populate the plan of attack's fields. AttackOption finalOption = finalOptions[Random.Range(0, finalOptions.Count)]; poa.fireLocation = finalOption.target.pos; poa.attackDirection = finalOption.direction; poa.moveLocation = finalOption.bestMoveTile.pos; }
public void StartToProcessOptions(JSONObject jsonObject) { int count = 0; foreach (JSONObject j in jsonObject["options"].list) { switch (j["option_type"].str) { case MULLIGAN: //WHY DID I DO THIS /* * Mulligan m = new Mulligan(); * m.n = count; * // m.cardGuid = j["cardGuid"].str; * count++; * if(!options.ContainsKey(m.cardGuid)) * { * options.Add(m.cardGuid, new List<Option>()); * } * * options[m.cardGuid].Add(m); * */ break; case NO_MULLIGAN: NoMulligan nm = new NoMulligan(); nm.n = count; count++; if (!options.ContainsKey(noMulliganKey)) { options.Add(noMulliganKey, new List <Option>()); } options[noMulliganKey].Add(nm); break; case END_TURN: EndTurn et = new EndTurn(); et.n = count; count++; if (!options.ContainsKey(END_TURN)) { options.Add(END_TURN, new List <Option>()); } options[END_TURN].Add(et); break; case PLAY_CARD: PlayCardOption pc = new PlayCardOption(); pc.n = count; pc.cardGuid = j["source_uid"].n.ToString(); pc.targetGuid = j["target_uid"].n.ToString(); count++; if (!options.ContainsKey(pc.cardGuid)) { options.Add(pc.cardGuid, new List <Option>()); } options[pc.cardGuid].Add(pc); break; case ATTACK: AttackOption a = new AttackOption(); a.n = count; a.cardGuid = j ["source_uid"].n.ToString(); a.defenderGuid = j["target_uid"].n.ToString(); count++; if (!options.ContainsKey(a.cardGuid)) { options.Add(a.cardGuid, new List <Option>()); } options[a.cardGuid].Add(a); break; case HERO_POWER: break; case PLAY_SPELL: PlaySpellOption ps = new PlaySpellOption(); ps.n = count; ps.cardGuid = j["cardGuid"].n.ToString(); ps.target = j["targetGuid"].n.ToString(); count++; if (!options.ContainsKey(ps.cardGuid)) { options.Add(ps.cardGuid, new List <Option>()); } options[ps.cardGuid].Add(ps); break; default: break; } } }
void OnGUI() { //Player 1's hp bar float hpRatio = (float)player1.hpCurrent / (float)player1.hpMax; float targetBarWidth = healthBar.width * hpRatio; float deltaValue = targetBarWidth - healthBar1Width; healthBar1Width += deltaValue / 8; if (Mathf.Abs(deltaValue) < .02f) healthBar1Width = targetBarWidth; if (healthBar1Width == targetBarWidth) targetHealthReached = true; GUI.DrawTexture(new Rect(10, Screen.height - healthBack.height - 20, healthBack.width, healthBack.height), healthBack, ScaleMode.StretchToFill); GUI.DrawTexture(new Rect(10, Screen.height - healthBar.height - 20, healthBar1Width, healthBar.height), healthBar, ScaleMode.StretchToFill); GUI.Label(new Rect(10, Screen.height - 20, 100, 25), player1.hpCurrent + "/" + player1.hpMax); //Player 2's hp bar hpRatio = (float)player2.hpCurrent / (float)player2.hpMax; targetBarWidth = healthBar.width * hpRatio; healthBar2Width += (targetBarWidth - healthBar2Width) / 8; if (Mathf.Abs(targetBarWidth - healthBar2Width) < .02f) healthBar2Width = targetBarWidth; if (healthBar1Width == targetBarWidth) targetHealthReached2 = true; GUI.DrawTexture(new Rect(Screen.width - healthBack.width - 10, Screen.height - healthBack.height - 20, healthBack.width, healthBack.height), healthBack, ScaleMode.StretchToFill); GUI.DrawTexture(new Rect(Screen.width - healthBar2Width - 10, Screen.height - healthBar.height - 20, healthBar2Width, healthBar.height), healthBar, ScaleMode.StretchToFill); GUI.Label(new Rect(Screen.width - 40, Screen.height - 20, 50, 25), player2.hpCurrent + "/" + player2.hpMax); //Player 1's endurance bar float enduranceRatio = (float)player1.enduranceCurrent / (float)player1.enduranceMax; float barHeight = enduranceBar.height * enduranceRatio; enduranceBar1Height += (barHeight - enduranceBar1Height) / 8; if (Mathf.Abs(barHeight - enduranceBar1Height) < .02f) enduranceBar1Height = barHeight; if (enduranceBar1Height == barHeight && playerTurn == PlayerIndex.One) targetEnduranceReached = true; GUI.DrawTexture(new Rect(10, Screen.height - enduranceBack.height - 60, enduranceBack.width, enduranceBack.height), enduranceBack, ScaleMode.StretchToFill); GUI.DrawTexture(new Rect(10, Screen.height - enduranceBar1Height - 60, enduranceBar.width, enduranceBar1Height), enduranceBar, ScaleMode.StretchToFill); GUI.Label(new Rect(15 + enduranceBar.width, Screen.height - 85, 100, 25), player1.enduranceCurrent + "/" + player1.enduranceMax); //Player 2's endurance bar enduranceRatio = (float)player2.enduranceCurrent / (float)player2.enduranceMax; barHeight = enduranceBar.height * enduranceRatio; enduranceBar2Height += (barHeight - enduranceBar2Height) / 8; if (Mathf.Abs(barHeight - enduranceBar2Height) < .02f) enduranceBar2Height = barHeight; if (enduranceBar2Height == barHeight && playerTurn == PlayerIndex.Two) targetEnduranceReached = true; GUI.DrawTexture(new Rect(Screen.width - enduranceBack.width - 10, Screen.height - enduranceBack.height - 60, enduranceBack.width, enduranceBack.height), enduranceBack, ScaleMode.StretchToFill); GUI.DrawTexture(new Rect(Screen.width - enduranceBar.width - 10, Screen.height - enduranceBar2Height - 60, enduranceBar.width, enduranceBar2Height), enduranceBar, ScaleMode.StretchToFill); GUI.Label(new Rect(Screen.width - enduranceBar.width - 45, Screen.height - 85, 100, 25), player2.enduranceCurrent + "/" + player2.enduranceMax); switch (turnStage) //Depending on the turn stage, the GUI does different things { case TurnStage.PlayerStart: //Player must hit button to start their turn string playerString = ""; if (playerTurn == PlayerIndex.One) playerString = "Player 1"; else playerString = "Player 2"; if (GUI.Button(new Rect(Screen.width / 2, Screen.height / 2, 100, 20), playerString + " Start!")) { turnStage = TurnStage.RecoverEndurance; } break; case TurnStage.RecoverEndurance: //Labels the stage GUI.Label(new Rect(Screen.width / 2 - 100, 50, 200, 20), "Recovery Stage"); break; case TurnStage.ChooseAttack: //Labels the stage GUI.Label(new Rect(Screen.width / 2 - 100, 50, 200, 20), "Choose Attack"); for (int i = 0; i < attacker.attackList.Count; i++) //Goes through all the attack options for the current attacker { //Creates a button for each attack option AttackOption atk = attacker.attackList[i]; float cellHeight = 60; //If player has enough endurance, button is green. If not, button is red if (attacker.enduranceCurrent < atk.enduranceCost) GUI.color = Color.red; else GUI.color = Color.green; float yValue = (Screen.height / 2 - (float)attacker.attackList.Count / 2 * cellHeight) + (i * cellHeight) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue, 400, 40), "|" + atk.attackName + "| " + atk.attackGroup.ToString() + " " + atk.attackMethod.ToString() + " Power: " + atk.basePower + " Cost: " + atk.enduranceCost + "\n" + atk.attackDescription)) { if(attacker.enduranceCurrent >= atk.enduranceCost){ currentAttack = atk; turnStage = TurnStage.ChooseAttackType; } } } //Player can choose to not attack GUI.color = Color.green; if(GUI.Button (new Rect(Screen.width / 2 - 100, Screen.height / 2 + 200, 200, 40), "Don't Attack")){ currentAttack = null; turnStage = TurnStage.ChooseDefense; } break; case TurnStage.ChooseAttackType: //Player can choose either rock, paper, or scissors for their attack type //Creates a button for each GUI.Label(new Rect(Screen.width / 2 - 100, 50, 200, 20), "Jan-ken Attack!"); float cellHeight2 = 60; float yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (0 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "ROCK")) { actionAttack = ActionType.Rock; turnStage = TurnStage.ExecuteAttack; } cellHeight2 = 60; yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (1 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "PAPER")) { actionAttack = ActionType.Paper; turnStage = TurnStage.ExecuteAttack; } cellHeight2 = 60; yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (2 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "SCISSORS")) { actionAttack = ActionType.Scissors; turnStage = TurnStage.ExecuteAttack; } break; case TurnStage.ChooseDefense: //Labels the stage GUI.Label(new Rect(Screen.width / 2 - 100, 50, 200, 20), "Choose Defense"); for (int i = 0; i < attacker.defendList.Count; i++) //Goes through all the defend options for the current player { //Creates a button for each defend option DefendOption def = attacker.defendList[i]; float cellHeight = 60; //If player has enough endurance, button is green, if not, button is red if (attacker.enduranceCurrent < def.enduranceCost) GUI.color = Color.red; else GUI.color = Color.green; float yValue = (Screen.height / 2 - (float)attacker.attackList.Count / 2 * cellHeight) + (i * cellHeight) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue, 400, 40), "|" + def.defendName + "| " + def.defendGroup.ToString() + " " + " Defense strength: " + def.baseDefense + " Cost: " + def.enduranceCost + "\n" + def.defendDescription)) { if(attacker.enduranceCurrent >= def.enduranceCost){ currentDefend = def; turnStage = TurnStage.ChooseDefenseType; attacker.UseEndurance(currentDefend.enduranceCost); } } } //Player can choose to not defend GUI.color = Color.green; if(GUI.Button (new Rect(Screen.width / 2 - 100, Screen.height / 2 + 100, 200, 40), "Don't Defend")){ currentDefend = null; turnStage = TurnStage.ChooseDefenseType; } break; case TurnStage.ChooseDefenseType: //If the player has chosen to defend, they can choose rock, paper, or scissors for defend type if(currentDefend != null){ GUI.Label(new Rect(Screen.width / 2 - 100, 50, 200, 20), "Jan-ken Attack!"); cellHeight2 = 60; yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (0 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "ROCK")) { actionDefend = ActionType.Rock; turnStage = TurnStage.PlayerStart; if(playerTurn == PlayerIndex.One) playerTurn = PlayerIndex.Two; else playerTurn = PlayerIndex.One; DefendParticleGo(); } cellHeight2 = 60; yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (1 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "PAPER")) { actionDefend = ActionType.Paper; turnStage = TurnStage.PlayerStart; if(playerTurn == PlayerIndex.One) playerTurn = PlayerIndex.Two; else playerTurn = PlayerIndex.One; DefendParticleGo(); } cellHeight2 = 60; yValue2 = (Screen.height / 2 - 3f / 2 * cellHeight2) + (2 * cellHeight2) + 10; if (GUI.Button(new Rect(Screen.width / 2 - 200, yValue2, 400, 40), "SCISSORS")) { actionDefend = ActionType.Scissors; turnStage = TurnStage.PlayerStart; if(playerTurn == PlayerIndex.One) playerTurn = PlayerIndex.Two; else playerTurn = PlayerIndex.One; DefendParticleGo(); } } else //If there was no defend chosen, then we just skip ahead { turnStage = TurnStage.PlayerStart; if(playerTurn == PlayerIndex.One) playerTurn = PlayerIndex.Two; else playerTurn = PlayerIndex.One; } break; case TurnStage.EndOfBattle: //Displays which player won and provides a button that will take players to the upgrade screen playerString = ""; if (losingPlayer.playerIndex == PlayerIndex.Two) playerString = "Player 1"; else playerString = "Player 2"; if (GUI.Button(new Rect(Screen.width / 2, Screen.height / 2, 100, 20), playerString + " Wins!")) { battleEnd = true; } break; } }
List <Faction> GetDefendingFactions(AttackOption target) { if (target.OwnerFactionID != null) { return new List <Faction> { factions.Find(x => x.FactionID == target.OwnerFactionID) } } ; return(factions.Where(x => x != AttackingFaction).ToList()); } void JoinPlanetAttack(int targetPlanetId, string userName) { AttackOption attackOption = AttackOptions.Find(x => x.PlanetID == targetPlanetId); if (attackOption != null) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && account.FactionID == AttackingFaction.FactionID && account.CanPlayerPlanetWars()) { // remove existing user from other options foreach (AttackOption aop in AttackOptions) { aop.Attackers.RemoveAll(x => x == userName); } // add user to this option if (attackOption.Attackers.Count < attackOption.TeamSize) { attackOption.Attackers.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins attack on {1}", userName, attackOption.Name), true); if (attackOption.Attackers.Count == attackOption.TeamSize) { StartChallenge(attackOption); } else { UpdateLobby(); } } } } } } void JoinPlanetDefense(int targetPlanetID, string userName) { if (Challenge != null && Challenge.PlanetID == targetPlanetID && Challenge.Defenders.Count < Challenge.TeamSize) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && GetDefendingFactions(Challenge).Any(y => y.FactionID == account.FactionID) && account.CanPlayerPlanetWars()) { if (!Challenge.Defenders.Any(y => y == user.Name)) { Challenge.Defenders.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins defense of {1}", userName, Challenge.Name), true); if (Challenge.Defenders.Count == Challenge.TeamSize) { AcceptChallenge(); } else { UpdateLobby(); } } } } } } void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { tas.Say(TasClient.SayPlace.Channel, fac.Shortcut, message, true); } var text = new StringBuilder(); try { var db = new ZkDataContext(); List <string> playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); PlanetWarsTurnHandler.EndTurn(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && x.Faction != null).ToList(), text, null, db.Accounts.Where(x => option.Attackers.Contains(x.Name) && x.Faction != null).ToList()); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } } void ResetAttackOptions() { AttackOptions.Clear(); AttackerSideChangeTime = DateTime.UtcNow; Challenge = null; ChallengeTime = null; using (var db = new ZkDataContext()) { var gal = db.Galaxies.First(x => x.IsDefault); int cnt = 2; var attacker = db.Factions.Single(x => x.FactionID == AttackingFaction.FactionID); var planets = gal.Planets.Where(x => x.OwnerFactionID != AttackingFaction.FactionID).OrderByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Dropships)).ThenByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Influence)).ToList(); // list of planets by attacker's influence foreach (var planet in planets) { if (planet.CanMatchMakerPlay(attacker)) { // pick only those where you can actually attack atm InternalAddOption(planet); cnt--; } if (cnt == 0) { break; } } if (!AttackOptions.Any(y => y.TeamSize == 2)) { var planet = planets.FirstOrDefault(x => x.TeamSize == 2 && x.CanMatchMakerPlay(attacker)); if (planet != null) { InternalAddOption(planet); } } } UpdateLobby(); tas.Say(TasClient.SayPlace.Channel, AttackingFaction.Shortcut, "It's your turn! Select a planet to attack", true); } void InternalAddOption(Planet planet) { AttackOptions.Add(new AttackOption { PlanetID = planet.PlanetID, Map = planet.Resource.InternalName, OwnerFactionID = planet.OwnerFactionID, Name = planet.Name, TeamSize = planet.TeamSize, }); } void SaveStateToDb() { var db = new ZkDataContext(); Galaxy gal = db.Galaxies.First(x => x.IsDefault); gal.MatchMakerState = JsonConvert.SerializeObject((MatchMakerState)this); gal.AttackerSideCounter = AttackerSideCounter; gal.AttackerSideChangeTime = AttackerSideChangeTime; db.SubmitAndMergeChanges(); } void StartChallenge(AttackOption attackOption) { Challenge = attackOption; ChallengeTime = DateTime.UtcNow; AttackOptions.Clear(); UpdateLobby(); } void TasOnChannelUserAdded(object sender, TasEventArgs args) { string chan = args.ServerParams[0]; string userName = args.ServerParams[1]; Faction faction = factions.FirstOrDefault(x => x.Shortcut == chan); if (faction != null) { var db = new ZkDataContext(); var acc = Account.AccountByName(db, userName); if (acc != null && acc.CanPlayerPlanetWars()) { UpdateLobby(userName); } } } /// <summary> /// Intercept channel messages for attacking/defending /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void TasOnPreviewSaid(object sender, CancelEventArgs <TasSayEventArgs> args) { if (args.Data.Text.StartsWith("!") && (args.Data.Place == TasSayEventArgs.Places.Channel || args.Data.Place == TasSayEventArgs.Places.Normal) && args.Data.Origin == TasSayEventArgs.Origins.Player && args.Data.UserName != GlobalConst.NightwatchName) { int targetPlanetId; if (int.TryParse(args.Data.Text.Substring(1), out targetPlanetId)) { JoinPlanet(args.Data.UserName, targetPlanetId); } } } /// <summary> /// Remove/reduce poll count due to lobby quits /// </summary> void TasOnUserRemoved(object sender, TasEventArgs args) { if (Challenge == null) { if (AttackOptions.Count > 0) { string userName = args.ServerParams[0]; int sumRemoved = 0; foreach (AttackOption aop in AttackOptions) { sumRemoved += aop.Attackers.RemoveAll(x => x == userName); } if (sumRemoved > 0) { UpdateLobby(); } } } else { string userName = args.ServerParams[0]; if (Challenge.Defenders.RemoveAll(x => x == userName) > 0) { UpdateLobby(); } } } void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { try { if (Challenge == null) { // attack timer if (DateTime.UtcNow > GetAttackDeadline()) { AttackerSideCounter++; ResetAttackOptions(); } } else { // accept timer if (DateTime.UtcNow > GetAcceptDeadline()) { if (Challenge.Defenders.Count >= Challenge.Attackers.Count - 1 && Challenge.Defenders.Count > 0) { AcceptChallenge(); } else { RecordPlanetwarsLoss(Challenge); AttackerSideCounter++; ResetAttackOptions(); } } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } }
//Adds an attack option to this profile public void AddAttackOption(string attackName, AttackMethod attackMethod, ActionGroup attackGroup, int baseDamage, int enduranceCost, string attackDescription) { AttackOption atkOpt = new AttackOption(attackName, attackMethod, attackGroup, baseDamage, enduranceCost, attackDescription); attackList.Add(atkOpt); }
public PlanOfAttack Evaluate() { // Create an empty plan of Attack to fill in PlanOfAttack poa = new PlanOfAttack(); poa.fireLocations = new List <Tile>(); poa.moveLocation = actor.tile.pos; // Step 1: Decide what ability to use with a pattern if available. Redraw hand if unusable. AttackPattern pattern = actor.GetComponentInChildren <AttackPattern>(); if (pattern) { pattern.Pick(poa); } List <Tile> moveOptions = GetMoveOptions(); moveOptions.Add(actor.tile); Tile startTile = actor.tile; Dictionary <Tile, AttackOption> map = new Dictionary <Tile, AttackOption>(); for (int i = 0; i < moveOptions.Count; ++i) { Tile moveTile = moveOptions[i]; actor.Place(moveTile); AttackOption ao = null; if (map.ContainsKey(moveTile)) { ao = map[moveTile]; } else { ao = new AttackOption(); map[moveTile] = ao; RateFireLocation(poa, ao); } ao.AddMoveTarget(moveTile); } actor.Place(startTile); List <AttackOption> list = new List <AttackOption>(map.Values); PickBestOption(poa, list); // Step 2: Determine where to move and aim to best use the ability if (poa.ability == null) { MoveTowardOpponent(poa); } else if (poa.ability.GetComponent <BaseAbilityEffect>() is HealAbilityEffect && poa.moveLocation == actor.tile.pos) { foreach (Tile t in poa.fireLocations) { if (t.content != null) { t.content.GetComponent <Unit>().beingHealed = true; } } } // Return the completed plan return(poa); }
void StartChallenge(AttackOption attackOption) { Challenge = attackOption; ChallengeTime = DateTime.UtcNow; AttackOptions.Clear(); UpdateLobby(); }
void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { tas.Say(SayPlace.Channel, fac.Shortcut, message, true); } var text = new StringBuilder(); try { var db = new ZkDataContext(); List<string> playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); PlanetWarsTurnHandler.EndTurn(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && x.Faction != null).ToList(), text, null, db.Accounts.Where(x => option.Attackers.Contains(x.Name) && x.Faction != null).ToList()); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } }
List<Faction> GetDefendingFactions(AttackOption target) { if (target.OwnerFactionID != null) return new List<Faction> { factions.Find(x => x.FactionID == target.OwnerFactionID) }; return factions.Where(x => x != AttackingFaction).ToList(); }
public void AddAttackOption(AttackOption attopt) { AttackOption atkOpt = new AttackOption(attopt.attackName,attopt.attackMethod,attopt.attackGroup, attopt.basePower, attopt.enduranceCost, attopt.attackDescription); attackList.Add (atkOpt); }