[comp.sources.games.bugs] Yet more Omega bugs

pwing@apple.UUCP (Philip L. Wing) (02/09/88)

	Looks like the variables that store the level at which you entered
a guild is not saved in the save file.  This produces interesting effects
like being very high level in the respective to where you should be, e.x.
I'm 7th level and a priest of the Druids, Magii teacher or something, and
of comparable level in the Sorcerors.

-- 
Live Long And Prosper and May The Force Be With You(And The Carrier, Too...)

				Philip L. Wing

ajcd@its63b.ed.ac.uk (Angus Duggan, Department of Computer Science, University of Edinburgh) (02/23/88)

[warning - line eater at work]

Here's a load more omega bug fixes, some cosmetic, some essential.

#1 Imprisonment status, search length option and starting levels for guilds
   are not saved in the player's save file. NOTE - this fix makes save files
   incompatible with old versions. If you alter VERSION in odefs.h omega will
   reject old save files.

======== Diff for oglob.h ========
*** oglob.h~	Mon Jan 25 14:47:51 1988
--- oglob.h	Fri Feb 19 11:29:45 1988
***************
*** 109,114 ****
--- 109,117 ----
  extern int Deepest;
  /* The deepest level attained */
  
+ extern int imprisonment;
+ /* number of times player sent to prison */
+ 
  extern int SuppressPrinting;
  /* turn off mprint, printm, when TRUE */
  
======== End of Diff ========

======== Diff for o.c ========
*** o.c~	Tue Feb  2 11:53:39 1988
--- o.c	Fri Feb 19 11:28:01 1988
***************
*** 106,111 ****
--- 106,112 ----
  int Bank_Broken = FALSE;              /* Has bank been broken into */
  char Password[64];                    /* autoteller password */
  int Deepest = 0;                      /* The deepest level attained */
+ int imprisonment = 0;                 /* number of times in gaol */
  int SuppressPrinting=FALSE;           /* turn off mprint, printm, when TRUE */
  char Str1[100],Str2[100],Str3[100],Str4[100];
     /* Some string space, random uses */
======== End of Diff ========

