[comp.sources.games.bugs] Omega bug: inventory loses names of objects, and bug fix

malloy@nprdc.arpa (Sean Malloy) (08/10/88)

While playing omega, I have found that at unpredictable intervals, the
program will 'forget' what the name of an item in my pack or on my person
is. This results in an inventory showing entries like 'blessed +1' or 'h'
or, in several cases, a blank. All of the functions of the object were
still there, but the description strings got lost.

The patch to oitem.c alters the item creation routines to call a new function,
get_obj. What get_obj does is essentially the same thing that was done for
each item before -- copy the Objects[] entry for that item into the pointer.
However, in addition to this, it also specifically allocates space for the
descriptions of each item, and copies them into the allocated space, rather
than retaining the pointers to the descriptions in the Objects[] array;
it is these pointers getting confused that is causing the problem.

The patch to osave.c adds three lines of code to explicitly copy the
descriptions of an item in your inventory into the inventory before a Save,
so that if you have had problems with this before, doing a Save and restore
will reconstruct the names of all your items.


	Sean Malloy
	Navy Personnel Research & Development Center
	San Diego, CA 92152-6800
	malloy@nprdc.arpa

*******************************
*** oitem.c.old	Wed Aug 10 08:58:51 1988
--- oitem.c	Wed Aug 10 08:46:25 1988
***************
*** 39,49 ****
--- 39,62 ----
    return(new);
  }
  
