Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New map #788

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
216 changes: 121 additions & 95 deletions postinit/map/forest_map.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
local modimport = modimport
GLOBAL.setfenv(1, GLOBAL)

require("constants")
require("mathutil")
require("map/storygen")

local separate_region = require("map/separate_region")
local Levels = require("map/levels")

local build_map = require("map/build_map")
local build_porkland = require("map/build_porkland")
local startlocations = require("map/startlocations")
local forest_map = require("map/forest_map")
Expand Down Expand Up @@ -50,33 +54,14 @@ end
local SKIP_GEN_CHECKS = false
local _Generate = forest_map.Generate
local GetTileForNoiseTile = ToolUtil.GetUpvalue(_Generate, "GetTileForNoiseTile")
local pickspawnprefab = ToolUtil.GetUpvalue(_Generate, "pickspawnprefab")
local pickspawngroup = ToolUtil.GetUpvalue(_Generate, "pickspawngroup")
local pickspawncountprefabforground = ToolUtil.GetUpvalue(_Generate, "pickspawncountprefabforground")
local TranslateWorldGenChoices = ToolUtil.GetUpvalue(_Generate, "TranslateWorldGenChoices")
local SpawnFunctions = {
pickspawnprefab = ToolUtil.GetUpvalue(_Generate, "pickspawnprefab"),
pickspawngroup = ToolUtil.GetUpvalue(_Generate, "pickspawngroup"),
pickspawncountprefabforground = ToolUtil.GetUpvalue(_Generate, "pickspawncountprefabforground"),
}

forest_map.Generate = function(prefab, map_width, map_height, tasks, level, level_type, ...)
assert(level.overrides ~= nil, "Level must have overrides specified.")

local is_porkland = level.location == "porkland"
Node.is_porkland = is_porkland
if not is_porkland then
return _Generate(prefab, map_width, map_height, tasks, level, level_type, ...)
end

TRANSLATE_TO_PREFABS["grass"] = {"grass", "grass_tall", "grass_tall_bunche_patch"}

WorldSim:SetPointsBarrenOrReservedTile(WORLD_TILES.ROAD)
WorldSim:SetResolveNoiseFunction(GetTileForNoiseTile)

WorldSim:SetValidateGroundTileFunction(validate_ground_tile)

local SpawnFunctions = {
pickspawnprefab = pickspawnprefab,
pickspawngroup = pickspawngroup,
pickspawncountprefabforground = pickspawncountprefabforground,
}

local function GetWorldGenParams(level, level_type)
local current_gen_params = deepcopy(level.overrides)
local default_impassible_tile = WORLD_TILES.IMPASSABLE

Expand All @@ -98,16 +83,16 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
end
end

if current_gen_params.islands ~= nil then
if current_gen_params.islands ~= nil then
local percent = {always = 1, never = 0, default = 0.2, sometimes = 0.1, often = 0.8}
story_gen_params.island_percent = percent[current_gen_params.islands]
end

if current_gen_params.branching ~= nil then
if current_gen_params.branching ~= nil then
story_gen_params.branching = current_gen_params.branching
end

if current_gen_params.loop ~= nil then
if current_gen_params.loop ~= nil then
local loop_percent = { never = 0, default = nil, always = 1.0 }
local loop_target = { never = "any", default = nil, always = "end"}
story_gen_params.loop_percent = loop_percent[current_gen_params.loop]
Expand Down Expand Up @@ -141,8 +126,16 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
end
end

return current_gen_params, story_gen_params
end

local function InitWorld(world_size, join_islands, topology_save)
WorldSim:SetPointsBarrenOrReservedTile(WORLD_TILES.ROAD)
WorldSim:SetResolveNoiseFunction(GetTileForNoiseTile)
WorldSim:SetValidateGroundTileFunction(validate_ground_tile)

local min_size = 350
if current_gen_params.world_size ~= nil then
if world_size ~= nil then
local sizes
if PLATFORM == "PS4" then
sizes = {
Expand All @@ -152,36 +145,30 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
}
else
sizes = {
["tiny"] = 250,
["small"] = 350,
["tiny"] = 1,
["small"] = 50,
["medium"] = 400,
["default"] = 425, -- default == large, at the moment...
["large"] = 425,
["huge"] = 450,
}
end

