Jump to content

Recommended Posts

Possible?

 

From what I can gather, my understanding is that the swap_(item) sprite used in the OverrideSymbol function simply replaces a sprite in the owner/character's animation, discarding any animation data.  That means the the character would have to contain any equip-slot animation desired.

 

I can only think of two possible workarounds:

  • Create custom characters (to replace the existing characters) that include those animations.  This would be a huge amount of work.
  • Constantly swap out the sprite to create a sort of pre-rendered animation, which I would imagine could create performance issues, or at the least only allow for a very low-frame animation.

Is there a better workaround? Or perhaps I have a misunderstanding of how it works?

Possible?

 

From what I can gather, my understanding is that the swap_(item) sprite used in the OverrideSymbol function simply replaces a sprite in the owner/character's animation, discarding any animation data.  That means the the character would have to contain any equip-slot animation desired.

 

I can only think of two possible workarounds:

  • Create custom characters (to replace the existing characters) that include those animations.  This would be a huge amount of work.
  • Constantly swap out the sprite to create a sort of pre-rendered animation, which I would imagine could create performance issues, or at the least only allow for a very low-frame animation.

Is there a better workaround? Or perhaps I have a misunderstanding of how it works?

 

No, there's not. From what I could gather at least..

Having dug further into this, it looks like I might be able to accomplish what I need by overriding the run stategraph(I only want the animation to play while moving) with AddStategraphState() and playing a custom animation.

 

I still don't know where that dummy sprite comes from though.....

 

edit:

 

from player_actions.zip's anim.bin--

 

simple_element{
   name swap_object
   frame 1
   layer_name ARM_carry
   scale_x 0.948755
   scale_y 0.948755
   rot 353.623993
   tx 105.449997
   ty -107.448997
   tz 2.222222
  }

 

one step closer...

Edited by Corrosive

SUCCESS! :livid: I'll post my solution in the event that it's useful to anyone else. I used the excellent BinaryConverter tool to unpack the anim.bin located in anim/player_basic.zip into anim.txt.  This didn't work until I made a fake "build.bin"(which was just an empty file).  The program crashes when it tries to convert the build.bin, but hey, what works, works!

 

After 3 million or so unsuccessful regular expressions, I gave up and just manually trimmed everything but the run_loop animations from that file.  I then separated each instance of run_loop.  There is one for when the character faces up, one for when the character faces down, and one for when the character faces either left or right.  I was primarily concerned with the left/right animation, cause I haven't created the art for the other views yet.

 

This is what the format looks like, with extra spacing for legibility, and comments:

anim{  name run_loop    <- The name of the animation.  You can change this.  face_right 1     <- This animation is used when the character faces right  face_up 0  face_left 1      <- This animation is also used when the character faces left  face_down 0  root wilson  framerate 30.000000  frame{    x 27.775499     \    y -162.949493    | ______ Positional data    w 348.449005     |         for the frame    h 386.898987    /    simple_element{      name LANTERN_OVERLAY        <---- A sprite that I wasn't interested in(there are many of these)      frame 1      layer_name LANTERN_OVERLAY      scale_x 0.947375      scale_y 0.947375      rot 16.255959      tx 101.099998      ty -137.848999      tz -5.000000    }    simple_element{      name swap_object          <---- This is the dummy sprite for hand-held equippables      frame 1                   <---- The frame seems to always be "1" for these.  I didn't       layer_name ARM_carry            want to mess around with this value.      scale_x 0.947375      scale_y 0.947375      rot 24.000000     <---- Rotation.  This can be 0 or a positive number up to 359.999999      tx 101.099998     ----\      ty -137.848999         |--- Translation(position).  I kept these as-is, because they      tz 2.500000       ----/     match up with the movement of the hand when running.    }  }}

Each simple_element represents a single sprite's position/scale/rotation for a single frame.  In the case of run_loop, there were 16 frames, each with one swap_object element.  Since my animation simply needed to rotate the object, I started from the top and replaced each of the 16 "rot xxxxxxxx" values with the desired number.  I changed the name of the animation from run_loop to run_loop_(my mod's name).

 

I then used BinaryConverter to pack it back into anim.bin and added it to a zip archive.

 

From within my mod, I was able to declare the animation using

Assets = {  Asset("ANIM", "anim/run_(mymod).zip")}

I tested it out by making a stategraph that overrode the default run stategraph(which isn't ideal since ALL held items twirl when running!) and it works great. I don't want to post that function until I clean it up to work properly.

 

edit: Here's the stategraph override.  Turns out I barely had to do anything!

local function DoFoleySounds(inst)	for k,v in pairs(inst.components.inventory.equipslots) do		if v.components.inventoryitem and v.components.inventoryitem.foleysound then			inst.SoundEmitter:PlaySound(v.components.inventoryitem.foleysound)		end	end    if inst.prefab == "wx78" then        inst.SoundEmitter:PlaySound("dontstarve/movement/foley/wx78")    endend    local run_state_override = {                name = "run",        tags = {"moving", "running", "canrotate"},                onenter = function(inst)             inst.components.locomotor:RunForward()            if inst.components.inventory.equipslots.hands and inst.components.inventory.equipslots.hands.prefab == "prefab_name" then              inst.AnimState:PlayAnimation("run_loop_mod_name")             else              inst.AnimState:PlayAnimation("run_loop")            end        end,                onupdate = function(inst)            inst.components.locomotor:RunForward()        end,        timeline=        {            TimeEvent(7*FRAMES, function(inst)				inst.sg.mem.foosteps = inst.sg.mem.foosteps + 1                PlayFootstep(inst, inst.sg.mem.foosteps < 5 and 1 or .6)                DoFoleySounds(inst)            end),            TimeEvent(15*FRAMES, function(inst)				inst.sg.mem.foosteps = inst.sg.mem.foosteps + 1                PlayFootstep(inst, inst.sg.mem.foosteps < 5 and 1 or .6)                DoFoleySounds(inst)            end),        },                events=        {               EventHandler("animover", function(inst) inst.sg:GoToState("run") end ),                }}

If anyone uses this, keep in mind you need to import the variables GLOBAL.EventHandler, GLOBAL.TimeEvent, GLOBAL.PlayFootstep, and GLOBAL.FRAMES.

Edited by Corrosive

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
×
  • Create New...