+ void get_obj(new,id)
+ pob new;
+ int id;
+ {
+ 	*new = Objects[id];
+ 	new->objstr = salloc(Objects[id].objstr);
+ 	new->cursestr = salloc(Objects[id].cursestr);
+ 	new->truename = salloc(Objects[id].truename);
+ }
+ 
  void make_cash(new,level)
  pob new;
  int level;
  {
+ /*****
    *new = Objects[CASHID];
+ *****/
+   get_obj(new,CASHID);
    new->basevalue = random_range(level*level+10)+1; /* aux is AU value */
    new->objstr = salloc(cashstr());
    new->cursestr = new->truename = new->objstr;
***************
*** 54,60 ****
--- 67,76 ----
  int id;
  {
    if (id == -1) id = random_range(NUMFOODS);
+ /*****
    *new = Objects[FOODID+id];
+ *****/
+   get_obj(new,FOODID+id);
  }
  
  
***************
*** 62,68 ****
--- 78,87 ----
  pob new;
  struct monster *m;
  {
+ /*****
    *new = Objects[CORPSEID];
+ *****/
+   get_obj(new,CORPSEID);
    new->charge = m->id;
    new->weight = m->corpseweight;
    new->basevalue = m->corpsevalue;
***************
*** 133,139 ****
--- 152,161 ----
  int id;
  {
    if (id == -1) id = random_range(NUMRINGS);
+ /*****
    *new = Objects[RINGID+id];
+ *****/
+   get_obj(new,RINGID+id);
    if (new->blessing == 0) new->blessing = itemblessing();
    if (new->plus == 0) new->plus = itemplus()+1;
    if (new->blessing < 0) new->plus = -1 - abs(new->plus);
***************
*** 144,150 ****
--- 166,175 ----
  int id;
  {
    if (id == -1) id = random_range(NUMTHINGS);
+ /*****
    *new = Objects[THINGID+id];
+ *****/
+   get_obj(new,THINGID+id);
    if (strcmp(new->objstr,"grot") == 0) {
      new->objstr = salloc(grotname());
      new->truename = new->cursestr = new->objstr;
***************
*** 157,163 ****
--- 182,191 ----
  int id;
  {
    if (id == -1) id = random_range(NUMSCROLLS);
+ /*****
    *new = Objects[SCROLLID+id];
+ *****/
+   get_obj(new,SCROLLID+id);
    /* if a scroll of spells, aux is the spell id in Spells */
    if (new->id == SCROLLID+1) {
      new->aux = random_range(NUMSPELLS);
***************
*** 169,175 ****
--- 197,206 ----
  int id;
  {
    if (id == -1) id = random_range(NUMPOTIONS);
+ /*****
    *new = Objects[POTIONID+id];
+ *****/
+   get_obj(new,POTIONID+id);
    if (new->plus == 0) new->plus = itemplus();
  }
  
***************
*** 178,184 ****
--- 209,218 ----
  int id;
  {
    if (id == -1) id = random_range(NUMWEAPONS);
+ /*****
    *new = Objects[WEAPONID+id];
+ *****/
+   get_obj(new,WEAPONID+id);
    if ((id == 28) || (id == 29)) /* bolt or arrow */
      new->number = random_range(20)+1;
    if (new->blessing == 0) new->blessing = itemblessing();
***************
*** 196,202 ****
--- 230,239 ----
  int id;
  {
    if (id == -1) id = random_range(NUMSHIELDS);
+ /*****
    *new = Objects[SHIELDID+id];
+ *****/
+   get_obj(new,SHIELDID+id);
    if (new->plus == 0)
      new->plus = itemplus();
    if (new->blessing == 0) new->blessing = itemblessing();
***************
*** 211,217 ****
--- 248,257 ----
  int id;
  {
    if (id == -1) id = random_range(NUMARMOR);
+ /*****
    *new = Objects[ARMORID+id];
+ *****/
+   get_obj(new,ARMORID+id);
    if (new->plus == 0) new->plus = itemplus();
    if (new->blessing == 0) new->blessing = itemblessing();
    if (new->blessing < 0)
***************
*** 226,232 ****
--- 266,275 ----
  {
    if (id == -1) id = random_range(NUMCLOAKS);
    Objects[CLOAKID+4].plus = 2;
+ /*****
    *new = Objects[CLOAKID+id];
+ *****/
+   get_obj(new,CLOAKID+id);
    if (new->blessing == 0) new->blessing = itemblessing();
  }
  
***************
*** 235,241 ****
--- 278,287 ----
  int id;
  {
    if (id == -1) id = random_range(NUMBOOTS);
+ /*****
    *new = Objects[BOOTID+id];
+ *****/
+   get_obj(new,BOOTID+id);
    if (new->blessing == 0) new->blessing = itemblessing();
  }
  
***************
*** 244,250 ****
--- 290,299 ----
  int id;
  {
    if (id == -1) id = random_range(NUMSTICKS);
+ /*****
    *new = Objects[STICKID+id];
+ *****/
+   get_obj(new,STICKID+id);
    new->charge = itemcharge();
    if (new->blessing == 0) new->blessing = itemblessing();
  }
***************
*** 253,259 ****
--- 302,311 ----
  pob new;
  {
    if (id == -1) id = random_range(NUMARTIFACTS);
+ /*****
    *new = Objects[ARTIFACTID+id];
+ *****/
+   get_obj(new,ARTIFACTID+id);
  }
  
  
***************
*** 569,575 ****
  {
    int p = 0;
  
!   while (random_range(2) == 0)
      p++;
    return(p);
  }
--- 621,628 ----
  {
    int p = 0;
  
!   /*while (random_range(2) == 0)*/
!   while (random_range(10) > 3)
      p++;
    return(p);
  }
***************
*** 578,584 ****
  
  int itemcharge()
  {
!   return(random_range(20)+1);
  }
  
  
--- 631,638 ----
  
  int itemcharge()
  {
!   /*return(random_range(20)+1);*/
!   return(random_range(200)+1);
  }
  
  
***************
*** 739,748 ****
      case I_PERM_FEAR_RESIST: i_perm_fear_resist(o); break;
      case I_PERM_ENERGY_RESIST: i_perm_energy_resist(o); break;
      case I_PERM_BREATHING: i_perm_breathing(o); break;
  
      /* weapons functions */
      case I_NORMAL_WEAPON: i_normal_weapon(o); break;
!     case I_LIGHTSABRE: i_lightsabre(o); break;
      case I_DEMONBLADE: i_demonblade(o); break;
      case I_DESECRATE: i_desecrate(o); break;
      case I_MACE_DISRUPT: i_mace_disrupt(o); break;
--- 793,811 ----
      case I_PERM_FEAR_RESIST: i_perm_fear_resist(o); break;
      case I_PERM_ENERGY_RESIST: i_perm_energy_resist(o); break;
      case I_PERM_BREATHING: i_perm_breathing(o); break;
+     case I_PERM_COMBAT_STR: i_perm_combat_str(o);
+ 			    i_victrix(o);
+ 			    i_perm_energy_resist(o);
+ 			    i_perm_fear_resist(o);
+ 			    i_perm_breathing(o); break;
+     case I_PERM_SCOUT_STR: i_perm_scout_str(o);
+ 			    i_perm_breathing(o); break;
  
+ 
      /* weapons functions */
      case I_NORMAL_WEAPON: i_normal_weapon(o); break;
!     case I_LIGHTSABRE: i_lightsabre(o);
! 			i_perm_deflect(o); break;
      case I_DEMONBLADE: i_demonblade(o); break;
      case I_DESECRATE: i_desecrate(o); break;
      case I_MACE_DISRUPT: i_mace_disrupt(o); break;
***********************
*** osave.c.old	Wed Aug 10 09:02:55 1988
--- osave.c	Wed Aug 10 08:35:42 1988
***************
*** 246,251 ****
--- 246,256 ----
      fprintf(fd,"Null Object. Report if you see this!\n");
    }
    else {
+ /*****/
+ 	o->objstr = salloc(Objects[o->id].objstr);
+ 	o->cursestr = salloc(Objects[o->id].cursestr);
+ 	o->truename = salloc(Objects[o->id].truename);
+ /*****/
      fwrite((char *)o,sizeof(objtype),1,fd);
      fprintf(fd,"%s\n",o->truename);
    }

malloy@nprdc.arpa (Sean Malloy) (08/10/88)

Oops. I accidentally left in some of my exploratory hacking when I
posted the bug fix. Please remove the following lines from the patch
input before applying -- some of the stuff I left in requires changes
in other files not included here:

|***************
|*** 569,575 ****
|  {
|    int p = 0;
|  
|!   while (random_range(2) == 0)
|      p++;
|    return(p);
|  }
|--- 621,628 ----
|  {
|    int p = 0;
|  
|!   /*while (random_range(2) == 0)*/
|!   while (random_range(10) > 3)
|      p++;
|    return(p);
|  }
|***************
|*** 578,584 ****
|  
|  int itemcharge()
|  {
|!   return(random_range(20)+1);
|  }
|  
|  
|--- 631,638 ----
|  
|  int itemcharge()
|  {
|!   /*return(random_range(20)+1);*/
|!   return(random_range(200)+1);
|  }
|  
|  
|***************
|*** 739,748 ****
|      case I_PERM_FEAR_RESIST: i_perm_fear_resist(o); break;
|      case I_PERM_ENERGY_RESIST: i_perm_energy_resist(o); break;
|      case I_PERM_BREATHING: i_perm_breathing(o); break;
|  
|      /* weapons functions */
|      case I_NORMAL_WEAPON: i_normal_weapon(o); break;
|!     case I_LIGHTSABRE: i_lightsabre(o); break;
|      case I_DEMONBLADE: i_demonblade(o); break;
|      case I_DESECRATE: i_desecrate(o); break;
|      case I_MACE_DISRUPT: i_mace_disrupt(o); break;
|--- 793,811 ----
|      case I_PERM_FEAR_RESIST: i_perm_fear_resist(o); break;
|      case I_PERM_ENERGY_RESIST: i_perm_energy_resist(o); break;
|      case I_PERM_BREATHING: i_perm_breathing(o); break;
|+     case I_PERM_COMBAT_STR: i_perm_combat_str(o);
|+ 			    i_victrix(o);
|+ 			    i_perm_energy_resist(o);
|+ 			    i_perm_fear_resist(o);
|+ 			    i_perm_breathing(o); break;
|+     case I_PERM_SCOUT_STR: i_perm_scout_str(o);
|+ 			    i_perm_breathing(o); break;
|  
|+ 
|      /* weapons functions */
|      case I_NORMAL_WEAPON: i_normal_weapon(o); break;
|!     case I_LIGHTSABRE: i_lightsabre(o);
|! 			i_perm_deflect(o); break;
|      case I_DEMONBLADE: i_demonblade(o); break;
|      case I_DESECRATE: i_desecrate(o); break;
|      case I_MACE_DISRUPT: i_mace_disrupt(o); break;

I apologize for any inconvenience this may have caused.


	Sean Malloy
	Navy Personnel Research & Development Center
	San Diego, CA 92152-6800
	malloy@nprdc.arpa