/* ** AreaEditor - a program for editing SMAUG and ROM area files. ** Author: Nick Gammon ** http://www.gammon.com.au/ ** See Copyright Notice at the end of AreaEditor.h */ #include "stdafx.h" #include "AreaEditor.h" #include "MainFrm.h" #include "AreaEditorDoc.h" // helper routine for turning descriptions into one long sequence static CString FixUpDescription (const CString strOldText) { CString strText = strOldText; CString strNewText; int iPos; while ((iPos = strText.Find (ENDLINE)) != -1) { strNewText = strText.Left (iPos); strNewText += ' '; strNewText += strText.Mid (iPos + strlen (ENDLINE)); strText = strNewText; } // end of finding an ENDLINE sequence // get rid of opening braces while ((iPos = strText.Find ('{')) != -1) strText.SetAt (iPos, '('); // get rid of closing braces while ((iPos = strText.Find ('}')) != -1) strText.SetAt (iPos, ')'); strNewText = strText; // surround text in braces - this will "escape out" characters like a comma strText = '{'; strText += strNewText; strText += '}'; return strText; } // end of FixUpDescription static char * dir_mushname [11] = { "North;n", "East;e", "South;s", "West;w", "Up;u", "Down;d", "Northeast;ne", "Northwest;nw", "Southeast;se", "Southwest;sw", "" }; void CAreaEditorDoc::OnFileExportMush() { CFileDialog dlg(FALSE, // FALSE for FileSave "txt", // default extension "mushcode.txt", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, "Text files (*.txt)|*.txt||", NULL); dlg.m_ofn.lpstrTitle = "MUSHcode file"; if (dlg.DoModal() != IDOK) return; POSITION RoomPos; POSITION ExitPos; int i; int iRoomCount = 0, iExitCount = 0, iMobCount = 0, iObjectCount = 0; try { CFile f (dlg.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive); CArchive ar (&f, CArchive::store); // create a placeholder for vnum # to db # translations ar.WriteString ("think --------" ENDLINE); ar.WriteString ("think Creating vnum# to db# placeholder ..." ENDLINE); ar.WriteString ("think --------" ENDLINE); ar.WriteString ("@destroy DBHOLDER" ENDLINE); // delete old one ar.WriteString ("@destroy DBHOLDER" ENDLINE); // make it really go ar.WriteString ("@create DBHOLDER" ENDLINE); // create new one CRoom * room; /* ************************************************************************** Create rooms ************************************************************************** */ ar.WriteString ("think --------" ENDLINE); ar.WriteString (CFormat ("think Generating %i rooms and room descriptions ..." ENDLINE, m_RoomList.GetCount ())); ar.WriteString ("think --------" ENDLINE); for (RoomPos = m_RoomList.GetHeadPosition (); RoomPos; ) { room = m_RoomList.GetNext (RoomPos); // create the room (dig it) ar.WriteString (CFormat ("@set DBHOLDER=room%i:[dig(%s)]" ENDLINE, room->vnum, (LPCTSTR) FixUpDescription (room->name) )); iRoomCount++; // if it has a description, set it if (!room->description.IsEmpty ()) ar.WriteString (CFormat ("@describe xget(DBHOLDER, room%i)=%s" ENDLINE, room->vnum, (LPCTSTR) FixUpDescription (room->description) )); } // end of each room /* ************************************************************************** Create exits to link the rooms ************************************************************************** */ ar.WriteString ("think --------" ENDLINE); ar.WriteString ("think Creating exits and linking them to rooms ..." ENDLINE); ar.WriteString ("think --------" ENDLINE); for (RoomPos = m_RoomList.GetHeadPosition (); RoomPos; ) { room = m_RoomList.GetNext (RoomPos); i = 1; for (ExitPos = room->exitlist.GetHeadPosition (); ExitPos; i++) { CExit * exit = room->exitlist.GetNext (ExitPos); CRoom * exitroom; CString strExitName; CString strExitDirection; CString strThisName; strExitDirection = dir_mushname [exit->vdir]; if (strExitDirection.IsEmpty ()) strExitDirection = exit->keyword; // for "somewhere" exits if (exitroom = get_room_index (exit->vnum)) { strExitName = exitroom->name; strThisName = room->name; // create the exit (open it) ar.WriteString (CFormat ("@set DBHOLDER=room%iexit%i:[open(%s, xget(DBHOLDER, room%i))]" ENDLINE, room->vnum, i, (LPCTSTR) strExitDirection, exit->vnum )); iExitCount++; // the exit's description will be the name of the room it leads to ar.WriteString (CFormat ("@describe xget(DBHOLDER, room%iexit%i)=%s" ENDLINE, room->vnum, i, (LPCTSTR) FixUpDescription (strExitName) )); // teleport the exit to its appropriate room ar.WriteString (CFormat ("@teleport xget(DBHOLDER, room%iexit%i)=xget(DBHOLDER, room%i)" ENDLINE, room->vnum, i, room->vnum )); /* ************************************************************************** Do @succ, @osucc, and @odrop messages ************************************************************************** */ // make first char of direction lower case if (!strExitDirection.IsEmpty ()) { strExitDirection.SetAt (0, LOWER(strExitDirection[0])); // truncate direction to remove anything after the semicolon int iSemicolon; if ((iSemicolon = strExitDirection.Find (';')) != -1) strExitDirection = strExitDirection.Left (iSemicolon); } // ditto for destination room if (!strExitName.IsEmpty ()) strExitName.SetAt (0, LOWER(strExitName[0])); // and this room if (!strThisName.IsEmpty ()) strThisName.SetAt (0, LOWER(strThisName[0])); // do the @succ message ar.WriteString (CFormat ("@succ xget(DBHOLDER, room%iexit%i)=%s" ENDLINE, room->vnum, i, (LPCTSTR) FixUpDescription (CFormat ("You go %s to %s.", (LPCTSTR) strExitDirection, (LPCTSTR) strExitName)) )); // do the @osucc message ar.WriteString (CFormat ("@osucc xget(DBHOLDER, room%iexit%i)=%s" ENDLINE, room->vnum, i, (LPCTSTR) FixUpDescription (CFormat ("goes %s to %s.", (LPCTSTR) strExitDirection, (LPCTSTR) strExitName)) )); // do the @odrop message ar.WriteString (CFormat ("@odrop xget(DBHOLDER, room%iexit%i)=%s" ENDLINE, room->vnum, i, (LPCTSTR) FixUpDescription (CFormat ("enters from %s.", (LPCTSTR) strThisName)) )); } // end of exited-to room being in this area } // end of processing each exit } // end of each room /* ************************************************************************** Add mobs and objects to rooms ************************************************************************** */ ar.WriteString ("think --------" ENDLINE); ar.WriteString ("think Loading mobs and objects ..." ENDLINE); ar.WriteString ("think --------" ENDLINE); CMobile * mob; CMUDObject * object; i = 1; for (POSITION resetPos = m_ResetList.GetHeadPosition (); resetPos; i++) { CReset * reset = m_ResetList.GetNext (resetPos); switch (reset->command) { case 'M': // load mobile if ((room = get_room_index (reset->arg3)) == NULL) break; // room not found if ((mob = get_mob_index( reset->arg1)) == NULL) break; // mob not found ar.WriteString (CFormat ("@set DBHOLDER=reset%i:[create(%s, 10)]" ENDLINE, i, (LPCTSTR) FixUpDescription (mob->long_descr) )); iMobCount++; // if it has a description, set it if (!mob->description.IsEmpty ()) ar.WriteString (CFormat ("@describe xget(DBHOLDER, reset%i)=%s" ENDLINE, i, (LPCTSTR) FixUpDescription (mob->description) )); // lock it to itself ar.WriteString (CFormat ("@lock xget(DBHOLDER, reset%i)=xget(DBHOLDER, reset%i)" ENDLINE, i, i )); // teleport the mob to its appropriate room ar.WriteString (CFormat ("@teleport xget(DBHOLDER, reset%i)=xget(DBHOLDER, room%i)" ENDLINE, i, room->vnum )); break; case 'O': // load object if ((room = get_room_index (reset->arg3)) == NULL) break; // room not found if ((object = get_obj_index( reset->arg1)) == NULL) break; // object not found ar.WriteString (CFormat ("@set DBHOLDER=reset%i:[create(%s, 10)]" ENDLINE, i, (LPCTSTR) FixUpDescription (object->description) )); iObjectCount++; // if no extra description, just make the description the description if (object->extralist.IsEmpty ()) ar.WriteString (CFormat ("@describe xget(DBHOLDER, reset%i)=%s" ENDLINE, i, (LPCTSTR) FixUpDescription (object->description) )); else // we will assume that the first extra description is the object's description ar.WriteString (CFormat ("@describe xget(DBHOLDER, reset%i)=%s" ENDLINE, i, (LPCTSTR) FixUpDescription (object->extralist.GetHead ()->description) )); // lock it to itself ar.WriteString (CFormat ("@lock xget(DBHOLDER, reset%i)=xget(DBHOLDER, reset%i)" ENDLINE, i, i )); // teleport the object to its appropriate room ar.WriteString (CFormat ("@teleport xget(DBHOLDER, reset%i)=xget(DBHOLDER, room%i)" ENDLINE, i, room->vnum )); break; } // end of switch } // end of processing each reset /* ************************************************************************** All done ************************************************************************** */ ar.WriteString ("think --------" ENDLINE); ar.WriteString ("think Done." ENDLINE); ar.WriteString ("think --------" ENDLINE); ar.Close (); } catch (CException* e) { e->ReportError(); e->Delete(); return; } ::AfxMessageBox (CFormat ("Exported %i room%s, %i exit%s, %i mobile%s, %i object%s." ENDLINE ENDLINE "Please read file MUSHEXPORT.TXT before attempting to use this file.", PLURAL (iRoomCount), PLURAL (iExitCount), PLURAL (iMobCount), PLURAL (iObjectCount)), MB_ICONINFORMATION); } void CAreaEditorDoc::OnUpdateFileExportMush(CCmdUI* pCmdUI) { pCmdUI->Enable (!m_RoomList.IsEmpty ()); }