Merged changelog.

This commit is contained in:
Kyzentun
2014-12-08 16:06:46 -07:00
5 changed files with 269 additions and 8 deletions
+4
View File
@@ -11,6 +11,10 @@ ________________________________________________________________________________
Reset key mappings option added to debug menu for recovering from an Reset key mappings option added to debug menu for recovering from an
unusuble keymap without needing to find and delete KeyMaps.ini. [kyzentun] unusuble keymap without needing to find and delete KeyMaps.ini. [kyzentun]
2014/11/30
----------
* [NoteField] New functions added for controlling the receptor and ghost arrow
(explosion) flashes. [kyzentun]
2014/11/28 2014/11/28
---------- ----------
+10
View File
@@ -964,6 +964,16 @@
<Function name='SelectCourse'/> <Function name='SelectCourse'/>
<Function name='SelectSong'/> <Function name='SelectSong'/>
</Class> </Class>
<Class base='ActorFrame' name='NoteField'>
<Function name='DidHoldNote'/>
<Function name='DidTapNote'/>
<Function name='SetPressed'/>
<Function name='SetDidHoldNoteCallback'/>
<Function name='SetDidTapNoteCallback'/>
<Function name='SetSetPressedCallback'/>
<Function name='SetStepCallback'/>
<Function name='Step'/>
</Class>
<Class name='NoteSkinManager'> <Class name='NoteSkinManager'>
<Function name='DoesNoteSkinExist'/> <Function name='DoesNoteSkinExist'/>
<Function name='GetMetric'/> <Function name='GetMetric'/>
+39
View File
@@ -2941,6 +2941,45 @@ save yourself some time, copy this for undocumented things:
Returns a table of noteskin names for the current gametype. Returns a table of noteskin names for the current gametype.
</Function> </Function>
</Class> </Class>
<Class name='NoteField'>
<Function name='DidHoldNote' return='' arguments='int column, TapNoteScore tns, bool bright'>
Makes the NoteField act as if a hold note was hit in the column, with the given score and bright setting. <br />
The callback for DidHoldNote will not be called.
</Function>
<Function name='DidTapNote' return='' arguments='int column, TapNoteScore tns, bool bright'>
Makes the NoteField act as if a tap note was hit in the column, with the given score and bright setting. <br />
The callback for DidTapNote will not be called.
</Function>
<Function name='SetDidHoldNoteCallback' return= '' arguments='function callback'>
Same as SetDidTapNoteCallback, but for hold notes. Uses HoldNoteScore instead of TapNoteScore.
</Function>
<Function name='SetDidTapNoteCallback' return= '' arguments='function callback'>
Sets the function that the NoteField will call whenever a tap note is hit.<br />
The callback function is passed the column, the TapNoteScore, and whether the explosion will be bright.<br />
The callback function can return changed values for the NoteField to use instead of the ones that were passed.<br />
Pass nil instead of a function to clear the callback.
</Function>
<Function name='SetPressed' return='' arguments='int column'>
Makes the NoteField act as if a press occurred in the column. <br />
The callback for SetPressed will not be called.
</Function>
<Function name='SetSetPressedCallback' return= '' arguments='function callback'>
Sets the function that the NoteField will call whenever a press occurs.<br />
The callback function is passed the column for the press.<br />
The callback function can return changed values for the NoteField to use instead of the ones that were passed.<br />
Pass nil instead of a function to clear the callback.
</Function>
<Function name='SetStepCallback' return= '' arguments='function callback'>
Sets the function that the NoteField will call whenever a step occurs.<br />
The callback function is passed the column and the TapNoteScore for the step.<br />
The callback function can return changed values for the NoteField to use instead of the ones that were passed.<br />
Pass nil instead of a function to clear the callback.
</Function>
<Function name='Step' return='' arguments='int column, TapNoteScore tns'>
Makes the NoteField act as if a step occurred in the column with the given score.
The callback for Step will not be called.
</Function>
</Class>
<Class name='OptionRow'> <Class name='OptionRow'>
<Function name='FirstItemGoesDown' return='bool' arguments=''> <Function name='FirstItemGoesDown' return='bool' arguments=''>
Returns <code>true</code> if the first item in the row goes down. Returns <code>true</code> if the first item in the row goes down.
+202 -4
View File
@@ -67,6 +67,11 @@ NoteField::NoteField()
m_iBeginMarker = m_iEndMarker = -1; m_iBeginMarker = m_iEndMarker = -1;
m_fPercentFadeToFail = -1; m_fPercentFadeToFail = -1;
m_StepCallback.SetFromNil();
m_SetPressedCallback.SetFromNil();
m_DidTapNoteCallback.SetFromNil();
m_DidHoldNoteCallback.SetFromNil();
} }
NoteField::~NoteField() NoteField::~NoteField()
@@ -1375,10 +1380,111 @@ void NoteField::FadeToFail()
m_fPercentFadeToFail = max( 0.0f, m_fPercentFadeToFail ); // this will slowly increase every Update() m_fPercentFadeToFail = max( 0.0f, m_fPercentFadeToFail ); // this will slowly increase every Update()
// don't fade all over again if this is called twice // don't fade all over again if this is called twice
} }
void NoteField::Step( int iCol, TapNoteScore score ) { m_pCurDisplay->m_ReceptorArrowRow.Step( iCol, score ); }
void NoteField::SetPressed( int iCol ) { m_pCurDisplay->m_ReceptorArrowRow.SetPressed( iCol ); } // A few functions and macros to take care of processing the callback
void NoteField::DidTapNote( int iCol, TapNoteScore score, bool bBright ) { m_pCurDisplay->m_GhostArrowRow.DidTapNote( iCol, score, bBright ); } // return values, since the code would be identical in all of them. -Kyz
void NoteField::DidHoldNote( int iCol, HoldNoteScore score, bool bBright ) { m_pCurDisplay->m_GhostArrowRow.DidHoldNote( iCol, score, bBright ); }
#define OPEN_CALLBACK_BLOCK(member_name) \
if(!from_lua && !member_name.IsNil()) \
{ \
Lua* L= LUA->Get(); \
member_name.PushSelf(L);
#define OPEN_RUN_BLOCK(arg_count) \
RString error= "Error running callback: "; \
if(LuaHelpers::RunScriptOnStack(L, error, arg_count, arg_count, true)) \
{
#define CLOSE_RUN_AND_CALLBACK_BLOCKS } lua_settop(L, 0); LUA->Release(L); }
static void get_returned_column(Lua* L, int index, int& col)
{
if(lua_isnumber(L, index))
{
// 1-indexed columns in lua
int tmpcol= lua_tonumber(L, index) - 1;
if(tmpcol < 0 || tmpcol >= GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer)
{
LuaHelpers::ReportScriptErrorFmt(
"Column returned by callback must be between 1 and %d "
"(GAMESTATE:GetCurrentStyle():ColumnsPerPlayer()).",
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer);
}
else
{
col= tmpcol;
}
}
}
// Templated so it can be used for TNS and HNS. -Kyz
template<class T> static void get_returned_score(Lua* L, int index, T& score)
{
T maybe_score= Enum::Check<T>(L, index, true, true);
if(maybe_score != EnumTraits<T>::Invalid)
{
score= maybe_score;
}
}
static void get_returned_bright(Lua* L, int index, bool& bright)
{
if(lua_isboolean(L, index))
{
bright= lua_toboolean(L, index);
}
}
void NoteField::Step(int col, TapNoteScore score, bool from_lua)
{
OPEN_CALLBACK_BLOCK(m_StepCallback);
lua_pushnumber(L, col);
Enum::Push(L, score);
OPEN_RUN_BLOCK(2);
get_returned_column(L, 1, col);
get_returned_score(L, 2, score);
CLOSE_RUN_AND_CALLBACK_BLOCKS;
m_pCurDisplay->m_ReceptorArrowRow.Step(col, score);
}
void NoteField::SetPressed(int col, bool from_lua)
{
OPEN_CALLBACK_BLOCK(m_SetPressedCallback);
lua_pushnumber(L, col);
OPEN_RUN_BLOCK(1);
get_returned_column(L, 1, col);
CLOSE_RUN_AND_CALLBACK_BLOCKS;
m_pCurDisplay->m_ReceptorArrowRow.SetPressed(col);
}
void NoteField::DidTapNote(int col, TapNoteScore score, bool bright, bool from_lua)
{
OPEN_CALLBACK_BLOCK(m_DidTapNoteCallback);
lua_pushnumber(L, col);
Enum::Push(L, score);
lua_pushboolean(L, bright);
OPEN_RUN_BLOCK(3);
get_returned_column(L, 1, col);
get_returned_score(L, 2, score);
get_returned_bright(L, 3, bright);
CLOSE_RUN_AND_CALLBACK_BLOCKS;
m_pCurDisplay->m_GhostArrowRow.DidTapNote(col, score, bright);
}
void NoteField::DidHoldNote(int col, HoldNoteScore score, bool bright, bool from_lua)
{
OPEN_CALLBACK_BLOCK(m_DidHoldNoteCallback);
lua_pushnumber(L, col);
Enum::Push(L, score);
lua_pushboolean(L, bright);
OPEN_RUN_BLOCK(3);
get_returned_column(L, 1, col);
get_returned_score(L, 2, score);
get_returned_bright(L, 3, bright);
CLOSE_RUN_AND_CALLBACK_BLOCKS;
m_pCurDisplay->m_GhostArrowRow.DidHoldNote(col, score, bright);
}
#undef OPEN_CALLBACK_BLOCK
#undef OPEN_RUN_BLOCK
#undef CLOSE_RUN_AND_CALLBACK_BLOCKS
void NoteField::HandleMessage( const Message &msg ) void NoteField::HandleMessage( const Message &msg )
{ {
@@ -1391,6 +1497,98 @@ void NoteField::HandleMessage( const Message &msg )
ActorFrame::HandleMessage( msg ); ActorFrame::HandleMessage( msg );
} }
// lua start
#include "LuaBinding.h"
/** @brief Allow Lua to have access to the Notefield. */
class LunaNoteField: public Luna<NoteField>
{
public:
#define SET_CALLBACK_GENERIC(callback_name, member_name) \
static int callback_name(T* p, lua_State* L) \
{ \
if(lua_isnoneornil(L, 1)) \
{ \
p->member_name.SetFromNil(); \
} \
else if(lua_isfunction(L, 1)) \
{ \
p->member_name.SetFromStack(L); \
} \
else \
{ \
luaL_error(L, #callback_name "Callback argument must be nil (to clear the callback) or a function (to set the callback)."); \
} \
return 0; \
}
SET_CALLBACK_GENERIC(SetStepCallback, m_StepCallback);
SET_CALLBACK_GENERIC(SetSetPressedCallback, m_SetPressedCallback);
SET_CALLBACK_GENERIC(SetDidTapNoteCallback, m_DidTapNoteCallback);
SET_CALLBACK_GENERIC(SetDidHoldNoteCallback, m_DidHoldNoteCallback);
#undef SET_CALLBACK_GENERIC
static int check_column(lua_State* L, int index)
{
// 1-indexed columns in lua
int col= IArg(1)-1;
if(col < 0 || col >= GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer)
{
luaL_error(L, "Column must be between 1 and %d "
"(GAMESTATE:GetCurrentStyle():ColumnsPerPlayer()).",
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer);
}
return col;
}
static int Step(T* p, lua_State* L)
{
int col= check_column(L, 1);
TapNoteScore tns= Enum::Check<TapNoteScore>(L, 2);
p->Step(col, tns, true);
return 0;
}
static int SetPressed(T* p, lua_State* L)
{
int col= check_column(L, 1);
p->SetPressed(col, true);
return 0;
}
static int DidTapNote(T* p, lua_State* L)
{
int col= check_column(L, 1);
TapNoteScore tns= Enum::Check<TapNoteScore>(L, 2);
bool bright= BArg(3);
p->DidTapNote(col, tns, bright, true);
return 0;
}
static int DidHoldNote(T* p, lua_State* L)
{
int col= check_column(L, 1);
HoldNoteScore hns= Enum::Check<HoldNoteScore>(L, 2);
bool bright= BArg(3);
p->DidHoldNote(col, hns, bright, true);
return 0;
}
LunaNoteField()
{
ADD_METHOD(SetStepCallback);
ADD_METHOD(SetSetPressedCallback);
ADD_METHOD(SetDidTapNoteCallback);
ADD_METHOD(SetDidHoldNoteCallback);
ADD_METHOD(Step);
ADD_METHOD(SetPressed);
ADD_METHOD(DidTapNote);
ADD_METHOD(DidHoldNote);
}
};
LUA_REGISTER_DERIVED_CLASS(NoteField, ActorFrame)
// lua end
/* /*
* (c) 2001-2004 Chris Danford * (c) 2001-2004 Chris Danford
* All rights reserved. * All rights reserved.
+14 -4
View File
@@ -36,10 +36,20 @@ public:
void CacheAllUsedNoteSkins(); void CacheAllUsedNoteSkins();
void FadeToFail(); void FadeToFail();
void Step( int iCol, TapNoteScore score ); void Step(int col, TapNoteScore score, bool from_lua= false);
void SetPressed( int iCol ); void SetPressed(int col, bool from_lua= false);
void DidTapNote( int iCol, TapNoteScore score, bool bBright ); void DidTapNote(int col, TapNoteScore score, bool bright, bool from_lua= false);
void DidHoldNote( int iCol, HoldNoteScore score, bool bBright ); void DidHoldNote(int col, HoldNoteScore score, bool bright, bool from_lua= false);
virtual void PushSelf( lua_State *L );
// Allows the theme to modify the parameters to Step, SetPressed,
// DidTapNote, and DidHoldNote before they pass on to the ghost arrows or
// receptors. -Kyz
LuaReference m_StepCallback;
LuaReference m_SetPressedCallback;
LuaReference m_DidTapNoteCallback;
LuaReference m_DidHoldNoteCallback;
const PlayerState *GetPlayerState() const { return m_pPlayerState; } const PlayerState *GetPlayerState() const { return m_pPlayerState; }