Jump to content

How Would I Temporarily Change the Sprites for an Already Existing Sprite?


Recommended Posts

Hello everyone, I am very new to modding so I apologize in advance for not understanding everything. I have a sprite for a usable item on the ground and in the inventory on my computer, and I want to replace the Pan Flute sprites with those. Just to see what my sprites would look like in-game. I have Notepad++ and know how to navigate through the code for dst. What code would I put down to change an already existing sprite for inventory and ground?

Edited by thegreatJash
Link to comment
Share on other sites

 

1 hour ago, thegreatJash said:

Hello everyone, I am very new to modding so I apologize in advance for not understanding everything. I have a sprite for a usable item on the ground and in the inventory on my computer, and I want to replace the Pan Flute sprites with those. Just to see what my sprites would look like in-game. I have Notepad++ and know how to navigate through the code for dst. What code would I put down to change an already existing sprite for inventory and ground?

AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
	inst.AnimState:SetBank("customsprite") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
	inst.AnimState:SetBuild("customsprite")

	if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
    	return
    end
    
    inst.components.inventoryitem.atlasname = "images/customatlas.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "customimage" --the name of your image
end)

 

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, Hornete said:

 


AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
	inst.AnimState:SetBank("customsprite") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
	inst.AnimState:SetBuild("customsprite")

	if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
    	return
    end
    
    inst.components.inventoryitem.atlasname = "images/customatlas.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "customimage" --the name of your image
end)

 

Thanks. I'll have to try this out.

Link to comment
Share on other sites

20 hours ago, Hornete said:

 


AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
	inst.AnimState:SetBank("customsprite") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
	inst.AnimState:SetBuild("customsprite")

	if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
    	return
    end
    
    inst.components.inventoryitem.atlasname = "images/customatlas.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "customimage" --the name of your image
end)

 

Ok now I got somewhere but still experiencing problems. It did override the sprite for the Pan Flute, but now there is nothing on for both the floor or inventory sprites, just blankness. I converted my sprite PNG file to both XML and TEX and put those both in a folder called "images". I named them both "shell" and inserted the name when necessary. I copy and pastes your code into the modmain and put shell in them. I think there might be a problem with the images, as I'm not sure using a website to convert them did the trick. Any proper method to converting my image? I noticed that every image has both a XML file and a TEX file. I have the sprite as a PNG, now I need help converting and putting it into the code. Here's the current code by the way.

AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
    inst.AnimState:SetBank("shell") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
    inst.AnimState:SetBuild("shell")

    if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
        return
    end
    
    inst.components.inventoryitem.atlasname = "images/shell.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "shell" --the name of your image
end)

  • Like 1
Link to comment
Share on other sites

On 6/3/2021 at 9:23 AM, thegreatJash said:

Ok now I got somewhere but still experiencing problems. It did override the sprite for the Pan Flute, but now there is nothing on for both the floor or inventory sprites, just blankness. I converted my sprite PNG file to both XML and TEX and put those both in a folder called "images". I named them both "shell" and inserted the name when necessary. I copy and pastes your code into the modmain and put shell in them. I think there might be a problem with the images, as I'm not sure using a website to convert them did the trick. Any proper method to converting my image? I noticed that every image has both a XML file and a TEX file. I have the sprite as a PNG, now I need help converting and putting it into the code. Here's the current code by the way.

AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
    inst.AnimState:SetBank("shell") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
    inst.AnimState:SetBuild("shell")

    if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
        return
    end
    
    inst.components.inventoryitem.atlasname = "images/shell.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "shell" --the name of your image
end)

