<commit_before>--[=============================================================================[
The MIT License (MIT)

Copyright (c) 2014 RepeatPan
excluding parts that were written by Radiant Entertainment

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]=============================================================================]

--[[--
	This is an overriden Stonehearth file. Parts that were changed, added or removed
	by Jelly have been marked with "START JELLY" and "END JELLY" blocks.
	Everything outside of these Jelly blocks is assumed to have been decompiled from
	the original game files and its copyright belongs entirely to Radiant Entertainment.
--]]--

local TerrainType = require("services.world_generation.terrain_type")
local TerrainInfo = require("services.world_generation.terrain_info")
local Array2D = require("services.world_generation.array_2D")
local MathFns = require("services.world_generation.math.math_fns")
local FilterFns = require("services.world_generation.filter.filter_fns")
local PerturbationGrid = require("services.world_generation.perturbation_grid")
local BoulderGenerator = require("services.world_generation.boulder_generator")
local log = radiant.log.create_logger("world_generation")
local Point3 = _radiant.csg.Point3
local mod_name = "stonehearth"
local mod_prefix = mod_name .. ":"
local oak = "oak_tree"
local juniper = "juniper_tree"
local tree_types = {oak, juniper}
local small = "small"
local medium = "medium"
local large = "large"
local tree_sizes = {
  small,
  medium,
  large
}
local pink_flower_name = mod_prefix .. "pink_flower"
local berry_bush_name = mod_prefix .. "berry_bush"
local generic_vegetaion_name = "vegetation"

--[[ JELLY START ]]--
local generic_vegetation_name = generic_vegetaion_name

local load_class, mixinto = jelly.util.load_class, jelly.util.mixinto
local GenericLandscaper = require('jelly.generators.generic_landscaper')

--[[ JELLY END ]]--

local boulder_name = "boulder"
local Landscaper = class()

function Landscaper:__init(terrain_info, rng, async)
  if async == nil then
    async = false
  end
  self._terrain_info = terrain_info
  self._tile_width = self._terrain_info.tile_size
  self._tile_height = self._terrain_info.tile_size
  self._feature_size = self._terrain_info.feature_size
  self._rng = rng
  self._async = async
  self._boulder_probabilities = {
    [TerrainType.plains] = 0.02,
    [TerrainType.foothills] = 0.02,
    [TerrainType.mountains] = 0.02
  }
  self._boulder_generator = BoulderGenerator(self._terrain_info, self._rng)
  self._noise_map_buffer = nil
  self._density_map_buffer = nil
  self._perturbation_grid = PerturbationGrid(self._tile_width, self._tile_height, self._feature_size, self._rng)
  self:_initialize_function_table()
end

function Landscaper:_initialize_function_table()
  local tree_name
  local function_table = {}
  for _, tree_type in pairs(tree_types) do
    for _, tree_size in pairs(tree_sizes) do
      tree_name = get_tree_name(tree_type, tree_size)
      if tree_size == small then
        function_table[tree_name] = self._place_small_tree
      else
        function_table[tree_name] = self._place_normal_tree
      end
    end
  end
  function_table[berry_bush_name] = self._place_berry_bush
  function_table[pink_flower_name] = self._place_flower
  self._function_table = function_table
end

function Landscaper:_get_filter_buffers(width, height)
  if self._noise_map_buffer == nil or self._noise_map_buffer.width ~= width or self._noise_map_buffer.height ~= height then
    self._noise_map_buffer = Array2D(width, height)
    self._density_map_buffer = Array2D(width, height)
  end
  assert(self._density_map_buffer.width == self._noise_map_buffer.width)
  assert(self._density_map_buffer.height == self._noise_map_buffer.height)
  return self._noise_map_buffer, self._density_map_buffer
end

function Landscaper:is_forest_feature(feature_name)
  if feature_name == nil then
    return false
  end
  if self:is_tree_name(feature_name) then
    return true
  end
  if feature_name == generic_vegetaion_name then
    return true
  end
  return false
end

function Landscaper:place_flora(tile_map, feature_map, tile_offset_x, tile_offset_y)
  local function place_item(uri, x, y)
    local entity = radiant.entities.create_entity(uri)
    radiant.terrain.place_entity(entity, Point3(x - 1 + tile_offset_x, 1, y - 1 + tile_offset_y))
    self:_set_random_facing(entity)
    return entity
  end
  self:place_features(tile_map, feature_map, place_item)
end