if sizes[current_gen_params.world_size] then
min_size = sizes[current_gen_params.world_size]
print("New size:", min_size, current_gen_params.world_size)
if sizes[world_size] then
min_size = sizes[world_size]
print("New size:", min_size, world_size)
else
print("ERROR: Worldgen preset had an invalid size: "..current_gen_params.world_size)
print("ERROR: Worldgen preset had an invalid size: " .. world_size)
end
end
map_width = min_size
map_height = min_size
local map_width = min_size
local map_height = min_size
WorldSim:SetWorldSize(map_width, map_height)

print("Creating story...")
require("map/storygen")
local topology_save, storygen = BuildPorkLandStory(tasks, story_gen_params, level)

WorldSim:WorldGen_InitializeNodePoints();

WorldSim:WorldGen_VoronoiPass(100)

print("... story created")

print("Baking map...", min_size)

if not WorldSim:WorldGen_Commit() then
Expand All @@ -193,63 +180,101 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
end

topology_save.root:ApplyPoisonTag()
WorldSim:ConvertToTileMap(min_size)

-- WorldSim:SeparateIslands()
WorldSim:ConvertToTileMap(min_size)

print("Map Baked!")
map_width, map_height = WorldSim:GetWorldSize()

local join_islands = not current_gen_params.no_joining_islands

-- Note: This also generates land tiles
local ground_fill = WORLD_TILES.DIRT
WorldSim:ForceConnectivity(join_islands, false, ground_fill)

-- WorldSim:SeparateIslands()

return map_width, map_height
end

local function MakeFakeStory(story_gen_params)
local level_data = Levels.GetDataForLevelID("PORKLAND_TEST")
level_data.overrides.world_size = "medium"
local level = Level(level_data)
level:ChooseTasks()
level:ChooseSetPieces()
local tasks = level:GetTasksForLevel()

local topology_save, storygen = BuildPorkLandStory(tasks, story_gen_params, level)

return topology_save, storygen
end

local function GeneratePorkland(prefab, map_width, map_height, tasks, level, level_type, ...)
TRANSLATE_TO_PREFABS["grass"] = {"grass", "grass_tall", "grass_tall_bunche_patch"}

local current_gen_params, story_gen_params = GetWorldGenParams(level, level_type)

local join_islands = not current_gen_params.no_joining_islands

print("Creating story...")
local topology_save, storygen = BuildPorkLandStory(tasks, story_gen_params, level)

print("Init world...")
map_width, map_height = InitWorld(current_gen_params.world_size, join_islands, topology_save)

if map_width == nil or map_height == nil then
return nil
end

local entities = {}
local save = {
ents = entities,
map = {
tiles = "",
roads = {},
topology = {},
generated = {
densities = {},
},
prefab = prefab,
has_ocean = current_gen_params.has_ocean,
},
}

if level.id == "PORKLAND_DEFAULT" then
modimport("postinit/map/worldsim")

build_map.RecordMap(topology_save)

collectgarbage("collect")
WorldSim:ResetAll()

local fake_topology_save, fake_storygen = MakeFakeStory(story_gen_params)
map_width, map_height = InitWorld("medium", join_islands, fake_topology_save)

local result = build_map.ReBuildMap(map_width, map_height)
if not result then
print("PANIC: Failed to generate map!")
return nil
end

save.map.topology.node_datas = WorldSim:GetNodeDatas()

WorldSim:CreateNodeIdTileMap()
topology_save.root:SaveEncode({width = map_width, height = map_height}, save.map.topology)
else
topology_save.root:SaveEncode({width = map_width, height = map_height}, save.map.topology)
WorldSim:CreateNodeIdTileMap(save.map.topology.ids)
end

-- Run Node specific functions here
local nodes = topology_save.root:GetNodes(true)
for _, node in pairs(nodes) do
node:SetTilesViaFunction(entities, map_width, map_height)
end
separate_region(nodes, 2) -- ensure at least two tiles at intervals between islands

print("Encoding...")

