diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt
index 49c0335c11..c4b025070e 100644
--- a/Docs/Changelog_sm5.txt
+++ b/Docs/Changelog_sm5.txt
@@ -4,6 +4,10 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes
from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
________________________________________________________________________________
+2015/01/09
+----------
+* [Sprite] SetStateProperties function added. [kyzentun]
+
2014/12/20
----------
* [Preferences] AllowMultipleHighScoreWithSameName, ComboContinuesBetweenSongs
diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml
index 53d2d79fd4..fb367a0849 100644
--- a/Docs/Luadoc/Lua.xml
+++ b/Docs/Luadoc/Lua.xml
@@ -1581,6 +1581,7 @@
+
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index fa8011dbe4..37069fa2a1 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -4511,6 +4511,21 @@ save yourself some time, copy this for undocumented things:
Sets the number of seconds into the animation to fSeconds.
+
+ Sets the properties of the states of the sprite. The properties table is identical to the "Frames" table that can be put in the sprite when calling Def.Sprite.
+ Example:
+ {{Frame= 0, Delay= .016, {0, 0}, {.25, .25}},
+ {Frame= 1, Delay= .016, {0, 0}, {.25, .25}},
+ {Frame= 2, Delay= .016, {0, 0}, {.25, .25}},
+ {Frame= 3, Delay= .016, {0, 0}, {.25, .25}},
+ }
+ Frame is optional, defaulting to 0.
+ Delay is optional, defaulting to 0.
+ The two tables are optional upper left and lower right corners of the fraction of the frame to use. The example makes the sprite only use the upper left corner of each frame.
+ Simpler example:
+ {{Frame= 0, Delay= .016}, {Frame= 1, Delay= .016}, {Frame= 2, Delay= .016}, {Frame= 3, Delay= .016}}
+ This example makes the sprite use the whole of each frame.
+
Set the texture to texture.
diff --git a/src/Sprite.cpp b/src/Sprite.cpp
index 3d5b9a3ab6..5549d68267 100644
--- a/src/Sprite.cpp
+++ b/src/Sprite.cpp
@@ -1093,6 +1093,80 @@ public:
static int addimagecoords( T* p, lua_State *L ) { p->AddImageCoords( FArg(1),FArg(2) ); COMMON_RETURN_SELF; }
static int setstate( T* p, lua_State *L ) { p->SetState( IArg(1) ); COMMON_RETURN_SELF; }
static int GetState( T* p, lua_State *L ) { lua_pushnumber( L, p->GetState() ); return 1; }
+ static int SetStateProperties(T* p, lua_State* L)
+ {
+ // States table example:
+ // {{Frame= 0, Delay= .016, {0, 0}, {.25, .25}}}
+ // Each element in the States table must have a Frame and a Delay.
+ // Frame is optional, defaulting to 0.
+ // Delay is optional, defaulting to 0.
+ // The two tables in the state are the upper left and lower right and are
+ // optional.
+ if(!lua_istable(L, 1))
+ {
+ luaL_error(L, "State properties must be in a table.");
+ }
+ vector new_states;
+ size_t num_states= lua_objlen(L, 1);
+ for(size_t s= 0; s < num_states; ++s)
+ {
+ Sprite::State new_state;
+ lua_rawgeti(L, 1, s+1);
+ lua_getfield(L, -1, "Frame");
+ int frame_index= 0;
+ if(lua_isnumber(L, -1))
+ {
+ frame_index= IArg(-1);
+ if(frame_index < 0 || frame_index >= p->GetTexture()->GetNumFrames())
+ {
+ luaL_error(L, "Frame index out of range 0-%d.",
+ p->GetTexture()->GetNumFrames()-1);
+ }
+ }
+ new_state.rect= *p->GetTexture()->GetTextureCoordRect(frame_index);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "Delay");
+ if(lua_isnumber(L, -1))
+ {
+ new_state.fDelay= FArg(-1);
+ // I wonder what a negative state delay does... -Kyz
+ }
+ lua_pop(L, 1);
+ RectF r= new_state.rect;
+ lua_rawgeti(L, -1, 1);
+ if(lua_istable(L, -1))
+ {
+ lua_rawgeti(L, -1, 1);
+ // I have no idea why the points are from 0 to 1 and make it use only
+ // a portion of the state. This is just copied from LoadFromNode.
+ // -Kyz
+ new_state.rect.left= SCALE(FArg(-1), 0.0f, 1.0f, r.left, r.right);
+ lua_pop(L, 1);
+ lua_rawgeti(L, -1, 2);
+ new_state.rect.top= SCALE(FArg(-1), 0.0f, 1.0f, r.top, r.bottom);
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+ lua_rawgeti(L, -1, 2);
+ if(lua_istable(L, -1))
+ {
+ lua_rawgeti(L, -1, 1);
+ // I have no idea why the points are from 0 to 1 and make it use only
+ // a portion of the state. This is just copied from LoadFromNode.
+ // -Kyz
+ new_state.rect.right= SCALE(FArg(-1), 0.0f, 1.0f, r.left, r.right);
+ lua_pop(L, 1);
+ lua_rawgeti(L, -1, 2);
+ new_state.rect.bottom= SCALE(FArg(-1), 0.0f, 1.0f, r.top, r.bottom);
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+ new_states.push_back(new_state);
+ lua_pop(L, 1);
+ }
+ p->SetStateProperties(new_states);
+ COMMON_RETURN_SELF;
+ }
static int GetAnimationLengthSeconds( T* p, lua_State *L ) { lua_pushnumber( L, p->GetAnimationLengthSeconds() ); return 1; }
static int SetSecondsIntoAnimation( T* p, lua_State *L ) { p->SetSecondsIntoAnimation(FArg(0)); COMMON_RETURN_SELF; }
static int SetTexture( T* p, lua_State *L )
@@ -1136,6 +1210,7 @@ public:
ADD_METHOD( addimagecoords );
ADD_METHOD( setstate );
ADD_METHOD( GetState );
+ ADD_METHOD( SetStateProperties );
ADD_METHOD( GetAnimationLengthSeconds );
ADD_METHOD( SetSecondsIntoAnimation );
ADD_METHOD( SetTexture );
diff --git a/src/Sprite.h b/src/Sprite.h
index f6f95e5fba..6820b80f14 100644
--- a/src/Sprite.h
+++ b/src/Sprite.h
@@ -11,6 +11,14 @@ class RageTexture;
class Sprite: public Actor
{
public:
+ /** @brief The Sprite's present state. */
+ struct State
+ {
+ RectF rect;
+ /** @brief The number of "seconds to show". */
+ float fDelay;
+ };
+
Sprite();
Sprite( const Sprite &cpy );
virtual ~Sprite();
@@ -48,6 +56,8 @@ public:
int GetState() { return m_iCurState; }
virtual float GetAnimationLengthSeconds() const;
virtual void SetSecondsIntoAnimation( float fSeconds );
+ void SetStateProperties(const vector& new_states)
+ { m_States= new_states; }
RString GetTexturePath() const;
@@ -90,13 +100,6 @@ private:
RageTexture* m_pTexture;
- /** @brief The Sprite's present state. */
- struct State
- {
- RectF rect;
- /** @brief The number of "seconds to show". */
- float fDelay;
- };
vector m_States;
int m_iCurState;
/** @brief The number of seconds that have elapsed since we switched to this frame. */