internal void GetValue(MapDataStore.Tile tempTile, MeshLayer staticMaterial, out object colorContent) { throw new NotImplementedException(); }
void UpdateItem(UnitDefinition unit, ref int creatureCount) { UnitFlags1 flags1 = (UnitFlags1)unit.flags1; //UnitFlags2 flags2 = (UnitFlags2)unit.flags2; //UnitFlags3 flags3 = (UnitFlags3)unit.flags3; if (((flags1 & UnitFlags1.dead) == UnitFlags1.dead) || ((flags1 & UnitFlags1.left) == UnitFlags1.left) || ((flags1 & UnitFlags1.caged) == UnitFlags1.caged) || ((flags1 & UnitFlags1.forest) == UnitFlags1.forest) ) { if (creatureList.ContainsKey(unit.id)) { Destroy(creatureList[unit.id].gameObject); creatureList.Remove(unit.id); } } else { MapDataStore.Tile tile = null; if (MapDataStore.Main != null) { tile = MapDataStore.Main[unit.pos_x, unit.pos_y, unit.pos_z]; } if (!ShouldRender(unit.pos_x, unit.pos_y, unit.pos_z, tile) && !singleRow) { if (creatureList.ContainsKey(unit.id)) { creatureList[unit.id].gameObject.SetActive(false); } return; } else if (creatureList.ContainsKey(unit.id)) { creatureList[unit.id].gameObject.SetActive(true); } if (!creatureList.ContainsKey(unit.id)) { creatureList[unit.id] = Instantiate(creatureTemplate, gameObject.transform); creatureList[unit.id].name = "Unit_" + unit.id; creatureList[unit.id].transform.position = new Vector3(-3000, -3000, -3000); } if (creatureList[unit.id].gameObject.activeSelf) //Only update stuff if it's actually visible. { if (singleRow) { creatureList[unit.id].transform.position = new Vector3(creatureCount * spacing, 0, 0); } else { var position = GameMap.DFtoUnityCoord(unit.pos_x + unit.subpos_x, unit.pos_y + unit.subpos_y, unit.pos_z + unit.subpos_z); //RaycastHit hitInfo; //if (((flags1 & UnitFlags1.projectile) != UnitFlags1.projectile) && Physics.Raycast(position + new Vector3(0, 2.9f, 0), Vector3.down, out hitInfo, 3, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore)) // creatureList[unit.id].TargetPos = hitInfo.point; //else creatureList[unit.id].TargetPos = position + new Vector3(0, GameMap.floorHeight, 0); } if (unit.rider_id >= 0 && creatureList.ContainsKey(unit.rider_id)) { creatureList[unit.id].TargetPos += new Vector3(0, creatureList[unit.rider_id].transform.localScale.y, 0); } UnitScaler unitScaler = creatureList[unit.id].GetComponentInChildren <UnitScaler>(); if (unitScaler != null) { unitScaler.UpdateSize(unit, creatureList[unit.id].GetComponentInChildren <LayeredSprite>()); } CameraFacing cameraFacing = creatureList[unit.id].GetComponentInChildren <CameraFacing>(); if ((flags1 & UnitFlags1.on_ground) == UnitFlags1.on_ground) { cameraFacing.transform.localPosition = Vector3.zero; cameraFacing.enabled = false; cameraFacing.transform.rotation = Quaternion.Euler(90, 0, 0); } else { cameraFacing.transform.localPosition = new Vector3(0, 1, 0); cameraFacing.enabled = true; } creatureList[unit.id].UpdateCreature(unit); } creatureCount++; } }
void UpdateCreatures() { if (!GameSettings.Instance.units.drawUnits) { return; } if (creatureTemplate == null) { return; } if (ContentLoader.Instance == null) { return; } var tempUnitList = DFConnection.Instance.PopUnitListUpdate(); if (tempUnitList == null) { return; } else { Units = tempUnitList; } UnityEngine.Profiling.Profiler.BeginSample("UpdateCreatures", this); int creatureCount = 0; foreach (var unit in Units.creature_list) { if (creatureList == null) { creatureList = new Dictionary <int, Creature>(); } UnitFlags1 flags1 = (UnitFlags1)unit.flags1; //UnitFlags2 flags2 = (UnitFlags2)unit.flags2; //UnitFlags3 flags3 = (UnitFlags3)unit.flags3; if (((flags1 & UnitFlags1.dead) == UnitFlags1.dead) || ((flags1 & UnitFlags1.left) == UnitFlags1.left) || ((flags1 & UnitFlags1.caged) == UnitFlags1.caged) || ((flags1 & UnitFlags1.forest) == UnitFlags1.forest) ) { if (creatureList.ContainsKey(unit.id)) { Destroy(creatureList[unit.id].gameObject); creatureList.Remove(unit.id); } } else { if (!creatureList.ContainsKey(unit.id)) { creatureList[unit.id] = Instantiate(creatureTemplate, gameObject.transform); creatureList[unit.id].name = "Unit_" + unit.id; creatureList[unit.id].transform.position = new Vector3(-3000, -3000, -3000); } if (!singleRow) { MapDataStore.Tile tile = null; if (MapDataStore.Main != null) { tile = MapDataStore.Main[unit.pos_x, unit.pos_y, unit.pos_z]; } creatureList[unit.id].gameObject.SetActive( (unit.pos_z < (GameMap.Instance.firstPerson ? GameMap.Instance.PosZ + GameSettings.Instance.rendering.drawRangeUp : GameMap.Instance.PosZ)) && unit.pos_z >= (GameMap.Instance.PosZ - GameSettings.Instance.rendering.drawRangeDown) && (unit.pos_x / GameMap.blockSize > (GameMap.Instance.PosXBlock - GameSettings.Instance.rendering.drawRangeSide)) && (unit.pos_x / GameMap.blockSize < (GameMap.Instance.PosXBlock + GameSettings.Instance.rendering.drawRangeSide)) && (unit.pos_y / GameMap.blockSize > (GameMap.Instance.PosYBlock - GameSettings.Instance.rendering.drawRangeSide)) && (unit.pos_y / GameMap.blockSize < (GameMap.Instance.PosYBlock + GameSettings.Instance.rendering.drawRangeSide)) && (tile != null ? !tile.Hidden : true) ); } if (creatureList[unit.id].gameObject.activeSelf) //Only update stuff if it's actually visible. { if (singleRow) { creatureList[unit.id].transform.position = new Vector3(creatureCount * spacing, 0, 0); } else { var position = GameMap.DFtoUnityCoord(unit.pos_x + unit.subpos_x, unit.pos_y + unit.subpos_y, unit.pos_z + unit.subpos_z); RaycastHit hitInfo; if (((flags1 & UnitFlags1.projectile) != UnitFlags1.projectile) && Physics.Raycast(position + new Vector3(0, 2.9f, 0), Vector3.down, out hitInfo, 3, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore)) { creatureList[unit.id].TargetPos = hitInfo.point; } else { creatureList[unit.id].TargetPos = position + new Vector3(0, GameMap.floorHeight, 0); } } if (unit.rider_id >= 0 && creatureList.ContainsKey(unit.rider_id)) { creatureList[unit.id].TargetPos += new Vector3(0, creatureList[unit.rider_id].transform.localScale.y, 0); } UnitScaler unitScaler = creatureList[unit.id].GetComponentInChildren <UnitScaler>(); if (unitScaler != null) { unitScaler.UpdateSize(unit, creatureList[unit.id].GetComponentInChildren <LayeredSprite>()); } CameraFacing cameraFacing = creatureList[unit.id].GetComponentInChildren <CameraFacing>(); if ((flags1 & UnitFlags1.on_ground) == UnitFlags1.on_ground) { cameraFacing.transform.localPosition = Vector3.zero; cameraFacing.enabled = false; cameraFacing.transform.rotation = Quaternion.Euler(90, 0, 0); } else { cameraFacing.transform.localPosition = new Vector3(0, 1, 0); cameraFacing.enabled = true; } creatureList[unit.id].GetComponent <Creature>().UpdateCreature(unit); } creatureCount++; } } UnityEngine.Profiling.Profiler.EndSample(); }
public override bool GetValue(MapDataStore.Tile tile, MeshLayer layer, out T value) { MatPairStruct mat = tile.material; int plantIndex = mat.mat_index; switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: return(GetMaterialRef(tile.material, tile, layer, out value)); case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: return(GetMaterialRef(tile.base_material, tile, layer, out value)); case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: return(GetMaterialRef(tile.layer_material, tile, layer, out value)); case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: return(GetMaterialRef(tile.vein_material, tile, layer, out value)); case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.NoMaterialBuilding: case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: if (defaultMaterial == null) { break; } value = defaultMaterial.GetValue(tile, layer); return(true); case MeshLayer.BuildingMaterial: case MeshLayer.BuildingMaterialCutout: case MeshLayer.BuildingMaterialTransparent: return(GetMaterialRef(tile.buildingMaterial, tile, layer, out value)); case MeshLayer.GrowthMaterial: case MeshLayer.GrowthCutout: case MeshLayer.GrowthTransparent: if ((mat.mat_type != PlantType) || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths.Count <= 0 || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[0].mat == null) { value = default(T); return(false); } return(GetMaterialRef(DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[0].mat, tile, layer, out value)); case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthTransparent1: if ((mat.mat_type != PlantType) || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths.Count <= 1 || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[0].mat == null) { value = default(T); return(false); } return(GetMaterialRef(DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[1].mat, tile, layer, out value)); case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthTransparent2: if ((mat.mat_type != PlantType) || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths.Count <= 2 || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[0].mat == null) { value = default(T); return(false); } return(GetMaterialRef(DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[2].mat, tile, layer, out value)); case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent3: if ((mat.mat_type != PlantType) || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths.Count <= 3 || DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[0].mat == null) { value = default(T); return(false); } return(GetMaterialRef(DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths[3].mat, tile, layer, out value)); default: break; } value = default(T); return(false); }
private void Update3DUnit(UnitDefinition unit, ref int creatureCount) { UnitFlags1 flags1 = (UnitFlags1)unit.flags1; //UnitFlags2 flags2 = (UnitFlags2)unit.flags2; //UnitFlags3 flags3 = (UnitFlags3)unit.flags3; if (((flags1 & UnitFlags1.dead) == UnitFlags1.dead) || ((flags1 & UnitFlags1.left) == UnitFlags1.left) || ((flags1 & UnitFlags1.caged) == UnitFlags1.caged) || ((flags1 & UnitFlags1.forest) == UnitFlags1.forest) ) { if (creatureList3D.ContainsKey(unit.id)) { Destroy(creatureList3D[unit.id].gameObject); creatureList3D.Remove(unit.id); } return; } MapDataStore.Tile tile = null; if (MapDataStore.Main != null) { tile = MapDataStore.Main[unit.pos_x, unit.pos_y, unit.pos_z]; } if (!ShouldRender(unit.pos_x, unit.pos_y, unit.pos_z, tile) && !singleRow) { if (creatureList3D.ContainsKey(unit.id)) { creatureList3D[unit.id].gameObject.SetActive(false); } return; } else if (creatureList3D.ContainsKey(unit.id)) { creatureList3D[unit.id].gameObject.SetActive(true); } if (!creatureList3D.ContainsKey(unit.id)) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.race = DFConnection.Instance.CreatureRaws[unit.race.mat_type]; creatureBase.caste = creatureBase.race.caste[unit.race.mat_index]; creatureBase.unit = unit; creatureBase.MakeBody(); if (string.IsNullOrEmpty(unit.name)) { creatureBase.name = creatureBase.race.name[0]; } creatureBase.name = unit.name; creatureList3D[unit.id] = creatureBase; creatureBase.transform.parent = transform; } var placedUnit = creatureList3D[unit.id]; if (!placedUnit.gameObject.activeSelf) { return; } placedUnit.UpdateUnit(unit); if (unit.rider_id >= 0 && creatureList3D.ContainsKey(unit.rider_id)) { placedUnit.transform.parent = creatureList3D[unit.rider_id].transform; if (creatureList3D[unit.rider_id].riderPosition == null) { placedUnit.transform.position = creatureList3D[unit.rider_id].rootPart.transform.position; placedUnit.transform.rotation = creatureList3D[unit.rider_id].rootPart.transform.rotation; } else { placedUnit.transform.position = creatureList3D[unit.rider_id].riderPosition.transform.position; placedUnit.transform.rotation = creatureList3D[unit.rider_id].riderPosition.transform.rotation; } } else { placedUnit.transform.parent = transform; placedUnit.transform.position = GameMap.DFtoUnityCoord(unit.pos_x + unit.subpos_x, unit.pos_y + unit.subpos_y, unit.pos_z + unit.subpos_z) + new Vector3(0, GameMap.floorHeight, 0); } }
void GenerateMesh() { if (width == 1 && height == 1) return; int length = width * height * 4; List<Vector3> vertices = new List<Vector3>(length); List<Color> colors = new List<Color>(length); List<Vector2> uvs = new List<Vector2>(length); List<Vector2> uv2s = new List<Vector2>(length); List<Vector2> uv3s = new List<Vector2>(length); List<int> triangles = new List<int>(length); List<Vector3> waterVerts = new List<Vector3>(); List<Vector2> waterUvs = new List<Vector2>(); List<int> waterTris = new List<int>(); foreach(MeshFilter mf in terrainChunks) { if (mf.mesh != null) mf.mesh.Clear(); } foreach(MeshFilter mf in waterChunks) { if (mf.mesh != null) mf.mesh.Clear(); } chunkIndex = 0; waterChunkIndex = 0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (DetailRegions.ContainsKey(new DFCoord2d(x, y))) continue; //If the vertex lists are already full, make a chunk with what we have, and keep going if (vertices.Count >= (65535 - 20)) { FinalizeGeometryChunk(vertices, colors, uvs, uv2s, uv3s, triangles); } //If the vertex lists are already full, make a chunk with what we have, and keep going if (waterVerts.Count >= (65535 - 20)) { FinalizeWaterGeometryChunk(waterVerts, waterUvs, waterTris); } MapDataStore.Tile fakeTile = new MapDataStore.Tile(null, new DFCoord(0, 0, 0)); fakeTile.material = regionTiles[x, y].surface_material; ColorContent colorContent; ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent); Color terrainColor = colorContent.color; Color plantColor = Color.black; float grassPercent = Mathf.Pow(regionTiles[x, y].vegetation / 100.0f, 0.25F); float treePercent = Mathf.Pow(regionTiles[x, y].vegetation / 100.0f, 0.5F); foreach (var item in regionTiles[x, y].plant_materials) { fakeTile.material = item; ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent); plantColor += colorContent.color; } if (regionTiles[x, y].plant_materials.Count == 0) grassPercent = 0; else plantColor /= regionTiles[x, y].plant_materials.Count; Color treeColor = Color.black; int treeCount = 0; foreach (var tree in regionTiles[x,y].tree_materials) { int plantIndex = tree.mat_index; if (tree.mat_type != 419 || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex) continue; var treeMat = tree; foreach (var growth in DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths) { int currentTicks = TimeHolder.DisplayedTime.CurrentYearTicks; if ((growth.timing_start != -1 && growth.timing_start > currentTicks) || (growth.timing_end != -1 && growth.timing_end < currentTicks)) continue; treeMat = growth.mat; break; } fakeTile.material = treeMat; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent)) { treeColor += colorContent.color; treeCount++; } } if (treeCount == 0) treePercent = 0; else treeColor /= treeCount; terrainColor = Color.Lerp(terrainColor, plantColor, grassPercent); terrainColor = Color.Lerp(terrainColor, treeColor, treePercent); Vector2 biome = new Vector2(regionTiles[x, y].rainfall, 100 - regionTiles[x, y].drainage) / 100; Vector3 vert1 = RegionToUnityCoords(x, y, regionTiles[x, y].elevation); Vector3 vert2 = RegionToUnityCoords(x + 1, y + 1, regionTiles[x, y].elevation); bool snow = regionTiles[x, y].snow > 0; RegionMaker.AddHorizontalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, uv3s, triangles, snow); if (regionTiles[x, y].elevation < regionTiles[x, y].water_elevation) { vert1 = RegionToUnityCoords(x, y, regionTiles[x, y].water_elevation); vert2 = RegionToUnityCoords(x + 1, y + 1, regionTiles[x, y].water_elevation); RegionMaker.AddHorizontalQuad(vert1, vert2, biome, terrainColor, waterVerts, null, waterUvs, null, null, waterTris, false); } int north = 0; if (y > 0 && !DetailRegions.ContainsKey(new DFCoord2d(x, y - 1))) north = regionTiles[x, y - 1].elevation; if (north < regionTiles[x, y].elevation) { vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth)) * scale; vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, north * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth)) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, uv3s, triangles, snow); } int south = 0; if (y < height - 1 && !DetailRegions.ContainsKey(new DFCoord2d(x, y + 1))) south = regionTiles[x, y + 1].elevation; if (south < regionTiles[x, y].elevation) { vert1 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth)) * scale; vert2 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, south * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth)) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, uv3s, triangles, snow); } int east = 0; if (x < width - 1 && !DetailRegions.ContainsKey(new DFCoord2d(x + 1, y))) east = regionTiles[x + 1, y].elevation; if (east < regionTiles[x, y].elevation) { vert1 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth)) * scale; vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, east * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth)) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, uv3s, triangles, snow); } int west = 0; if (x > 0 && !DetailRegions.ContainsKey(new DFCoord2d(x - 1, y))) west = regionTiles[x - 1, y].elevation; if (west < regionTiles[x, y].elevation) { vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth)) * scale; vert2 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, west * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth)) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, uv3s, triangles, snow); } } } FinalizeGeometryChunk(vertices, colors, uvs, uv2s, uv3s, triangles); FinalizeWaterGeometryChunk(waterVerts, waterUvs, waterTris); }
public override bool GetValue(MapDataStore.Tile tile, MeshLayer layer, out T value) { switch (tile.digDesignation) { case RemoteFortressReader.TileDigDesignation.NO_DIG: break; case RemoteFortressReader.TileDigDesignation.DEFAULT_DIG: if (designationBlocks.ContainsKey(DesignationTypes.Default)) { value = designationBlocks[DesignationTypes.Default].GetValue(tile, layer); return(true); } break; case RemoteFortressReader.TileDigDesignation.UP_DOWN_STAIR_DIG: if (designationBlocks.ContainsKey(DesignationTypes.UpDownStairs)) { value = designationBlocks[DesignationTypes.UpDownStairs].GetValue(tile, layer); return(true); } break; case RemoteFortressReader.TileDigDesignation.CHANNEL_DIG: if (designationBlocks.ContainsKey(DesignationTypes.Channel)) { value = designationBlocks[DesignationTypes.Channel].GetValue(tile, layer); return(true); } break; case RemoteFortressReader.TileDigDesignation.RAMP_DIG: if (designationBlocks.ContainsKey(DesignationTypes.Ramp)) { value = designationBlocks[DesignationTypes.Ramp].GetValue(tile, layer); return(true); } break; case RemoteFortressReader.TileDigDesignation.DOWN_STAIR_DIG: if (designationBlocks.ContainsKey(DesignationTypes.DownStairs)) { value = designationBlocks[DesignationTypes.DownStairs].GetValue(tile, layer); return(true); } break; case RemoteFortressReader.TileDigDesignation.UP_STAIR_DIG: if (designationBlocks.ContainsKey(DesignationTypes.UpStairs)) { value = designationBlocks[DesignationTypes.UpStairs].GetValue(tile, layer); return(true); } break; default: break; } if (tile.hidden) { if (designationBlocks.ContainsKey(DesignationTypes.Hidden)) { value = designationBlocks[DesignationTypes.Hidden].GetValue(tile, layer); return(true); } } value = default(T); return(false); }
// A big method, but pretty simple. // Walk through tiles (starting in current one); // in each tile, check if the ray is actively hitting something. // If it's not, find the wall of the tile the ray exits through, // go to that tile, and repeat. bool FindCurrentTarget(Ray ray, out DFCoord tileCoord, out Vector3 unityCoord) { if (!HitsMapCube(ray)) { tileCoord = default(DFCoord); unityCoord = default(Vector3); return(false); } // In each tile, we find its bottom corner, and then add these // values to find the coordinates of the walls. // If the ray increases on this axis, the offset will be the // width of the tile along that axis; if the ray decreases, // the offset will be 0 (since we're already on that wall.) float xWallOffset, yWallOffset, zWallOffset; // When we pass through a tile and hit this wall, how do we increment // our DFCoord? DFCoord xHitIncrement, yHitIncrement, zHitIncrement; if (ray.direction.x > 0) { xWallOffset = GameMap.tileWidth; xHitIncrement = new DFCoord(1, 0, 0); } else { xWallOffset = 0; xHitIncrement = new DFCoord(-1, 0, 0); } if (ray.direction.z > 0) { zWallOffset = GameMap.tileWidth; zHitIncrement = new DFCoord(0, -1, 0); } else { zWallOffset = 0; zHitIncrement = new DFCoord(0, 1, 0); } if (ray.direction.y > 0) { yWallOffset = GameMap.tileHeight; yHitIncrement = new DFCoord(0, 0, 1); } else { yWallOffset = 0; yHitIncrement = new DFCoord(0, 0, -1); } // If this is true and we go onto a tile outside the map, // we stop iterating (since we can't hit anything.) bool haveHitMap = false; // The coordinate we start at. DFCoord currentCoord = GameMap.UnityToDFCoord(ray.origin); // The coordinate of the last tile wall intersection. Vector3 lastHit = ray.origin; // Cheap hack to keep from looping forever if we screw up somehow. for (int _insurance = 0; _insurance < MAXIMUM_CHECKS; _insurance++) { if (debugMode) { DebugHighlightTile(currentCoord, Color.blue); } // Make sure we don't move backwards somehow. if ((lastHit.x - ray.origin.x) / ray.direction.x < 0) { throw new UnityException("Negative distance multiplier?"); } // Get the corner of the current tile. Vector3 cornerCoord = GameMap.DFtoUnityBottomCorner(currentCoord); // Are we in the selectable area of the map? if (!MapDataStore.InMapBounds(currentCoord) || gameMap.PosZ <= currentCoord.z) { // No. if (haveHitMap) { // But we have been before; // we've entered and exited the map without hitting anything. tileCoord = default(DFCoord); unityCoord = default(Vector3); return(false); } } else { // We are in the map. haveHitMap = true; MapDataStore.Tile currentTile = MapDataStore.Main[currentCoord.x, currentCoord.y, currentCoord.z]; // Are we in a real tile? if (currentTile != null) { // Yes. switch (currentTile.shape) { case RemoteFortressReader.TiletypeShape.EMPTY: case RemoteFortressReader.TiletypeShape.NO_SHAPE: // We're not hitting anything, though. break; //case RemoteFortressReader.TiletypeShape.SHRUB: //case RemoteFortressReader.TiletypeShape.SAPLING: case RemoteFortressReader.TiletypeShape.WALL: case RemoteFortressReader.TiletypeShape.FORTIFICATION: //case RemoteFortressReader.TiletypeShape.TRUNK_BRANCH: case RemoteFortressReader.TiletypeShape.TWIG: // We must be hitting things. // (maybe adjust shrub, saplings out of this group?) tileCoord = currentCoord; unityCoord = lastHit; return(true); case RemoteFortressReader.TiletypeShape.RAMP: case RemoteFortressReader.TiletypeShape.FLOOR: case RemoteFortressReader.TiletypeShape.BOULDER: case RemoteFortressReader.TiletypeShape.PEBBLES: case RemoteFortressReader.TiletypeShape.BROOK_TOP: case RemoteFortressReader.TiletypeShape.SAPLING: case RemoteFortressReader.TiletypeShape.SHRUB: case RemoteFortressReader.TiletypeShape.BRANCH: case RemoteFortressReader.TiletypeShape.TRUNK_BRANCH: // Check if we're in the floor. // (that we're in the tile is implied.) if (Between(cornerCoord.y, lastHit.y, cornerCoord.y + GameMap.floorHeight)) { tileCoord = currentCoord; unityCoord = lastHit; return(true); } // Check if we enter the floor; same way we check wall intersections. float floorY = cornerCoord.y + GameMap.floorHeight; float toFloorMult = (floorY - ray.origin.y) / ray.direction.y; Vector3 floorIntercept = ray.origin + ray.direction * toFloorMult; if (Between(cornerCoord.x, floorIntercept.x, cornerCoord.x + GameMap.tileWidth) && Between(cornerCoord.z, floorIntercept.z, cornerCoord.z + GameMap.tileWidth)) { tileCoord = currentCoord; unityCoord = lastHit; return(true); } break; } } } // Didn't hit anything in the tile; figure out which wall we're hitting & walk to that tile. { float xMult = (cornerCoord.x + xWallOffset - ray.origin.x) / ray.direction.x; Vector3 xIntercept = ray.origin + ray.direction * xMult; if (Between(cornerCoord.z, xIntercept.z, cornerCoord.z + GameMap.tileWidth) && Between(cornerCoord.y, xIntercept.y, cornerCoord.y + GameMap.tileHeight)) { lastHit = xIntercept; currentCoord += xHitIncrement; continue; } } { float zMult = (cornerCoord.z + zWallOffset - ray.origin.z) / ray.direction.z; Vector3 zIntercept = ray.origin + ray.direction * zMult; if (Between(cornerCoord.x, zIntercept.x, cornerCoord.x + GameMap.tileWidth) && Between(cornerCoord.y, zIntercept.y, cornerCoord.y + GameMap.tileHeight)) { lastHit = zIntercept; currentCoord += zHitIncrement; continue; } } { float yMult = (cornerCoord.y + yWallOffset - ray.origin.y) / ray.direction.y; Vector3 yIntercept = ray.origin + ray.direction * yMult; if (cornerCoord.x <= yIntercept.x && yIntercept.x <= cornerCoord.x + GameMap.tileWidth && cornerCoord.z <= yIntercept.z && yIntercept.z <= cornerCoord.z + GameMap.tileWidth) { lastHit = yIntercept; currentCoord += yHitIncrement; continue; } } // We haven't found a wall to hit. // This shouldn't happen, but occasionally does. //throw new UnityException("Didn't hit any tile walls?"); } // We went the maximum amount of time without hitting anything tileCoord = default(DFCoord); unityCoord = default(Vector3); return(false); }
void DrawItems() { if (ContentLoader.Instance == null) return; UnityEngine.Profiling.Profiler.BeginSample("DrawItems", this); if (itemParticles == null) { itemParticles = new ParticleSystem.Particle[itemParticleSystem.main.maxParticles]; } MapDataStore.Tile tempTile = new MapDataStore.Tile(null, new DFCoord(0, 0, 0)); int i = 0; foreach (var count in customItemParticleSystems) { customItemParticleCount[count.Key] = 0; } foreach (var item in itemPositions) { var pos = item.Key; if (!(pos.z < PosZ && pos.z >= (PosZ - GameSettings.Instance.rendering.drawRangeDown))) continue; tempTile.material = item.Value.material; tempTile.construction_item = item.Value.type; ColorContent colorContent; MeshContent meshContent; var part = new ParticleSystem.Particle(); part.startSize = 1; part.position = DFtoUnityCoord(item.Value.pos) + new Vector3(0, floorHeight + 0.5f, 0); if (ContentLoader.Instance.ColorConfiguration.GetValue(tempTile, MeshLayer.StaticMaterial, out colorContent)) part.startColor = colorContent.color; else if (materials.ContainsKey(item.Value.material) && materials[item.Value.material].state_color != null) { var stateColor = materials[item.Value.material].state_color; part.startColor = new Color32((byte)stateColor.red, (byte)stateColor.green, (byte)stateColor.blue, 255); } else part.startColor = Color.gray; if(item.Value.dye != null) { part.startColor *= (Color)(new Color32((byte)item.Value.dye.red, (byte)item.Value.dye.green, (byte)item.Value.dye.blue, 255)); } if (ContentLoader.Instance.ItemMeshConfiguration != null && ContentLoader.Instance.ItemMeshConfiguration.GetValue(tempTile, MeshLayer.StaticMaterial, out meshContent)) { ParticleSystem partSys; if (!customItemParticleSystems.ContainsKey(meshContent.UniqueIndex)) { partSys = Instantiate(itemParticleSystem); partSys.transform.parent = transform; var renderer = partSys.GetComponent<ParticleSystemRenderer>(); Mesh mesh = new Mesh(); if (meshContent.MeshData.ContainsKey(MeshLayer.StaticCutout)) { meshContent.MeshData[MeshLayer.StaticCutout].CopyToMesh(mesh); noCustomParticleColor[meshContent.UniqueIndex] = false; } else if (meshContent.MeshData.ContainsKey(MeshLayer.NoMaterialCutout)) { meshContent.MeshData[MeshLayer.NoMaterialCutout].CopyToMesh(mesh); noCustomParticleColor[meshContent.UniqueIndex] = true; } else { bool copied = false; foreach (var backup in meshContent.MeshData) { backup.Value.CopyToMesh(mesh); noCustomParticleColor[meshContent.UniqueIndex] = false; copied = true; break; } if (!copied) continue; } renderer.mesh = mesh; if (meshContent.MaterialTexture != null) renderer.material.SetTexture("_MainTex", meshContent.MaterialTexture.Texture); else { TextureContent texCon; if(ContentLoader.Instance.MaterialTextureConfiguration.GetValue(tempTile, MeshLayer.StaticMaterial, out texCon)) renderer.material.SetTexture("_MainTex", texCon.Texture); } if (meshContent.ShapeTexture != null) renderer.material.SetTexture("_BumpMap", meshContent.ShapeTexture.Texture); else { NormalContent normalCon; if(ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tempTile, MeshLayer.StaticMaterial, out normalCon)) renderer.material.SetTexture("_BumpMap", normalCon.Texture); } if (meshContent.SpecialTexture != null) renderer.material.SetTexture("_SpecialTex", meshContent.SpecialTexture.Texture); customItemParticleSystems[meshContent.UniqueIndex] = partSys; customItemParticles[meshContent.UniqueIndex] = new ParticleSystem.Particle[partSys.main.maxParticles]; customItemParticleCount[meshContent.UniqueIndex] = 0; } if (meshContent.Rotation == RotationType.Random) part.rotation = (float)noise.eval(pos.x, pos.y, pos.z) * 360; part.position = DFtoUnityCoord(item.Value.pos) + new Vector3(0, floorHeight, 0); if (noCustomParticleColor[meshContent.UniqueIndex]) part.startColor = Color.gray; customItemParticles[meshContent.UniqueIndex][customItemParticleCount[meshContent.UniqueIndex]] = part; customItemParticleCount[meshContent.UniqueIndex]++; } else { part.position = DFtoUnityCoord(item.Value.pos) + new Vector3(0, floorHeight + 0.5f, 0); itemParticles[i] = part; i++; } } itemParticleSystem.SetParticles(itemParticles, i); foreach (var sys in customItemParticleSystems) { sys.Value.SetParticles(customItemParticles[sys.Key], customItemParticleCount[sys.Key]); } UnityEngine.Profiling.Profiler.EndSample(); }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); Vector2 index1 = Vector2.zero; Vector2 index2 = Vector2.zero; MeshContent meshContent = null; buffer.color = Color.grey; if (layer == MeshLayer.Collision) { if (!ContentLoader.Instance.CollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) { buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; } else if (meshContent.MeshData.ContainsKey(MeshLayer.StaticMaterial)) { buffer.meshData = meshContent.MeshData[MeshLayer.StaticMaterial]; } else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } if (ContentLoader.Instance.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); index1.x = ContentLoader.GetPatternIndex(tile.DesignationMat) / ContentLoader.Instance.PatternTextureDepth; buffer.color = ContentLoader.GetColor(tile.DesignationMat); if (meshContent.ShapeTexture != null) { index1.y = meshContent.ShapeTexture.ArrayIndex; } else { index1.y = ContentLoader.Instance.DefaultShapeTexArrayIndex; } if (meshContent.SpecialTexture != null) { index2.x = meshContent.SpecialTexture.ArrayIndex; } else { index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } var matColor = ContentLoader.GetColor(tile.GetMaterial(layer)); var matPatternIndex = ContentLoader.GetPatternIndex(tile.GetMaterial(layer)); switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthCutout: case MeshLayer.GrowthTransparent: matColor = ContentLoader.GetColor(new MatPairStruct(55, 0), tile.GetMaterial(layer)); break; case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthTransparent1: matColor = ContentLoader.GetColor(new MatPairStruct(55, 1), tile.GetMaterial(layer)); break; case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthTransparent2: matColor = ContentLoader.GetColor(new MatPairStruct(55, 2), tile.GetMaterial(layer)); break; case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent3: matColor = ContentLoader.GetColor(new MatPairStruct(55, 3), tile.GetMaterial(layer)); break; default: break; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!ContentLoader.Instance.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; default: { if (layer == MeshLayer.NaturalTerrain) { if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.HandleShape(tile) && !VoxelGenerator.UseBoth(tile)) { layer = MeshLayer.StaticMaterial; } else { buffer.meshData = null; return; } } else if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.UseBoth(tile)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } //Use the transparent shader instead of the opaque shader if the material is transparent. if (matColor.a < 0.5f) { switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.BaseMaterial: case MeshLayer.LayerMaterial: case MeshLayer.VeinMaterial: buffer.meshData = null; return; case MeshLayer.StaticTransparent: layer = MeshLayer.StaticMaterial; break; case MeshLayer.BaseTransparent: layer = MeshLayer.BaseMaterial; break; case MeshLayer.LayerTransparent: layer = MeshLayer.LayerMaterial; break; case MeshLayer.VeinTransparent: layer = MeshLayer.VeinMaterial; break; default: break; } } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 shapeTextTransform = ContentLoader.Instance.DefaultShapeTexTransform; Matrix4x4 specialTexTransform = Matrix4x4.identity; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { if (ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; index1.y = meshContent.ShapeTexture.ArrayIndex; } index1.x = matPatternIndex / ContentLoader.Instance.PatternTextureDepth; if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; index2.x = meshContent.SpecialTexture.ArrayIndex; } else { specialTexTransform = ContentLoader.Instance.DefaultSpecialTexTransform; index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.color = matColor; buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); }
public override bool GetValue(MapDataStore.Tile tile, MeshLayer layer, out T value) { Content cont; switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: if (materialMatcher.Get(tile.material, out cont)) { value = cont.GetValue(tile, layer); return(true); } break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: if (materialMatcher.Get(tile.base_material, out cont)) { value = cont.GetValue(tile, layer); return(true); } break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: if (materialMatcher.Get(tile.layer_material, out cont)) { value = cont.GetValue(tile, layer); return(true); } break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: if (materialMatcher.Get(tile.vein_material, out cont)) { value = cont.GetValue(tile, layer); return(true); } break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: if (defaultMaterial == null) { break; } value = defaultMaterial.GetValue(tile, layer); return(true); case MeshLayer.Growth0Cutout: break; case MeshLayer.Growth1Cutout: break; case MeshLayer.Growth2Cutout: break; case MeshLayer.Growth3Cutout: break; default: break; } value = default(T); return(false); }
public static Quaternion TranslateRotation(RotationType rotationType, MapDataStore.Tile tile) { switch (rotationType) { case RotationType.None: return(Quaternion.identity); case RotationType.AwayFromWall: { Directions wallSides = tile.WallBuildingSides; Vector2 average = Vector2.zero; if ((wallSides & Directions.NorthWest) == Directions.NorthWest) { average += new Vector2(-1, 1); } if ((wallSides & Directions.North) == Directions.North) { average += new Vector2(0, 1); } if ((wallSides & Directions.NorthEast) == Directions.NorthEast) { average += new Vector2(1, 1); } if ((wallSides & Directions.West) == Directions.West) { average += new Vector2(-1, 0); } if ((wallSides & Directions.East) == Directions.East) { average += new Vector2(1, -0); } if ((wallSides & Directions.SouthWest) == Directions.SouthWest) { average += new Vector2(-1, -1); } if ((wallSides & Directions.South) == Directions.South) { average += new Vector2(0, -1); } if ((wallSides & Directions.SouthEast) == Directions.SouthEast) { average += new Vector2(1, -1); } if (average.magnitude < 0.001) { return(Quaternion.Euler(0, 0, 0)); } float angle = Mathf.Atan2(average.x, average.y) * 180 / Mathf.PI; float angle90 = Mathf.Round(angle / 90) * 90; float angle45 = Mathf.Round(angle / 45) * 45; if (Mathf.Abs(angle90 - angle) < 30) { return(Quaternion.Euler(0, angle90, 0)); } else { return(Quaternion.Euler(0, angle45, 0)); } } case RotationType.Door: { Directions wallSides = tile.WallBuildingSides; if ((wallSides & (Directions.North | Directions.South | Directions.East | Directions.West)) == (Directions.North | Directions.South | Directions.East | Directions.West)) { return(Quaternion.identity); } if ((wallSides & (Directions.North | Directions.South)) == (Directions.North | Directions.South)) { return(Quaternion.Euler(0, 90, 0)); } ; return(Quaternion.identity); } case RotationType.BuildingDirection: { switch (tile.buildingDirection) { case RemoteFortressReader.BuildingDirection.NORTH: return(Quaternion.Euler(0, 0, 0)); case RemoteFortressReader.BuildingDirection.EAST: return(Quaternion.Euler(0, 90, 0)); case RemoteFortressReader.BuildingDirection.SOUTH: return(Quaternion.Euler(0, 180, 0)); case RemoteFortressReader.BuildingDirection.WEST: return(Quaternion.Euler(0, -90, 0)); default: return(Quaternion.Euler(0, 0, 0)); } } case RotationType.Random: { if (noise == null) { noise = new OpenSimplexNoise(); } float rot = (float)noise.eval(tile.position.x, tile.position.y, tile.position.z); return(Quaternion.Euler(0, rot * 360, 0)); } case RotationType.Random90: { if (noise == null) { noise = new OpenSimplexNoise(); } float rot = (float)noise.eval(tile.position.x, tile.position.y, tile.position.z); rot = Mathf.Round(rot * 4) * 90; return(Quaternion.Euler(0, rot, 0)); } case RotationType.TreeFlat: { Vector2 treeDir = new Vector2(-tile.positionOnTree.x, tile.positionOnTree.y); if (treeDir.sqrMagnitude < 0.001) { return(Quaternion.identity); } float angle = Mathf.Atan2(treeDir.x, treeDir.y) * 180 / Mathf.PI; return(Quaternion.Euler(0, angle, 0)); } case RotationType.TreeRound: { Vector3 treeDir = new Vector3(-tile.positionOnTree.x, tile.positionOnTree.z, tile.positionOnTree.y); if (treeDir.sqrMagnitude < 0.001) { return(Quaternion.identity); } return(Quaternion.LookRotation(treeDir, Vector3.up)); } case RotationType.TreeRoundTall: { if (noise == null) { noise = new OpenSimplexNoise(); } float mainRot = (float)noise.eval(tile.position.x, tile.position.y, tile.position.z); Vector3 smallRot = new Vector3((float)noise.eval(tile.position.x, tile.position.y, tile.position.z * 17), (float)noise.eval(tile.position.x * 17, tile.position.y, tile.position.z), 0); Vector3 treeDir = new Vector3(-tile.positionOnTree.x, tile.positionOnTree.z / 2.0f, tile.positionOnTree.y); if (treeDir.sqrMagnitude < 0.001) { return(Quaternion.identity); } return(Quaternion.LookRotation(treeDir, Vector3.up) * Quaternion.Euler(smallRot * 15) * Quaternion.AngleAxis(mainRot * 360.0f, Vector3.back)); } default: return(Quaternion.identity); } }
public Quaternion GetRotation(MapDataStore.Tile tile) { return(TranslateRotation(rotationType, tile)); }
void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent content = null; if (!contentLoader.TileMeshConfiguration.GetValue(tile, layer, out content)) { buffer.meshData = null; return; } buffer.meshData = content.meshData[(int)layer]; buffer.transform = Matrix4x4.TRS(GameMap.DFtoUnityCoord(tile.position), Quaternion.identity, Vector3.one); Matrix4x4 shapeTextTransform = Matrix4x4.identity; NormalContent tileTexContent; if (contentLoader.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; } Matrix4x4 matTexTransform = Matrix4x4.identity; TextureContent matTexContent; if (contentLoader.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; } ColorContent newColorContent; Color newColor; if (contentLoader.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat; mat.mat_type = -1; mat.mat_index = -1; switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: break; case MeshLayer.Growth0Cutout: break; case MeshLayer.Growth1Cutout: break; case MeshLayer.Growth2Cutout: break; case MeshLayer.Growth3Cutout: break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.grey; } } buffer.color = newColor; buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.hiddenFaces = MeshCombineUtility.HiddenFaces.None; if (tile.North != null && tile.North.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.North; } if (tile.South != null && tile.South.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.South; } if (tile.East != null && tile.East.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.East; } if (tile.West != null && tile.West.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.West; } if (tile.Up != null && tile.Up.Value.isSolidBase) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Up; } if (tile.Down != null && tile.Down.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Down; } }
abstract public bool GetValue(MapDataStore.Tile tile, MeshLayer layer, out T value);
void GenerateSpatterTexture(int z) { UnityEngine.Profiling.Profiler.BeginSample("GenerateSpatterTexture", this); Color[] textureColors = new Color[MapDataStore.MapSize.x * MapDataStore.MapSize.y]; for (int x = 0; x < MapDataStore.MapSize.x; x++) for (int y = 0; y < MapDataStore.MapSize.y; y++) { var tile = MapDataStore.Main[x, y, z]; if (tile == null) continue; if (tile.spatters == null || tile.spatters.Count == 0) continue; if (tile.Hidden) continue; Color totalColor = new Color(0, 0, 0, 0); float totalAmount = 0; int index = x + (y * MapDataStore.MapSize.x); foreach (var spatter in tile.spatters) { if (spatter.amount == 0) continue; MapDataStore.Tile fakeTile = new MapDataStore.Tile(null, new DFCoord(0, 0, 0)); fakeTile.material = spatter.material; Color color = Color.white; ColorContent cont; if (spatter.material.mat_type == (int)MatBasic.ICE && spatter.state == MatterState.Powder) { color = Color.white; } else if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out cont)) { color = cont.color; } else if (materials.ContainsKey(spatter.material)) { var colorDef = materials[spatter.material].state_color; color = new Color32((byte)colorDef.red, (byte)colorDef.green, (byte)colorDef.blue, 255); } float amount = spatter.amount; if (spatter.item != null) amount /= 3000; else amount /= 100; //amount = Mathf.Clamp01(amount); color *= amount; color.a = amount; totalColor += color; totalAmount += amount; } if (totalAmount > 1) { totalColor /= totalAmount; } textureColors[index] = totalColor; } if (spatterLayers[z] == null) { spatterLayers[z] = new Texture2D(MapDataStore.MapSize.x, MapDataStore.MapSize.y); spatterLayers[z].wrapMode = TextureWrapMode.Clamp; } if (spatterLayers[z].width != MapDataStore.MapSize.x || spatterLayers[z].height != MapDataStore.MapSize.y) spatterLayers[z].Resize(MapDataStore.MapSize.x, MapDataStore.MapSize.y); spatterLayers[z].SetPixels(textureColors); spatterLayers[z].Apply(); UnityEngine.Profiling.Profiler.EndSample(); }
public override bool GetValue(MapDataStore.Tile tile, MeshLayer layer, out T value) { value = content.GetValue(tile, layer); return(true); }
void GenerateMesh() { if (width == 1 && height == 1) { return; } int length = width * height * 4; List <Vector3> vertices = new List <Vector3>(length); List <Color> colors = new List <Color>(length); List <Vector2> uvs = new List <Vector2>(length); List <Vector2> uv2s = new List <Vector2>(length); List <int> triangles = new List <int>(length); List <Vector3> waterVerts = new List <Vector3>(); List <Vector2> waterUvs = new List <Vector2>(); List <int> waterTris = new List <int>(); foreach (MeshFilter mf in terrainChunks) { if (mf.mesh != null) { mf.mesh.Clear(); } } foreach (MeshFilter mf in waterChunks) { if (mf.mesh != null) { mf.mesh.Clear(); } } int chunkIndex = 0; int waterChunkIndex = 0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (DetailRegions.ContainsKey(new DFCoord2d(x, y))) { continue; } //If the vertex lists are already full, make a chunk with what we have, and keep going if (vertices.Count >= (65535 - 20)) { if (terrainChunks.Count <= chunkIndex) { terrainChunks.Add(Instantiate <MeshFilter>(terrainPrefab)); terrainChunks[chunkIndex].transform.parent = transform; terrainChunks[chunkIndex].gameObject.name = "TerrainChunk" + chunkIndex; } MeshFilter mf = terrainChunks[chunkIndex]; if (mf.mesh == null) { mf.mesh = new Mesh(); } Mesh terrainMesh = mf.mesh; terrainMesh.vertices = vertices.ToArray(); terrainMesh.colors = colors.ToArray(); terrainMesh.uv = uvs.ToArray(); terrainMesh.uv2 = uv2s.ToArray(); terrainMesh.triangles = triangles.ToArray(); terrainMesh.RecalculateNormals(); terrainMesh.RecalculateTangents(); mf.mesh = terrainMesh; vertices.Clear(); colors.Clear(); uvs.Clear(); uv2s.Clear(); triangles.Clear(); chunkIndex++; } //If the vertex lists are already full, make a chunk with what we have, and keep going if (waterVerts.Count >= (65535 - 20)) { if (waterChunks.Count <= waterChunkIndex) { waterChunks.Add(Instantiate <MeshFilter>(waterPrefab)); waterChunks[waterChunkIndex].transform.parent = transform; waterChunks[waterChunkIndex].gameObject.name = "WaterChunk" + waterChunkIndex; } MeshFilter mf = waterChunks[waterChunkIndex]; if (mf.mesh == null) { mf.mesh = new Mesh(); } Mesh waterMesh = mf.mesh; waterMesh.vertices = waterVerts.ToArray(); waterMesh.uv = waterUvs.ToArray(); waterMesh.triangles = waterTris.ToArray(); waterMesh.RecalculateNormals(); waterMesh.RecalculateTangents(); mf.mesh = waterMesh; waterVerts.Clear(); waterUvs.Clear(); waterTris.Clear(); waterChunkIndex++; } MapDataStore.Tile fakeTile = new MapDataStore.Tile(null, new DFCoord(0, 0, 0)); fakeTile.material = regionTiles[x, y].surface_material; ColorContent colorContent; ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent); Color terrainColor = colorContent.value; Color plantColor = Color.black; float grassPercent = Mathf.Pow(regionTiles[x, y].vegetation / 100.0f, 0.25F); float treePercent = Mathf.Pow(regionTiles[x, y].vegetation / 100.0f, 0.5F); foreach (var item in regionTiles[x, y].plant_materials) { fakeTile.material = item; ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent); plantColor += colorContent.value; } if (regionTiles[x, y].plant_materials.Count == 0) { grassPercent = 0; } else { plantColor /= regionTiles[x, y].plant_materials.Count; } Color treeColor = Color.black; int treeCount = 0; foreach (var tree in regionTiles[x, y].tree_materials) { int plantIndex = tree.mat_index; if (tree.mat_type != 419 || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex) { continue; } var treeMat = tree; foreach (var growth in DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths) { int currentTicks = TimeHolder.DisplayedTime.CurrentYearTicks; if ((growth.timing_start != -1 && growth.timing_start > currentTicks) || (growth.timing_end != -1 && growth.timing_end < currentTicks)) { continue; } treeMat = growth.mat; break; } fakeTile.material = treeMat; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorContent)) { treeColor += colorContent.value; treeCount++; } } if (treeCount == 0) { treePercent = 0; } else { treeColor /= treeCount; } terrainColor = Color.Lerp(terrainColor, plantColor, grassPercent); terrainColor = Color.Lerp(terrainColor, treeColor, treePercent); Vector2 biome = new Vector2(regionTiles[x, y].rainfall, 100 - regionTiles[x, y].drainage) / 100; Vector3 vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; Vector3 vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddHorizontalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, triangles); if (regionTiles[x, y].elevation < regionTiles[x, y].water_elevation) { vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].water_elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].water_elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddHorizontalQuad(vert1, vert2, biome, terrainColor, waterVerts, null, waterUvs, null, waterTris); } int north = 0; if (y > 0 && !DetailRegions.ContainsKey(new DFCoord2d(x, y - 1))) { north = regionTiles[x, y - 1].elevation; } if (north < regionTiles[x, y].elevation) { vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, north * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, triangles); } int south = 0; if (y < height - 1 && !DetailRegions.ContainsKey(new DFCoord2d(x, y + 1))) { south = regionTiles[x, y + 1].elevation; } if (south < regionTiles[x, y].elevation) { vert1 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; vert2 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, south * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, triangles); } int east = 0; if (x < width - 1 && !DetailRegions.ContainsKey(new DFCoord2d(x + 1, y))) { east = regionTiles[x + 1, y].elevation; } if (east < regionTiles[x, y].elevation) { vert1 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; vert2 = (new Vector3((x + 1) * 48 * 16 * GameMap.tileWidth, east * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, triangles); } int west = 0; if (x > 0 && !DetailRegions.ContainsKey(new DFCoord2d(x - 1, y))) { west = regionTiles[x - 1, y].elevation; } if (west < regionTiles[x, y].elevation) { vert1 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, regionTiles[x, y].elevation * GameMap.tileHeight, -(y + 1) * 48 * 16 * GameMap.tileWidth) + offset) * scale; vert2 = (new Vector3(x * 48 * 16 * GameMap.tileWidth, west * GameMap.tileHeight, -y * 48 * 16 * GameMap.tileWidth) + offset) * scale; RegionMaker.AddVerticalQuad(vert1, vert2, biome, terrainColor, vertices, colors, uvs, uv2s, triangles); } } } { if (terrainChunks.Count <= chunkIndex) { terrainChunks.Add(Instantiate <MeshFilter>(terrainPrefab)); terrainChunks[chunkIndex].transform.parent = transform; terrainChunks[chunkIndex].gameObject.name = "TerrainChunk" + chunkIndex; } MeshFilter mf = terrainChunks[chunkIndex]; if (mf.mesh == null) { mf.mesh = new Mesh(); } Mesh terrainMesh = mf.mesh; terrainMesh.vertices = vertices.ToArray(); terrainMesh.colors = colors.ToArray(); terrainMesh.uv = uvs.ToArray(); terrainMesh.uv2 = uv2s.ToArray(); terrainMesh.triangles = triangles.ToArray(); terrainMesh.RecalculateNormals(); terrainMesh.RecalculateTangents(); mf.mesh = terrainMesh; } { if (waterChunks.Count <= waterChunkIndex) { waterChunks.Add(Instantiate <MeshFilter>(waterPrefab)); waterChunks[waterChunkIndex].transform.parent = transform; waterChunks[waterChunkIndex].gameObject.name = "WaterChunk" + waterChunkIndex; } MeshFilter mf = waterChunks[waterChunkIndex]; if (mf.mesh == null) { mf.mesh = new Mesh(); } Mesh waterMesh = mf.mesh; waterMesh.vertices = waterVerts.ToArray(); waterMesh.uv = waterUvs.ToArray(); waterMesh.triangles = waterTris.ToArray(); waterMesh.RecalculateNormals(); waterMesh.RecalculateTangents(); mf.mesh = waterMesh; waterVerts.Clear(); waterUvs.Clear(); waterTris.Clear(); waterChunkIndex++; } }
void GenerateMesh() { int h = height - 1; int w = width - 1; vertices.Clear(); colors.Clear(); uvCoords.Clear(); uvCoords2.Clear(); uvCoords3.Clear(); triangles.Clear(); waterVerts.Clear(); waterUvs.Clear(); waterTris.Clear(); DFCoord fortMin = DFConnection.Instance.EmbarkMapPosition - regionOrigin; DFCoord fortMax = fortMin + (DFConnection.Instance.EmbarkMapSize / 3); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { if (IsInCoords(fortMin, fortMax, x, y)) continue; RegionTile tile = tiles[x, y]; if (tile == null) continue; bool snow = tile.snow > 0; Vector2 biome = new Vector2(tile.rainfall, 100 - tile.drainage) / 100; Vector3 vert1 = new Vector3(x * 48 * GameMap.tileWidth, tile.elevation * GameMap.tileHeight, -y * 48 * GameMap.tileWidth); Sides riverSides = 0; if (tile.rivers != null) { if (tile.rivers.north.min_pos >= 0) riverSides |= Sides.North; if (tile.rivers.east.min_pos >= 0) riverSides |= Sides.East; if (tile.rivers.south.min_pos >= 0) riverSides |= Sides.South; if (tile.rivers.west.min_pos >= 0) riverSides |= Sides.West; } int north = 0; if (y > 0 && !IsInCoords(fortMin, fortMax, x, y - 1)) north = tiles[x, y - 1].elevation; int south = 0; if (y < h - 1 && !IsInCoords(fortMin, fortMax, x, y + 1)) south = tiles[x, y + 1].elevation; int east = 0; if (x < w - 1 && !IsInCoords(fortMin, fortMax, x + 1, y)) east = tiles[x + 1, y].elevation; int west = 0; if (x > 0 && !IsInCoords(fortMin, fortMax, x - 1, y)) west = tiles[x - 1, y].elevation; MapDataStore.Tile fakeTile = new MapDataStore.Tile(null, new DFCoord(0, 0, 0)); fakeTile.material = tile.surfaceMaterial; Color terrainColor = Color.green; ColorContent colorDef; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) terrainColor = colorDef.color; Color plantColor = Color.black; Color stoneColor = Color.grey; foreach (var item in tile.plantMaterials) { fakeTile.material = item; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) plantColor += colorDef.color; } float plantBlend = Mathf.Pow(tile.vegetation / 100.0f, 0.25f); if (tile.plantMaterials.Count == 0) plantBlend = 0; else plantColor /= tile.plantMaterials.Count; if (tile.stoneMaterials.Count > 0) { fakeTile.material = tile.stoneMaterials[0]; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) stoneColor = colorDef.color; } Color blendedColor = Color.Lerp(terrainColor, plantColor, plantBlend); if (riverSides == 0) AddFlatTile(vert1, biome, north * GameMap.tileHeight, east * GameMap.tileHeight, south * GameMap.tileHeight, west * GameMap.tileHeight, tile.water_elevation, blendedColor, snow); else { AddRiverTile(riverSides, tile.rivers, vert1, biome, north * GameMap.tileHeight, east * GameMap.tileHeight, south * GameMap.tileHeight, west * GameMap.tileHeight, blendedColor, snow); } if (GameSettings.Instance.rendering.distantTerrainDetail == GameSettings.LandscapeDetail.High) { foreach (SiteRealizationBuilding building in tile.buildings) { Vector3 min, max; switch (building.type) { case SiteRealizationBuildingType.cottage_plot: case SiteRealizationBuildingType.castle_courtyard: case SiteRealizationBuildingType.house: case SiteRealizationBuildingType.temple: case SiteRealizationBuildingType.shop_house: case SiteRealizationBuildingType.warehouse: case SiteRealizationBuildingType.well: case SiteRealizationBuildingType.vault: case SiteRealizationBuildingType.hillock_house: case SiteRealizationBuildingType.mead_hall: case SiteRealizationBuildingType.fortress_entrance: case SiteRealizationBuildingType.library: case SiteRealizationBuildingType.tavern: { fakeTile.material = building.material; Color buildingColor; ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef); if (colorDef != null) buildingColor = colorDef.color; else { Debug.LogError("No valid color for " + building.type); buildingColor = Color.magenta; } min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 2 * GameMap.tileHeight, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, buildingColor, snow); break; } case SiteRealizationBuildingType.courtyard: case SiteRealizationBuildingType.market_square: case SiteRealizationBuildingType.waste: { min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 1 * GameMap.tileHeight / 6.0f, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, terrainColor, snow); break; } case SiteRealizationBuildingType.pasture: { min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 1 * GameMap.tileHeight / 6.0f, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, plantColor, snow); break; } case SiteRealizationBuildingType.trenches: { int mid_x = (building.min_x + building.max_x) / 2; int mid_y = (building.min_y + building.max_y) / 2; min = new Vector3((mid_x - 1) * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((mid_x + 2) * GameMap.tileWidth, 1 * GameMap.tileHeight / 6.0f, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, Color.black, snow); min = new Vector3(building.min_x * GameMap.tileWidth, 0, -(mid_y - 1) * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 1 * GameMap.tileHeight / 6.0f, -(mid_y + 2) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, Color.black, snow); break; } case SiteRealizationBuildingType.great_tower: { fakeTile.material = building.material; Color buildingColor; if(ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) buildingColor = colorDef.color; else { Debug.LogError("No valid color for " + building.type); buildingColor = Color.magenta; } min = new Vector3((building.min_x + 5) * GameMap.tileWidth, 0, -(building.min_y + 5) * GameMap.tileWidth); max = new Vector3((building.max_x - 4) * GameMap.tileWidth, 15 * GameMap.tileHeight, -(building.max_y - 4) * GameMap.tileWidth); AddCylinder(vert1 + min, vert1 + max, biome, buildingColor, snow); break; } case SiteRealizationBuildingType.castle_tower: { fakeTile.material = building.material; Color buildingColor; Color roofColor; if(ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) { buildingColor = colorDef.color; roofColor = colorDef.color; } else { buildingColor = stoneColor; roofColor = terrainColor; } int top = 2; if (building.tower_info != null) { if (building.tower_info.goblin) { top = 11; } else { top = building.tower_info.roof_z; top -= tile.elevation; } } min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, top * GameMap.tileHeight, -(building.max_y + 1) * GameMap.tileWidth); if (building.tower_info != null && building.tower_info.round) AddCylinder(vert1 + min, vert1 + max, biome, buildingColor, snow, roofColor); else AddBlock(vert1 + min, vert1 + max, biome, buildingColor, snow, roofColor); break; } case SiteRealizationBuildingType.castle_wall: { fakeTile.material = building.material; Color buildingColor; if(ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) buildingColor = colorDef.color; else { buildingColor = Color.magenta; } if (building.wall_info != null) { min = new Vector3((building.wall_info.start_x + 1) * GameMap.tileWidth, (building.wall_info.start_z - tile.elevation) * GameMap.tileHeight, -(building.wall_info.start_y + 1) * GameMap.tileWidth); max = new Vector3((building.wall_info.end_x + 1) * GameMap.tileWidth, 0, -(building.wall_info.end_y + 1) * GameMap.tileWidth); AddWall(vert1 + min, vert1 + max, 4 * GameMap.tileWidth, biome, buildingColor, snow); } else { min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 2 * GameMap.tileHeight, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, Color.black, snow); } break; } case SiteRealizationBuildingType.tomb: { fakeTile.material = building.material; if (fakeTile.material.mat_type < 0) fakeTile.material = new MatPairStruct(0, fakeTile.material.mat_index); Color buildingColor; if(ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) buildingColor = colorDef.color; else buildingColor = Color.grey; min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); int tombHeight = (building.max_x - building.min_x + building.max_y - building.min_y) / 8; max = new Vector3((building.max_x + 1) * GameMap.tileWidth, tombHeight * GameMap.tileHeight, -(building.max_y + 1) * GameMap.tileWidth); AddPyramid(vert1 + min, vert1 + max, biome, buildingColor, snow); break; } case SiteRealizationBuildingType.tree_house: { var tree = building.material; int plantIndex = tree.mat_index; if (tree.mat_type >= 419 && tree.mat_type < 619 && DFConnection.Instance.NetPlantRawList != null && DFConnection.Instance.NetPlantRawList.plant_raws.Count > plantIndex) foreach (var growth in DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths) { int currentTicks = TimeHolder.DisplayedTime.CurrentYearTicks; if ((growth.timing_start != -1 && growth.timing_start > currentTicks) || (growth.timing_end != -1 && growth.timing_end < currentTicks)) continue; tree = growth.mat; break; } fakeTile.material = tree; Color buildingColor; if(ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) buildingColor = colorDef.color; else { Debug.LogError("No valid color for " + building.type); buildingColor = Color.magenta; } Vector3 pos = new Vector3((building.min_x + building.max_x + 1) / 2.0f, 0, -(building.min_y + building.max_y + 1) / 2.0f) * GameMap.tileWidth; float treeRadius = (building.max_x - building.min_x + building.max_y - building.min_y) / 4.0f * GameMap.tileWidth * 1.28676f; if (tree.mat_type == 419) // bare tree AddTree(vert1+pos, GameMap.tileWidth / 2, Random.Range(9.0f, 11.0f) * GameMap.tileHeight, buildingColor, biome, snow, Random.Range(0.0f, 360.0f)); else AddTree(vert1 + pos, treeRadius, Random.Range(9.0f, 11.0f) * GameMap.tileHeight, buildingColor, biome, snow, Random.Range(0.0f, 360.0f)); break; } default: { min = new Vector3(building.min_x * GameMap.tileWidth, 0, -building.min_y * GameMap.tileWidth); max = new Vector3((building.max_x + 1) * GameMap.tileWidth, 13 * GameMap.tileHeight / 6.0f, -(building.max_y + 1) * GameMap.tileWidth); AddBlock(vert1 + min, vert1 + max, biome, Color.magenta, snow); break; } } } Random.InitState(new DFCoord2d(x+regionOrigin.x, y+regionOrigin.y).GetHashCode()); if (tile.buildings.Count == 0 && tile.treeMaterials.Count > 0) { float treeRadius = 4f * GameMap.tileWidth; var treeCoords = UniformPoissonDiskSampler.SampleRectangle(new Vector2(vert1.x + treeRadius, vert1.z - 48 * GameMap.tileWidth + treeRadius), new Vector2(vert1.x + 48 * GameMap.tileWidth - treeRadius, vert1.z - treeRadius), (Mathf.Lerp(48.0f, 8.0f, Mathf.Pow(tile.vegetation / 100.0f, 0.5f))) * GameMap.tileWidth); foreach (var coord in treeCoords) { var tree = tile.treeMaterials[Random.Range(0, tile.treeMaterials.Count - 1)]; int plantIndex = tree.mat_index; if (tree.mat_type != 419 || DFConnection.Instance.NetPlantRawList == null || DFConnection.Instance.NetPlantRawList.plant_raws.Count <= plantIndex) continue; foreach (var growth in DFConnection.Instance.NetPlantRawList.plant_raws[plantIndex].growths) { int currentTicks = TimeHolder.DisplayedTime.CurrentYearTicks; if ((growth.timing_start != -1 && growth.timing_start > currentTicks) || (growth.timing_end != -1 && growth.timing_end < currentTicks)) continue; tree = growth.mat; break; } Color treeColor = Color.green; fakeTile.material = tree; if (ContentLoader.Instance.ColorConfiguration.GetValue(fakeTile, MeshLayer.StaticMaterial, out colorDef)) treeColor = colorDef.color; if (tree.mat_type == 419) // bare tree AddTree(new Vector3(coord.x, tile.elevation * GameMap.tileHeight, coord.y), GameMap.tileWidth / 2, Random.Range(7.0f, 9.0f) * GameMap.tileHeight, treeColor, biome, snow, Random.Range(0.0f, 360.0f)); else AddTree(new Vector3(coord.x, tile.elevation * GameMap.tileHeight, coord.y), treeRadius, Random.Range(7.0f, 9.0f) * GameMap.tileHeight, treeColor, biome, snow, Random.Range(0.0f, 360.0f)); } } } if (vertices.Count >= (65535 - 20)) break; } if (vertices.Count >= (65535 - 20)) break; } terrainMesh = new Mesh(); terrainMesh.vertices = vertices.ToArray(); terrainMesh.colors = colors.ToArray(); terrainMesh.uv = uvCoords.ToArray(); terrainMesh.uv2 = uvCoords2.ToArray(); terrainMesh.uv3 = uvCoords3.ToArray(); terrainMesh.triangles = triangles.ToArray(); terrainMesh.RecalculateNormals(); terrainMesh.RecalculateTangents(); meshFilter.mesh = terrainMesh; if(waterVerts.Count > 0) { if (waterChunk == null) { waterChunk = Instantiate(parentMap.regionWaterPrefab); waterChunk.transform.parent = transform; waterChunk.gameObject.name = "Water "; waterChunk.transform.localPosition = Vector3.zero; } if (waterChunk.mesh == null) waterChunk.mesh = new Mesh(); Mesh waterMesh = waterChunk.mesh; waterMesh.Clear(); waterMesh.vertices = waterVerts.ToArray(); waterMesh.uv = waterUvs.ToArray(); waterMesh.triangles = waterTris.ToArray(); waterMesh.RecalculateNormals(); waterMesh.RecalculateTangents(); waterChunk.mesh = waterMesh; waterVerts.Clear(); waterUvs.Clear(); waterTris.Clear(); } }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); Vector2 index1 = Vector2.zero; Vector2 index2 = Vector2.zero; MeshContent meshContent = null; buffer.color = Color.grey; if (layer == MeshLayer.Collision) { if (!ContentLoader.Instance.CollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) { buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; } else if (meshContent.MeshData.ContainsKey(MeshLayer.StaticMaterial)) { buffer.meshData = meshContent.MeshData[MeshLayer.StaticMaterial]; } else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } //if (layer == MeshLayer.BuildingCollision) //{ // if (tile.buildingType == default(BuildingStruct) || !ContentLoader.Instance.BuildingCollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) // { // buffer.meshData = null; // return; // } // if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) // buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterial)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterial]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialCutout)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialCutout]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialTransparent)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialTransparent]; // else // { // buffer.meshData = null; // return; // } // buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); // buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); // return; //} if (ContentLoader.Instance.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); if (TextureStorage.UsingArray) { if (meshContent.MaterialTexture != null) { index1.x = meshContent.MaterialTexture.ArrayIndex; } else { index1.x = ContentLoader.Instance.DefaultMatTexArrayIndex; } if (meshContent.ShapeTexture != null) { index1.y = meshContent.ShapeTexture.ArrayIndex; } else { index1.y = ContentLoader.Instance.DefaultShapeTexArrayIndex; } if (meshContent.SpecialTexture != null) { index2.x = meshContent.SpecialTexture.ArrayIndex; } else { index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { if (meshContent.MaterialTexture != null) { buffer.uv1Transform = meshContent.MaterialTexture.UVTransform; } else { buffer.uv1Transform = ContentLoader.Instance.DefaultMatTexTransform; } if (meshContent.ShapeTexture != null) { buffer.uv2Transform = meshContent.ShapeTexture.UVTransform; } else { buffer.uv2Transform = ContentLoader.Instance.DefaultShapeTexTransform; } if (meshContent.SpecialTexture != null) { buffer.uv3Transform = meshContent.SpecialTexture.UVTransform; } else { buffer.uv3Transform = ContentLoader.Instance.DefaultSpecialTexTransform; } } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!ContentLoader.Instance.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; //case MeshLayer.BuildingMaterial: //case MeshLayer.NoMaterialBuilding: //case MeshLayer.BuildingMaterialCutout: //case MeshLayer.NoMaterialBuildingCutout: //case MeshLayer.BuildingMaterialTransparent: //case MeshLayer.NoMaterialBuildingTransparent: // { // if (tile.buildingType == default(BuildingStruct)) // { // buffer.meshData = null; // return; // } // if (!ContentLoader.Instance.BuildingMeshConfiguration.GetValue(tile, layer, out meshContent)) // { // buffer.meshData = null; // return; // } // } // break; default: { if (layer == MeshLayer.NaturalTerrain) { if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.HandleShape(tile) && !VoxelGenerator.UseBoth(tile)) { layer = MeshLayer.StaticMaterial; } else { buffer.meshData = null; return; } } else if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.UseBoth(tile)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 matTexTransform = ContentLoader.Instance.DefaultMatTexTransform; Matrix4x4 shapeTextTransform = ContentLoader.Instance.DefaultShapeTexTransform; Matrix4x4 specialTexTransform = Matrix4x4.identity; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { //if (layer == MeshLayer.BuildingMaterial // || layer == MeshLayer.BuildingMaterialCutout // || layer == MeshLayer.NoMaterialBuilding // || layer == MeshLayer.NoMaterialBuildingCutout // || layer == MeshLayer.BuildingMaterialTransparent // || layer == MeshLayer.NoMaterialBuildingTransparent // ) //{ // if (ContentLoader.Instance.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) // { // shapeTextTransform = tileTexContent.UVTransform; // index1.y = tileTexContent.ArrayIndex; // } //} //else { if (ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; index1.y = meshContent.ShapeTexture.ArrayIndex; } if (meshContent.MaterialTexture != null && (layer == MeshLayer.NoMaterial //|| layer == MeshLayer.NoMaterialBuilding //|| layer == MeshLayer.NoMaterialBuildingCutout //|| layer == MeshLayer.NoMaterialBuildingTransparent || layer == MeshLayer.NoMaterialCutout || layer == MeshLayer.NoMaterialTransparent)) { matTexTransform = meshContent.MaterialTexture.UVTransform; index1.x = meshContent.MaterialTexture.ArrayIndex; } else { TextureContent matTexContent; if (ContentLoader.Instance.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; index1.x = matTexContent.ArrayIndex; } } if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; index2.x = meshContent.SpecialTexture.ArrayIndex; } else { specialTexTransform = ContentLoader.Instance.DefaultSpecialTexTransform; index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } ColorContent newColorContent; Color newColor; if (ContentLoader.Instance.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.color; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: //case MeshLayer.NoMaterialBuildingCutout: //case MeshLayer.NoMaterialBuilding: //case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; //case MeshLayer.BuildingMaterial: //case MeshLayer.BuildingMaterialCutout: //case MeshLayer.BuildingMaterialTransparent: // mat = tile.buildingMaterial; // break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.grey; } } buffer.color = newColor; if (TextureStorage.UsingArray) { buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.uv3Transform = specialTexTransform; } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); }