Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

odelete.c

Go to the documentation of this file.
00001 //#include <types.h>
00002 
00003 #include <sys/types.h>
00004 
00005 #include <ctype.h>
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <time.h>
00010 #include "merc.h"
00011 #include "tables.h"
00012 #include "olc.h"
00013 
00014 
00015 /*From: Christopher Feist <Christopher.Feist.feist@nt.com>
00016 
00017 Recently I have been working on OLC delete commands since they would
00018 be really handy.
00019 
00020 I have come up with working versions of oedit_delete
00021 and medit_delete. redit_delete is still in the works and I dont
00022 think im going to bother with aedit_delete.
00023 
00024 The basic premise is that you remove the vnum from the appropriate
00025 hash and then delete all resets which refer to said vnum. This is
00026 of course much easier to say then to do. The tricky part is
00027 getting resets for objects inside other objects. Both of the
00028 delete functions handle these cases.
00029 
00030 I specificaly do not free up the index data because doing that
00031 would require me to eliminate every instance of said vnum from
00032 the mud. (because pIndexData still points to this memory location)
00033 This isnt too bad for mobiles but for objects it really
00034 really bites. If someone wants to code it up ill gladly take it
00035 however. :)
00036 
00037 I am submitting the two delete functions so that other muds besides
00038 Aeon can test them and maybe force out any small bugs that I havent
00039 caught. I STRONGLY suggest you read and understand what is happening
00040 before you put these in. You will also have to add the hooks in
00041 to call the functions yourself. (That should prevent most copy/paste
00042 implementors from doing dumb things :P)
00043 
00044 If you are trying to understand what is happening here I reccomend
00045 uncommenting the debug code in oedit delete as it spews alot less
00046 output then the medit delete code. I admit that neither of these
00047 routines are particularily elegant coding examples however they
00048 do work.
00049 
00050 Lastly on Aeon there is a small glitch in medit_delete whereby
00051 the person deleting the mobile somehow has his mount set to
00052 a predictable value sometime after the exit of the function.
00053 (i.e its something in our code not the function)
00054 
00055 Unfortunatly I havent been able to figureout how/why/where this happens.
00056 If anyone knows how to break on the change of the value
00057 of a dereferenced pointer in gdb an example would be REALLY REALLY 
00058 appreciated. For those of you who have muds without mount code
00059 (or with mount code) you will have to get rid of that little 
00060 section at the bottom of medit_delete since our mount code
00061 isnt taken from a stock snippet.
00062 
00063 Enjoy.
00064 
00065 Narbo
00066 
00067 Coder @ Aeon
00068 telnet://mud.aeon.org:4000
00069 */
00070 //OEDIT( oedit_delete )
00071  OEDIT (CHAR_DATA *ch, char *argument)
00072 {
00073      OBJ_INDEX_DATA *pObj;
00074      OBJ_INDEX_DATA *iObj;
00075      OBJ_INDEX_DATA *sObj;
00076      RESET_DATA *pReset = NULL;
00077      RESET_DATA *prev = NULL;
00078      ROOM_INDEX_DATA *pRoom = NULL;
00079      char arg[MIL];
00080      char buf[MSL];
00081      int index, count, iHash, i;
00082 
00083      if ( argument[0] == '\0' )
00084      {
00085           send_to_char( "Syntax:  oedit delete [vnum]\n\r", ch );
00086           return FALSE;
00087      }
00088 
00089      one_argument( argument, arg );
00090 
00091      if( is_number( arg ) )
00092      {
00093           index = atoi( arg );
00094           pObj = get_obj_index( index );
00095      }
00096      else
00097      {
00098           send_to_char( "That is not a number.\n\r", ch );
00099           return FALSE;
00100      }
00101 
00102      SET_BIT( pObj->area->area_flags, AREA_CHANGED );
00103 
00104      /* Remove it from the object list */
00105 
00106      iHash = index % MAX_KEY_HASH;
00107 
00108      /* DEBUG CODE - uncomment this if you have doubts */
00109      /* printf("\nObject hash for location %d:\n", iHash);
00110      for ( tObj = obj_index_hash[iHash]; tObj != NULL; tObj = tObj->next )
00111           printf("name: %s vnum: %d\n", tObj->name, tObj->vnum ); */
00112 
00113      sObj = obj_index_hash[iHash];
00114 
00115      if( sObj->next == NULL ) /* only entry */
00116           obj_index_hash[iHash] = NULL;
00117      else if( sObj == pObj ) /* first entry */
00118           obj_index_hash[iHash] = pObj->next;
00119      else /* everything else */
00120      {
00121           for( iObj = sObj; iObj != NULL; iObj = iObj->next )
00122           {
00123                if( iObj ==  pObj )
00124                {
00125                     sObj->next = pObj->next;
00126                     break;
00127                }
00128                sObj = iObj;
00129           }
00130      }
00131 
00132      /* If you uncomment this you also need to
00133         find every instance of the object that exists in
00134         the mud and extract them otherwise each of thier
00135         pIndexData will be pointing at free memory.
00136         (Which may or may not contain the actual info)
00137         As it is all the objects will be removed the reboot/login
00138         automatically by fread_obj when it cant find the index */
00139 
00140      /* free_string( pObj->name );
00141      free_string( pObj->short_descr );
00142      free_string( pObj->description );
00143 
00144      for( pAf = pObj->affected; pAf; pAf = pAf->next )
00145           free_affect( pAf );
00146 
00147      for( pExtra = pObj->extra_descr; pExtra; pExtra = pExtra->next )
00148           free_extra_descr( pExtra );
00149 
00150      free( pObj ); */
00151 
00152      /* DEBUG CODE - uncomment this if you have doubts */
00153      /* printf("\nObject hash for location %d after removal:\n", iHash);
00154      for ( tObj = obj_index_hash[iHash]; tObj != NULL; tObj = tObj->next )
00155           printf("name: %s vnum: %d\n", tObj->name, tObj->vnum ); */
00156 
00157      /* DEBUG CODE */
00158      // printf( "\ntop_vnum_obj before: %d\n", top_vnum_obj );
00159 
00160      if( top_vnum_obj == index )
00161           for( i = 1; i < index; i++ )
00162                if( get_obj_index( i ) )
00163                     top_vnum_obj = i;
00164 
00165      /* DEBUG CODE */
00166      // printf( "top_vnum_obj after: %d\n", top_vnum_obj );
00167 
00168      top_obj_index--;
00169 
00170      /* Now crush all resets */
00171      count = 0;
00172      for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
00173      {
00174           for( pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next )
00175           {
00176                prev = pRoom->reset_first;
00177                for( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
00178                {
00179                     switch( pReset->command )
00180                     {
00181                          case 'O':
00182                          case 'E':
00183                          case 'P':
00184                          case 'G':
00185                               if( ( pReset->arg1 == index ) ||
00186                                   ( (  pReset->command == 'P' ) && (
00187 pReset->arg3 == index ) ) )
00188                               {
00189                                    // printf("\nprev: %d  prev->next: %d\n",
00190 //prev, prev->next );
00191 
00192                                    /* DEBUG CODE - uncomment this if you have
00193 doubts */
00194                                    /* printf("\nReset info for room %d:\n",
00195 pRoom->vnum );
00196                                    for( tReset = pRoom->reset_first; tReset;
00197 tReset = tReset->next )
00198                                         printf("command: %c  vnum: %d 
00199 memloc:%d\n", tReset->command, tReset->arg1, tReset ); */
00200 
00201                                    if( pRoom->reset_first == pReset )
00202                                    {
00203                                         pRoom->reset_first = pReset->next;
00204                                         if( !pRoom->reset_first )
00205                                              pRoom->reset_last = NULL;
00206                                    }
00207                                    else if( pRoom->reset_last == pReset )
00208                                    {
00209                                         pRoom->reset_last = prev;
00210                                         prev->next = NULL;
00211                                    }
00212                                    else
00213                                    {
00214                                         prev->next = prev->next->next;
00215                                    }
00216 
00217                                    count++;
00218                                    SET_BIT( pRoom->area->area_flags,
00219 AREA_CHANGED );
00220 
00221                                    /* DEBUG CODE - uncomment this if you have
00222 doubts */
00223                                    /* printf("\nReset info for room %d after
00224 removal:\n", pRoom->vnum );
00225                                    for( tReset = pRoom->reset_first; tReset;
00226 tReset = tReset->next )
00227                                         printf("command: %c  vnum: %d 
00228 memloc:%d\n", tReset->command, tReset->arg1, tReset ); */
00229 
00230                                    // printf("\nprev: %d  prev->next: %d\n",
00231 //prev, prev->next );
00232                               }
00233                     }
00234                     prev = pReset;
00235                }
00236           }
00237      }
00238 
00239      sprintf( buf, "Removed object vnum {R%d{x and {R%d{x resets.\n\r", index,
00240 count );
00241      send_to_char( buf, ch );
00242      return TRUE;
00243 }
00244 
00245 /*
00246 MEDIT( medit_delete )
00247 {
00248      MOB_INDEX_DATA *pMob;
00249      MOB_INDEX_DATA *sMob;
00250      MOB_INDEX_DATA *iMob;
00251      RESET_DATA *pReset = NULL;
00252      RESET_DATA *prev= NULL;
00253      ROOM_INDEX_DATA *pRoom = NULL;
00254      char arg[MIL];
00255      char buf[MSL];
00256      int index, count, iHash, i;
00257      int dobj[100];  I highly doubt one mobile will have 100 unique object
00258 resets 
00259      bool foundmob = FALSE;
00260      bool exist = FALSE;
00261      bool foundobj = FALSE;
00262 
00263      if ( argument[0] == '\0' )
00264      {
00265           send_to_char( "Syntax:  medit delete [vnum]\n\r", ch );
00266           return FALSE;
00267      }
00268 
00269      one_argument( argument, arg );
00270 
00271      if( is_number( arg ) )
00272      {
00273           index = atoi( arg );
00274           pMob = get_mob_index( index );
00275      }
00276      else
00277      {
00278           send_to_char( "That is not a number.\n\r", ch );
00279           return FALSE;
00280      }
00281 
00282      if( !pMob )
00283      {
00284           send_to_char( "No such mobile.\n\r", ch );
00285           return FALSE;
00286      }
00287 
00288      SET_BIT( pMob->area->area_flags, AREA_CHANGED );
00289 
00290       Remove it from the object list 
00291 
00292      iHash = index % MAX_KEY_HASH;
00293 
00294       DEBUG CODE - uncomment this if you have doubts */
00295      /* printf("\nMobile hash for location %d:\n", iHash);
00296      for ( tMob = mob_index_hash[iHash]; tMob != NULL; tMob = tMob->next )
00297           printf("short_desc: %s  vnum: %d\n", tMob->short_descr, tMob->vnum );
00298 
00299 
00300      sMob = mob_index_hash[iHash];
00301 
00302      if( sMob->next == NULL )  only entry 
00303           mob_index_hash[iHash] = NULL;
00304      else if( sMob == pMob )  first entry 
00305           mob_index_hash[iHash] = pMob->next;
00306      else  everything else 
00307      {
00308           for( iMob = sMob; iMob != NULL; iMob = iMob->next )
00309           {
00310                if( iMob ==  pMob )
00311                {
00312                     sMob->next = pMob->next;
00313                     break;
00314                }
00315           }
00316      }
00317 
00318       See oedit_delete for why i dont free pMob here */
00319 
00320      /* DEBUG CODE - uncomment this if you have doubts */
00321      /* printf("\nMobile hash for location %d after removal:\n", iHash);
00322      for ( tMob = mob_index_hash[iHash]; tMob != NULL; tMob = tMob->next )
00323           printf("short_desc: %s  vnum: %d\n", tMob->short_descr, tMob->vnum );
00324 
00325 
00326      if( top_vnum_mob == index )
00327           for( i = 1; i < index; i++ )
00328                if( get_obj_index( i ) )
00329                     top_vnum_obj = i;
00330 
00331      top_mob_index--;
00332 
00333       Now crush all resets 
00334      count = 0;
00335      for( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
00336      {
00337           for( pRoom = room_index_hash[iHash]; pRoom; pRoom = pRoom->next )
00338           {
00339                dobj[0] = -1;
00340                prev = pRoom->reset_first;
00341                for( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
00342                {
00343                     switch( pReset->command )
00344                     {
00345                          case 'M':
00346                               if( pReset->arg1 == index )
00347                               {
00348                                    foundmob = TRUE;
00349 
00350                                     DEBUG CODE - uncomment this if you have
00351 doubts 
00352                                     printf("\nReset info for room %d:\n",
00353 pRoom->vnum );
00354                                    for( tReset = pRoom->reset_first; tReset;
00355 tReset = tReset->next )
00356                                         printf("command: %c  vnum: %d\n",
00357 tReset->command, tReset->arg1 ); 
00358 
00359                                    if( pRoom->reset_first == pReset )
00360                                    {
00361                                         pRoom->reset_first = pReset->next;
00362                                         if( !pRoom->reset_first )
00363                                              pRoom->reset_last = NULL;
00364                                    }
00365                                    else if( pRoom->reset_last == pReset )
00366                                    {
00367                                         pRoom->reset_last = prev;
00368                                         prev->next = NULL;
00369                                    }
00370                                    else
00371                                         prev->next = prev->next->next;
00372 
00373                                    count++;
00374                                    SET_BIT( pRoom->area->area_flags,
00375 AREA_CHANGED );
00376 
00377                                     DEBUG CODE - uncomment this if you have
00378 doubts 
00379                                     printf("\nReset info for room %d after
00380 removal:\n", pRoom->vnum );
00381                                    for( tReset = pRoom->reset_first; tReset;
00382 tReset = tReset->next )
00383                                         printf("command: %c  vnum: %d\n",
00384 tReset->command, tReset->arg1 ); 
00385 
00386                               }
00387                               else
00388                                    foundmob = FALSE;
00389 
00390                               break;
00391                          case 'E':
00392                          case 'G':
00393                               if( foundmob )
00394                               {
00395                                    // printf( "Removing: command: %c  vnum:
00396 %d\n", pReset->command, pReset->arg1 );
00397 
00398                                     DEBUG CODE - uncomment this if you have
00399 doubts 
00400                                    * printf("\nReset info for room %d:\n",
00401 pRoom->vnum );
00402                                    for( tReset = pRoom->reset_first; tReset;
00403 tReset = tReset->next )
00404                                         printf("command: %c  vnum: %d\n",
00405 tReset->command, tReset->arg1 ); 
00406 
00407                                    exist = FALSE;
00408 
00409                                    for( i = 0; dobj[i] != -1; i++ )
00410                                    {
00411                                         if( dobj[i] == pReset->arg1 )
00412                                         {
00413                                              exist = TRUE;
00414                                              break;
00415                                         }
00416                                    }
00417 
00418                                    if( !exist )
00419                                    {
00420                                         dobj[i] = pReset->arg1;
00421                                         dobj[i + 1] = -1;
00422 
00423                                          DEBUG CODE 
00424                                          for( i = 0; dobj[i] != -1; i++ )
00425                                              printf( "dobj[%d] : %d\n", i,
00426 dobj[i] ); 
00427                                    }
00428 
00429                                    if( pRoom->reset_first == pReset )
00430                                    {
00431                                         pRoom->reset_first = pReset->next;
00432                                         if( !pRoom->reset_first )
00433                                              pRoom->reset_last = NULL;
00434                                    }
00435                                    else if( pRoom->reset_last == pReset )
00436                                    {
00437                                         pRoom->reset_last = prev;
00438                                         prev->next = NULL;
00439                                    }
00440                                    else
00441                                         prev->next = prev->next->next;
00442 
00443                                    count++;
00444                                    SET_BIT( pRoom->area->area_flags,
00445 AREA_CHANGED );
00446 
00447                                     DEBUG CODE - uncomment this if you have
00448 doubts 
00449                                     printf("\nReset info for room %d after
00450 removal:\n", pRoom->vnum );
00451                                    for( tReset = pRoom->reset_first; tReset;
00452 tReset = tReset->next )
00453                                         printf("command: %c  vnum: %d\n",
00454 tReset->command, tReset->arg1 ); 
00455                               }
00456 
00457                               break;
00458                          case 'P':
00459                               foundobj = FALSE;
00460 
00461                               for( i = 0; dobj[i] != -1; i++ )
00462                                    if( dobj[i] == pReset->arg3 )
00463                                         foundobj = TRUE;
00464 
00465                               if( foundobj )
00466                               {
00467                                    printf( "Removing: command: %c  vnum: %d\n",
00468 pReset->command, pReset->arg1 );
00469 
00470                                   * DEBUG CODE - uncomment this if you have
00471 doubts 
00472                                     printf("\nReset info for room %d:\n",
00473 pRoom->vnum );
00474                                    for( tReset = pRoom->reset_first; tReset;
00475 tReset = tReset->next )
00476                                         printf("command: %c  vnum: %d\n",
00477 tReset->command, tReset->arg1 ); 
00478 
00479                                    if( pRoom->reset_first == pReset )
00480                                    {
00481                                         pRoom->reset_first = pReset->next;
00482                                         if( !pRoom->reset_first )
00483                                              pRoom->reset_last = NULL;
00484                                    }
00485                                    else if( pRoom->reset_last == pReset )
00486                                    {
00487                                         pRoom->reset_last = prev;
00488                                         prev->next = NULL;
00489                                    }
00490                                    else
00491                                         prev->next = prev->next->next;
00492 
00493                                    count++;
00494                                    SET_BIT( pRoom->area->area_flags,
00495 AREA_CHANGED );
00496 
00497                                     DEBUG CODE - uncomment this if you have
00498 doubts 
00499                                     printf("\nReset info for room %d after
00500 removal:\n", pRoom->vnum );
00501                                    for( tReset = pRoom->reset_first; tReset;
00502 tReset = tReset->next )
00503                                         printf("command: %c  vnum: %d\n",
00504 tReset->command, tReset->arg1 ); 
00505                               }
00506                     }
00507                     prev = pReset;
00508                }
00509           }
00510      }
00511 
00512       This is a dumb way to fix what is probably someone elses problem 
00513 * The reason for the kludge is that sometime after the exit of
00514 medit_delete 
00515       ch->mount becomes 0x10000000 and I have no idea how or where 
00516      
00517      if( ch->mount == NULL )
00518           medit_delete_kludge = ch;
00519 
00520      sprintf( buf, "Removed mobile vnum ^C%d^x and ^C%d^x resets.\n\r", index,
00521 count );
00522      send_to_char( buf, ch );
00523      return TRUE;
00524 }
00525 */
00526 /*
00527 -- 
00528 
00529 0o0o0o0o0o0o0o0o0o0o0o00o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0
00530 o Chris Feist      GCS/GMUd-s+:-a--C++++USUH$ULU+++P++L++E-W-N++o?Kw-- o
00531 o Dept 7M52        O?M++V-PS+PEY+PGP+t+5+X-Rtv+b++DI++D++Ge++@hr--!y+  0
00532 0 SS7 Verification                                                     o
00533 o feist@nortel.ca  George Bush: "It's amazing how many people beat you 0 
00534 0                  at golf now that you're no longer president."       o
00535 o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0o0
00536 */

Generated on Thu Jan 13 21:48:13 2005 for Beyond the Shadows by  doxygen 1.4.0