======== Diff for osite.c ========
*** osite.c~	Mon Feb  8 12:49:47 1988
--- osite.c	Fri Feb 19 11:29:36 1988
***************
*** 1286,1293 ****
--- 1286,1292 ----
  void send_to_jail()
  {
    int i,j,found=FALSE;
-   static int imprisonment=0;
    switch(imprisonment++){
    case 0:
      mprint("The Justiciar sternly reprimands you.");
      mprint("As a first-time offender, you are given probation.");
======== End of Diff ========

======== Diff for olev.c ========
*** olev.c~	Mon Feb 22 10:43:44 1988
--- olev.c	Mon Feb 22 10:37:14 1988
***************
*** 334,339 ****
--- 334,346 ----
    write_int(fd,Clubmember);
    write_int(fd,Sawdruid);
    write_int(fd,Soldcondo);
+   write_int(fd,Searchnum);
+   write_int(fd,Thieflevel);
+   write_int(fd,Clericlevel);
+   write_int(fd,Sorcerorlevel);
+   write_int(fd,Collegelevel);
+   write_int(fd,Merclevel);
+   write_int(fd,imprisonment);
    write_int(fd,Player.str);
    write_int(fd,Player.con);
    write_int(fd,Player.dex);
***************
*** 618,623 ****
--- 626,638 ----
    Clubmember = read_int(fd);
    Sawdruid = read_int(fd);
    Soldcondo = read_int(fd);
+   Searchnum = read_int(fd);
+   Thieflevel = read_int(fd);
+   Clericlevel = read_int(fd);
+   Sorcerorlevel = read_int(fd);
+   Collegelevel = read_int(fd);
+   Merclevel = read_int(fd);
+   imprisonment = read_int(fd);
    Player.str = read_int(fd);
    Player.con = read_int(fd);
    Player.dex = read_int(fd);
======== End of Diff ========


#2 Cosmetic - Spaces missed out of monster status information.

======== Diff for oaux1.c ========
*** oaux1.c~	Mon Feb  8 12:06:54 1988
--- oaux1.c	Fri Feb 19 13:34:16 1988
***************
*** 489,497 ****
  {
    if (m->uniqueness == COMMON) {
      if (m->hp < Monsters[m->id].hp / 3)
!       strcpy(Str2,"a grievously injured");
      else if (m->hp < Monsters[m->id].hp / 2)
!       strcpy(Str2,"a severely injured");
      else if (m->hp < Monsters[m->id].hp)
        strcpy(Str2,"an injured ");
      else strcpy(Str2,getarticle(m->monstring));
--- 489,497 ----
  {
    if (m->uniqueness == COMMON) {
      if (m->hp < Monsters[m->id].hp / 3)
!       strcpy(Str2,"a grievously injured ");
      else if (m->hp < Monsters[m->id].hp / 2)
!       strcpy(Str2,"a severely injured ");
      else if (m->hp < Monsters[m->id].hp)
        strcpy(Str2,"an injured ");
      else strcpy(Str2,getarticle(m->monstring));
***************
*** 505,515 ****
    else {
      strcpy(Str2,m->monstring);
      if (m->hp < Monsters[m->id].hp / 3)
!       strcat(Str2,"who is grievously injured");
      else if (m->hp < Monsters[m->id].hp / 2)
!       strcat(Str2,"who is severely injured");
      else if (m->hp < Monsters[m->id].hp)
!       strcat(Str2,"who is injured ");
    }
    return(Str2);
  }
--- 505,515 ----
    else {
      strcpy(Str2,m->monstring);
      if (m->hp < Monsters[m->id].hp / 3)
!       strcat(Str2," who is grievously injured");
      else if (m->hp < Monsters[m->id].hp / 2)
!       strcat(Str2," who is severely injured");
      else if (m->hp < Monsters[m->id].hp)
!       strcat(Str2," who is injured ");
    }
    return(Str2);
  }
======== End of Diff ========


#3 Monsters which can have M_SP_SURPRISE ability can attack player after being
   killed in tactical combat mode.

======== Diff for oaux2.c ========
*** oaux2.c~	Fri Feb 19 11:40:04 1988
--- oaux2.c	Fri Feb 19 11:45:33 1988
***************
*** 790,796 ****
      }
    }
    morewait();
!   monster_special(m);
  }
  
  
--- 790,797 ----
      }
    }
    morewait();
!   if (m->hp > 0)
!     monster_special(m);
  }
  
  
======== End of Diff ========


#4 Aborting shadowform asks if wizard mode is to be toggled.

