2003-02-16 04:01:45 +00:00
|
|
|
#include "global.h"
|
2002-09-03 00:22:12 +00:00
|
|
|
#include "CodeDetector.h"
|
2003-05-04 13:58:45 +00:00
|
|
|
#include "PlayerOptions.h"
|
2002-09-03 00:22:12 +00:00
|
|
|
#include "GameState.h"
|
|
|
|
|
#include "InputQueue.h"
|
2003-12-02 09:04:00 +00:00
|
|
|
#include "InputMapper.h"
|
2002-09-03 00:22:12 +00:00
|
|
|
#include "ThemeManager.h"
|
|
|
|
|
#include "RageLog.h"
|
2004-07-25 17:07:32 +00:00
|
|
|
#include "Game.h"
|
2003-02-06 07:32:57 +00:00
|
|
|
#include "RageUtil.h"
|
2004-12-20 06:25:59 +00:00
|
|
|
#include "PlayerState.h"
|
2006-09-08 04:19:42 +00:00
|
|
|
#include "InputEventPlus.h"
|
2007-03-15 20:38:12 +00:00
|
|
|
#include "Foreach.h"
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2006-01-04 22:30:51 +00:00
|
|
|
const char *CodeNames[] = {
|
2002-09-03 00:22:12 +00:00
|
|
|
"Easier1",
|
|
|
|
|
"Easier2",
|
|
|
|
|
"Harder1",
|
|
|
|
|
"Harder2",
|
|
|
|
|
"NextSort1",
|
|
|
|
|
"NextSort2",
|
2003-12-06 00:32:42 +00:00
|
|
|
"NextSort3",
|
|
|
|
|
"NextSort4",
|
2004-01-11 08:15:44 +00:00
|
|
|
"ModeMenu1",
|
|
|
|
|
"ModeMenu2",
|
2002-09-03 00:22:12 +00:00
|
|
|
"Mirror",
|
|
|
|
|
"Left",
|
|
|
|
|
"Right",
|
|
|
|
|
"Shuffle",
|
|
|
|
|
"SuperShuffle",
|
2003-02-16 20:27:53 +00:00
|
|
|
"NextTransform",
|
2002-09-03 00:22:12 +00:00
|
|
|
"NextScrollSpeed",
|
2003-01-16 23:31:34 +00:00
|
|
|
"PreviousScrollSpeed",
|
2003-01-25 11:05:12 +00:00
|
|
|
"NextAccel",
|
2002-09-03 00:22:12 +00:00
|
|
|
"NextEffect",
|
|
|
|
|
"NextAppearance",
|
|
|
|
|
"NextTurn",
|
|
|
|
|
"Reverse",
|
|
|
|
|
"HoldNotes",
|
2003-11-07 07:25:52 +00:00
|
|
|
"Mines",
|
2002-09-03 00:22:12 +00:00
|
|
|
"Dark",
|
2003-05-04 13:58:45 +00:00
|
|
|
"Hidden",
|
|
|
|
|
"RandomVanish",
|
2003-04-13 04:50:08 +00:00
|
|
|
"CancelAll",
|
|
|
|
|
"NextTheme",
|
2003-09-25 02:16:37 +00:00
|
|
|
"NextTheme2",
|
2003-09-07 22:03:23 +00:00
|
|
|
"NextAnnouncer",
|
2003-09-25 02:16:37 +00:00
|
|
|
"NextAnnouncer2",
|
2003-09-07 22:03:23 +00:00
|
|
|
"NextBannerGroup",
|
2004-02-12 09:44:16 +00:00
|
|
|
"NextBannerGroup2",
|
2005-04-26 08:40:27 +00:00
|
|
|
"SaveScreenshot1",
|
|
|
|
|
"SaveScreenshot2",
|
2004-02-23 07:44:57 +00:00
|
|
|
"CancelAllPlayerOptions",
|
2004-05-08 19:22:51 +00:00
|
|
|
"BackInEventMode",
|
2002-09-03 00:22:12 +00:00
|
|
|
};
|
2006-10-15 00:09:18 +00:00
|
|
|
XToString( Code );
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2006-09-26 20:49:10 +00:00
|
|
|
static CodeItem g_CodeItems[NUM_Code];
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
static const float g_fSimultaneousThreshold = 0.05f;
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2004-01-25 02:29:18 +00:00
|
|
|
bool CodeItem::EnteredCode( GameController controller ) const
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2006-09-26 20:59:40 +00:00
|
|
|
if( controller == GameController_Invalid )
|
2004-01-25 15:45:50 +00:00
|
|
|
return false;
|
2007-03-15 20:38:12 +00:00
|
|
|
if( m_aPresses.size() == 0 )
|
2003-04-14 05:22:33 +00:00
|
|
|
return false;
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
RageTimer OldestTimeAllowed;
|
|
|
|
|
OldestTimeAllowed += -fMaxSecondsBack;
|
|
|
|
|
|
|
|
|
|
// iterate newest to oldest
|
|
|
|
|
int iSequenceIndex = m_aPresses.size()-1; // count down
|
|
|
|
|
const vector<InputEventPlus> &aQueue = INPUTQUEUE->GetQueue( controller );
|
|
|
|
|
int iQueueIndex = aQueue.size()-1;
|
|
|
|
|
while( iQueueIndex >= 0 )
|
2003-12-02 09:04:00 +00:00
|
|
|
{
|
|
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
const InputEventPlus &iep = aQueue[iQueueIndex];
|
|
|
|
|
if( iep.DeviceI.ts < OldestTimeAllowed )
|
2006-09-08 04:19:42 +00:00
|
|
|
return false;
|
2007-03-15 20:38:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Search backwards for all of Press.m_aButtonsToPress pressed within g_fTapThreshold seconds
|
|
|
|
|
* with m_aButtonsToHold pressed. */
|
|
|
|
|
const ButtonPress &Press = m_aPresses[iSequenceIndex];
|
|
|
|
|
bool bMatched = false;
|
|
|
|
|
int iMinSearchIndexUsed = iQueueIndex;
|
|
|
|
|
for( int b=0; b<(int) Press.m_aButtonsToPress.size(); ++b )
|
|
|
|
|
{
|
|
|
|
|
/* Search backwards for the buttons in this tap, within the tap threshold since iQueueIndex. */
|
|
|
|
|
RageTimer OldestTimeAllowedForTap( aQueue[iQueueIndex].DeviceI.ts );
|
|
|
|
|
OldestTimeAllowedForTap += -g_fSimultaneousThreshold;
|
2006-09-08 04:19:42 +00:00
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
const InputEventPlus *pIEP = NULL;
|
|
|
|
|
int iQueueSearchIndex = iQueueIndex;
|
|
|
|
|
for( ; iQueueSearchIndex>=0; --iQueueSearchIndex ) // iterate newest to oldest
|
|
|
|
|
{
|
|
|
|
|
const InputEventPlus &iep = aQueue[iQueueSearchIndex];
|
|
|
|
|
if( iep.DeviceI.ts < OldestTimeAllowedForTap ) // buttons are too old. Stop searching because we're not going to find a match
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if( iep.GameI.button == Press.m_aButtonsToPress[b] )
|
|
|
|
|
{
|
|
|
|
|
pIEP = &iep;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( pIEP == NULL )
|
|
|
|
|
break; // didn't find the button
|
|
|
|
|
|
|
|
|
|
// Check that m_aButtonsToHold were being held when the buttons were pressed.
|
|
|
|
|
bool bAllButtonsPressed = true;
|
|
|
|
|
for( unsigned i=0; i<Press.m_aButtonsToHold.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
GameInput gi( controller, Press.m_aButtonsToHold[i] );
|
|
|
|
|
if( !INPUTMAPPER->IsBeingPressed(gi, MultiPlayer_Invalid, &pIEP->InputList) )
|
|
|
|
|
bAllButtonsPressed = false;
|
|
|
|
|
}
|
|
|
|
|
if( !bAllButtonsPressed )
|
|
|
|
|
continue;
|
|
|
|
|
if( b == (int) Press.m_aButtonsToPress.size()-1 )
|
2003-12-02 09:04:00 +00:00
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
bMatched = true;
|
|
|
|
|
iMinSearchIndexUsed = min( iMinSearchIndexUsed, iQueueSearchIndex );
|
2003-12-02 09:04:00 +00:00
|
|
|
}
|
2007-03-15 20:38:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !bMatched )
|
|
|
|
|
{
|
|
|
|
|
/* The press wasn't matched. If m_bAllowIntermediatePresses is true,
|
|
|
|
|
* skip the last press, and look again. */
|
|
|
|
|
if( !Press.m_bAllowIntermediatePresses )
|
|
|
|
|
return false;
|
|
|
|
|
--iQueueIndex;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( iSequenceIndex == 0 )
|
|
|
|
|
{
|
|
|
|
|
// we matched the whole pattern. Empty the queue so we don't match on it again.
|
|
|
|
|
INPUTQUEUE->ClearQueue( controller );
|
2006-09-08 04:19:42 +00:00
|
|
|
return true;
|
2003-12-02 09:04:00 +00:00
|
|
|
}
|
2007-03-15 20:38:12 +00:00
|
|
|
|
|
|
|
|
/* The press was matched. */
|
|
|
|
|
iQueueIndex = iMinSearchIndexUsed - 1;
|
|
|
|
|
--iSequenceIndex;
|
2003-12-02 09:04:00 +00:00
|
|
|
}
|
2007-03-15 20:38:12 +00:00
|
|
|
|
|
|
|
|
return false;
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2006-01-22 01:00:06 +00:00
|
|
|
bool CodeItem::Load( RString sButtonsNames )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
m_aPresses.clear();
|
2004-01-25 02:29:18 +00:00
|
|
|
|
2006-01-22 01:00:06 +00:00
|
|
|
vector<RString> asButtonNames;
|
2003-12-02 09:04:00 +00:00
|
|
|
|
2005-12-21 08:43:44 +00:00
|
|
|
bool bHasAPlus = sButtonsNames.find( '+' ) != string::npos;
|
|
|
|
|
bool bHasADash = sButtonsNames.find( '-' ) != string::npos;
|
2003-12-02 09:04:00 +00:00
|
|
|
|
|
|
|
|
if( bHasAPlus )
|
|
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
// press all buttons simultaneously
|
2003-12-02 09:04:00 +00:00
|
|
|
split( sButtonsNames, "+", asButtonNames, false );
|
|
|
|
|
}
|
|
|
|
|
else if( bHasADash )
|
|
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
// hold the first iNumButtons-1 buttons, then press the last
|
2003-12-02 09:04:00 +00:00
|
|
|
split( sButtonsNames, "-", asButtonNames, false );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
// press the buttons in sequence
|
2003-12-02 09:04:00 +00:00
|
|
|
split( sButtonsNames, ",", asButtonNames, false );
|
|
|
|
|
}
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2005-04-24 06:31:39 +00:00
|
|
|
if( asButtonNames.size() < 1 )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2004-01-21 05:25:19 +00:00
|
|
|
if( sButtonsNames != "" )
|
2007-03-15 20:38:12 +00:00
|
|
|
LOG->Trace( "Ignoring empty code \"%s\".", sButtonsNames.c_str() );
|
2004-01-25 15:45:50 +00:00
|
|
|
return false;
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
vector<GameButton> buttons;
|
2004-01-25 02:29:18 +00:00
|
|
|
for( unsigned i=0; i<asButtonNames.size(); i++ ) // for each button in this code
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2006-01-22 01:00:06 +00:00
|
|
|
const RString sButtonName = asButtonNames[i];
|
2002-09-03 00:22:12 +00:00
|
|
|
|
|
|
|
|
// Search for the corresponding GameButton
|
2006-09-30 08:24:05 +00:00
|
|
|
const GameButton gb = INPUTMAPPER->GetInputScheme()->ButtonNameToIndex( sButtonName );
|
2006-09-27 04:44:15 +00:00
|
|
|
if( gb == GameButton_Invalid )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
LOG->Trace( "The code \"%s\" contains an unrecognized button \"%s\".", sButtonsNames.c_str(), sButtonName.c_str() );
|
|
|
|
|
m_aPresses.clear();
|
2004-01-25 15:45:50 +00:00
|
|
|
return false;
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
2004-01-25 02:29:18 +00:00
|
|
|
|
|
|
|
|
buttons.push_back( gb );
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
if( bHasAPlus )
|
|
|
|
|
{
|
|
|
|
|
m_aPresses.push_back( ButtonPress() );
|
|
|
|
|
FOREACH( GameButton, buttons, gb )
|
|
|
|
|
{
|
|
|
|
|
m_aPresses.back().m_aButtonsToPress.push_back( *gb );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( bHasADash )
|
|
|
|
|
{
|
|
|
|
|
m_aPresses.push_back( ButtonPress() );
|
|
|
|
|
m_aPresses.back().m_aButtonsToHold.insert( m_aPresses.back().m_aButtonsToHold.begin(), buttons.begin(), buttons.end()-1 );
|
|
|
|
|
m_aPresses.back().m_aButtonsToPress.push_back( buttons.back() );
|
|
|
|
|
}
|
|
|
|
|
else
|
2003-12-02 09:04:00 +00:00
|
|
|
{
|
2007-03-15 20:38:12 +00:00
|
|
|
FOREACH( GameButton, buttons, gb )
|
|
|
|
|
{
|
|
|
|
|
m_aPresses.push_back( ButtonPress() );
|
|
|
|
|
m_aPresses.back().m_aButtonsToPress.push_back( *gb );
|
|
|
|
|
m_aPresses.back().m_bAllowIntermediatePresses = false;
|
|
|
|
|
}
|
2003-12-02 09:04:00 +00:00
|
|
|
}
|
2003-04-14 05:22:33 +00:00
|
|
|
|
2007-03-15 20:38:12 +00:00
|
|
|
if( m_aPresses.size() == 1 )
|
|
|
|
|
fMaxSecondsBack = 0.55f;
|
|
|
|
|
else
|
|
|
|
|
fMaxSecondsBack = (m_aPresses.size()-1)*0.6f;
|
|
|
|
|
|
2002-09-03 00:22:12 +00:00
|
|
|
// if we make it here, we found all the buttons in the code
|
2004-01-25 15:45:50 +00:00
|
|
|
return true;
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2004-01-25 02:29:18 +00:00
|
|
|
bool CodeDetector::EnteredCode( GameController controller, Code code )
|
|
|
|
|
{
|
|
|
|
|
return g_CodeItems[code].EnteredCode( controller );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-01-22 01:00:06 +00:00
|
|
|
void CodeDetector::RefreshCacheItems( RString sClass )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2004-05-22 23:54:23 +00:00
|
|
|
if( sClass == "" )
|
|
|
|
|
sClass = "CodeDetector";
|
2007-03-15 20:39:58 +00:00
|
|
|
FOREACH_ENUM( Code, c )
|
2004-01-25 02:29:18 +00:00
|
|
|
{
|
2005-05-05 19:55:04 +00:00
|
|
|
CodeItem& item = g_CodeItems[c];
|
2006-01-22 01:00:06 +00:00
|
|
|
const RString sCodeName = CodeToString(c);
|
|
|
|
|
const RString sButtonsNames = THEME->GetMetric(sClass,sCodeName);
|
2004-01-25 02:29:18 +00:00
|
|
|
|
|
|
|
|
item.Load( sButtonsNames );
|
|
|
|
|
}
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2003-09-07 22:03:23 +00:00
|
|
|
bool CodeDetector::EnteredNextBannerGroup( GameController controller )
|
|
|
|
|
{
|
|
|
|
|
return EnteredCode(controller,CODE_BW_NEXT_GROUP) || EnteredCode(controller,CODE_BW_NEXT_GROUP2);
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-03 00:22:12 +00:00
|
|
|
bool CodeDetector::EnteredEasierDifficulty( GameController controller )
|
|
|
|
|
{
|
2003-04-13 04:50:08 +00:00
|
|
|
return EnteredCode(controller,CODE_EASIER1) || EnteredCode(controller,CODE_EASIER2);
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CodeDetector::EnteredHarderDifficulty( GameController controller )
|
|
|
|
|
{
|
2003-04-13 04:50:08 +00:00
|
|
|
return EnteredCode(controller,CODE_HARDER1) || EnteredCode(controller,CODE_HARDER2);
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CodeDetector::EnteredNextSort( GameController controller )
|
|
|
|
|
{
|
2003-12-06 00:32:42 +00:00
|
|
|
return EnteredCode(controller,CODE_NEXT_SORT1) ||
|
|
|
|
|
EnteredCode(controller,CODE_NEXT_SORT2) ||
|
|
|
|
|
EnteredCode(controller,CODE_NEXT_SORT3) ||
|
|
|
|
|
EnteredCode(controller,CODE_NEXT_SORT4);
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
|
|
|
|
|
2004-01-11 08:15:44 +00:00
|
|
|
bool CodeDetector::EnteredModeMenu( GameController controller )
|
|
|
|
|
{
|
|
|
|
|
return EnteredCode(controller,CODE_MODE_MENU1) || EnteredCode(controller,CODE_MODE_MENU2);
|
2003-12-02 09:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-03 00:22:12 +00:00
|
|
|
#define TOGGLE(v,a,b) if(v!=a) v=a; else v=b;
|
2003-02-26 23:26:57 +00:00
|
|
|
#define FLOAT_TOGGLE(v) if(v!=1.f) v=1.f; else v=0.f;
|
2003-11-04 08:44:26 +00:00
|
|
|
// XXX: Read the metrics file instead!
|
|
|
|
|
// Using this can give us unlisted scroll speeds on the Options screen.
|
2002-09-03 00:22:12 +00:00
|
|
|
#define INCREMENT_SCROLL_SPEED(s) (s==0.5f) ? s=0.75f : (s==0.75f) ? s=1.0f : (s==1.0f) ? s=1.5f : (s==1.5f) ? s=2.0f : (s==2.0f) ? s=3.0f : (s==3.0f) ? s=4.0f : (s==4.0f) ? s=5.0f : (s==5.0f) ? s=8.0f : s=0.5f;
|
2003-01-16 23:31:34 +00:00
|
|
|
#define DECREMENT_SCROLL_SPEED(s) (s==0.75f) ? s=0.5f : (s==1.0f) ? s=0.75f : (s==1.5f) ? s=1.0f : (s==2.0f) ? s=1.5f : (s==3.0f) ? s=2.0f : (s==4.0f) ? s=3.0f : (s==5.0f) ? s=4.0f : (s==8.0f) ? s=4.0f : s=8.0f;
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2003-04-13 04:50:08 +00:00
|
|
|
bool CodeDetector::DetectAndAdjustMusicOptions( GameController controller )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
2006-09-30 05:47:22 +00:00
|
|
|
PlayerNumber pn = INPUTMAPPER->ControllerToPlayerNumber( controller );
|
2002-09-03 00:22:12 +00:00
|
|
|
|
2003-04-13 06:29:02 +00:00
|
|
|
for( int c=CODE_MIRROR; c<=CODE_CANCEL_ALL; c++ )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
|
|
|
|
Code code = (Code)c;
|
|
|
|
|
|
2006-08-05 02:38:05 +00:00
|
|
|
PlayerOptions po = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetPreferred();
|
2004-12-20 06:25:59 +00:00
|
|
|
|
2003-04-13 04:50:08 +00:00
|
|
|
if( EnteredCode(controller,code) )
|
2002-09-03 00:22:12 +00:00
|
|
|
{
|
|
|
|
|
switch( code )
|
|
|
|
|
{
|
2006-03-01 07:31:20 +00:00
|
|
|
case CODE_MIRROR: po.ToggleOneTurn( PlayerOptions::TURN_MIRROR ); break;
|
|
|
|
|
case CODE_LEFT: po.ToggleOneTurn( PlayerOptions::TURN_LEFT ); break;
|
|
|
|
|
case CODE_RIGHT: po.ToggleOneTurn( PlayerOptions::TURN_RIGHT ); break;
|
|
|
|
|
case CODE_SHUFFLE: po.ToggleOneTurn( PlayerOptions::TURN_SHUFFLE ); break;
|
|
|
|
|
case CODE_SUPER_SHUFFLE: po.ToggleOneTurn( PlayerOptions::TURN_SUPER_SHUFFLE ); break;
|
|
|
|
|
case CODE_NEXT_TRANSFORM: po.NextTransform(); break;
|
2004-12-20 06:25:59 +00:00
|
|
|
case CODE_NEXT_SCROLL_SPEED: INCREMENT_SCROLL_SPEED( po.m_fScrollSpeed ); break;
|
2005-10-27 07:51:37 +00:00
|
|
|
case CODE_PREVIOUS_SCROLL_SPEED: DECREMENT_SCROLL_SPEED( po.m_fScrollSpeed ); break;
|
2006-03-01 07:31:20 +00:00
|
|
|
case CODE_NEXT_ACCEL: po.NextAccel(); break;
|
|
|
|
|
case CODE_NEXT_EFFECT: po.NextEffect(); break;
|
|
|
|
|
case CODE_NEXT_APPEARANCE: po.NextAppearance(); break;
|
|
|
|
|
case CODE_NEXT_TURN: po.NextTurn(); break;
|
|
|
|
|
case CODE_REVERSE: po.NextScroll(); break;
|
|
|
|
|
case CODE_HOLDS: TOGGLE( po.m_bTransforms[PlayerOptions::TRANSFORM_NOHOLDS], true, false ); break;
|
|
|
|
|
case CODE_MINES: TOGGLE( po.m_bTransforms[PlayerOptions::TRANSFORM_NOMINES], true, false ); break;
|
|
|
|
|
case CODE_DARK: FLOAT_TOGGLE( po.m_fDark ); break;
|
|
|
|
|
case CODE_CANCEL_ALL: GAMESTATE->GetDefaultPlayerOptions( po ); break;
|
2006-08-05 02:38:05 +00:00
|
|
|
case CODE_HIDDEN:
|
|
|
|
|
ZERO(po.m_fAppearances);
|
|
|
|
|
po.m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN] = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CODE_RANDOMVANISH:
|
|
|
|
|
ZERO(po.m_fAppearances);
|
|
|
|
|
po.m_fAppearances[PlayerOptions::APPEARANCE_RANDOMVANISH] = 1;
|
|
|
|
|
break;
|
2005-10-27 07:51:37 +00:00
|
|
|
default: break;
|
2002-09-03 00:22:12 +00:00
|
|
|
}
|
2006-08-05 02:38:05 +00:00
|
|
|
|
2006-08-05 04:47:01 +00:00
|
|
|
GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.Assign( ModsLevel_Preferred, po );
|
2006-08-05 02:38:05 +00:00
|
|
|
|
|
|
|
|
|
2002-09-03 00:22:12 +00:00
|
|
|
return true; // don't check any more
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2004-05-31 22:42:12 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* (c) 2001-2004 Chris Danford
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
|
|
|
|
* whom the Software is furnished to do so, provided that the above
|
|
|
|
|
* copyright notice(s) and this permission notice appear in all copies of
|
|
|
|
|
* the Software and that both the above copyright notice(s) and this
|
|
|
|
|
* permission notice appear in supporting documentation.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
|
|
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
|
|
|
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
|
|
|
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
|
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
*/
|