www.pudn.com > uoth_src.zip > Character.cpp
//----------------------------------------------------------------------------- // // @doc // // @module Character.cpp - Character information class | // // This module contains the Character information class. // // Copyright (c) 2002 - Descartes Systems Sciences, Inc. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // 2. Neither the name of Descartes Systems Sciences, Inc nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // @end // // $History: Cnf.cpp $ // //----------------------------------------------------------------------------- #include "stdafx.h" #include "Character.h" #include "DataParser.h" #include "uoth.h" // // Debug NEW // #if defined (_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // // Class globals // CAtlArrayCCharacter::gm_vCharacters; // // Externals // extern HWND g_hWndMain; extern TCHAR g_szSettingsFile []; // // Locals // static int s_nCurrent = -1; //----------------------------------------------------------------------------- // // @mfunc constructor. // // @rdesc None. // //----------------------------------------------------------------------------- CCharacter::CCharacter () { Init (true); } //----------------------------------------------------------------------------- // // @mfunc destructor. // // @rdesc None. // //----------------------------------------------------------------------------- CCharacter::~CCharacter () { } //----------------------------------------------------------------------------- // // @mfunc Initialize the object // // @parm bool | fConstruct | If true, we are being called from the // the constructor // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::Init (bool fConstruct) { m_strName .Empty (); m_vMapCounts .RemoveAll (); } //----------------------------------------------------------------------------- // // @mfunc Begin the processing of a Character // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char ** | papszAttrs | Attributes // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::OnStart (CDataParser *pParser, const XML_Char **papszAttrs) { // // No attributes are allowed // if (papszAttrs [0] != NULL) { pParser ->SetError (IDS_ERR_XML_NO_ATTRS); return; } // // Initialize the Character // Init (false); // // Move to the new state // pParser ->SetState (CDataParser::InCharacter); return; } //----------------------------------------------------------------------------- // // @mfunc Begin the processing of an XML element // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char * | pszName | Name of the element // // @parm const XML_Char ** | papszAttrs | Attributes // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::OnStartElement (CDataParser *pParser, const XML_Char *pszName, const XML_Char **papszAttrs) { // // Get the element // _Element nElement = GetElement (pszName); if (nElement == Unknown) { pParser ->SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } // // If this is a map count // if (nElement == MapCounts) { // // The only allowed attribute is Index and // it is required // if (papszAttrs [0] == NULL || strcmp (papszAttrs [0], "Index") != 0 || papszAttrs [2] != NULL) { pParser ->SetError (IDS_ERR_XML_ONLY_INDEX); return; } // // Get the index number // int nIndex = atol (papszAttrs [1]); // // Validate the treasure range // if (nIndex <= 0 || nIndex > CTreasure::Max_Treasure) { pParser ->SetError (IDS_ERR_XML_INDEX_RANGE); return; } // // Save the index // pParser ->m_nMapIndex = nIndex; } // // Otherwise // else { // // No attributes are allowed // if (papszAttrs [0] != NULL) { pParser ->SetError (IDS_ERR_XML_NO_ATTRS); return; } } return; } //----------------------------------------------------------------------------- // // @mfunc End an XML element // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char * | pszName | Name of the element // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::OnEndElement (CDataParser *pParser, const XML_Char *pszName) { // // Get the element // _Element nElement = GetElement (pszName); if (nElement == Unknown) { pParser ->SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } // // Switch based on the element // switch (nElement) { // // If we are ending the Character // case Character: pParser ->SetState (CDataParser::InData); gm_vCharacters .Add (*this); break; // // If this is the name // case Name: m_strName = pParser ->GetText (false); break; // // If this is the map counts // case MapCounts: { CMapCounts mc; mc .m_nIndex = pParser ->m_nMapIndex; XML_Char *psz = pParser ->GetText (true); int i = 0; while (psz && *psz && i < Max_Level) { XML_Char *pszComma = strchr (psz, ','); if (pszComma) *pszComma++ = 0; mc .m_anCounts [i++] = atol (psz); psz = pszComma; } while (i < Max_Level) mc .m_anCounts [i++] = 0; m_vMapCounts .Add (mc); } break; } return; } //----------------------------------------------------------------------------- // // @mfunc Get the element number // // @parm const XML_Char * | pszName | Element name // // @rdesc Element id. // //----------------------------------------------------------------------------- CCharacter::_Element CCharacter::GetElement (const XML_Char *pszName) { if (stricmp (pszName, "Character") == 0) return Character; else if (stricmp (pszName, "Name") == 0) return Name; else if (stricmp (pszName, "MapCounts") == 0) return MapCounts; else return Unknown; } //----------------------------------------------------------------------------- // // @mfunc Locate a map count for the given treasure // // @parm int | nIndex | Treasure index // // @rdesc Pointer to the map count or NULL if not found // //----------------------------------------------------------------------------- CMapCounts *CCharacter::FindMapCounts (int nIndex) { for (int imc = 0; imc < m_vMapCounts .GetCount (); ++imc) { if (m_vMapCounts [imc] .m_nIndex == nIndex) return &m_vMapCounts [imc]; } return NULL; } //----------------------------------------------------------------------------- // // @mfunc Locate a character // // @parm LPCTSTR | pszName | Name of the character // // @rdesc Pointer to the character or NULL if not found // //----------------------------------------------------------------------------- CCharacter *CCharacter::Find (LPCTSTR pszName) { for (int ic = 0; ic < gm_vCharacters .GetCount (); ++ic) { if (_tcsicmp (gm_vCharacters [ic] .m_strName, pszName) == 0) return &gm_vCharacters [ic]; } return NULL; } //----------------------------------------------------------------------------- // // @mfunc Add a character // // @parm LPCTSTR | pszName | Name of the character // // @rdesc Pointer to the character // //----------------------------------------------------------------------------- CCharacter *CCharacter::Add (LPCTSTR pszName) { // // Try to find the character // CCharacter *pCharacter = Find (pszName); if (pCharacter != NULL) return pCharacter; // // Create a new character // CCharacter c; c .m_strName = pszName; gm_vCharacters .Add (c); pCharacter = &gm_vCharacters [gm_vCharacters .GetCount () - 1]; return pCharacter; } //----------------------------------------------------------------------------- // // @mfunc Adjust teh count of a treasure // // @parm int | nTreasure | Treasure number // // @parm int | nLevel | Treasure level // // @parm bool | fAdd | If true, we are adding // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::AdjustCount (int nTreasure, int nLevel, bool fAdd) { // // Locate the counts // CMapCounts *pCounts = FindMapCounts (nTreasure); // // If not found // if (pCounts == NULL) { if (fAdd) { CMapCounts c; memset (&c, 0, sizeof (c)); c .m_nIndex = nTreasure; c .m_anCounts [nLevel - 1] = 1; m_vMapCounts .Add (c); } } // // If found // else { if (fAdd) { pCounts ->m_anCounts [nLevel - 1]++; } else if (pCounts ->m_anCounts [nLevel - 1] > 0) { pCounts ->m_anCounts [nLevel - 1]--; } } // // Reset the has map // ApplyFilter (); } //----------------------------------------------------------------------------- // // @mfunc Write to a stream // // @parm FILE * | fp | Output file // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::Write (FILE *fp) { fprintf (fp, "\t \n"); fprintf (fp, "\t\t \n"); return; } //----------------------------------------------------------------------------- // // @mfunc Get the max level for this count // // @parm CMapCounts * | pCounts | Pointer to the map counts structure // // @rdesc Index of the max level or zero for none // //----------------------------------------------------------------------------- int CCharacter::GetMaxLevel (CMapCounts *pCounts) { int nMax = 0; for (int i = 0; i < Max_Level; i++) { if (pCounts ->m_anCounts [i] > 0) nMax = i + 1; } return nMax; } //----------------------------------------------------------------------------- // // @mfunc Return the current character // // @rdesc Pointer to the current character or NULL if there is none // //----------------------------------------------------------------------------- CCharacter *CCharacter::GetCurrent () { if (s_nCurrent >= 0) return &gm_vCharacters [s_nCurrent]; else return NULL; } //----------------------------------------------------------------------------- // // @mfunc Set the current character // // @parm CCharacter * | pCharacter | Pointer to the character // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::SetCurrent (CCharacter *pCharacter) { // // Set the character // s_nCurrent = pCharacter - &gm_vCharacters [0]; // // Reset the has maps // ApplyFilter (); // // Save the setting // ::WritePrivateProfileString (PROFILE_SETTINGS, PROFILE_CHARACTER, pCharacter ? (LPCTSTR) pCharacter ->m_strName : _T ( ""), g_szSettingsFile); return; } //----------------------------------------------------------------------------- // // @mfunc Get the default character from the profile // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::GetDefaultCurrent () { // // Get the current character // TCHAR szText [256]; ::GetPrivateProfileString (PROFILE_SETTINGS, PROFILE_CHARACTER, _T ( ""), szText, _countof (szText), g_szSettingsFile); szText [_countof (szText) - 1] = 0; // // Locate the character // CCharacter *pCharacter = Find (szText); // // Based on the results of the find, select the default // if (pCharacter == NULL) { if (gm_vCharacters .GetCount () > 0) s_nCurrent = 0; else s_nCurrent = -1; } else s_nCurrent = pCharacter - &gm_vCharacters [0]; ApplyFilter (); } //----------------------------------------------------------------------------- // // @mfunc Delete a character // // @parm CCharacter * | pCharacter | Character to delete. This address // must be within the array of characters. // // @rdesc None. // //----------------------------------------------------------------------------- void CCharacter::Delete (CCharacter *pCharacter) { // // Adjust the current index // int nDelete = pCharacter - &gm_vCharacters [0]; if (s_nCurrent < nDelete) ; else if (s_nCurrent == nDelete) s_nCurrent = -1; else s_nCurrent--; // // Delete the character // gm_vCharacters .RemoveAt (nDelete); // // Update the current // SetCurrent (GetCurrent ()); }%s \n", (LPCTSTR) m_strName); for (int imc = 0; imc < m_vMapCounts .GetCount (); ++imc) { CMapCounts *pMapCounts = &m_vMapCounts [imc]; int nMax = GetMaxLevel (pMapCounts); if (nMax > 0) { fprintf (fp, "\t\t", pMapCounts ->m_nIndex); for (int i = 0; i < nMax; i++) { if (i != 0) fputc (',', fp); fprintf (fp, "%d", pMapCounts ->m_anCounts [i]); } fprintf (fp, " \n"); } } fprintf (fp, "\t