Jump to content

Special character perk help


Recommended Posts

I am making a character mod, and what I basically wanted was a character that can grow plants at their feet like wormwood/fuelweaver and leave trails constantly. I have no idea how to achieve this..

Help would be greatly appreciated

Link to comment
Share on other sites

Do you want just the visual trail, with no added effect?

If you need just the visual trail, the file with the effects is wormwood_plant_fx.lua in the prefab folder. It's just a bunch of animation settings you can copy exactly, or even hijack to include your character.

I would achieve this by giving the custom character a unique tag for the trail, and then adding a new definition for onAnimOver for the fx effect, that also snaps its position back to your character's feet. (Just a matter of checking an extra tag)

Something like the code below should work. It might double up existing Wormwood plant trails but this is also easily fixable by removing the  original listener in TrailFxPrefabPostInit. It might also crash, there might be some bugs in the code.

Spoiler

local trail_fx = require("prefabs/wormwood_plant_fx.lua")

local old_OnAnimOver = trail_fx.onAnimOver

local function new_OnAnimOver(inst)

    if inst.AnimState:IsCurrentAnimation("ungrow_"..tostring(inst.variation)) then
        inst:Remove()
    else
        local x, y, z = inst.Transform:GetWorldPosition()
        for i, v in ipairs(AllPlayers) do
            if v.fullbloom and
                v:HasTag([ YOUR NEW TAG GOES HERE ]) and
                not (v.components.health:IsDead() or v:HasTag("playerghost")) and
                v.entity:IsVisible() and
                v:GetDistanceSqToPoint(x, y, z) < 4 then
                inst.AnimState:PlayAnimation("idle_"..tostring(inst.variation))
                return
            else

                 return old_onAnimOver(inst)

            end
        end
        inst.AnimState:PlayAnimation("ungrow_"..inst.variation)
    end
end

local function TrailFxPrefabPostInit(prefab)
    prefab:ListenForEvent("onAnimOver", new_OnAnimOver)
end

AddPrefabPostInit("wormwood_plant_fx",TrailFxPrefabPostInit)

If you want to change the animation itself, you can just duplicate the file and change the animation bank.

  • Like 2
Link to comment
Share on other sites

9 hours ago, AndRay said:

Do you want just the visual trail, with no added effect?

If you need just the visual trail, the file with the effects is wormwood_plant_fx.lua in the prefab folder. It's just a bunch of animation settings you can copy exactly, or even hijack to include your character.

I would achieve this by giving the custom character a unique tag for the trail, and then adding a new definition for onAnimOver for the fx effect, that also snaps its position back to your character's feet. (Just a matter of checking an extra tag)

Something like the code below should work. It might double up existing Wormwood plant trails but this is also easily fixable by removing the  original listener in TrailFxPrefabPostInit. It might also crash, there might be some bugs in the code.

  Hide contents

local trail_fx = require("prefabs/wormwood_plant_fx.lua")

local old_OnAnimOver = trail_fx.onAnimOver

local function new_OnAnimOver(inst)

    if inst.AnimState:IsCurrentAnimation("ungrow_"..tostring(inst.variation)) then
        inst:Remove()
    else
        local x, y, z = inst.Transform:GetWorldPosition()
        for i, v in ipairs(AllPlayers) do
            if v.fullbloom and
                v:HasTag([ YOUR NEW TAG GOES HERE ]) and
                not (v.components.health:IsDead() or v:HasTag("playerghost")) and
                v.entity:IsVisible() and
                v:GetDistanceSqToPoint(x, y, z) < 4 then
                inst.AnimState:PlayAnimation("idle_"..tostring(inst.variation))
                return
            else

                 return old_onAnimOver(inst)

            end
        end
        inst.AnimState:PlayAnimation("ungrow_"..inst.variation)
    end
end

local function TrailFxPrefabPostInit(prefab)
    prefab:ListenForEvent("onAnimOver", new_OnAnimOver)
end

AddPrefabPostInit("wormwood_plant_fx",TrailFxPrefabPostInit)

If you want to change the animation itself, you can just duplicate the file and change the animation bank.

Thank you so much for your help, I know next to nothing about modding, so forgive me for my ignorance- But-

Basically, I have to go to scripts, get prefabs/wormwood_plant_fx, put it in my  prefab folder, and also get the decompile from krane the anim of the fx zip and put it in exported to let it autocompile- And this code, does it belong in my character's prefab or modmain?

And yes, I just wanted the visual effect wormwood gets at his feet during spring and the trail, but always active.. I am very grateful 

Link to comment
Share on other sites

Sorry for the delayed response.

No, the whole point of the fix is to abuse what a prefab is. Prefab means the game has a special custom-made function to place the object (this is what a [thing].lua must return)

The game has already in its code all of the logic to process the animation. So, instead of having to hard-wire the animation all over again, you just use that code and functions. So, you just add to modmain.lua the code that says "hey, game, how about, when you go to set up my mod stuff, you just go to that prefab file and tweak this little piece?"

You tell the game: 1) you wish to change stuff in wormwood_plant_fx.lua (this is the AddPrefabPostInit)

2) your desired change is to change the function OnAnimOver that the file defines. Why that function? Well, it's because it's the only function in the file that checks the players' tag (and therefore is the only function that "knows" it's dealing with a Wormwood)

The function that deals with the swapping process is TrailFxPrefabPostInit. (This function is custom-made and therefore its name can be whatever you want)

3) you want to change OnAnimOver by adding a new handler for your custom character (this is what new_OnAnimOver does; it's a copy of the important part of the function with the Wormwood tags swapped for your custom character ones), and then (AND THIS IS VERY IMPORTANT) you resume processing the usual OnAnimOver function. (This is what old_OnAnimOver does, it gets the old code before you changed it)

Why do you want to get and use the old code instead of copying it all? First, for simplicity; and second and more important, you maintain compatibility with the base game and all mods that ever want to change that thing (because if they also get the old code before running, the logic will be safe no matter what is changed and in what order)

That's all.

So, this is a small tweak that wants to be run only once in the game. Therefore, you put it in modmain.lua, which runs only at setup, instead of putting it in your character prefab, and force the poor game to run your code everytime a new instance of your character is called.

Also, one thing I forgot to take into account. Wormwood needs to set up the first animation (because the trigger we are changing is OnAnimOver, which only gets called if the animation already ended, and so it won't start in the first place) The fix is simple, though: go to wormwood.lua and copy the whole function PlantTick from lines 243 to 280, and just paste that at the top in your character file (because each individual character has to set its own trail, this can't go in modmain [well, it can, by using AddPrefabPostInit before your character is created, but this would do the same thing in a much more confusing way]) Then, INSIDE your function to define the character (the function that you return) put, in the last line possible, the code

local inst.trail_task = inst:DoPeriodicTask(.25, PlantTick)

Although, to be clear, you CAN code a new copy, it's just a bit longer, and requires you to also copy all the internal wiring of the trail as well. So, to be able to do this, you would need to take a bit of a deeper look at these functions and do the necessary changes. There are not that many (mostly naming conflicts), but it's just cleaner to copy what's already done.

Also, on a second reading, I forgot to address two small points.

There is no need to delve into .tex / Spriter animations, or files, because if you use the default trail you will also use the default trail files.

Even if you created copies of those, as you didn't tell the game to import those, they will just sit forever unused in limbo. (The code for importing files can be seen at the start of a prefab file, it's the Asset stuff, and then the constructor function (the one you return) sets the animation build and bank.)

The second thing is a minor observation on my commentary about modmain versus [character].lua. In general, if you put code inside a prefab file, there are two complications that can arrive. First, there can be timing issues depending on when the file is loaded, so it's best to not mess with other prefab stuff inside of them, and second, there can be indexing issues because the prefab file is treated as a separate thing and so does not get access (by default) to the stuff you define elsewhere (such as trail parameters.)

Be sure to put, inside your character file, near the top, the code

local prefabs = { "wormwood_plant_fx" }

or add "wormwood_plant_fx" to your prefab list if it's already there, to prevent that second problem I just mentioned.

Sorry for the humongous wall of text.

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

On 11/8/2020 at 8:37 PM, AndRay said:

Sorry for the delayed response.

No, the whole point of the fix is to abuse what a prefab is. Prefab means the game has a special custom-made function to place the object (this is what a [thing].lua must return)

The game has already in its code all of the logic to process the animation. So, instead of having to hard-wire the animation all over again, you just use that code and functions. So, you just add to modmain.lua the code that says "hey, game, how about, when you go to set up my mod stuff, you just go to that prefab file and tweak this little piece?"

You tell the game: 1) you wish to change stuff in wormwood_plant_fx.lua (this is the AddPrefabPostInit)

2) your desired change is to change the function OnAnimOver that the file defines. Why that function? Well, it's because it's the only function in the file that checks the players' tag (and therefore is the only function that "knows" it's dealing with a Wormwood)

The function that deals with the swapping process is TrailFxPrefabPostInit. (This function is custom-made and therefore its name can be whatever you want)

3) you want to change OnAnimOver by adding a new handler for your custom character (this is what new_OnAnimOver does; it's a copy of the important part of the function with the Wormwood tags swapped for your custom character ones), and then (AND THIS IS VERY IMPORTANT) you resume processing the usual OnAnimOver function. (This is what old_OnAnimOver does, it gets the old code before you changed it)

Why do you want to get and use the old code instead of copying it all? First, for simplicity; and second and more important, you maintain compatibility with the base game and all mods that ever want to change that thing (because if they also get the old code before running, the logic will be safe no matter what is changed and in what order)

That's all.

So, this is a small tweak that wants to be run only once in the game. Therefore, you put it in modmain.lua, which runs only at setup, instead of putting it in your character prefab, and force the poor game to run your code everytime a new instance of your character is called.

Also, one thing I forgot to take into account. Wormwood needs to set up the first animation (because the trigger we are changing is OnAnimOver, which only gets called if the animation already ended, and so it won't start in the first place) The fix is simple, though: go to wormwood.lua and copy the whole function PlantTick from lines 243 to 280, and just paste that at the top in your character file (because each individual character has to set its own trail, this can't go in modmain [well, it can, by using AddPrefabPostInit before your character is created, but this would do the same thing in a much more confusing way]) Then, INSIDE your function to define the character (the function that you return) put, in the last line possible, the code

local inst.trail_task = inst:DoPeriodicTask(.25, PlantTick)

Although, to be clear, you CAN code a new copy, it's just a bit longer, and requires you to also copy all the internal wiring of the trail as well. So, to be able to do this, you would need to take a bit of a deeper look at these functions and do the necessary changes. There are not that many (mostly naming conflicts), but it's just cleaner to copy what's already done.

Also, on a second reading, I forgot to address two small points.

There is no need to delve into .tex / Spriter animations, or files, because if you use the default trail you will also use the default trail files.

Even if you created copies of those, as you didn't tell the game to import those, they will just sit forever unused in limbo. (The code for importing files can be seen at the start of a prefab file, it's the Asset stuff, and then the constructor function (the one you return) sets the animation build and bank.)

The second thing is a minor observation on my commentary about modmain versus [character].lua. In general, if you put code inside a prefab file, there are two complications that can arrive. First, there can be timing issues depending on when the file is loaded, so it's best to not mess with other prefab stuff inside of them, and second, there can be indexing issues because the prefab file is treated as a separate thing and so does not get access (by default) to the stuff you define elsewhere (such as trail parameters.)

Be sure to put, inside your character file, near the top, the code

local prefabs = { "wormwood_plant_fx" }

or add "wormwood_plant_fx" to your prefab list if it's already there, to prevent that second problem I just mentioned.

Sorry for the humongous wall of text.

 

THANK YOU SO MUCH. 

  • Like 1
Link to comment
Share on other sites

@AndRay about Wormwood, i really like his ability to plant seeds straight into the ground, is there a ways to transfer this to other mod char?! 

I found this ability has something to do with tag plantkin (appeared in Wormwood.lua, seed.lua, and veggie.lua, and some other lua file), so i add the line "inst:AddTag("plantkin")" from Wormwood.lua to my mod char, and my mod char can plant seeds into the gound but he also have Wormwood's Nature craft tab which i don't want.

P/s: i'm a copy-paste kind of modder (which mean i know next to nothing about modding :D), sorry to mention you in this post. sorry Op for i take advance of your post instead of create a new thread.

P/s 2: i don't mind 

18 hours ago, Arimo said:

humongous wall of text

as long as it help me get the mod done. But since i'm next to nothing about modding, can you simplify the answer into something like: copy this lines into this file (modinfo.lua or modmain.lua, or yourchar.lua file, or create a new file with this line and copy that to this folder....) much appreciated.

This are the lines i found in seeds and veggies (Which i think matter):

Spoiler

Seeds.lua

    inst:AddComponent("deployable")
    inst.components.deployable:SetDeployMode(DEPLOYMODE.PLANT)
    inst.components.deployable.restrictedtag = "plantkin"
    inst.components.deployable.ondeploy = OnDeploy

Veggies.lua:

        inst:AddComponent("deployable")
        inst.components.deployable:SetDeployMode(DEPLOYMODE.PLANT)
        inst.components.deployable.restrictedtag = "plantkin"
        inst.components.deployable.ondeploy = OnDeploy

It's look the same, and i think it mean that those who have "plantkin" tag can plant seeds and veggies seeds into the ground. Don't know how to bring these code to other mod char, because just add the "plantkin" tag to the char will also bring Wormwood's Nature craft tab.

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

So, main issue is: game loves to recycle tags. (It also has an unnecessary extra supply of them, and it's weird that they do both, but oh well)

Doing a quick search reveals the main issue: the game uses the "plantkin" tag as essential part of the crafting tab. (Also sanity checks so it gains some of the bad sanity perks of Wormwood)

This leaves us with essentially two options: either we modify the existing tags, or we copy the functionality of the tags themselves. The tradeoffs are, as above, modifying what's already there requires knowing where to insert code, and copying functionality requires knowing how to organize code hierarchy.

Small hierarchy info: usually, things that are done with the mouse icon are actions. These are always indexed by "can the person do the action" and "can the object take part in this action".

Here, copying seeds is not really feasible; reason being, there are a ton of ways to get and use seeds so modifying them all is very prone to errors and crashes. We should probably try to modify the tag effects then. Better yet, as there is a neat special variable to hold a check tag (restrictedtag above) we can just change that and give our character and Wormwood the new tag.

So, we just need to put this new tag on these four* places.

The first in your custom character; you can modify its prefab file at will so you can just go to the source code of [yourcharacter].lua and add

Spoiler

inst:AddTag("can_plant_seeds_on_ground")

The second is in the seed prefab file. You need to hijack it with AddPrefabPostInit. So:

Spoiler

local function SeedTagFix(prefab)

       prefab.components.deployer.restrictedtag = "can_plant_seeds_on_ground"

end

AddPrefabPostInit("seeds", SeedTagFix)

The third is a bit more involved. The game does not have a single file for each veggie prefab (that would be weird) so it does them in batch. That means that 1. the code you're looking for is much less obvious to find and 2. you have to fix it in batches as well. I'm not 100% sure this code works, but it should. There also might be an easier way to get the table, but manual insertion is good enough. Not compatible with other mods, though :/

Spoiler

local veggie_seed_table = {seed1="carrot_seeds", seed2="potato_seeds",} --add all veggie seeds you want to change

for k,v in pairs(veggie_seed_table) do

       AddPrefabPostInit(v, SeedTagFix)

end

The last is giving poor Wormwood its ability back.

Spoiler

local function WormwoodGiveTag(prefab)

       prefab:AddTag("can_plant_seeds_on_ground")

end

AddPrefabPostInit("wormwood", WormwoodGiveTag)

All of these run only once, at startup, and therefore go in modmain.

  • Like 2
Link to comment
Share on other sites

First of all, i want to thank you for taking time explain things, much appreciated.

I got this when create a new game with the new code

image.thumb.png.35e871b618fce1784238e1fc70e17682.png

Your code in my modmain.lua look like this (don't know if i doing it right):

Spoiler

----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------

local function SeedTagFix(prefab)

       prefab.components.deployer.restrictedtag = "can_plant_seeds_on_ground"   <<< I think the Error message mention this line

end

AddPrefabPostInit("seeds", SeedTagFix)

local veggie_seed_table = {seed1="carrot_seeds", seed2="potato_seeds", seed3="corn_seeds", seed4="dragonfruit_seeds", seed5="durian_seeds", seed6="eggplant_seeds", seed7="pomegranate_seeds", seed8="pumpkin_seeds", seed9="watermelon_seeds", seed10="asparagus_seeds", seed11="tomato_seeds", seed12="onion_seeds", seed13="pepper_seeds", seed14="garlic_seeds",} --add all veggie seeds you want to change

for k,v in pairs(veggie_seed_table) do

       AddPrefabPostInit(v, SeedTagFix)

end

local function WormwoodGiveTag(prefab)

       prefab:AddTag("can_plant_seeds_on_ground")

end

AddPrefabPostInit("wormwood", WormwoodGiveTag)

----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------

I play Woodie, with the mod Woodie Unchained, so in the woodie.lua file (of the Woodie Unchained mod), i add inst:AddTag("can_plant_seeds_on_ground") under the local function common_postinit(inst) section (Right?!).

P/s: thanks for your help.

Link to comment
Share on other sites

1 hour ago, AndRay said:

"deployable"

Tried that too, the error message mentioned the "deployer" in the line No.100 of the modmain.lua, so i replaced it with "deployable", still the error. So i switch back to "deployer" to take the screenshot.

"deployable" still a nil value :D

image.thumb.png.9f5ced7a0997de69c60c1b5ccb8b87a3.png

P/s: Thank for still here with me, maybe i should give up on this perk :D

Link to comment
Share on other sites

Yeah, Cave on by default, because summer is a pain in the .... :D

So the line look like this:

    if GLOBAL.TheWorld.ismastersim then (prefab.components.deployable.restrictedtag = "can_plant_seeds_on_ground") 
    end

and the whole part look like this:

Spoiler

local function SeedTagFix(prefab)

    if GLOBAL.TheWorld.ismastersim then (prefab.components.deployable.restrictedtag = "can_plant_seeds_on_ground") 
    end

end

Now i'm stuck at "Server is Generating World" message, and still loading :D.

Link to comment
Share on other sites


[string "../mods/workshop-846748508/modmain.lua"]:100: ')' expected near '='

Mismatched parenthesis.

The game correctly shuts down the crashing mod, but then it realizes it shut down a server mod and freaks out because you're not supposed to disable mods mid-playthrough.

  • Like 2
  • Haha 1
Link to comment
Share on other sites

Is there a easy way to recondition something.

I found a line in constants.lua under CUSTOM_RECIPETABS section:

Spoiler

    NATURE        = { str = "NATURE",            sort = 999, icon = "tab_nature.tex",        owner_tag = "plantkin"     },

Which i think mean that those who have the "plantkin" tag will have access to Nature craft tab. So what if we change that to a new tag and give that new tag to Wormwood, than we can use "Plantkin" tag on the mod char to have the abilitiy to plant seed into the ground (plus some sanity downside) without the nature craft tab. Would it be easier?! Just some thought.

P/s: Since no further instruction on how to fix "Mismatched parenthesis." i just add "Plantkin" tag to my Woodie and live with it :D, then the idea above came up. tbh the nature's craft tab is the one that bother me :D.

Edited by Psychomaniac
Link to comment
Share on other sites

Editing the craft recipe would need just as much work but it would be more annoying because of the amount of recipes needed.

Mismatched parenthesis can be seen in any decent text editor, such as Notepad++. Just go to the line marked and check all parenthesis pairs. There is probably one missing at the end. Just add it back.

This is not the kind of mistake that you should give up for, because typing errors will be ubiquitous if you keep on modding. It's just a matter of getting used to the debugger.

  • Like 3
Link to comment
Share on other sites

OMG, IT'S WORK :D !!!!!

The error line is this line:

if GLOBAL.TheWorld.ismastersim then (prefab.components.deployable.restrictedtag = "can_plant_seeds_on_ground")

after try place the "(" & ")" every place possible code still not work:

if GLOBAL.TheWorld.ismastersim then (prefab.components.deployable.restrictedtag) = ("can_plant_seeds_on_ground")

if GLOBAL.TheWorld.ismastersim then (prefab.components.deployable.restrictedtag) = "can_plant_seeds_on_ground"

on my last atempt, i decided to just get rid of "(" and ")" in that line, so it became: 

if GLOBAL.TheWorld.ismastersim then prefab.components.deployable.restrictedtag = "can_plant_seeds_on_ground"
This time it's work :D

Thank you so much.

Here is the final code for the "Plant seeds into the ground" ability:

Spoiler

Step1: Copy this into your modmain.lua file:

----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------

-- Ability: Plant seeds into the ground
-- Codes & Guide: AndRay from DST's 4rum
-- Hijack the ability from the seed prefab file with AddPrefabPostInit
local function SeedTagFix(prefab)

    if GLOBAL.TheWorld.ismastersim then prefab.components.deployable.restrictedtag = "can_plant_seeds_on_ground"
    end

end

-- List all the seeds
AddPrefabPostInit("seeds", SeedTagFix)

local veggie_seed_table = {seed1="carrot_seeds", seed2="potato_seeds", seed3="corn_seeds", seed4="dragonfruit_seeds", seed5="durian_seeds", seed6="eggplant_seeds", seed7="pomegranate_seeds", seed8="pumpkin_seeds", seed9="watermelon_seeds", seed10="asparagus_seeds", seed11="tomato_seeds", seed12="onion_seeds", seed13="pepper_seeds", seed14="garlic_seeds",} --add all veggie seeds you want to change

for k,v in pairs(veggie_seed_table) do

       AddPrefabPostInit(v, SeedTagFix)

end

-- Give poor Wormwood its ability back
local function WormwoodGiveTag(prefab)

       prefab:AddTag("can_plant_seeds_on_ground")

end

AddPrefabPostInit("wormwood", WormwoodGiveTag)

----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------

Step 2: Copy this line into [yourcharacter].lua file under the local function common_postinit(inst) section

    -- Ability: Plant seeds into the ground like Wormwood
    inst:AddTag("can_plant_seeds_on_ground")

Step 3: Save and DONE!!! Enjoy!!!!

 

 

Edited by Psychomaniac
  • Like 2
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...