======== Diff for ocom.c ========
*** ocom.c~	Tue Feb  2 11:55:13 1988
--- ocom.c	Sat Feb 20 11:13:39 1988
***************
*** 97,103 ****
      switch (Cmd) {
       case ' ': 
       case 13: Skipmonsters = TRUE; break;  /* no op on space or return */
!      case 6: abortshadowform(); /* ^f */
       case 7: wizard(); break; /* ^g */
       case 14: xredraw(); Skipmonsters = TRUE; break; /* ^l */
       case 16: lastmprint(); break; /* ^p */ 
--- 97,103 ----
      switch (Cmd) {
       case ' ': 
       case 13: Skipmonsters = TRUE; break;  /* no op on space or return */
!      case 6: abortshadowform(); break; /* ^f */
       case 7: wizard(); break; /* ^g */
       case 14: xredraw(); Skipmonsters = TRUE; break; /* ^l */
       case 16: lastmprint(); break; /* ^p */ 
======== End of Diff ========


#5 SERIOUS - There is no Hall of Fate! There should be 6 altar levels, not 5.

======== Diff for ogen.c ========
*** ogen.c~	Tue Feb  2 11:59:00 1988
--- ogen.c	Fri Feb 19 16:02:03 1988
***************
*** 83,96 ****
    if (tolevel == 5) cavern_level(tolevel,1);
    else if (tolevel == 18) pond_level(tolevel,1);
    else if (tolevel == 27) pond_level(tolevel,2);
!   else if (tolevel == 33) cavern_level(tolevel,2);
!   else if (tolevel == 34) room_level(tolevel,1);
!   else if (tolevel == 35) room_level(tolevel,2);
!   else if (tolevel == 36) room_level(tolevel,3);
!   else if (tolevel == 37) room_level(tolevel,4);
!   else if (tolevel == 38) room_level(tolevel,5);
    else if (tolevel == NUMLEVELS-1) load_depths();
!   else  switch(random_range(20)) {
      case 0:
      case 1:
      case 2: 
--- 83,97 ----
    if (tolevel == 5) cavern_level(tolevel,1);
    else if (tolevel == 18) pond_level(tolevel,1);
    else if (tolevel == 27) pond_level(tolevel,2);
!   else if (tolevel == 32) cavern_level(tolevel,2);
!   else if (tolevel == 33) room_level(tolevel,1);
!   else if (tolevel == 34) room_level(tolevel,2);
!   else if (tolevel == 35) room_level(tolevel,3);
!   else if (tolevel == 36) room_level(tolevel,4);
!   else if (tolevel == 37) room_level(tolevel,5);
!   else if (tolevel == 38) room_level(tolevel,6);
    else if (tolevel == NUMLEVELS-1) load_depths();
!   else switch(random_range(20)) {
      case 0:
      case 1:
      case 2: 
======== End of Diff ========

======== Diff for oguild.c ========
*** oguild.c~	Wed Feb 17 18:53:40 1988
--- oguild.c	Fri Feb 19 16:19:54 1988
***************
*** 1258,1284 ****
    switch(Player.patron) {
    case ODIN:
      mprint(Priest[SET]);
!     mprint("whose Temple of the Black Hand is somewhere on levels 34 to 38");
      break;
    case SET:
      mprint(Priest[ODIN]);
!     mprint("whose Shrine of the Noose is somewhere on levels 34 to 38");
      break;
    case ATHENA:
      mprint(Priest[HECATE]);
!     mprint("whose Church of the Far Side is somewhere on levels 34 to 38");
      break;
    case HECATE:
      mprint(Priest[ATHENA]);
!     mprint("whose Parthenon is somewhere on levels 34 to 38");
      break;
    case DRUID:
      mprint("any of the aligned priests");
!     mprint("whose temples are somewhere on levels 34 to 38");
      break;
    case DESTINY:
      mprint(Priest[DESTINY]);
!     mprint("whose Hall of Fate is somewhere on levels 34 to 38");
      break;
    }
  }
--- 1258,1284 ----
    switch(Player.patron) {
    case ODIN:
      mprint(Priest[SET]);
!     mprint("whose Temple of the Black Hand is somewhere on levels 33 to 38");
      break;
    case SET:
      mprint(Priest[ODIN]);
!     mprint("whose Shrine of the Noose is somewhere on levels 33 to 38");
      break;
    case ATHENA:
      mprint(Priest[HECATE]);
!     mprint("whose Church of the Far Side is somewhere on levels 33 to 38");
      break;
    case HECATE:
      mprint(Priest[ATHENA]);
!     mprint("whose Parthenon is somewhere on levels 33 to 38");
      break;
    case DRUID:
      mprint("any of the aligned priests");
!     mprint("whose temples are somewhere on levels 33 to 38");
      break;
    case DESTINY:
      mprint(Priest[DESTINY]);
!     mprint("whose Hall of Fate is somewhere on levels 33 to 38");
      break;
    }
  }
======== End of Diff ========


#6 Cosmetic change - makes altars stop runs

======== Diff for ogen.c ========
*** ogen.c~	Tue Feb  2 11:59:00 1988
--- ogen.c	Fri Feb 19 16:02:03 1988
***************
*** 609,614 ****
--- 610,616 ----
  	  Dungeon[level][x][y].locchar = ALTAR;
  	  Dungeon[level][x][y].p_locf = L_ALTAR;
  	  Dungeon[level][x][y].aux = random_range(10);
+ 	  Dungeon[level][x][y].stopsrun = TRUE;
  	}
  	else if (i < 25) {
  	  Dungeon[level][x][y].locchar = WATER;
***************
*** 876,881 ****
--- 878,884 ----
      Dungeon[level][x][y].locchar = ALTAR;
      Dungeon[level][x][y].p_locf = L_ALTAR;
      Dungeon[level][x][y].aux = special_level;
+     Dungeon[level][x][y].stopsrun = TRUE;
      ml = (pml) malloc(sizeof(mltype));
      ml->next = NULL;
      ml->m = 
======== End of Diff ========


#7 Murk fungus is wrongly initialised

======== Diff for oinitmon0to3.c ========
*** oinitmon0to3.c~	Wed Jan 27 14:35:33 1988
--- oinitmon0to3.c	Sat Feb 20 11:55:02 1988
***************
*** 870,876 ****
  
  
    /* murk fungus  */
!   Monsters[ML2+8].id = ML2+7;
    Monsters[ML2+8].hp = 7;
    Monsters[ML2+8].speed = 12;
    Monsters[ML2+8].hit = 0;
--- 870,876 ----
  
  
    /* murk fungus  */
!   Monsters[ML2+8].id = ML2+8;
    Monsters[ML2+8].hp = 7;
    Monsters[ML2+8].speed = 12;
    Monsters[ML2+8].hit = 0;
======== End of Diff ========


#8 SERIOUS - If Orb of Earth used before identified, dumps core.

======== Diff for oitemf.c ========
*** oitemf.c~	Tue Feb  2 12:00:48 1988
--- oitemf.c	Fri Feb 19 12:52:35 1988
***************
*** 577,583 ****
      mprint("The Orb of Earth blasts you!");
      for (i=0;i<MAXITEMS;i++) {
        if (Player.possessions[i] != NULL) {
! 	conform_lost_objects(Player.possessions[i]);
        }
      }
      mprint("Your pack disintegrates!");
--- 577,584 ----
      mprint("The Orb of Earth blasts you!");
      for (i=0;i<MAXITEMS;i++) {
        if (Player.possessions[i] != NULL) {
! 	conform_lost_objects(Player.possessions[i]->number,
! 			     Player.possessions[i]);
        }
      }
      mprint("Your pack disintegrates!");
======== End of Diff ========


#9 Addition to earlier Condo bug fix - correctly saves and restores money.
   Do not restore old save files with money in the condo safe after making
   this fix. (Hi Joe! Sorry about this one!)

======== Diff for olev.c ========
*** olev.c~	Mon Feb 22 10:43:44 1988
--- olev.c	Mon Feb 22 10:37:14 1988
***************
*** 502,507 ****
--- 508,515 ----
      write_int(fd,o->blessing);
      write_int(fd,o->aux);
      write_int(fd,o->number);
+     if (o->id == CASHID)
+       write_int(fd,o->basevalue);
    }
    else putc('#',fd);
  }
