Jump to content

[SOLVED] Custom reader component


Recommended Posts

Hi and thanks for taking the time to read this.
Basically, I wanted my custom character to have the ability to read only my custom book and could not read the wickerbottom books (and wickerbottom or maxwell could not read my custom book either).
I tried to copy the components "reader" and "book", changing to "readertwo" and "booktwo" (and adding the respective tags as well), for example, but without success. Only the option to examine the book appears.
Then I tried several times to mess around with the stategraph used when reading a book, and yet, no success (well, I'm not very familiar with stategraphs).

I would like to know if someone more experienced would have a solution (or even a simpler method, which I am not aware of from my point of view).

Link to comment
Share on other sites

I'm aware of the use of tags. It's the same system wigfrid uses to craft her personal items (spear and helm).
Codex umbra also uses the tag "shadowmagic", so only maxwell can use it.
However, the codex umbra acts as a science machine, not as a book itself. So this system of adding tags, by itself, does not eliminate my problem.
Anyway, thanks for your response.

Still no solution. Somebody else?

Link to comment
Share on other sites

If I am not mistaken, while you are on the right track, you forgot to make a new action for your unique reader component.

There was a tutorial on here somewhere: 

 

But I think you can even recycle the book stategraph animation and just make a modified clone of the actions.

Spoiler

local READTWO = GLOBAL.Action({ priority= 10 })	
READTWO.str = "Read"
READTWO.id = "READTWO"
READTWO.fn = function(act)
    local targ = act.target or act.invobject
    if targ ~= nil and
        act.doer ~= nil and
        targ.components.booktwo ~= nil and
        act.doer.components.readertwo ~= nil then
        return act.doer.components.readertwo:Read(targ)
    end
end
AddAction(READTWO)
-- Stategraph ActionHandler. Name is pretty self-explanatory. It handles actions, so that the stategraph can execute them.
-- Check out Steam/SteamApps/common/Dont Starve Together/scripts/stategraphs/SGwilson.lua to learn more.
local READTWO_handler = ActionHandler(ACTIONS.READTWO, "book")
AddStategraphActionHandler("wilson", READTWO_handler)
AddStategraphActionHandler("wilson_client", READTWO_handler)

-- ComponentAction. This makes it so we get a prompt to use our action.
-- ComponentActions also exist on clients. Things like components and variables arent networked, so dont check for these.
-- The best way is to check tags or replicable components.
-- Check Steam/SteamApps/common/Dont Starve Together/scripts/componentactions.lua to learn more.
AddComponentAction("INVENTORY", "readertwo", function(inst, doer, actions)
    if doer:HasTag("player")then
        table.insert(actions, ACTIONS.READTWO)
    end
end)

Paste into modmain.lua

This assumes you are using a component.readertwo on your custom character as well as a custom component.booktwo for the books.

I haven't tested this, but it seems to be the direction you need to go.

Iron_Hunter

 

Link to comment
Share on other sites

Wow, that piece of code gave me hope. Maybe I had never come to this conclusion xD

Yes, I also think it is possible to recycle the action used to read books.
After adjusting some small details (the game was crashing because of the global variable), still, no success (I even tried lowering the priority to 3 or less).
The game is no longer crashing, which is a good sign. But the book still only provides the option to examine.
But I have hopes that we are on the right track. Maybe you want to analyze my entire file? (if you have the time and the will for it, of course). Some important detail may have gone unnoticed in my eyes.

Edited by Rita
Link to comment
Share on other sites

I think I forgot to include

local require = GLOBAL.require
local State = GLOBAL.State
local Action = GLOBAL.Action
local ActionHandler = GLOBAL.ActionHandler
local TimeEvent = GLOBAL.TimeEvent
local EventHandler = GLOBAL.EventHandler
local ACTIONS = GLOBAL.ACTIONS
local FRAMES = GLOBAL.FRAMES

before that snippet of code

Which explains the global issues.

I'll do a test when I have some time.

Iron_Hunter

Edited by IronHunter
typo
Link to comment
Share on other sites

After some testing I got it to work

Spoiler

local ACTIONS = GLOBAL.ACTIONS
local Action = GLOBAL.Action
local ActionHandler = GLOBAL.ActionHandler
local READTWO = Action({ priority= 10, mount_valid=true })	
READTWO.str = "Read"
READTWO.id = "READTWO"
READTWO.fn = function(act)
    local book = act.invobject or act.target 
    if book and act.doer and book.components.booktwo and act.doer.components.readertwo then
        return act.doer.components.readertwo:Read(book)
    end
end
AddAction(READTWO)
AddComponentAction("INVENTORY", "booktwo", function(inst, doer, actions)
    if doer:HasTag("readertwo")then
        table.insert(actions, ACTIONS.READTWO)
    end
end)
local readtwo_handler = ActionHandler(ACTIONS.READTWO, "book")
AddStategraphActionHandler("wilson_client", readtwo_handler)
AddStategraphActionHandler("wilson", readtwo_handler)

In modmain.lua

The good news is we don't need to make a custom stategraph we just recycle the existing book ones.

This utilizes the booktwo and readertwo components which are just copies of the originals and given to the appropriate prefabs.

 

Cheers

Iron_Hunter

Edited by IronHunter
typo
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...