public void Destroyed() { if (m_currentBuildingThing != null) { //Removes supplyValue from object being built as it was artificially added ! Same with UnitPower m_player.RemoveSupply(GetSupplyValue()); m_player.RemoveUnitPower(m_currentBuildingThing.m_type); //Sets currentlybuilding to null m_currentBuildingThing = null; } //remove the building from builders list m_player.RemoveThingBuilder(m_builder); if (m_sacrifices.Count > 0) { //Since This buildbehavior removed the workers without removing supply & unitPower yet removed em from the list, //Just Adding them back would cause double supplies & unitpower Growth which is bad! m_player.RemoveSupply(m_sacrifices.Count * m_sacrifices[0].m_supplyValue); m_player.RemoveUnitPower(m_sacrifices[0].m_type, m_sacrifices.Count); //Doesn't remove the blocked tiles on map, cause that's the m_builders.RemoveMe() functions job MathGameHelper.RestoreXPercentUnits(m_sacrifices, m_player, 0.25f); } //If the building dies before the new possible sacrifices becomes fullfledged ones! foreach (Thing asp in m_aspiringSacrifices) { //Make it stop moving! asp.ChangeDestination(asp.m_currentposition); } }
public override void RemoveMe(Player a_player, Map a_map) { Rectangle f_rect = MathGameHelper.GetAreaRectangle(ref m_currentposition, ref m_size); a_map.RemoveBuildingOnMap(ref f_rect); a_player.CurrentMaxSupply -= SupplyIncrement; }
/// <summary> /// User canceled the build, meaning user will be refunded some of the resources used to build the structure / something else. /// </summary> public void CancelBuild(Player a_player, Map a_map) { MathGameHelper.RestoreXPercentUnits(m_builders, a_player, 0.25f); Rectangle f_buildArea = MathGameHelper.GetAreaRectangle(ref m_object.m_currentposition, ref m_object.m_size); //Also removes the blocked tiles from the building a_map.RemoveBuildingOnMap(ref f_buildArea); m_cancelled = true; }
public override void RemoveMe(Player a_player, Map a_map) { if (m_thingState != ThingState.BeingBuilt) { m_buildBehavior.Destroyed(); } Rectangle f_rect = MathGameHelper.GetAreaRectangle(ref m_currentposition, ref m_size); a_map.RemoveBuildingOnMap(ref f_rect); }
/// <summary> /// If it returns true it tells Player to remove me, by making m_deleteMe = true /// </summary> public bool DoBuildStuff(Player a_player, Map a_map, PathFinder a_pathfinder, float a_elapsedTime) { //If not cancelled proceed to build stuff if (!m_cancelled) { //If object is not finished building if (m_object.m_thingState == ThingState.BeingBuilt && !m_deleteMe) { //If this object isn't being built it needs to check if builders are close enough e.t.c.! if (!m_isBuilding) { //If there are no builders there's no need to check they are all within range if (m_builders != null) { //Checks builder states, like 1 died or stopped moving e.t.c. thus canceling the build CheckBuilderStates(); //Has to have the same amount of builders as the price if (m_builders.Count == m_object.m_price && !m_cancelled) { //Sets that everyone is in range to start with bool m_everyoneInRange = true; //Loops through all builders to check if they are out of range, if they are m_everyoneINrange is set to false foreach (Thing builder in m_builders) { if ((builder.m_currentposition - m_object.m_currentposition).LengthSquared() > builder.m_buildBehavior.GetBuildRangeSquared()) { m_everyoneInRange = false; } } //If everyone happened to be in range, the building shall be built! if (m_everyoneInRange) { Rectangle f_buildArea = MathGameHelper.GetAreaRectangle(m_object.m_currentposition, m_object.m_size); //Checks if can build there, could be that someone else managed to build before ^_^ if (CanBuildThere(a_map, ref f_buildArea)) { if (!m_object.m_isUnit) { a_map.AddBuildingOnMap(ref f_buildArea); } //Sets existance to false so player will remove the builders from the game but the reference will live on in the BuildingObject //until it's finished building incase of cancelled building or similar foreach (Thing builder in m_builders) { builder.m_exists = false; } m_isBuilding = true; }//if you can't build there , like another builder was faster it will cancel the building object else { m_cancelled = true; } } } }//If there is no builder the object will start building! as there's no need to check for logics there! else { Rectangle f_buildArea = MathGameHelper.GetAreaRectangle(m_object.m_currentposition, m_object.m_size); if (CanBuildThere(a_map, ref f_buildArea)) { if (!m_object.m_isUnit) { a_map.AddBuildingOnMap(ref f_buildArea); } m_isBuilding = true; } else { m_cancelled = true; } } return(false); }//If m_isBuilding = true else { if (m_object.m_exists && m_object.m_alive) { //Builds the object and when it's finished the m_object.State will change from beingbuilt to something else if (m_object.BuildMe(a_elapsedTime)) { //One might think you should tell m_builders to clear itself, but the reference to the builders will disappear once this buildingObject disappears //So no need to do so! //Set the interfaces and then return true so player will remove this buildingobject m_object.SpawnMe(a_player, a_map, a_pathfinder); //Removes the supply object was taking up because AddReadyThing will add the supply back //NOTE: No need to worry about unitPower here cause it never added unitpower in a faked way here a_player.RemoveSupply(m_object.m_supplyValue); a_player.AddReadyThing(m_object, null); if (m_builders != null) { m_builders.Clear(); } return(true); } }//The building was killed else { DestroyBuild(a_map, a_player); //returns true to tell buildingObject list to delete me! return(true); } } return(false); }//If m_delete == true or the state isn't beingBuilt anymore somehow else { return(true); } }//If m_cancelled = true else { if (m_builders != null) { ///<Summary> /// This part makes it so that builders that's inside a blocked area gets moved to a none-blocked area so they can be used again. /// As example 2 different builder groups build at same area and the builders that can't build there gets trapped inside the blocked tiles. /// So This part makes them if possible move through pathfinder to the position, if that's not possible forcefully move them ignoring tiles completly /// Towards the 'spawn position' of the object (bottom left corner) ///</Summary> //The area of m_object Rectangle f_area = MathGameHelper.GetAreaRectangle(ref m_object.m_currentposition, ref m_object.m_size); //Loops through each builder foreach (Thing builder in m_builders) { //Creates a new point Point f_point = new Point((int)builder.m_currentposition.X, (int)builder.m_currentposition.Y); //Checks if the builder is inside the blocked tile area if (f_area.Contains(f_point)) { //If it is, get the destination point (lower left corner) Vector3 f_destinationPoint = new Vector3(m_object.m_currentposition.X - m_object.m_size.X * 0.5f , m_object.m_currentposition.Y - m_object.m_size.Y * 0.5f , m_object.m_currentposition.Z); //Try to find path there! if (a_pathfinder.FindPath(builder.m_currentposition, f_destinationPoint) == 1) { builder.ChangeDestination(a_pathfinder.m_pathList); } else { builder.m_currentposition = f_destinationPoint; builder.ChangeDestination(builder.m_currentposition); /* Possible BAKA code! * Vector3 f_tempPos = builder.m_currentposition; * builder.m_currentposition = f_destinationPoint; * * if (a_pathfinder.FindPath(builder.m_currentposition, f_destinationPoint) == 1) * { * builder.ChangeDestination(a_pathfinder.m_pathList); * } * else * { * builder.m_currentposition = f_tempPos; * builder.ChangeDestination(builder.m_currentposition); * }*/ } }//If the builder isn't inside the m_object area, just stop moving! else { builder.ChangeDestination(builder.m_currentposition); } } } //As the object is canceled, it should cease to exist m_object.m_exists = false; return(true); } }
public void DrawTryingToBuild(GraphicsDevice a_graphics, Vector3 a_wpos, Map a_map, Vector3 a_size, bool a_needWO) { //This needs some kind of peak function or similar , but a.t.m. if the size is 0 it will think the size is 3 //and draw white boxes for everything, reddish if blocked or dark gray if on other height if (a_size.X > 0 && a_size.Y > 0) { #region SettingVariables bool f_ok = true; Rectangle f_buildArea = MathGameHelper.GetAreaRectangle(ref a_wpos, ref a_size); ModelClasses.WorldObjects.WorldObject f_worldObject = a_map.GetWorldObject(ref f_buildArea); Rectangle f_worldObjectArea = new Rectangle(); if (f_worldObject != null) { f_worldObjectArea = MathGameHelper.GetAreaRectangle(ref f_worldObject.m_position, ref f_worldObject.m_size); } if (a_needWO && f_worldObject == null) { f_ok = false; } else if (a_needWO && f_worldObject != null) { a_wpos = f_worldObject.m_position; } else if (!a_needWO && f_worldObject != null) { f_ok = false; } //Has to be used cause the ray trace gets stuck on bounding box at like 0.000000004 cause of float precision error? float f_height = a_map.m_tiles[(int)a_wpos.X, (int)a_wpos.Y].m_height; int f_wposLeft = (int)(a_wpos.X) - (int)(a_size.X * 0.5f); int f_wposRight = f_wposLeft + (int)(a_size.X); int f_wposBottom = (int)(a_wpos.Y) - (int)(a_size.Y * 0.5f); int f_wposTop = f_wposBottom + (int)a_size.Y; //Mouse is in middle, so - 1/2 building size then -1 for additional grid info int f_leftSide = f_wposLeft - 1; //Same but to right side int f_rightSide = f_wposRight + 1; //Same but for the bottom int f_bottom = f_wposBottom - 1; //For the top! int f_top = f_wposTop + 1; //checks the corners if they have a tile or not, if they don't you can't build if (!a_map.IsTile(f_wposLeft, f_wposBottom) || !a_map.IsTile(f_wposLeft, f_wposTop - 1) || !a_map.IsTile(f_wposRight - 1, f_wposBottom) || !a_map.IsTile(f_wposRight - 1, f_wposTop - 1)) { f_ok = false; } if (f_ok) { BoundingBoxBuffer.m_color = Color.White; } else { BoundingBoxBuffer.m_color = Color.LightPink; } #endregion #region OuterRegion //Draws bottom strip first if (a_map.IsYPosInside(f_bottom)) { for (int x = f_leftSide; x < f_rightSide; x++) { if (a_map.IsXPosInside(x)) { DrawBoundingBoxBiggerLines(a_map.m_tiles[x, f_bottom].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } } //Draws Top strip if (a_map.IsYPosInside(f_top - 1)) { for (int x = f_leftSide; x < f_rightSide; x++) { if (a_map.IsXPosInside(x)) { DrawBoundingBoxBiggerLines(a_map.m_tiles[x, f_top - 1].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } } if (a_map.IsXPosInside(f_leftSide)) { for (int y = f_bottom + 1; y < f_top - 1; y++) { if (a_map.IsYPosInside(y)) { DrawBoundingBoxBiggerLines(a_map.m_tiles[f_leftSide, y].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } } if (a_map.IsXPosInside(f_rightSide - 1)) { for (int y = f_bottom + 1; y < f_top - 1; y++) { if (a_map.IsYPosInside(y)) { DrawBoundingBoxBiggerLines(a_map.m_tiles[f_rightSide - 1, y].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } } #endregion #region InnerRegion //Lops from bottom to the top for (int y = f_wposBottom; y < f_wposTop; y++) { if (a_map.IsYPosInside(y)) { //x = a_wpos.X - 1 (a_wpos is rounded) and loops until x >= a_wpos + a_buildingsize.X + 1 for (int x = f_wposLeft; x < f_wposRight; x++) { if (a_map.IsXPosInside(x)) { BoundingBoxBuffer.m_color = Color.Red; //If x is larger than left side and smaller than rightside - 1 and larger than bottom and smaller than top -1 //You are at the positions of the building where its positions are //So if the height is not the same as where your mouse is Z wise (not same height) the grid will draw the color red if (f_height == a_map.m_tiles[x, y].m_height && a_map.m_tiles[x, y].m_type != Tiletype.Blocked && f_ok) { BoundingBoxBuffer.m_color = Color.GreenYellow; } else if (a_map.m_tiles[x, y].m_type == Tiletype.Blocked) { BoundingBoxBuffer.m_color = Darkred; } DrawBoundingBoxBiggerLines(a_map.m_tiles[x, y].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } //End of x for loop } } //end of y for loop #endregion } else { #region Can't_Get_Size_From_BuildBehavior a_size = new Vector3(3); //Has to be used cause the ray trace gets stuck on bounding box at like 0.000000004 cause of float precision error? float f_height = a_map.m_tiles[(int)a_wpos.X, (int)a_wpos.Y].m_height; int f_wposLeft = (int)(a_wpos.X) - (int)(a_size.X * 0.5f); int f_wposRight = f_wposLeft + (int)(a_size.X); int f_wposBottom = (int)(a_wpos.Y) - (int)(a_size.Y * 0.5f); int f_wposTop = f_wposBottom + (int)a_size.Y; //Mouse is in middle, so - 1/2 building size then -1 for additional grid info int f_leftSide = f_wposLeft - 1; //Same but to right side int f_rightSide = f_wposRight + 1; //Same but for the bottom int f_bottom = f_wposBottom - 1; //For the top! int f_top = f_wposTop + 1; for (int x = f_leftSide; x < f_rightSide; x++) { if (a_map.IsXPosInside(x)) { for (int y = f_bottom; y < f_top; y++) { if (a_map.IsYPosInside(y)) { BoundingBoxBuffer.m_color = Color.White; if (a_map.m_tiles[x, y].m_type == Tiletype.Blocked) { BoundingBoxBuffer.m_color = Darkred; } else if (f_height != a_map.m_tiles[x, y].m_height) { BoundingBoxBuffer.m_color = Color.DarkGray; } DrawBoundingBoxBiggerLines(a_map.m_tiles[x, y].m_boundBox, a_graphics, Matrix.Identity, m_camera); } } } } #endregion } }
/// <summary> /// Attempt to start building, goes through a lot of trying to build logic here /// </summary> public void StartBuild() { //If currently is not building anything and the queue is larger than 0 if (m_currentBuildingThing == null && m_buildingQueue.Count > 0) { Thing f_temp = null; //Switch check the buildable types switch (m_buildingQueue.Dequeue()) { case ThingType.C_Extractor: //Create extractor at position where you clicked f_temp = m_player.m_thingsAssets.CreateExtractor(m_position); //Extractor needs a SoL so it's looking for a WO and puts the type too m_lookingForWO = true; m_lookingForWOType = WorldObjectType.SoL; break; case ThingType.C_Igloo: f_temp = m_player.m_thingsAssets.CreateIgloo(m_position); m_lookingForWO = false; break; case ThingType.C_Barrack: f_temp = m_player.m_thingsAssets.CreateBarrack(m_position); m_lookingForWO = false; break; } //If f_temp got valued if (f_temp != null) { #region SetPositionCorrect if (!f_temp.m_isUnit) { if (f_temp.m_size.X % 2 == 0) { m_position.X = (int)m_position.X; } else { m_position.X = (int)m_position.X + Map.m_tileSizeDivided; } if (f_temp.m_size.Y % 2 == 0) { m_position.Y = (int)m_position.Y; } else { m_position.Y = (int)m_position.Y + Map.m_tileSizeDivided; } m_position.Z = m_map.m_tiles[(int)m_position.X, (int)m_position.Y].m_height; } #endregion #region GetMapData //Checks for stuff on the map, Like a barrack if it gets a SoL? Cancel! Rectangle f_buildArea = MathGameHelper.GetAreaRectangle(m_position, f_temp.m_size); // IF looking for a WO if (m_lookingForWO) { //Get a worldobject at the position trying to build at m_currentWorldObject = m_map.GetWorldObject(ref f_buildArea, m_lookingForWOType); if (m_currentWorldObject == null) { return; } //If it's SoL check if it's taken or not if (m_currentWorldObject.m_type == WorldObjectType.SoL) { if ((m_currentWorldObject as SoL).m_taken) { m_currentWorldObject = null; return; } } //if found a WO if (m_currentWorldObject == null) { return; } }//If not looking for WO else { //Is outside, because if m_lookingForWO is false and m_currentWorldObject != null it fails, can't build on a WO m_currentWorldObject = m_map.GetWorldObject(ref f_buildArea); if (m_currentWorldObject != null) { return; } } #endregion #region ValidationAndCreation //Here it validates if it can Add the building / unit, if it can build on the map (no blocked tiles... or units!) and that player has enough workers //If possible to add the thingy , and the area is buildable and player has enough selected workers if (m_player.CanAddUnit(f_temp) && m_map.AreaBuildable(ref f_buildArea, m_position.Z) && m_player.m_selectedWorkers >= f_temp.m_price) { m_currentBuildingThing = f_temp; if (m_currentBuildingThing.m_requiredBuildTime > 0) { float f_hp = 0.1f * (m_currentBuildingThing.m_maxHP - 1); m_currentBuildingThing.HP = 1; m_currentBuildingThing.HPBuffer = f_hp; } //Sets the thingys position to position based by size & tileSize m_currentBuildingThing.m_currentposition = m_position; //find path to building spot m_pathfinder.FindPath(m_builder.m_currentposition, m_position); //Will try to create the new unit, which will either add the builder to an already existing BuildingObject or create a new one if the //m_currentBuildingThing aren't the same if (m_player.TryToCreateNewUnit(m_currentBuildingThing, m_builder, m_map, m_currentWorldObject, m_pathfinder.m_pathLength)) { //clear previous paths m_builder.m_destination.Clear(); //set path to building spot m_builder.m_destination = m_pathfinder.m_pathList; m_builder.m_thingState = ThingState.Building; } m_currentBuildingThing = null; m_currentWorldObject = null; } //end of if canAddUnit && map.AreaBuildable && m_player.m_selectedworkers >= price #endregion } //End of If f_temp != null } }