// help.cpp
#include "stdafx.h"
#include "smaug.h"
#include "help.h"
// Adds a help page to the list if it is not a duplicate of an existing page.
// Page is insert-sorted by keyword. -Thoric
// (The reason for sorting is to keep do_hlist looking nice)
void CHelpList::Add (CHelpData *pHelp)
{
BOOL bFound = FALSE;
POSITION CurPos, pos = GetTailPosition ();
while (pos) {
CurPos = pos;
CHelpData &Htest = *(CHelpData*) GetPrev (pos);
if (Htest == *pHelp) {
bug ("add_help: duplicate: %s. Deleting.",
NCCP pHelp->GetKey ());
delete pHelp;
return;
}
if (Htest < *pHelp) {
InsertAfter (CurPos, pHelp);
bFound = TRUE;
break;
}
}
if (! bFound)
AddHead (pHelp);
}
BOOL CHelpData::operator== (CHelpData& in)
{
return m_Level == in.GetLevel () && ! str_cmp (m_pKey, in.m_pKey);
}
BOOL CHelpData::operator> (CHelpData& in)
{
char *k1 = m_pKey;
char *k2 = in.m_pKey;
while (*k1 == '\'' || *k1 == '\"')
++k1;
while (*k2 == '\'' || *k1 == '\"')
++k2;
int rv = stricmp (k1, k2);
if (rv > 0) then return TRUE;
if (! rv && m_Level > in.GetLevel ()) then return TRUE;
return FALSE;
}
BOOL CHelpData::operator< (CHelpData& in)
{
char *k1 = m_pKey;
char *k2 = in.m_pKey;
while (*k1 == '\'' || *k1 == '\"')
++k1;
while (*k2 == '\'' || *k1 == '\"')
++k2;
int rv = stricmp (k1, k2);
if (rv < 0) then return TRUE;
if (! rv && m_Level < in.GetLevel ()) then return TRUE;
return FALSE;
}
// Load a help section.
void LoadAllHelp (FILE *fp)
{
CHelpData *pHelp;
char *pLine;
for (;;) {
pLine = fread_line (fp);
pHelp = new CHelpData;
pHelp->SetLevel (ParseNumber (pLine));
pHelp->SetKey (ParseString (pLine, fp));
if (pHelp->IsLastKey ()) {
delete pHelp;
break;
}
pLine = fread_line (fp);
pHelp->SetText (ParseString (pLine, fp));
if (pHelp->IsEmpty ()) {
delete pHelp;
continue;
}
HelpList.Add (pHelp);
}
}
CHelpData::~CHelpData ()
{
STRFREE (m_pText);
STRFREE (m_pKey);
}
CHelpData *CHelpList::Find (const char* key, int level, int TrustLevel)
{
BOOL bFound = FALSE;
CHelpData *pHelp;
POSITION pos = GetHeadPosition ();
while (pos) {
pHelp = (CHelpData*) GetNext (pos);
if (str_cmp (pHelp->m_pKey, key) < 0) then break; // not found
if (is_name (key, pHelp->m_pKey)) {
// if found but player TrustLevel too low...
if (pHelp->GetLevel () > TrustLevel) then break;
if (level == -2 || pHelp->GetLevel () == level) {
bFound = TRUE;
break;
}
}
}
return bFound ? pHelp : NULL;
}
void CHelpList::Remove (CHelpData* pHelp)
{
if (pHelp) {
POSITION pos = CPtrList::Find (pHelp);
RemoveAt (pos);
delete pHelp;
}
}
void CHelpList::RemoveAll ()
{
while (! IsEmpty ())
delete (CHelpData*) RemoveTail ();
CPtrList::RemoveAll ();
}