-- f1 world restore (plots + pet holes/pets) on instance init -- Called from map event 0 (OnInit) for each initialized creature. local function _script_dir() local src = debug.getinfo(1, "S").source if type(src) ~= "string" then return "" end if src:sub(1, 1) == "@" then src = src:sub(2) end src = src:gsub("\\", "/") local dir = src:match("^(.*)/") if dir == nil then return "" end return dir .. "/" end local function _dofile_rel(name) return dofile(_script_dir() .. name) end local map_def = _dofile_rel("f1_mappings.lua") local plot_store = _dofile_rel("f1_plot_store.lua") local pet_plot_store = _dofile_rel("pet_plot_store.lua") local M = {} local PET_HOLE = 5810201 local PET_TYPES = { [5810202] = true, [5810203] = true, [5810204] = true, [5810205] = true, [5810206] = true, [5810207] = true, [5810208] = true, [5810209] = true, [5810210] = true, } local function _now() return os.time() end local function _hungry_seconds_by_type(TargetTypeID) -- kura: 1h, feya: 2h, kabanchik: 5h if TargetTypeID == 5810202 or TargetTypeID == 5810203 or TargetTypeID == 5810204 then return 3600 elseif TargetTypeID == 5810205 or TargetTypeID == 5810206 or TargetTypeID == 5810207 then return 7200 elseif TargetTypeID == 5810208 or TargetTypeID == 5810209 or TargetTypeID == 5810210 then return 18000 end return 3600 end local function _replace_creature(MapID, InstanceID, CreatureID, expectedType, x, y, z) map.MapDeleteCreature(MapID, InstanceID, CreatureID) return map.MapCreateCreature(MapID, InstanceID, expectedType, x, y, z), expectedType end local function _expected_type_for_plot(plot, currentTypeId) if plot == nil then return currentTypeId end if plot.Stage == map_def.STAGE_MOUND then return map_def.MOUND_BASIC end local def = map_def.plants[plot.PlantId] if def == nil then return currentTypeId end if plot.Stage == map_def.STAGE_SEED then return def.seed elseif plot.Stage == map_def.STAGE_SEEDLING then return def.seedling elseif plot.Stage == map_def.STAGE_HARVEST then return def.harvest end return currentTypeId end local function _restore_plot(MapID, InstanceID, CreatureID, CreatureTypeID) if not plot_store.schemaReady() then return end local x, y, z = unit.GetPosition(MapID, InstanceID, CreatureID) local plot = plot_store.getPlot(MapID, InstanceID, x, y, z) if plot == nil then return end local now = _now() if plot.Stage == map_def.STAGE_SEEDLING and (plot.StageStartTime or 0) > 0 then local def = map_def.plants[plot.PlantId] if def ~= nil and def.growSeconds ~= nil then if (now - plot.StageStartTime) >= def.growSeconds then plot_store.setPlot(MapID, InstanceID, x, y, z, { Stage = map_def.STAGE_HARVEST, StageStartTime = 0 }) plot.Stage = map_def.STAGE_HARVEST plot.StageStartTime = 0 end end end local expected = _expected_type_for_plot(plot, CreatureTypeID) if expected ~= nil and expected ~= 0 and expected ~= CreatureTypeID then _replace_creature(MapID, InstanceID, CreatureID, expected, x, y, z) end end local function _restore_pet(MapID, InstanceID, CreatureID, CreatureTypeID) if not pet_plot_store.schemaReady() then return end -- Personal instance: InstanceID is created using RoleID, so treat InstanceID as owner RoleID. local ownerRoleID = tonumber(InstanceID) or 0 if ownerRoleID <= 0 then return end local x, y, z = unit.GetPosition(MapID, InstanceID, CreatureID) local slot = pet_plot_store.ensureSlotForCoord(ownerRoleID, x, y, z) if slot == nil then return end local expected = tonumber(slot.PetTypeID) or 0 if expected == 0 then expected = PET_HOLE end local newId = CreatureID local newType = CreatureTypeID if expected ~= CreatureTypeID then newId, newType = _replace_creature(MapID, InstanceID, CreatureID, expected, x, y, z) end if newType ~= PET_HOLE then local last = tonumber(slot.LastFeedTime) or 0 cre.SetCreatureScriptData(MapID, InstanceID, newId, 1, 1, ownerRoleID) cre.SetCreatureScriptData(MapID, InstanceID, newId, 1, 2, last) cre.SetCreatureScriptData(MapID, InstanceID, newId, 1, 3, 1) local hungrySeconds = _hungry_seconds_by_type(newType) local s = (last <= 0) and hungrySeconds or os.difftime(_now(), last) if s >= hungrySeconds then unit.CancelBuff(MapID, InstanceID, newId, 9857101) unit.AddBuff(MapID, InstanceID, newId, 9857001, newId) else unit.CancelBuff(MapID, InstanceID, newId, 9857001) unit.AddBuff(MapID, InstanceID, newId, 9857101, newId) end end end function M.onInit(MapID, InstanceID, CreatureID, CreatureTypeID) -- Restore plots: mound + all plant stages (seed/seedling/harvest) if CreatureTypeID == map_def.MOUND_BASIC or map_def.creature_to_plant[CreatureTypeID] ~= nil then _restore_plot(MapID, InstanceID, CreatureID, CreatureTypeID) return end -- Restore pets: hole + pet creatures if CreatureTypeID == PET_HOLE or PET_TYPES[CreatureTypeID] then _restore_pet(MapID, InstanceID, CreatureID, CreatureTypeID) return end end return M