/// <summary> /// Building a perimeter wall around a large floor or dungeon map is time consuming, especially /// when wall pieces have to constantly be rotated into place due to World Wizard's /// slightly elaborate tile system. /// Build Perimeter Walls assists the player by searching for the perimeter of all contiguous /// tiles. Once the perimeter has been found, the walls are erected and added to the /// current Scene Graph. /// </summary> /// <param name="resourceTag">the resource to place around the perimeter</param> /// <param name="wwObject">the floor tile to start the search from</param> public static void BuildPerimeterWalls(string resourceTag, WWObject wwObject) { IntVector3 curIndex = wwObject.GetCoordinate().Index; Dictionary <IntVector3, WWWalls> coordToWalls = SelectPerimeter(curIndex); foreach (KeyValuePair <IntVector3, WWWalls> coordToWall in coordToWalls) { // Note: WWWalls is a bitmask, an there may be multiple perimeter walls // for a given coordinate index. Hence why these are if statements and not if elses. // if the perimeter wall is on the north side... if (Convert.ToBoolean(WWWalls.North & coordToWall.Value)) { TryToPlaceWall(coordToWall.Key, WWWalls.North, resourceTag); } // if the perimeter wall is on the east side... if (Convert.ToBoolean(WWWalls.East & coordToWall.Value)) { TryToPlaceWall(coordToWall.Key, WWWalls.East, resourceTag); } // if the perimeter wall is on the south side... if (Convert.ToBoolean(WWWalls.South & coordToWall.Value)) { TryToPlaceWall(coordToWall.Key, WWWalls.South, resourceTag); } // if the perimeter wall is on the west side... if (Convert.ToBoolean(WWWalls.West & coordToWall.Value)) { TryToPlaceWall(coordToWall.Key, WWWalls.West, resourceTag); } } }
/// <summary> /// Consumes a WWObject and determines whether this object can fit at its current coordinate, /// taking into consideration rotation, or if it collides with other WWObjects being maintained /// by this data structure. This is private method and it safe to assume that the WWObject being tested /// for collision has not yet been added to this data structure. Note: it would be easy to do a Guid /// comparison before checking collision if the use case ever arises in the future. /// </summary> /// <param name="wwObject">The object to test for collision.</param> /// <returns>True if the WWObject can fit without colliding given its current coordinate.</returns> private bool Collides(WWObject wwObject) { if (coordinates.ContainsKey(wwObject.GetCoordinate().Index)) // any objects at coordinate? { List <WWObject> objectsAtCoord = GetObjects(wwObject.GetCoordinate()); WWWalls totalWalls = 0; // this is a bit mask which will keep the running total of wall collisions foreach (WWObject obj in objectsAtCoord) // only need to do collision checking at the coordinate index { if (obj.ResourceMetadata.wwObjectMetadata.type.Equals(WWType.Tile)) // ignore non Tile types { // get the walls of the WWObject after applying its rotation transformation WWWalls walls = WWWallsHelper.GetRotatedWWWalls(obj.ResourceMetadata, obj.GetRotation()); totalWalls = totalWalls | walls; // OR the walls with the running sum stored in totalWalls } } // now get the walls for the object that is being collision checked for WWWalls newWalls = WWWallsHelper.GetRotatedWWWalls(wwObject.ResourceMetadata, wwObject.GetRotation()); bool doesCollide = Convert.ToBoolean(newWalls & totalWalls); // 0 or False if no collision return(doesCollide); } return(false); // if there are no objects at the index, obviously there are no collisions }
/// <summary> /// Attempt to Add a WWObject to the data structure. /// </summary> /// <param name="wwObject">The object to Add.</param> /// <returns>True if the object can be Added to the data structure.</returns> public bool Add(WWObject wwObject) { Coordinate coord = wwObject.GetCoordinate(); Guid guid = wwObject.GetId(); if (Collides(wwObject) && wwObject.ResourceMetadata.wwObjectMetadata.type.Equals(WWType.Tile)) { Debug.Log("Tile collides with existing tiles. Preventing placement of new tile."); return(false); } if (coordinates.ContainsKey(coord.Index)) { coordinates[coord.Index].Add(guid); // append the existing list of Guids for this index } else // create new entry in the map { var guidList = new List <Guid>(); guidList.Add(guid); coordinates.Add(coord.Index, guidList); } objects.Add(wwObject.GetId(), wwObject); return(true); // sucessfully added the object to the data structure }