GLOBAL.setmetatable( env, {__index = function(a, b) return GLOBAL.rawget(GLOBAL, b) end } ) local function OnProtect(inst, owner, prefab) if owner and owner.SoundEmitter then owner.SoundEmitter:PlaySound("dontstarve/common/destroy_clothing", "cloth") owner:DoTaskInTime(.25, function() owner.SoundEmitter:KillSound("cloth") end) end if prefab then local fueled = inst.components.fueled fueled:DoDelta(fueled.maxfuel * -(prefab == "book" and 0.5 or 0.25)) end end AddPrefabPostInit("earmuffshat", function(inst) if not TheWorld.ismastersim then return end inst.OnProtect = OnProtect end) local function HearPanFlute(inst, musician, instrument) if (TheNet:GetPVPEnabled() or not inst:HasTag("player")) and not (inst.components.freezable ~= nil and inst.components.freezable:IsFrozen()) and not (inst.components.pinnable ~= nil and inst.components.pinnable:IsStuck()) and not (inst.components.fossilizable ~= nil and inst.components.fossilizable:IsFossilized()) then local mount = inst.components.rider ~= nil and inst.components.rider:GetMount() or nil if mount ~= nil then mount:PushEvent("ridersleep", { sleepiness = 10, sleeptime = instrument.panflute_sleeptime }) end if inst.components.farmplanttendable ~= nil then inst.components.farmplanttendable:TendTo(musician) elseif inst.components.sleeper ~= nil then inst.components.sleeper:AddSleepiness(10, instrument.panflute_sleeptime) if inst.components.sleeper:IsAsleep() then if instrument.panflute_wortox_forget_debuff and inst.components.combat then inst:AddDebuff("wortox_forget_debuff", "wortox_forget_debuff", {toforget = musician}) end end elseif inst.components.grogginess ~= nil then inst.components.grogginess:AddGrogginess(10, instrument.panflute_sleeptime, nil, "flute") else inst:PushEvent("knockedout") end end end AddPrefabPostInit("panflute", function(inst) if not TheWorld.ismastersim then return end inst.components.instrument:SetOnHeardFn(HearPanFlute) end) local SLEEPTARGET_PVP_ONEOF_TAGS = { "sleeper", "player" } local SLEEPTARGET_NOPVP_MUST_TAGS = { "sleeper" } local SLEEPTARGET_CANT_TAGS = { "playerghost", "FX", "DECOR", "INLIMBO" } local function OnRead(inst, reader) local x, y, z = reader.Transform:GetWorldPosition() local range = 30 local ents = TheNet:GetPVPEnabled() and TheSim:FindEntities(x, y, z, range, nil, SLEEPTARGET_CANT_TAGS, SLEEPTARGET_PVP_ONEOF_TAGS) or TheSim:FindEntities(x, y, z, range, SLEEPTARGET_NOPVP_MUST_TAGS, SLEEPTARGET_CANT_TAGS) if #ents == 0 then return false, "NOSLEEPTARGETS" end for i, v in ipairs(ents) do if not (v.components.freezable ~= nil and v.components.freezable:IsFrozen()) and not (v.components.pinnable ~= nil and v.components.pinnable:IsStuck()) and not (v.components.fossilizable ~= nil and v.components.fossilizable:IsFossilized()) then local ismount, mount if v.components.rider ~= nil then ismount = v.components.rider:IsRiding() mount = v.components.rider:GetMount() end if mount ~= nil then mount:PushEvent("ridersleep", { sleepiness = 10, sleeptime = 20 }) end if v.components.sleeper ~= nil then v.components.sleeper:AddSleepiness(10, 20) elseif v.components.grogginess ~= nil then v.components.grogginess:AddGrogginess(10, 20, nil, "book") else v:PushEvent("knockedout") end local fx = SpawnPrefab(ismount and "fx_book_sleep_mount" or "fx_book_sleep") fx.Transform:SetPosition(v.Transform:GetWorldPosition()) fx.Transform:SetRotation(v.Transform:GetRotation()) end end return true end AddPrefabPostInit("book_sleep", function(inst) if not TheWorld.ismastersim then return end inst.components.book:SetOnRead(OnRead) end) local function IsSleepResistant(inst) local item = inst.components.inventory and inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD) if item and item.prefab == "earmuffshat" then return item end return nil end AddPlayerPostInit(function(inst) if not TheWorld.ismastersim then return end inst.IsSleepResistant = IsSleepResistant end) AddComponentPostInit("grogginess", function(self) local _AddGrogginess = self.AddGrogginess function self:AddGrogginess(grogginess, knockoutduration, ignore_protect, prefab) local head = not ignore_protect and (self.inst.IsSleepResistant and self.inst:IsSleepResistant()) or nil if grogginess > 1 and head and prefab then head:OnProtect(self.inst, prefab) else return _AddGrogginess(self, grogginess, knockoutduration, ignore_protect) end end end) local _PlayerDespawn local function OnPlayerDespawn(inst, player, cb) if player.components.playercontroller then player.components.playercontroller:Enable(false) end if player.components.locomotor then player.components.locomotor:StopMoving() player.components.locomotor:Clear() end player:DoTaskInTime(5, function() if player.components.playercontroller and player.components.playercontroller.classified then _PlayerDespawn(inst, player, cb) end end) end AddComponentPostInit("playerspawner", function(self) _PlayerDespawn = self.inst.event_listeners["ms_playerdespawn"][self.inst][1] self.inst.event_listeners.ms_playerdespawn[self.inst][1] = OnPlayerDespawn end) AddComponentPostInit("locomotor", function(self) function self:CheckDrownable() local drownable = self.inst.components.drownable if drownable then local fallingreason = drownable:GetFallingReason() if fallingreason == FALLINGREASON.OCEAN then self.inst:PushEvent("onsink") return true end end end end) AddComponentPostInit("drownable", function(self) function self:GetFallingReason() if self:ShouldDrown() then return FALLINGREASON.OCEAN end end end)