***************
*** 851,856 ****
--- 865,872 ----
      o->blessing = read_int(fd);
      o->aux = read_int(fd);
      o->number = read_int(fd);
+     if (o->id == CASHID)
+       o->basevalue = read_int(fd);
      if (o->id == CORPSEID) {
        strcpy(o->objstr,Monsters[o->aux].corpsestr);
        strcpy(o->truename,Monsters[o->aux].corpsestr);
======== End of Diff ========


#10 Restore names of corpses carried correctly

======== Diff for olev.c ========
*** olev.c~	Mon Feb 22 10:43:44 1988
--- olev.c	Mon Feb 22 10:37:14 1988
***************
*** 576,585 ****
      else {
        for(i=0;i<NUMLEVELS;i++)
  	Leveldata[i].generated = FALSE;
-       restore_player(fd);
        initmon0to3();
        initmon4to7();
        initmon8to10();
        restore_level(fd);
        restore_level(fd);
        mprint("Restoration complete");
--- 584,593 ----
      else {
        for(i=0;i<NUMLEVELS;i++)
  	Leveldata[i].generated = FALSE;
        initmon0to3();
        initmon4to7();
        initmon8to10();
+       restore_player(fd);
        restore_level(fd);
        restore_level(fd);
        mprint("Restoration complete");
======== End of Diff ========


# 11 SERIOUS - Create Hiscore NPC's correctly

======== Diff for omon.c ========
*** omon.c~	Tue Feb  2 12:01:45 1988
--- omon.c	Fri Feb 19 14:58:20 1988
***************
*** 523,581 ****
    /* each of the high score npc's can be created here */
    switch(npcid) {
    case 1:
-     level = Priestlevel[1];
-     behavior = Priestbehavior[1];
-     break;
    case 2:
-     level = Priestlevel[2];
-     behavior = Priestbehavior[2];
-     break;
    case 3:
-     level = Priestlevel[3];
-     behavior = Priestbehavior[3];
-     break;
    case 4:
-     level = Priestlevel[4];
-     behavior = Priestbehavior[4];
-     break;
    case 5:
-     level = Priestlevel[5];
-     behavior = Priestbehavior[5];
-     break;
    case 6:
!     level = Priestlevel[6];
!     behavior = Priestbehavior[6];
      break;
    case 7:
      level = Shadowlordlevel;
      behavior = Shadowlordbehavior;
      break;
    case 8:
      level = Commandantlevel;
      behavior = Commandantbehavior;
      break;
    case 9:
      level = Archmagelevel;
      behavior = Archmagebehavior;
      break;
    case 10:
      level = Primelevel;
      behavior = Primebehavior;
      break;
    case 11:
      level = Championlevel;
      behavior = Championbehavior;
      break;
    case 12:
-     level = Primelevel;
-     behavior = Primebehavior;
-     break;
-   case 13:
      level = Dukelevel;
      behavior = Dukebehavior;
      break;
    }
-   strcpy(npc->monstring,Str2);
    npc->hp = level*20;
    npc->status = AWAKE+MOBILE+WANDERING;
    combatype = ((int) ((behavior % 100) / 10));
--- 523,576 ----
    /* each of the high score npc's can be created here */
    switch(npcid) {
+   case 0:
+     level = Hilevel;
+     behavior = Hibehavior;
+     strcpy(npc->monstring,Hiscorer);
+     break;
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
+     ob = ((pob) malloc(sizeof(objtype)));
+     *ob = Objects[ARTIFACTID+npcid+13];
+     m_pickup(npc,ob);
!     level = Priestlevel[npcid];
!     behavior = Priestbehavior[npcid];
!     strcpy(npc->monstring,Priest[npcid]);
      break;
    case 7:
      level = Shadowlordlevel;
      behavior = Shadowlordbehavior;
+     strcpy(npc->monstring,Shadowlord);
      break;
    case 8:
      level = Commandantlevel;
      behavior = Commandantbehavior;
+     strcpy(npc->monstring,Commandant);
      break;
    case 9:
      level = Archmagelevel;
      behavior = Archmagebehavior;
+     strcpy(npc->monstring,Archmage);
      break;
    case 10:
      level = Primelevel;
      behavior = Primebehavior;
+     strcpy(npc->monstring,Prime);
      break;
    case 11:
      level = Championlevel;
      behavior = Championbehavior;
+     strcpy(npc->monstring,Champion);
      break;
    case 12:
      level = Dukelevel;
      behavior = Dukebehavior;
+     strcpy(npc->monstring,Duke);
      break;
    }
    npc->hp = level*20;
    npc->status = AWAKE+MOBILE+WANDERING;
    combatype = ((int) ((behavior % 100) / 10));
======== End of Diff ========


#12 SERIOUS - create altar levels correctly

======== Diff for ogen.c ========
*** ogen.c~	Fri Feb 19 16:02:03 1988
--- ogen.c	Mon Feb 22 15:39:37 1988
***************
*** 870,875 ****
--- 870,876 ----
      room_connect_corridor(i,i+1,level);
  
    if (special_level) {
+     populate_level(level,ML8+9);
      do {
        x = random_range(WIDTH);
        y = random_range(LENGTH);
***************
*** 879,893 ****
      Dungeon[level][x][y].p_locf = L_ALTAR;
      Dungeon[level][x][y].aux = special_level;
      Dungeon[level][x][y].stopsrun = TRUE;
!     ml = (pml) malloc(sizeof(mltype));
!     ml->next = NULL;
!     ml->m = 
        Dungeon[level][x][y].creature = 
  	((pmt) make_hiscore_npc(special_level));
!     ml->m->x = x;
!     ml->m->y = y;
!     Mlist[level] = ml;
!     populate_level(level,ML8+9);
      left = 
        Leveldata[level].rooms[Dungeon[level][x][y].roomnumber-ROOMBASE].left;
      right = 
--- 880,890 ----
      Dungeon[level][x][y].p_locf = L_ALTAR;
      Dungeon[level][x][y].aux = special_level;
      Dungeon[level][x][y].stopsrun = TRUE;
!     Mlist[level]->m = 
        Dungeon[level][x][y].creature = 
  	((pmt) make_hiscore_npc(special_level));
!     Mlist[level]->m->x = x;
!     Mlist[level]->m->y = y;
      left = 
        Leveldata[level].rooms[Dungeon[level][x][y].roomnumber-ROOMBASE].left;
      right = 
***************
*** 908,914 ****
        for(l=top;l<bottom;l++)
  	Dungeon[level][k][l].roomnumber = templetype;
    }
!   populate_level(level,-1);
    stock_level(level);
  }
  
--- 905,911 ----
        for(l=top;l<bottom;l++)
  	Dungeon[level][k][l].roomnumber = templetype;
    }
!   else populate_level(level,-1);
    stock_level(level);
  }
  
======== End of Diff ========


#13 Cosmetic change - remove manadrain countdown if JUMPMOVE option set (useful
    for playing over a network).

