private void Scout_Click(object sender, EventArgs e) { bool running = controller.Enabled; controller.Stop(); string report = "When scouting the sorrounding area, you see the following:"; List <WorldPlayer> objects = World.Instance.actors.Where(a => AIUtility.Distance(a.WorldPosition, player.WorldPosition) == 1).ToList(); foreach (var obj in objects) { report += obj.Report() + "\n"; } Scouting s = player.GetTree("Scouting") as Scouting; if (s is null) { Scouting item = new Scouting(); player.trees.Add(item); item.Activate(); } else { s.Xp += objects.Count; } MessageBox.Show(report); if (running) { controller.Start(); } }
public CaravanRoute(City start, City end, CaravanMarket caravanMarket, List <string> itemTypes, int money, List <InventoryItem> items = null) { this.start = start; this.end = end; this.itemTypes = itemTypes; this.money = money; this.items = items; days = AIUtility.Distance(start.position, end.position) / 10; BuyItems(); this.caravanMarket = caravanMarket; }
private void WorldProgressTime(object sender, EventArgs e) { World.Instance.ProgressTime(new TimeSpan(0, 0, 30, 0)); worldRenderer.Redraw = true; //Is there a way we can avoid this? Render(); if (!player.spectatorMode) { startMission.Visible = player.availableActions.Exists(a => a is StartMission); enterCity.Visible = player.availableActions.Exists(a => a is InteractCity); scout.Visible = World.Instance.actors.Exists(p => AIUtility.Distance(p.WorldPosition, player.WorldPosition) == 1); World.Instance.actors.FindAll(a => a is PureWorldPlayer && a.WorldPosition == player.WorldPosition).ForEach(a => (a as PureWorldPlayer).OnPlayerEntry()); } else { if (player.caravan != null) { startMission.Visible = false; enterCity.Visible = false; if (player.WorldPosition == player.caravan.end.position) { //The caravan has ended player.troop.Image = Resources.playerTroop; player.caravan.End(); player.spectatorMode = false; int payed = player.caravan.GetGuardPayment(); MessageBox.Show($"The caravan has finally reached its goal. You have been payed {payed} coins."); player.Money.RawValue += payed; player.caravan = null; } Scouting s = player.GetTree("Scouting") as Scouting; if (World.random.Next(30 + (s?.level ?? 0) * 2) == 1) { controller.Stop(); MessageBox.Show($"The caravan is being attacked!"); player.troop.Image = Resources.playerTroop; Mission.Mission mission = new CaravanDefense(); int difficulty = player.caravan.items.Select(i => i.Amount * i.Cost).Sum() / 200; RunMission(difficulty, mission); player.troop.Image = Resources.Caravan; } } } }
private void ActionOptionList_SelectedIndexChanged(object sender, EventArgs e) { if (cityV.actionOptionList.SelectedIndex == -1) { cityV.button1.Visible = false; return; } City selected = cityV.actionOptionList.SelectedItem as City; cityV.actionOptionList.Text = selected.position.ToString(); cityV.button1.Text = "Travel"; time = new TimeSpan(AIUtility.Distance(city.position, selected.position) / 20, 0, 0); cost = (int)time.TotalHours * 10; cityV.actionOptionLabel.Visible = true; cityV.actionOptionLabel.Text = $"{selected.Description} Travel in {time.Days} days and {time.Hours} hours. It costs {cost} coins."; cityV.button1.Click += Button1_Click; cityV.button1.Visible = true; cityV.button1.Enabled = cityV.player.Money.Value >= cost; }
public override void WorldAction() { week++; if (week % 51 != 0) { return; } //Find closest tile to work Point point = city.position; int searchSize = 1; WorldTile toWork = null; while (true) { double maxForest = -0.1; for (int x = 0; x < searchSize; x++) { for (int y = 0; y < searchSize; y++) { WorldTile tile = World.Instance.worldMap.Get((x + point.X).Cut(0, World.WORLD_SIZE - 1), (y + point.Y).Cut(0, World.WORLD_SIZE - 1)); if (tile.forest > maxForest) { toWork = tile; maxForest = tile.forest; } } } if (maxForest > 0.2) { break; } if (searchSize == 10) { break; } searchSize++; } double work = (double)workers * (5 - AIUtility.Distance(toWork.position, point)).Cut(1, 6) / 50 * (1.25 - World.random.NextDouble() / 2); toWork.forest -= work; toWork.forest = toWork.forest.Cut(0, 100); ProduceItem("Wood", (int)(work * 10)); }
GenerateMission(int difficulty, int Round, ref Map map, Player player) { string desc = "Welcome to the mission. "; #region Player Creation List <Player> players = new List <Player>() { player }; //Find position of player players[0].troop.Position = map.DeterminSpawnPoint(1, SpawnType.road)[0]; //Find position of campsite Point camp; camp = map.map.Cast <MapTile>().ToList().Where(t => t.neighbours.rawMaptiles.Count(n => n.type.FType == FieldType.land) == 4).OrderByDescending(m => AIUtility.Distance(m.position, player.troop.Position)).First().position; //Make camp fire Building fireplace = new Building("Fireplace", camp, Resources.firePlace, map); map.entities.Add(fireplace); map.renderObjects.Add(new EntityRenderObject(fireplace, new TeleportPointAnimation(new Point(0, 0), fireplace.Position))); int enemyNumber = Round / 5 + 2 * difficulty / 3; List <Point> startPos = new List <Point>(); List <Point> toCheck = map.map[camp.X, camp.Y].neighbours.rawMaptiles.ToList().ConvertAll(m => m.position); //Add a few more than neccessary so ones which are path can be removed while (startPos.Count <= enemyNumber + 10 && toCheck.Count != 0) { Point checking = toCheck[0]; toCheck.Remove(checking); startPos.Add(checking); map.map[checking.X, checking.Y].neighbours.rawMaptiles.ToList().ForEach(m => { //Check if it does not exist, if land and is not blocked if (!startPos.Exists(f => f.X == m.position.X && f.Y == m.position.Y) && m.type.FType == FieldType.land && m.free) { toCheck.Add(m.position); } }); } enemyNumber = Math.Min(enemyNumber, startPos.Count); //in case there are too few positions //If extra, remove path Map _map = map; while (startPos.Count > enemyNumber) { if (startPos.Exists(f => _map.map[f.X, f.Y].type.type == MapTileTypeEnum.road)) { startPos.Remove(startPos.First(f => _map.map[f.X, f.Y].type.type == MapTileTypeEnum.road)); } //If no path left remove random else { startPos.RemoveAt(World.World.random.Next(startPos.Count)); } } //Generate basic bandits and set position for (int i = 0; i < enemyNumber; i++) { string name = $"Bandit {i + 1}"; DefensiveBanditAI item = new DefensiveBanditAI(PlayerType.computer, name, map, new Player[] { player }, camp); item.troop = new Troop(name, new Weapon(3 + difficulty / 5 + Round / 2, BaseAttackType.melee, BaseDamageType.sharp, 1, "Dagger", 2, false), Resources.enemyScout, 0, map, item, Dodge: 25) { armours = new List <Armour> { new Armour("Cap", 10, new List <BodyParts> { BodyParts.Head }, Material.Materials.First(m => m.name == "Cloth"), Quality.Simple, ArmourLayer.clothing), new Armour("Shirt", 20, new List <BodyParts> { BodyParts.Torso }, Material.Materials.First(m => m.name == "Cloth"), Quality.Poor, ArmourLayer.clothing), new Armour("Hose", 25, new List <BodyParts> { BodyParts.UpperLegs, BodyParts.LeftLowerLeg, BodyParts.RightLowerLeg }, Material.Materials.First(m => m.name == "Cloth"), Quality.Common, ArmourLayer.clothing), new Armour("Cloak", 35, new List <BodyParts> { BodyParts.LeftUpperArm, BodyParts.RightUpperArm, BodyParts.Torso, BodyParts.UpperLegs, BodyParts.LeftLowerLeg, BodyParts.RightLowerLeg }, Material.Materials.First(m => m.name == "Wool"), Quality.Common, ArmourLayer.light) } }; players.Add(item); players[i + 1].troop.Position = startPos[i]; } #endregion Player Creation #region WinCodition Creation //Must kill spider nest to win List <WinCheck> wins = new List <WinCheck> { deathCheck }; desc += "Kill all the bandits to steal their treasure. "; #endregion WinCodition Creation #region DeathCondition Creation List <WinCheck> deaths = new List <WinCheck> { playerDeath }; desc += "Do not die. "; #endregion DeathCondition Creation desc += "Good luck! "; return(players, wins, deaths, desc); }
string description) GenerateMission(int difficulty, int Round, ref Map map, Player player) { string desc = "Welcome to an epic dragon fight! Reach the dragons nest to win! "; #region Player Creation List <Player> players = new List <Player>() { player }; xp = (int)((player as HumanPlayer).levelXP * (World.World.random.NextDouble() + 2)); //Set player position players[0].troop.Position = map.DeterminSpawnPoint(1, SpawnType.road)[0]; //Find highest peak Point peak = map.DeterminSpawnPoint(1, SpawnType.heighestField)[0]; //Create the nest Building egg = new Building("Nest", peak, Resources.DragonEggNest, map, true); map.entities.Add(egg); map.renderObjects.Add(new EntityRenderObject(egg, new TeleportPointAnimation(new Point(0, 0), egg.Position))); //Spawn dragon close to the highest peak Point dragonSpawn = new Point(peak.X + World.World.random.Next(3), peak.Y + World.World.random.Next(3)); while (dragonSpawn.X >= map.map.GetUpperBound(0) && dragonSpawn.Y >= map.map.GetUpperBound(1)) { dragonSpawn.X = dragonSpawn.X >= map.map.GetUpperBound(0) ? dragonSpawn.X - 1 : dragonSpawn.X; dragonSpawn.Y = dragonSpawn.Y >= map.map.GetUpperBound(1) ? dragonSpawn.Y - 1 : dragonSpawn.Y; } Dictionary <DamageType, double> vurn = new Dictionary <DamageType, double> { { DamageType.fire, 0 } }; DragonMotherAI dragonMother = new DragonMotherAI(PlayerType.computer, "Dragon", map, new Player[] { player }, peak, Round, difficulty); dragonMother.troop = new Troop("Dragon", new Weapon(8 + difficulty / 4 + Round - 1, BaseAttackType.melee, BaseDamageType.sharp, 3, "Claw", 1, false), Resources.Dragon, 0, map, dragonMother, Vurneabilities: vurn); players.Add(dragonMother); players[1].troop.Position = dragonSpawn; players[1].troop.weapons.Add(new Weapon(6 + difficulty / 3 + Round, BaseAttackType.melee, BaseDamageType.blunt, 6, "Tail", 1, false, 1)); #endregion Player Creation #region WinCodition Creation List <WinCheck> wins = new List <WinCheck> { deathCheck, (_map, _main) => { return(AIUtility.Distance(_main.humanPlayer.troop.Position, peak) == 1); } }; WinCheck fail = ((_map, main) => false); wins.Add(fail); #endregion WinCodition Creation #region DeathCondition Creation List <WinCheck> deaths = new List <WinCheck> { playerDeath }; desc += "Do not die. "; #endregion DeathCondition Creation desc += "Good luck! "; return(players, wins, deaths, desc); }
/// <summary> /// Generates roads between cities where it makes sense /// </summary> public void GenerateRoads() { //TODO: Check if roads connect to other cities int roads = 0; foreach (var island in islands.Where(i => i.Settled)) { Trace.TraceInformation($"Generating roads for island {island.island.Name} \t Cities: {island.cities.Count}"); List <RoadNetwork> roadNetworks = new List <RoadNetwork>(); List <City> order = island.cities.OrderByDescending(c => c.priority).ToList(); void AddRoad(Road road, City city1, City city2) { RoadNetwork roadNetwork = roadNetworks.Find(n => n.roads.Contains(road.position)); if (roadNetwork is null) { RoadNetwork item = new RoadNetwork(); item.roads.Add(road.position); item.cities.Add(city1); item.cities.Add(city2); roadNetworks.Add(item); roadNetwork = item; } else { if (!roadNetwork.cities.Contains(city1)) { roadNetwork.cities.Add(city1); } if (!roadNetwork.cities.Contains(city2)) { roadNetwork.cities.Add(city2); } if (!roadNetwork.roads.Contains(road.position)) { roadNetwork.roads.Add(road.position); } } RoadNetwork oRoadNetwork = roadNetworks.Find(n => n.roads.Contains(road.position.Add(-1, 0))); if (oRoadNetwork != null) { roadNetwork.MergeNetwork(oRoadNetwork); roadNetworks.Remove(oRoadNetwork); } oRoadNetwork = roadNetworks.Find(n => n.roads.Contains(road.position.Add(1, 0))); if (oRoadNetwork != null) { roadNetwork.MergeNetwork(oRoadNetwork); roadNetworks.Remove(oRoadNetwork); } oRoadNetwork = roadNetworks.Find(n => n.roads.Contains(road.position.Add(0, -1))); if (oRoadNetwork != null) { roadNetwork.MergeNetwork(oRoadNetwork); roadNetworks.Remove(oRoadNetwork); } oRoadNetwork = roadNetworks.Find(n => n.roads.Contains(road.position.Add(0, 1))); if (oRoadNetwork != null) { roadNetwork.MergeNetwork(oRoadNetwork); roadNetworks.Remove(oRoadNetwork); } } foreach (var city in island.cities.OrderBy(c => AIUtility.Distance(order[0].position, c.position))) { List <City> allowedCities = order.Where(c => c != city && AIUtility.Distance(c.position, city.position) < Math.Max(c.Wealth, 15)).ToList(); for (int i = 0; i < Math.Min(city.connections, allowedCities.Count()); i++) { City toCity = allowedCities[i]; if (city.roadConnections.Contains(toCity) || toCity.roadConnections.Contains(city)) { continue; } Trace.TraceInformation($"Generated road between {city.position} and {toCity.position}"); roads++; toCity.costMap = AStar.GenerateCostMap(World.Instance.costMap, ref toCity.position, AIUtility.Distance(toCity.position, city.position) * 10); Point[] route = AStar.FindPath(toCity.position, city.position, toCity.costMap); foreach (var point in route) { if (!World.Instance.features.Exists(f => f is Road && f.position == point)) { Road road = new Road(point); World.Instance.features.Add(road); AddRoad(road, city, toCity); } } } } //Finalise all connections foreach (var network in roadNetworks) { foreach (var _city in network.cities) { _city.roadConnections = new List <City>(network.cities); _city.roadConnections.Remove(_city); } } } Trace.TraceInformation($"Generated {roads} roads!"); }
public override void WorldAction() { if (dead) { return; } day++; description = $"The agricultural value of the town is {city.agriculturalProduction} and the mineral value is {city.mineralProduction}. The city requires {FoodRequirement()} food per week and is getting food from {farms.Count}. It has {money} coins."; if (day % 7 == 0) { //Update this in case farms get added or removed Island island = World.Instance.worldMap.Get(city.position).island; farms = World.Instance.nation.farms.Where(f => World.Instance.worldMap.Get(f.position).island == island).OrderBy(f => AIUtility.Distance(city.position, f.position)).ToList(); int foodRequirement = FoodRequirement(); int initialFoodRequirement = foodRequirement; FoodMarket market = city.buildings.Find(f => f is FoodMarket) as FoodMarket; while (foodRequirement != 0) { if (market.Items.Count == 0 || !market.Items.Exists(i => market.GetBuyPrice(i.item) <= money)) { //People are going hungry Trace.TraceInformation($"In {city.name} {foodRequirement} died from hunger - Wealth {money} - Market Items: {market.Items.Sum(i => i.Amount)}" + $" Market Money: {market.money}"); checked { city.Population -= foodRequirement; } break; } List <InventoryItem> foodList = market.Items.OrderBy(r => r.Cost).ToList(); foreach (var food in foodList) { int amount = Math.Min(food.Amount, foodRequirement); int individualPrice = market.GetBuyPrice(food.item); amount = Math.Min(money / individualPrice, amount); int price = individualPrice * amount; if (money >= price) { foodRequirement -= amount; money -= price; market.money += price; food.Amount -= amount; if (food.Amount == 0) { market.Items.Remove(food); } } if (foodRequirement == 0) { break; } } } } if (day % 365 == 0) { money += city.Population * 2; Trace.TraceInformation($"City: {city.name} Wealth: {money}"); if (city.Population < city.lastPopulation || (city.buildings.Find(f => f is FoodMarket) as FoodMarket).Items.Count == 0) { //Find close tile and build new farm WorldTile tile = null; double maxAgri = 0; for (int x = 0; x < 11; x++) { for (int y = 0; y < 11; y++) { WorldTile worldTile = World.Instance.worldMap[(city.position.X - 5 + x).Cut(0, World.WORLD_SIZE - 1), (city.position.Y - 5 + y).Cut(0, World.WORLD_SIZE - 1)]; double agriculture = World.Instance.agriculturalMap[(city.position.X - 5 + x).Cut(0, World.WORLD_SIZE - 1), (city.position.Y - 5 + y).Cut(0, World.WORLD_SIZE - 1)]; if (maxAgri < agriculture) { tile = worldTile; maxAgri = agriculture; } } } if (tile != null && maxAgri > 0) { Trace.TraceInformation($"{city.name} created a new farm at {tile.position}"); World.Instance.nation.toChange.Add(new Farm(tile.position, (int)(maxAgri * 100))); } } } if (city.Population < 100) { Trace.TraceInformation($"The city {city.name} is dead!"); dead = true; //The city is dead World.Instance.nation.toChange.Add(city); } //Trace.TraceInformation($"{city.name} on {World.Instance.worldMap.Get(city.position).island.Name}: {initialFoodRequirement} - Hunger deaths: {foodRequirement}"); }