Jump to content

Recommended Posts

I've been trying to make it so, on the first dawn of a new season, the game plays a (season) stinger, instead of the regular (dawn_stinger), but I'm not sure what kind of check can only be applied at the very start of a season and not the following days

Edited by Sukaiba
Simpler wording

Let me know how well this works.

AddComponentPostInit("dynamicmusic", function(component) -- dynamicmusic is completely private so adding it here is only for organization but whatever
	local SEASON_STINGERS =
	{
		autumn = {sound = "dontstarve_DLC001/creatures/bearger/yawn", duration = 5},
		winter = {sound = "dontstarve/creatures/deerclops/death", duration = 4},
		spring = {sound = "dontstarve_DLC001/creatures/mossling/honk", duration = 10},
		summer = {sound = "dontstarve_DLC001/creatures/dragonfly/death", duration = 3},
	}
	component.inst:WatchWorldState("season", function(inst, season) -- (component.inst = TheWorld) 
		if not SEASON_STINGERS[season] then return end -- If you want to stay true to stingers, also check if you're on the surface (not HasTag"cave")
		component.inst:PushEvent("enabledynamicmusic", false)
		GLOBAL.TheFocalPoint.SoundEmitter:PlaySound(SEASON_STINGERS[season].sound)
		component.inst:DoTaskInTime(SEASON_STINGERS[season].duration, function()
			component.inst:PushEvent("enabledynamicmusic", true)
		end)
	end)
end) -- TheWorld:PushEvent("ms_setseason", season) to test
Edited by oregu
  • Health 1
16 hours ago, oregu said:

Let me know how well this works.

AddComponentPostInit("dynamicmusic", function(component) -- dynamicmusic is completely private so adding it here is only for organization but whatever
	local SEASON_STINGERS =
	{
		autumn = {sound = "dontstarve_DLC001/creatures/bearger/yawn", duration = 5},
		winter = {sound = "dontstarve/creatures/deerclops/death", duration = 4},
		spring = {sound = "dontstarve_DLC001/creatures/mossling/honk", duration = 10},
		summer = {sound = "dontstarve_DLC001/creatures/dragonfly/death", duration = 3},
	}
	component.inst:WatchWorldState("season", function(inst, season) -- (component.inst = TheWorld) 
		if not SEASON_STINGERS[season] then return end -- If you want to stay true to stingers, also check if you're on the surface (not HasTag"cave")
		component.inst:PushEvent("enabledynamicmusic", false)
		GLOBAL.TheFocalPoint.SoundEmitter:PlaySound(SEASON_STINGERS[season].sound)
		component.inst:DoTaskInTime(SEASON_STINGERS[season].duration, function()
			component.inst:PushEvent("enabledynamicmusic", true)
		end)
	end)
end) -- TheWorld:PushEvent("ms_setseason", season) to test

It works perfectly! You're a lifesaver man!

Been struggling with this for a while, I got only the most rock-bottom knowledge of lua so you really saved my ass here

At the risk of overreaching your goodwill, would you happen to know if there's a way to make it so the main menu and item collection screens choose a random music file each time they're entered?

I tried putting this in the modmain.lua file, but its only random the first time each is entered, then it commits to that choice until you exit out of a world or restart the whole game

