Revamped the unlock system. Currently it supports the following methods:

DP - dance points, what Miryokuteki had in place
AP - arcade points, like MAX2 arcade
SP - song points, like MAX2 home (though I don't know the exact system)
CS - clear stages, like 5th home

Somewhat strewn but not supported yet:
!! - Toastys seen
EC - cleared extra stages
EF - fail extra stage (don't quote me on these two yet, I haven't tried them yet)
RO - roulette (theres fifteen roulette slots, but its not implemented yet)

Also updated the INI to store values for these means of unlocking.  The system
still isn't "optimized" yet, though.
This commit is contained in:
Andrew Wong
2003-07-07 10:22:53 +00:00
parent 7622dc7282
commit d27a25e472
7 changed files with 336 additions and 54 deletions
+200 -45
View File
@@ -17,10 +17,11 @@
#include "UnlockSystem.h"
#include <fstream>
#include <map>
using namespace std;
#define POINTS_ACCUMULATED_BEFORE_LAST_ROUND // Load from file here
#include "stdio.h"
// #define POINTS_ACCUMULATED_BEFORE_LAST_ROUND // Load from file here
UnlockSystem::UnlockSystem()
{
@@ -30,97 +31,247 @@ UnlockSystem::UnlockSystem()
bool UnlockSystem::SongIsLocked( CString sSongName )
{
sSongName.MakeUpper(); //Avoid case-sensitive problems
for( unsigned i=0; i<m_SongEntries.size(); i++ )
{
if( sSongName == m_SongEntries[i].m_sSongName )
{
if( PREFSMAN->m_fDancePointsAccumulated >= m_SongEntries[i].m_fDancePointsRequired ) { LOG->Trace(" *This song is UNLOCKED"); return false; }
else { LOG->Trace(" *This song is LOCKED"); return true; };
}
else { continue; };
}
LOG->Trace( " *This song is UNLOCKED (wasn't locked in the first place)" );
for(int i = 0; i < m_SongEntries.size(); i++)
if (m_SongEntries[i].m_sSongName == sSongName)
return m_SongEntries[i].isLocked;
return false;
}
bool UnlockSystem::SongIsRoulette( CString sSongName )
{
sSongName.MakeUpper(); //Avoid case-sensitive problems
for(int i = 0; i < m_SongEntries.size(); i++)
if (m_SongEntries[i].m_sSongName == sSongName)
return (m_SongEntries[i].m_iRouletteSeed != 0);
return false;
}
operator == (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName == b.m_sSongName;
}
operator != (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName != b.m_sSongName;
}
operator >= (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName >= b.m_sSongName;
}
operator <= (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName <= b.m_sSongName;
}
operator > (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName > b.m_sSongName;
}
operator < (const SongEntry &a, const SongEntry &b)
{
return a.m_sSongName <= b.m_sSongName;
}
SongEntry::SongEntry()
{
m_fDancePointsRequired = 0;
m_fArcadePointsRequired = 0;
m_fSongPointsRequired = 0;
m_fExtraStagesCleared = 0;
m_fExtraStagesFailed = 0;
m_fStagesCleared = 0;
m_fToastysSeen = 0;
m_iRouletteSeed = 0;
isLocked = true;
}
static int CompareSongEntries(const SongEntry &se1, const SongEntry &se2)
{
return se1.m_fDancePointsRequired < se2.m_fDancePointsRequired;
return se1.m_sSongName < se2.m_sSongName;
}
void UnlockSystem::SortSongEntriesArray()
bool UnlockSystem::ParseRow(CString text, CString &type, float &qty,
CString &songname)
{
sort( m_SongEntries.begin(), m_SongEntries.end(), CompareSongEntries );
int pos = -1;
int end;
char unlock_type[4];
char qty_text[20];
while (text[pos] != '|' && pos < text[pos] != '\0')
{
pos++;
if (text[pos] == '[') text[pos] = ' ';
if (text[pos] == ']') text[pos] = ' ';;
if (text[pos] == '|')
{
end = pos;
text[pos] = ' ';
}
}
songname = text.Right(text.GetLength() - 1 - end);
sscanf(text, "%s %s|", unlock_type, qty_text);
type = unlock_type;
qty = atof(qty_text);
LOG->Trace( "UnlockSystem Entry %s", text.c_str() );
LOG->Trace( " Title %s", songname.c_str() );
LOG->Trace( " Type %s", type.c_str() );
LOG->Trace( " Value %s", qty_text );
return true;
}
bool SongEntry::updateLocked()
{
if (!isLocked) return true; // if its already true
if (m_fArcadePointsRequired != 0)
isLocked = (PREFSMAN->m_fArcadePointsAccumulated < m_fArcadePointsRequired);
if (m_fDancePointsRequired != 0)
isLocked = (PREFSMAN->m_fDancePointsAccumulated < m_fDancePointsRequired);
if (m_fSongPointsRequired != 0)
isLocked = (PREFSMAN->m_fSongPointsAccumulated < m_fSongPointsRequired);
if (m_fExtraStagesCleared != 0)
isLocked = (PREFSMAN->m_fExtraStagesCleared < m_fExtraStagesCleared);
if (m_fExtraStagesFailed != 0)
isLocked = (PREFSMAN->m_fExtraStagesFailed < m_fExtraStagesFailed);
if (m_fStagesCleared != 0)
isLocked = (PREFSMAN->m_fTotalStagesCleared < m_fStagesCleared);
if (m_fToastysSeen != 0)
isLocked = (PREFSMAN->m_fTotalToastysSeen < m_fToastysSeen);
if (m_iRouletteSeed != 0)
isLocked = (PREFSMAN->m_RouletteSeeds[m_iRouletteSeed] == '0');
return !isLocked;
}
bool UnlockSystem::LoadFromDATFile( CString sPath )
{
LOG->Trace( "UnlockSystem::LoadFromDATFile(%s)", sPath.c_str() );
ifstream input(sPath);
if(input.bad())
ifstream input;
input.open(sPath);
if(input.fail())
{
LOG->Warn( "Error opening file '%s' for reading.", sPath.c_str() );
return false;
}
string line;
m_SongEntries.clear();
char line[256];
CString unlock_type, song_title;
float datavalue;
while(input.good() && getline(input, line))
// m_SongEntries.clear();
while(input.getline(line, 255))
{
if(!line.compare(0, 2, "//")) //Check for comments
if(line[0] == '/' && line[1] == '/') //Check for comments
continue;
/* "[data1] data2". Ignore whitespace at the beginning of the line. */
static Regex x("^ *\\[([^]]+)\\] *(.*)$");
vector<CString> matches;
if(!x.Compare(line, matches))
if (!ParseRow(line, unlock_type, datavalue, song_title))
continue;
SongEntry current;
song_title.MakeUpper(); //Avoid case-sensitive problems
current.m_sSongName = song_title;
CString &sValueName = matches[0];
CString &sValueData = matches[1];
StripCrnl(sValueData);
if (unlock_type == "AP")
{
current.m_fArcadePointsRequired = datavalue;
current.isLocked = (PREFSMAN->m_fArcadePointsAccumulated < datavalue);
}
if (unlock_type == "DP")
{
current.m_fDancePointsRequired = datavalue;
current.isLocked = (PREFSMAN->m_fDancePointsAccumulated < datavalue);
}
if (unlock_type == "SP")
{
current.m_fSongPointsRequired = datavalue;
current.isLocked = (PREFSMAN->m_fSongPointsAccumulated < datavalue);
}
if (unlock_type == "EC")
{
current.m_fExtraStagesCleared = datavalue;
current.isLocked = (PREFSMAN->m_fExtraStagesCleared < datavalue);
}
if (unlock_type == "EF")
{
current.m_fExtraStagesFailed = datavalue;
current.isLocked = (PREFSMAN->m_fExtraStagesFailed < datavalue);
}
if (unlock_type == "CS")
{
current.m_fStagesCleared = datavalue;
current.isLocked = (PREFSMAN->m_fTotalStagesCleared < datavalue);
}
if (unlock_type == "!!")
{
current.m_fToastysSeen = datavalue;
current.isLocked = (PREFSMAN->m_fTotalToastysSeen < datavalue);
}
if (unlock_type == "RO")
{
current.m_iRouletteSeed = (int)datavalue;
current.isLocked = (PREFSMAN->m_fArcadePointsAccumulated < datavalue);
}
// Handle our data
if( 0==stricmp(sValueName,"DP") ) // This means the DancePoints value is coming up
{
float DP;
CString SongName;
DP = (float)atof( sValueData.Left(sValueData.Find("|",1)) );
SongName = (CString)sValueData.Right( sValueData.GetLength() - (sValueData.Find("|",1)+1) );
SongName.MakeUpper(); // Avoid case-sensitive problems
SongEntry SE;
SE.m_fDancePointsRequired = DP;
SE.m_sSongName = SongName.c_str();
m_SongEntries.push_back( SE );
continue;
}
m_SongEntries.push_back(current);
}
// sort list so we can make use of binary searching
sort( m_SongEntries.begin(), m_SongEntries.end(), CompareSongEntries );
for(int i=0; i < m_SongEntries.size(); i++)
LOG->Trace( "UnlockSystem entry: %s", m_SongEntries[i].m_sSongName.c_str() );
return true;
}
bool SongEntry::SelectableWheel()
{
return (!isLocked); // cached
}
bool SongEntry::SelectableRoulette()
{
if (!isLocked) return true;
if (m_iRouletteSeed != 0) return true;
return false;
}
float UnlockSystem::NumPointsUntilNextUnlock()
{
float fSmallestPoints;
fSmallestPoints = 4000000000; // or an arbitrarily large value
for( unsigned a=0; a<m_SongEntries.size(); a++ )
for( unsigned a=0; a<100; a++ )
{
// old line: if( m_SongEntries[a].m_fDancePointsRequired >= fSmallestPoints )
// new: it makes sure the number of points to the song is positive, AND it is less than
@@ -133,4 +284,8 @@ float UnlockSystem::NumPointsUntilNextUnlock()
float fResults = (fSmallestPoints - PREFSMAN->m_fDancePointsAccumulated);
return fResults;
return 0;
}