The autocompiler will automatically convert png files in the images folder to their xml and tex counterparts when you open the game(Assuming you have the Don't Starve Mod Tools enabled).

What is the name of your bank and build for the shell? Make sure they are set up correctly.

Edited by Hornete
  • Thanks 1
Link to comment
Share on other sites

25 minutes ago, Hornete said:

The autocompiler will automatically convert png files in the images folder to their xml and tex counterparts when you open the game(Assuming you have the Don't Starve Mod Tools enabled).

What is the name of your bank and build for the shell? Make sure they are set up correctly.

What exactly does this mean? Sorry I don't fully understand. I know that there is nothing wrong with my images because I pulled other TEX and XML files from properly functioning mods and still the sprite is blank. Do I have to cite the images somewhere in the code similarly how prefabs cite other prefabs? Also thanks for responding and helping me.

  • Like 1
Link to comment
Share on other sites

2 minutes ago, thegreatJash said:

What exactly does this mean? Sorry I don't fully understand. I know that there is nothing wrong with my images because I pulled other TEX and XML files from properly functioning mods and still the sprite is blank. Do I have to cite the images somewhere in the code similarly how prefabs cite other prefabs? Also thanks for responding and helping me.

Oh yeah, silly me, you'll need to load in the assets you're using in the Assets table in modmain.lua, if you don't have one then create it yourself
 

Assets = {
	Asset("IMAGE", "images/shell.tex"),
	Asset("ATLAS", "images/shell.xml"),
}

this should work alright 

Link to comment
Share on other sites

7 hours ago, Hornete said:

The autocompiler will automatically convert png files in the images folder to their xml and tex counterparts when you open the game(Assuming you have the Don't Starve Mod Tools enabled).

What is the name of your bank and build for the shell? Make sure they are set up correctly.

Ok nevermind. I got the sprites to work but there is no gound sprite for some reason. But the inventory one is working properly now. How to fix ground sprites?

Edited by thegreatJash
Link to comment
Share on other sites

23 hours ago, thegreatJash said:

Ok nevermind. I got the sprites to work but there is no gound sprite for some reason. But the inventory one is working properly now. How to fix ground sprites?

What does your scml project look like?

Link to comment
Share on other sites

On 6/5/2021 at 5:11 PM, Hornete said:

What does your scml project look like?

It is just one picture. I want the inventory and ground sprites to be the same.

Assets = {
    Asset("IMAGE", "images/rain_shell.tex"),
    Asset("ATLAS", "images/rain_shell.xml"),
}
AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
    inst.AnimState:SetBank("rain_shell") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
    inst.AnimState:SetBuild("rain_shell")

    if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
        return
    end
    
    inst.components.inventoryitem.atlasname = "images/rain_shell.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "rain_shell" --the name of your image
end)

Don't I have to make a "anim" folder and put my sprite in there and then somehow link it? I read somewhere that ground sprites are in the anim folder, along with some .bin files.
 

Rainy Shell Bell.png

Edited by thegreatJash
Link to comment
Share on other sites

 

On 6/5/2021 at 5:11 PM, Hornete said:

What does your scml project look like?

I think I am ready to transition into making this it's own item/prefab, I will figure out the ground sprite thing later. Mind helping me with setting up a new item prefab?

Edited by thegreatJash
Link to comment
Share on other sites

On 6/6/2021 at 12:52 PM, thegreatJash said:

It is just one picture. I want the inventory and ground sprites to be the same.

Assets = {
    Asset("IMAGE", "images/rain_shell.tex"),
    Asset("ATLAS", "images/rain_shell.xml"),
}
AddPrefabPostInit("panflute", function(inst) --"editing" the pan flute prefab
    inst.AnimState:SetBank("rain_shell") --setting new bank and build, replace "customsprite", with well, the name of your sprite.
    inst.AnimState:SetBuild("rain_shell")

    if not GLOBAL.TheWorld.ismastersim then --client passes this check and is returned, the server continues
        return
    end
    
    inst.components.inventoryitem.atlasname = "images/rain_shell.xml" --the directory of your atlas
    inst.components.inventoryitem.imagename = "rain_shell" --the name of your image
end)

Don't I have to make a "anim" folder and put my sprite in there and then somehow link it? I read somewhere that ground sprites are in the anim folder, along with some .bin files.
 

Rainy Shell Bell.png

Hi, sorry i'm late.

To make the ground sprite you'll need to make an "animation" (it'll just be a still sprite of course, but it's considered an animation nonetheless). To make an animation for anything in the game, you'll need to create a scml project. Create a new folder in your mod folder named "exported", and then make another folder in the exported folder named "rain_shell", in that folder. Now that you did that, open spriter, click File > New Project(Ctrl + N)

Select the rain_shell folder to be the root folder for your project, and click Select Folder. Now you did that, your spriter project should be created. Before we talk about what to do in spriter, go back to the rain_shell folder, create another folder, let's say just "shell", and then place the image you'd like to use in there and name it "shell-0". This will be your symbol.

Now go back to the spriter project, and on the right you should see something like this.
image.png.2781b87684a6fc9bca8aea7d81441b43.png
Change the name of "entity_000" to "rain_shell", and "NewAnimation" to "idle", this is your bank(AnimState:SetBank("rain_shell")) and your idle animation (AnimState:PlayAnimation("idle"))

Now at the top right here...
image.png.0bc28737c7e5b84be8ccafddd6b846bb.png
You should see your "shell" folder that you made earlier, open it up, and you should see your image, drag your image into the animation like this
2102318268_GIF6-8-20215-37-57PM.thumb.gif.2d166434ccca52d19f7da8daba382477.gif

If you're wondering where to place it, you should place it slightly above where the two lines(x axis and y axis) meet, as if the image is sitting on top of the horizontal line.

Now that you did that, save the project (in your rain_shell) folder, and make sure your scml file is named "rain_shell"(The name of your scml file is your build name fyi, (AnimState:SetBuild("rain_shell")), get the autocompiler running, and the game will compile your animation, and it'll appear in the anim folder(provided you have created one, if not, make sure to create an anim folder in your mods folder).

Now you can load in the animation
 

Asset("ANIM", "anim/rain_shell.zip")

Into the Assets table in your modmain.lua, and the pan flutes sprite should now be replaced with yours, Let me know if anything wrong happened.

 

Edited by Hornete
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Hornete said:

Hi, sorry i'm late.

To make the ground sprite you'll need to make an "animation" (it'll just be a still sprite of course, but it's considered an animation nonetheless). To make an animation for anything in the game, you'll need to create a scml project. Create a new folder in your mod folder named "exported", and then make another folder in the exported folder named "rain_shell", in that folder. Now that you did that, open spriter, click File > New Project(Ctrl + N)

Select the rain_shell folder to be the root folder for your project, and click Select Folder. Now you did that, your spriter project should be created. Before we talk about what to do in spriter, go back to the rain_shell folder, create another folder, let's say just "shell", and then place the image you'd like to use in there and name it "shell-0". This will be your symbol.

Now go back to the spriter project, and on the right you should see something like this.
image.png.2781b87684a6fc9bca8aea7d81441b43.png
Change the name of "entity_000" to "rain_shell", and "NewAnimation" to "idle", this is your bank(AnimState:SetBank("rain_shell")) and your idle animation (AnimState:PlayAnimation("idle"))

Now at the top right here...
image.png.0bc28737c7e5b84be8ccafddd6b846bb.png
You should see your "shell" folder that you made earlier, open it up, and you should see your image, drag your image into the animation like this
2102318268_GIF6-8-20215-37-57PM.thumb.gif.2d166434ccca52d19f7da8daba382477.gif

If you're wondering where to place it, you should place it slightly above where the two lines(x axis and y axis) meet, as if the image is sitting on top of the horizontal line.

Now that you did that, save the project (in your rain_shell) folder, and make sure your scml file is named "rain_shell"(The name of your scml file is your build name fyi, (AnimState:SetBuild("rain_shell")), get the autocompiler running, and the game will compile your animation, and it'll appear in the anim folder(provided you have created one, if not, make sure to create an anim folder in your mods folder).

Now you can load in the animation
 


Asset("ANIM", "anim/rain_shell.zip")

Into the Assets table in your modmain.lua, and the pan flutes sprite should now be replaced with yours, Let me know if anything wrong happened.

 

holy wow this is a lot of information. Thanks a lot. One question though, what is "spriter" and how do I get/use it?

  • Like 1
Link to comment
Share on other sites

17 minutes ago, thegreatJash said:

holy wow this is a lot of information. Thanks a lot. One question though, what is "spriter" and how do I get/use it?

Spriter is the main animation tool modders use for creating animations for the game (you're going to hate it if you ever do something more complicated like mobs)

It comes with the Mod Tools and can be launched from there

image.thumb.png.edc658a21004f4bf464c20b4bff6a77d.png

Or you can download the latest version online, which would probably be best.

  • Like 1
Link to comment
Share on other sites

1 minute ago, Hornete said:

Spriter is the main animation tool modders use for creating animations for the game (you're going to hate it if you ever do something more complicated like mobs)

It comes with the Mod Tools and can be launched from there

image.thumb.png.edc658a21004f4bf464c20b4bff6a77d.png

Or you can download the latest version online, which would probably be best.

Ok cool I'll check it out. Also I have no interest for modding mobs, so don't worry.

13 minutes ago, Hornete said:

Spriter is the main animation tool modders use for creating animations for the game (you're going to hate it if you ever do something more complicated like mobs)

It comes with the Mod Tools and can be launched from there

image.thumb.png.edc658a21004f4bf464c20b4bff6a77d.png

Or you can download the latest version online, which would probably be best.

Ok sweet it works! Now I wish to make this item it's own item prefab thing, but I'll toy with the ground sprite first.

  • Like 1
Link to comment
Share on other sites

18 hours ago, Hornete said:

Hi, sorry i'm late.

To make the ground sprite you'll need to make an "animation" (it'll just be a still sprite of course, but it's considered an animation nonetheless). To make an animation for anything in the game, you'll need to create a scml project. Create a new folder in your mod folder named "exported", and then make another folder in the exported folder named "rain_shell", in that folder. Now that you did that, open spriter, click File > New Project(Ctrl + N)

Select the rain_shell folder to be the root folder for your project, and click Select Folder. Now you did that, your spriter project should be created. Before we talk about what to do in spriter, go back to the rain_shell folder, create another folder, let's say just "shell", and then place the image you'd like to use in there and name it "shell-0". This will be your symbol.

Now go back to the spriter project, and on the right you should see something like this.
image.png.2781b87684a6fc9bca8aea7d81441b43.png
Change the name of "entity_000" to "rain_shell", and "NewAnimation" to "idle", this is your bank(AnimState:SetBank("rain_shell")) and your idle animation (AnimState:PlayAnimation("idle"))

Now at the top right here...
image.png.0bc28737c7e5b84be8ccafddd6b846bb.png
You should see your "shell" folder that you made earlier, open it up, and you should see your image, drag your image into the animation like this
2102318268_GIF6-8-20215-37-57PM.thumb.gif.2d166434ccca52d19f7da8daba382477.gif

If you're wondering where to place it, you should place it slightly above where the two lines(x axis and y axis) meet, as if the image is sitting on top of the horizontal line.

Now that you did that, save the project (in your rain_shell) folder, and make sure your scml file is named "rain_shell"(The name of your scml file is your build name fyi, (AnimState:SetBuild("rain_shell")), get the autocompiler running, and the game will compile your animation, and it'll appear in the anim folder(provided you have created one, if not, make sure to create an anim folder in your mods folder).

Now you can load in the animation
 


Asset("ANIM", "anim/rain_shell.zip")

Into the Assets table in your modmain.lua, and the pan flutes sprite should now be replaced with yours, Let me know if anything wrong happened.

 

Ok I toyed around with the inventory and ground sprites and I am happy with where they are. I would now like to make this item it's own item instead of just reskinning the Pan Flute. I want it to have the same sprites that I currently have reskinning the Pan Flute. Is there any sort of item prefab template that is not outdated out on the web? I would like to make it drop from Crab King and be a non-equipable tool (similar to the Pan Flute and Beefalo Horn). If you ever decide to find or make a item prefab template yourself, it would be really helpful if it was labeled, like with what these pieces of code etc.

I currently have a "scripts" folder and a "prefabs" folder inside of that folder. Thanks in advance.

  • Like 1
Link to comment
Share on other sites

7 hours ago, thegreatJash said:

Ok I toyed around with the inventory and ground sprites and I am happy with where they are. I would now like to make this item it's own item instead of just reskinning the Pan Flute. I want it to have the same sprites that I currently have reskinning the Pan Flute. Is there any sort of item prefab template that is not outdated out on the web? I would like to make it drop from Crab King and be a non-equipable tool (similar to the Pan Flute and Beefalo Horn). If you ever decide to find or make a item prefab template yourself, it would be really helpful if it was labeled, like with what these pieces of code etc.

I currently have a "scripts" folder and a "prefabs" folder inside of that folder. Thanks in advance.

rainshell.lua

I think something like this will work, I provided information on every line and what it does so you can still learn from it. This file should be played in the scripts/prefabs folder and then loaded into the game by placing
 

PrefabFiles = {
	"rainshell"
}

the game will then look for a "rainshell" file in scripts/prefabs and it'll find it(hopefully) and load it in, then you can go in-game and be able to spawn the shell through c_give("rainshell")

To add the shell to crab kings loot table, something like 
 

AddPrefabPostInit("crabking", function(inst) --editing crab kings "blueprint"
	if inst.components.lootdropper ~= nil then --check if the lootdropper component exists
		inst.components.lootdropper:AddChanceLoot("rainshell", 1) --1 is the chance for it to drop, 1 being 100%, and 0 being 0%
	end
end)

in modmain should work and will make him drop one rain shell when he dies at all times.

ok now finish this mod i wanna grind crab king for rain shells

Edited by Hornete
  • GL Happy 1
Link to comment
Share on other sites

42 minutes ago, Hornete said:

rainshell.lua

I think something like this will work, I provided information on every line and what it does so you can still learn from it. This file should be played in the scripts/prefabs folder and then loaded into the game by placing
 


PrefabFiles = {
	"rainshell"
}

the game will then look for a "rainshell" file in scripts/prefabs and it'll find it(hopefully) and load it in, then you can go in-game and be able to spawn the shell through c_give("rainshell")

To add the shell to crab kings loot table, something like 
 


AddPrefabPostInit("crabking", function(inst) --editing crab kings "blueprint"
	if inst.components.lootdropper ~= nil then --check if the lootdropper component exists
		inst.components.lootdropper:AddChanceLoot("rainshell", 1) --1 is the chance for it to drop, 1 being 100%, and 0 being 0%
	end
end)

in modmain should work and will make him drop one rain shell when he dies at all times.

ok now finish this mod i wanna grind crab king for rain shells

lol I know. This mod is taking longer to make than Silksong. I will definitely try this code out. After this is functioning properly, I'll only need to add a use, to summon rain, and character quotes. Also a mini sign icon. Thanks.

Edit: Wow, already force rain codes. You are on top of things.

Edited by thegreatJash
  • Like 1
Link to comment
Share on other sites

13 hours ago, thegreatJash said:

 Also a mini sign icon.

Ooh right! For minisign icons, you'll need to do this in the modmain.lua
 

RegisterInventoryItemAtlas("images/rain_shell.xml", "rain_shell")

And it'll hopefully work properly.

  • GL Happy 1
Link to comment
Share on other sites

2 hours ago, Hornete said:

Ooh right! For minisign icons, you'll need to do this in the modmain.lua
 


RegisterInventoryItemAtlas("images/rain_shell.xml", "rain_shell")

And it'll hopefully work properly.

I have a couple of questions regarding your code. I haven't run into any problems with your code yet, btw.

What does the "forceprecipitation" exactly do? Like I know it summons rain, but for how long? What happens if I run the command while it is already raining? What about in the caves?

Also how do I open and edit an already existing DST animation? I want the play animation to be the same as the Beefalo Horn play animation. How do I open it and replace the horn with my shell? Do I use Spriter? How would I implement it?

Also I think it would be kind of cool if the rain started like 3 seconds after the play animation ran.

You don't have to answer these question immediately, so take your time if you need to, as I am still playing around with the code you gave me yesterday. These questions are pretty much everything else I have to ask. After I sort these out, the mod will pretty much be complete. Thanks in advance.

  • Like 1
Link to comment
Share on other sites

25 minutes ago, thegreatJash said:

I have a couple of questions regarding your code. I haven't run into any problems with your code yet, btw.

What does the "forceprecipitation" exactly do? Like I know it summons rain, but for how long? What happens if I run the command while it is already raining? What about in the caves?

Also how do I open and edit an already existing DST animation? I want the play animation to be the same as the Beefalo Horn play animation. How do I open it and replace the horn with my shell? Do I use Spriter? How would I implement it?

Also I think it would be kind of cool if the rain started like 3 seconds after the play animation ran.

You don't have to answer these question immediately, so take your time if you need to, as I am still playing around with the code you gave me yesterday. These questions are pretty much everything else I have to ask. After I sort these out, the mod will pretty much be complete. Thanks in advance.

The weather component listens for the "ms_forceprecipitation" event, and calls the OnForcePrecipitation function when the event i pushed.

inst:ListenForEvent("ms_forceprecipitation", OnForcePrecipitation, _world)
local OnForcePrecipitation = _ismastersim and function(src, enable)
    _moisture:set(enable ~= false and _moistureceil:value() or _moisturefloor:value())
end or nil

If you set it to true, then the moisture level of the current world you're in will be set to to the _moisturecel value, if it's false, it'll be set to the _moisturefloor value, thus enabling/disabling rain respectively.

The _moistureceiling and _moisturefloor levels are determined every time rain starts and ends and they are slightlly random each time, they are the max/minimum values the moisture of the world can be. These values will vary each season too. If you run the command while it's already raining, the moisture value will just be set to the maximum value it can be again. In the caves, there's pretty much no difference and it works perfectly fine.

You won't need to create a new animation, you'll be doing something called "symbol swapping/overriding", where essentially you swap one piece in an animation for another, to replace the horn with your shell, you're gonna "swap" the horn sprite with your shell sprite, I'll show you how to do this later.

To delay the rain you can do DoTaskInTime, which does exactly what it sounds like, something like
 

local function OnPlayed(inst, musician)
	inst:DoTaskInTime(3, function()  --Wait 3 seconds to run the function we passed
		TheWorld:PushEvent("ms_forceprecipitation", true)
	end)
end

When the shell is played, after 3 seconds the rain will begin. You can change the 3 to whichever value you'd like, remember that it's in amount of seconds.

  • Like 2
Link to comment
Share on other sites

2 hours ago, Hornete said:

The weather component listens for the "ms_forceprecipitation" event, and calls the OnForcePrecipitation function when the event i pushed.


inst:ListenForEvent("ms_forceprecipitation", OnForcePrecipitation, _world)

local OnForcePrecipitation = _ismastersim and function(src, enable)
    _moisture:set(enable ~= false and _moistureceil:value() or _moisturefloor:value())
end or nil

If you set it to true, then the moisture level of the current world you're in will be set to to the _moisturecel value, if it's false, it'll be set to the _moisturefloor value, thus enabling/disabling rain respectively.

The _moistureceiling and _moisturefloor levels are determined every time rain starts and ends and they are slightlly random each time, they are the max/minimum values the moisture of the world can be. These values will vary each season too. If you run the command while it's already raining, the moisture value will just be set to the maximum value it can be again. In the caves, there's pretty much no difference and it works perfectly fine.

You won't need to create a new animation, you'll be doing something called "symbol swapping/overriding", where essentially you swap one piece in an animation for another, to replace the horn with your shell, you're gonna "swap" the horn sprite with your shell sprite, I'll show you how to do this later.

To delay the rain you can do DoTaskInTime, which does exactly what it sounds like, something like
 


local function OnPlayed(inst, musician)
	inst:DoTaskInTime(3, function()  --Wait 3 seconds to run the function we passed
		TheWorld:PushEvent("ms_forceprecipitation", true)
	end)
end

When the shell is played, after 3 seconds the rain will begin. You can change the 3 to whichever value you'd like, remember that it's in amount of seconds.

Thanks. I'll sure be busy tonight. You probably won't hear from me for at least a day or two. I'll come back once everything you have given me is in place.

Link to comment
Share on other sites

6 hours ago, Hornete said:

The weather component listens for the "ms_forceprecipitation" event, and calls the OnForcePrecipitation function when the event i pushed.


inst:ListenForEvent("ms_forceprecipitation", OnForcePrecipitation, _world)

local OnForcePrecipitation = _ismastersim and function(src, enable)
    _moisture:set(enable ~= false and _moistureceil:value() or _moisturefloor:value())
end or nil

If you set it to true, then the moisture level of the current world you're in will be set to to the _moisturecel value, if it's false, it'll be set to the _moisturefloor value, thus enabling/disabling rain respectively.

The _moistureceiling and _moisturefloor levels are determined every time rain starts and ends and they are slightlly random each time, they are the max/minimum values the moisture of the world can be. These values will vary each season too. If you run the command while it's already raining, the moisture value will just be set to the maximum value it can be again. In the caves, there's pretty much no difference and it works perfectly fine.

You won't need to create a new animation, you'll be doing something called "symbol swapping/overriding", where essentially you swap one piece in an animation for another, to replace the horn with your shell, you're gonna "swap" the horn sprite with your shell sprite, I'll show you how to do this later.

To delay the rain you can do DoTaskInTime, which does exactly what it sounds like, something like
 


local function OnPlayed(inst, musician)
	inst:DoTaskInTime(3, function()  --Wait 3 seconds to run the function we passed
		TheWorld:PushEvent("ms_forceprecipitation", true)
	end)
end

When the shell is played, after 3 seconds the rain will begin. You can change the 3 to whichever value you'd like, remember that it's in amount of seconds.

I played with this code all day and the raining/snowing is working properly. The item also has a functioning ground/water sprite, and drops from Crab King like it should. The mod the is nearing completion, but I still have a couple unanswered questions.

The mod name is "MISSINGNAME". Should I put something like STRING.NAME.RAINSHELL = "Rain Shell Bell" in the rainshell prefab?

How do I implement character quotes.

Also the minisign code doesn't seem to function properly, as the minisign doesn't display anything. The item also doesn't have an inventory sprite, it's just blank again. I loaded in both the .XML and .TEX files in the rainshell prefab. The ground sprite works fine though.

I'm currently fine with the animation being the Pan Flute one, so you can take as much time as you want with this "symbol swapping".

Edit: I must a dumb@ss or something because I put two lines of code that fixed the inventory sprite thing. How did I forget. I also toyed around with the code and fixed the MISSINGNAME thing.

Edited by thegreatJash
  • Like 1
Link to comment
Share on other sites

On 6/10/2021 at 6:09 PM, thegreatJash said:

I'm currently fine with the animation being the Pan Flute one, so you can take as much time as you want with this "symbol swapping".

Alrighty, you're going to need to add a new "state" to the player character, a state is exactly what it sounds like, just something that controls specific states for a player, like there's a "play_flute" state for the pan flute, and a "play_horn" state for the beefalo horn.

In modmain you'll need to put
 

--GLOBAL is just a thing we need to put for some variables to properly access them
AddStategraphState("wilson", GLOBAL.State{
        name = "play_shell", --The name of your state(Maybe you want to make the name more unique? If another mod adds the same name, it'll override, and "play_shell" is a pretty basic name, your noice!)
        tags = { "doing", "playing" }, --Tags to add during the state

        onenter = function(inst)
            inst.components.locomotor:Stop() --Tell our character to stop moving
            inst.AnimState:PlayAnimation("action_uniqueitem_pre") --play the necessary animations
            inst.AnimState:PushAnimation("flute", false) --PushAnimation queues the next animation

            inst.AnimState:OverrideSymbol("pan_flute01", "rain_shell", "shell") --We are overriding the "pan_flute01" symbol with the "shell" symbol from our "rain_shell" file

            inst.AnimState:Hide("ARM_carry")
            inst.AnimState:Show("ARM_normal")
            inst.components.inventory:ReturnActiveActionItem(inv_obj)
        end,

        timeline =
        {
            TimeEvent(30 * FRAMES, function(inst)
                if inst:PerformBufferedAction() then
                    inst.SoundEmitter:PlaySound("dontstarve/wilson/flute_LP", "flute") --Play the flute sound, (Maybe make a unique sound? would be cool :P)
                else
                    inst.AnimState:SetTime(94 * FRAMES)
                end
            end),
            TimeEvent(85 * FRAMES, function(inst)
                inst.SoundEmitter:KillSound("flute")
            end),
        },

        events =
        {
            EventHandler("animqueueover", function(inst)
                if inst.AnimState:AnimDone() then
                    inst.sg:GoToState("idle") --When the animation is done, return to the idle state
                end
            end),
        },

        onexit = function(inst)
            inst.SoundEmitter:KillSound("flute") --kill the flute sound
            if inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) then
                inst.AnimState:Show("ARM_carry")
                inst.AnimState:Hide("ARM_normal")
            end
        end,
    })

This will add the "play_shell" state to the "wilson" stategraph(All characters use the "wilson" stategraph, so don't worry, you don't need to add to a "willow" stategraph of some kind and others) I just copy and pasted the play_flute state found in stategraphs/SGwilson.lua and edited it to have the shell sprite swapped instead.

You still need to do one last thing though! You need to actually tell the game which state to play when doing the PLAY action, for that, we need to edit an actionhandler.
 

AddStategraphPostInit("wilson", function(sg)
	local _PLAY = inst.actionhandlers[ACTIONS.PLAY].deststate --Save the original function determining the state for the PLAY action
	inst.actionhandlers[ACTIONS.PLAY].deststate = function(inst, act, ...)
		return act.invobject ~= nil --Make sure the object responsible for the action exists, unlikely to happen, but if it does happen, the game would crash! So this check is important
			and	(act.invobject:HasTag("rain_shell") and "play_shell") --If the object has the "rain_shell" tag, then the play_shell state will play
			or _PLAY(inst, act, ...) --If all checks fail, go back to the original vanilla function
	end
end)
--We "wrap" the function so we can have compatibility, if we just replaced it, the code might break if another mod also replaces it, or klei updates the original function. This way the code should never break

You also need this in modmain.lua, Add the "rain_shell" tag to your shell(by putting inst:AddTag("rain_shell") in your shells constructor) and it should hopefully work! If it does not, let me know.

 

 

On 6/10/2021 at 6:09 PM, thegreatJash said:

How do I implement character quotes.

local STRINGS = GLOBAL.STRINGS --shortens our code, so that we don't need to put GLOBAL. before each call of STRINGS

STRINGS.CHARACTERS.GENERIC.DESCRIBE.RAINSHELL =  "   " --Generic is Wilsons examinations
STRINGS.CHARACTERS.WILLOW.DESCRIBE.RAINSHELL =  "   "
STRINGS.CHARACTERS.WENDY.DESCRIBE.RAINSHELL =  "   "
--and etc, Im sure you know what else to put to have quotes for the other characters

(in modmain.lua)

 

On 6/10/2021 at 6:09 PM, thegreatJash said:

Also the minisign code doesn't seem to function properly, as the minisign doesn't display anything

Ahh, I think I typed it wrong, I accidentally put an underscore between rain and shell in the 2nd string. I think this'll work
 

RegisterInventoryItemAtlas("images/rain_shell.xml", "rainshell")

 

  • GL Happy 1
Link to comment
Share on other sites

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
 Share

×
  • Create New...