Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Allows manipulation of region biomes, mainly changing of evilness and addition/removal of plants and creatures from biome regions.
- --
- --[====[
- biomemanipulator
- ========
- -- The biome determination logic is mainly copied and adapted from https://github.com/ragundo/exportmaps/blob/master/cpp/df_utils/biome_type.cpp#L105
- --
- ]====]
- local gui = require 'gui'
- local dialog = require 'gui.dialogs'
- local widgets =require 'gui.widgets'
- local guiScript = require 'gui.script'
- local utils = require 'utils'
- local args = {...}
- local Main_Page = {}
- local Animal_Page = {}
- local Plant_Page = {}
- --================================================================
- -- The Grid widget defines an pen supporting X/Y character display grid supporting display of
- -- a grid larger than the frame allows through a panning viewport. The init function requires
- -- the specification of the width and height attributes that defines the grid dimensions.
- -- The grid coordinates are 0 based.
- --
- Grid = defclass (Grid, widgets.Widget)
- Grid.ATTRS =
- {width = DEFAULT_NIL,
- height = DEFAULT_NIL}
- --================================================================
- function Grid:init ()
- if type (self.width) ~= 'number' or
- type (self.height) ~= 'number' or
- self.width < 0 or
- self.height < 0 then
- error ("Grid widgets have to have their width and height set permanently on initiation")
- return
- end
- self.grid = dfhack.penarray.new (self.width, self.height)
- self.viewport = {x1 = 0,
- x2 = self.frame.r - self.frame.l,
- y1 = 0,
- y2 = self.frame.b - self.frame.t}
- end
- --================================================================
- function Grid:panTo (x, y)
- local x_size = self.viewport.x2 - self.viewport.x1 + 1
- local y_size = self.viewport.y2 - self.viewport.y1 + 1
- self.viewport.x1 = x
- if self.viewport.x1 + x_size > self.width then
- self.viewport.x1 = self.width - x_size
- end
- if self.viewport.x1 < 0 then
- self.viewport.x1 = 0
- end
- self.viewport.x2 = self.viewport.x1 + x_size - 1
- self.viewport.y1 = y
- if self.viewport.y1 + y_size > self.height then
- self.viewport.y1 = self.height - y_size
- end
- if self.viewport.y1 < 0 then
- self.viewport.y1 = 0
- end
- self.viewport.y2 = self.viewport.y1 + y_size - 1
- end
- --================================================================
- -- Pans the viewport in the X and Y dimensions the number of steps specified by the parameters.
- -- It will stop the panning at 0, however, and will not pan outside of the grid (a grid smaller)
- -- than the frame will still have non grid parts in the frame, of course).
- --
- function Grid:pan (x, y)
- self:panTo (self.viewport.x1 + x, self.viewport.y1 + y)
- end
- --================================================================
- function Grid:panCenter (x, y)
- self:panTo (x - math.floor ((self.viewport.x2 - self.viewport.x1 + 1) / 2),
- y - math.floor ((self.viewport.y2 - self.viewport.y1 + 1) / 2))
- end
- --================================================================
- -- Assigns a value to the specified grid (not frame) coordinates. The 'pen'
- -- parameter has to be a DFHack 'pen' table or object.
- --
- function Grid:set (x, y, pen)
- if x < 0 or x >= self.width then
- error ("Grid:set error: x out of bounds " .. tostring (x) .. " vs 0 - " .. tostring (self.width - 1))
- return
- elseif y < 0 or y >= self.height then
- error ("Grid:set error: y out of bounds " .. tostring (y) .. " vs 0 - " .. tostring (self.height - 1))
- return
- end
- self.grid:set_tile (x, y, pen)
- end
- --================================================================
- -- Returns the data at position x, y in the grid.
- --
- function Grid:get (x, y)
- if x < 0 or x >= self.width then
- error ("Grid:set error: x out of bounds " .. tostring (x) .. " vs 0 - " .. tostring (self.width - 1))
- return
- elseif y < 0 or y >= self.height then
- error ("Grid:set error: y out of bounds " .. tostring (y) .. " vs 0 - " .. tostring (self.height - 1))
- return
- else
- return self.grid:get_tile (x, y)
- end
- end
- --================================================================
- -- Renders the contents within the viewport into the frame.
- --
- function Grid:onRenderBody (dc)
- self.grid:draw (self.frame.l,
- self.frame.t,
- self.viewport.x2 - self.viewport.x1 + 1,
- self.viewport.y2 - self.viewport.y1 + 1,
- self.viewport.x1,
- self.viewport.y1)
- end
- --================================================================
- --================================================================
- function biomemanipulator (region)
- local map_width = df.global.world.world_data.world_width
- local map_height = df.global.world.world_data.world_height
- local pole = df.global.world.world_data.flip_latitude
- local evilness
- local animals = 0
- local plants = 0
- local size
- local x
- local y
- local Focus = "Main"
- local Unrestricted = false
- if region == NIL then
- x = df.global.world.world_data.region_details [0].pos.x
- y = df.global.world.world_data.region_details [0].pos.y
- region = df.global.world.world_data.region_map [x]:_displace (y).region_id
- else
- x = df.global.world.world_data.regions [region].region_coords.x [0]
- y = df.global.world.world_data.regions [region].region_coords.x [0]
- end
- evilness = df.global.world.world_data.region_map [x]:_displace (y).evilness
- size = #df.global.world.world_data.regions [region].region_coords.x
- for i, population in ipairs (df.global.world.world_data.regions [region].population) do
- if population.type == df.world_population_type.Animal or
- population.type == df.world_population_type.Vermin or
- population.type == df.world_population_type.VerminInnumerable or
- population.type == df.world_population_type.ColonyInsect then
- animals = animals + 1
- elseif population.type == df.world_population_type.Tree or
- population.type == df.world_population_type.Grass or
- population.type == df.world_population_type.Bush then
- plants = plants + 1
- end
- end
- local keybindings = {
- evilness = {key = "CUSTOM_E",
- desc = "Change biome's Evilness"},
- unrestricted = {key = "CUSTOM_U",
- desc = "Toggles whether plant and animal selection is limited to region applicable types"},
- animals = {key = "CUSTOM_A",
- desc = "Change Animals within the biome"},
- plants = {key = "CUSTOM_P",
- desc = "Change Plants within the biome"},
- floradiversity = {key = "CUSTOM_F",
- desc = "Gives all regions all plants legal to their biomes"},
- faunadiversity = {key = "CUSTOM_SHIFT_F",
- desc = "Gives all regions all creatures legal to their biomes"},
- region = {key = "CUSTOM_R",
- desc = "Display the region map"},
- biome = {key = "CUSTOM_B",
- desc = "Display the biome map"},
- min_count = {key = "CUSTOM_X",
- desc = "Change the minimum number of a creature"},
- max_count = {key = "CUSTOM_SHIFT_X",
- desc = "Change the maximum number of a creature"},
- next_edit = {key = "CHANGETAB",
- desc = "Change focus to the next item"},
- prev_edit = {key = "SEC_CHANGETAB",
- desc = "Change focus to the previous item"},
- up = {key = "CURSOR_UP",
- desc = "Shifts focus 1 step upwards"},
- down = {key = "CURSOR_DOWN",
- desc = "Shifts focus 1 step downwards"},
- left = {key = "CURSOR_LEFT",
- desc = "Shifts focus 1 step to the left"},
- right = {key = "CURSOR_RIGHT",
- desc = "Shift focus 1 step to the right"},
- upleft = {key = "CURSOR_UPLEFT",
- desc = "Shifts focus 1 step up to the left"},
- upright = {key = "CURSOR_UPRIGHT",
- desc = "Shifts focus 1 step up to the right"},
- downleft = {key = "CURSOR_DOWNLEFT",
- desc = "Shifts focus 1 step down to the left"},
- downright = {key = "CURSOR_DOWNRIGHT",
- desc = "Shifts focus 1 step down to the right"},
- help = {key = "HELP",
- desc= " Show this help/info"}}
- --============================================================
- function check_tropicality_no_poles_world (temperature)
- local is_possible_tropical_area_by_latitude = false
- local is_tropical_area_by_latitude = false
- -- No poles => Temperature determines tropicality
- --
- if temperature >= 75 then
- is_possible_tropical_area_by_latitude = true
- end
- is_tropical_area_by_latitude = temperature >= 85
- return is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude
- end
- --============================================================
- function check_tropicality_north_pole_only_world (pos_y,
- map_height)
- local v6
- local is_possible_tropical_area_by_latitude = false
- local is_tropical_area_by_latitude = false
- if map_height == 17 then
- v6 = pos_y * 16
- elseif map_height == 33 then
- v6 = pos_y * 8
- elseif map_height == 65 then
- v6 = pos_y * 4
- elseif map_height == 129 then
- v6 = pos_y * 2
- else
- v6 = pos_y
- end
- is_possible_tropical_area_by_latitude = v6 > 170
- is_tropical_area_by_latitude = v6 >= 200
- return is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude
- end
- --============================================================
- function check_tropicality_south_pole_only_world (pos_y,
- map_height)
- local v6 = map_height - pos_y - 1
- local is_possible_tropical_area_by_latitude = false
- local is_tropical_area_by_latitude = false
- if map_height == 17 then
- v6 = v6 * 16
- elseif map_height == 33 then
- v6 = v6 * 8
- elseif map_height == 65 then
- v6 = v6 * 4
- elseif map_height == 129 then
- v6 = v6 * 2
- else
- v6 = v6
- end
- is_possible_tropical_area_by_latitude = v6 > 170
- is_tropical_area_by_latitude = v6 >= 200
- return is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude
- end
- --============================================================
- function check_tropicality_both_poles_world (pos_y,
- map_height)
- local v6
- local is_possible_tropical_area_by_latitude = false
- local is_tropical_area_by_latitude = false
- if pos_y < math.floor (map_height / 2) then
- v6 = 2 * pos_y
- else
- v6 = map_height + 2 * (math.floor (map_height / 2) - pos_y) - 1
- if v6 < 0 then
- v6 = 0
- end
- if v6 >= map_height then
- v6 = map_height - 1
- end
- end
- if map_height == 17 then
- v6 = v6 * 16
- elseif map_height == 33 then
- v6 = v6 * 8
- elseif map_height == 65 then
- v6 = v6 * 4
- elseif map_height == 129 then
- v6 = v6 * 2
- else
- v6 = v6
- end
- is_possible_tropical_area_by_latitude = v6 > 170
- is_tropical_area_by_latitude = v6 >= 200
- return is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude
- end
- --============================================================
- function check_tropicality (pos_y,
- map_height,
- temperature)
- local flip_latitude = df.global.world.world_data.flip_latitude
- if flip_latitude == -1 then -- No poles
- return check_tropicality_no_poles_world (temperature)
- elseif flip_latitude == 0 then -- North pole
- return check_tropicality_north_pole_only_world (pos_y,
- map_height)
- elseif flip_latitude == 1 then -- South pole
- return check_tropicality_south_pole_only_world (pos_y,
- map_height)
- elseif flip_latitude == 2 then -- Both poles
- return check_tropicality_both_poles_world (pos_y,
- map_height)
- else
- return false, false
- end
- end
- --============================================================
- function get_parameter_percentage (flip_latitude,
- pos_y,
- rainfall,
- map_height)
- local result
- local ypos = pos_y
- if flip_latitude == -1 then -- No poles
- return 100
- elseif flip_latitude == 1 then -- South pole
- ypos = map_height - ypos - 1
- elseif flip_latitude == 2 then -- North and South pole
- if ypos < math.floor (map_height / 2) then
- ypos = ypos * 2
- else
- ypos = map_height + 2 * (math.floor (map_height / 2) - ypos) - 1
- if ypos < 0 then
- ypos = 0
- end
- if ypos >= map_height then
- ypos = map_height - 1
- end
- end
- end
- local latitude
- if map_height == 17 then
- latitude = 16 * ypos
- elseif map_height == 33 then
- latitude = 8 * ypos
- elseif map_height == 65 then
- latitude = 4 * ypos
- elseif map_height == 129 then
- latitude = 2 * ypos
- else
- latitude = ypos
- end
- if latitude > 220 then
- return 100
- elseif latitude > 190 and
- latitude < 201 then
- return 0
- elseif latitude >= 201 then
- result = rainfall + 16 * (latitude - 207)
- else
- result = 16 * (184 - latitude) - rainfall
- end
- if result < 0 then
- return 0
- elseif result > 100 then
- return 100
- else
- return result
- end
- end
- --============================================================
- function get_region_parameter (pos_y,
- rainfall,
- map_height)
- local result = 100
- if map_height > 65 then -- Medium & Large worlds
- return get_parameter_percentage (df.global.world.world_data.flip_latitude,
- pos_y,
- rainfall,
- map_height)
- end
- return result
- end
- --============================================================
- function get_lake_biome (is_possible_tropical_area_by_latitude,
- salinity)
- if salinity < 33 then
- if is_possible_tropical_area_by_latitude then
- return df.biome_type.LAKE_TROPICAL_FRESHWATER
- else
- return df.biome_type.LAKE_TEMPERATE_FRESHWATER
- end
- elseif salinity < 66 then
- if is_possible_tropical_area_by_latitude then
- return df.biome_type.LAKE_TROPICAL_BRACKISHWATER
- else
- return df.biome_type.LAKE_TEMPERATE_BRACKISHWATER
- end
- else
- if is_possible_tropical_area_by_latitude then
- return df.biome_type.LAKE_TROPICAL_SALTWATER
- else
- return df.biome_type.LAKE_TEMPERATE_SALTWATER
- end
- end
- end
- --============================================================
- function get_ocean_biome (is_tropical_area_by_latitude,
- temperature)
- if is_tropical_area_by_latitude then
- return df.biome_type.OCEAN_TROPICAL
- elseif temperature <= -5 then
- return df.biome_type.OCEAN_ARCTIC
- else
- return df.biome_type.OCEAN_TEMPERATE
- end
- end
- --============================================================
- function get_desert_biome (drainage)
- if drainage < 33 then
- return df.biome_type.DESERT_SAND
- elseif drainage < 66 then
- return df.biome_type.DESERT_ROCK
- else
- return df.biome_type.DESERT_BADLAND
- end
- end
- --============================================================
- function get_biome_grassland (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- if (is_possible_tropical_area_by_latitude and
- get_region_parameter(pos_y, rainfall, map_height) < 66) or
- is_tropical_area_by_latitude then
- return df.biome_type.GRASSLAND_TROPICAL
- else
- return df.biome_type.GRASSLAND_TEMPERATE
- end
- end
- --============================================================
- function get_biome_savanna (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- if is_tropical_area_by_latitude or
- (is_possible_tropical_area_by_latitude and
- get_region_parameter (pos_y, rainfall, map_height) <= 6) then
- return df.biome_type.SAVANNA_TROPICAL
- else
- return df.biome_type.SAVANNA_TEMPERATE
- end
- end
- --============================================================
- function get_biome_desert_or_grassland_or_savanna (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- vegetation,
- drainage,
- rainfall,
- pos_y,
- map_height)
- if vegetation < 10 then
- return get_desert_biome (drainage)
- elseif vegetation < 20 then
- return get_biome_grassland (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- else
- return get_biome_savanna (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- end
- end
- --============================================================
- function get_biome_shrubland (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- if is_tropical_area_by_latitude or
- (is_possible_tropical_area_by_latitude and
- get_region_parameter (pos_y, rainfall, map_height) < 66) then
- return df.biome_type.SHRUBLAND_TROPICAL
- else
- return df.biome_type.SHRUBLAND_TEMPERATE
- end
- end
- --============================================================
- function get_biome_marsh (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- salinity,
- rainfall,
- pos_y,
- map_height)
- if salinity < 66 then
- if is_tropical_area_by_latitude or
- (is_possible_tropical_area_by_latitude and
- get_region_parameter (pos_y, rainfall, map_height) < 66) then
- return df.biome_type.MARSH_TROPICAL_FRESHWATER
- else
- return df.biome_type.MARSH_TEMPERATE_FRESHWATER
- end
- else
- if is_tropical_area_by_latitude or
- (is_possible_tropical_area_by_latitude and
- get_region_parameter (pos_y, rainfall, map_height) < 66) then
- return df.biome_type.MARSH_TROPICAL_SALTWATER
- else
- return df.biome_type.MARSH_TEMPERATE_SALTWATER
- end
- end
- end
- --============================================================
- function get_biome_shrubland_or_marsh (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- drainage,
- salinity,
- rainfall,
- pos_y,
- map_height)
- if drainage < 33 then
- return get_biome_marsh (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- salinity,
- rainfall,
- pos_y,
- map_height)
- else
- return get_biome_shrubland (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- pos_y,
- map_height)
- end
- end
- --============================================================
- function get_biome_forest (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- temperature,
- pos_y,
- map_height)
- local parameter = get_region_parameter (pos_y, rainfall, map_height)
- if is_possible_tropical_area_by_latitude then
- if (parameter < 66 or
- is_tropical_area_by_latitude) and
- rainfall < 75 then
- return df.biome_type.FOREST_TROPICAL_CONIFER
- elseif parameter < 66 then
- return df.biome_type.FOREST_TROPICAL_DRY_BROADLEAF
- elseif is_tropical_area_by_latitude then
- return df.biome_type.FOREST_TROPICAL_MOIST_BROADLEAF
- elseif rainfall < 75 or
- temperature < 65 then
- if temperature < 10 then
- return df.biome_type.FOREST_TAIGA
- else
- return df.biome_type.FOREST_TEMPERATE_CONIFER
- end
- else
- return df.biome_type.FOREST_TEMPERATE_BROADLEAF
- end
- else
- if rainfall < 75 or
- temperature < 65 then
- if temperature < 10 then
- return df.biome_type.FOREST_TAIGA
- else
- return df.biome_type.FOREST_TEMPERATE_CONIFER
- end
- else
- return df.biome_type.FOREST_TEMPERATE_BROADLEAF
- end
- end
- end
- --============================================================
- function get_biome_swamp (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- salinity,
- drainage,
- rainfall,
- pos_y,
- map_height)
- local parameter = get_region_parameter (pos_y, rainfall, map_height)
- if is_possible_tropical_area_by_latitude then
- if salinity < 66 then
- if parameter < 66 or
- is_tropical_area_by_latitude then
- return df.biome_type.SWAMP_TROPICAL_FRESHWATER
- else
- return df.biome_type.SWAMP_TEMPERATE_FRESHWATER
- end
- elseif parameter < 66 or
- is_tropical_area_by_latitude then
- if drainage < 10 then
- return df.biome_type.SWAMP_MANGROVE
- else
- return df.biome_type.SWAMP_TROPICAL_SALTWATER
- end
- else
- return df.biome_type.SWAMP_TEMPERATE_SALTWATER
- end
- else
- if salinity < 66 then
- return df.biome_type.SWAMP_TEMPERATE_FRESHWATER
- else
- return df.biome_type.SWAMP_TEMPERATE_SALTWATER
- end
- end
- end
- --============================================================
- function get_biome_type (biome_pos_y,
- map_height,
- temperature,
- elevation,
- drainage,
- rainfall,
- salinity,
- vegetation,
- region_id)
- local is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude =
- check_tropicality (biome_pos_y,
- map_height,
- temperature)
- if df.global.world.world_data.regions[region_id].type == df.world_region_type.Lake then
- return get_lake_biome (is_possible_tropical_area_by_latitude,
- salinity)
- elseif elevation >= 150 then
- return df.biome_type.MOUNTAIN
- elseif elevation < 100 then
- return get_ocean_biome (is_tropical_area_by_latitude,
- temperature)
- elseif temperature <= -5 then
- if drainage < 75 then
- return df.biome_type.TUNDRA
- else
- return df.biome_type.GLACIER
- end
- elseif vegetation < 33 then
- return get_biome_desert_or_grassland_or_savanna (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- vegetation,
- drainage,
- rainfall,
- biome_pos_y,
- map_height)
- elseif vegetation < 66 then
- return get_biome_shrubland_or_marsh (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- drainage,
- salinity,
- rainfall,
- biome_pos_y,
- map_height)
- elseif drainage < 33 then
- return get_biome_swamp (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- salinity,
- drainage,
- rainfall,
- biome_pos_y,
- map_height)
- else
- return get_biome_forest (is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude,
- rainfall,
- temperature,
- biome_pos_y,
- map_height)
- end
- end
- --============================================================
- function get_biome_character (local_pos_y,
- biome_reference_y,
- biome_home_y,
- map_height,
- temperature,
- elevation,
- drainage,
- rainfall,
- salinity,
- vegetation,
- region_id)
- local biome_type
- biome_type = get_biome_type (biome_reference_y,
- map_height,
- temperature,
- elevation,
- drainage,
- rainfall,
- salinity,
- vegetation,
- region_id)
- if biome_type == df.biome_type.MOUNTAIN then
- return '+'
- elseif biome_type == df.biome_type.GLACIER then
- return '*'
- elseif biome_type == df.biome_type.TUNDRA then
- return 't'
- elseif biome_type == df.biome_type.SWAMP_TEMPERATE_FRESHWATER then
- return 'p'
- elseif biome_type == df.biome_type.SWAMP_TEMPERATE_SALTWATER then
- return 'r'
- elseif biome_type == df.biome_type.MARSH_TEMPERATE_FRESHWATER then
- return 'n'
- elseif biome_type == df.biome_type.MARSH_TEMPERATE_SALTWATER then
- return 'y'
- elseif biome_type == df.biome_type.SWAMP_TROPICAL_FRESHWATER then
- return 'P'
- elseif biome_type == df.biome_type.SWAMP_TROPICAL_SALTWATER then
- return 'R'
- elseif biome_type == df.biome_type.SWAMP_MANGROVE then
- return 'M'
- elseif biome_type == df.biome_type.MARSH_TROPICAL_FRESHWATER then
- return 'N'
- elseif biome_type == df.biome_type.MARSH_TROPICAL_SALTWATER then
- return 'Y'
- elseif biome_type == df.biome_type.FOREST_TAIGA then
- return 'T'
- elseif biome_type == df.biome_type.FOREST_TEMPERATE_CONIFER then
- return 'c'
- elseif biome_type == df.biome_type.FOREST_TEMPERATE_BROADLEAF then
- return 'l'
- elseif biome_type == df.biome_type.FOREST_TROPICAL_CONIFER then
- return 'C'
- elseif biome_type == df.biome_type.FOREST_TROPICAL_DRY_BROADLEAF then
- return 'd'
- elseif biome_type == df.biome_type.FOREST_TROPICAL_MOIST_BROADLEAF then
- return 'L'
- elseif biome_type == df.biome_type.GRASSLAND_TEMPERATE then
- return 'g'
- elseif biome_type == df.biome_type.SAVANNA_TEMPERATE then
- return 's'
- elseif biome_type == df.biome_type.SHRUBLAND_TEMPERATE then
- return 'u'
- elseif biome_type == df.biome_type.GRASSLAND_TROPICAL then
- return 'G'
- elseif biome_type == df.biome_type.SAVANNA_TROPICAL then
- return 'S'
- elseif biome_type == df.biome_type.SHRUBLAND_TROPICAL then
- return 'U'
- elseif biome_type == df.biome_type.DESERT_BADLAND then
- return 'B'
- elseif biome_type == df.biome_type.DESERT_ROCK then
- return 'e'
- elseif biome_type == df.biome_type.DESERT_SAND then
- return 'D'
- elseif biome_type == df.biome_type.OCEAN_TROPICAL then
- return 'O'
- elseif biome_type == df.biome_type.OCEAN_TEMPERATE then
- return 'o'
- elseif biome_type == df.biome_type.OCEAN_ARCTIC then
- return 'a'
- elseif biome_type == df.biome_type.POOL_TEMPERATE_FRESHWATER then
- return '.'
- elseif biome_type == df.biome_type.POOL_TEMPERATE_BRACKISHWATER then
- return ':'
- elseif biome_type == df.biome_type.POOL_TEMPERATE_SALTWATER then
- return '!'
- elseif biome_type == df.biome_type.POOL_TROPICAL_FRESHWATER then
- return ','
- elseif biome_type == df.biome_type.POOL_TROPICAL_BRACKISHWATER then
- return ';'
- elseif biome_type == df.biome_type.POOL_TROPICAL_SALTWATER then
- return '|'
- elseif biome_type == df.biome_type.LAKE_TEMPERATE_FRESHWATER then
- return '<'
- elseif biome_type == df.biome_type.LAKE_TEMPERATE_BRACKISHWATER then
- return '-'
- elseif biome_type == df.biome_type.LAKE_TEMPERATE_SALTWATER then
- return '['
- elseif biome_type == df.biome_type.LAKE_TROPICAL_FRESHWATER then
- return '>'
- elseif biome_type == df.biome_type.LAKE_TROPICAL_BRACKISHWATER then
- return '='
- elseif biome_type == df.biome_type.LAKE_TROPICAL_SALTWATER then
- return ']'
- elseif biome_type == df.biome_type.RIVER_TEMPERATE_FRESHWATER then
- return '\\'
- elseif biome_type == df.biome_type.RIVER_TEMPERATE_BRACKISHWATER then
- return '%'
- elseif biome_type == df.biome_type.RIVER_TEMPERATE_SALTWATER then
- return '('
- elseif biome_type == df.biome_type.RIVER_TROPICAL_FRESHWATER then
- return '/'
- elseif biome_type == df.biome_type.RIVER_TROPICAL_BRACKISHWATER then
- return '&'
- elseif biome_type == df.biome_type.RIVER_TROPICAL_SALTWATER then
- return ')'
- elseif biome_type == df.biome_type.SUBTERRANEAN_WATER then -- Never generated
- return '_'
- elseif biome_type == df.biome_type.SUBTERRANEAN_CHASM then -- Never generated
- return '^'
- elseif biome_type == df.biome_type.SUBTERRANEAN_LAVA then
- return '~'
- end
- end
- --============================================================
- function Sort (list)
- local temp
- for i, dummy in ipairs (list) do
- for k = i + 1, #list do
- if list [k].name < list [i].name then
- temp = list [i]
- list [i] = list [k]
- list [k] = temp
- end
- end
- end
- end
- --============================================================
- function Is_Animal (value)
- return value == df.world_population_type.Animal or
- value == df.world_population_type.Vermin or
- value == df.world_population_type.VerminInnumerable or
- value == df.world_population_type.ColonyInsect
- end
- --============================================================
- function Is_Plant (value)
- return value == df.world_population_type.Tree or
- value == df.world_population_type.Grass or
- value == df.world_population_type.Bush
- end
- --============================================================
- function Locate_Animal (index)
- for i, population in ipairs (df.global.world.world_data.regions [region].population) do
- if Is_Animal (population.type) and
- population.race == index then
- return i
- end
- end
- return NIL
- end
- --============================================================
- function Locate_Plant (index)
- for i, population in ipairs (df.global.world.world_data.regions [region].population) do
- if Is_Plant (population.type) and
- population.plant == index then
- return i
- end
- end
- return NIL
- end
- --============================================================
- function Fit_Right (Item, Size)
- if string.len (Item) > Size then
- return string.rep ('#', Size)
- else
- return string.rep (' ', Size - string.len (Item)) .. Item
- end
- end
- --============================================================
- function Savagery_Pen (evilness)
- if evilness < 33 then
- return COLOR_LIGHTCYAN
- elseif evilness < 66 then
- return COLOR_YELLOW
- else
- return COLOR_LIGHTMAGENTA
- end
- end
- --============================================================
- local Region_Pen =
- {[0] = COLOR_WHITE,
- [1] = COLOR_LIGHTCYAN,
- [2] = COLOR_CYAN,
- [3] = COLOR_LIGHTBLUE,
- [4] = COLOR_BLUE,
- [5] = COLOR_LIGHTGREEN,
- [6] = COLOR_GREEN,
- [7] = COLOR_YELLOW,
- [8] = COLOR_LIGHTMAGENTA,
- [9] = COLOR_MAGENTA,
- [10] = COLOR_LIGHTRED,
- [11] = COLOR_RED,
- [12] = COLOR_GREY,
- [13] = COLOR_DARKGREY,
- [14] = COLOR_BROWN}
- --============================================================
- local Region_Character =
- {[0] = 'A',
- [1] = 'B',
- [2] = 'C',
- [3] = 'D',
- [4] = 'E',
- [5] = 'F',
- [6] = 'G',
- [7] = 'H',
- [8] = 'K',
- [9] = 'L',
- [10] = 'M',
- [11] = 'O',
- [12] = 'P',
- [13] = 'R',
- [14] = 'S'}
- --============================================================
- function Make_Region (x, y)
- local ch
- local fg
- local bg
- local tile_color
- local region_id
- for i = 0, map_height - 1 do
- for k = 0, map_width - 1 do
- region_id = df.global.world.world_data.region_map [k]:_displace (i).region_id
- ch = Region_Character [math.floor (region_id / 15) % 15]
- if x == k and y == i then
- fg = COLOR_BLACK
- bg = Region_Pen [region_id % 15]
- tile_color = false
- else
- fg = Region_Pen [region_id % 15]
- bg = COLOR_BLACK
- tile_color = true
- end
- Main_Page.Region_Grid:set (k, i,{ch = ch,
- fg = fg,
- bg = bg,
- bold = false,
- tile = nil,
- tile_color = tile_color,
- tile_fg = nil,
- tile_bg = nil})
- end
- end
- end
- --============================================================
- function Biome_Color (savagery, evilness)
- if evilness < 33 then
- if savagery < 33 then
- return COLOR_BLUE
- elseif savagery < 66 then
- return COLOR_GREEN
- else
- return COLOR_LIGHTCYAN
- end
- elseif evilness < 66 then
- if savagery < 33 then
- return COLOR_GREY
- elseif savagery < 66 then
- return COLOR_LIGHTGREEN
- else
- return COLOR_YELLOW
- end
- else
- if savagery < 33 then
- return COLOR_MAGENTA
- elseif savagery < 66 then
- return COLOR_LIGHTRED
- else
- return COLOR_RED
- end
- end
- end
- --============================================================
- function Make_Biome (x, y)
- local ch
- local fg
- local bg
- local tile_color
- local region
- for i = 0, map_height - 1 do
- for k = 0, map_width - 1 do
- region = df.global.world.world_data.region_map [k]:_displace (i)
- ch = get_biome_character (i,
- i,
- i,
- map_height,
- region.temperature,
- region.elevation,
- region.drainage,
- region.rainfall,
- region.salinity,
- region.vegetation,
- region.region_id)
- if x == k and y == i then
- fg = COLOR_BLACK
- bg = Biome_Color (region.savagery, region.evilness)
- tile_color = false
- else
- fg = Biome_Color (region.savagery, region.evilness)
- bg = COLOR_BLACK
- tile_color = true
- end
- Main_Page.Biome_Grid:set (k, i,{ch = ch,
- fg = fg,
- bg = bg,
- bold = false,
- tile = nil,
- tile_color = tile_color,
- tile_fg = nil,
- tile_bg = nil})
- end
- end
- end
- --============================================================
- function Add_One (List, Index)
- List [Index] = List [Index] + 1
- end
- --============================================================
- function Make_Profile (region)
- local Profile =
- {BIOME_MOUNTAIN = 0,
- BIOME_GLACIER = 0,
- BIOME_TUNDRA = 0,
- BIOME_SWAMP_TEMPERATE_SALTWATER = 0,
- BIOME_SWAMP_TEMPERATE_FRESHWATER = 0,
- BIOME_MARSH_TEMPERATE_FRESHWATER = 0,
- BIOME_MARSH_TEMPERATE_SALTWATER = 0,
- BIOME_SWAMP_TROPICAL_FRESHWATER = 0,
- BIOME_SWAMP_TROPICAL_SALTWATER = 0,
- BIOME_SWAMP_MANGROVE = 0,
- BIOME_MARSH_TROPICAL_FRESHWATER = 0,
- BIOME_MARSH_TROPICAL_SALTWATER = 0,
- BIOME_FOREST_TAIGA = 0,
- BIOME_FOREST_TEMPERATE_CONIFER = 0,
- BIOME_FOREST_TEMPERATE_BROADLEAF = 0,
- BIOME_FOREST_TROPICAL_CONIFER = 0,
- BIOME_FOREST_TROPICAL_DRY_BROADLEAF = 0,
- BIOME_FOREST_TROPICAL_MOIST_BROADLEAF = 0,
- BIOME_GRASSLAND_TEMPERATE = 0,
- BIOME_SAVANNA_TEMPERATE = 0,
- BIOME_SHRUBLAND_TEMPERATE = 0,
- BIOME_GRASSLAND_TROPICAL = 0,
- BIOME_SAVANNA_TROPICAL = 0,
- BIOME_SHRUBLAND_TROPICAL = 0,
- BIOME_DESERT_BADLAND = 0,
- BIOME_DESERT_ROCK = 0,
- BIOME_DESERT_SAND = 0,
- BIOME_OCEAN_TROPICAL = 0,
- BIOME_OCEAN_TEMPERATE = 0,
- BIOME_OCEAN_ARCTIC = 0,
- --BIOME_SUBTERRANEAN_WATER = 0,
- --BIOME_SUBTERRANEAN_CHASM = 0,
- --BIOME_SUBTERRANEAN_LAVA = 0,
- GOOD = false,
- EVIL = false,
- SAVAGE = 0}
- for i, x_coord in ipairs (df.global.world.world_data.regions [region].region_coords.x) do
- local y_coord = df.global.world.world_data.regions [region].region_coords.y [i]
- local biome = df.global.world.world_data.region_map [x_coord]:_displace (y_coord)
- local is_possible_tropical_area_by_latitude, is_tropical_area_by_latitude =
- check_tropicality (y_coord,
- map_height,
- biome.temperature,
- pole)
- local biome_type = get_biome_type
- (y_coord,
- map_height,
- biome.temperature,
- biome.elevation,
- biome.drainage,
- biome.rainfall,
- biome.salinity,
- biome.rainfall, -- biome.vegetation, -- Should be vegetation, but doesn't seem to be set before finalization.
- pole,
- is_possible_tropical_area_by_latitude,
- is_tropical_area_by_latitude)
- Add_One (Profile, "BIOME_" .. df.biome_type [biome_type])
- if biome.evilness < 33 then
- Profile.GOOD = true
- elseif biome.evilness >= 66 then
- Profile.EVIL = true
- end
- if biome.savagery >= 66 then
- Add_One (Profile, "SAVAGE")
- end
- end
- Animal_Page.Present_List = {}
- Animal_Page.Absent_List = {}
- Animal_Page.Forbidden_List = {}
- Plant_Page.Present_List = {}
- Plant_Page.Absent_List = {}
- Plant_Page.Forbidden_List = {}
- for i, creature in ipairs (df.global.world.raws.creatures.all) do
- local found = false
- local matching
- for k, v in ipairs (df.global.world.world_data.regions [region].population) do
- if Is_Animal (v.type) and
- v.race == i then
- table.insert (Animal_Page.Present_List, {name = creature.creature_id, index = i})
- found = true
- break
- end
- end
- if not found then
- if creature.flags.EQUIPMENT_WAGON or
- creature.flags.CASTE_MEGABEAST or
- creature.flags.CASTE_SEMIMEGABEAST or
- -- creature.flags.GENERATED or -- When is this flag set?
- creature.flags.CASTE_TITAN or
- creature.flags.CASTE_UNIQUE_DEMON or
- creature.flags.CASTE_DEMON or
- creature.flags.CASTE_NIGHT_CREATURE_ANY or
- (creature.flags.GOOD and not Profile.GOOD) or
- (creature.flags.EVIL and not Profile.EVIL) or
- (creature.flags.SAVAGE and Profile.SAVAGE == 0) then
- matching = false
- elseif (creature.flags.BIOME_MOUNTAIN and Profile.BIOME_MOUNTAIN > 0) or
- (creature.flags.BIOME_GLACIER and Profile.BIOME_GLACIER > 0) or
- (creature.flags.BIOME_TUNDRA and Profile.BIOME_TUNDRA > 0) or
- (creature.flags.BIOME_SWAMP_TEMPERATE_FRESHWATER and Profile.BIOME_SWAMP_TEMPERATE_FRESHWATER > 0) or
- (creature.flags.BIOME_SWAMP_TEMPERATE_SALTWATER and Profile.BIOME_SWAMP_TEMPERATE_SALTWATER > 0) or
- (creature.flags.BIOME_MARSH_TEMPERATE_FRESHWATER and Profile.BIOME_MARSH_TEMPERATE_FRESHWATER > 0) or
- (creature.flags.BIOME_MARSH_TEMPERATE_SALTWATER and Profile.BIOME_MARSH_TEMPERATE_SALTWATER > 0) or
- (creature.flags.BIOME_SWAMP_TROPICAL_FRESHWATER and Profile.BIOME_SWAMP_TROPICAL_FRESHWATER > 0) or
- (creature.flags.BIOME_SWAMP_TROPICAL_SALTWATER and Profile.BIOME_SWAMP_TROPICAL_SALTWATER > 0) or
- (creature.flags.BIOME_SWAMP_MANGROVE and Profile.BIOME_SWAMP_MANGROVE > 0) or
- (creature.flags.BIOME_MARSH_TROPICAL_FRESHWATER and Profile.BIOME_MARSH_TROPICAL_FRESHWATER > 0) or
- (creature.flags.BIOME_MARSH_TROPICAL_SALTWATER and Profile.BIOME_MARSH_TROPICAL_SALTWATER > 0) or
- (creature.flags.BIOME_FOREST_TAIGA and Profile.BIOME_FOREST_TAIGA > 0) or
- (creature.flags.BIOME_FOREST_TEMPERATE_CONIFER and Profile.BIOME_FOREST_TEMPERATE_CONIFER > 0) or
- (creature.flags.BIOME_FOREST_TEMPERATE_BROADLEAF and Profile.BIOME_FOREST_TEMPERATE_BROADLEAF > 0) or
- (creature.flags.BIOME_FOREST_TROPICAL_CONIFER and Profile.BIOME_FOREST_TROPICAL_CONIFER > 0) or
- (creature.flags.BIOME_FOREST_TROPICAL_DRY_BROADLEAF and Profile.BIOME_FOREST_TROPICAL_DRY_BROADLEAF > 0) or
- (creature.flags.BIOME_FOREST_TROPICAL_MOIST_BROADLEAF and Profile.BIOME_FOREST_TROPICAL_MOIST_BROADLEAF > 0) or
- (creature.flags.BIOME_GRASSLAND_TEMPERATE and Profile.BIOME_GRASSLAND_TEMPERATE > 0) or
- (creature.flags.BIOME_SAVANNA_TEMPERATE and Profile.BIOME_SAVANNA_TEMPERATE > 0) or
- (creature.flags.BIOME_SHRUBLAND_TEMPERATE and Profile.BIOME_SHRUBLAND_TEMPERATE > 0) or
- (creature.flags.BIOME_GRASSLAND_TROPICAL and Profile.BIOME_GRASSLAND_TROPICAL > 0) or
- (creature.flags.BIOME_SAVANNA_TROPICAL and Profile.BIOME_SAVANNA_TROPICAL > 0) or
- (creature.flags.BIOME_SHRUBLAND_TROPICAL and Profile.BIOME_SHRUBLAND_TROPICAL > 0) or
- (creature.flags.BIOME_DESERT_BADLAND and Profile.BIOME_DESERT_BADLAND > 0) or
- (creature.flags.BIOME_DESERT_ROCK and Profile.BIOME_DESERT_ROCK > 0) or
- (creature.flags.BIOME_DESERT_SAND and Profile.BIOME_DESERT_SAND > 0) or
- (creature.flags.BIOME_OCEAN_TROPICAL and Profile.BIOME_OCEAN_TROPICAL > 0) or
- (creature.flags.BIOME_OCEAN_TEMPERATE and Profile.BIOME_OCEAN_TEMPERATE > 0) or
- (creature.flags.BIOME_OCEAN_ARCTIC and Profile.BIOME_OCEAN_ARCTIC > 0) then
- matching = true
- end
- if matching then
- table.insert (Animal_Page.Absent_List, {name = creature.creature_id, index = i})
- elseif Unrestricted then
- table.insert (Animal_Page.Absent_List, {name = creature.creature_id, index = i})
- end
- end
- end
- for i, plant in ipairs (df.global.world.raws.plants.all) do
- local found = false
- local matching
- for k, v in ipairs (df.global.world.world_data.regions [region].population) do
- if Is_Plant (v.type) and
- v.plant == i then
- table.insert (Plant_Page.Present_List, {name = plant.id, index = i})
- found = true
- break
- end
- end
- if not found then
- if (plant.flags.GOOD and not Profile.GOOD) or
- (plant.flags.EVIL and not Profile.EVIL) or
- (plant.flags.SAVAGE and Profile.SAVAGE == 0) then
- matching = false
- elseif (plant.flags.BIOME_MOUNTAIN and Profile.BIOME_MOUNTAIN > 0) or
- (plant.flags.BIOME_GLACIER and Profile.BIOME_GLACIER > 0) or
- (plant.flags.BIOME_TUNDRA and Profile.BIOME_TUNDRA > 0) or
- (plant.flags.BIOME_SWAMP_TEMPERATE_FRESHWATER and Profile.BIOME_SWAMP_TEMPERATE_FRESHWATER > 0) or
- (plant.flags.BIOME_SWAMP_TEMPERATE_SALTWATER and Profile.BIOME_SWAMP_TEMPERATE_SALTWATER > 0) or
- (plant.flags.BIOME_MARSH_TEMPERATE_FRESHWATER and Profile.BIOME_MARSH_TEMPERATE_FRESHWATER > 0) or
- (plant.flags.BIOME_MARSH_TEMPERATE_SALTWATER and Profile.BIOME_MARSH_TEMPERATE_SALTWATER > 0) or
- (plant.flags.BIOME_SWAMP_TROPICAL_FRESHWATER and Profile.BIOME_SWAMP_TROPICAL_FRESHWATER > 0) or
- (plant.flags.BIOME_SWAMP_TROPICAL_SALTWATER and Profile.BIOME_SWAMP_TROPICAL_SALTWATER > 0) or
- (plant.flags.BIOME_SWAMP_MANGROVE and Profile.BIOME_SWAMP_MANGROVE > 0) or
- (plant.flags.BIOME_MARSH_TROPICAL_FRESHWATER and Profile.BIOME_MARSH_TROPICAL_FRESHWATER > 0) or
- (plant.flags.BIOME_MARSH_TROPICAL_SALTWATER and Profile.BIOME_MARSH_TROPICAL_SALTWATER > 0) or
- (plant.flags.BIOME_FOREST_TAIGA and Profile.BIOME_FOREST_TAIGA > 0) or
- (plant.flags.BIOME_FOREST_TEMPERATE_CONIFER and Profile.BIOME_FOREST_TEMPERATE_CONIFER > 0) or
- (plant.flags.BIOME_FOREST_TEMPERATE_BROADLEAF and Profile.BIOME_FOREST_TEMPERATE_BROADLEAF > 0) or
- (plant.flags.BIOME_FOREST_TROPICAL_CONIFER and Profile.BIOME_FOREST_TROPICAL_CONIFER > 0) or
- (plant.flags.BIOME_FOREST_TROPICAL_DRY_BROADLEAF and Profile.BIOME_FOREST_TROPICAL_DRY_BROADLEAF > 0) or
- (plant.flags.BIOME_FOREST_TROPICAL_MOIST_BROADLEAF and Profile.BIOME_FOREST_TROPICAL_MOIST_BROADLEAF > 0) or
- (plant.flags.BIOME_GRASSLAND_TEMPERATE and Profile.BIOME_GRASSLAND_TEMPERATE > 0) or
- (plant.flags.BIOME_SAVANNA_TEMPERATE and Profile.BIOME_SAVANNA_TEMPERATE > 0) or
- (plant.flags.BIOME_SHRUBLAND_TEMPERATE and Profile.BIOME_SHRUBLAND_TEMPERATE > 0) or
- (plant.flags.BIOME_GRASSLAND_TROPICAL and Profile.BIOME_GRASSLAND_TROPICAL > 0) or
- (plant.flags.BIOME_SAVANNA_TROPICAL and Profile.BIOME_SAVANNA_TROPICAL > 0) or
- (plant.flags.BIOME_SHRUBLAND_TROPICAL and Profile.BIOME_SHRUBLAND_TROPICAL > 0) or
- (plant.flags.BIOME_DESERT_BADLAND and Profile.BIOME_DESERT_BADLAND > 0) or
- (plant.flags.BIOME_DESERT_ROCK and Profile.BIOME_DESERT_ROCK > 0) or
- (plant.flags.BIOME_DESERT_SAND and Profile.BIOME_DESERT_SAND > 0) or
- (plant.flags.BIOME_OCEAN_TROPICAL and Profile.BIOME_OCEAN_TROPICAL > 0) or
- (plant.flags.BIOME_OCEAN_TEMPERATE and Profile.BIOME_OCEAN_TEMPERATE > 0) or
- (plant.flags.BIOME_OCEAN_ARCTIC and Profile.BIOME_OCEAN_ARCTIC > 0) then
- matching = true
- end
- if matching then
- table.insert (Plant_Page.Absent_List, {name = plant.id, index = i})
- elseif Unrestricted then
- table.insert (Plant_Page.Absent_List, {name = plant.id, index = i})
- end
- end
- end
- Sort (Animal_Page.Present_List)
- Sort (Animal_Page.Absent_List)
- Sort (Plant_Page.Present_List)
- Sort (Plant_Page.Absent_List)
- return Profile
- end
- --============================================================
- function Apply_Animal_Selection (index, choice)
- if not Animal_Page.Present then
- return -- Startup, so it doesn't exist properly yet
- end
- local animal_visible = true
- if not Animal_Page.Present.active or
- choice == NIL or
- #Animal_Page.Present_List == 0 then
- animal_visible = false
- else
- local region_index = Locate_Animal (Animal_Page.Present_List [index].index)
- local element = df.global.world.world_data.regions [region].population [region_index]
- Animal_Page.Type:setText (df.world_population_type [element.type])
- Animal_Page.Race:setText (choice.text)
- Animal_Page.Min_Count:setText (Fit_Right (tostring (element.count_min), 8))
- Animal_Page.Max_Count:setText (Fit_Right (tostring (element.count_max), 8))
- end
- for i, element in ipairs (Animal_Page.Animal_Visible_List) do
- element.visible = animal_visible
- end
- end
- --============================================================
- function Apply_Plant_Selection (index, choice)
- if not Plant_Page.Present then
- return -- Startup, so it doesn't exist properly yet
- end
- local plant_visible = true
- if not Plant_Page.Present.active or
- choice == NIL or
- #Plant_Page.Present_List == 0 then
- plant_visible = false
- else
- local region_index = Locate_Plant (Plant_Page.Present_List [index].index)
- local element = df.global.world.world_data.regions [region].population [region_index]
- Plant_Page.Type:setText (df.world_population_type [element.type])
- Plant_Page.Plant:setText (choice.text)
- end
- for i, element in ipairs (Plant_Page.Plant_Visible_List) do
- element.visible = plant_visible
- end
- end
- --============================================================
- function Make_List (List)
- local Result = {}
- for i, element in ipairs (List) do
- table.insert (Result, element.name)
- end
- return Result
- end
- --============================================================
- function Update (delta_x, delta_y)
- x = x + delta_x
- if x < 0 then
- x = 0
- elseif x >= map_width then
- x = map_width - 1
- end
- y = y + delta_y
- if y < 0 then
- y = 0
- elseif y >= map_height then
- y = map_height - 1
- end
- region = df.global.world.world_data.region_map [x]:_displace (y).region_id
- evilness = df.global.world.world_data.region_map [x]:_displace (y).evilness
- size = #df.global.world.world_data.regions [region].region_coords.x
- animals = 0
- plants = 0
- for i, population in ipairs (df.global.world.world_data.regions [region].population) do
- if Is_Animal (population.type) then
- animals = animals + 1
- elseif Is_Plant (population.type) then
- plants = plants + 1
- end
- end
- Main_Page.Profile = Make_Profile (region)
- Make_Region (x, y)
- Make_Biome (x, y)
- Main_Page.X:setText (Fit_Right (tostring (x), 3))
- Main_Page.Y:setText (Fit_Right (tostring (y), 3))
- Main_Page.Biome:setText (Fit_Right (tostring (region), 4))
- Main_Page.Size:setText (Fit_Right (tostring (size), 6))
- Main_Page.Type:setText (df.world_region_type [df.global.world.world_data.regions [region].type])
- Main_Page.Evilness:setText (Fit_Right (tostring (evilness), 3))
- Main_Page.Evilness.text_pen = Savagery_Pen (evilness)
- Main_Page.Animals:setText (Fit_Right (tostring (animals), 3))
- Main_Page.Plants:setText (Fit_Right (tostring (plants), 3))
- Main_Page.Region_Grid:panCenter (x, y)
- Main_Page.Biome_Grid:panCenter (x, y)
- Animal_Page.Present:setChoices (Make_List (Animal_Page.Present_List), 1)
- Animal_Page.Absent:setChoices (Make_List (Animal_Page.Absent_List), 1)
- Apply_Animal_Selection ()
- Plant_Page.Present:setChoices (Make_List (Plant_Page.Present_List), 1)
- Plant_Page.Absent:setChoices (Make_List (Plant_Page.Absent_List), 1)
- Apply_Plant_Selection ()
- end
- --============================================================
- BiomeManipulatorUi = defclass (BiomeManipulatorUi, gui.FramedScreen)
- BiomeManipulatorUi.ATTRS = {
- frame_style = gui.GREY_LINE_FRAME,
- frame_title = "Biome Manipulator",
- }
- --============================================================
- function BiomeManipulatorUi:onHelp ()
- self.subviews.pages:setSelected (4)
- Focus = "Help"
- end
- --============================================================
- function Disclaimer ()
- local helptext = {{text = "Help/Info"}, NEWLINE, NEWLINE}
- for i, v in pairs (keybindings) do
- table.insert (helptext, {text = v.desc, key = v.key, key_sep = ': '})
- table.insert (helptext, NEWLINE)
- end
- table.insert (helptext, NEWLINE)
- local dsc =
- {"The Biome Manipulator is used pre embark to manipulate biome regions in the world, in", NEWLINE,
- "particular pre embark.", NEWLINE,
- "The main screen displays the world map using characters indicating the biome of the", NEWLINE,
- "various world tiles. This display can be alternated with a region display, where", NEWLINE,
- "regions are given a color and a letter, with no meaning other than to tell them apart.", NEWLINE,
- "The purpose of this second display is to see whether biomes belong to the same region or", NEWLINE,
- "not.", NEWLINE,
- "Above the map the main display shows the X/Y coordinates of the current world tile, the", NEWLINE,
- "biome region number it refers to (useless in itself unless using DFHack), and the", NEWLINE,
- "general type of biomes the region contains.", NEWLINE,
- "Below that information you have a number of fields where command keys are displayed", NEWLINE,
- "together with a summary of the information they control. The Evilness field shows the", NEWLINE,
- "Evilness value of the current world tile (color coded for good/neutral/evil), and", NEWLINE,
- "pressing the command key allows you to change the Evilness value for all tiles belonging", NEWLINE,
- "to the same region to the specified value. That also causes animals and plants dependent", NEWLINE,
- "on the old Evilness value but not supported by the new one to be removed from the region", NEWLINE,
- "population list. Any evil interaction associated with the region is also removed of the", NEWLINE,
- "ceases to be evil.", NEWLINE,
- "The Animals field shows the number of creature species tied to the region, and the 'a'", NEWLINE,
- "key changes the focus to the Animal page where you can add and remove creatures to/from", NEWLINE,
- "the region, as well as change the counts for creatures.", NEWLINE,
- "The Plants field shows the number of plant species tied to the region, and the 'p' key", NEWLINE,
- "changes the focus to the Plant page, which works the same as for the creature ones, but", NEWLINE,
- "on plants.", NEWLINE,
- "The Unrestricted key 'u' allows you to change the Animal and Plant selections to span", NEWLINE,
- "the complete range defined by DF (the default is restricted to what DF defines as legal)", NEWLINE,
- "for the region). Usage of this mode is mostly untested, and thus the user takes a risk", NEWLINE,
- "using it.", NEWLINE,
- "The floradiversity key 'f' sets all biome regions to contain all plants legal to their", NEWLINE,
- "respecive biomes, while the Faunadiversity one, 'F', does the same for creatures", NEWLINE,
- " throughout the world. Note that neither of these are affected by the Unrestricted value.", NEWLINE,
- "All changes performed by this tool are applied directly to DF, so the only ways to cancel", NEWLINE,
- "changes are to manually reverse them or to abort the save without embarking.", NEWLINE,
- NEWLINE,
- "The biome map uses a color coding to indicate savagery + evilness and a large number of", NEWLINE,
- "characters to indicate various biome versions.", NEWLINE,
- "The biomes listed are the ones present in the corresponding DF enumeration, (except for", NEWLINE,
- "Subterranean Chasm and Subterranean Water which aren't detected, and pools and rivers", NEWLINE,
- "which are embedded in biomes, rather than forming biomes themselves).", NEWLINE,
- NEWLINE,
- "Color coding key:", NEWLINE,
- {text = "Serene ", pen = COLOR_BLUE}, {text = "Mirthful ", pen = COLOR_GREEN}, {text = "Joyous Wilds ", pen = COLOR_LIGHTCYAN}, NEWLINE,
- {text = "Calm ", pen = COLOR_GREY}, {text = "Wilderness ", pen = COLOR_LIGHTGREEN}, {text = "Untamed Wilds", pen = COLOR_YELLOW}, NEWLINE,
- {text = "Sinister ", pen = COLOR_MAGENTA}, {text = "Haunted ", pen = COLOR_LIGHTRED}, {text = "Terrifying ", pen = COLOR_RED}, NEWLINE,
- NEWLINE,
- "The environment character symbols use lower case for the temperate version and upper case", NEWLINE,
- "for the tropical one. The one exception is d/D.", NEWLINE,
- "Biome", NEWLINE,
- "a = Arctic Ocean", NEWLINE,
- " B = Badlands", NEWLINE,
- "c = Temperate Conifer C = Tropical Conifer", NEWLINE,
- "d = Dry Tropical Broadleaf D = Sand Desert", NEWLINE,
- "e = Rocky Desert", NEWLINE,
- "g = Temperate Grassland G = Tropical Grassland", NEWLINE,
- "l = Temperate Broadleaf L = Tropical Moist Broadleaf", NEWLINE,
- " M = Mangrove Swamp", NEWLINE,
- "n = Temperate Freshwater Marsh N = Tropical Freshwater Marsh", NEWLINE,
- "o = Temperate Ocean O = Tropical Ocean", NEWLINE,
- "p = Temperate Freshwater Swamp P = Tropical Freshwater Swamp", NEWLINE,
- "r = Temperate Saltwater Swamp R = Tropical Saltwater Swamp", NEWLINE,
- "s = Temperate Savanna S = Tropical Savanna", NEWLINE,
- "t = Tundra T = Taiga", NEWLINE,
- "u = Temperate Shrubland U = Tropical Shrubland", NEWLINE,
- "Y = Temperate Saltwater Marsh Y = Tropical Saltwater Marsh", NEWLINE,
- "+ = Mountain * = Glacier", NEWLINE,
- -- " ~ = Subterranean Lava", NEWLINE, -- Commented out won't appear.
- -- ". = Temperate Freshwater Pool , = Tropical Freshwater Pool", NEWLINE,
- -- ": = Temperate Brackish Pool ; = Tropical Brackish Pool", NEWLINE,
- -- "! = Temperate Saltwater Pool | = Tropical Saltwater Pool", NEWLINE,
- "< = Temperate Freshwater Lake > = Tropical Freshwater Lake", NEWLINE,
- "- = Temperate Brackish Lake = = Tropical Brackish Lake", NEWLINE,
- "[ = Temperate Saltwater Lake ] = Tropical Saltwater Lake", NEWLINE,
- -- "\\ = Temperate Freshwater River / = Tropical Freshwater River", NEWLINE,
- -- "% = Temperate Brackish River & = Tropical Brackish River", NEWLINE,
- -- "( = Temperate Saltwater River ) = Tropical Saltwater River", NEWLINE,
- NEWLINE,
- "Version 0.1, 2017-06-26", NEWLINE,
- "Caveats: Only tested to a limited degree.", NEWLINE
- }
- for i, v in pairs (dsc) do
- table.insert (helptext, v)
- end
- return helptext
- end
- --============================================================
- function BiomeManipulatorUi:init ()
- self.stack = {}
- self.item_count = 0
- self.keys = {}
- local screen_width, screen_height = dfhack.screen.getWindowSize ()
- Main_Page.Background =
- widgets.Label {text = {{text = "Help/Info",
- key = keybindings.help.key,
- key_sep = '()'},
- " X: Y: Biome: Size: Type:", NEWLINE,
- {text = "",
- key = keybindings.evilness.key,
- key_sep = '()'},
- {text = " Evilness: ",
- pen = COLOR_LIGHTBLUE},
- {text = "",
- key = keybindings.animals.key,
- key_sep = '()'},
- {text = " Animals: ",
- pen = COLOR_LIGHTBLUE},
- {text = "",
- key = keybindings.plants.key,
- key_sep = '()'},
- {text = " Plants:",
- pen = COLOR_LIGHTBLUE}, NEWLINE,
- {text = "",
- key = keybindings.unrestricted.key,
- key_sep = '()'},
- {text = " Unrestricted: ",
- pen = COLOR_LIGHTBLUE},
- {text = "",
- key = keybindings.floradiversity.key,
- key_sep = '()'},
- {text = " floradiversity",
- pen = COLOR_LIGHTBLUE},
- {text = "",
- key = keybindings.faunadiversity.key,
- key_sep = '()'},
- {text = " Faunadiversity",
- pen = COLOR_LIGHTBLUE}},
- frame = {l = 1, t = 1, y_align = 0}}
- Main_Page.X =
- widgets.Label {text = Fit_Right (tostring (x), 3),
- frame = {l = 17, t = 1, yalign = 0}}
- Main_Page.Y =
- widgets.Label {text = Fit_Right (tostring (y), 3),
- frame = {l = 23, t = 1, yalign = 0}}
- Main_Page.Biome =
- widgets.Label {text = Fit_Right (tostring (region), 4),
- frame = {l = 33, t = 1, yalign = 0}}
- Main_Page.Size =
- widgets.Label {text = Fit_Right (tostring (size), 6),
- frame = {l = 43, t = 1, yalign = 0}}
- Main_Page.Type =
- widgets.Label {text = df.world_region_type [df.global.world.world_data.regions [region].type],
- frame = {l = 56, t = 1, yalign = 0}}
- Main_Page.Evilness =
- widgets.Label {text = Fit_Right (tostring (evilness), 3),
- frame = {l = 15, t = 2, yalign = 0},
- text_pen = Savagery_Pen (evilness)}
- Main_Page.Animals =
- widgets.Label {text = Fit_Right (tostring (animals), 3),
- frame = {l = 34, t = 2, yalign = 0},
- text_pen = COLOR_LIGHTBLUE}
- Main_Page.Plants =
- widgets.Label {text = Fit_Right (tostring (plants), 3),
- frame = {l = 50, t = 2, yalign = 0},
- text_pen = COLOR_LIGHTBLUE}
- Main_Page.Unrestricted =
- widgets.Label {text = tostring (Unrestricted),
- frame = {l = 20, t = 3, yalign = 0},
- text_pen = COLOR_LIGHTBLUE}
- Main_Page.Region_Grid = Grid {frame = {l = 1,
- t = 6,
- r = math.min (map_width, screen_width - 1),
- b = math.min (map_height + 4, screen_height - 2)},
- width = map_width,
- height = map_height,
- visible = false}
- Main_Page.Biome_Grid = Grid {frame = {l = 1,
- t = 6,
- r = math.min (map_width, screen_width - 1),
- b = math.min (map_height + 4, screen_height - 2)},
- width = map_width,
- height = map_height,
- visible = true}
- Make_Region (x, y)
- Make_Biome (x, y)
- Main_Page.Profile = Make_Profile (region)
- local mainPage = widgets.Panel {
- subviews = {Main_Page.Background,
- Main_Page.X,
- Main_Page.Y,
- Main_Page.Biome,
- Main_Page.Size,
- Main_Page.Type,
- Main_Page.Evilness,
- Main_Page.Animals,
- Main_Page.Plants,
- Main_Page.Unrestricted,
- Main_Page.Region_Grid,
- Main_Page.Biome_Grid}}
- Animal_Page.Background =
- widgets.Label {text = "Creatures Present Creatures Absent",
- frame = {l = 1, t = 4, yalign = 0}}
- Animal_Page.Animal_Background =
- widgets.Label {text = {" Type: Race:\n",
- {text = "",
- key = keybindings.min_count.key,
- key_sep = '()'},
- {text = " Count min: ",
- pen = COLOR_LIGHTBLUE},
- {text = "",
- key = keybindings.max_count.key,
- key_sep = '()'},
- {text = " Count Max:",
- pen = COLOR_LIGHTBLUE}},
- frame = {l = 1, t = 1, yalign = 0}}
- Animal_Page.Animal_Visible_List = {}
- table.insert (Animal_Page.Animal_Visible_List, Animal_Page.Animal_Background)
- Animal_Page.Type =
- widgets.Label {text = "",
- frame = {l = 12, t = 1, yalign = 0}}
- table.insert (Animal_Page.Animal_Visible_List, Animal_Page.Type)
- Animal_Page.Race =
- widgets.Label {text = "",
- frame = {l = 37, t = 1, yalign = 0}}
- table.insert (Animal_Page.Animal_Visible_List, Animal_Page.Race)
- Animal_Page.Min_Count =
- widgets.Label {text = "",
- frame = {l = 17, t = 2, yalign = 0}}
- table.insert (Animal_Page.Animal_Visible_List, Animal_Page.Min_Count)
- Animal_Page.Max_Count =
- widgets.Label {text = "",
- frame = {l = 42, t = 2, yalign = 0}}
- table.insert (Animal_Page.Animal_Visible_List, Animal_Page.Max_Count)
- Animal_Page.Present =
- widgets.List {view_id = "Present Animals",
- choices = Make_List (Animal_Page.Present_List),
- frame = {l = 1, r = 25, t = 6, yalign = 0},
- on_submit = self:callback ("removeAnimal"),
- text_pen = COLOR_DARKGRAY,
- cursor_pen = COLOR_YELLOW,
- inactive_pen = COLOR_GREY,
- on_select = (function (index, choice) Apply_Animal_Selection (index, choice) end)}
- Apply_Animal_Selection (Animal_Page.Present:getSelected ())
- Animal_Page.Absent =
- widgets.List {view_id = "Absent Animals",
- choices = Make_List (Animal_Page.Absent_List),
- frame = {l = 27, r = 51, t = 6, yalign = 0},
- on_submit = self:callback ("addAnimal"),
- text_pen = COLOR_DARKGRAY,
- cursor_pen = COLOR_YELLOW,
- inactive_pen = COLOR_GREY}
- local animalPage = widgets.Panel {
- subviews = {Animal_Page.Background,
- Animal_Page.Animal_Background,
- Animal_Page.Type,
- Animal_Page.Race,
- Animal_Page.Min_Count,
- Animal_Page.Max_Count,
- Animal_Page.Present,
- Animal_Page.Absent}}
- Plant_Page.Background =
- widgets.Label {text = "Plants Present Plants Absent",
- frame = {l = 1, t = 4, yalign = 0}}
- Plant_Page.Plant_Background =
- widgets.Label {text = {" Type: Plant:"},
- frame = {l = 1, t = 1, yalign = 0}}
- Plant_Page.Plant_Visible_List = {}
- table.insert (Plant_Page.Plant_Visible_List, Plant_Page.Plant_Background)
- Plant_Page.Type =
- widgets.Label {text = "",
- frame = {l = 12, t = 1, yalign = 0}}
- table.insert (Plant_Page.Plant_Visible_List, Plant_Page.Type)
- Plant_Page.Plant =
- widgets.Label {text = "",
- frame = {l = 37, t = 1, yalign = 0}}
- table.insert (Plant_Page.Plant_Visible_List, Plant_Page.Plant)
- Plant_Page.Present =
- widgets.List {view_id = "Present Plants",
- choices = Make_List (Plant_Page.Present_List),
- frame = {l = 1, r = 25, t = 6, yalign = 0},
- on_submit = self:callback ("removePlant"),
- text_pen = COLOR_DARKGRAY,
- cursor_pen = COLOR_YELLOW,
- inactive_pen = COLOR_GREY,
- on_select = (function (index, choice) Apply_Plant_Selection (index, choice) end)}
- Apply_Plant_Selection (Plant_Page.Present:getSelected ())
- Plant_Page.Absent =
- widgets.List {view_id = "Absent Plants",
- choices = Make_List (Plant_Page.Absent_List),
- frame = {l = 27, r= 51, t = 6, yalign = 0},
- on_submit = self:callback ("addPlant"),
- text_pen = COLOR_DARKGRAY,
- cursor_pen = COLOR_YELLOW,
- inactive_pen = COLOR_GREY}
- local plantPage = widgets.Panel {
- subviews = {Plant_Page.Background,
- Plant_Page.Plant_Background,
- Plant_Page.Type,
- Plant_Page.Plant,
- Plant_Page.Present,
- Plant_Page.Absent}}
- helpPage = widgets.Panel {
- subviews = {widgets.Label {text = Disclaimer (),
- frame = {l = 1, t = 1, yalign = 0}}}}
- local pages = widgets.Pages
- {subviews = {mainPage,
- animalPage,
- plantPage,
- helpPage},view_id = "pages",
- }
- pages:setSelected (1)
- Focus = "Main"
- self:addviews {pages}
- end
- --==============================================================
- function BiomeManipulatorUi:updateEvilness (value)
- if not tonumber (value) or
- tonumber (value) < 0 or
- tonumber (value) > 100 then
- dialog.showMessage ("Error!", "The Evilness legal range is 0 - 100", COLOR_LIGHTRED)
- else
- local val = tonumber (value)
- local purge_good = false
- local purge_evil = false
- local typ
- local x_coord
- if evilness < 33 and
- val >= 33 then
- purge_good = true
- elseif evilness >= 66 and val < 66 then
- purge_evil = true
- end
- if purge_good or purge_evil then
- for i = #df.global.world.world_data.regions [region].population - 1, 0, -1 do
- typ = df.global.world.world_data.regions [region].population [i].type
- if Is_Animal (typ) then
- if (purge_good and
- df.global.world.raws.creatures.all [df.global.world.world_data.regions [region].population [i].race].flags.GOOD) or
- (purge_evil and
- df.global.world.raws.creatures.all [df.global.world.world_data.regions [region].population [i].race].flags.EVIL) then
- df.global.world.world_data.regions [region].population:erase (i)
- end
- elseif Is_Plant (typ) then
- if (purge_good and
- df.global.world.raws.plants.all [df.global.world.world_data.regions [region].population [i].plant].flags.GOOD) or
- (purge_evil and
- df.global.world.raws.plants.all [df.global.world.world_data.regions [region].population [i].plant].flags.EVIL) then
- df.global.world.world_data.regions [region].population:erase (i)
- end
- end
- end
- end
- if purge_evil then
- for i = #df.global.world.interaction_instances.all - 1, 0, -1 do
- if df.global.world.interaction_instances.all [i].region_index == region then
- df.global.world.interaction_instances.all:erase (i)
- end
- end
- end
- for i, x_coord in ipairs (df.global.world.world_data.regions [region].region_coords.x) do
- df.global.world.world_data.region_map [x_coord]:_displace (df.global.world.world_data.regions [region].region_coords.y [i]).evilness = val
- end
- end
- Update (0, 0)
- end
- --==============================================================
- function BiomeManipulatorUi:Floradiversity ()
- local Profile
- local unrestricted_cache = Unrestricted
- local plant
- Unrestricted = false
- for i, biome_region in ipairs (df.global.world.world_data.regions) do
- dfhack.println ("Updating flora for region " .. tostring (i))
- Profile = Make_Profile (i)
- for k, plant_entry in ipairs (Plant_Page.Absent_List) do
- plant = df.global.world.raws.plants.all [plant_entry.index]
- local new_plant = df.world_population:new ()
- new_plant.plant = plant_entry.index
- if plant.flags.TREE then
- new_plant.type = df.world_population_type.Tree
- elseif plant.flags.GRASS then
- new_plant.type = df.world_population_type.Grass
- else
- new_plant.type = df.world_population_type.Bush
- end
- new_plant.count_min = 10000001
- new_plant.count_max = 10000001
- df.global.world.world_data.regions [i].population:insert ("#", new_plant)
- end
- end
- Unrestricted = unrestricted_cache
- Update (0, 0)
- end
- --==============================================================
- function BiomeManipulatorUi:Faunadiversity ()
- local Profile
- local unrestricted_cache = Unrestricted
- local creature
- Unrestricted = false
- for i, biome_region in ipairs (df.global.world.world_data.regions) do
- dfhack.println ("Updating fauna for region " .. tostring (i))
- Profile = Make_Profile (i)
- for k, animal_entry in ipairs (Animal_Page.Absent_List) do
- creature = df.global.world.raws.creatures.all [animal_entry.index]
- local new_creature = df.world_population:new ()
- new_creature.race = animal_entry.index
- if creature.flags.VERMIN_SOIL_COLONY then
- new_creature.type = df.world_population_type.ColonyInsect
- elseif creature.flags.any_vermin then
- if creature.flags.UBIQUITOUS then
- new_creature.type = df.world_population_type.VerminInnumerable
- else
- new_creature.type = df.world_population_type.Vermin
- end
- else
- new_creature.type = df.world_population_type.Animal
- end
- if creature.flags.UBIQUITOUS then
- new_creature.count_min = 10000001
- new_creature.count_max = 10000001
- else
- local creature_biome_count = 0
- for t, q in pairs (Profile) do
- if type (q) == 'number' and
- q ~= "SAVAGE" and
- creature.flags [t] then
- creature_biome_count = creature_biome_count + q
- end
- end
- if creature.flags.SAVAGE then
- creature_biome_count = math.min (creature_biome_count, Profile.SAVAGE)
- end
- new_creature.count_min = creature_biome_count * (7 + math.random (9))
- new_creature.count_max = new_creature.count_min
- end
- df.global.world.world_data.regions [i].population:insert ("#", new_creature)
- end
- end
- Unrestricted = unrestricted_cache
- Update (0, 0)
- end
- --==============================================================
- function BiomeManipulatorUi:removeAnimal (index, choice)
- if choice ~= NIL then
- table.insert (Animal_Page.Absent_List, {name = choice.text, index = Animal_Page.Present_List [index].index})
- Sort (Animal_Page.Absent_List)
- Animal_Page.Absent:setChoices (Make_List (Animal_Page.Absent_List))
- df.global.world.world_data.regions [region].population:erase (Locate_Animal (Animal_Page.Present_List [index].index))
- table.remove (Animal_Page.Present_List, index)
- Animal_Page.Present:setChoices (Make_List (Animal_Page.Present_List))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:addAnimal (index, choice)
- if choice ~= NIL then
- table.insert (Animal_Page.Present_List, {name = choice.text, index = Animal_Page.Absent_List [index].index})
- Sort (Animal_Page.Present_List)
- Animal_Page.Present:setChoices (Make_List (Animal_Page.Present_List))
- local creature = df.global.world.raws.creatures.all [Animal_Page.Absent_List [index].index]
- local new_creature = df.world_population:new ()
- new_creature.race = Animal_Page.Absent_List [index].index
- if creature.flags.VERMIN_SOIL_COLONY then
- new_creature.type = df.world_population_type.ColonyInsect
- elseif creature.flags.any_vermin then
- if creature.flags.UBIQUITOUS then
- new_creature.type = df.world_population_type.VerminInnumerable
- else
- new_creature.type = df.world_population_type.Vermin
- end
- else
- new_creature.type = df.world_population_type.Animal
- end
- if creature.flags.UBIQUITOUS then
- new_creature.count_min = 10000001
- new_creature.count_max = 10000001
- else
- local creature_biome_count = 0
- for t, q in pairs (Main_Page.Profile) do
- if type (q) == 'number' and
- q ~= "SAVAGE" and
- creature.flags [t] then
- creature_biome_count = creature_biome_count + q
- end
- end
- if creature.flags.SAVAGE then
- creature_biome_count = math.min (creature_biome_count, Main_Page.Profile.SAVAGE)
- end
- new_creature.count_min = creature_biome_count * (7 + math.random (9))
- new_creature.count_max = new_creature.count_min
- end
- df.global.world.world_data.regions [region].population:insert ("#", new_creature)
- table.remove (Animal_Page.Absent_List, index)
- Animal_Page.Absent:setChoices (Make_List (Animal_Page.Absent_List))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:updateAnimalMinCount (value)
- if not tonumber (value) or
- tonumber (value) < 0 or
- tonumber (value) > tonumber (Animal_Page.Max_Count.text) then
- dialog.showMessage ("Error!", "The min count cannot be negative or exceed Max count", COLOR_LIGHTRED)
- else
- local index, choice = Animal_Page.Present:getSelected ()
- local pop_index = Locate_Animal (Animal_Page.Present_List [index].index)
- df.global.world.world_data.regions [region].population [pop_index].count_min = tonumber (value)
- Animal_Page.Min_Count:setText (Fit_Right (value, 8))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:updateAnimalMaxCount (value)
- if not tonumber (value) or
- tonumber (value) < 0 or
- tonumber (value) < tonumber (Animal_Page.Min_Count.text) then
- dialog.showMessage ("Error!", "The Max count cannot be negative or less than the min count", COLOR_LIGHTRED)
- else
- local index, choice = Animal_Page.Present:getSelected ()
- local pop_index = Locate_Animal (Animal_Page.Present_List [index].index)
- df.global.world.world_data.regions [region].population [pop_index].count_max = tonumber (value)
- Animal_Page.Max_Count:setText (Fit_Right (value, 8))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:removePlant (index, choice)
- if choice ~= NIL then
- table.insert (Plant_Page.Absent_List, {name = choice.text, index = Plant_Page.Present_List [index].index})
- Sort (Plant_Page.Absent_List)
- Plant_Page.Absent:setChoices (Make_List (Plant_Page.Absent_List))
- df.global.world.world_data.regions [region].population:erase (Locate_Plant (Plant_Page.Present_List [index].index))
- table.remove (Plant_Page.Present_List, index)
- Plant_Page.Present:setChoices (Make_List (Plant_Page.Present_List))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:addPlant (index, choice)
- if choice ~= NIL then
- table.insert (Plant_Page.Present_List, {name = choice.text, index = Plant_Page.Absent_List [index].index})
- Sort (Plant_Page.Present_List)
- Plant_Page.Present:setChoices (Make_List (Plant_Page.Present_List))
- local plant = df.global.world.raws.plants.all [Plant_Page.Absent_List [index].index]
- local new_plant = df.world_population:new ()
- new_plant.plant = Plant_Page.Absent_List [index].index
- if plant.flags.TREE then
- new_plant.type = df.world_population_type.Tree
- elseif plant.flags.GRASS then
- new_plant.type = df.world_population_type.Grass
- else
- new_plant.type = df.world_population_type.Bush
- end
- new_plant.count_min = 10000001
- new_plant.count_max = 10000001
- df.global.world.world_data.regions [region].population:insert ("#", new_plant)
- table.remove (Plant_Page.Absent_List, index)
- Plant_Page.Absent:setChoices (Make_List (Plant_Page.Absent_List))
- end
- end
- --==============================================================
- function BiomeManipulatorUi:onInput (keys)
- if keys.LEAVESCREEN_ALL then
- self:dismiss ()
- end
- if keys.LEAVESCREEN then
- if Focus == "Help" or
- Focus == "Animal" or
- Focus == "Plant" then
- Focus = "Main"
- self.subviews.pages:setSelected (1)
- else
- self:dismiss ()
- end
- end
- if keys [keybindings.evilness.key] then
- if Focus == "Main" then
- dialog.showInputPrompt("Evilness",
- "Changing evilness to a different range will result\n" ..
- "in all plants and animals dependent on the former\n" ..
- "Evilness to be removed from the biome.\n" ..
- "Any change to the Evilness value will cause that\n" ..
- "value to be applied to all world tiles belonging\n" ..
- "to the edited region, destroying any variation\n\n" ..
- "Also removes any interactions associated with the\n" ..
- "region.\n" ..
- "Evilness (" .. tostring (evilness) .."):",
- COLOR_WHITE,
- "",
- self:callback ("updateEvilness"))
- end
- elseif keys [keybindings.animals.key] then
- Animal_Page.Present.active = true
- Animal_Page.Absent.active = false
- Apply_Animal_Selection (Animal_Page.Present:getSelected ())
- Focus = "Animal"
- self.subviews.pages:setSelected (2)
- elseif keys [keybindings.plants.key] then
- Plant_Page.Present.active = true
- Plant_Page.Absent.active = false
- Apply_Plant_Selection (Plant_Page.Present:getSelected ())
- Focus = "Plant"
- self.subviews.pages:setSelected (3)
- elseif keys [keybindings.unrestricted.key] then
- if Focus == "Main" then
- if not Unrestricted then
- dialog.showYesNoPrompt("Enabling unrestricted plant and creature selection",
- "Defaults to disabled for a reason...\n" ..
- "When Unrestricted is True the plant and creature\n" ..
- "selection choices list all those existing in DF\n" ..
- "regardless of whether they make sense or not.\n" ..
- "Using this mode is completely on the user's own\n" ..
- "responsibility, as potential results are crashes\n" ..
- "(probably not), plain failure to have any effect\n" ..
- "(not unreasonable), or just stupid.\n" ..
- "Are you sure you want to enable Unrestricted mode?",
- COLOR_MAGENTA,
- (function () Unrestricted = true
- Main_Page.Unrestricted:setText (tostring (Unrestricted))
- Update (0, 0)
- end),
- (function () end))
- else
- dialog.showMessage ("Leaving Terra Incognita", "You have returned to plant/creature selections within the normal DF habitat bounds.")
- Unrestricted = false
- Main_Page.Unrestricted:setText (tostring (Unrestricted))
- Update (0, 0)
- end
- end
- elseif keys [keybindings.floradiversity.key] then
- if Focus == "Main" then
- dialog.showYesNoPrompt("Floradiversity",
- "This command assigns all plants legal to each region\n" ..
- "in the world to be present in those regions\n" ..
- "Are you sure you want to do that?",
- COLOR_WHITE,
- self:callback ("Floradiversity"),
- (function () end))
- end
- elseif keys [keybindings.faunadiversity.key] then
- if Focus == "Main" then
- dialog.showYesNoPrompt("Faunadiversity",
- "This command assigns all creatures legal to each region\n" ..
- "in the world to be present in those regions\n" ..
- "Are you sure you want to do that?",
- COLOR_WHITE,
- self:callback ("Faunadiversity"),
- (function () end))
- end
- elseif keys [keybindings.region.key] then
- Main_Page.Region_Grid.visible = true
- Main_Page.Biome_Grid.visible = false
- elseif keys [keybindings.biome.key] then
- Main_Page.Region_Grid.visible = false
- Main_Page.Biome_Grid.visible = true
- elseif keys [keybindings.next_edit.key] or
- keys [keybindings.prev_edit.key] then -- As long as there's only two objects...
- if Focus == "Animal" then
- if Animal_Page.Present.active then
- Animal_Page.Present.active = false
- Animal_Page.Absent.active = true
- for i, element in ipairs (Animal_Page.Animal_Visible_List) do
- element.visible = false
- end
- else
- Animal_Page.Present.active = true
- Animal_Page.Absent.active = false
- Apply_Animal_Selection (Animal_Page.Present:getSelected ())
- end
- elseif Focus == "Plant" then
- if Plant_Page.Present.active then
- Plant_Page.Present.active = false
- Plant_Page.Absent.active = true
- for i, element in ipairs (Plant_Page.Plant_Visible_List) do
- element.visible = false
- end
- else
- Plant_Page.Present.active = true
- Plant_Page.Absent.active = false
- Apply_Plant_Selection (Plant_Page.Present:getSelected ())
- end
- end
- elseif keys [keybindings.min_count.key] then
- if Focus == "Animal" and
- Animal_Page.Min_Count.visible then
- dialog.showInputPrompt("min count",
- "Has to be non negative and less than or equal to\n" ..
- "Max Count\n" ..
- "min count (" .. tostring (Animal_Page.Min_Count.text) .."):",
- COLOR_WHITE,
- "",
- self:callback ("updateAnimalMinCount"))
- end
- elseif keys [keybindings.max_count.key] then
- if Focus == "Animal" and
- Animal_Page.Max_Count.visible then
- dialog.showInputPrompt("Max count",
- "Has to be non negative and equal to or greater than\n" ..
- "min Count\n" ..
- "Max count (" .. tostring (Animal_Page.Max_Count.text) .."):",
- COLOR_WHITE,
- "",
- self:callback ("updateAnimalMaxCount"))
- end
- elseif keys [keybindings.up.key] then
- if Focus == "Main" then
- Update (0, -1)
- end
- elseif keys [keybindings.down.key] then
- if Focus == "Main" then
- Update (0, 1)
- end
- elseif keys [keybindings.left.key] then
- if Focus == "Main" then
- Update (-1, 0)
- end
- elseif keys [keybindings.right.key] then
- if Focus == "Main" then
- Update (1, 0)
- end
- elseif keys [keybindings.upleft.key] then
- if Focus == "Main" then
- Update (-1, -1)
- end
- elseif keys [keybindings.upright.key] then
- if Focus == "Main" then
- Update (1, -1)
- end
- elseif keys [keybindings.downleft.key] then
- if Focus == "Main" then
- Update (-1, 1)
- end
- elseif keys [keybindings.downright.key] then
- if Focus == "Main" then
- Update (1, 1)
- end
- end
- self.super.onInput (self, keys)
- end
- --============================================================
- function Show_Viewer ()
- local screen = BiomeManipulatorUi {}
- persist_screen = screen
- screen:show ()
- end
- --============================================================
- Show_Viewer ()
- end
- if not dfhack.isWorldLoaded () then
- dfhack.color (COLOR_LIGHTRED)
- dfhack.print ("Error: This script requires a world to be loaded.")
- dfhack.color(COLOR_RESET)
- dfhack.println ()
- return
- end
- if #args > 1 or
- #args == 1 and
- (tonumber (args [1]) == NIL or
- tonumber (args [1]) < 0 or
- tonumber (args [1]) >= #df.global.world.world_data.regions) then
- dfhack.color (COLOR_LIGHTRED)
- dfhack.print ("biomemanipulator takes either no arguments, or a single numerical argument specifying the number of the biome region")
- dfhack.color (COLOR_RESET)
- dfhack.println ()
- return
- end
- biomemanipulator (args [1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement