A few weeks ago I started a personal project of updating an outdated mod which adds 8 new techs to Starbound. The techs add "Stands" from the anime JoJo's Bizarre Adventure into the game, or at least they're supposed to. After asking for help in another thread I made, I have already gotten some help with most of the outdated files. Now I have the problem of not knowing how to code in lua and am therefore unable to update it. This is the lua code that overall sets the standard of how all the other Stands work and what they can do. I know it is outdated because I looked through the "Official Starbound Wiki" and saw that this code here contains functions that are not in the list of functions that work in the latest version. Code: function init() data.active = false data.fireTimer = 0 tech.setVisible(false) data.punched = false data.started = false data.ended = false end function uninit() if data.active then data.active = false tech.setVisible(false) tech.setToolUsageSuppressed(false) tech.setParentFacingDirection(nil) end end function input(args) if args.moves["special"] == 1 then if data.active then return "standDeactivate" else return "standActivate" end elseif args.moves["primaryFire"] then return "standFire" end return nil end function update(args) local energyCostPerSecond = tech.parameter("energyCostPerSecond") local standFireCycle = tech.parameter("standFireCycle") local standStartCycle = tech.parameter("standStartInterval") local standAttackCycle = tech.parameter("standAttackInterval") local standProjectile = tech.parameter("standProjectile") local attackSound = tech.parameter("attackSound") local summonSound = tech.parameter("summonSound") local standProjectileConfig = tech.parameter("standProjectileConfig") local standAimLimit = tech.parameter("standAimLimit") * math.pi / 180 if not data.active and args.actions["standActivate"] then tech.setVisible(true) tech.playImmediateSound(summonSound) tech.setParentAppearance("normal") tech.setAnimationState("moving","summon") tech.setToolUsageSuppressed(true) data.active = true elseif data.active and (args.actions["standDeactivate"] or energyCostPerSecond * args.dt > args.availableEnergy) then tech.setVisible(false) tech.setParentAppearance("normal") tech.setToolUsageSuppressed(false) tech.setParentOffset({0, 0}) data.active = false end tech.setParentFacingDirection(nil) if data.active then local diff = world.distance(args.aimPosition, tech.position()) local aimAngle = math.atan2(diff[2], diff[1]) local flip = aimAngle > math.pi / 2 or aimAngle < -math.pi / 2 if flip then tech.setFlipped(true) tech.setParentFacingDirection(-1) if aimAngle > 0 then aimAngle = math.max(aimAngle, math.pi - standAimLimit) else aimAngle = math.min(aimAngle, -math.pi + standAimLimit) end else tech.setFlipped(false) tech.setParentFacingDirection(1) if aimAngle > 0 then aimAngle = math.min(aimAngle, standAimLimit) else aimAngle = math.max(aimAngle, -standAimLimit) end end if data.started==false then if not tech.onGround() then if tech.velocity()[2] > 0 then tech.setAnimationState("moving", "moving") else tech.setAnimationState("moving", "moving") end elseif tech.walking() or tech.running() then if flip and tech.direction() == 1 or not flip and tech.direction() == -1 then tech.setAnimationState("moving", "moving") else tech.setAnimationState("moving", "moving") end else tech.setAnimationState("moving", "idle") end end if args.actions["standFire"] or data.started==true then if data.fireTimer <=standStartCycle and data.fireTimer>=0 then if data.started == false then tech.setAnimationState("moving","start") tech.playImmediateSound(attackSound) end data.started=true elseif data.fireTimer>standStartCycle and data.fireTimer<=standAttackCycle and data.started==true then if data.punched==false then tech.setAnimationState("moving","attack") world.spawnProjectile(standProjectile, tech.position(), tech.parentEntityId(), {math.cos(aimAngle), math.sin(aimAngle)}, false, standProjectileConfig) end data.punched=true elseif data.fireTimer>standAttackCycle and data.fireTimer<=standFireCycle and data.punched==true then if data.ended==false then tech.setAnimationState("moving","end") end data.ended=true elseif data.fireTimer>standFireCycle and data.ended==true then data.started=false data.punched=false data.ended=false data.fireTimer=0 end data.fireTimer = data.fireTimer + args.dt end return energyCostPerSecond * args.dt end return 0 end I don't know much about many coding/programming languages but I can mostly tell what a program can do when I look at it. Now I don't want people to recode the whole thing for me because that way I don't learn anything. I just want to know the basics of how programming techs in Starbound works so I can do it myself.
Basically, scripted things in Starbound are either "client-side" or "server-side" (for example, techs are clientside, objects are serverside), and scripts get access to tables depending on their context (for example, "tech.setVisible()" is a function in the tech table; the tech table is only available in tech scripts). You can find documentation about (mostly) all the available tables and their functions in your game's folder, /Starbound/doc/lua. From a quick read of that code, it seems most of the "outdated" functions have just been moved to another table; for example "tech.running()" is now "mcontroller.running()"; "tech.position()" would be "mcontroller.position()", and "tech.parentEntityId()" would be "entity.id()". If you look around in the docs, you should more or less easily find the functions you want. I'd recommend loading the whole folder (referenced as a "project" i think?) in your text editor, and fuzzy-search in it (ctrl+shift+F generally) for things. (If you want some examples of good text editors for coding, there's a list there: http://starbounder.org/Modding:Text_Editors You'll probably also need to change "special" to "special1" soon since that will change in 1.3 If you snoop into other up-to-date tech scripts, you should probably find working examples doing similar things!
Thank you for your reply. This will help me a lot and I will hopefully make this mod work again. Though I technically still need to wait to get a reply from the original uploader who made this mod because otherwise I can't upload my rework here.
I have looked online for a lot of the changes made to the lua in starbound and have already changed most of the lua files. But there is still one file that needs updating but I couldn't figure out what to change in it. The lua code is supposed to act like a blink dash tech. Now the problem I have with that is that I can't seem to find any version of a blink dash lua code for me to use as reference. Code: function checkCollision(position) local collisionBounds = tech.collisionBounds() collisionBounds[1] = collisionBounds[1] - mcontroller.position()[1] + position[1] collisionBounds[2] = collisionBounds[2] - mcontroller.position()[2] + position[2] collisionBounds[3] = collisionBounds[3] - mcontroller.position()[1] + position[1] collisionBounds[4] = collisionBounds[4] - mcontroller.position()[2] + position[2] return not world.rectCollision(collisionBounds) end function blinkAdjust(position, doPathCheck, doCollisionCheck, doLiquidCheck, doStandCheck) local blinkCollisionCheckDiameter = tech.parameter("blinkCollisionCheckDiameter") local blinkVerticalGroundCheck = tech.parameter("blinkVerticalGroundCheck") local blinkFootOffset = tech.parameter("blinkFootOffset") if doPathCheck then local collisionBlocks = world.collisionBlocksAlongLine(mcontroller.position(), position, true, 1) if #collisionBlocks ~= 0 then local diff = world.distance(position, mcontroller.position()) diff[1] = diff[1] / math.abs(diff[1]) diff[2] = diff[2] / math.abs(diff[2]) position = {collisionBlocks[1][1] - diff[1], collisionBlocks[1][2] - diff[2]} end end if doCollisionCheck and not checkCollision(position) then local spaceFound = false for i = 1, blinkCollisionCheckDiameter * 2 do if checkCollision({position[1] + i / 2, position[2] + i / 2}) then position = {position[1] + i / 2, position[2] + i / 2} spaceFound = true break end if checkCollision({position[1] - i / 2, position[2] + i / 2}) then position = {position[1] - i / 2, position[2] + i / 2} spaceFound = true break end if checkCollision({position[1] + i / 2, position[2] - i / 2}) then position = {position[1] + i / 2, position[2] - i / 2} spaceFound = true break end if checkCollision({position[1] - i / 2, position[2] - i / 2}) then position = {position[1] - i / 2, position[2] - i / 2} spaceFound = true break end end if not spaceFound then return nil end end if doStandCheck then local groundFound = false for i = 1, blinkVerticalGroundCheck * 2 do local checkPosition = {position[1], position[2] - i / 2} if world.pointCollision(checkPosition, false) then groundFound = true position = {checkPosition[1], checkPosition[2] + 0.5 - blinkFootOffset} break end end if not groundFound then return nil end end if doLiquidCheck and (world.liquidAt(position) or world.liquidAt({position[1], position[2] + blinkFootOffset})) then return nil end if doCollisionCheck and not checkCollision(position) then return nil end return position end function findRandomBlinkLocation(doCollisionCheck, doLiquidCheck, doStandCheck) local randomBlinkTries = tech.parameter("randomBlinkTries") local randomBlinkDiameter = tech.parameter("randomBlinkDiameter") for i=1,randomBlinkTries do local position = mcontroller.position() position[1] = position[1] + (math.random() * 2 - 1) * randomBlinkDiameter position[2] = position[2] + (math.random() * 2 - 1) * randomBlinkDiameter local position = blinkAdjust(position, false, doCollisionCheck, doLiquidCheck, doStandCheck) if position then return position end end return nil end function init() data.mode = "none" data.timer = 0 data.targetPosition = nil data.active = false data.fireTimer = 0 data.started = false data.warped = false data.ended = false tech.setVisible(false) tech.setToolUsageSuppressed(true) end function uninit() tech.setParentState() if data.active then data.active = false tech.setVisible(false) tech.setToolUsageSuppressed(false) mcontroller.controlFace(nil) end end function input(args) if args.moves["special1"] == 1 then if data.active then return "standDeactivate" else return "standActivate" end elseif args.moves["primaryFire"] then return "blink" end return nil end function update(args) local energyUsage = tech.parameter("energyUsage") local energyCostPerSecond = tech.parameter("energyCostPerSecond") local blinkMode = tech.parameter("blinkMode") local blinkOutTime = tech.parameter("blinkOutTime") local blinkInTime = tech.parameter("blinkInTime") local startSound = tech.parameter("startSound") local endSound = tech.parameter("endSound") local summonSound = tech.parameter("summonSound") local standAimLimit = tech.parameter("standAimLimit") * math.pi / 180 local standFireCycle = tech.parameter("standFireCycle") local standStartCycle = tech.parameter("standStartInterval") local standAttackCycle = tech.parameter("standAttackInterval") if not data.active and args.actions["standActivate"] then tech.setVisible(true) tech.playSound(summonSound) tech.setParentState() tech.setToolUsageSuppressed(true) data.active = true elseif data.active and (args.actions["standDeactivate"] or energyCostPerSecond * args.dt > status.resource("energy")) then tech.setVisible(false) tech.setParentState() tech.setToolUsageSuppressed(false) tech.setParentOffset({0, 0}) data.active = false end mcontroller.controlFace(nil) if data.active then local diff = world.distance(tech.aimPosition, mcontroller.position()) local aimAngle = math.atan2(diff[2], diff[1]) local flip = aimAngle > math.pi / 2 or aimAngle < -math.pi / 2 if flip then animator.setFlipped(true) mcontroller.controlFace(-1) if aimAngle > 0 then aimAngle = math.max(aimAngle, math.pi - standAimLimit) else aimAngle = math.min(aimAngle, -math.pi + standAimLimit) end else animator.setFlipped(false) mcontroller.controlFace(1) if aimAngle > 0 then aimAngle = math.min(aimAngle, standAimLimit) else aimAngle = math.max(aimAngle, -standAimLimit) end end if data.started==false then if not mcontroller.onGround() then if mcontroller.velocity()[2] > 0 then animator.setAnimationState("moving", "moving") else animator.setAnimationState("moving", "moving") end elseif mcontroller.walking() or mcontroller.running() then if flip and mcontroller.movingDirection() == 1 or not flip and mcontroller.movingDirection() == -1 then animator.setAnimationState("moving", "moving") else animator.setAnimationState("moving", "moving") end else animator.setAnimationState("moving", "idle") end end if (args.actions["blink"] and data.mode == "none" and status.resource("energy") > energyUsage and data.active==true) or data.started==true then local blinkPosition = nil if blinkMode == "random" then local randomBlinkAvoidCollision = tech.parameter("randomBlinkAvoidCollision") local randomBlinkAvoidMidair = tech.parameter("randomBlinkAvoidMidair") local randomBlinkAvoidLiquid = tech.parameter("randomBlinkAvoidLiquid") blinkPosition = findRandomBlinkLocation(randomBlinkAvoidCollision, randomBlinkAvoidMidair, randomBlinkAvoidLiquid) or findRandomBlinkLocation(randomBlinkAvoidCollision, randomBlinkAvoidMidair, false) or findRandomBlinkLocation(randomBlinkAvoidCollision, false, false) elseif blinkMode == "cursor" then if data.fireTimer <=standStartCycle and data.fireTimer>=0 then if data.started==false then tech.setParentState() animator.setAnimationState("blinking", "out") animator.setAnimationState("moving","start") tech.playSound(startSound) end data.started=true elseif data.started==true and data.warped==false and data.fireTimer>standStartCycle and data.fireTimer<standAttackCycle then blinkPosition = blinkAdjust(tech.aimPosition, true, true, false, false) data.warped = true elseif data.warped ==true and data.started==true and data.fireTimer >=standAttackCycle and data.fireTimer<standFireCycle then if data.ended==false then tech.setParentState() animator.setAnimationState("blinking", "in") animator.setAnimationState("moving","end") tech.playSound(endSound) end data.ended=true elseif data.ended==true and data.warped==true and data.fireTimer >=standFireCycle then data.started=false data.warped=false data.ended=false data.fireTimer=0 end data.fireTimer = data.fireTimer + args.dt elseif blinkMode == "cursorPenetrate" then blinkPosition = blinkAdjust(tech.aimPosition, false, true, false, false) end if blinkPosition then data.targetPosition = blinkPosition data.mode = "start" else -- Make some kind of error noise end end if data.mode == "start" then tech.setVelocity({0, 0}) data.mode = "out" data.timer = 0 return energyUsage elseif data.mode == "out" then tech.setVelocity({0, 0}) data.timer = data.timer + args.dt if data.timer > blinkOutTime then tech.setPosition(data.targetPosition) data.mode = "in" data.timer = 0 end return 0 elseif data.mode == "in" then tech.setVelocity({0, 0}) data.timer = data.timer + args.dt if data.timer > blinkInTime then data.mode = "none" end return 0 end end end I have already changed most of the things I found by replacing them in notepad++ so this isn't really the original code.
I hope that you are going to keep working on it because Im not good at modding but I really want to use this old Jojo mod!