-- Marks the trees
function Landscaper:mark_trees(elevation_map, feature_map)
	--[[ START JELLY ]]--
	-- All old code has been removed or completely re-factored.
	local generator = self:_create_generator(self._trees_by_terrain, 'filter_2D_0125', 10, elevation_map, feature_map)

	-- Except this. The noise function is pretty much the same.
	generator:set_noise_function(function(i, j, args)
		local rng, noise_map, density_map, elevation_map, terrain_info = args.rng, args.noise_map, args.density_map, args.elevation_map, args.terrain_info

		local mean = 0
		local std_dev = 100
		
		if noise_map:is_boundary(i, j) then
			mean = mean - 20
		end
		
		local elevation = elevation_map:get(i, j)
		local terrain_type, step = terrain_info:get_terrain_type_and_step(elevation)
		
		if terrain_type == TerrainType.mountains then
			if step <= 2 then
				mean = mean + 50
				std_dev = 0
			else
				std_dev = std_dev * 0.3
			end
		elseif terrain_type == TerrainType.plains then
			if step == 2 then
				mean = mean - 5
			else
				mean = mean - 100
			end
		elseif step == 2 then
			mean = mean + 5<commit_msg>Updated landscaper.lua to A2R48<commit_after>--[=============================================================================[
The MIT License (MIT)

Copyright (c) 2014 RepeatPan
excluding parts that were written by Radiant Entertainment

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]=============================================================================]

--[[--
	This is an overriden Stonehearth file. Parts that were changed, added or removed
	by Jelly have been marked with "START JELLY" and "END JELLY" blocks.
	Everything outside of these Jelly blocks is assumed to have been decompiled from
	the original game files and its copyright belongs entirely to Radiant Entertainment.
--]]--

local TerrainType = require("services.world_generation.terrain_type")
local TerrainInfo = require("services.world_generation.terrain_info")
local Array2D = require("services.world_generation.array_2D")
local MathFns = require("services.world_generation.math.math_fns")
local FilterFns = require("services.world_generation.filter.filter_fns")
local PerturbationGrid = require("services.world_generation.perturbation_grid")
local BoulderGenerator = require("services.world_generation.boulder_generator")
local log = radiant.log.create_logger("world_generation")
local Point3 = _radiant.csg.Point3
local mod_name = "stonehearth"
local mod_prefix = mod_name .. ":"
local oak = "oak_tree"
local juniper = "juniper_tree"
local tree_types = {oak, juniper}
local small = "small"
local medium = "medium"
local large = "large"
local tree_sizes = {
  small,
  medium,
  large
}
local pink_flower_name = mod_prefix .. "pink_flower"
local berry_bush_name = mod_prefix .. "berry_bush"
local generic_vegetaion_name = "vegetation"

--[[ JELLY START ]]--
local generic_vegetation_name = generic_vegetaion_name

local load_class, mixinto = jelly.util.load_class, jelly.util.mixinto
local GenericLandscaper = require('jelly.generators.generic_landscaper')

--[[ JELLY END ]]--

local boulder_name = "boulder"
local Landscaper = class()

function Landscaper:__init(terrain_info, rng, async)
  if async == nil then
    async = false
  end
  self._terrain_info = terrain_info
  self._tile_width = self._terrain_info.tile_size
  self._tile_height = self._terrain_info.tile_size
  self._feature_size = self._terrain_info.feature_size
  self._rng = rng
  self._async = async
  self._boulder_probabilities = {
    [TerrainType.plains] = 0.02,
    [TerrainType.foothills] = 0.02,
    [TerrainType.mountains] = 0.02
  }
  self._boulder_generator = BoulderGenerator(self._terrain_info, self._rng)
  self._noise_map_buffer = nil
  self._density_map_buffer = nil
  self._perturbation_grid = PerturbationGrid(self._tile_width, self._tile_height, self._feature_size, self._rng)
  self:_initialize_function_table()
end

function Landscaper:_initialize_function_table()
  local tree_name
  local function_table = {}
  for _, tree_type in pairs(tree_types) do
    for _, tree_size in pairs(tree_sizes) do
      tree_name = get_tree_name(tree_type, tree_size)
      if tree_size == small then
        function_table[tree_name] = self._place_small_tree
      else
        function_table[tree_name] = self._place_normal_tree
      end
    end
  end
  function_table[berry_bush_name] = self._place_berry_bush
  function_table[pink_flower_name] = self._place_flower
  self._function_table = function_table
end

function Landscaper:_get_filter_buffers(width, height)
  if self._noise_map_buffer == nil or self._noise_map_buffer.width ~= width or self._noise_map_buffer.height ~= height then
    self._noise_map_buffer = Array2D(width, height)
    self._density_map_buffer = Array2D(width, height)
  end
  assert(self._density_map_buffer.width == self._noise_map_buffer.width)
  assert(self._density_map_buffer.height == self._noise_map_buffer.height)
  return self._noise_map_buffer, self._density_map_buffer
end

function Landscaper:is_forest_feature(feature_name)
  if feature_name == nil then
    return false
  end
  if self:is_tree_name(feature_name) then
    return true
  end
  if feature_name == generic_vegetaion_name then
    return true
  end
  return false
end

function Landscaper:place_flora(tile_map, feature_map, tile_offset_x, tile_offset_y)
  local function place_item(uri, x, y)
    local entity = radiant.entities.create_entity(uri)
    radiant.terrain.place_entity(entity, Point3(x - 1 + tile_offset_x, 1, y - 1 + tile_offset_y))
    self:_set_random_facing(entity)
    return entity
  end
  self:place_features(tile_map, feature_map, place_item)
end

-- Marks the trees
function Landscaper:mark_trees(elevation_map, feature_map)
	--[[ START JELLY ]]--
	-- All old code has been removed or completely re-factored.
	local generator = self:_create_generator(self._trees_by_terrain, 'filter_2D_0125', 10, elevation_map, feature_map)

	-- Except this. The noise function is pretty much the same.
	generator:set_noise_function(function(i, j, args)
		local rng, noise_map, density_map, elevation_map, terrain_info = args.rng, args.noise_map, args.density_map, args.elevation_map, args.terrain_info

		local mean = 0
		local std_dev = 100
		
		if noise_map:is_boundary(i, j) then
			mean = mean - 20
		end
		
		local elevation = elevation_map:get(i, j)
		local terrain_type, step = terrain_info:get_terrain_type_and_step(elevation)
		
		if terrain_type == TerrainType.mountains then
			if step <= 2 then
				mean = mean + 50
				std_dev = 0
			else
				std_dev = std_dev * 0.3
			end
		elseif terrain_type == TerrainType.plains then
			if step == 2 then
				mean = mean - 5
			else
				mean = mean - 300
				std_dev = 0
			end
		elseif step == 2 then
			mean = mean + 5
{'fraction_non_alphanumeric': 0.09966676764616783, 'fraction_numerical': 0.007724931838836716, 'mean_word_length': 4.848095659875996, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4620863', 'n_tokens_mistral': 4390, 'n_tokens_neox': 4014, 'n_words': 1190}