/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | * * -----------------------------------------------------------| \\._.// * * SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) * * -----------------------------------------------------------| ).:.( * * SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} * * -----------------------------------------------------------| / ' ' \ * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~* * Scryn, Swordbearer, Rennard, Tricops, and Gorog. | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. * ****************************************************************************/ // commands.cpp #include "stdafx.h" #include "smaug.h" #include "Smaugx.h" #include "commands.h" #include "SmaugFiles.h" void CCmdType::SetName (char* n) { // make sure the name is all lowercase for (int x = 0; n [x] != '\0'; ++x) n [x] = LOWER (n [x]); m_pName = n; } #if defined (KEY) #undef KEY #endif #define KEY(literal,field,value) \ if (!str_cmp (word, literal)) { \ field = value; \ fMatch = TRUE; \ break; \ } BOOL CCmdType::Read (FILE *fp) { char *word, *pLine; BOOL fMatch; for (;;) { fMatch = FALSE; if (! feof (fp)) { pLine = fread_line (fp); word = ParseWord (pLine); } else word = "End"; switch (UPPER (word [0])) { case '*': fMatch = TRUE; break; case 'C': KEY ("Code", do_fun, skill_function (ParseWord (pLine))); break; case 'E': if (! str_cmp (word, "End")) { if (! m_pName) { bug ("CCmdType::Read: Name not found"); return FALSE; } if (! do_fun) { bug ("CCmdType::Read: Function not found"); return FALSE; } return TRUE; } break; case 'L': KEY ("Level", level, ParseNumber (pLine)); KEY ("Log", log, ParseNumber (pLine)); break; case 'N': KEY ("Name", m_pName, ParseStringNohash (pLine, fp)); break; case 'P': KEY ("Position", position, ParseNumber (pLine)); break; } if (!fMatch) bug ("CCmdType::Read: no match: %s", word); } ASSERT (0); return FALSE; // should never get here } void CCmdType::Write (FILE* fp) { fprintf (fp, "#COMMAND\n"); fprintf (fp, "Name %s~\n", m_pName); fprintf (fp, "Code %s\n", skill_name (do_fun)); fprintf (fp, "Position %d\n", position); fprintf (fp, "Level %d\n", level); fprintf (fp, "Log %d\n", log); fprintf (fp, "End\n\n"); } CCmdType *CCommandTable::Find (char *command) { CCmdType *cmd; int hash = GetHash (command [0]); for (cmd = m_ct [hash]; cmd; cmd = cmd->GetNext ()) if (! str_prefix (command, cmd->GetName ())) return cmd; return NULL; } // Remove a command from it's hash index -Thoric void CCommandTable::Unlink (CCmdType *command) { CCmdType *tmp, *tmp_next; if (!command) { bug ("Unlink_command NULL command", 0); return; } int hash = GetHash (command->GetName ()[0]); if (command == (tmp = GetCommand (hash))) { m_ct [hash] = tmp->GetNext (); return; } for (; tmp; tmp = tmp_next) { tmp_next = tmp->GetNext (); if (command == tmp_next) { tmp->SetNext (tmp_next->GetNext ()); return; } } } // Add a command to the command hash table -Thoric void CCommandTable::Add (CCmdType *command) { CCmdType *tmp, *prev; if (!command) { bug ("CCommandTable::Add: NULL command", 0); return; } if (!command->GetName ()) { bug ("CCommandTable::Add: NULL command->name", 0); return; } if (!command->do_fun) { bug ("CCommandTable::Add: NULL command->do_fun", 0); return; } int hash = GetHash (command->GetName ()[0]); if ((prev = tmp = GetCommand (hash)) == NULL) { command->SetNext (GetCommand (hash)); m_ct [hash] = command; return; } // add to the END of the list for (; tmp; tmp = tmp->GetNext ()) if (!tmp->GetNext ()) { tmp->SetNext (command); command->SetNext (NULL); } } void CCommandTable::Load () { FILE *fp; char *pLine; if ((fp = fopen (FileTable.GetName (SM_COMMAND_FILE), "r")) != NULL) { for (;;) { char letter; char *word; pLine = fread_line (fp); letter = *pLine++; if (letter == '*') continue; if (letter != '#') { bug ("CCommandTable::Load: # not found."); break; } word = ParseWord (pLine); if (! str_cmp (word, "COMMAND")) { CCmdType *pCmd = new CCmdType; if (pCmd->Read (fp)) then Add (pCmd); else delete pCmd; } else if (! str_cmp (word, "END")) break; else { bug ("CCommandTable::Load: bad section."); continue; } } fclose (fp); } else { bug ("Cannot open commands.dat"); ThrowSmaugException (SE_COMMAND); } } // Save the commands to disk void CCommandTable::Save () { FILE *fp; CCmdType *command; if ((fp=fopen (FileTable.GetName (SM_COMMAND_FILE), "w")) == NULL) { bug ("CCommandTable::Save: Cannot open commands.dat for writing", 0); perror (COMMAND_FILE); return; } for (int hash = 0; hash < MAX_COMMANDS; ++hash) { for (command = GetCommand (hash); command; command = command->GetNext ()) { command->Write (fp); } } fprintf (fp, "#END\n"); fclose (fp); } void CCommandTable::RemoveAll () { CCmdType *pNcmd, *pCmd; for (int hash = 0; hash < MAX_COMMANDS; ++hash) { pCmd = GetCommand (hash); while (pCmd) { pNcmd = pCmd->GetNext (); delete pCmd; pCmd = pNcmd; } } Empty (); }