local save = {}
save.ents = {}
save.map = {
tiles = "",
topology = {},
prefab = prefab,
has_ocean = current_gen_params.has_ocean,
}
topology_save.root:SaveEncode({width = map_width, height = map_height}, save.map.topology)
WorldSim:CreateNodeIdTileMap(save.map.topology.ids)
print("Encoding... DONE")

-- TODO: Double check that each of the rooms has enough space (minimimum # tiles generated) - maybe countprefabs + %
-- For each item in the topology list
-- Get number of tiles for that node
-- if any are less than minumum - restart the generation

for idx, val in ipairs(save.map.topology.nodes) do
if string.find(save.map.topology.ids[idx], "LOOP_BLANK_SUB") == nil then
local area = WorldSim:GetSiteArea(save.map.topology.ids[idx])
if area < 8 then
print ("ERROR: Site "..save.map.topology.ids[idx].." area < 8: "..area)
if SKIP_GEN_CHECKS == false then
return nil
end
end
end
end

local translated_prefabs, runtime_overrides = TranslateWorldGenChoices(current_gen_params)

print("Populating voronoi...")

topology_save.root:GlobalPrePopulate(entities, map_width, map_height)
topology_save.root:ConvertGround(SpawnFunctions, entities, map_width, map_height)
WorldSim:ReplaceSingleNonLandTiles()
Expand All @@ -258,22 +283,18 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
local replace_count = WorldSim:DetectDisconnect()
--allow at most 5% of tiles to be disconnected
if replace_count > math.floor(map_width * map_height * 0.05) then
print("PANIC: Too many disconnected tiles...", replace_count)
print("PANIC: Too many disconnected tiles...",replace_count)
if SKIP_GEN_CHECKS == false then
return nil
end
else
print("disconnected tiles...", replace_count)
print("disconnected tiles...",replace_count)
end
else
print("Not checking for disconnected tiles.")
end

save.map.generated = {}
save.map.generated.densities = {}

topology_save.root:PopulateVoronoi(SpawnFunctions, entities, map_width, map_height, translated_prefabs, save.map.generated.densities)

topology_save.root:GlobalPostPopulate(entities, map_width, map_height)

for k, ents in pairs(entities) do
Expand All @@ -291,7 +312,7 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve

if translated_prefabs ~= nil then
-- Filter out any etities over our overrides
for prefab, mult in pairs(translated_prefabs) do
for prefab,mult in pairs(translated_prefabs) do
if type(mult) == "number" and mult < 1 and entities[prefab] ~= nil and #entities[prefab] > 0 then
local new_amt = math.floor(#entities[prefab]*mult)
if new_amt == 0 then
Expand All @@ -308,7 +329,6 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve

BunchSpawnerInit(entities, map_width, map_height)
BunchSpawnerRun(WorldSim)

AncientArchivePass(entities, map_width, map_height, WorldSim)

build_porkland(entities, topology_save, map_width, map_height, current_gen_params)
Expand Down Expand Up @@ -348,13 +368,11 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
end
end

save.ents = entities

save.map.tiles, save.map.tiledata, save.map.nav, save.map.adj, save.map.nodeidtilemap = WorldSim:GetEncodedMap(join_islands)
save.map.world_tile_map = GetWorldTileMap()

save.map.topology.overrides = deepcopy(current_gen_params)
save.map.topology.pl_worldgen_version = 1 -- Feel free to increase this version when making big changes
save.map.topology.pl_worldgen_version = 2 -- Feel free to increase this version when making big changes

if save.map.topology.overrides == nil then
save.map.topology.overrides = {}
Expand Down Expand Up @@ -401,9 +419,17 @@ forest_map.Generate = function(prefab, map_width, map_height, tasks, level, leve
end
end

save.map.roads = {}

print("Done "..prefab.." map gen!")

return save
return save, topology_save
end

forest_map.Generate = function(prefab, map_width, map_height, tasks, level, level_type, ...)
local is_porkland = level.location == "porkland"
Node.is_porkland = is_porkland
if not is_porkland then
return _Generate(prefab, map_width, map_height, tasks, level, level_type, ...)
end

return GeneratePorkland(prefab, map_width, map_height, tasks, level, level_type, ...)
end
Loading