So, i'm trying to create a better paint tool than the one the base game gives you. I've been fairly successful so far and have figured out how to create drawables to highlight the area you're aiming at, but i've run into a problem - the animation script and regular script for the item are separate and I don't know how to pass information from one to the other, such as what color or brush sizes are currently selected. This is hamstringing my effort to provide the player with more visual feedback from the paint tool, to say the least. Right now I just have a static 3x3 area that looks like this, even when shift is held to paint single blocks: I'd like the highlight to visually expand/shrink and be colorized depending on what the player is doing, but I can't do that without being able to transmit data from the main script to the animation script, and since animationScripts doesn't seem to have access to the activeItem lua functions, this is a problem. The pertinent files are as follows: { "itemName" : "isn_paint_tool", "shortdescription" : "Portable Paint Tool", "description" : "A high-end paint tool for artists and construction workers.", "rarity" : "Legendary", "price" : 500, "level" : 1, "maxStack" : 1, "category" : "Tool", "twoHanded" : true, "inventoryIcon" : "isn_paint_tool_item.png", "animation" : "/items/isn_paint_tool/isn_paint_tool.animation", "animationParts" : { "middle" : "isn_paint_tool.png" }, "animationCustom" : { "sounds" : { "paint" : [ "/sfx/tools/paint_splash.ogg" ], "switchcolor" : [ "/sfx/tools/flashlight_toggle.ogg" ], "switchmode" : [ "/sfx/tech/tech_multijump.ogg" ] } }, "scripts" : ["/items/isn_paint_tool/isn_paint_tool.lua"], "scriptDelta" : 1, "animationScripts" : ["/items/isn_paint_tool/isn_paint_tool_anim.lua"], "animationDelta" : 1 } require "/scripts/util.lua" require "/scripts/vec2.lua" function init() self.paintradius = 2 self.paintcolor = 0 self.paintmode = 0 self.paintbg = false self.paintfg = true self.lastfire = "none" self.blocklock = nil self.colorCache = {} self.fireOffset = config.getParameter("fireOffset") updateAim() animator.setParticleEmitterBurstCount("isn_pnttoo_msg_both", 1) animator.setParticleEmitterBurstCount("isn_pnttoo_msg_fg", 1) animator.setParticleEmitterBurstCount("isn_pnttoo_msg_bg", 1) animator.setParticleEmitterBurstCount("isn_pnttoo_msg_bl_on", 1) animator.setParticleEmitterBurstCount("isn_pnttoo_msg_bl_off", 1) animator.setParticleEmitterBurstCount("isn_pnttoo_msg_bl_error", 1) end function update(dt, fireMode, shiftHeld) updateAim() local aimpos = activeItem.ownerAimPosition() local posX = aimpos[1] local posY = aimpos[2] if shiftHeld == true then self.paintradius = 0 else self.paintradius = 2 end if fireMode == "primary" then for x = 0 - self.paintradius, self.paintradius do for y = 0 - self.paintradius, self.paintradius do if self.paintfg == true then if self.blocklock ~= nil then if self.blocklock == world.material({posX + x, posY + y}, "foreground") then --sb.logInfo(tostring("BL: " .. self.blocklock)) --sb.logInfo(tostring("FG: " .. world.material({posX + x, posY + y}, "foreground"))) world.setMaterialColor({posX + x, posY + y}, "foreground", self.paintcolor) end else world.setMaterialColor({posX + x, posY + y}, "foreground", self.paintcolor) end end if self.paintbg == true then if self.blocklock ~= nil then if self.blocklock == world.material({posX + x, posY + y}, "background") then --sb.logInfo(tostring("BL: " .. self.blocklock)) --sb.logInfo(tostring("BG: " .. world.material({posX + x, posY + y}, "background"))) world.setMaterialColor({posX + x, posY + y}, "background", self.paintcolor) end else world.setMaterialColor({posX + x, posY + y}, "background", self.paintcolor) end end end end animator.playSound("paint") elseif fireMode == "alt" and self.lastfire ~= "alt" then if shiftHeld == true then if mcontroller.crouching() then if self.blocklock ~= nil then self.blocklock = nil animator.playSound("switchmode") animator.burstParticleEmitter("isn_pnttoo_msg_bl_off") else local bgtile = world.material({posX, posY}, "background") local fgtile = world.material({posX, posY}, "foreground") if fgtile ~= false and fgtile ~= nil then self.blocklock = fgtile animator.playSound("switchmode") animator.burstParticleEmitter("isn_pnttoo_msg_bl_on") elseif bgtile ~= false and bgtile ~= nil then self.blocklock = bgtile animator.playSound("switchmode") animator.burstParticleEmitter("isn_pnttoo_msg_bl_on") else animator.playSound("error") animator.burstParticleEmitter("isn_pnttoo_msg_bl_error") end end else animator.playSound("switchmode") self.paintmode = self.paintmode + 1 if self.paintmode > 2 then self.paintmode = 0 end if self.paintmode < 0 then self.paintmode = 2 end if self.paintmode == 0 then self.paintbg = false self.paintfg = true animator.burstParticleEmitter("isn_pnttoo_msg_fg") elseif self.paintmode == 1 then self.paintbg = true self.paintfg = false animator.burstParticleEmitter("isn_pnttoo_msg_bg") else self.paintbg = true self.paintfg = true animator.burstParticleEmitter("isn_pnttoo_msg_both") end end else animator.playSound("switchcolor") if mcontroller.crouching() then self.paintcolor = self.paintcolor - 1 else self.paintcolor = self.paintcolor + 1 end if self.paintcolor > 8 then self.paintcolor = 0 end if self.paintcolor < 0 then self.paintcolor = 8 end animator.setAnimationState("color", tostring(self.paintcolor)) end end self.lastfire = fireMode end function uninit() end function updateAim() self.aimAngle, self.aimDirection = activeItem.aimAngleAndDirection(0.0, activeItem.ownerAimPosition()) self.aimAngle = self.aimAngle activeItem.setArmAngle(self.aimAngle) activeItem.setFacingDirection(self.aimDirection) end require "/scripts/util.lua" require "/scripts/vec2.lua" function init() self.colorCache = {} end function update(dt, fireMode, shiftHeld) localAnimator.clearDrawables() local aimpos = activeItemAnimation.ownerAimPosition() local highlight_offset = -0.5 local image_to_use = "/items/isn_paint_tool/isn_paint_tool_highlight_3.png" local posX = math.ceil(aimpos[1]) local posY = math.ceil(aimpos[2]) if getCurrentRadius() == 0 then image_to_use = "/items/isn_paint_tool/isn_paint_tool_highlight_1.png" end posX = posX + highlight_offset posY = posY + highlight_offset localAnimator.addDrawable({ image = image_to_use, fullbright = true, position = {posX, posY}, centered = true, color = {255, 255, 255, 100} }, "overlay") end function uninit() end Any help is appreciated!
I haven't looked exactly what the active item animation scripts have access to, but try the messaging system.
If message.setHandler exists in the animation script -> set up one or two way communication between the two scripts. If world.sendEntityMessage exists in the animation script -> set up one way communication from the animation script to the item script to ask for the data. If status exists in the animation script -> use status.statusProperty to obtain the data and update it in the item script with status.setStatusProperty. If you don't know how to set up message handlers, I hope this documentation helps: https://github.com/Silverfeelin/Starbound-MessageHandling-Demo/wiki
Do activeItems have an entity id I can use for the first argument in world.sendEntityMessage? I didn't think items counted as entities? EDIT: Oh hey, I seem to have stumbled on the solution! Turns out there's dedicated functions for this. On the transmitting end: activeItem.setScriptedAnimationParameter(String parameter, Json value) And on the recieving end: animationConfig.animationParameter(String key)