Modding Help [actually mostly solved] Needing more assistance on my armor...

Discussion in 'Starbound Modding' started by MetaFace, Feb 15, 2017.

  1. MetaFace

    MetaFace Guest

    I just found that last night, was going to look up how to use these functions today. Thanks for the help. I'll try it tomorrow since I work all day.
     
  2. MetaFace

    MetaFace Guest

    I tried that set animation function but I couldn't figure out what parameters were supposed to be input into it. So now I'm a little lost again, anyone knows how this works?
     
  3. MetaFace

    MetaFace Guest

    Sort of a bump here to make sure my thread doesn't fall into the void.

    So I want to remove my code from the player_primary in order to help with performance (so its not constantly checking these things).

    Code:
    function update(dt)
     
    if status.stat("encumberance") > 0 and not status.resourcePositive("energyRegenBlock") then
        if status.resource("energy") == 0 then
          status.setResourceLocked("energy", true)
        elseif not status.resourceLocked("energy") then
          if mcontroller.walking() then
            status.modifyResourcePercentage("energy", -status.stat("encumberance") / 16 * dt)
            mcontroller.controlModifiers({
            groundMovementModifier = 1.5,
            speedModifier = 1.5
          })
          end
          if mcontroller.jumping() then
            status.modifyResourcePercentage("energy", -status.stat("encumberance") / 4 * dt)
          end
        end
      end
    
    I take this and save it as "My_Mod/scripts/myarmor.lua" and in my armor I put ""scripts" : ["/scripts/myarmor.lua"]" in my armor files. Would that technically work?

    Because since making this code, I have definitely noticed a decrease in performance even with the armor off, and I'm pretty sure its because the game is always checking for these conditions and that isn't good for the frame rate.
     
  4. Inf_Wolf14

    Inf_Wolf14 Parsec Taste Tester


    bool animator.setAnimationState(String stateType, String State, bool startNew = false)
    Sets an animation state. If startNew is true, restart the animation loop if it's already active. Returns whether the state was set.




    As for your performance issue, you can use it as a standalone script as long as none of your references are to functions/private variables within player_primary.lua (which it doesn't seem like an issue).
    Also, in general, using standalone scripts opposed to script edits is always better for compatibility reasons.

    (Other than those, the only other way to possibly improve performance is to check and improve the code for efficiency... Not something I can help with, i'm afraid.)
     
  5. MetaFace

    MetaFace Guest

    Ok, so in theory, my script should work as assuming that im not using local variables not present, which is easy enough.

    As for setAnimationState(), what/where are the stateType and States available? I've messed a bit with it and didn't know what valid options were available for a player. More specifically for walking and running. Thanks again for a reply.
     
  6. Inf_Wolf14

    Inf_Wolf14 Parsec Taste Tester

    I'd have to look into the states myself as I can't recall them either.

    In general, if you have Notepad++ or another text editor equivalent, use a "Find in Files" operation to check for instances of the function being used in the vanilla assets.
    (Imitation is the greatest form of flattery... It's also the best way to learn and understand scripting functionality, lol.)
     
  7. bk3k

    bk3k Oxygen Tank

    That function is for setting parts to part states. What is available is defined by you in your animation file. You should find the exact strings for the part, and for the state you are setting.

    Look at the doors for an easy to understand example.
     
    MetaFace likes this.
  8. MetaFace

    MetaFace Guest

    I'll do that, just give me awhile, getting a little excited because I'm about to get a new $1500 computer, so I've been a little off track. Also watching Adventure Time, so freaking off track...
     
  9. MetaFace

    MetaFace Guest

    This is really nothing more than a bump to make sure this doesn't fall into the abyss, but I do also have a relevant question... where would I find the file that defines the player and the parts/part states?
     
  10. bk3k

    bk3k Oxygen Tank

    I forgot with my answer that we where talking about the player specifically. It is true for the function that it addresses states for parts defined elsewhere. But the player...

    There where some .animation files under /player/ but I don't think those cover all bases. This may be some hard coded stuff, but I'd guess some of the things you see in the armor's files are parts too. For example

    "body"
    "backSleeve"
    "frontSleeve"

    Probably would need to do other guesswork to find them.
    "head"
    "pants"
    "back"
    etc

    I think it is safe to assume some "states" that exist from the frames files found in /items/armor/
    So I think you may have to piece this together, plus some guesswork, trial and error. If you find anything interesting, let us know.

    I'm pretty sure you'll get errors when trying to set non-existent parts. You could put together a dummy script that doesn't do much but tries lots of guesses(ipairs on a big list), and when you guess wrong
    1. just delete that guess from the table.
    2. /reload
    3. refresh log(I manually set F5 as a hotkey in notepad++)
    4. repeat

    That should at least speed up the process. And keep in mind for your guesses, try
    "head"
    and
    "Head"
    because those are two different namespaces.

    For a "state" to set, I'm going to guess "idle" is a state they all have. I believe you'd get a different error for not having the state.
    But the errors would probably look like
    Code:
    'no such entry 'head' found in map():part'
    etc
    I forget the exact error, but something along those lines as best I recall. Take that recollection with a grain of salt

    Anyhow the what is left of the list you haven't deleted will be your parts. That's probably a much faster approach than plugging in guesses into your legitimate script. Something like

    Code:
    guesses = {
      "head",
      "Head",
      "body",
      "Body",
      "backsleeve",
      "backSleeve",
      "BackSleeve",
      "Backsleeve"
    --etc
    }
    sb.logInfo("\n" .. "This specific string will be easy to search for" .. "\n")
      --obviously use the text editor's find feature, this can be useful if you have large logs.
    local result = false
    for i, part in ipairs(guesses) do
      result = animator.setAnimationState(part, "idle", false)
      sb.loginfo("\nanimator.setAnimationState returned " .. tostring(result) .. "\nfor part" .. part)
    end
    
    edit:
    Now possibly someone knows a better source to find the player and armor parts? That would obviously be better than brute force guesswork.

    A few more guesses
    "helmet"
    "mask"
     
    MetaFace likes this.
  11. MetaFace

    MetaFace Guest

    Thanks, this was something I'd been looking at, I assumed the bsleeve, fsleeve files and such were a possible key to this, I'll come back tomorrow and tell you if I figured it out and how.
     
  12. MetaFace

    MetaFace Guest

    Sorry, forgot it was the weekend... but I looked through and scoured the entire starbound assets folder, found out how the setAnimationState() would work, however there is no animation file that describes the player states, so it is confirmed hard-coded, for now at least, hopefully they make this possible in the future. So one last question before this thread is closed and I open another (as I will making my armor into a mech instead to expand possibilities).

    I tried to add my script to my armor like such:
    Code:
    "scripts" : ["/scripts/myarmor.lua"],
    To no avail I noted that armor items don't call scripts, which is the main reason I want to transfer over to a vehicle instead, however I just want other's input to check this, make sure it actually is possible and I'm not just being really stupid.
     
  13. EmissaryOfInfinity

    EmissaryOfInfinity Subatomic Cosmonaut

    Armor can't directly call scripts, no. However, you can have the armor apply a status effect that then uses the script you wanted instead. It's a pretty simple workaround, thankfully, and should be capable of nearly anything you want the script to do.
     
  14. MetaFace

    MetaFace Guest

    Kinda what I thought, seems like the armor is only called upon once before it just becomes a pretty overlay, so after putting it on it doesn't do anything anymore.

    So with that answered I guess I'm going to close this and open the NEXT EPISODE! Sorry... I'm just dumb...
     
  15. MetaFace

    MetaFace Guest

    So kind of a necro to my own thread here, but I think I can change this to something better, to anyone here who was waiting to see if I solved this problem... I kinda did.
    Code:
    if status.stat("weight") > 0 and not status.resourcePositive("energyRegenBlock") then
        if status.resource("energy") == 0 then
          status.setResourceLocked("energy", true)
          if status.resourceLocked("energy") then
            status.setPersistentEffects("movementAbility", {{stat = "encumberance", amount = status.stat("weight")}})
          end
        elseif not status.resourceLocked("energy") then
          if (mcontroller.walking() or mcontroller.running()) then
            status.modifyResourcePercentage("energy", -status.stat("weight") * mcontroller.xVelocity() / 4 * mcontroller.movingDirection() / 16 * dt)
            status.clearPersistentEffects("movementAbility")
          end
          if mcontroller.jumping() then
            status.modifyResourcePercentage("energy", -status.stat("weight") / 4 * dt)
          end
        end
      end
    Anyone who doesn't understand this I CAN explain most of it, anyone who knows lua well, probably notes immediately that some if's need to be moved somewhere else and an if or two needs to be a while loop. Also the redundancy is a downside until I optimize this.

    I just felt this old-ish thread was the right place to put this code.
     
    IHart likes this.
  16. MetaFace

    MetaFace Guest

    Ok fixed it so it works a LOT BETTER!

    Code:
     if status.stat("weight") > 0 and not status.resourcePositive("energyRegenBlock") then
        if not (status.resourcePercentage("energy") == 0) and not status.resourceLocked("energy") then
          if mcontroller.walking() or mcontroller.running() then
            status.modifyResourcePercentage("energy", -status.stat("weight") * mcontroller.xVelocity() / 4 * mcontroller.movingDirection() / 16 * dt)
            status.clearPersistentEffects("movementAbility")
            if status.resource("energy") == 0 then
              status.setResourceLocked("energy", true)
              if status.resourceLocked("energy") then
                status.setPersistentEffects("movementAbility", {{stat = "encumberance", amount = status.stat("weight")}})
              end
            end
          end
          if mcontroller.jumping() then
            status.modifyResourcePercentage("energy", -status.stat("weight") / 4 * dt)
          end
        end
      end
    This works as far as I can tell right now.
     
  17. bk3k

    bk3k Oxygen Tank

    Minor suggested edit.

    Code:
      if status.stat("weight") > 0 and not status.resourcePositive("energyRegenBlock") then
        if not (status.resourcePercentage("energy") == 0) and not status.resourceLocked("energy") then
          if mcontroller.jumping() then
            status.modifyResourcePercentage("energy", -status.stat("weight") / 4 * dt)
          elseif mcontroller.running() or mcontroller.walking() then
            status.modifyResourcePercentage("energy", -status.stat("weight") * mcontroller.xVelocity() / 4 * mcontroller.movingDirection() / 16 * dt)
            status.clearPersistentEffects("movementAbility")
            if status.resource("energy") == 0 then
              status.setResourceLocked("energy", true)
              if status.resourceLocked("energy") then
                status.setPersistentEffects("movementAbility", {{stat = "encumberance", amount = status.stat("weight")}})
              end
            end
          end
        end
      end
      
    And the reasons for my edits are
    You probably don't need to check for running and walking while jumping.
    I put running before walking because I think you're more likely to be running so test for that first. I only recall "walking" in the Protectorate mission. But I could be mistaken on that.

    Where performance versus checks are concerned, any expression to the right side of or won't be evaluated unless what's on the left side is false. Likewise what's on the right side of and won't be evaluated unless the left side is true.

    But I found something you may find more interesting than that. You may know this, but there is mcontroller.mass(). Humanoid mass is 1.6 per humanoid.config (it may also pull a few values not specified here from default_actor_movement.config too) and therefore this function called on a humanoid will always return 1.6 ...or will it?
    Code:
      mcontroller.controlParameters({
        mass = 1.6 + (status.stat("weight") or 0)
      })
    
    So now how you move will be affected. You can't jump as high(unassisted by techs) and you're falling will be accelerated. It takes more force to change your velocity in any direction. Perhaps ALL armor should be doing something similar(by varying amounts).
    What's more, you can replace all other calls to status.stat("weight") with mcontroller.mass()

    You can adjust the actual weight value though, as it will be replaced by something with 1.6 inherent.
     
    Last edited: Mar 10, 2017
    MetaFace likes this.
  18. MetaFace

    MetaFace Guest

    Love this work, one reason that walking and running is checked is to prevent energy from easily regenerated by jumping constantly. I'll try this all out to see what can be done to make it all better.
     
  19. bk3k

    bk3k Oxygen Tank

    Alternate ways to figure out energy drains might be
    Code:
    math.abs(mcontroller.xVelocity())
    would return the velocity in either direction as a positive number. But you would probably do something different for 'y'

    Code:
    math.max(mcontroller.yVelocity(), 0)
    means it wouldn't see falling for the purpose of calculating energy. But mcontroller.jumping() is good enough.

    You could do
    Code:
    world.gravity( mcontroller.position() ) * mcontroller.mass
    to vary how much energy it takes to jump at different gravity levels. The Vanilla game though is 80 gravity everywhere except 20 on moons. So sad. But some mods fix this obvious mistake.

    It might be fair for your calculation to forgive 1.6 mass, since it doesn't cost any energy to jump with vanilla mass. Thus.
    Code:
    math.max((mcontroller.mass() - 1.6), 0) * world.gravity(mcontroller.position() )
    And of course to tidy it up, you might make a dedicated function to calculate mass multiplier and gravity.
     
  20. MetaFace

    MetaFace Guest

    Is there a way to call and change the run speed in the lua? I see runSpeed in default actor movement config, but almost 100% sure that this has nothing to do with the actual player. I'd like to know if the run speed can be altered, and I've tried approach velocity functions, they didn't work.
     

Share This Page