AngelLucifer Posted January 23, 2023 Share Posted January 23, 2023 Hey! I've been making mods for a while now and they're mostly simple. But I have a problem that I don't know how to deal with. I want to make an artist whose drawings come to life. For this I want to use the Umbra codex system, but I have no idea how to do it. I will be glad if you help me, sorry in advance for my English. Link to comment https://forums.kleientertainment.com/forums/topic/145732-help-pls/ Share on other sites More sharing options...
Merkyrrie Posted January 26, 2023 Share Posted January 26, 2023 At its core it seems to be comprised of these three components attached to the "spellbook" item; Spellbook, AOETargetting, and AOESpell Both the Spellbook and AOETargetting component should be added before SetPristine It comes down to mostly copy/pasting from waxwelljournal.lua, it doesn't take too much to get a very simple "spell" working This is just me tinkering and having it spawn a rabbit with no fuel needed local prefabs = { "rabbit" } -- The function the codex uses to tell if a location is valid for the aoe spell local function ReticuleTargetAllowWaterFn() local player = ThePlayer local ground = TheWorld.Map local pos = Vector3() --Cast range is 8, leave room for error --4 is the aoe range for r = 7, 0, -.25 do pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0) if ground:IsPassableAtPoint(pos.x, 0, pos.z, true) and not ground:IsGroundTargetBlocked(pos) then return pos end end return pos end -- Just a basic "spell" that simply spawns a rabbit at targetted position local function SummonRabbitFn(inst, doer, pos) -- This is where you would check for fuel local spell = SpawnPrefab("rabbit") -- Most of maxwell's spells spawn a prefab that's built from a prefab file with multiple prefabs like preparedfoods so they're harder to find if you go looking for them as an example -- spell.caster = doer -- gives the prefab a variable with the player attached, not needed here -- spell.item = inst -- gives the prefab a variable with this item attached, not needed here -- For setting the spell's position local platform = TheWorld.Map:GetPlatformAtPoint(pos.x, pos.z) if platform ~= nil then spell.entity:SetParent(platform.entity) spell.Transform:SetPosition(platform.entity:WorldToLocalSpace(pos:Get())) else spell.Transform:SetPosition(pos:Get()) end -- This is where you would make the spell use fuel and any other effects on the item and player -- Can also have a check that returns false if the spell can not be done return true end -- AOE Targetting function for giving the player control over it local function StartAOETargeting(inst) local playercontroller = ThePlayer.components.playercontroller if playercontroller ~= nil then playercontroller:StartAOETargetingUsing(inst) end end local ICON_SCALE = .6 local ICON_RADIUS = 50 local SPELLBOOK_RADIUS = 100 local SPELLBOOK_FOCUS_RADIUS = SPELLBOOK_RADIUS + 2 local SPELLS = { { -- Sets the data for each individual spell in the table label = "Summon Rabbit", -- Name of the spell, the codex assigns it in STRINGS but doing it here works fine onselect = function(inst) inst.components.spellbook:SetSpellName("Summon Rabbit") -- Same as label inst.components.aoetargeting:SetDeployRadius(0) inst.components.aoetargeting:SetShouldRepeatCastFn(nil) inst.components.aoetargeting.reticule.reticuleprefab = "reticuleaoe_1d2_12" inst.components.aoetargeting.reticule.pingprefab = "reticuleaoeping_1d2_12" if TheWorld.ismastersim then inst.components.aoetargeting:SetTargetFX("reticuleaoesummontarget_1d2") inst.components.aoespell:SetSpellFn(SummonRabbitFn) -- The actual spell function inst.components.spellbook:SetSpellFn(nil) -- The spell function if it wasn't using AOE Targetting end end, execute = StartAOETargeting, -- Starts the new AOE Targetting system with the function above atlas = "images/spell_icons.xml", -- Just taken from the pillars spell, I tried my own image but it didn't work normal = "shadow_pillars.tex", widget_scale = ICON_SCALE, -- Size of the widget, set earlier hit_radius = ICON_RADIUS, -- I couldn't 100% tell what this did, but I'm guessing its how wide the "hitbox" for pressing it is }, } -- In the prefab's fn, above SetPristine inst:AddComponent("spellbook") -- Tag required for the user inst.components.spellbook:SetRequiredTag("charactertag") inst.components.spellbook:SetRadius(SPELLBOOK_RADIUS) inst.components.spellbook:SetFocusRadius(SPELLBOOK_FOCUS_RADIUS) inst.components.spellbook:SetItems(SPELLS) -- Used for changing the image of the codex to open or closed if needed --inst.components.spellbook:SetOnOpenFn(OnOpenSpellBook) --inst.components.spellbook:SetOnCloseFn(OnCloseSpellBook) inst.components.spellbook.opensound = "dontstarve/common/together/book_maxwell/use" inst.components.spellbook.closesound = "dontstarve/common/together/book_maxwell/close" inst:AddComponent("aoetargeting") inst.components.aoetargeting:SetAllowWater(true) -- Water is valid spot for the spell inst.components.aoetargeting.reticule.targetfn = ReticuleTargetAllowWaterFn -- Sets the targetting function inst.components.aoetargeting.reticule.validcolour = { 1, .75, 0, 1 } -- Color for when location is valid inst.components.aoetargeting.reticule.invalidcolour = { .5, 0, 0, 1 } -- Color for when its not inst.components.aoetargeting.reticule.ease = true -- Not entirely sure what this does inst.components.aoetargeting.reticule.mouseenabled = true -- Can use mouse to target inst.components.aoetargeting.reticule.twinstickmode = 1 -- For controller inst.components.aoetargeting.reticule.twinstickrange = 8 -- For Controller -- Below SetPristine with the other AddComponents inst:AddComponent("aoespell") Most of the stuff I commented was probably self-explanatory, but just in case since its been removed from its original context Hopefully this helps get you started with using the spellbook and aoetargetting component, you can look through the correlated files yourself to get a better idea of what else can be done with it but this all the code that appears to be needed to make it function. Its also possible to do a spell without the aoetargetting component, waxwelljournal.lua has an example of that with the commented out tophat spell Link to comment https://forums.kleientertainment.com/forums/topic/145732-help-pls/#findComment-1618926 Share on other sites More sharing options...
LeoT444 Posted March 31, 2025 Share Posted March 31, 2025 On 1/26/2023 at 5:35 PM, Merkyrrie said: At its core it seems to be comprised of these three components attached to the "spellbook" item; Spellbook, AOETargetting, and AOESpell Both the Spellbook and AOETargetting component should be added before SetPristine It comes down to mostly copy/pasting from waxwelljournal.lua, it doesn't take too much to get a very simple "spell" working This is just me tinkering and having it spawn a rabbit with no fuel needed local prefabs = { "rabbit" } -- The function the codex uses to tell if a location is valid for the aoe spell local function ReticuleTargetAllowWaterFn() local player = ThePlayer local ground = TheWorld.Map local pos = Vector3() --Cast range is 8, leave room for error --4 is the aoe range for r = 7, 0, -.25 do pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0) if ground:IsPassableAtPoint(pos.x, 0, pos.z, true) and not ground:IsGroundTargetBlocked(pos) then return pos end end return pos end -- Just a basic "spell" that simply spawns a rabbit at targetted position local function SummonRabbitFn(inst, doer, pos) -- This is where you would check for fuel local spell = SpawnPrefab("rabbit") -- Most of maxwell's spells spawn a prefab that's built from a prefab file with multiple prefabs like preparedfoods so they're harder to find if you go looking for them as an example -- spell.caster = doer -- gives the prefab a variable with the player attached, not needed here -- spell.item = inst -- gives the prefab a variable with this item attached, not needed here -- For setting the spell's position local platform = TheWorld.Map:GetPlatformAtPoint(pos.x, pos.z) if platform ~= nil then spell.entity:SetParent(platform.entity) spell.Transform:SetPosition(platform.entity:WorldToLocalSpace(pos:Get())) else spell.Transform:SetPosition(pos:Get()) end -- This is where you would make the spell use fuel and any other effects on the item and player -- Can also have a check that returns false if the spell can not be done return true end -- AOE Targetting function for giving the player control over it local function StartAOETargeting(inst) local playercontroller = ThePlayer.components.playercontroller if playercontroller ~= nil then playercontroller:StartAOETargetingUsing(inst) end end local ICON_SCALE = .6 local ICON_RADIUS = 50 local SPELLBOOK_RADIUS = 100 local SPELLBOOK_FOCUS_RADIUS = SPELLBOOK_RADIUS + 2 local SPELLS = { { -- Sets the data for each individual spell in the table label = "Summon Rabbit", -- Name of the spell, the codex assigns it in STRINGS but doing it here works fine onselect = function(inst) inst.components.spellbook:SetSpellName("Summon Rabbit") -- Same as label inst.components.aoetargeting:SetDeployRadius(0) inst.components.aoetargeting:SetShouldRepeatCastFn(nil) inst.components.aoetargeting.reticule.reticuleprefab = "reticuleaoe_1d2_12" inst.components.aoetargeting.reticule.pingprefab = "reticuleaoeping_1d2_12" if TheWorld.ismastersim then inst.components.aoetargeting:SetTargetFX("reticuleaoesummontarget_1d2") inst.components.aoespell:SetSpellFn(SummonRabbitFn) -- The actual spell function inst.components.spellbook:SetSpellFn(nil) -- The spell function if it wasn't using AOE Targetting end end, execute = StartAOETargeting, -- Starts the new AOE Targetting system with the function above atlas = "images/spell_icons.xml", -- Just taken from the pillars spell, I tried my own image but it didn't work normal = "shadow_pillars.tex", widget_scale = ICON_SCALE, -- Size of the widget, set earlier hit_radius = ICON_RADIUS, -- I couldn't 100% tell what this did, but I'm guessing its how wide the "hitbox" for pressing it is }, } -- In the prefab's fn, above SetPristine inst:AddComponent("spellbook") -- Tag required for the user inst.components.spellbook:SetRequiredTag("charactertag") inst.components.spellbook:SetRadius(SPELLBOOK_RADIUS) inst.components.spellbook:SetFocusRadius(SPELLBOOK_FOCUS_RADIUS) inst.components.spellbook:SetItems(SPELLS) -- Used for changing the image of the codex to open or closed if needed --inst.components.spellbook:SetOnOpenFn(OnOpenSpellBook) --inst.components.spellbook:SetOnCloseFn(OnCloseSpellBook) inst.components.spellbook.opensound = "dontstarve/common/together/book_maxwell/use" inst.components.spellbook.closesound = "dontstarve/common/together/book_maxwell/close" inst:AddComponent("aoetargeting") inst.components.aoetargeting:SetAllowWater(true) -- Water is valid spot for the spell inst.components.aoetargeting.reticule.targetfn = ReticuleTargetAllowWaterFn -- Sets the targetting function inst.components.aoetargeting.reticule.validcolour = { 1, .75, 0, 1 } -- Color for when location is valid inst.components.aoetargeting.reticule.invalidcolour = { .5, 0, 0, 1 } -- Color for when its not inst.components.aoetargeting.reticule.ease = true -- Not entirely sure what this does inst.components.aoetargeting.reticule.mouseenabled = true -- Can use mouse to target inst.components.aoetargeting.reticule.twinstickmode = 1 -- For controller inst.components.aoetargeting.reticule.twinstickrange = 8 -- For Controller -- Below SetPristine with the other AddComponents inst:AddComponent("aoespell") Most of the stuff I commented was probably self-explanatory, but just in case since its been removed from its original context Hopefully this helps get you started with using the spellbook and aoetargetting component, you can look through the correlated files yourself to get a better idea of what else can be done with it but this all the code that appears to be needed to make it function. Its also possible to do a spell without the aoetargetting component, waxwelljournal.lua has an example of that with the commented out tophat spell God bless you! I was trying to do exactly that! Link to comment https://forums.kleientertainment.com/forums/topic/145732-help-pls/#findComment-1810155 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