private bool CanFungusGrowOn(int t, int h, int b, VoxelInfo[, ,] neighbourhood) { bool res = false; if (t < 2) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t + 1, h, b].Type); } if (t > 0) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t - 1, h, b].Type); } if (h < 2) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t, h + 1, b].Type); } if (h > 0) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t, h - 1, b].Type); } if (b < 2) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t, h, b + 1].Type); } if (b > 0) { res = res || TypeInformation.CanFungusGrowOn(neighbourhood[t, h, b - 1].Type); } return(res); }
bool CanPlace(int t, int h, int b, VoxelInfo[, ,] neighbourhood) { bool res = neighbourhood[t, h, b].Type == VoxelType.EMPTY; //if (h < 2) res = res && neighbourhood[t, h + 1, b].Type != VoxelType.SPRUCE_NEEDLE; //if (h > 0) res = res && neighbourhood[t, h - 1, b].Type != VoxelType.SPRUCE_NEEDLE; return(res);// && neighbourhood[1, 1, 1].Resources < 51; }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.BEECH_WOOD)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; if (gen == 0) { // Grow 2x2 and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1, 10); output[2, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1, 10); output[1, 1, 2] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1, 10); output[2, 1, 2] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1, 10); } else if (gen == 1 && neighbourhood[1, 1, 1].Resources == 10) { // Grow Cross and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1, 0, TypeInformation.GetGrowingSteps(VoxelType.PINE_WOOD) / 2); if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY) { output[2, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1); } if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY) { output[0, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1); } if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY) { output[1, 1, 2] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1); } if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY) { output[1, 1, 0] = new VoxelInfo(VoxelType.BEECH_WOOD, true, 1); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.BEECH_WOOD)) { // Grow upwards output[1, 2, 1] = new VoxelInfo(VoxelType.BEECH_WOOD, true, gen + 1); output[1, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD); } else { // Grow upwards one last time output[1, 2, 1] = new VoxelInfo(VoxelType.BEECH_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.BEECH_WOOD); } return(output); }
bool CanPlace(int t, int h, int b, VoxelInfo[, ,] neighbourhood) { bool res = neighbourhood[t, h, b].Type == VoxelType.EMPTY; if (h < 2) { res = res && neighbourhood[t, h + 1, b].Type != VoxelType.TEAK_LEAF; } if (h > 0) { res = res && neighbourhood[t, h - 1, b].Type != VoxelType.TEAK_LEAF; } return(res && neighbourhood[1, 1, 1].Resources < 51); }
/// <summary> /// The core of the simulation. This function applies all rules to all /// living voxels. /// </summary> /// <returns>Every change which have to be made to apply the latest changes.</returns> private ConcurrentDictionary <Int32, VoxelInfo> SimulateAsync() { // There is just one map but nobody should write before all have // seen the current state -> collect all results first. ConcurrentDictionary <Int32, VoxelInfo> results = new ConcurrentDictionary <Int32, VoxelInfo>(); Parallel.ForEach(_livingVoxels, currentVoxel => //foreach( KeyValuePair<Int32, LivingVoxel> currentVoxel in _livingVoxels ) { ++currentVoxel.Value.Ticks; // Create a local window for the rule algorithms VoxelInfo[, ,] localFrame = new VoxelInfo[3, 3, 3]; IterateNeighbours((x, y, z) => { Int32 pos = _map.EncodePosition(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1); VoxelType voxel = _map.Get(pos); // Living? if (_map.IsLiving(pos)) { // Yes: query more information from the dictinary LivingVoxel voxelInfo = _livingVoxels[pos]; localFrame[z, y, x] = new VoxelInfo(voxel, true, voxelInfo.Generation, voxelInfo.Resources, voxelInfo.Ticks, voxelInfo.From); } else { // No uses directly localFrame[z, y, x] = new VoxelInfo((VoxelType)voxel); } }); // Apply the rule for currentVoxel VoxelInfo[, ,] ruleResult = TypeInformation.GetRule(localFrame[1, 1, 1].Type).ApplyRule(localFrame); if (ruleResult != null) { currentVoxel.Value.Ticks = 0; // Add changes to the change collection IterateNeighbours((x, y, z) => { if (ruleResult[z, y, x] != null && _map.IsInside(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1)) { Int32 positionCode = _map.EncodePosition(currentVoxel.Value.X + x - 1, currentVoxel.Value.Y + y - 1, currentVoxel.Value.Z + z - 1); // Two rules tried to grow at the same location. Use decision function results.AddOrUpdate(positionCode, ruleResult[z, y, x], (key, old) => GamePlayUtils.GetStrongerVoxel(ref old, ref ruleResult[z, y, x])); } }); } }); return(results); }
private Direction FoodInDirection(VoxelInfo[, ,] neighbourhood) { for (int t = 0; t < 3; ++t) { for (int h = 0; h < 3; ++h) { for (int b = 0; b < 3; ++b) { if (!(t == 1 && h == 1 && b == 1)) // if not the voxel itself { if (TypeInformation.IsBiomass(neighbourhood[t, h, b].Type)) { return(DirectionConverter.ToDirection(t, h, b)); } } } } } return(Direction.SELF); }
private Direction GetBranchDirection(VoxelInfo[, ,] neighbourhood) { if (neighbourhood[2, 1, 1].Type == VoxelType.PINE_WOOD && neighbourhood[0, 1, 1].Type == VoxelType.EMPTY) { return(DirectionConverter.ToDirection(0, 1, 1)); } if (neighbourhood[0, 1, 1].Type == VoxelType.PINE_WOOD && neighbourhood[2, 1, 1].Type == VoxelType.EMPTY) { return(DirectionConverter.ToDirection(2, 1, 1)); } if (neighbourhood[1, 1, 2].Type == VoxelType.PINE_WOOD && neighbourhood[1, 1, 0].Type == VoxelType.EMPTY) { return(DirectionConverter.ToDirection(1, 1, 0)); } if (neighbourhood[1, 1, 0].Type == VoxelType.PINE_WOOD && neighbourhood[1, 1, 2].Type == VoxelType.EMPTY) { return(DirectionConverter.ToDirection(1, 1, 2)); } return(Direction.SELF); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.OAK_WOOD)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int res = neighbourhood[1, 1, 1].Resources; if (gen == 0) { // Grow Cross and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 0, TypeInformation.GetGrowingSteps(VoxelType.OAK_WOOD) / 2); output[2, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 10); output[0, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 10); output[1, 1, 2] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 10); output[1, 1, 0] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 10); } else if (gen == 1 && res == 10) { // Grow Cross and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.OAK_WOOD) / 2); if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY) { output[2, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 20); } if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY) { output[0, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 20); } if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY) { output[1, 1, 2] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 20); } if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY) { output[1, 1, 0] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 20); } } else if (gen == 1 && res == 20) { int energy = 0; if (neighbourhood[1, 1, 0].Type != VoxelType.OAK_WOOD && neighbourhood[1, 1, 2].Type != VoxelType.OAK_WOOD) { energy = 3; if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY) { output[1, 1, 2] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1); } if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY) { output[1, 1, 0] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1); } } else if (neighbourhood[0, 1, 1].Type != VoxelType.OAK_WOOD && neighbourhood[2, 1, 1].Type != VoxelType.OAK_WOOD) { energy = 3; if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY) { output[2, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1); } if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY) { output[0, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1); } } output[1, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 2, energy, TypeInformation.GetGrowingSteps(VoxelType.OAK_WOOD) / 4); } else if (res == 4 && gen < 5) { if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY && neighbourhood[0, 1, 1].Type == VoxelType.OAK_WOOD) { output[2, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, gen < 4, gen + 1, res); } if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY && neighbourhood[2, 1, 1].Type == VoxelType.OAK_WOOD) { output[0, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, gen < 4, gen + 1, res); } if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY && neighbourhood[1, 1, 0].Type == VoxelType.OAK_WOOD) { output[1, 1, 2] = new VoxelInfo(VoxelType.OAK_WOOD, gen < 4, gen + 1, res); } if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY && neighbourhood[1, 1, 2].Type == VoxelType.OAK_WOOD) { output[1, 1, 0] = new VoxelInfo(VoxelType.OAK_WOOD, gen < 4, gen + 1, res); } /*if (!(gen < 4)) * { * if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY && neighbourhood[0, 1, 1].Type == VoxelType.OAK_WOOD) * output[2, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen, res); * if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY && neighbourhood[2, 1, 1].Type == VoxelType.OAK_WOOD) * output[0, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen, res); * if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY && neighbourhood[1, 1, 0].Type == VoxelType.OAK_WOOD) * output[1, 1, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen, res); * if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY && neighbourhood[1, 1, 2].Type == VoxelType.OAK_WOOD) * output[1, 1, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen, res); * }*/ } else if (gen < TypeInformation.GetGrowHeight(VoxelType.OAK_WOOD)) { // Grow upwards output[1, 2, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, gen + 1, res); output[1, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD); if (res == 3 && gen > TypeInformation.GetGrowHeight(VoxelType.OAK_WOOD) / 2 && random.Next(0, 11) > 6) { if (neighbourhood[2, 1, 1].Type == VoxelType.EMPTY) { output[2, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 4); } if (neighbourhood[0, 1, 1].Type == VoxelType.EMPTY) { output[0, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 4); } if (neighbourhood[1, 1, 2].Type == VoxelType.EMPTY) { output[1, 1, 2] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 4); } if (neighbourhood[1, 1, 0].Type == VoxelType.EMPTY) { output[1, 1, 0] = new VoxelInfo(VoxelType.OAK_WOOD, true, 1, 4); } } } else { // Grow upwards one last time output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true); output[1, 1, 1] = new VoxelInfo(VoxelType.OAK_WOOD); } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_NEEDLE)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int res = neighbourhood[1, 1, 1].Resources; if (gen == 0) { output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 2, 1].Type) || neighbourhood[1, 2, 1].Type == VoxelType.EMPTY) { output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, -1, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_NEEDLE) / 2); } if (CanPlace(2, 1, 1, neighbourhood)) { output[2, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, 1); } if (CanPlace(0, 1, 1, neighbourhood)) { output[0, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, 1); } if (CanPlace(1, 1, 2, neighbourhood)) { output[1, 1, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, 1); } if (CanPlace(1, 1, 0, neighbourhood)) { output[1, 1, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, 1); } } else if (gen == -1) { output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 2, 1].Type) || neighbourhood[1, 2, 1].Type == VoxelType.EMPTY) { output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.SPRUCE_NEEDLE) && gen % 3 == 1) { // Grow to the side //output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, gen + 1); //output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); if (CanPlace(2, 0, 2, neighbourhood)) { output[2, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(1, 0, 2, neighbourhood)) { output[1, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(0, 0, 2, neighbourhood)) { output[0, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(0, 0, 1, neighbourhood)) { output[0, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(1, 0, 1, neighbourhood)) { output[1, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(2, 0, 1, neighbourhood)) { output[2, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(1, 0, 0, neighbourhood)) { output[1, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } if (CanPlace(2, 0, 0, neighbourhood)) { output[2, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.SPRUCE_NEEDLE)) { // Grow to the side //output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, gen + 1); //output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); if (CanPlace(1, 0, 1, neighbourhood)) { output[1, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + 1, 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); } /*if (CanPlace(1, 0, 2, neighbourhood)) * output[1, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(0, 0, 2, neighbourhood)) * output[0, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(0, 0, 1, neighbourhood)) * output[0, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(1, 0, 1, neighbourhood)) * output[1, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(2, 0, 1, neighbourhood)) * output[2, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(1, 0, 0, neighbourhood)) * output[1, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE))); * if (CanPlace(2, 0, 0, neighbourhood)) * output[2, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true, gen + random.Next(1, 3), 0, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.PINE_NEEDLE)));*/ } else { // Grow upwards one last time //output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE); } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; if (gen == 0) { // Grow 3x3 and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 1, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 2); output[2, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4); output[0, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4); output[1, 1, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4); output[1, 1, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4); output[2, 1, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2); output[2, 1, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2); output[0, 1, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2); output[0, 1, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 1].Type) || neighbourhood[2, 0, 1].Type == VoxelType.EMPTY) { output[2, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[0, 0, 1].Type) || neighbourhood[0, 0, 1].Type == VoxelType.EMPTY) { output[0, 0, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 2].Type) || neighbourhood[1, 0, 2].Type == VoxelType.EMPTY) { output[1, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 0].Type) || neighbourhood[1, 0, 0].Type == VoxelType.EMPTY) { output[1, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, TypeInformation.GetGrowingSteps(VoxelType.SPRUCE_WOOD) / 4, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 2].Type) || neighbourhood[2, 0, 2].Type == VoxelType.EMPTY) { output[2, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 0].Type) || neighbourhood[2, 0, 0].Type == VoxelType.EMPTY) { output[2, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[0, 0, 2].Type) || neighbourhood[0, 0, 2].Type == VoxelType.EMPTY) { output[0, 0, 2] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[0, 0, 0].Type) || neighbourhood[0, 0, 0].Type == VoxelType.EMPTY) { output[0, 0, 0] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, 2, 0, 0, Direction.UP); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.SPRUCE_WOOD)) { // Grow upwards // Grow in given direction Int3 coord = DirectionConverter.FromDirection(DirectionConverter.ToOppositeDirection(neighbourhood[1, 1, 1].From)); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[coord.X, coord.Y, coord.Z].Type) || neighbourhood[coord.X, coord.Y, coord.Z].Type == VoxelType.EMPTY) { output[coord.X, coord.Y, coord.Z] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, gen + 1, 0, 0, neighbourhood[1, 1, 1].From); } //output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD, true, gen + 1); output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD); } else { // Grow upwards one last time //output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD); if (neighbourhood[1, 1, 1].From != Direction.UP) { output[1, 2, 1] = new VoxelInfo(VoxelType.SPRUCE_NEEDLE, true); } output[1, 1, 1] = new VoxelInfo(VoxelType.SPRUCE_WOOD); } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.NOBLEROT_FUNGUS)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int min = 0;// TypeInformation.GetGrowingSteps(VoxelType.NOBLEROT_FUNGUS) / 2; int max = TypeInformation.GetGrowingSteps(VoxelType.NOBLEROT_FUNGUS) / 2; int growadd; if (gen == 0) { int fung = 0; VoxelType voxeltype; // check the neighbourhood for (int t = 0; t < 3; ++t) { for (int h = 0; h < 3; ++h) { for (int b = 0; b < 3; ++b) { if (!(t == 1 && h == 1 && b == 1)) // if not the voxel itself { voxeltype = neighbourhood[t, h, b].Type; if ((TypeInformation.IsBiomass(voxeltype) || // there is a voxel in which the fungus can grow voxeltype == VoxelType.EMPTY) && // or the field is empty !TypeInformation.IsGroundOrFungus(voxeltype)) { if (CanFungusGrowOn(t, h, b, neighbourhood)) // there is a voxel in d6 on which the fungus can grow on { // grow growadd = 0; if (voxeltype == VoxelType.ROCK || voxeltype == VoxelType.TEAK_WOOD) { growadd = -30; } if (voxeltype == VoxelType.PINE_WOOD || voxeltype == VoxelType.BEECH_WOOD || voxeltype == VoxelType.REDWOOD) { growadd = 10; } output[t, h, b] = new VoxelInfo(VoxelType.NOBLEROT_FUNGUS, true, 0, 0, random.Next(min, max) + growadd); } } } } } } // check for kill the fungus (if in d6 all places are occupied) if (TypeInformation.IsGroundOrFungus(neighbourhood[2, 1, 1].Type)) { fung++; } if (TypeInformation.IsGroundOrFungus(neighbourhood[0, 1, 1].Type)) { fung++; } if (TypeInformation.IsGroundOrFungus(neighbourhood[1, 2, 1].Type)) { fung++; } if (TypeInformation.IsGroundOrFungus(neighbourhood[1, 0, 1].Type)) { fung++; } if (TypeInformation.IsGroundOrFungus(neighbourhood[1, 1, 2].Type)) { fung++; } if (TypeInformation.IsGroundOrFungus(neighbourhood[1, 1, 0].Type)) { fung++; } if (fung == 6) { output[2, 1, 1] = new VoxelInfo(VoxelType.NOBLEROT_FUNGUS); } } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.TEAK_LEAF)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int res = neighbourhood[1, 1, 1].Resources; if (gen == 0) { output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF); if (CanPlace(2, 1, 1, neighbourhood)) { output[2, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF, true, 1); } if (CanPlace(0, 1, 1, neighbourhood)) { output[0, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF, true, 1); } if (CanPlace(1, 1, 2, neighbourhood)) { output[1, 1, 2] = new VoxelInfo(VoxelType.TEAK_LEAF, true, 1); } if (CanPlace(1, 1, 0, neighbourhood)) { output[1, 1, 0] = new VoxelInfo(VoxelType.TEAK_LEAF, true, 1); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.TEAK_LEAF)) { // Grow to the side //output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, gen + 1); //output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF); if (CanPlace(2, 1, 1, neighbourhood)) { output[2, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF, true, gen + random.Next(0, 3), res += 10, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.TEAK_LEAF))); } if (CanPlace(0, 1, 1, neighbourhood)) { output[0, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF, true, gen + random.Next(0, 3), res += 10, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.TEAK_LEAF))); } if (CanPlace(1, 1, 2, neighbourhood)) { output[1, 1, 2] = new VoxelInfo(VoxelType.TEAK_LEAF, true, gen + random.Next(0, 3), res += 10, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.TEAK_LEAF))); } if (CanPlace(1, 1, 0, neighbourhood)) { output[1, 1, 0] = new VoxelInfo(VoxelType.TEAK_LEAF, true, gen + random.Next(0, 3), res += 10, random.Next(0, TypeInformation.GetGrowingSteps(VoxelType.TEAK_LEAF))); } } else { // Grow upwards one last time //output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_LEAF); } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.HESPEROPHANES_CINNEREUS)) { return(null); } VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int res = neighbourhood[1, 1, 1].Resources; int t = random.Next(0, 3); int h = random.Next(0, 3); int b = random.Next(0, 3); if (gen == 0) { if (IsWalkable(neighbourhood[t, h, b])) { output[1, 1, 1] = new VoxelInfo(VoxelType.EMPTY); output[t, h, b] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, 1); } else { output[1, 1, 1] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, 1); } } else if (gen < TypeInformation.GetGrowHeight(VoxelType.HESPEROPHANES_CINNEREUS) && res == 10) { Int3 moveTo = DirectionConverter.FromDirection(neighbourhood[1, 1, 1].From); t = moveTo.X; h = moveTo.Y; b = moveTo.Z; output[t, h, b] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, 0); if (random.Next(0, 11) > 7) { output[1, 1, 1] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, gen + random.Next(1, 5), 0, TypeInformation.GetGrowingSteps(VoxelType.HESPEROPHANES_CINNEREUS), Direction.SELF); } else { output[1, 1, 1] = new VoxelInfo(VoxelType.EMPTY); } } else// if (gen < TypeInformation.GetGrowHeight(VoxelType.HESPEROPHANES_CINNEREUS)) { Direction food = FoodInDirection(neighbourhood); if (food != Direction.SELF) { Int3 foodPos = DirectionConverter.FromDirection(food); int eattime = -10; if (neighbourhood[foodPos.X, foodPos.Y, foodPos.Z].Type == VoxelType.PINE_WOOD || neighbourhood[foodPos.X, foodPos.Y, foodPos.Z].Type == VoxelType.SPRUCE_WOOD) { eattime = -20; } if (neighbourhood[foodPos.X, foodPos.Y, foodPos.Z].Type == VoxelType.TEAK_WOOD || neighbourhood[foodPos.X, foodPos.Y, foodPos.Z].Type == VoxelType.OAK_WOOD) { eattime = -5; } output[1, 1, 1] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, gen + random.Next(0, 3), 10, eattime, food); } else if (IsWalkable(neighbourhood[t, h, b])) { output[1, 1, 1] = new VoxelInfo(VoxelType.EMPTY); output[t, h, b] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, gen + random.Next(1, 5)); } else { output[1, 1, 1] = new VoxelInfo(VoxelType.HESPEROPHANES_CINNEREUS, true, gen + random.Next(1, 5)); } } /* else * { * output[1, 1, 1] = new VoxelInfo(VoxelType.EMPTY); * }*/ return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.PINE_WOOD)) { return(null); } int height = random.Next((int)(TypeInformation.GetGrowHeight(VoxelType.PINE_WOOD) * 0.75), (int)(TypeInformation.GetGrowHeight(VoxelType.PINE_WOOD) * 1.25)); VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; int res = neighbourhood[1, 1, 1].Resources; if (gen == 0) { // Grow Cross and ovveride current generation output[1, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, 1, 0, TypeInformation.GetGrowingSteps(VoxelType.PINE_WOOD) / 2); output[2, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, 2, 30); output[0, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, 2, 30); output[1, 1, 2] = new VoxelInfo(VoxelType.PINE_WOOD, true, 2, 30); output[1, 1, 0] = new VoxelInfo(VoxelType.PINE_WOOD, true, 2, 30); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 1].Type) || neighbourhood[1, 0, 1].Type == VoxelType.EMPTY) { output[1, 0, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next(1, height), 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 1].Type) || neighbourhood[2, 0, 1].Type == VoxelType.EMPTY) { output[2, 0, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next(1, height), 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[0, 0, 1].Type) || neighbourhood[0, 0, 1].Type == VoxelType.EMPTY) { output[0, 0, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next(1, height), 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 2].Type) || neighbourhood[1, 0, 2].Type == VoxelType.EMPTY) { output[1, 0, 2] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next(1, height), 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 0].Type) || neighbourhood[1, 0, 0].Type == VoxelType.EMPTY) { output[1, 0, 0] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next(1, height), 0, 0, Direction.UP); } } else if (gen == -1) { output[1, 2, 1] = new VoxelInfo(VoxelType.PINE_NEEDLE, true); output[1, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD); } else if (gen < height) { if (res > 0 && gen > TypeInformation.GetGrowHeight(VoxelType.PINE_WOOD) / 2) { if (random.Next(0, 11) > 7) { res -= 15; Direction grow = GetBranchDirection(neighbourhood); Int3 temp = DirectionConverter.FromDirection(grow); if (neighbourhood[temp.X, 0, temp.Z].Type == VoxelType.EMPTY || TypeInformation.IsNotWoodButBiomass(neighbourhood[temp.X, 0, temp.Z].Type)) { output[temp.X, temp.Y, temp.Z] = new VoxelInfo(VoxelType.PINE_WOOD, true, random.Next((int)(height * 0.75), height), 0, 0, DirectionConverter.ToOppositeDirection(grow)); } } } Int3 coord = DirectionConverter.FromDirection(DirectionConverter.ToOppositeDirection(neighbourhood[1, 1, 1].From)); // Grow in given direction if (TypeInformation.IsNotWoodButBiomass(neighbourhood[coord.X, coord.Y, coord.Z].Type) || neighbourhood[coord.X, coord.Y, coord.Z].Type == VoxelType.EMPTY) { output[coord.X, coord.Y, coord.Z] = new VoxelInfo(VoxelType.PINE_WOOD, true, gen + 1, res, 0, neighbourhood[1, 1, 1].From); } output[1, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD); } else { // Grow upwards one last time if (neighbourhood[1, 1, 1].From != Direction.UP) { output[1, 2, 1] = new VoxelInfo(VoxelType.PINE_WOOD, true, -1, 0, TypeInformation.GetGrowingSteps(VoxelType.PINE_WOOD)); } output[1, 1, 1] = new VoxelInfo(VoxelType.PINE_WOOD); } return(output); }
public VoxelInfo[, ,] ApplyRule(VoxelInfo[, ,] neighbourhood) { // Apply each 18-th turn if (neighbourhood[1, 1, 1].Ticks < TypeInformation.GetGrowingSteps(VoxelType.TEAK_WOOD)) { return(null); } int height = random.Next((int)(TypeInformation.GetGrowHeight(VoxelType.TEAK_WOOD) * 0.75), (int)(TypeInformation.GetGrowHeight(VoxelType.TEAK_WOOD) * 1.25)); VoxelInfo[, ,] output = new VoxelInfo[3, 3, 3]; int gen = neighbourhood[1, 1, 1].Generation; if (gen == 0) { // Grow a 2x2 quad (override current generation) output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1); output[2, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1); output[1, 1, 2] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1); output[2, 1, 2] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1); if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 1].Type) || neighbourhood[1, 0, 1].Type == VoxelType.EMPTY) { output[1, 0, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 1].Type) || neighbourhood[2, 0, 1].Type == VoxelType.EMPTY) { output[2, 0, 1] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 0, 2].Type) || neighbourhood[1, 0, 2].Type == VoxelType.EMPTY) { output[1, 0, 2] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1, 0, 0, Direction.UP); } if (TypeInformation.IsNotWoodButBiomass(neighbourhood[2, 0, 2].Type) || neighbourhood[2, 0, 2].Type == VoxelType.EMPTY) { output[2, 0, 2] = new VoxelInfo(VoxelType.TEAK_WOOD, true, 1, 0, 0, Direction.UP); } } else if (gen < height) { Int3 coord = DirectionConverter.FromDirection(DirectionConverter.ToOppositeDirection(neighbourhood[1, 1, 1].From)); // Grow in given direction if (TypeInformation.IsNotWoodButBiomass(neighbourhood[coord.X, coord.Y, coord.Z].Type) || neighbourhood[coord.X, coord.Y, coord.Z].Type == VoxelType.EMPTY) { output[coord.X, coord.Y, coord.Z] = new VoxelInfo(VoxelType.TEAK_WOOD, true, gen + 1, 0, 0, neighbourhood[1, 1, 1].From); } output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); } else { if (neighbourhood[1, 1, 1].From == Direction.DOWN) { if (TypeInformation.IsNotWoodButBiomass(neighbourhood[1, 2, 1].Type) || neighbourhood[1, 2, 1].Type == VoxelType.EMPTY) { output[1, 2, 1] = new VoxelInfo(VoxelType.TEAK_LEAF, true, 1); } } output[1, 1, 1] = new VoxelInfo(VoxelType.TEAK_WOOD); } return(output); }