/// <summary> /// Creates a fromBuilding with specified parameters, the unit list will /// be initiated but empty and the current health will be set at maxHealth. /// Regarding the controlZone the first tile should be the /// tile the fromBuilding is standing on. /// </summary> /// <param name="name">The name for the fromBuilding TODO Decide if this is /// needded</param> /// <param name="posX">The x tile coordinate</param> /// <param name="posY">The y tile coordinate</param> /// <param name="maxHealth">The max health of this fromBuilding</param> /// <param name="owner">The player that owns the fromBuilding</param> /// <param name="type">The </param> /// <param name="baseBuilding">The Base Building this fromBuilding belongs /// <param name="controlZone">The nine tiles around the fromBuilding /// and the tile the fromBuilding is on.</param> /// to</param> public Building(String name, int posX, int posY, int maxHealth, Player owner, Globals.BuildingTypes type, BaseBuilding baseBuilding, LinkedList <Tile> controlZone) : base(new Vector2(((float)posX) + 0.5f, ((float)posY) + 0.5f), owner) { if (maxHealth <= 0) { throw new ArgumentOutOfRangeException("maxHealth", "The max of health may not be zero or less"); } logger.Trace("Constructing new Building with choosen values"); this.name = name; this.maxHealth = maxHealth; this.currentHealth = maxHealth; this.units = new List <Unit>(); this.incomingUnits = new List <Unit>(); this.type = type; this.IsAggressive = true; this.baseBuilding = baseBuilding; if (baseBuilding != null) { Accept(baseBuilding); } this.controlZone = controlZone; foreach (Tile t in controlZone) { t.unitsChanged += UpdateAggressiveness; } }
/// <summary> /// Called when a new fromBuilding should be created. Creates a fromBuilding of a given type at the /// given point from the given sourceBuilding. Returns false if it failed. /// </summary> /// <param name="point"></param> /// <param name="baseBuilding"></param> /// <param name="buildingType"></param> /// <returns></returns> private bool IssueBuildOrder(Vector2 point, Building sourceBuilding, Globals.BuildingTypes buildingType) { bool created = BuildingController.AddBuilding(buildingType, sourceBuilding, point, m_view.world, this); if (created) { m_view.BuildingAddedAt(point); } return(created); }
/// <summary> /// This method calculates how many buildings of the specified type the player have. /// </summary> /// <param name="type">The type of building to count</param> public uint CountBuildingsOfType(Globals.BuildingTypes type) { uint retur = 0; foreach (Graph g in graphs) { foreach (Building b in g.GetBuildings()) { if (b.type == type) { retur += 1; } } } return(retur); }
/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="payer">The player this building is built for</param> /// <returns>The cost when considering the price inflation</returns> public uint CalculateBuildingCostInflation(Globals.BuildingTypes type) { uint defaultCost = Building.GetBuyPrice(type); uint buildingCount = owner.CountBuildingsOfType(type); //return (uint)(defaultCost + (buildingCount * buildingCount * defaultCost / 2)); if (buildingCount == 0) { return(defaultCost); } double exp = 1f / Math.Pow((buildingCount), 1f / ((float)MAX_OF_EACH_BUILDING_TYPE[(int)type] - 1f)); double bas = 1f / ((float)MAX_OF_EACH_BUILDING_TYPE[(int)type] - 1f); double test = Math.Pow(bas, exp); return((uint)(POP_CAP_PER_PLAYER * test)); }
/// <returns>Returns the buy price for a fromBuilding, it is set /// at its health divided by 10. Upkeep should be added elsewhere.</returns> public static uint GetBuyPrice(Globals.BuildingTypes type) { switch (type) { case Globals.BuildingTypes.Base: return(BASE_BUILDING_COST); case Globals.BuildingTypes.Aggressive: return(AGGRESSIVE_BUILDING_COST); case Globals.BuildingTypes.Barrier: return(BARRIER_BUILDING_COST); case Globals.BuildingTypes.Resource: return(RESOURCE_BUILDING_COST); } return(0); }
/// <summary> /// Add a fromBuilding to the source buildings owners graph, /// the source fromBuilding will be used to find the correct graph. /// </summary> /// <param name="buildingType">The type of fromBuilding to build.</param> /// <param name="sourceBuilding">The fromBuilding used to build this fromBuilding.</param> /// <param name="targetCoordinate">The tile coordinates where the fromBuilding will be built.</param> /// <param name="world">The world to build the fromBuilding in.</param> public static bool AddBuilding(Globals.BuildingTypes buildingType, Building sourceBuilding, Vector2 targetCoordinate, World world, Player owner) { if (sourceBuilding != null && buildingType != Globals.BuildingTypes.Base && (Math.Abs(((int)sourceBuilding.position.X) - (int)targetCoordinate.X) > MAX_BUILDING_RANGE || (Math.Abs(((int)sourceBuilding.position.Y) - (int)targetCoordinate.Y) > MAX_BUILDING_RANGE))) { logger.Debug("Building position out of range"); throw new BuildingOutOfRangeException(); } uint price = owner.unitAcc.CalculateBuildingCostInflation(buildingType); if (sourceBuilding != null && (uint)sourceBuilding.CountUnits() < price) { logger.Debug("Building too expensive"); return(false); } logger.Info("Building a building at position " + targetCoordinate + " of " + buildingType + "."); lock (owner.GetGraphs()) { LinkedList <Tile> controlZone = CreateControlZone(targetCoordinate, world); //The Base building is handled in another way due to it's nature. if (buildingType == Globals.BuildingTypes.Base) { logger.Trace("Adding a Base Building and also constructing a new graph"); BaseBuilding baseBuilding = new BaseBuilding("Base Buidling", (int)targetCoordinate.X, (int)targetCoordinate.Y, owner, controlZone); world.map.GetTile((int)targetCoordinate.X, (int)targetCoordinate.Y).SetBuilding(baseBuilding); owner.AddGraph(GraphController.Instance.AddBaseBuilding(baseBuilding, sourceBuilding)); } else { //The other buildings constructs in similiar ways but they are constructed //as the specified type. Building newBuilding = null; switch (buildingType) { case Globals.BuildingTypes.Aggressive: logger.Trace("Building a new Aggressive building"); newBuilding = new AggressiveBuilding("Aggresive Building", (int)targetCoordinate.X, (int)targetCoordinate.Y, owner, GraphController.Instance.GetGraph(sourceBuilding).baseBuilding, controlZone); break; case Globals.BuildingTypes.Barrier: logger.Trace("Building a new Barrier building"); newBuilding = new BarrierBuilding("Barrier Building", (int)targetCoordinate.X, (int)targetCoordinate.Y, owner, GraphController.Instance.GetGraph(sourceBuilding).baseBuilding, controlZone); break; case Globals.BuildingTypes.Resource: logger.Trace("Building a new Resource building"); newBuilding = new ResourceBuilding("Resource Building", (int)targetCoordinate.X, (int)targetCoordinate.Y, owner, GraphController.Instance.GetGraph(sourceBuilding).baseBuilding, controlZone); break; } world.map.GetTile((int)targetCoordinate.X, (int)targetCoordinate.Y).SetBuilding(newBuilding); newBuilding.Parent = sourceBuilding; GraphController.Instance.AddBuilding(sourceBuilding, newBuilding); } if (sourceBuilding != null && world.map.GetTile((int)targetCoordinate.X, (int)targetCoordinate.Y).GetBuilding() != null) { logger.Info("The building has " + sourceBuilding.CountUnits() + " and the building costs " + price); owner.unitAcc.DestroyUnits(sourceBuilding.units, (int)price); logger.Info("The source building only got " + sourceBuilding.CountUnits() + " units left."); } else if (world.map.GetTile((int)targetCoordinate.X, (int)targetCoordinate.Y).GetBuilding() == null) { throw new Exception("A building was not placed on the tile even though it should have been."); } SoundsController.playSound("buildingPlacement"); } // Let's update the fog of war! /* * for (int i = -3; i <= 3; i++) * { * for (int j = -3; j <= 3; j++) * { * try * { * world.map.GetTile((int)targetCoordinate.X + j, (int)targetCoordinate.Y + i).MakeVisibleTo(owner); * } * catch(IndexOutOfRangeException e) * { * } * } * } */ return(true); }