local fe_array={"_a","_1","_2"} -- Pool of music files
local fe_randomIndex = math.random(1, #fe_array) -- FIX TO REROLL WHEN REENTERING MAINMENU
local fe_stuff = fe_array[fe_randomIndex] -- Chosen file

GLOBAL.FE_MUSIC = "music_mod/music/music_FE"..fe_stuff -- Final Main Menu music file

local array={"_box","_1"} -- Pool of music files
local randomIndex = math.random(1, #array) -- FIX TO REROLL WHEN REENTERING CURIOS
local stuff = array[randomIndex] -- Chosen file

RemapSoundEvent("dontstarve/HUD/Together_HUD/collectionscreen/music/jukebox","music_mod/music/juke"..stuff) -- Final Item Collection music file

I'm sorry if its sticky spaghetti code, as I said, complete noob to lua lmao

Also I am aware that FMOD allows you to make Simple Events that can work as randomizers, the problem is that some of the files in the pools are Multi-Track (since they include intros)

Edited by Sukaiba
Mistakes 2: the Mistakening
  • Like 1

My guess for the problem is RemapSoundEvent is determined a special way and what you need to do requires RemoveRemapSoundEvent, another modutil function but I think we can do something better than replacing the sound event, because it is possible that in the future the items collection theme could be replaced by another file that could be named differently, so we'll do something more precise.

I'm going to do an AddClassPostConstruct, which works like an AddWidgetPostInit in this context. This screen is where you want the override to happen. I also explained how the game loads scripts more in depth and why it works that it chooses a random number each time you go to the main menu.

Item Collection Screen (Random but not each time it's entered)

Spoiler
-- You can do 'if TheNet:GetIsMasterSimulation() then return end' (the same as "if you're on the main menu then proceed")
-- But it's possible that a mod may want to use the screen while you're in game, so we may as well keep that out.
local SUMMARY_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
-- Scripts (in modmain.lua at least) get reloaded when you are in game and when you are on the main menu
-- Leaving it out of the Add function makes it reload each time the script loads, 
-- Things in Add functions persist and therefore each time you load the widget, the random number would change, at least for this widget.
local randomtrack = math.random(#SUMMARY_MUSIC_TRACKS)
AddClassPostConstruct("screens/redux/playersummaryscreen", function(self)
	local function OnStartMusic(inst, self)
		self.musictask = nil
		self.musicstopped = false
		TheFrontEnd:GetSound():PlaySound(SUMMARY_MUSIC_TRACKS[randomtrack], "FEMusic")
	end
	self.StartMusic = function() -- Overwrite StartMusic function for the screen entirely
		if self.musicstopped and self.musictask == nil then
			self.musictask = self.inst:DoTaskInTime(1.25, OnStartMusic, self)
		end
	end
end)

 

Main Menu Screen (Random but not each time it's entered)

Spoiler
local MAIN_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
local randmain = math.random(#MAIN_MUSIC_TRACKS)
GLOBAL.FE_MUSIC = MAIN_MUSIC_TRACKS[randmain] -- Overwriting FE_MUSIC is relatively simple because it's a constant

Ah, but I misread your post. I explained the solution to make it random each time it's entered for item collection, but let me do the main screen(s) as well.

Items Collection Screen (Random each time it's entered)

Spoiler
local SUMMARY_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
local randsum
AddClassPostConstruct("screens/redux/playersummaryscreen", function(self)
	randsum = math.random(#SUMMARY_MUSIC_TRACKS)
	local function OnStartMusic(inst, self)
		self.musictask = nil
		self.musicstopped = false
		TheFrontEnd:GetSound():PlaySound(SUMMARY_MUSIC_TRACKS[randsum], "FEMusic")
	end
	self.StartMusic = function() -- Overwrite StartMusic function for the screen entirely
		if self.musicstopped and self.musictask == nil then
			self.musictask = self.inst:DoTaskInTime(1.25, OnStartMusic, self)
		end
	end
end)

Main Menu Screen (Random each time it's entered)

Spoiler
local MAIN_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
local randmain
local PushScreen_old = GLOBAL.FrontEnd.PushScreen -- func hook (FrontEnd seems to be pre-init TheFrontEnd?)
GLOBAL.FrontEnd.PushScreen = function(...) -- There's a lot of screens FE_MUSIC is played (and there may be new screens in the future), so we will just assign a random number each time the screen changes.
	randmain = math.random(#MAIN_MUSIC_TRACKS)
	GLOBAL.FE_MUSIC = MAIN_MUSIC_TRACKS[randmain]
	PushScreen_old(...)
end

 

Edited by oregu
Random each time it's entered
  • Health 1
15 hours ago, oregu said:

My guess for the problem is RemapSoundEvent is determined a special way and what you need to do requires RemoveRemapSoundEvent, another modutil function but I think we can do something better than replacing the sound event, because it is possible that in the future the items collection theme could be replaced by another file that could be named differently, so we'll do something more precise.

I'm going to do an AddClassPostConstruct, which works like an AddWidgetPostInit in this context. This screen is where you want the override to happen. I also explained how the game loads scripts more in depth and why it works that it chooses a random number each time you go to the main menu.

Ah, but I misread your post. I explained the solution to make it random each time it's entered for item collection, but let me do the main screen(s) as well.

Items Collection Screen (Random each time it's entered)

  Hide contents
local SUMMARY_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
local randsum
AddClassPostConstruct("screens/redux/playersummaryscreen", function(self)
	randsum = math.random(#SUMMARY_MUSIC_TRACKS)
	local function OnStartMusic(inst, self)
		self.musictask = nil
		self.musicstopped = false
		TheFrontEnd:GetSound():PlaySound(SUMMARY_MUSIC_TRACKS[randsum], "FEMusic")
	end
	self.StartMusic = function() -- Overwrite StartMusic function for the screen entirely
		if self.musicstopped and self.musictask == nil then
			self.musictask = self.inst:DoTaskInTime(1.25, OnStartMusic, self)
		end
	end
end)

Main Menu Screen (Random each time it's entered)

  Hide contents
local MAIN_MUSIC_TRACKS = 
{
	"dontstarve_DLC001/creatures/bearger/yawn",
	"dontstarve/creatures/deerclops/death",
	"dontstarve_DLC001/creatures/mossling/honk",
	"dontstarve_DLC001/creatures/dragonfly/death",
}
local randmain
local PushScreen_old = GLOBAL.FrontEnd.PushScreen -- func hook (FrontEnd seems to be pre-init TheFrontEnd?)
GLOBAL.FrontEnd.PushScreen = function(...) -- There's a lot of screens FE_MUSIC is played (and there may be new screens in the future), so we will just assign a random number each time the screen changes.
	randmain = math.random(#MAIN_MUSIC_TRACKS)
	GLOBAL.FE_MUSIC = MAIN_MUSIC_TRACKS[randmain]
	PushScreen_old(...)
end

 

Bro you are seriously my hero

After months of figuring out how to patch the dynamicmusic.lua file to have continuous music for all times of day, areas and other stuff (Since the tutorial for continuous music is like 5 years old now and is missing a lot of areas and content), these two were the last hurdle I needed to overcome and you came in so clutch

Admittedly I do not understand most of the wizardry you're doing with these lines of code (Not familiar with lua syntax; I still have trouble wrapping my head around how summoning/asigning values to functions work, let alone postinit or func hooks lol), but I still appreciate the notes added as if you were trying to walk me through them

Edited by Sukaiba
  • Like 1
2 hours ago, Sukaiba said:

Bro you are seriously my hero

After months of figuring out how to patch the dynamicmusic.lua file to have continuous music for all times of day, areas and other stuff (Since the tutorial for continuous music is like 5 years old now and is missing a lot of areas and content), these two were the last hurdle I needed to overcome and you came in so clutch

Admittedly I do not understand most of the wizardry you're doing with these lines of code (Not familiar with lua syntax; I still have trouble wrapping my head around how summoning/asigning values to functions work, let alone postinit or func hooks lol), but I still appreciate the notes added as if you were trying to walk me through them

No problem. Don't sweat it too hard, it took me a while to comprehend DST modding as well, and there's some areas I don't understand as well. I say it wouldn't have to do with the complexity of Lua necessarily; Lua is a relatively low-level language if you want it to be. But you need to have the resources to know what all the functions do, that's the tricky part for me. As far as I know, for some functions you have to directly read from the code. I've gotten better at that, at least.

You wouldn't expect dynamicmusic to be private (meaning only serverside mods can mess with it) since what exists on it is fundamentally clientside , maybe it has to do with its inst being "TheWorld" or being a class with no owner? Maybe, maybe not. Either way glad to help, let me know if something goes wrong or need more help.

As a sidenote, this FE override is nice for me as well because I can hear when DST finished loading (I don't often use music).

Edited by oregu
  • Health 1
1 hour ago, oregu said:

No problem. Don't sweat it too hard, it took me a while to comprehend DST modding as well, and there's some areas I don't understand as well. I say it wouldn't have to do with the complexity of Lua necessarily; Lua is a relatively low-level language if you want it to be. But you need to have the resources to know what all the functions do, that's the tricky part for me. As far as I know, for some functions you have to directly read from the code. I've gotten better at that, at least.

You wouldn't expect dynamicmusic to be private (meaning only serverside mods can mess with it) since what exists on it is fundamentally clientside , maybe it has to do with its inst being "TheWorld" or being a class with no owner? Maybe, maybe not. Either way glad to help, let me know if something goes wrong or need more help.

Frankly I do have a couple of other inconveniences, the problem is that those most likely lay within dynamicmusic.lua... And are probably artifacts from whatever spaghetti dodgy patchjob I did there and I'm not savvy enough to pin down the issues or a solution to them

And even though I really, really appreciate your help, there's absolutely zero way I can expect you to scour through my code and pinpoint whatever mistakes I made

I frankly posted the previous two because I figured they (mostly) would rely on pieces of code that I have no knowledge of, instead of being born from conflicts that I caused

I still am thankful for the offer however, and if I stumble upon simple-ish problems that I cannot figure out, I'll keep you in mind!

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...