/* ** 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" #include "AreaEditorView.h" #include "RenumberDlg.h" #include "AreaLoadingProblems.h" #define FixupMobVnum(arg) FixupVnum (arg, pOldMobVnum, pNewMobVnum, iMobCount) #define FixupObjVnum(arg) FixupVnum (arg, pOldObjVnum, pNewObjVnum, iObjCount) #define FixupRoomVnum(arg) FixupVnum (arg, pOldRoomVnum, pNewRoomVnum, iRoomCount) bool CAreaEditorDoc::AreaRenumber (const t_renumbertype iRenumberType, const int iOldVnum, const int iNewVnum) { // vnums - low and high int obj_low_vnum = INT_MAX; int obj_hi_vnum = 0; int mob_low_vnum = INT_MAX; int mob_hi_vnum = 0; int room_low_vnum = INT_MAX; int room_hi_vnum = 0; // item counts int iMobCount = m_MobList.GetCount (); int iObjCount = m_ObjectList.GetCount (); int iRoomCount = m_RoomList.GetCount (); int iPrograms = 0; long iMilestone = 0; POSITION pos; POSITION mobPos; POSITION objPos; POSITION roomPos; CMobile * mob; CRoom * room; CMUDObject * obj; CMUDprogram * program; CString strMessage; CRenumberDlg dlg; dlg.m_iMobCount = iMobCount; dlg.m_iObjCount = iObjCount; dlg.m_iRoomCount = iRoomCount; // update mob vnum ranges for (mobPos = m_MobList.GetHeadPosition (); mobPos; ) { mob = m_MobList.GetNext (mobPos); if (mob->vnum > mob_hi_vnum) mob_hi_vnum = mob->vnum; if (mob->vnum < mob_low_vnum) mob_low_vnum = mob->vnum; iPrograms += mob->programlist.GetCount (); // count programs } // end of each mob if (mob_low_vnum == INT_MAX) mob_low_vnum = 0; // update obj vnum ranges for (objPos = m_ObjectList.GetHeadPosition (); objPos; ) { obj = m_ObjectList.GetNext (objPos); if (obj->vnum > obj_hi_vnum) obj_hi_vnum = obj->vnum; if (obj->vnum < obj_low_vnum) obj_low_vnum = obj->vnum; iPrograms += obj->programlist.GetCount (); // count programs } // end of each object if (obj_low_vnum == INT_MAX) obj_low_vnum = 0; // update room vnum ranges for (roomPos = m_RoomList.GetHeadPosition (); roomPos; ) { room = m_RoomList.GetNext (roomPos); if (room->vnum > room_hi_vnum) room_hi_vnum = room->vnum; if (room->vnum < room_low_vnum) room_low_vnum = room->vnum; iPrograms += room->programlist.GetCount (); // count programs } // end of each room if (room_low_vnum == INT_MAX) room_low_vnum = 0; dlg.m_iMobLowVnum = mob_low_vnum; dlg.m_iMobHighVnum = mob_hi_vnum; dlg.m_iObjLowVnum = obj_low_vnum; dlg.m_iObjHighVnum = obj_hi_vnum; dlg.m_iRoomLowVnum = room_low_vnum; dlg.m_iRoomHighVnum = room_hi_vnum; dlg.m_iNewLowMobVnum = mob_low_vnum; dlg.m_iNewLowObjVnum = obj_low_vnum; dlg.m_iNewLowRoomVnum = room_low_vnum; if (iRenumberType == eRenumberAll) { if (dlg.DoModal () != IDOK) return false; // check they actually want to renumber something if (dlg.m_iNewLowMobVnum == mob_low_vnum && dlg.m_iNewLowObjVnum == obj_low_vnum && dlg.m_iNewLowRoomVnum == room_low_vnum && !dlg.m_bMobCompact && !dlg.m_bObjCompact && !dlg.m_bRoomCompact) { ::AfxMessageBox ("No renumbering requested - all vnums the same", MB_ICONINFORMATION); return false; } // end of no renumber wanted } // end of renumber all // don't do it if we have not commands, socials or skills if (iPrograms) { if (App.m_CommandList.IsEmpty () || App.m_SocialList.IsEmpty () || App.m_SkillList.IsEmpty ()) { ::AfxMessageBox ("Your area has MUD programs, but you have not loaded all of the" " following files:" "\ncommands.dat, socials.dat and skills.dat." "\n\nRenumbering cannot proceed as MUD programs cannot be analysed", MB_ICONSTOP); return false; } // Just to be safe, check syntax in all programs, and only go ahead if no errors m_strErrorMessage.Empty (); m_nErrors = 0; Frame.CreateProgressBar ("Checking programs", iPrograms); // check mobs for (mobPos = m_MobList.GetHeadPosition (); mobPos; ) { mob = m_MobList.GetNext (mobPos); for (POSITION progPos = mob->programlist.GetHeadPosition (); progPos; ) { program = mob->programlist.GetNext (progPos); if (iMilestone++ % 10 == 0) Frame.UpdateProgressBar (iMilestone); // check program if (CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs)) Warning (mob, strMessage); } // end of each program } // end of each mob // check rooms for (roomPos = m_RoomList.GetHeadPosition (); roomPos; ) { room = m_RoomList.GetNext (roomPos); for (POSITION progPos = room->programlist.GetHeadPosition (); progPos; ) { program = room->programlist.GetNext (progPos); if (iMilestone++ % 10 == 0) Frame.UpdateProgressBar (iMilestone); // check program if (CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs)) Warning (room, strMessage); } // end of each program } // end of each room // check objects for (objPos = m_ObjectList.GetHeadPosition (); objPos; ) { obj = m_ObjectList.GetNext (objPos); for (POSITION progPos = obj->programlist.GetHeadPosition (); progPos; ) { program = obj->programlist.GetNext (progPos); if (iMilestone++ % 10 == 0) Frame.UpdateProgressBar (iMilestone); // check program if (CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs)) Warning (obj, strMessage); } // end of each program } // end of each obj Frame.RemoveProgressBar (); if (m_nErrors) { // MODELESS dialog here CAreaLoadingProblems * dlg = new CAreaLoadingProblems; dlg->m_strTitle = "Error(s) in programs - cannot renumber"; // set up dialog title dlg->m_strErrors = m_strErrorMessage; // what it says dlg->Create (ID_PROBLEMS_LOADING_AREA, NULL); // create it dlg->ShowWindow(SW_SHOW); // and, finally, show it - dialog will delete itself return false; } // end of errors in programs } // end of having at least one program somewhere int * pOldMobVnum = NULL; int * pNewMobVnum = NULL; int * pOldObjVnum = NULL; int * pNewObjVnum = NULL; int * pOldRoomVnum = NULL; int * pNewRoomVnum = NULL; int i; int iDifference; switch (iRenumberType) { case eRenumberAll: // deselect "area" view so that vnums get updated correctly if (m_leftview) m_leftview->GetTreeCtrl().Select (m_leftview->m_hdlTreeHelps, TVGN_CARET); // set up for new vnum ranges m_Area->obj_low_vnum = INT_MAX; m_Area->obj_hi_vnum = 0; m_Area->mob_low_vnum = INT_MAX; m_Area->mob_hi_vnum = 0; m_Area->room_low_vnum = INT_MAX; m_Area->room_hi_vnum = 0; // create arrays to hold the "from" and "to" vnums pOldMobVnum = new int [iMobCount]; pNewMobVnum = new int [iMobCount]; pOldObjVnum = new int [iObjCount]; pNewObjVnum = new int [iObjCount]; pOldRoomVnum = new int [iRoomCount]; pNewRoomVnum = new int [iRoomCount]; break; case eRenumberMob: iMobCount = 1; iObjCount = 0; iRoomCount = 0; pOldMobVnum = new int [1]; pNewMobVnum = new int [1]; pOldMobVnum [0] = iOldVnum; pNewMobVnum [0] = iNewVnum; break; case eRenumberObj: iMobCount = 0; iObjCount = 1; iRoomCount = 0; pOldObjVnum = new int [1]; pNewObjVnum = new int [1]; pOldObjVnum [0] = iOldVnum; pNewObjVnum [0] = iNewVnum; break; case eRenumberRoom: iMobCount = 0; iObjCount = 0; iRoomCount = 1; pOldRoomVnum = new int [1]; pNewRoomVnum = new int [1]; pOldRoomVnum [0] = iOldVnum; pNewRoomVnum [0] = iNewVnum; break; } // end of switch iMilestone = 0; long iItems = m_MobList.GetCount () + m_ObjectList.GetCount () + m_RoomList.GetCount () + m_ResetList.GetCount () + m_ShopList.GetCount () + m_RepairList.GetCount () + m_HelpList.GetCount (); Frame.CreateProgressBar ("Renumbering area", iItems); // on a renumber all, go through each one and assign its new number if (iRenumberType == eRenumberAll) { // renumber mobs iDifference = dlg.m_iNewLowMobVnum - mob_low_vnum; for (i = 0, mobPos = m_MobList.GetHeadPosition (); mobPos; i++) { mob = m_MobList.GetNext (mobPos); pOldMobVnum [i] = mob->vnum; // remember old vnum if (dlg.m_bMobCompact) mob->vnum = dlg.m_iNewLowMobVnum + i; // compact, just add 1 else mob->vnum = mob->vnum + iDifference; // otherwise take difference pNewMobVnum [i] = mob->vnum; // remember new vnum mob->m_pTreeCtrl->SetItemText (mob->m_hdlTreeItem, mob->Summary ()); // alter summary // update vnum ranges if (mob->vnum > m_Area->mob_hi_vnum) m_Area->mob_hi_vnum = mob->vnum; if (mob->vnum < m_Area->mob_low_vnum) m_Area->mob_low_vnum = mob->vnum; } // end of each mob // renumber objects iDifference = dlg.m_iNewLowObjVnum - obj_low_vnum; for (i = 0, objPos = m_ObjectList.GetHeadPosition (); objPos; i++) { obj = m_ObjectList.GetNext (objPos); pOldObjVnum [i] = obj->vnum; // remember old vnum if (dlg.m_bObjCompact) obj->vnum = dlg.m_iNewLowObjVnum + i; // compact, just add 1 else obj->vnum = obj->vnum + iDifference; // otherwise take difference pNewObjVnum [i] = obj->vnum; // remember new vnum obj->m_pTreeCtrl->SetItemText (obj->m_hdlTreeItem, obj->Summary ()); // alter summary // update vnum ranges if (obj->vnum > m_Area->obj_hi_vnum) m_Area->obj_hi_vnum = obj->vnum; if (obj->vnum < m_Area->obj_low_vnum) m_Area->obj_low_vnum = obj->vnum; } // end of each obj // renumber rooms iDifference = dlg.m_iNewLowRoomVnum - room_low_vnum; for (i = 0, roomPos = m_RoomList.GetHeadPosition (); roomPos; i++) { room = m_RoomList.GetNext (roomPos); pOldRoomVnum [i] = room->vnum; // remember old vnum if (dlg.m_bRoomCompact) room->vnum = dlg.m_iNewLowRoomVnum + i; // compact, just add 1 else room->vnum = room->vnum + iDifference; // otherwise take difference pNewRoomVnum [i] = room->vnum; // remember new vnum room->m_pTreeCtrl->SetItemText (room->m_hdlTreeItem, room->Summary ()); // alter summary // update vnum ranges if (room->vnum > m_Area->room_hi_vnum) m_Area->room_hi_vnum = room->vnum; if (room->vnum < m_Area->room_low_vnum) m_Area->room_low_vnum = room->vnum; } // end of each room } // end of renumber all // fix up cross-references - cannot do above, as we may have an exit // to a room that is not renumbered yet!! t_renumber ProgramRenumberStuff; ProgramRenumberStuff.pOldMobVnum = pOldMobVnum ; ProgramRenumberStuff.pNewMobVnum = pNewMobVnum ; ProgramRenumberStuff.pOldObjVnum = pOldObjVnum ; ProgramRenumberStuff.pNewObjVnum = pNewObjVnum ; ProgramRenumberStuff.pOldRoomVnum = pOldRoomVnum; ProgramRenumberStuff.pNewRoomVnum = pNewRoomVnum; ProgramRenumberStuff.iMobCount = iMobCount; ProgramRenumberStuff.iObjCount = iObjCount ; ProgramRenumberStuff.iRoomCount = iRoomCount; // fix up mobs for (mobPos = m_MobList.GetHeadPosition (); mobPos; ) { mob = m_MobList.GetNext (mobPos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); for (POSITION progPos = mob->programlist.GetHeadPosition (); progPos; ) { program = mob->programlist.GetNext (progPos); // renumber program CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs, &ProgramRenumberStuff); } // end of each program } // end of each mob // fix up rooms for (roomPos = m_RoomList.GetHeadPosition (); roomPos; ) { room = m_RoomList.GetNext (roomPos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); // fix up the tele_vnum FixupRoomVnum (room->tele_vnum); // fix up all exits for (pos = room->exitlist.GetHeadPosition (); pos; ) { CExit * exit = room->exitlist.GetNext (pos); FixupObjVnum (exit->key); FixupRoomVnum (exit->vnum); exit->m_pTreeCtrl->SetItemText (exit->m_hdlTreeItem, exit->Summary ()); // alter summary } // end of processing each exit for (POSITION progPos = room->programlist.GetHeadPosition (); progPos; ) { program = room->programlist.GetNext (progPos); // renumber program CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs, &ProgramRenumberStuff); } // end of each program } // end of each room // fix up objects for (objPos = m_ObjectList.GetHeadPosition (); objPos; ) { obj = m_ObjectList.GetNext (objPos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); for (POSITION progPos = obj->programlist.GetHeadPosition (); progPos; ) { program = obj->programlist.GetNext (progPos); // renumber program CheckCommandSyntax (program->comlist, strMessage, program->xref_rooms, program->xref_objects, program->xref_mobs, &ProgramRenumberStuff); } // end of each program } // end of each obj // fix up the resets for (pos = m_ResetList.GetHeadPosition (); pos; ) { CReset * reset = m_ResetList.GetNext (pos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); switch (reset->command) { case 'M': FixupMobVnum (reset->arg1); FixupRoomVnum (reset->arg3); break; case 'O': FixupObjVnum (reset->arg1); FixupRoomVnum (reset->arg3); break; case 'P': FixupObjVnum (reset->arg1); FixupObjVnum (reset->arg3); break; case 'G': case 'E': FixupObjVnum (reset->arg1); break; case 'H': FixupObjVnum (reset->arg1); break; case 'D': FixupRoomVnum (reset->arg1); break; case 'R': FixupRoomVnum (reset->arg1); break; } // end of switch reset->m_pTreeCtrl->SetItemText (reset->m_hdlTreeItem, reset->Summary ()); // alter summary } // end of processing each reset // fix up the shops for (pos = m_ShopList.GetHeadPosition (); pos; ) { CShop * shop = m_ShopList.GetNext (pos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); FixupMobVnum (shop->keeper); shop->m_pTreeCtrl->SetItemText (shop->m_hdlTreeItem, shop->Summary ()); // alter summary } // end of processing each shop // fix up the repairs for (pos = m_RepairList.GetHeadPosition (); pos; ) { CRepair * repair = m_RepairList.GetNext (pos); if (iMilestone++ % 32 == 0) Frame.UpdateProgressBar (iMilestone); FixupMobVnum (repair->keeper); repair->m_pTreeCtrl->SetItemText (repair->m_hdlTreeItem, repair->Summary ()); // alter summary } // end of processing each repair // get rid of "from" and "to" arrays delete [] pOldMobVnum; delete [] pNewMobVnum; delete [] pOldObjVnum; delete [] pNewObjVnum; delete [] pOldRoomVnum; delete [] pNewRoomVnum; // don't show ridiculous numbers if no items in a category if (m_Area->mob_low_vnum == INT_MAX) m_Area->mob_low_vnum = 0; if (m_Area->obj_low_vnum == INT_MAX) m_Area->obj_low_vnum = 0; if (m_Area->room_low_vnum == INT_MAX) m_Area->room_low_vnum = 0; Frame.RemoveProgressBar (); SetModifiedFlag (); // tell them, if we renumber all if (iRenumberType == eRenumberAll) { // reselect "area" view so that vnums get updated correctly if (m_leftview) m_leftview->GetTreeCtrl().Select (m_leftview->m_hdlTreeArea, TVGN_CARET); ::AfxMessageBox ("Area renumbered", MB_ICONINFORMATION); } return true; // OK return } // end of CAreaEditorDoc::AreaRenumber void CAreaEditorDoc::OnUpdateAreaRenumber(CCmdUI* pCmdUI) { pCmdUI->Enable (m_Area != NULL); } void CAreaEditorDoc::OnAreaRenumber() { AreaRenumber (); // renumber all } // end of CAreaEditorDoc::OnAreaRenumber