public void GenerateMap() { //used for pathfinding prototype //if (TileList == null) { TileList = new TileListBase(width, height, depth); } TileList2DControl ReturnedTileArray = new TileList2DControl(TileList); System.Random rng = new System.Random((int)DateTime.Now.Ticks); double MapCenterX = width / 2; //same off by one error double MapCenterY = height / 2; double TileCount = width * height; double TileCountSqr = Math.Sqrt(TileCount); float radius = width / 2; if (width > height) { radius = height / 2; //radius ought not to extend off the map so the small of the two is used here } for (int i = 0; i < TileCount; i++) { int xindex = i % width; int yindex = i / width; if (Mathf.Sqrt(Mathf.Pow(((float)xindex - (float)MapCenterX), 2) + Mathf.Pow(((float)yindex - (float)MapCenterY), 2)) <= radius) { ReturnedTileArray.AssignFloorType(HexCoordinates.FromOffsetCoordinates(xindex, yindex, 0), FloorTile); } else { ReturnedTileArray.AssignFloorType(HexCoordinates.FromOffsetCoordinates(xindex, yindex, 0), null); } } //map will be ~ 78.5% grass tiles, and a circle }
private TileListBase HardCutOff(List <double> diffScore, TileListBase clearTileList, Tile tilePrefab, TileType terrain, TileType terrainB) { double Cutoff = .5; int XDim = clearTileList.XDim; int YDim = clearTileList.YDim; int ZDim = clearTileList.ZDim; int YLevel = (int)YDim / 2; for (int z = 0; z < ZDim; z++) { for (int x = 0; x < XDim; x++) { Tile newTile = new Tile(); if (diffScore[x + z * XDim] > Cutoff) { newTile.AssignSolidType(terrainB); newTile.AssignFloorType(terrainB); } else { newTile.AssignSolidType(terrain); newTile.AssignFloorType(terrain); } clearTileList.SetTile(new Vector3(x, YLevel, z), newTile); } } return(clearTileList); }
public void AssignList(TileListBase tileList) { BaseTiles = tileList; Wc = Math.Ceiling(BaseTiles.XDim * divbyCW); Hc = Math.Ceiling(BaseTiles.ZDim * divbyCH); Dc = Math.Ceiling(BaseTiles.YDim * divbyCD); GenerateChunks(); }
private TileListBase DoDithering(List <double> diffScore, TileListBase clearTileList, Tile tilePrefab, TileType terrain, TileType terrainB) { int XDim = clearTileList.XDim; int YDim = clearTileList.YDim; int ZDim = clearTileList.ZDim; double GreaterThan = .5; double oldpixel; double newpixel; double quant_error; int YLevel = (int)YDim / 2; for (int z = 0; z < ZDim; z++) { for (int x = 0; x < XDim; x++) { oldpixel = diffScore[x + z * XDim]; newpixel = (oldpixel > GreaterThan) ? 1 : 0; Tile newTile = new Tile(); if (newpixel == 1) { newTile.AssignSolidType(Instantiate(terrain)); newTile.AssignFloorType(Instantiate(terrain)); } if (newpixel == 0) { newTile.AssignSolidType(Instantiate(terrainB)); newTile.AssignFloorType(Instantiate(terrainB)); } clearTileList.SetTile(new Vector3(x, YLevel, z), newTile); quant_error = oldpixel - newpixel; if (x + z * XDim + 1 > diffScore.Count - 1) { continue; } diffScore[x + z * XDim + 1] = diffScore[x + z * XDim + 1] + quant_error * 7 / 16; if (x + (1 + z) * XDim - 1 > diffScore.Count - 1) { continue; } diffScore[x + (1 + z) * XDim - 1] = diffScore[x + (1 + z) * XDim - 1] + quant_error * 3 / 16; if (x + (1 + z) * XDim > diffScore.Count - 1) { continue; } diffScore[x + (1 + z) * XDim] = diffScore[x + (1 + z) * XDim] + quant_error * 5 / 16; if (x + (1 + z) * XDim + 1 > diffScore.Count - 1) { continue; } diffScore[x + (1 + z) * XDim + 1] = diffScore[x + (1 + z) * XDim + 1] + quant_error * 1 / 16; } } return(clearTileList); }
// Use this for initialization void Start() { BaseList = new TileListBase(50, 50, 10); TileList2DControl BaseList2D = new TileList2DControl(BaseList); //OldMapGen Generate = new OldMapGen(); Generate.GenerateRandomMap(BaseList.XDim, BaseList.ZDim, BaseList.YDim, BaseList2D); ChunkMaker.AssignList(BaseList); TheGameBoard = Instantiate <EntityMapping>(TheGameBoard); //TheGameBoard.GiveTileMap(BaseList); }
private TileListBase NaiveRandom(List <double> diffScore, TileListBase clearTileList, Tile tilePrefab, TileType terrain, TileType terrainB) { double Ceiling = 1; double Floor = .50; int XDim = clearTileList.XDim; int YDim = clearTileList.YDim; int ZDim = clearTileList.ZDim; double XStep = 1 / (double)XDim; double ZStep = 1 / (double)ZDim; double YStep = 1 / (double)YDim; int YLevel = (int)YDim / 2; for (int z = 0; z < ZDim; z++) { for (int x = 0; x < XDim; x++) { Tile newTile = new Tile(); double Check = diffScore[x + z * XDim]; if (Check < Floor) { newTile.AssignSolidType(null); newTile.AssignFloorType(Instantiate(terrain)); } else if (Check > Ceiling) { newTile.AssignSolidType(null); newTile.AssignFloorType(Instantiate(terrainB)); } else { Check = Check - Floor; Check = Check / Ceiling; if (Check > rng.NextDouble()) { newTile.AssignSolidType(null); newTile.AssignFloorType(Instantiate(terrainB)); } else { newTile.AssignSolidType(null); newTile.AssignFloorType(Instantiate(terrain)); } } double pNoise = Mathf.PerlinNoise(.13f + (float)(x * XStep), .13f + (float)(z * ZStep)); //Debug.Log(pNoise); clearTileList.SetTile(new Vector3(x, (int)(pNoise * YDim), z), newTile); } } return(clearTileList); }
public void AssignTiles(List <HexCoordinates> tiles, TileListBase baseTiles) { BaseTiles = baseTiles; ChunkTile = tiles; TileTriangleCount = new List <int>(); for (int i = 0; i < ChunkTile.Count; i++) { TileTriangleCount.Add(0); } MapChunkMesh.Clear(); ChunkVectors = new List <Vector3>(); ChunkTriangles = new List <int>(); ChunkColors = new List <Color>(); for (int i = 0; i < ChunkTile.Count; i++) { BaseTiles.GetTile(ChunkTile[i]).TileTypeChangedEvent += TileTypeChanged; } CreateChunk(); }
public TileListBase(TileListBase tilelist) //deep copy { _XDim = tilelist.XDim; _ZDim = tilelist.ZDim; _YDim = tilelist.YDim; _MapTiles = new List <Tile>(XDim * ZDim * YDim); if (_MapTiles.Capacity == 0) { throw new Exception("Don't make zero capacity tile lists please."); } for (int i = 0; i < _MapTiles.Capacity; i++) { _MapTiles.Add(null); if (tilelist.GetTile(i) != null) { //throw new Exception("Its working"); this.SetTile(i, new Tile(tilelist.GetTile(i).solidType, tilelist.GetTile(i).floorType)); } else { this.SetTile(i, new Tile()); } } }
internal static bool CanPath(IMapCollisionDetection map, EntityMapping entityMap, TileListBase tileMap, IEntityMovement actor, HexCoordinates source, HexCoordinates target) { return (MapPathfinder.GetPath(map, entityMap, tileMap, source, target, actor) != null); //Slow }
private static bool SanityCheck(IMapCollisionDetection map, EntityMapping entityMap, TileListBase tileMap, HexCoordinates start, HexCoordinates end, IEntityMovement movement) { if(!tileMap.ValidCoords(start) || !tileMap.ValidCoords(end)) { return false; } //one or both coords are not valid, dont path if(map.SpaceBlocked(entityMap, tileMap, end, movement)) { return false; } // end location is blocked, cannot path return true; }
public static List<HexCoordinates> GetPath(IMapCollisionDetection map, EntityMapping entityMap, TileListBase tileMap, HexCoordinates start, HexCoordinates end, IEntityMovement movement) { //tilearray is an array full of tiles, which have cubecoords. start/end are obvious. movementtype influences some of the pathing decisions. if (!SanityCheck(map, entityMap, tileMap, start, end, movement)) { return null; } List<HexCoordinates> ReturnValue = new List<HexCoordinates>(); List<HexNode> closedset = new List<HexNode>(); //nodes already examined List<HexNode> openset = new List<HexNode>(); //nodes that still can be examined /* having actual C# lists, instead of just having some kind of linkedlist setup may be a poor choice */ HexNode thing = new HexNode(start, end, null); //location, goal, parent node. starting node has no parent. /* H is a herustic that is part of determining which node to check first. in this case, distance is a distance formula for xyz since the vast majority of time, the closer two points in "real" space, the less nodes exist between them this is obviously not always the case (walls exist), but in the majority of cases, it holds true. score is H + G, lowest score gets picked from the opennode list G value is 1 + parent node's G. */ thing.H = HexCoordinates.Distance(start, end); openset.Add(thing); while (openset.Count > 0) { HexNode current = openset[0]; for (int i = 1; i < openset.Count; i++) { if (openset[i].Score < current.Score) { current = openset[i]; } } /* The above could, and maybe ought to, be replaced by keeping the openset list sorted after every addition, and just popping openset[0]. I think doing 1-to-n amount of compares for each openset addition is more costly than just having a constant n each runthrough but maybe it works out so that most openset additions wind up near the front so often that it might become noticably faster if openset gets particuarlly large but I'm not a computer science guy and its a waste of time to care about stuff like this sometimes */ if (current.Coords.X == end.X && current.Coords.Y == end.Y && current.Coords.Z == end.Z && current.Coords.Depth == end.Depth) //we have reached our goal { return RebuildPath(current); } openset.Remove(current); //"pop" current closedset.Add(current); // //get all tile coords that are adjacent to current List<HexCoordinates> neighbors = map.AdjacentMoveSpaces(entityMap, tileMap, current.Coords, movement); for (int i = 0; i < neighbors.Count; i++) { bool found = false; HexCoordinates NeighborCoords = neighbors[i]; for (int j = 0; j < closedset.Count; j++) { if (closedset[j].Coords.X == NeighborCoords.X && closedset[j].Coords.Y == NeighborCoords.Y && closedset[j].Coords.Z == NeighborCoords.Z && closedset[j].Coords.Depth == NeighborCoords.Depth) { found = true; break; } } if (found) { continue; } //node was found in closedset, so dont do anything for (int j = 0; j < openset.Count; j++) { if (openset[j].Coords.X == NeighborCoords.X && openset[j].Coords.Y == NeighborCoords.Y && openset[j].Coords.Z == NeighborCoords.Z && openset[j].Coords.Depth == NeighborCoords.Depth) { found = true; break; } } if (found) { continue; } //neighbor found in openset HexNode NewNode = new HexNode(NeighborCoords, end, current); //neighbor is a new node, add it to openset. openset.Add(NewNode); } } return null; // ran out of currentset before goal was reached. no path is possible. //returning null is kind of dangerous, but it communicates the idea in a self-evident manner, i feel. }
//TileListBase BaseList; public TileList3DControl(TileListBase baseList) { BaseList = baseList; }
public override List <HexCoordinates> GetTargetSpaces(HexCoordinates source, HexDirection dir, EntityMapping entityMap, TileListBase tileMap, IMapCollisionDetection collide) { EntityAbilityUser AAUser = AbilityUser as EntityAbilityUser; if (AAUser) { List <HexCoordinates> ret = MapPathfinder.GetAllPathableTiles(entityMap, tileMap, source, AAUser.GetComponent <IEntityMovement>(), collide); //probably not good return(ret); } else { return(new List <HexCoordinates>()); } }
public void CloneList(AbstractTileControl cloneFrom) { BaseList = new TileListBase(cloneFrom.BaseList); }
public override bool Validate(IEntityMovement movement, IMapCollisionDetection seer, HexCoordinates PathOrigin, EntityMapping entityMap, TileListBase tileMap) { return((int)MininimumPath >= (int)seer.PathStatus(entityMap, tileMap, PathOrigin, movement, Direction)); }
public TileList2DControl(TileList2DControl list2DControl) { BaseList = new TileListBase(list2DControl.BaseList); }
} // prefer not to do this but needed for now public abstract List <HexCoordinates> GetTargetSpaces(HexCoordinates source, HexDirection dir, EntityMapping entityMap, TileListBase tileMap, IMapCollisionDetection collide);
internal static List<HexCoordinates> GetAllPathableTiles(EntityMapping entityMap, TileListBase tileMap, HexCoordinates source, IEntityMovement movement, IMapCollisionDetection map) { List<HexCoordinates> ret = new List<HexCoordinates>(); IEntityMovement Move = movement; int MoveRange = movement.MovementRange; List<HexNode> closedset = new List<HexNode>(); //nodes already examined List<HexNode> openset = new List<HexNode>(); //nodes that still can be examined HexNode thing = new HexNode(source, source, null); thing.H = HexCoordinates.Distance(source, source); //dont really care 'bout H openset.Add(thing); while (openset.Count > 0) { HexNode current = openset[0]; openset.Remove(current); closedset.Add(current); if (current.G >= MoveRange) { continue; } //can't go any further from this location List<HexCoordinates> neighbors = map.AdjacentMoveSpaces(entityMap, tileMap, current.Coords, movement); for (int i = 0; i < neighbors.Count; i++) { bool found = false; HexCoordinates NeighborCoords = neighbors[i]; for (int j = 0; j < closedset.Count; j++) { if (closedset[j].Coords == NeighborCoords) { found = true; break; } } if (found) { continue; } //node was found in closedset, so dont do anything for (int j = 0; j < openset.Count; j++) { if (openset[j].Coords == NeighborCoords) { found = true; break; } } if (found) { continue; } //neighbor found in openset, no need to add it again. HexNode NewNode = new HexNode(NeighborCoords, source, current); //neighbor is a new node, add it to openset. openset.Add(NewNode); } } for(int i=0; i<closedset.Count; i++) { ret.Add(closedset[i].Coords); } return ret; }
public override bool Validate(IEntityMovement movement, IMapCollisionDetection seer, HexCoordinates origin, EntityMapping entityMap, TileListBase tileMap) { HexCoordinates CheckSpace = ClearSpace + origin; return((int)seer.NodeStatus(entityMap, tileMap, CheckSpace, movement) >= (int)MinimumClarity); }
internal static List<HexCoordinates> GetPath(EntityMapping entityMap, TileListBase tileMap, IMapCollisionDetection map, HexCoordinates start, HexCoordinates end) { IEntityMovement actor = new DefaultEnityMovement(); return GetPath(map, entityMap, tileMap, start, end, actor); /* if (!SanityCheck(map, start, end, actor)) { //UnityEngine.Debug.Log("Invalid path: Invalid paramaters."); return null; } List<HexCoordinates> ReturnValue = new List<HexCoordinates>(); List<HexNode> closedset = new List<HexNode>(); //nodes already examined List<HexNode> openset = new List<HexNode>(); //nodes that still can be examined HexNode thing = new HexNode(start, end, null); //location, goal, parent node. starting node has no parent. thing.H = HexCoordinates.Distance(start, end); openset.Add(thing); while (openset.Count > 0) { HexNode current = openset[0]; if (current.Coords == end) //we have reached our goal { return RebuildPath(current); } openset.Remove(current); //"pop" current closedset.Add(current); // //get all tile coords that are adjacent to current List<HexDirection3D> neighbors = map.ValidMoveDirections(current.Coords, actor); for (int i = 0; i < neighbors.Count; i++) { bool found = false; for (int j = 0; j < closedset.Count; j++) { if (closedset[j].Coords == neighbors[i]) { found = true; break; } } if (found) { continue; } //node was found in closedset, so dont do anything for (int j = 0; j < openset.Count; j++) { if (openset[j].Coords == neighbors[i]) { found = true; break; } } if (found) { continue; } //neighbor found in openset, no need to add it again. HexNode NewNode = new HexNode(neighbors[i], end, current); //neighbor is a new node, add it to openset. int index = openset.Count; for (int j = 0; j < openset.Count; j++) { if (NewNode.Score <= openset[j].Score) //newnode has lower or same score, should be inserted before checked node in openset { index = j; break; //doing this sort should improve pathfinding speed... } } openset.Insert(index, NewNode); } } //UnityEngine.Debug.Log("Invalid path: Could not draw path."); return null; */ }
public HexCoordinates Destination; //Use local coordinates public bool Validate(IEntityMovement movement, HexCoordinates source, EntityMapping entityMap, TileListBase tileMap, IMapCollisionDetection collide) { foreach (MovementCondition c in MovementConditions) { if (c.Validate(movement, collide, source, entityMap, tileMap) == false) { return(false); } } return(true); }
public abstract bool Validate(IEntityMovement movement, IMapCollisionDetection seer, HexCoordinates PathOrigin, EntityMapping entityMap, TileListBase tileMap);