======== Diff for omove.c ========
*** omove.c~	Mon Jan 25 14:47:57 1988
--- omove.c	Fri Feb 19 16:23:10 1988
***************
*** 203,211 ****
      Dungeon[Dlevel][Player.x][Player.y].locchar = TRAP;
      mprint("A weird rainbow light seems to play over you....");
      mprint("You feel drained.");
!     while (Player.mana > 0) {
!       Player.mana--;
        dataprint();
      }
      dispel(-1);
    }
--- 203,216 ----
      Dungeon[Dlevel][Player.x][Player.y].locchar = TRAP;
      mprint("A weird rainbow light seems to play over you....");
      mprint("You feel drained.");
!     if (optionp(JUMPMOVE)) {
!       Player.mana = 0;
        dataprint();
+     } else {
+       while (Player.mana > 0) {
+ 	Player.mana--;
+ 	dataprint();
+       }
      }
      dispel(-1);
    }
======== End of Diff ========
-- 
Angus Duggan, Department of Computer Science, University of Edinburgh
James Clerk Maxwell Building, The King's Buildings, Mayfield Road,
Edinburgh, EH9 3JZ, Scotland, U.K.
JANET:  ajcd@uk.ac.ed.ecsvax  ARPA: ajcd%ed.ecsvax@nss.cs.ucl.ac.uk
USENET: ajcd@ecsvax.ed.ac.uk  UUCP: ...!mcvax!ukc!ed.ecsvax!ajcd
BITNET: ukacrl.earn!ed.ecsvax!ajcd or ajcd%ed.ecsvax@uk.ac

sam@csri.toronto.edu ("S. Weber") (03/02/88)

I have found yet another bug.  This one's cute.
You can drop items you are wielding without unwielding them.  When you
do this you still receive their benefits.  Drop boots of levitating,
and you are permanently levitating.  Drop a cloak of negimmunity,
and you are permanently immune to negative energies!  This also
happens when a baddie blows up one of your objects:  You still get
the benefits.

-- 
                              -Sam Weber
             "As long as people will accept crap, it will be
           financially profitable to dispense it" --Dick Cavett
UUCP: {ihnp4 utzoo decwrl uw-beaver}!utcsri!sam
ARPA: sam@csri.toronto.edu