饥荒是个自由度很高的游戏,shark工作组确实厉害,不过新手面对无穷尽的死亡还是很头疼。
下面两句mod里的代码注释后可以防止删档,当任务死亡后只需要按esc正常quit,小退下重进就可以了从最近的存档恢复。
目录每个版本都不一样,只要在安装目录下搜索到gamelogic.lua文件就可以了。
在OnPlayerDeath方法中注释所有调用HandleDeathCleanup的方法就可以了。
注释方法就是在句首加上“--”。
最后贴上最新版的完整代码,覆盖前友情提醒先备份原版的代码。
require "mods"
require "playerprofile"
require "saveindex"
require "screens/mainscreen"
require "screens/deathscreen"
require "screens/popupdialog"
require "screens/bigpopupdialog"
require "screens/endgamedialog"
Print (VERBOSITY.DEBUG, "[Loading frontend assets]")
local start_game_time = nil
TheSim:SetRenderPassDefaultEffect( RENDERPASS.BLOOM, "data/shaders/anim_bloom.ksh" )
TheSim:SetErosionTexture( "data/images/erosion.tex" )
--this is suuuuuper placeholdery. We need to think about how to handle all of the different types of updates for this
local function DoAgeWorld()
for k,v in pairs(Ents) do
--spoil all of the spoilables
if v.components.perishable then
v.components.perishable:Perish()
end
--send things to their homes
if v.components.homeseeker and v.components.homeseeker.home then
if v.components.homeseeker.home.components.childspawner then
v.components.homeseeker.home.components.childspawner:GoHome(v)
end
if v.components.homeseeker.home.components.spawner then
v.components.homeseeker.home.components.spawner:GoHome(v)
end
end
if v.components.fueled then
v.components.fueled:MakeEmpty()
end
end
end
local function LoadAssets(fe)
local be_prefabs = {"hud", "forest", "cave", "ceiling", "maxwell", "fire", "character_fire", "shatter"}
local fe_prefabs = {"frontend"}
local recipe_prefabs = {}
for k,v in pairs(Recipes) do
table.insert(recipe_prefabs, v.name)
if v.placer then
table.insert(recipe_prefabs, v.placer)
end
end
if fe then
print ("LOAD FE")
TheSim:LoadPrefabs(fe_prefabs)
TheSim:UnloadPrefabs(be_prefabs)
TheSim:UnloadPrefabs(recipe_prefabs)
print ("LOAD FE: done")
else
print ("LOAD BE")
TheSim:UnloadPrefabs(fe_prefabs)
TheSim:LoadPrefabs(be_prefabs)
TheSim:LoadPrefabs(recipe_prefabs)
print ("LOAD BE: done")
end
end
function GetTimePlaying()
if not start_game_time then
return 0
end
return GetTime() - start_game_time
end
function CalculatePlayerRewards(wilson)
local Progression = require "progressionconstants"
print("Calculating progression")
--increment the xp counter and give rewards
local days_survived = GetClock().numcycles
local start_xp = wilson.profile:GetXP()
local reward_xp = Progression.GetXPForDays(days_survived)
local new_xp = math.min(start_xp + reward_xp, Progression.GetXPCap())
local all_rewards = Progression.GetRewardsForTotalXP(new_xp)
for k,v in pairs(all_rewards) do
wilson.profile:UnlockCharacter(v)
end
wilson.profile:SetXP(new_xp)
print("Progression: ",days_survived, start_xp, reward_xp, new_xp)
return days_survived, start_xp, reward_xp, new_xp
end
local function HandleDeathCleanup(wilson, data)
local game_time = GetClock():ToMetricsString()
if SaveGameIndex:GetCurrentMode() == "survival" then
local playtime = GetTimePlaying()
playtime = math.floor(playtime*1000)
SetTimingStat("time", "scenario", playtime)
SendTrackingStats()
local days_survived, start_xp, reward_xp, new_xp = CalculatePlayerRewards(wilson)
ProfileStatsSet("xp_gain", reward_xp)
ProfileStatsSet("xp_total", new_xp)
SubmitCompletedLevel() --close off the instance
wilson.components.health.invincible = true
wilson.profile:Save(function()
SaveGameIndex:EraseCurrent(function()
scheduler:ExecuteInTime(3, function()
TheFrontEnd:PushScreen(DeathScreen(days_survived, start_xp))
end)
end)
end)
elseif SaveGameIndex:GetCurrentMode() == "adventure" then
SaveGameIndex:OnFailAdventure(function()
scheduler:ExecuteInTime(3, function()
TheFrontEnd:Fade(false, 3, function()
local params = json.encode{reset_action="loadslot", save_slot = SaveGameIndex:GetCurrentSaveSlot(), playeranim="failadventure"}
TheSim:SetInstanceParameters(params)
TheSim:Reset()
end)
end)
end)
elseif SaveGameIndex:GetCurrentMode() == "cave" then
scheduler:ExecuteInTime(2, function()
TheFrontEnd:Fade(false, 2, function()
for k,v in pairs(Ents) do
if v.prefab == "cave_exit" then
GetPlayer().Transform:SetPosition(v.Transform:GetWorldPosition())
break
end
end
DoAgeWorld()
SaveGameIndex:SaveCurrent(function()
SaveGameIndex:OnFailCave(function()
local params = json.encode{reset_action="loadslot", save_slot = SaveGameIndex:GetCurrentSaveSlot(), playeranim="failcave"}
TheSim:SetInstanceParameters(params)
TheSim:Reset()
end)
end)
end)
end)
end
end
local function OnPlayerDeath(wilson, data)
local cause = data.cause or "unknown"
local will_resurrect = wilson.components.resurrectable and wilson.components.resurrectable:CanResurrect()
TheMixer:PushMix("death")
wilson.HUD:Hide()
local game_time = GetClock():ToMetricsString()
RecordDeathStats(cause, GetClock():GetPhase(), wilson.components.sanity.current, wilson.components.hunger.current, will_resurrect)
ProfileStatsAdd("killed_by_"..cause)
ProfileStatsAdd("deaths")
--local res = TheSim:FindFirstEntityWithTag("resurrector")
if will_resurrect then
scheduler:ExecuteInTime(4, function()
TheMixer:PopMix("death")
if wilson.components.resurrectable:DoResurrect() then
ProfileStatsAdd("resurrections")
else
--HandleDeathCleanup(wilson, data)
end
end)
else
--HandleDeathCleanup(wilson, data)
end
end
function SetUpPlayerCharacterCallbacks(wilson)
--set up on ondeath handler
wilson:ListenForEvent( "death", function(inst, data) OnPlayerDeath(wilson, data) end)
wilson:ListenForEvent( "quit",
function()
Print (VERBOSITY.DEBUG, "I SHOULD QUIT!")
TheMixer:PushMix("death")
wilson.HUD:Hide()
local playtime = GetTimePlaying()
playtime = math.floor(playtime*1000)
RecordQuitStats()
SetTimingStat("time", "scenario", playtime)
ProfileStatsSet("time_played", playtime)
SendTrackingStats()
SendAccumulatedProfileStats()
TheSim:SetInstanceParameters()
TheSim:Reset()
end)
wilson:ListenForEvent( "daycomplete",
function(it, data)
if not wilson.components.health:IsDead() then
RecordEndOfDayStats()
ProfileStatsAdd("nights_survived_iar")
SendAccumulatedProfileStats()
end
end, GetWorld())
--[[wilson:ListenForEvent( "daytime",
function(it, data)
if not wilson.components.health:IsDead() and not wilson.is_teleporting then
--print("Day has arrived...")
--SaveGameIndex:SaveCurrent()
end
end, GetWorld())
--]]
wilson:ListenForEvent("builditem", function(inst, data) ProfileStatsAdd("build_item_"..data.item.prefab) end)
wilson:ListenForEvent("buildstructure", function(inst, data) ProfileStatsAdd("build_structure_"..data.item.prefab) end)
end
local function StartGame(wilson)
TheFrontEnd:GetSound():KillSound("FEMusic") -- just in case...
start_game_time = GetTime()
SetUpPlayerCharacterCallbacks(wilson)
end
local deprecated = { turf_webbing = true }
local replace = {
farmplot = "slow_farmplot", farmplot2 = "fast_farmplot",
farmplot3 = "fast_farmplot", sinkhole= "cave_entrance",
cave_stairs= "cave_entrance"
}
function PopulateWorld(savedata, profile, playercharacter, playersavedataoverride)
playercharacter = playercharacter or "wilson"
Print(VERBOSITY.DEBUG, "PopulateWorld")
Print(VERBOSITY.DEBUG, "[Instantiating objects...]" )
local wilson = nil
if savedata then
--figure out our start info
local spawnpoint = Vector3(0,0,0)
local playerdata = {}
if savedata.playerinfo then
if savedata.playerinfo.x and savedata.playerinfo.z then
local y = savedata.playerinfo.y or 0
spawnpoint = Vector3(savedata.playerinfo.x, y, savedata.playerinfo.z)
end
if savedata.playerinfo.data then
playerdata = savedata.playerinfo.data
end
end
if playersavedataoverride then
playerdata = playersavedataoverride
end
local newents = {}
--local world = SpawnPrefab("forest")
local world = nil
local ceiling = nil
if savedata.map.prefab == "cave" then
world = SpawnPrefab("cave")
ceiling = SpawnPrefab("ceiling")
else
world = SpawnPrefab("forest")
end
--spawn the player character and set him up
TheSim:LoadPrefabs{playercharacter}
wilson = SpawnPrefab(playercharacter)
assert(wilson, "could not spawn player character")
wilson:SetProfile(Profile)
wilson.Transform:SetPosition(spawnpoint:Get())
--this was spawned by the level file. kinda lame - we should just do everything from in here.
local ground = GetWorld()
if ground then
if GetCeiling() then
GetCeiling().MapCeiling:SetSize(savedata.map.width, savedata.map.height)
GetCeiling().MapCeiling:SetFromString(savedata.map.tiles)
GetCeiling().MapCeiling:Finalize(TheSim:GetSetting("graphics", "static_walls") == "true")
end
ground.Map:SetSize(savedata.map.width, savedata.map.height)
if savedata.map.prefab == "cave" then
ground.Map:SetPhysicsWallDistance(0.75)--0) -- TEMP for STREAM
else
ground.Map:SetPhysicsWallDistance(0)--0.75)
end
ground.Map:SetFromString(savedata.map.tiles)
ground.Map:Finalize()
if savedata.map.nav then
print("Loading Nav Grid")
ground.Map:SetNavSize(savedata.map.width, savedata.map.height)
ground.Map:SetNavFromString(savedata.map.nav)
else
print("No Nav Grid")
end
ground.hideminimap = savedata.map.hideminimap
ground.topology = savedata.map.topology
ground.meta = savedata.meta
assert(savedata.map.topology.ids, "[MALFORMED SAVE DATA] Map missing topology information. This save file is too old, and is missing neccessary information.")
for i=#savedata.map.topology.ids,1, -1 do
local name = savedata.map.topology.ids[i]
if string.find(name, "LOOP_BLANK_SUB") ~= nil then
table.remove(savedata.map.topology.ids, i)
table.remove(savedata.map.topology.nodes, i)
for eid=#savedata.map.topology.edges,1,-1 do
if savedata.map.topology.edges[eid].n1 == i or savedata.map.topology.edges[eid].n2 == i then
table.remove(savedata.map.topology.edges, eid)
end
end
end
end
if ground.topology.level_number ~= nil then
require("map/levels")
if levels.story_levels[ground.topology.level_number] ~= nil then
profile:UnlockWorldGen("preset", levels.story_levels[ground.topology.level_number].name)
end
end
wilson:AddComponent("area_aware")
--wilson:AddComponent("area_unlock")
if ground.topology.override_triggers then
wilson:AddComponent("area_trigger")
wilson.components.area_trigger:RegisterTriggers(ground.topology.override_triggers)
end
for i,node in ipairs(ground.topology.nodes) do
local story = ground.topology.ids[i]
-- guard for old saves
local story_depth = nil
if ground.topology.story_depths then
story_depth = ground.topology.story_depths[i]
end
if story ~= "START" then
story = string.sub(story, 1, string.find(story,":")-1)
--
-- if Profile:IsWorldGenUnlocked("tasks", story) == false then
-- wilson.components.area_unlock:RegisterStory(story)
-- end
end
wilson.components.area_aware:RegisterArea({idx=i, type=node.type, poly=node.poly, story=story, story_depth=story_depth})
if node.type == "Graveyard" or node.type == "MistyCavern" then
if node.area_emitter == nil then
local mist = SpawnPrefab( "mist" )
mist.Transform:SetPosition( node.cent[1], 0, node.cent[2] )
mist.components.emitter.area_emitter = CreateAreaEmitter( node.poly, node.cent )
if node.area == nil then
node.area = 1
end
mist.components.emitter.density_factor = math.ceil(node.area / 4)/31
mist.components.emitter:Emit()
end
end
end
if savedata.map.persistdata ~= nil then
ground:SetPersistData(savedata.map.persistdata)
end
wilson.components.area_aware:StartCheckingPosition()
end
wilson:SetPersistData(playerdata, newents)
if wilson.components.health.currenthealth == 0 then
wilson.components.health.currenthealth = 1
end
if savedata.playerinfo and savedata.playerinfo.id then
newents[savedata.playerinfo.id] = {entity=wilson, data=playerdata}
end
--set the clock (LEGACY! this is now handled via the world object's normal serialization)
if savedata.playerinfo.day and savedata.playerinfo.dayphase and savedata.playerinfo.timeleftinera then
GetClock().numcycles = savedata.playerinfo and savedata.playerinfo.day or 0
if savedata.playerinfo and savedata.playerinfo.dayphase == "night" then
GetClock():StartNight(true)
elseif savedata.playerinfo and savedata.playerinfo.dayphase == "dusk" then
GetClock():StartDusk(true)
else
GetClock():StartDay(true)
end
if savedata.playerinfo.timeleftinera then
GetClock().timeLeftInEra = savedata.playerinfo.timeleftinera
end
end
-- Force overrides for ambient
local retune = require("tuning_override")
retune.OVERRIDES["areaambientdefault"].doit(savedata.map.prefab)
-- Check for map overrides
if ground.topology.overrides ~= nil and ground.topology.overrides ~= nil and GetTableSize(ground.topology.overrides) > 0 then
for area, overrides in pairs(ground.topology.overrides) do
for i,override in ipairs(overrides) do
if retune.OVERRIDES[override[1]] ~= nil then
retune.OVERRIDES[override[1]].doit(override[2])
end
end
end
end
--instantiate all the dudes
for prefab, ents in pairs(savedata.ents) do
local prefab = replace[prefab] or prefab
if not deprecated[prefab] then
for k,v in ipairs(ents) do
v.prefab = v.prefab or prefab -- prefab field is stripped out when entities are saved in global entity collections, so put it back
SpawnSaveRecord(v, newents)
end
end
end
--post pass in neccessary to hook up references
for k,v in pairs(newents) do
v.entity:LoadPostPass(newents, v.data)
end
GetWorld():LoadPostPass(newents, savedata.map.persistdata)
--Run scenario scripts
for guid, ent in pairs(Ents) do
if ent.components.scenariorunner then
ent.components.scenariorunner:Run()
end
end
--Record mod information
ModManager:SetModRecords(savedata.mods or {})
if SaveGameIndex:GetCurrentMode() ~= "adventure" and GetWorld().components.age and GetPlayer().components.age then
local player_age = GetPlayer().components.age:GetAge()
local world_age = GetWorld().components.age:GetAge()
if world_age <= 0 then
GetWorld().components.age.saved_age = player_age
elseif player_age > world_age then
local catch_up = player_age - world_age
print ("Catching up world", catch_up)
LongUpdate(catch_up, true)
--this is a cheesy workaround for coming out of a cave at night, so you don't get immediately eaten
if SaveGameIndex:GetCurrentMode() == "survival" and not GetWorld().components.clock:IsDay() then
local light = SpawnPrefab("exitcavelight")
light.Transform:SetPosition(GetPlayer().Transform:GetWorldPosition())
end
end
end
else
Print(VERBOSITY.ERROR, "[MALFORMED SAVE DATA] PopulateWorld complete" )
return
end
Print(VERBOSITY.DEBUG, "[FINISHED LOADING SAVED GAME] PopulateWorld complete" )
return wilson
end
local function DrawDebugGraph(graph)
-- debug draw of new map gen
local debugdrawmap = CreateEntity()
local draw = debugdrawmap.entity:AddDebugRender()
draw:SetZ(0.1)
for idx,node in ipairs(graph.nodes) do
local colour = graph.colours[node.c]
for i =1, #node.poly-1 do
draw:Line(node.poly[i][1], node.poly[i][2], node.poly[i+1][1], node.poly[i+1][2], colour.r, colour.g, colour.b, 255)
end
draw:Line(node.poly[1][1], node.poly[1][2], node.poly[#node.poly][1], node.poly[#node.poly][2], colour.r, colour.g, colour.b, 255)
draw:Poly(node.cent[1], node.cent[2], colour.r, colour.g, colour.b, colour.a, node.poly)
draw:String(graph.ids[idx].."("..node.cent[1]..","..node.cent[2]..")", node.cent[1], node.cent[2], node.ts)
end
draw:SetZ(0.15)
for idx,edge in ipairs(graph.edges) do
if edge.n1 ~= nil and edge.n2 ~= nil then
local colour = graph.colours[edge.c]
local n1 = graph.nodes[edge.n1]
local n2 = graph.nodes[edge.n2]
if n1 ~= nil and n2 ~= nil then
draw:Line(n1.cent[1], n1.cent[2], n2.cent[1], n2.cent[2], colour.r, colour.g, colour.b, colour.a)
end
end
end
end
--OK, we have our savedata and a profile. Instatiate everything and start the game!
function DoInitGame(playercharacter, savedata, profile, next_world_playerdata, fast)
--print("DoInitGame",playercharacter, savedata, profile, next_world_playerdata, fast)
TheFrontEnd:ClearScreens()
LoadAssets(false)
assert(savedata.map, "Map missing from savedata on load")
assert(savedata.map.prefab, "Map prefab missing from savedata on load")
assert(savedata.map.tiles, "Map tiles missing from savedata on load")
assert(savedata.map.width, "Map width missing from savedata on load")
assert(savedata.map.height, "Map height missing from savedata on load")
assert(savedata.map.topology, "Map topology missing from savedata on load")
assert(savedata.map.topology.ids, "Topology entity ids are missing from savedata on load")
--assert(savedata.map.topology.story_depths, "Topology story_depths are missing from savedata on load")
assert(savedata.map.topology.colours, "Topology colours are missing from savedata on load")
assert(savedata.map.topology.edges, "Topology edges are missing from savedata on load")
assert(savedata.map.topology.nodes, "Topology nodes are missing from savedata on load")
assert(savedata.map.topology.level_type, "Topology level type is missing from savedata on load")
assert(savedata.map.topology.overrides, "Topology overrides is missing from savedata on load")
assert(savedata.playerinfo, "Playerinfo missing from savedata on load")
assert(savedata.playerinfo.x, "Playerinfo.x missing from savedata on load")
--assert(savedata.playerinfo.y, "Playerinfo.y missing from savedata on load") --y is often omitted for space, don't check for it
assert(savedata.playerinfo.z, "Playerinfo.z missing from savedata on load")
--assert(savedata.playerinfo.day, "Playerinfo day missing from savedata on load")
assert(savedata.ents, "Entites missing from savedata on load")
if savedata.map.roads then
Roads = savedata.map.roads
for k, road_data in pairs( savedata.map.roads ) do
RoadManager:BeginRoad()
local weight = road_data[1]
if weight == 3 then
for i = 2, #road_data do
local ctrl_pt = road_data[i]
RoadManager:AddControlPoint( ctrl_pt[1], ctrl_pt[2] )
end
for k, v in pairs( ROAD_STRIPS ) do
RoadManager:SetStripEffect( v, "data/shaders/road.ksh" )
end
RoadManager:SetStripTextures( ROAD_STRIPS.EDGES, "data/images/roadedge.tex", "data/images/roadnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.CENTER, "data/images/square.tex", "data/images/roadnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.CORNERS, "data/images/roadcorner.tex", "data/images/roadnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.ENDS, "data/images/roadendcap.tex", "data/images/roadnoise.tex" )
RoadManager:GenerateVB(
ROAD_PARAMETERS.NUM_SUBDIVISIONS_PER_SEGMENT,
ROAD_PARAMETERS.MIN_WIDTH, ROAD_PARAMETERS.MAX_WIDTH,
ROAD_PARAMETERS.MIN_EDGE_WIDTH, ROAD_PARAMETERS.MAX_EDGE_WIDTH,
ROAD_PARAMETERS.WIDTH_JITTER_SCALE, true )
else
for i = 2, #road_data do
local ctrl_pt = road_data[i]
RoadManager:AddControlPoint( ctrl_pt[1], ctrl_pt[2] )
end
for k, v in pairs( ROAD_STRIPS ) do
RoadManager:SetStripEffect( v, "data/shaders/road.ksh" )
end
RoadManager:SetStripTextures( ROAD_STRIPS.EDGES, "data/images/roadedge.tex", "data/images/pathnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.CENTER, "data/images/square.tex", "data/images/pathnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.CORNERS, "data/images/roadcorner.tex", "data/images/pathnoise.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.ENDS, "data/images/roadendcap.tex", "data/images/pathnoise.tex" )
RoadManager:GenerateVB(
ROAD_PARAMETERS.NUM_SUBDIVISIONS_PER_SEGMENT,
0, 0,
ROAD_PARAMETERS.MIN_EDGE_WIDTH*4, ROAD_PARAMETERS.MAX_EDGE_WIDTH*4,
0, false )
--[[
else
for i = 2, #road_data do
local ctrl_pt = road_data[i]
RoadManager:AddSmoothedControlPoint( ctrl_pt[1], ctrl_pt[2] )
end
for k, v in pairs( ROAD_STRIPS ) do
RoadManager:SetStripEffect( v, "data/shaders/river.ksh" )
end
RoadManager:SetStripTextures( ROAD_STRIPS.EDGES, "data/images/square.tex", "data/images/river_bed.tex" )
RoadManager:SetStripTextures( ROAD_STRIPS.CENTER, "data/images/square.tex", "data/images/water_river.tex" )
RoadManager:SetStripUVAnimStep( ROAD_STRIPS.CENTER, 0, 0.25 )
RoadManager:SetStripWrapMode( ROAD_STRIPS.EDGES, WRAP_MODE.CLAMP_TO_EDGE, WRAP_MODE.WRAP )
--RoadManager:SetStripTextures( ROAD_STRIPS.CORNERS, "data/images/roadcorner.tex", "data/images/pathnoise.tex" )
--RoadManager:SetStripTextures( ROAD_STRIPS.ENDS, "data/images/roadendcap.tex", "data/images/pathnoise.tex" )
RoadManager:GenerateVB(
ROAD_PARAMETERS.NUM_SUBDIVISIONS_PER_SEGMENT,
5, 5,
2, 2,
0, false )
--]]
end
end
RoadManager:GenerateQuadTree()
end
SubmitStartStats(playercharacter)
--some lame explicit loads
Print(VERBOSITY.DEBUG, "DoInitGame Loading prefabs...")
Print(VERBOSITY.DEBUG, "DoInitGame Adjusting audio...")
TheMixer:SetLevel("master", 0)
--apply the volumes
Print(VERBOSITY.DEBUG, "DoInitGame Populating world...")
local wilson = PopulateWorld(savedata, profile, playercharacter, next_world_playerdata)
if wilson then
TheCamera:SetTarget(wilson)
StartGame(wilson)
TheCamera:SetDefault()
TheCamera:Snap()
else
Print(VERBOSITY.WARNING, "DoInitGame NO WILSON?")
end
if Profile.persistdata.debug_world == 1 then
if savedata.map.topology == nil then
Print(VERBOSITY.ERROR, "OI! Where is my topology info!")
else
DrawDebugGraph(savedata.map.topology)
end
end
local function OnStart()
Print(VERBOSITY.DEBUG, "DoInitGame OnStart Callback... turning volume up")
SetHUDPause(false)
end
if not TheFrontEnd:IsDisplayingError() then
local hud = PlayerHud()
TheFrontEnd:PushScreen(hud)
hud:SetMainCharacter(wilson)
--clear the player stats, so that it doesn't count items "acquired" from the save file
GetProfileStats(true)
RecordSessionStartStats()
--after starting everything up, give the mods additional environment variables
ModManager:SimPostInit(wilson)
GetPlayer().components.health:RecalculatePenalty()
if ( SaveGameIndex:GetCurrentMode() ~= "cave" and (SaveGameIndex:GetCurrentMode() == "survival" or SaveGameIndex:GetSlotWorld() == 1) and SaveGameIndex:GetSlotDay() == 1 and GetClock():GetNormTime() == 0) then
if GetPlayer().components.inventory.starting_inventory then
for k,v in pairs(GetPlayer().components.inventory.starting_inventory) do
local item = SpawnPrefab(v)
if item then
GetPlayer().components.inventory:GiveItem(item)
end
end
end
end
if fast then
OnStart()
else
SetHUDPause(true,"InitGame")
if Settings.playeranim == "failcave" then
GetPlayer().sg:GoToState("wakeup")
GetClock():MakeNextDay()
elseif Settings.playeranim == "failadventure" then
GetPlayer().sg:GoToState("failadventure")
GetPlayer().HUD:Show()
elseif GetWorld():IsCave() then
GetPlayer().sg:GoToState("caveenter")
GetPlayer().HUD:Show()
elseif Settings.playeranim == "wakeup" or playercharacter == "waxwell" or savedata.map.nomaxwell then
GetPlayer().sg:GoToState("wakeup")
GetPlayer().HUD:Show()
--announce your freedom if you are starting as waxwell
if playercharacter == "waxwell" and SaveGameIndex:GetCurrentMode() == "survival" and (GetClock().numcycles == 0 and GetClock():GetNormTime() == 0) then
GetPlayer():DoTaskInTime( 3.5, function()
GetPlayer().components.talker:Say(GetString("waxwell", "ANNOUNCE_FREEDOM"))
end)
end
elseif (GetClock().numcycles == 0 and GetClock():GetNormTime() == 0) or Settings.maxwell ~= nil then
local max = SpawnPrefab("maxwellintro")
local speechName = "NULL_SPEECH"
if Settings.maxwell then
speechName = Settings.maxwell
elseif SaveGameIndex:GetCurrentMode() == "adventure" then
if savedata.map.override_level_string == true then
local level_id = 1
if GetWorld().meta then
level_id = GetWorld().meta.level_id or level_id
end
speechName = "ADVENTURE_"..level_id
else
speechName = "ADVENTURE_"..SaveGameIndex:GetSlotWorld()
end
else
speechName = "SANDBOX_1"
end
max.components.maxwelltalker:SetSpeech(speechName)
max.components.maxwelltalker:Initialize()
max.task = max:StartThread(function() max.components.maxwelltalker:DoTalk() end)
--PlayNIS("maxwellintro", savedata.map.maxwell)
end
local title = STRINGS.UI.SANDBOXMENU.ADVENTURELEVELS[SaveGameIndex:GetSlotLevelIndexFromPlaylist()]
local subtitle = STRINGS.UI.SANDBOXMENU.CHAPTERS[SaveGameIndex:GetSlotWorld()]
local showtitle = SaveGameIndex:GetCurrentMode() == "adventure" and title
if showtitle then
TheFrontEnd:ShowTitle(title,subtitle)
end
TheFrontEnd:Fade(true, 1, function()
SetHUDPause(false)
TheMixer:SetLevel("master", 1)
TheMixer:PushMix("normal")
TheFrontEnd:HideTitle()
--TheFrontEnd:PushScreen(PopupDialogScreen(STRINGS.UI.HUD.READYTITLE, STRINGS.UI.HUD.READY, {{text=STRINGS.UI.HUD.START, cb = function() OnStart() end}}))
end, showtitle and 3, showtitle and function() SetHUDPause(false) end )
end
if savedata.map.hideminimap ~= nil then
hud.minimap:DoTaskInTime(0, function(inst) inst.MiniMap:ClearRevealedAreas(savedata.map.hideminimap) end)
end
if savedata.map.teleportaction ~= nil then
local teleportato = TheSim:FindFirstEntityWithTag("teleportato")
if teleportato then
local pickPosition = function()
local portpositions = GetRandomInstWithTag("teleportlocation", teleportato, 1000)
if portpositions then
return Vector3(portpositions.Transform:GetWorldPosition())
else
return Vector3(savedata.playerinfo.x, savedata.playerinfo.y or 0, savedata.playerinfo.z)
end
end
teleportato.action = savedata.map.teleportaction
teleportato.maxwell = savedata.map.teleportmaxwell
teleportato.teleportpos = pickPosition()
end
end
end
--DoStartPause("Ready!")
Print(VERBOSITY.DEBUG, "DoInitGame complete")
if PRINT_TEXTURE_INFO then
c_printtextureinfo( "texinfo.csv" )
TheSim:Quit()
end
end
------------------------THESE FUNCTIONS HANDLE STARTUP FLOW
local function DoLoadWorld(saveslot, playerdataoverride)
local function onload(savedata)
DoInitGame(SaveGameIndex:GetSlotCharacter(saveslot), savedata, Profile, playerdataoverride)
end
SaveGameIndex:GetSaveData(saveslot, SaveGameIndex:GetCurrentMode(saveslot), onload)
end
local function DoGenerateWorld(saveslot, type_override)
local function onComplete(savedata )
local function onsaved()
local success, world_table = RunInSandbox(savedata)
if success then
DoInitGame(SaveGameIndex:GetSlotCharacter(saveslot), world_table, Profile, SaveGameIndex:GetPlayerData(saveslot))
end
end
SaveGameIndex:OnGenerateNewWorld(saveslot, savedata, onsaved)
end
local world_gen_options =
{
level_type = type_override or SaveGameIndex:GetCurrentMode(saveslot),
custom_options = SaveGameIndex:GetSlotGenOptions(saveslot,SaveGameIndex:GetCurrentMode()),
level_world = SaveGameIndex:GetSlotLevelIndexFromPlaylist(saveslot),
profiledata = Profile.persistdata,
}
if world_gen_options.level_type == "adventure" then
world_gen_options["adventure_progress"] = SaveGameIndex:GetSlotWorld()
elseif world_gen_options.level_type == "cave" then
world_gen_options["cave_progress"] = SaveGameIndex:GetCurrentCaveLevel()
end
TheFrontEnd:PushScreen(WorldGenScreen(Profile, onComplete, world_gen_options))
end
local function LoadSlot(slot)
TheFrontEnd:ClearScreens()
if SaveGameIndex:HasWorld(slot, SaveGameIndex:GetCurrentMode(slot)) then
DoLoadWorld(slot, SaveGameIndex:GetModeData(slot, SaveGameIndex:GetCurrentMode(slot)).playerdata)
else
LoadAssets(true)
if SaveGameIndex:GetCurrentMode(slot) == "survival" and SaveGameIndex:IsContinuePending(slot) then
local function onsave()
DoGenerateWorld(slot)
end
local function onSet(character)
SaveGameIndex:SetSlotCharacter(slot, character, onsave)
end
TheFrontEnd:PushScreen(CharacterSelectScreen(Profile, onSet, true, SaveGameIndex:GetSlotCharacter(slot)))
else
DoGenerateWorld(slot)
end
end
end
----------------LOAD THE PROFILE AND THE SAVE INDEX, AND START THE FRONTEND
local function OnFilesLoaded()
UpdateGamePurchasedState( function()
--print( "[Settings]",Settings.character, Settings.savefile)
if Settings.reset_action then
if Settings.reset_action == "loadslot" then
if not SaveGameIndex:GetCurrentMode(Settings.save_slot) then
LoadAssets(true)
TheFrontEnd:ShowScreen(MainScreen(Profile))
else
LoadSlot(Settings.save_slot)
end
elseif Settings.reset_action == "printtextureinfo" then
LoadAssets(true)
DoGenerateWorld(1)
else
LoadAssets(true)
TheFrontEnd:ShowScreen(MainScreen(Profile))
end
else
if PRINT_TEXTURE_INFO then
SaveGameIndex:DeleteSlot(1,
function()
local function onsaved()
local params = json.encode{reset_action="printtextureinfo", save_slot = 1}
TheSim:SetInstanceParameters(params)
TheSim:Reset()
end
SaveGameIndex:StartSurvivalMode(1, "wilson", {}, onsaved)
end)
else
LoadAssets(true)
TheFrontEnd:ShowScreen(MainScreen(Profile))
end
end
end)
end
Profile = PlayerProfile()
SaveGameIndex = SaveIndex()
Print(VERBOSITY.DEBUG, "[Loading profile and save index]")
Profile:Load( function()
SaveGameIndex:Load( OnFilesLoaded )
end )
--dont_load_save in profile