pR1sm Posted May 27, 2017 Share Posted May 27, 2017 (edited) Hi, as the title suggets, i want to add the sound of rain hitting the umbrella to the "Rain Hat". However on reading some of the tutorials, i appears to me, that only existing sound events can be replaced. Since there doesn't seem to be an event for equipping the Rain Hat specifically, i wanted to ask if anyone here knows, if it's somehow possible to add that event to the game and add the soundfile to it. Obviously, that soundfile would only play while it's raining Thanks in advance Edited May 28, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/ Share on other sites More sharing options...
alainmcd Posted May 28, 2017 Share Posted May 28, 2017 Welcome around here, @pR1sm! local function updatesound(inst) local soundShouldPlay = GLOBAL.GetSeasonManager():IsRaining() and inst.components.equippable:IsEquipped() if soundShouldPlay ~= inst.SoundEmitter:PlayingSound("umbrellarainsound") then if soundShouldPlay then inst.SoundEmitter:PlaySound("dontstarve/rain/rain_on_umbrella", "umbrellarainsound") else inst.SoundEmitter:KillSound("umbrellarainsound") end end end local function rainhatpostinit(inst) inst.entity:AddSoundEmitter() local EquipOld = inst.components.equippable.Equip local UnequipOld = inst.components.equippable.Unequip inst.components.equippable.Equip = function(self, owner, slot) EquipOld(self, owner, slot) updatesound(self.inst) end inst.components.equippable.Unequip = function(self, owner, slot) UnequipOld(self, owner, slot) updatesound(self.inst) end inst:ListenForEvent("rainstop", function() updatesound(inst) end, GLOBAL.GetWorld()) inst:ListenForEvent("rainstart", function() updatesound(inst) end, GLOBAL.GetWorld()) end AddPrefabPostInit("rainhat", rainhatpostinit) Tested it briefly in SW and it worked, should work in RoG too. All headgear uses generic onequip and onunequip functions ( inst.components.equippable:SetOnEquip( onequip ) and inst.components.equippable:SetOnUnequip( onunequip ) in simple() in prefabs/hats.lua). Some hats with special behaviours then call SetOnEquip and SetOnUnequip again, overriding the generic function, like the Eyebrella does. You could just call SetOnEquip and SetOnUnequip, but then you'd have to define that default behaviour somewhere (or you wouldn't see the hat Rain Hat when worn) and it could potentially break other mods. Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926017 Share on other sites More sharing options...
pR1sm Posted May 28, 2017 Author Share Posted May 28, 2017 (edited) Thank you very much Would SetOn(Un)Equip call rainhatpostinit and would i have to simply add that call at the bottom of my mainmod.lua? I'm very much new to LUA and script languages in general, sorry ^^ Edited May 28, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926090 Share on other sites More sharing options...
alainmcd Posted May 28, 2017 Share Posted May 28, 2017 To change a prefab, you use AddPrefabPostInit. The first argument is the prefab, the second is the function that actually does something. If you wanted to use SetOnEquip and SetOnUnequip, your modmain.lua should look something like this (untested): Spoiler local function updatesound(inst) local soundShouldPlay = GLOBAL.GetSeasonManager():IsRaining() and inst.components.equippable:IsEquipped() if soundShouldPlay ~= inst.SoundEmitter:PlayingSound("umbrellarainsound") then if soundShouldPlay then inst.SoundEmitter:PlaySound("dontstarve/rain/rain_on_umbrella", "umbrellarainsound") else inst.SoundEmitter:KillSound("umbrellarainsound") end end end local function onequip(inst, owner) updatesound(inst) -- this is what we're adding --everything from this point on is just copied from onequip in hats.lua local skin_build = inst:GetSkinBuild() if skin_build ~= nil then owner:PushEvent("equipskinneditem", inst:GetSkinName()) owner.AnimState:OverrideItemSkinSymbol("swap_hat", skin_build, "swap_hat", inst.GUID, fname) else owner.AnimState:OverrideSymbol("swap_hat", fname, "swap_hat") end owner.AnimState:Show("HAT") owner.AnimState:Show("HAIR_HAT") owner.AnimState:Hide("HAIR_NOHAT") owner.AnimState:Hide("HAIR") if owner:HasTag("player") then owner.AnimState:Hide("HEAD") owner.AnimState:Show("HEAD_HAT") end if inst.components.fueled ~= nil then inst.components.fueled:StartConsuming() end end local function onunequip(inst, owner) updatesound(inst) -- this is what we're adding --everything from this point on is just copied from onunequip in hats.lua local skin_build = inst:GetSkinBuild() if skin_build ~= nil then owner:PushEvent("unequipskinneditem", inst:GetSkinName()) end owner.AnimState:ClearOverrideSymbol("swap_hat") owner.AnimState:Hide("HAT") owner.AnimState:Hide("HAIR_HAT") owner.AnimState:Show("HAIR_NOHAT") owner.AnimState:Show("HAIR") if owner:HasTag("player") then owner.AnimState:Show("HEAD") owner.AnimState:Hide("HEAD_HAT") end if inst.components.fueled ~= nil then inst.components.fueled:StopConsuming() end end local function rainhatpostinit(inst) inst.entity:AddSoundEmitter() inst.components.equippable:SetOnEquip(onequip) inst.components.equippable:SetOnUnequip(onunequip) inst:ListenForEvent("rainstop", function() updatesound(inst) end, GLOBAL.GetWorld()) inst:ListenForEvent("rainstart", function() updatesound(inst) end, GLOBAL.GetWorld()) end AddPrefabPostInit("rainhat", rainhatpostinit) You'd need all the extra code to make the Rain Hat visible when worn. As you can see, it's much longer. Even if the bulk of the new code is just copy-pasted (with some changes), it's definitely more work. Don't work more than you have to, make the most of what's already there. Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926188 Share on other sites More sharing options...
pR1sm Posted May 28, 2017 Author Share Posted May 28, 2017 (edited) Awesome work! So "AddPrefabPostInit" replaces all original functions of its first parameter with those provided in the modmain and subsequent lua-files? I get an error however, game complains that the variable GetSeasonManager is not declared. Maybe a difference between RoG and SW after all, since your first code worked and "soundShouldPlay" was initialised in the same manner? Edited May 28, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926216 Share on other sites More sharing options...
alainmcd Posted May 29, 2017 Share Posted May 29, 2017 Eww, I made a mess. I copied copied the functions from hats.lua in DST. No skins in single player! It should look like this (tested!): Spoiler local function updatesound(inst) local soundShouldPlay = GLOBAL.GetSeasonManager():IsRaining() and inst.components.equippable:IsEquipped() if soundShouldPlay ~= inst.SoundEmitter:PlayingSound("umbrellarainsound") then if soundShouldPlay then inst.SoundEmitter:PlaySound("dontstarve/rain/rain_on_umbrella", "umbrellarainsound") else inst.SoundEmitter:KillSound("umbrellarainsound") end end end local function onequip(inst, owner) updatesound(inst) -- this is what we're adding --everything from this point on is just copied from onequip in hats.lua local build = "hat_rain" owner.AnimState:OverrideSymbol("swap_hat", build, "swap_hat") owner.AnimState:Show("HAT") owner.AnimState:Show("HAT_HAIR") owner.AnimState:Hide("HAIR_NOHAT") owner.AnimState:Hide("HAIR") if owner:HasTag("player") then owner.AnimState:Hide("HEAD") owner.AnimState:Show("HEAD_HAIR") end if inst.components.fueled then inst.components.fueled:StartConsuming() end end local function onunequip(inst, owner) updatesound(inst) -- this is what we're adding --everything from this point on is just copied from onunequip in hats.lua owner.AnimState:Hide("HAT") owner.AnimState:Hide("HAT_HAIR") owner.AnimState:Show("HAIR_NOHAT") owner.AnimState:Show("HAIR") if owner:HasTag("player") then owner.AnimState:Show("HEAD") owner.AnimState:Hide("HEAD_HAIR") end if inst.components.fueled then inst.components.fueled:StopConsuming() end end local function rainhatpostinit(inst) inst.entity:AddSoundEmitter() inst.components.equippable:SetOnEquip(onequip) inst.components.equippable:SetOnUnequip(onunequip) inst:ListenForEvent("rainstop", function() updatesound(inst) end, GLOBAL.GetWorld()) inst:ListenForEvent("rainstart", function() updatesound(inst) end, GLOBAL.GetWorld()) end AddPrefabPostInit("rainhat", rainhatpostinit) Works in RoG too. Were you perhaps trying it in DST? Weather is handled somewhat differently. 12 hours ago, pR1sm said: So "AddPrefabPostInit" replaces all original functions of its first parameter with those provided in the modmain and subsequent lua-files? No, AddPrefabPostInit does not replace anything in the original prefab. It allows you to add to the prefab definition, as if you were directly extending that definition. For example, in this case we are adding the sound emitter and the event listeners to the rainhat prefab. Everything else remains the same: it still uses the fueled, waterproofer and equippable components and the same graphics without us mentioning any of it in our mod. However, the SetOnEquip and SetOnUnequip methods to the equippable component each allow for one special function to be called when equipping/unequipping the item. Since we do want to have a special behaviour (checking whether the sound should play) and the prefab definition already has set one up (changing the animations), we are replacing the original one (animations) with what we finally want (both: check sound to play and change animations). Does that make sense? Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926401 Share on other sites More sharing options...
pR1sm Posted May 29, 2017 Author Share Posted May 29, 2017 (edited) Ah, i was indeed trying the modification in DST, i assumed RoG was pretty much a subset of DST with DST only adding multiplayer support. I've read up on some of the differences between DST and the basic game, so inst:ListenForEvent("rainstop", function() updatesound(inst) end, GLOBAL.GetWorld()) inst:ListenForEvent("rainstart", function() updatesound(inst) end, GLOBAL.GetWorld()) should look somewhat like this, right? inst:WatchWorldState("israining", function() updatesound(inst) end, TheWorld) Now the only other thing that should need chaning would be local soundShouldPlay = GLOBAL.GetSeasonManager():IsRaining() and inst.components.equippable:IsEquipped() ..correct? Since DST doesnt use a seasonmanager, i figured it would be something like local soundShouldPlay = GLOBAL.TheWorld.state:israining() and inst.components.equippable:IsEquipped() However now the game complains about the israining call returning a boolean value (no idea why it would complain about that, after all we are evaluating wether its raining or not 0o), which at least told me that Global.TheWorld.state exists. Been searching online for some documentation on the whole season matter in DST, but couldnt find anything <.< Edited May 29, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926440 Share on other sites More sharing options...
alainmcd Posted May 29, 2017 Share Posted May 29, 2017 No, DS and DST have a lot of code in common, but some things are handled very differently. In DST, you'd only need AddPrefabPostInit("rainhat", function(inst) inst:AddTag("umbrella") end) in your modmain.lua. Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926452 Share on other sites More sharing options...
pR1sm Posted May 29, 2017 Author Share Posted May 29, 2017 (edited) 39 minutes ago, alainmcd said: ...In DST, you'd only need AddPrefabPostInit("rainhat", function(inst) inst:AddTag("umbrella") end) in your modmain.lua. well that and the seasonmanager, since that was the reason it didnt work for me to begin with in DST Hmm, i tried your new version in shipwrecked, and it doesnt work, but it DOES work in RoG 0_o. the mod does load according to the console, but the sound remains the same in SW, hmm makes no sense... Perhaps it has something to do with monsoon being a different season than spring? Edited May 29, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926455 Share on other sites More sharing options...
alainmcd Posted May 29, 2017 Share Posted May 29, 2017 27 minutes ago, pR1sm said: that and the seasonmanager No need, the single line I posted is all you need to add the Eyebrella sound to the Rain Hat. 30 minutes ago, pR1sm said: i tried your new version in shipwrecked, and it doesnt work shipwrecked_compatible = true? Works for me. Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926466 Share on other sites More sharing options...
pR1sm Posted May 29, 2017 Author Share Posted May 29, 2017 (edited) 20 minutes ago, alainmcd said: shipwrecked_compatible = true? Works for me. it works in both cases for RoG, wether the save-file is made compatible with SW or not, but ironically it doesnt work for SW EDIT. aaah, got it working by adding that line to the modinfo Now also works in DST, thanks alot mate, really appreciate it Any idea, where i can get a documenation on modding for dont starve without having to bother people on the forum? Edited May 29, 2017 by pR1sm Link to comment https://forums.kleientertainment.com/forums/topic/79242-adding-the-rain-on-umbrella-sound-to-the-rain-hat/#findComment-926471 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now