Wizardry Proving Grounds v3.0 - Pascal Code Changes
===================================================


Author: E. Labelle (email:snafaru@zimlab.com)
Release date of this document: 03 Aug 2023


Note: These are the code fixes and enhancements. The database fixes are also included in the release.


Web Site:	https://www.zimlab.com/wizardry/proving-grounds-v3


GitHub:		https://github.com/snafaru



The baseline is the re-engineered Pascal source code (and assembler code) from the Wizardry_I program by Thomas William Ewers. This project would not exist without it.

Final compiled file names: STARTUP.CODE WIZARDRY.CODE

Location: Boot and scenario disks.

Summary of Fixes:

	Boot Side: SYSTEM.STARTUP

		Bug/Issue #:	ST001 - Version and Date
		Bug/Issue #:	ST002 - Bypass Copy Protection Check
		Bug/Issue #:	ST003 - Boot Disk Write Protection Check
		Bug/Issue #:	ST004 - 80-Column IIe

	Scenario and Boot Sides: WIZARDRY.CODE
		
		Bug/Issue #:	WC001 - Bishop Bug
		Bug/Issue #:	WC002 - Misspelling Dispel, Morgue and Group #
		Bug/Issue #:	WC003 - Latumapic does not work
		Bug/Issue #:	WC004 - Misspelling of Gilgamesh
		Bug/Issue #:	WC005 - No Friends Fix (a.k.a. monster resists befriending)
		Bug/Issue #:	WC006 - Haman Mahaman
		Bug/Issue #:	WC007 - Object Special Number 23
		Bug/Issue #:	WC008 - Hidden CTRL-G Bell
		Bug/Issue #:	WC009 - Montino
		Bug/Issue #:	WC010 - Regeneration Degeneration
		Bug/Issue #:	WC011 - Monster Affliction Dispel
		Bug/Issue #:	WC012 - Mamorlis
		Bug/Issue #:	WC013 - Mabadi
		Bug/Issue #:	WC014 - Manifo
		Bug/Issue #:	WC015 - To Hit
		Bug/Issue #:	WC016 - Luck (LUCKSKIL)
		Bug/Issue #:	WC017 - Camp Use Item Screen Update
		Enhancement #:	WC018 - Display Hit Probability
		Enhancement #:	WC019 - Remove Password Prompts
		Enhancement #:	WC020 - Show Spells During Combat
		Bug/Issue #:	WC021 - Monsters Wrongly Casting Zilwan
		Bug/Issue #:	WC022 - Treasure Tables Range Bug
		Enhancement #:	WC023 - Surprise Round Enhancement
		Release #:	WC024 - Interim Release 09 Feb 2023 (Includes a Treasure Table fix)
		Bug/Issue #:	WC025 - Fix Addlongs vs Experience Points
		Bug/Issue #:	WC026 - Misspelling Bad Amount
		Enhancement #:	WC027 - Drain Only Once Per Combat Enhancement
		Enhancement #:	WC028 - Loktofeit
		Release #:	WC029 - Interim Release 14 Feb 2023 (Includes fixed spelling)
		Enhancement #:	WC030 - Ninja Enhancements
		Bug/Issue #:	WC031 - Mapiro Mahama Diromat
		Bug/Issue #:	WC032 - Roster Out Characters
		Bug/Issue #:	WC033 - Inventory Full Fix
		Bug/Issue #:	WC034 - Search for Item
		Release #:	WC035 - Release 2023-03-17 and fixed a misspelling
		Release #:	WC036 - Release 2023-03-23 - In alignment with a ProDOS release and added Quit the game.
		Bug/Issue #:	WC037 - Disarm Trap Bug
		Enhancement #:	WC038 - Camp Screen Update
		Release #:	WC039 - Release 09 Apr 2023 - Fix Maze Text Entry Overflow Crash
		Release #:	WC040 - Release 03 Aug 2023 - Pool and Divide Gold and More



Bug/Issue #:	ST001 - Version and Date
========================================

Status:		Fixed. Recompiled. Verified.

Date of change:	26-Dec-2022

Contributor:	E. Labelle

The Issue:	To track which version and release date we are at.

The Fix:	Change the version and date text displayed as needed.	

Source Disk:	Wiz1E.dsk

File:		OPTIONS.TEXT

Segment:	PROCEDURE OPTIONS;  (* P070301 *)

Code From:

    WRITE( '  VERSION 2.1 OF 22-JAN-82  SER:');

Code To:	New text output on boot splash screen. 

    (* ST001 CHANGE VERSION AND DATE DISPLAY AS NEEDED *)
    WRITE( '  VERSION 3.0 OF 26-DEC-22  SER:');

Final Compiled File Name:	SYSTEM.STARTUP

Destination Disk:		Any Wizardry Proving Grounds boot disk.



Bug/Issue #:	ST002 - Bypass Copy Protection Check
====================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	25-Dec-2022

Contributor:	E. Labelle (Information source: Thomas W. Ewers)

The Issue:	After putting a new compiled version of SYSTEM.STARTUP (STARTUP.CODE) on a Wizardry boot disk, the latter will hang on boot. This is due to the copy protection scheme used. Note: Skipping the write-protect check has not been implemented yet, therefore do not forget to write-protect your boot disk, else it will hang.

The Fix:	Remark out the copy protection check to bypass it.	

Source Disk:	Wiz1E.dsk

File:		STARTUP.TEXT

Segment:	PROCEDURE CHKCOPY;  (* P07004 *)

Code From:

          IF GOODCOPY THEN *)

Code To:	Putting the code between "(* " and " *)" makes it a remark and thus it is skipped, therefore bypassing the copy protection check. 

          (* ST001 REMARK OUT/BYPASS COPY PROTECTION CHECK *)
          (* IF GOODCOPY THEN *)

Final Compiled File Name:	SYSTEM.STARTUP

Destination Disk:		Any Wizardry Proving Grounds boot disk.



Bug/Issue #:	ST003 - Boot Disk Write Protection Check
========================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	25-Dec-2022

Contributor:	E. Labelle (Information source: Thomas W. Ewers, Chris Torrence)

The Issue:	If the write-protection tab on a physical diskette, or the read-only flag on a diskette image, is not on then game will go to a blank screen and stay in an infinity loop right after the game boot splash screens.

The Fix:	Remark out the write protection check code to bypass it.	

Source Disk:	Wiz1E.dsk

File:		OPTIONS.TEXT

Segment:	PROCEDURE OPTIONS;  (* P070301 *)

Code From:

    UNITREAD( DRIVE1, IOBUFF, SIZEOF( IOBUFF), 0, 0);
    UNITWRITE( DRIVE1, IOBUFF, SIZEOF( IOBUFF), 0, 0);
    
    IF IORESULT <> 16 THEN
      REPEAT
      UNTIL FALSE;

Code To:	Putting the code between "(* " and " *)" makes it a remark and thus it is skipped, therefore bypassing the write protection check. 

    (* ST003 REMARK OUT/BYPASS BOOT DISK WRITE-PROTECT CHECK *)
    (* UNITREAD( DRIVE1, IOBUFF, SIZEOF( IOBUFF), 0, 0);
    UNITWRITE( DRIVE1, IOBUFF, SIZEOF( IOBUFF), 0, 0);
    
    IF IORESULT <> 16 THEN
      REPEAT
      UNTIL FALSE; *)

Final Compiled File Name:	SYSTEM.STARTUP

Destination Disk:		Any Wizardry Proving Grounds boot disk.



Bug/Issue #:	ST004 - 80-Column IIe
======================================

Status:		Fixed. Verified.

Date of change:	04-Jan-2023

Contributor:	E. Labelle (Information source: Chris Torrence).

References:	https://archive.org/details/WizardryProvingGrounds
		https://www.youtube.com/watch?v=6v35XbbBKQw&t=360s

The Issue:	A bug where on an Apple //e (or //e emulator) with an 80-column card in the aux slot, Wizardry would incorrectly switch to 80-column mode and have weird spacing between all characters and lines on the screen. To fix this, memory location $B91D was changed from a JMP instruction ($6C) to a RTS ($60). This prevents Wizardry from attempting to switch out of 80-column mode, which was actually causing it to switch into 80 columns on an Apple //e.

The Fix:	Hex edit the value 6C to 60. Update the release date.	

Why this fix:	To have Wizardry running in 40-column text mode on an Apple //e or emulator. Sector editing is the only way to accomplish this for now until someone comes up with a better solution.

Sector Editing:
		Start your favorite sector editor
		Insert the Wizardry Boot disk
		Search for Hex 6C F6 00
		Replace Hex 6C to 60
		Note: This can be reversed if you wish or as needed.

Destination Disk:		Any Wizardry Proving Grounds boot disk.



Bug/Issue #:	WC001 - Bishop Bug
==================================

Status:		Fixed. Recompiled. Verified.

Date of change:	19-Dec-2022

Contributor:	E. Labelle (Information source: R. Woodhead)

The Issue:	If your character is a Bishop, it can identify the true name of an item. These items are in its inventory slots 1 through 8. Pressing other keys besides 1 through 8 can have the following benefits:

-	9 : The Bishop gains 100 million experience points.
-	S : The character below the Bishop gains 100 million experience points.
-	J : The character below the Bishop gains 100 million gold pieces.


The fix:

This bug is due to a programming error. The code is similar to "IF (CH>="1") OR (CH<="8") THEN". The "OR" should have been a "AND".

Why this fix:

To prevent exploit and to prevent game corruption if other keys are pressed.	

Source Disk:	Wiz1C.dsk

File:		UTILITIE.TEXT

Segment:	PROCEDURE IDITEM;  (* P010108 *)

Code From:

      UNTIL (ITEMX > 0) OR (ITEMX <= CHARACTR[ CHARX].POSS.POSSCNT);

Code To:

      (* WC001 CHANGE -OR- TO -AND- SO KEYS OUTSIDE 1-8 CANNOT BE USED *)    
      UNTIL (ITEMX > 0) AND (ITEMX <= CHARACTR[ CHARX].POSS.POSSCNT);

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC002 - Misspelling Dispel, Morgue and Group #
==============================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	26-Dec-2022

Contributor:	E. Labelle (Information source: D. Molony, E. Labelle)

The Issue:	Misspelling Dispel and Morgue. Also fixing spelling of "GROUP # ?" for consistency.

- While in the maze, you can cast the Kandi spell to find where a character is. If the character you are looking for is dead but has been brought back to the castle, you get the following message - "The soul of Werdna is.. in the mourge". Corrected "mourge" to "morgue".

- The word "Dispel" was misspelled "Dispell" throughout the game, they are corrected here:
Old Spelling		New Spelling
D)ISPELL		D)ISPEL
DISPELL WHICH GROUP# ?	DISPEL WHICH GROUP # ?
DISPELLS!		DISPELS!


The fix:	Edit the text.

Why this fix:	To correct misspelling and consistency in display.


Source Disk:	Wiz1C.dsk

File:		UTILITIE.TEXT

Segment:	PROCEDURE KANDILOC;  (* P01010C *)

Code From:

              WRITELN( 'IN THE MOURGE')

Code To:

              (* WC002 CHANGE -MOURGE- TO -MORGUE- *)
              WRITELN( 'IN THE MORGUE')


Source Disk:	Wiz1B.dsk

File:		COMBAT2.TEXT

Segment:	PROCEDURE SPGROUP( SPELLI:  INTEGER;  (* P010610 *)

Code From:

                WHICHGRP( 'CAST SPELL ON GROUP #?', SPELLCST)

Code To:

                (* WC002 CHANGE -GROUP #?- TO -GROUP # ?- *)
                WHICHGRP( 'CAST SPELL ON GROUP # ?', SPELLCST)


Source Disk:	Wiz1B.dsk

File:		COMBAT2.TEXT

Segment:	BEGIN (* CACTION *)

Code From:

                          BEGIN
                            BDISPELL := TRUE;
                            PRINTSTR( 'D)ISPELL ')
                          END;
			.
			.
			.
                        'D':  IF BDISPELL THEN
                                WHICHGRP( 'DISPELL WHICH GROUP# ?', -5);
                              
                        'R':  RUNAWAY;
                        
                        'F':  IF MYCHARX < 3 THEN
                                WHICHGRP( 'FIGHT AGAINST GROUP# ?', -1);

Code To:

                          BEGIN
                            BDISPELL := TRUE;
                            (* WC002 CHANGE -'D)ISPELL '- TO -'D)ISPEL  '- *)
                            PRINTSTR( 'D)ISPEL  ')
                          END;
			.
			.
			.
                        'D':  IF BDISPELL THEN
                                (* WC002 CHANGE -DISPELL WHICH GROUP# ?- *)
                                (* TO -DISPEL WHICH GROUP # ?- *)
                                WHICHGRP( 'DISPEL WHICH GROUP # ?', -5);
                              
                        'R':  RUNAWAY;
                        
                        'F':  IF MYCHARX < 3 THEN
                                (* WC002 CHANGE -GROUP# ?- TO -GROUP # ?- *)
                                WHICHGRP( 'FIGHT AGAINST GROUP # ?', -1);


Source Disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Segment:	PROCEDURE DODISPEL;  (* P010913 *)

Code From:

          PRINTSTR( 'DISPELLS!');

Code To:

          (* WC002 CHANGE -DISPELLS!- TO -DISPELS!- *)
          PRINTSTR( 'DISPELS!');


Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC003 - Latumapic does not work
===============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	27-Dec-2022

Contributor:	E. Labelle (Information source: DDG Ahab)

The Issue:	Casting the Latumapic spell does not identify the monsters' true names, thus making this spell useless.

The fix:	Change the loop variable from LLBASE04 to GROUPI.

Why this fix:	To make the Latumapic spell work on on all groups of monsters.

Source Disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Segment:	PROCEDURE DOPRIEST;  (* P01081B *)

Code From:

          IF SPELL = LATUMAPI THEN
            BEGIN
              FOR GROUPI := 1 TO 4 DO
                BATTLERC[ LLBASE04].A.IDENTIFI := TRUE;  (* BUG? WITH BASE04*)
            END;

Code To:

          IF SPELL = LATUMAPI THEN
            BEGIN
              FOR GROUPI := 1 TO 4 DO
                (* WC003 FROM -BATTLERC[ LLBASE04]- TO -BATTLERC[ GROUPI]- *)
                BATTLERC[ GROUPI].A.IDENTIFI := TRUE;  (* BUG? WITH BASE04 *)
            END;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC004 - Misspelling of Gilgamesh
================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	28-Dec-2022

Contributor:	E. Labelle (Information source: E. Labelle)

The Issue:	At the Castle Market, the option to go to G)ilgamesh's Tavern missed it possessive "s".

The fix:	Added trailing "s" in "Gilgamesh's".

Why this fix:	In accordance to standard English rules. Matches how it is spelled everywhere else.

Source Disk:	Wiz1C.dsk

File:		CASTLE2.TEXT

Segment:	PROCEDURE P010A26;  (* P010A26 *)

Code From:

      BEGIN
        GOTOXY( 0, 13);
        WRITE( CHR( 11));
        WRITE( ' ' : 13);
        WRITELN( 'YOU MAY GO TO:');
        WRITELN;
        WRITELN( 'THE A)DVENTURER''S INN, G)ILGAMESH''');
        WRITELN( 'TAVERN, B)OLTAC''S TRADING POST, THE');
        WRITELN( 'TEMPLE OF C)ANT, OR THE E)DGE OF TOWN.')
      END;

Code To:

      BEGIN
        GOTOXY( 0, 13);
        WRITE( CHR( 11));
        WRITE( ' ' : 13);
        WRITELN( 'YOU MAY GO TO:');
        WRITELN;
        (* WC004 CHANGE -G)ILGAMESH''');- TO -G)ILGAMESH''S');- *)
        WRITELN( 'THE A)DVENTURER''S INN, G)ILGAMESH''S');
        WRITELN( 'TAVERN, B)OLTAC''S TRADING POST, THE');
        WRITELN( 'TEMPLE OF C)ANT, OR THE E)DGE OF TOWN.')
      END;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC005 - No Friends Fix
======================================

Status:		Fixed. Recompiled. Verified.

Date of change:	30-Dec-2022

Contributor:	E. Labelle (Information source: E. Labelle)

The Issue:	The monsters' friends/no friends attribute does not work at all. In a monster record, there is an attribute to resist befriending, meaning you cannot have a friendly encounter with them if set to on (or true). The issue was that even if that attribute was on, you could still have a friendly encounter with them.

The fix:	Added a a line of code to the FRIENDLY procedure to check if that monster's attribute is on for the first group of monsters, and if it is then exit the FRIENDLY procedure.

Why this fix:	To make the monster's resistance to befriending work.

Source Disk:	Wiz1B.dsk

File:		COMBAT.TEXT

Segment:	PROCEDURE FRIENDLY;  (* P010509 *)

Code From:
          BEGIN (* FRIENDLY *)
            GOODLEAV := FALSE;

Code To: Note that BATTLERC is the monster group where 1 means the first monster group, WEPVSTY3 is the monster resistance where 0 is No Friends, 1 is Fire, 2 is Cold, Etc.

          BEGIN (* FRIENDLY *)
            (* WC005 EXIT IF FIRST MONSTER GROUP RESISTS BEFRIENDING *)
            IF BATTLERC[ 1].B.WEPVSTY3[ 0] THEN
              EXIT (FRIENDLY);
          
            GOODLEAV := FALSE;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC006 - Haman Mahaman
=====================================

Status:		Fixed. Recompiled. Verified.

Date of change:	01-Jan-2023

Contributor:	E. Labelle (Information source: Thomas W. Ewers)

The Bug:	There are supposed to be seven possible effects, with less powerful ones more likely to be selected. Instead, each spell has three possible effects with equal distribution, and two of the effects are impossible.

The fix:	Added parenthesis and changed the Mahaman flag value from 7 to 8.

Why this fix:	To make Haman and Mahaman work as intended.

Source Disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Segment:	PROCEDURE HAMMAHAM( MAHAMFLG: INTEGER);  (* P01080E *)
		and
		PROCEDURE DOMAGE;  (* P01081C *)

Code From:
        BEGIN  (* HAMMAHAM *)
          IF MAHAMFLG = 7 THEN
            PRINTSTR( 'MA');
          PRINTSTR( 'HAMAN IS INTONED AND...');
          PAUSE2;
          MVCURSOR( 1, 13);
          IF CHARACTR[ BATI].CHARLEV < 13 THEN
            BEGIN
              PRINTSTR( 'FAILS!');
              EXIT( HAMMAHAM)
            END;
          CHARACTR[ BATI].CHARLEV := CHARACTR[ BATI].CHARLEV - 1;
          DRAINED[ BATI] := TRUE;
          
          CASE RANDOM MOD 3 * MAHAMFLG OF     (* MAHAMFLG IS 6 OR 7 *)
             0,  1,  2,  3,  4,  5:  HAMCURE;   (*     1? 2? 3? 4? 5? *)
                 7,  8,  9, 10, 11:  HAMSILEN;  (*     8? 9? 10? 11?  *)
                    12, 13, 22, 23:  HAMMAGIC;  (*    13?, 22?, 23?   *)
                        14, 20, 21:  HAMTELEP;  (*    14?, 20?        *)
                         6, 15, 19:  HAMHEAL;   (*    15?, 19?        *)
                                17:  HAMPROT;   (*    17?      DEAD CODE    *)
                            16, 18:  HAMALIVE;  (*    16?, 18? DEAD CODE    *)
                            
          (* MAYBE THEY WANTED "RANDOM MOD (3 * MAHAMFLG)",
             AND MAHAMFLG = 6 OR 8 DEPENDING ON SPELL *)
                            
          END;

Code To:
        BEGIN  (* HAMMAHAM *)
          (* WC006 FROM -MAHAMFLG = 7- TO -MAHAMFLG = 8 *)
           IF MAHAMFLG = 8 THEN
            PRINTSTR( 'MA');
          PRINTSTR( 'HAMAN IS INTONED AND...');
          PAUSE2;
          MVCURSOR( 1, 13);
          IF CHARACTR[ BATI].CHARLEV < 13 THEN
            BEGIN
              PRINTSTR( 'FAILS!');
              EXIT( HAMMAHAM)
            END;
          CHARACTR[ BATI].CHARLEV := CHARACTR[ BATI].CHARLEV - 1;
          DRAINED[ BATI] := TRUE;
          
          (* WC006 FROM -3 * MAHAMFLG- TO -(3 * MAHAMFLG)- *)
          CASE RANDOM MOD (3 * MAHAMFLG) OF     (* MAHAMFLG IS 6 OR 8 *)
             0,  1,  2,  3,  4,  5:  HAMCURE;
                 7,  8,  9, 10, 11:  HAMSILEN;
                    12, 13, 22, 23:  HAMMAGIC;
                        14, 20, 21:  HAMTELEP;
                         6, 15, 19:  HAMHEAL;
                                17:  HAMPROT;
                            16, 18:  HAMALIVE;
          END;

Code From:
          IF SPELL = MAHAMAN THEN
            HAMMAHAM( 7);

Code To:
          IF SPELL = MAHAMAN THEN
            (* WC006 CHANGE -HAMMAHAM( 7)- TO -HAMMAHAM( 8)- *)
            HAMMAHAM( 8);

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC007 - Object Special Number 23
================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	02-Jan-2023

Contributor:	E. Labelle (Information source: Thomas W. Ewers)

The Bug:	Error in code.

The fix:	Added "- 1" to the code so that the routine applies the effect to characters 1 through 6 instead of 1 through 7.

Why this fix:	To have the correct code.

Source Disk:	Wiz1B.dsk

File:		UTILITIE2.TEXT

Segment:	PROCEDURE CHSPCPOW;  (* P01011A *)

Code From:
                          23: BEGIN
                                (* LOOKS LIKE BUG!  PARTYCNT - 1  !!! *)
                                FOR SPCTEMP := 0 TO PARTYCNT DO
                                    CHARACTR[ SPCTEMP].HPLEFT :=
                                      CHARACTR[ SPCTEMP].HPMAX
                              END;

Code To:
                          23: BEGIN
                                (* WC007 FROM -PARTYCNT- TO -PARTYCNT - 1- *)
                                FOR SPCTEMP := 0 TO PARTYCNT - 1 DO
                                    CHARACTR[ SPCTEMP].HPLEFT :=
                                      CHARACTR[ SPCTEMP].HPMAX
                              END;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC008 - Hidden CTRL-G Bell
==========================================

Status:		Fixed. Recompiled. Verified.

Date of change:	03-Jan-2023

Contributor:	E. Labelle (Information source: Thomas W. Ewers)

The Issue:	The COMBAT5.TEXT contains three hidden CTRL-G ascii characters to ring the BELL 3 times for when your character scores a critical hit. Key word here: hidden.

The fix:	Replace the three hidden CTRL-G by three CHR(7).

Why this fix:	To avoid future problems when editing or viewing COMBAT5.TEXT. To make it clear what is going on in the code.

Source Disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Segment:	PROCEDURE DAM2ENMY;  (* P01090F *)

Code From:
                        BEGIN
                          MVCURSOR( 1, 14);
                          PRINTSTR( 'A CRITICAL HIT!');
                          WRITE( '');
                          BATTLERC[ VICTIM].A.TEMP04[ SINGLEX].HPLEFT := 0;
                          PAUSE1;
                          CLRRECT( 1, 14, 38, 1)
                        END;

Code To:
                        BEGIN
                          MVCURSOR( 1, 14);
                          PRINTSTR( 'A CRITICAL HIT!');
                          (* WC008 REPLACE THREE HIDDEN CTRL-G BY CHR( 7) *)
                          WRITE( CHR( 7), CHR( 7), CHR( 7));
                          BATTLERC[ VICTIM].A.TEMP04[ SINGLEX].HPLEFT := 0;
                          PAUSE1;
                          CLRRECT( 1, 14, 38, 1)
                        END;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC009 - Montino
===============================

Status:		Fixed. Recompiled. Verified.

Date of change:	05-Jan-2023

Contributor:	E. Labelle (Information source: DDG Ahab)

The Issue:	The silencing effect of Montino (silence) is meant to wear off, but it does not.

The fix:	Adjust wrong variable pointer, added missing line of code.

Why this fix:	To have the Montino (silence) effect to wear off as intended.

Source Disk:	Wiz1B.dsk

File:		COMBAT3.TEXT

Segment:	PROCEDURE HEALHEAR;  (* P010623 *)

Code From:
            BEGIN
              FOR X := 0 TO ALIVECNT - 1 DO
                IF BATTLERC[ GROUPI].A.TEMP04[ ALIVECNT].INAUDCNT > 0 THEN
                   BATTLERC[ GROUPI].A.TEMP04[ ALIVECNT].INAUDCNT :=
                   BATTLERC[ GROUPI].A.TEMP04[ ALIVECNT].INAUDCNT - 1
            END;  (* DECINAUD *)
            
            
          BEGIN (* HEALHEAR *)
            DECINAUD( 0, PARTYCNT);
            DECINAUD( 1, BATTLERC[ 1].A.ALIVECNT);
            DECINAUD( 2, BATTLERC[ 2].A.ALIVECNT);
            DECINAUD( 3, BATTLERC[ 3].A.ALIVECNT)
          END; (* HEALHEAR *)

Code To:
            BEGIN
              FOR X := 0 TO ALIVECNT - 1 DO
                (* WC009 FROM -[ ALIVECNT]- TO -[ X]- *)
                IF BATTLERC[ GROUPI].A.TEMP04[ X].INAUDCNT > 0 THEN
                   BATTLERC[ GROUPI].A.TEMP04[ X].INAUDCNT :=
                   BATTLERC[ GROUPI].A.TEMP04[ X].INAUDCNT - 1
            END;  (* DECINAUD *)
            
            
          BEGIN (* HEALHEAR *)
            DECINAUD( 0, PARTYCNT);
            DECINAUD( 1, BATTLERC[ 1].A.ALIVECNT);
            DECINAUD( 2, BATTLERC[ 2].A.ALIVECNT);
            DECINAUD( 3, BATTLERC[ 3].A.ALIVECNT);
            (* WC009 ADDED NEXT LINE WAS MISSING LAST GROUP OF MONSTERS *)
            DECINAUD( 4, BATTLERC[ 4].A.ALIVECNT)
          END; (* HEALHEAR *)

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC010 - Regeneration Degeneration
=================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	06-Jan-2023

Contributor:	E. Labelle (Information source: DDG Ahab)

The Issue:	HEALPTS (hit points regeneration and degeneration) is probably meant to stack but instead, it just takes whatever item has the biggest heal value. Consequently, the DEADLY RING's HP draining property has no effect.

The fix:	Adjust code to have regeneration and degeneration items stack. Poison and stacking poison from chest traps are also taken in account.

Why this fix:	To have regeneration and degeneration effects stack. The Deadly Ring is now actually deadly.

Source Disk:	Wiz1B.dsk

File:		UTILITIE2.TEXT

Segment:	PROCEDURE NORMPOW;  (* P01011D *)

Code From:
              IF CHARACTR[ CHARI].HEALPTS < OBJECT.HEALPTS THEN
                CHARACTR[ CHARI].HEALPTS := OBJECT.HEALPTS;

Code To:
              (* WC010 MAKE OBJECT REGEN STACK AND INCLUDE NEGATIVE AMOUNTS *)
              (* REMOVE -IF CHARACTR[ CHARI].HEALPTS < OBJECT.HEALPTS THEN- *)
              (* REMOVE -CHARACTR[ CHARI].HEALPTS := OBJECT.HEALPTS;- *)
              (* ADD NEXT LINE *)
                CHARACTR[ CHARI].HEALPTS := CHARACTR[ CHARI].HEALPTS + OBJECT.HEALPTS;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC011 - Monster Affliction Dispel
=================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	07-Jan-2023

Contributor:	E. Labelle (Information source: DDG Ahab)

The Issue:	Dispel does not work on undead monsters with status afflictions. This would be a pretty rare occurrence though; Katino doesn't work on the undead, and casting Manifo when you can just dispel them is a bit crazy.

The fix:	Adjust code to have dispel work on monsters that have an affliction.

Why this fix:	To have dispel work on monsters that have an affliction.

Source Disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Segment:	PROCEDURE DODISPEL;  (* P010913 *)

Code From:
            IF BATTLERC[ VICTIM].A.TEMP04[ CHARX].STATUS = OK THEN

Code To:
            (* WC011 FROM -= OK- TO -< DEAD- *)
            IF BATTLERC[ VICTIM].A.TEMP04[ CHARX].STATUS < DEAD THEN

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC012 - Mamorlis
================================

Status:		Fixed. Recompiled. Verified.

Date of change:	09-Jan-2023

Contributor:	E. Labelle

The Issue:	Mamorlis is supposed to fear all the monsters (reduce their armor class by 3) but the 1st monster of each group is not affected.

The fix:	Adjust code to have all monsters affected.

Why this fix:	To have all monsters affected.

Source Disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Segment:	PROCEDURE DOMAGE;  (* P01081C *)

Code From:
          IF SPELL = MAMORLIS THEN
            FOR GROUPI := 1 TO 4 DO
              MODAC( GROUPI, -3, 1, BATTLERC[ GROUPI].A.ALIVECNT);

Code To:
          IF SPELL = MAMORLIS THEN
            FOR GROUPI := 1 TO 4 DO
              (* WC012 FROM -1-, -ALIVECNT- TO -0-, -ALIVECNT - 1- *)
              MODAC( GROUPI, -3, 0, BATTLERC[ GROUPI].A.ALIVECNT - 1);

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC013 - Mabadi
==============================

Status:		Fixed. Recompiled. Verified.

Date of change:	11-Jan-2023

Contributor:	E. Labelle

The Issue:	Monsters " IS HIT BY MABADI!" message is displayed although no monsters are left alive.

The fix:	Added code to skip that effect and message if the monster is dead. Also, removed an extra space at the beginning of " IS HIT...".

Why this fix:	To skip the Mabadi effect and message if the monster is dead.

Source Disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Segment:	PROCEDURE DOPRIEST;  (* P01081B *)

Code From:
          IF SPELL = MABADI THEN
            BEGIN
              CLRRECT( 1, 12, 38, 3);
              MVCURSOR( 1, 12);
              DSPNAMES( CASTGR, CASTI);
              PRINTSTR( ' IS HIT BY MABADI!');
               BATTLERC[ CASTGR].A.TEMP04[ CASTI].HPLEFT := 
                 1 + (RANDOM MOD 8);
            END;

Code To:
          IF SPELL = MABADI THEN
            (* WC013 ADD NEXT LINE *)
            IF BATTLERC[ CASTGR].A.TEMP04[ CASTI].STATUS < DEAD THEN
              BEGIN
                CLRRECT( 1, 12, 38, 3);
                MVCURSOR( 1, 12);
                DSPNAMES( CASTGR, CASTI);
                (* WC013 REMOVE EXTRA BEGINNING SPACE *)
                PRINTSTR( 'IS HIT BY MABADI!');
                  BATTLERC[ CASTGR].A.TEMP04[ CASTI].HPLEFT := 
                    1 + (RANDOM MOD 8);
              END;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC014 - Manifo
==============================

Status:		Fixed. Recompiled. Verified.

Date of change:	14-Jan-2023

Contributor:	E. Labelle (Information source: DDG Ahab)

The Issue:	Monsters affected by Manifo wrongly get the status Asleep instead of Paralyzed. Monster resistance to Manifo is so high that the spell is essentially useless.

The fix:	Adjust the code so that the monsters have the status PLYZE instead of ASLEEP if affected by Manifo. Reduce the monsters' resistance to Manifo so that it now sits in between the original setting and Legacy of Llylgamyn (over-powered). Ex: Now a level 3 monster has a 65% chance to resist Manifo, compared to a 60% chance to resist Katino. The second fix was done out of necessity and for negligeable coding space (less than 512 bytes left on disk for coding) and can easily be reversed or changed if necessary.

Why this fix:	To make the Manifo spell work as intended. Also, this makes use of the code that is already in the game for the monsters to recuperate from a paralysis effect. Make Manifo a useful spell.

Source Disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Segment:	PROCEDURE ISISNOT( GROUPI:    INTEGER;  (* P010804 *)
		PROCEDURE DOHOLD;  (* P010809 *)

Code From:
            BEGIN
              PRINTSTR( 'IS ');
              CASE DAMTYPE OF
              
                0, 3:  BATTLERC[ GROUPI].A.TEMP04[ CHARI].STATUS := ASLEEP;
                
                   1:  BATTLERC[ GROUPI].A.TEMP04[ CHARI].INAUDCNT :=
                         (RANDOM MOD 4) + 2;
                         
                   2:  BEGIN
                         BATTLERC[ GROUPI].A.TEMP04[ CHARI].STATUS := DEAD;
                         BATTLERC[ GROUPI].A.TEMP04[ CHARI].HPLEFT := 0
                       END
              END
            END;

Code To:
            BEGIN
              PRINTSTR( 'IS ');
              CASE DAMTYPE OF
              
                   (* WC014 ENABLED PARALYZE EFFECTS *)
                   0:  BATTLERC[ GROUPI].A.TEMP04[ CHARI].STATUS := PLYZE;
                
                   1:  BATTLERC[ GROUPI].A.TEMP04[ CHARI].INAUDCNT :=
                         (RANDOM MOD 4) + 2;
                         
                   2:  BEGIN
                         BATTLERC[ GROUPI].A.TEMP04[ CHARI].STATUS := DEAD;
                         BATTLERC[ GROUPI].A.TEMP04[ CHARI].HPLEFT := 0
                       END;
                   
                   3:  BATTLERC[ GROUPI].A.TEMP04[ CHARI].STATUS := ASLEEP
              END
            END;

Code From:
                ISISNOT( CASTGR,
                         CHARX,
                         50 + 10 * BATTLERC[ CASTGR].B.HPREC.LEVEL
                         ,
                         'HELD',
                         0)

Code To:
                (* WC014 FROM -10 *- TO -5 *- *)
                ISISNOT( CASTGR,
                         CHARX,
                         50 + 5 * BATTLERC[ CASTGR].B.HPREC.LEVEL
                         ,
                         'HELD',
                         0)

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC015 - To Hit
==============================

Status:		Fixed. Recompiled. Verified.

Date of change:	17-Jan-2023.

Contributor:	E. Labelle (Information source: DDG Ahab).

The Issue:	Monsters in the front row were harder to hit than monsters in the back row, which made no sense.

The fix:	The variable VICTIM is monster groups 1 to 4. Changed the code to: "+ ((3 * VICTIM) - 6);". Extra set of parentheses here to make sure nothing stupid happens and for clarity. This way, the chance to hit the first monster group does not change, i.e., -3 (-15%), a minus number here is good, but each subsequent monster groups are harder to hit by 3 (15%).

Why this fix:	To make the "To Hit" chance against the monsters work properly and logically.

Source Disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Segment:	PROCEDURE DAM2ENMY;  (* P01090F *)

Code From:
                HPCALCPC := 21
                              - BATTLERC[ VICTIM].B.AC
                              - CHARACTR[ BATI].HPCALCMD
                              + BATTLERC[ VICTIM].A.TEMP04[ SINGLEX].ARMORCL
                              - 3 * VICTIM;

Code To:
                HPCALCPC := 21
                              - BATTLERC[ VICTIM].B.AC
                              - CHARACTR[ BATI].HPCALCMD
                              + BATTLERC[ VICTIM].A.TEMP04[ SINGLEX].ARMORCL
                              + ((3 * VICTIM) - 6);
                              (* WC015 FROM - 3 * VICTIM *)

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC016 - Luck (LUCKSKIL)
=======================================

Status:		Fixed. Recompiled. Verified.

Date of change:	24-Jan-2023.

Contributor:	E. Labelle (Information source: E. Labelle, DDG Ahab).

The Issue:	Saving throws inconsistency.

The fix:	Saving throws are based on your character's Luck attribute and a modifier. After a long analysis, everything jives except for saving vs the chests' Poison Gas Trap. It pointed to "3" (Breath) attack, changed it to "2". Wizardry matches the 1979 AD&D Saving Throw table (http://grognardia.blogspot.com/2020/12/saving-throws.html). Detailed information at the end of this issue.

Why this fix:	This makes use of saving throw category "2", and it did not make sense for the Poison Gas Trap and Breath Attack being in the same category.

Source Disk:	Wiz1C.dsk

File:		REWARDS.TEXT

Segment:	PROCEDURE TYPE3DAM;  (* P010D11 *)

Code From:
              2:  (* GAS *)
              
                    FOR CHARX := 0 TO PARTYCNT - 1 DO
                      IF (RANDOM MOD 20) < CHARACTR[ CHARX].LUCKSKIL[ 3] THEN
                        CHARACTR[ CHARX].LOSTXYL.POISNAMT[ 1] := 1;

Code To:
              2:  (* GAS *)
              
                    FOR CHARX := 0 TO PARTYCNT - 1 DO
                      (* WC016 FROM -[ 3]- TO -[ 2]- *)
                      IF (RANDOM MOD 20) < CHARACTR[ CHARX].LUCKSKIL[ 2] THEN
                        CHARACTR[ CHARX].LOSTXYL.POISNAMT[ 1] := 1;

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.

Details:

There are the 5 saving throw checks used in the game:

0 - Poison & Paralysis & Critical Hit (Special monster skills).
1 - Stone.
2 - Was not used, moved the Poison Gas Chest Trap here.
3 - Breath. Poison Gas Chest Trap, made no sense, moved to 2.
4 - Silence. Anti-Mage/Anti-Priest Chest Traps.

Here are the compiled resistances, after changes, each point is 5%:

- [0] Vs. Poison & Paralysis & Critical Hit: Fighter 15%, Samurai 10%, Lord 10%, Ninja 15%, and if race is Human 5%.
- [1] Vs. Stoning: Priest 15%, Bishop 10%, Lord 10%, Ninja 10%, and if race is Gnome 10%.
- [2] Vs. Poison Gas Chest Trap: Bishop 10%, Ninja 20%, and if race is Elf 10%. 
- [3] Vs. Breath Attacks: Thief 15%, Ninja 15%, and if race is Dwarf 20% to reduce the Breath damage by half.
- [4] Vs. Anti-Mage and Anti-Priest chest trap and Silence: Mage 15%, Bishop 10%, Samurai 10%, Ninja 10%, and if the race is Hobbit 15%.

- Vs. all of the above: add 5% for every 5 Levels of your character.
- Vs. all of the above: add 5% if your Luck is 6, 10% if your Luck is 12, and 15% if your Luck is 18.

LUCKSKIL analysis:

wiz
---

PROGRAM WIZARDRY;
        TCHAR = RECORD
            LUCKSKIL : PACKED ARRAY[ 0..4] OF 0..31;


roller
------

    PROCEDURE MAKECHAR;  (* P010B09 *)
      
      
      PROCEDURE INITCHAR;  (* P010B0A *)
      
        VAR
             LSI    : INTEGER;
             UNUSED : INTEGER;
      
        BEGIN
          FILLCHAR( CHARREC, SIZEOF( CHARREC), 0);
          CHARREC.NAME := CHARNAME;
          CHARREC.AGE := (18 * 52) + (RANDOM MOD 300);
          CHARREC.GOLD.LOW := 90 + (RANDOM MOD 100);
          CHARREC.STATUS := OK;
          FOR LSI := 0 TO 4 DO
            BEGIN
              CHARREC.LUCKSKIL[ LSI] := 16
            END;
          CHARREC.MAXLEVAC := 1;
          CHARREC.CHARLEV := 1;
          CHARREC.ARMORCL := 10
        END;


utilitie2
---------
      PROCEDURE UPLCKSKL( LSSUB:    INTEGER;  (* P010123 *)
                          LSMODAMT: INTEGER);
      
        BEGIN
          LSMODAMT := CHARACTR[ CHARI].LUCKSKIL[ LSSUB] - LSMODAMT;
          IF LSMODAMT < 1 THEN
            LSMODAMT := 1;
          CHARACTR[ CHARI].LUCKSKIL[ LSSUB] := LSMODAMT
        END;
        
        
      PROCEDURE INITSTUF;  (* P010124 *)
      
        VAR
             X : INTEGER;
             Y : INTEGER;
      
        BEGIN
          WITH CHARACTR[ CHARI] DO
            BEGIN
              FOR X := 0 TO 13 DO
                BEGIN
                  WEPVSTY2[ 0][ X] := FALSE;
                  WEPVSTY2[ 1][ X] := FALSE;
                  WEPVSTYP[ X] := FALSE
                END;
              FOR Y := 0 TO 6 DO
                BEGIN
                  WEPVSTY3[ 0][ Y] := FALSE;
                  WEPVSTY3[ 1][ Y] := FALSE
                END
            END
        END;
        
        
      BEGIN  (* EQUIPCHR *)
        WITH CHARACTR[ CHARI] DO
          BEGIN
            TEMPX := (20 - CHARLEV DIV 5) - (ATTRIB[ LUCK] DIV 6);
            IF TEMPX < 1 THEN
              TEMPX := 1;
            FOR LUCKI := 0 TO 4 DO
              LUCKSKIL[ LUCKI] := TEMPX;
              
            CASE CLASS OF
            
              FIGHTER :   UPLCKSKL( 0, 3);
                 MAGE :   UPLCKSKL( 4, 3);
               PRIEST :   UPLCKSKL( 1, 3);
                THIEF :   UPLCKSKL( 3, 3);
                
               BISHOP : BEGIN
                          UPLCKSKL( 2, 2);
                          UPLCKSKL( 4, 2);
                          UPLCKSKL( 1, 2);
                        END;
                        
              SAMURAI : BEGIN
                          UPLCKSKL( 0, 2);
                          UPLCKSKL( 4, 2);
                        END;
                        
                 LORD : BEGIN
                          UPLCKSKL( 0, 2);
                          UPLCKSKL( 1, 2);
                        END;
                          
                NINJA : BEGIN
                          UPLCKSKL( 0, 3);
                          UPLCKSKL( 1, 2);
                          UPLCKSKL( 2, 4);
                          UPLCKSKL( 3, 3);
                          UPLCKSKL( 4, 2);
                        END;
               
            END;
            
            CASE RACE OF
               HUMAN:  UPLCKSKL( 0, 1);
                 ELF:  UPLCKSKL( 2, 2);
               DWARF:  UPLCKSKL( 3, 4);
               GNOME:  UPLCKSKL( 1, 2);
              HOBBIT:  UPLCKSKL( 4, 3);
            END;


rewards
-------
            BEGIN  (* ANTIPM *)
              FOR CHARPM := 0 TO PARTYCNT - 1 DO
                BEGIN
                  PLYZSTON := (RANDOM MOD 20) < CHARACTR[ CHARPM].LUCKSKIL[ 4];
                  
                  CASE CHARACTR[ CHARPM].CLASS OF
                  
                       MAGE:  IF BMAGEDAM THEN
                                IF PLYZSTON THEN
                                  ISPLYZE
                                ELSE
                                  ISSTONED;
                                  
                    SAMURAI:  IF BMAGEDAM THEN
                                IF NOT PLYZSTON THEN
                                  ISPLYZE;
                                 
                     PRIEST:  IF NOT BMAGEDAM THEN
                                IF PLYZSTON THEN
                                  ISPLYZE
                                ELSE
                                  ISSTONED;
                                  
                     BISHOP:  IF NOT BMAGEDAM THEN
                                IF NOT PLYZSTON THEN  (* IF NOT SET... *)
                                  ISPLYZE;
                  END
                END
            END;   (* ANTIPM *)
.
.
.
          BEGIN (* DOTRAPDM *)
            CLRRECT( 13, 8, 26, 2);
            MVCURSOR( 13, 8);
            IF TRAPTYPE <> 0 THEN
              BEGIN
                PRINTSTR( 'OOPPS! A ');
                PRTRAPTY( TRAPTYPE, TRAP3TYP)
              END
            ELSE
              PRINTSTR( 'THE CHEST WAS NOT TRAPPED');
            PAUSE2;
            
            CASE TRAPTYPE OF
            
              1:  (* POISON *)
              
                    CHARACTR[ CHRXCHST].LOSTXYL.POISNAMT[ 1] :=
                      CHARACTR[ CHRXCHST].LOSTXYL.POISNAMT[ 1] + 1;
                   
              2:  (* GAS *)
              
                    FOR CHARX := 0 TO PARTYCNT - 1 DO
                      IF (RANDOM MOD 20) < CHARACTR[ CHARX].LUCKSKIL[ 3] THEN
                        CHARACTR[ CHARX].LOSTXYL.POISNAMT[ 1] := 1;


combat4
-------

      PROCEDURE DOSILENC;  (* P01080A *)
      
        VAR
             CHARX : INTEGER;
      
        BEGIN
          FOR CHARX := 0 TO BATTLERC[ CASTGR].A.ALIVECNT - 1 DO
            IF CASTGR = 0 THEN
              ISISNOT( CASTGR,
                       CHARX,
                        100 - 5 * CHARACTR[ CHARX].LUCKSKIL[ 4],
                       'SILENCED',
                       1)
            ELSE
              ISISNOT( CASTGR,
                       CHARX,
                       10 * BATTLERC[ CASTGR].B.HPREC.LEVEL, 
                       'SILENCED',
                       1)
        END;


combat5
-------
            PROCEDURE RESULT( ATTK0123: INTEGER;  (* P01090B *)
                              STONFLAG: INTEGER;
                              POISSTON: INTEGER;
                              DAMSTR:   STRING);
            
              VAR
                   CHANCBAD : INTEGER;
            
              BEGIN
                IF (RANDOM MOD 20) >
                                  CHARACTR[ MYVICTIM].LUCKSKIL[ STONFLAG] THEN
                  EXIT( RESULT);
                IF ATTK0123 = 3 THEN
                  BEGIN
                    CHANCBAD := BATTLERC[ BATG].B.HPREC.LEVEL * 2;
                    IF CHANCBAD > 50 THEN
                      CHANCBAD := 50;
                    IF (RANDOM MOD 100) > CHANCBAD THEN
                      EXIT( RESULT)
                  END;
                IF POISSTON > 0 THEN
                  IF CHARACTR[ MYVICTIM].WEPVSTY3[ 1][ POISSTON] THEN
                    EXIT( RESULT);
                IF CHARACTR[ MYVICTIM].STATUS >= DEAD THEN
                  EXIT( RESULT);
                CLRRECT( 1, 14, 38, 1);
                MVCURSOR( 1, 14);
                PRNAME( 0, MYVICTIM);
                PRINTSTR( 'IS ');
                PRINTSTR( DAMSTR );
                CASE ATTK0123 OF
                
                  0:  IF BATTLERC[ 0].A.TEMP04[ MYVICTIM].STATUS < STONED THEN
                        BATTLERC[ 0].A.TEMP04[ MYVICTIM].STATUS := STONED;
                
                  1:  CHARACTR[ MYVICTIM].LOSTXYL.POISNAMT[ 1] := 1;
                     
                  2:  IF BATTLERC[ 0].A.TEMP04[ MYVICTIM].STATUS < PLYZE THEN
                        BATTLERC[ 0].A.TEMP04[ MYVICTIM].STATUS := PLYZE;
                       
                  3:  BEGIN
                        BATTLERC[ 0].A.TEMP04[ MYVICTIM].STATUS := DEAD;
                        BATTLERC[ 0].A.TEMP04[ MYVICTIM].HPLEFT := 0
                      END
                END;
                PAUSE1
              END;  (* RESULT *)
            
            
            BEGIN  (* CASEDAMG *)
              WITH BATTLERC[ BATG].B DO
                BEGIN
                  IF SPPC[ 1] THEN
                    RESULT( 1, 0, 3, 'POISONED');
                  IF SPPC[ 2] THEN
                    RESULT( 2, 0, 0, 'PARALYZED');
                  IF SPPC[ 0] THEN
                    RESULT( 0, 1, 5, 'STONED');
                    
                  IF DRAINAMT > 0 THEN
                    DRAINLEV;
                    
                  IF SPPC[ 3] THEN
                    RESULT( 3, 0, 0, 'CRITICALLY HIT')
                END
            END;  (* CASEDAMG *)


combat5
-------

      PROCEDURE DOBREATH;  (* P010906 *)
      
        VAR
             UNUSED : INTEGER;
             HITDAM : INTEGER;
             CHARX  : INTEGER;
      
        BEGIN
          PRINTSTR(  'BREATHES!');
          FOR CHARX := 0 TO PARTYCNT - 1 DO
            BEGIN
              IF BATTLERC[ 0].A.TEMP04[ CHARX].STATUS < DEAD THEN
                BEGIN
                  CLRRECT( 1, 12, 38, 3);
                  MVCURSOR( 1, 12);
                  HITDAM := BATTLERC[ BATG].A.TEMP04[ BATI].HPLEFT DIV 2;
                  IF (RANDOM MOD 20) >= CHARACTR[ CHARX].LUCKSKIL[ 3] THEN
                    HITDAM := (HITDAM + 1) DIV 2;
                  IF CHARACTR[ CHARX].WEPVSTY3[ 1][ BATTLERC[ BATG].B.BREATHE] 
                      THEN
                    HITDAM := (HITDAM + 1) DIV 2;
                  UNAFFECT( 0, CHARX, HITDAM)
                END
            END
        END;


            PROCEDURE RESULT( ATTK0123: INTEGER;  (* P01090B *)
                              STONFLAG: INTEGER;
                              POISSTON: INTEGER;
                              DAMSTR:   STRING);
            
              VAR
                   CHANCBAD : INTEGER;
            
              BEGIN
                IF (RANDOM MOD 20) >
                                  CHARACTR[ MYVICTIM].LUCKSKIL[ STONFLAG] THEN
                  EXIT( RESULT);
.
.
.
            BEGIN  (* CASEDAMG *)
              WITH BATTLERC[ BATG].B DO
                BEGIN
                  IF SPPC[ 1] THEN
                    RESULT( 1, 0, 3, 'POISONED');
                  IF SPPC[ 2] THEN
                    RESULT( 2, 0, 0, 'PARALYZED');
                  IF SPPC[ 0] THEN
                    RESULT( 0, 1, 5, 'STONED');



Bug/Issue #:	WC017 - Camp Use Item Screen Update
===================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	25-Jan-2023.

Contributor:	E. Labelle.

The Issue:	When in Camp, if using an item and it decays (Ex: Dios Potion > Broken Item), the display still shows the undecayed item name.

The fix:	Add a line of code to refresh the items list after an item has been used.

Why this fix:	To have the correct items' names displayed after use.

Source Disk:	Wiz1C.dsk

File:		CAMP.TEXT

Segment:	PROCEDURE USEITEM;  (* P010C11 *)

Code From:
          CASTSPEL( SCNTOC.SPELLHSH[ THEITEM.SPELLPWR])

Code To:
          CASTSPEL( SCNTOC.SPELLHSH[ THEITEM.SPELLPWR]);
          (* WC017 ADD NEXT LINE *)
          DSPITEMS

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC018 - Display Hit Probability
===============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	27-Jan-2023.

Contributor:	E. Labelle.

The Issue:	Enhance the battle details display by showing the hit probability of characters and monsters on-the-fly.

The fix:	Added code to accomplish this.

Why this fix:	Enhance the display of battle information.

Source Disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Segments:	PROCEDURE DOFIGHT;  (* P010907 *)
		PROCEDURE DAM2ME;  (* P010908 *)
		PROCEDURE DAM2ENMY;  (* P01090F *)

Code From:
      N/A.

Code To:
      PROCEDURE DOFIGHT;  (* P010907 *)

        (* WC018 DISPLAY HIT PROBABILITY *)
        PROCEDURE HITPROB( HITP: INTEGER);
          
          BEGIN
            PRINTSTR( 'WITH A HIT PROB OF ');
            PRINTNUM( (20 - HITP) * 5, 2);
            PRINTSTR( '%')
          END;
.
.
.
        PROCEDURE DAM2ME;  (* P010908 *)
...
                (* WC018 DISPLAY HIT PROBABILITY *)
                PRINTSTR( ' ');
                HITPROB( HPCALCPC);
.
.
.
        PROCEDURE DAM2ENMY;  (* P01090F *)
...
                HITPROB( HPCALCPC); (* WC018 DISPLAY HIT PROBABILITY *)

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC019 - Remove Password Prompts
===============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	29-Jan-2023.

Contributor:	E. Labelle.

The Issue:	Cannot add any more code since the floppy disk is full.

The fix:	Removed all the code pertaining to passwords.

Why this fix:	To make a good chunck of disk space availble for code. Passwords for characters are not necessary.

Source Disk:	Wiz1C.dsk

File:		CASTLE.TEXT
		ROLLER.TEXT

Segments:	PROCEDURE GETPASS( VAR PASSWORD: STRING);  (* P010A02 *) - This segment appears twice
		PROCEDURE ADDPARTY;  (* P010A09 *)
		PROCEDURE CHGPASS;  (* P010B1C *)
		PROCEDURE TRAINING;  (* P010B16 *)
		PROCEDURE MAKEMENU;  (* P010B0D *)

Removed code from:	CASTLE.TEXT

  6536  16    2:D     1     PROCEDURE GETPASS( VAR PASSWORD: STRING);  (* P010A02 *)
  6537  16    2:D     2                         
  6538  16    2:D     2       VAR
  6539  16    2:D     2            UNUSEDXX : INTEGER;
  6540  16    2:D     3            RANDX    : INTEGER;
  6541  16    2:D     4            CHRCNT   : INTEGER;
  6542  16    2:D     5                         
  6543  16    2:0     0       BEGIN
  6544  16    2:1     0         CHRCNT := 0;
  6545  16    2:1     3         REPEAT
  6546  16    2:2     3           GETKEY;
  6547  16    2:2     6           IF INCHAR <> CHR( CRETURN) THEN
  6548  16    2:3    11             IF CHRCNT < 15 THEN
  6549  16    2:4    16               BEGIN
  6550  16    2:5    16                 FOR RANDX := 0 TO (RANDOM MOD 2) DO
  6551  16    2:6    33                   WRITE( CHR( 88));
  6552  16    2:5    48                 CHRCNT := CHRCNT + 1;
  6553  16    2:5    53                 PASSWORD[ CHRCNT] := INCHAR
  6554  16    2:4    55               END
  6555  16    2:3    57             ELSE
  6556  16    2:4    59               WRITE( CHR(7))
  6557  16    2:1    67         UNTIL INCHAR = CHR( CRETURN);
  6558  16    2:1    72         WRITELN;
  6559  16    2:1    78         PASSWORD[ 0] := CHR( CHRCNT)
  6560  16    2:0    81       END;  (* GETPASS *)


PROCEDURE ADDPARTY;  (* P010A09 *)
  6725  16    9:1   270           GOTOXY( 0, 20);
  6726  16    9:1   275           WRITE( 'ENTER PASSWORD  >');
  6727  16    9:1   302           GETPASS(  CHARNAME);
  6728  16    9:1   306           GOTOXY( 0, 21);
  6729  16    9:1   311           IF CHARNAME <> CHARACTR[ PARTYCNT].PASSWORD THEN
  6730  16    9:2   324             EXITADDP( '** THATS NOT IT **');


Removed code from:	ROLLER.TEXT

  7412  17    2:D     1     PROCEDURE GETPASS( VAR PASSWORD: STRING);  (* P010B02 *)
  7413  17    2:D     2     
  7414  17    2:D     2       VAR
  7415  17    2:D     2            UNUSEDXX : INTEGER;
  7416  17    2:D     3            RANDX    : INTEGER;
  7417  17    2:D     4            CHRCNT   : INTEGER;
  7418  17    2:D     5       
  7419  17    2:0     0       BEGIN
  7420  17    2:1     0         CHRCNT := 0;
  7421  17    2:1     3         REPEAT
  7422  17    2:2     3           GETKEY;
  7423  17    2:2     6           IF INCHAR <> CHR( CRETURN) THEN
  7424  17    2:3    11             IF CHRCNT < 15 THEN
  7425  17    2:4    16               BEGIN
  7426  17    2:5    16                 FOR RANDX := 0 TO (RANDOM MOD 2) DO
  7427  17    2:6    33                   WRITE( CHR( 88));
  7428  17    2:5    48                 CHRCNT := CHRCNT + 1;
  7429  17    2:5    53                 PASSWORD[ CHRCNT] := INCHAR
  7430  17    2:4    55               END
  7431  17    2:3    57             ELSE
  7432  17    2:4    59               WRITE( CHR( 7));
  7433  17    2:1    67         UNTIL INCHAR = CHR( CRETURN);
  7434  17    2:1    72         WRITELN;
  7435  17    2:1    78         PASSWORD[ 0] := CHR( CHRCNT)
  7436  17    2:0    81       END;

  8082  17   28:D     1       PROCEDURE CHGPASS;  (* P010B1C *)
  8083  17   28:D     1       
  8084  17   28:D     1         VAR
  8085  17   28:D     1              NEWPASS2 : STRING[ 40];
  8086  17   28:D    22              NEWPASS1 : STRING[ 40];
  8087  17   28:D    43       
  8088  17   28:0     0         BEGIN;
  8089  17   28:1     0           WRITE( CHR(12));
  8090  17   28:1     8           WRITE( 'ENTER NEW PASSWORD ([RET] FOR NONE)');
  8091  17   28:1    53           REPEAT
  8092  17   28:2    53             GOTOXY( 10, 2);
  8093  17   28:2    58             GETPASS(  NEWPASS1)
  8094  17   28:1    60           UNTIL LENGTH( NEWPASS1) <= 15;
  8095  17   28:1    70           WRITE( CHR( 12));
  8096  17   28:1    78           WRITE( 'ENTER AGAIN TO BE SURE');
  8097  17   28:1   110           REPEAT
  8098  17   28:2   110             GOTOXY( 10, 2);
  8099  17   28:2   115             GETPASS( NEWPASS2)
  8100  17   28:1   117           UNTIL LENGTH( NEWPASS2) <= 15;
  8101  17   28:1   127           WRITE( CHR( 12));
  8102  17   28:1   135           IF NEWPASS1 = NEWPASS2 THEN
  8103  17   28:2   143             BEGIN
  8104  17   28:3   143               CHARREC.PASSWORD := NEWPASS1;
  8105  17   28:3   150               PUTCHARC( CHARREC, CHARACX);
  8106  17   28:3   158               GTSCNTOC;
  8107  17   28:3   160               WRITE( 'PASSWORD CHANGED - ')
  8108  17   28:2   189             END
  8109  17   28:1   189           ELSE
  8110  17   28:2   191             BEGIN
  8111  17   28:3   191               WRITELN( 'THEY ARE NOT THE SAME - YOUR PASSWORD');
  8112  17   28:3   244               WRITELN( 'HAS NOT BEEN CHANGED!');
  8113  17   28:3   281               WRITELN
  8114  17   28:2   281             END;
  8115  17   28:1   287           WRITE( 'PRESS [RET]');
  8116  17   28:1   308           GOTOXY( 41, 0);
  8117  17   28:1   313           READLN
  8118  17   28:0   313         END;

PROCEDURE TRAINING;  (* P010B16 *)
...
  8125  17   22:3     8             REPEAT
  8126  17   22:4     8               GOTOXY( 9, 10);
  8127  17   22:4    13               WRITE( 'PASSWORD >');
  8128  17   22:4    33               GETPASS( PASSSTR)
  8129  17   22:3    35             UNTIL LENGTH( PASSSTR) <= 15;
  8130  17   22:3    45             IF PASSSTR <> CHARREC.PASSWORD THEN
  8131  17   22:4    54               EXIT( TRAINING)
...
Code from:
  8157  17   22:2   348           WRITELN( 'C)HANGE  CLASS,' : 23);
Code to:
  8157  17   22:2   348           WRITELN( 'C)HANGE  CLASS, OR' : 26);
...
  8158  17   22:2   379           WRITELN( 'S)ET NEW PASSWORD, OR' : 29);
...
  8178  17   22:2   516             'S':  CHGPASS;

PROCEDURE MAKEMENU;  (* P010B0D *)
  7591  17   13:D     1         VAR
  7592  17   13:D     1              PASSWD : STRING;
...
Code from:
  7598  17   13:1    39           WRITELN( 'PASSWORD': 9);
Code to:
  7598  17   13:1    39           WRITELN( '': 9);
...
  7613  17   13:1   301           REPEAT
  7614  17   13:2   301             P010B0B;
  7615  17   13:2   303             WRITELN( 'ENTER A PASSWORD ([RET] FOR NONE)');
  7616  17   13:2   352             GOTOXY( 10, 1);
  7617  17   13:2   357             WRITE( CHR( 29));
  7618  17   13:2   365             GOTOXY( 10, 1);
  7619  17   13:2   370             GETPASS( CHARNAME);
  7620  17   13:2   375             IF LENGTH( CHARNAME) > 15 THEN
  7621  17   13:3   384               CHARNAME := COPY( CHARNAME, 1, 15);
  7622  17   13:2   401             P010B0B;
  7623  17   13:2   403             WRITELN( 'ENTER IT AGAIN TO BE SURE');
  7624  17   13:2   444             GOTOXY( 10, 1);
  7625  17   13:2   449             WRITE( CHR( 29));
  7626  17   13:2   457             GOTOXY( 10, 1);
  7627  17   13:2   462             GETPASS( PASSWD);
  7628  17   13:1   466           UNTIL PASSWD = CHARNAME;
  7629  17   13:1   475           CHARREC.PASSWORD := CHARNAME

Final Compiled File Name:	WIZARDRY.CODE

Destination Disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC020 - Show Spells During Combat
=================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	03-Feb-2023.

Contributor:	E. Labelle. Enhancement suggested by DDG Ahab.

The issue:	It would be nice to see what spells the monsters are casting.

The fix:	Added code to show what spells are cast by both the monsters and characters in the combat window.

Why this fix:	This is a useful and nice enhancement of the combat display details.

Source disks:	Wiz1A.dsk, Wiz1B.dsk

Files:		WIZ.TEXT
		WIZ2.TEXT
		COMBAT4.TEXT

Segments:	FORWARD DECLARATIONS
		PROGRAM WIZARDRY
		SEGMENT PROCEDURE CASTASPE;  (* P010801 *)
		
Add code to:	WIZ.TEXT

(* ---------- BEGIN FORWARD DECLARATIONS ---------- *)
.
.
.
PROCEDURE SHOWMP( SPELLINT: INTEGER); FORWARD; (* WC020 SHOW SPELL NAME *)


Add code to:	WIZ2.TEXT	(Note 1: using CASE here will not work because the numbers are bigger than 999.)
				(Note 2: this was not put in COMBAT4 because of space restrictions.)
				(Note 3: Although ugly, this is what takes the least lines of code.)

    PROCEDURE SHOWMP; (* WC020 SHOW SPELL NAME *)
      
      BEGIN
          IF SPELLINT = 4178 THEN PRINTSTR( 'HALITO');
          IF SPELLINT = 2409 THEN PRINTSTR( 'MOGREF');
          IF SPELLINT = 3983 THEN PRINTSTR( 'KATINO');
          IF SPELLINT = 3245 THEN PRINTSTR( 'DUMAPIC');
          IF SPELLINT = 3340 THEN PRINTSTR( 'DILTO');
          IF SPELLINT = 1953 THEN PRINTSTR( 'SOPIC');
          IF SPELLINT = 6181 THEN PRINTSTR( 'MAHALITO');
          IF SPELLINT = 4731 THEN PRINTSTR( 'MOLITO');
          IF SPELLINT = 4744 THEN PRINTSTR( 'MORLIS');
          IF SPELLINT = 3180 THEN PRINTSTR( 'DALTO');
          IF SPELLINT = 6156 THEN PRINTSTR( 'LAHALITO');
          IF SPELLINT = 7525 THEN PRINTSTR( 'MAMORLIS');
          IF SPELLINT = 6612 THEN PRINTSTR( 'MAKANITO');
          IF SPELLINT = 4925 THEN PRINTSTR( 'MADALTO');
          IF SPELLINT = 6587 THEN PRINTSTR( 'LAKANITO');
          IF SPELLINT = 4573 THEN PRINTSTR( 'ZILWAN');
          IF SPELLINT = 3990 THEN PRINTSTR( 'MASOPIC');
          IF SPELLINT = 1562 THEN PRINTSTR( 'HAMAN');
          IF SPELLINT = 3128 THEN PRINTSTR( 'MALOR');
          IF SPELLINT = 2597 THEN PRINTSTR( 'MAHAMAN');
          IF SPELLINT =11157 THEN PRINTSTR( 'TILTOWAIT');
          IF SPELLINT = 1449 THEN PRINTSTR( 'KALKI');
          IF SPELLINT = 2301 THEN PRINTSTR( 'DIOS');
          IF SPELLINT = 3675 THEN PRINTSTR( 'BADIOS');
          IF SPELLINT = 2889 THEN PRINTSTR( 'MILWA');
          IF SPELLINT = 2287 THEN PRINTSTR( 'PORFIC');
          IF SPELLINT = 3139 THEN PRINTSTR( 'MATU');
          IF SPELLINT = 1717 THEN PRINTSTR( 'CALFO');
          IF SPELLINT = 2619 THEN PRINTSTR( 'MANIFO');
          IF SPELLINT = 5970 THEN PRINTSTR( 'MONTINO');
          IF SPELLINT = 5333 THEN PRINTSTR( 'LOMILWA');
          IF SPELLINT = 2718 THEN PRINTSTR( 'DIALKO');
          IF SPELLINT = 6491 THEN PRINTSTR( 'LATUMAPIC');
          IF SPELLINT = 5169 THEN PRINTSTR( 'BAMATU');
          IF SPELLINT =  761 THEN PRINTSTR( 'DIAL');
          IF SPELLINT = 1253 THEN PRINTSTR( 'BADIAL');
          IF SPELLINT = 9463 THEN PRINTSTR( 'LATUMOFIS');
          IF SPELLINT = 4322 THEN PRINTSTR( 'MAPORFIC');
          IF SPELLINT = 1614 THEN PRINTSTR( 'DIALMA');
          IF SPELLINT = 2446 THEN PRINTSTR( 'BADIALMA');
          IF SPELLINT = 4396 THEN PRINTSTR( 'LITOKAN');
          IF SPELLINT = 1885 THEN PRINTSTR( 'KANDI');
          IF SPELLINT =  180 THEN PRINTSTR( 'DI');
          IF SPELLINT =  382 THEN PRINTSTR( 'BADI');
          IF SPELLINT = 4296 THEN PRINTSTR( 'LORTO');
          IF SPELLINT =  547 THEN PRINTSTR( 'MADI');
          IF SPELLINT =  759 THEN PRINTSTR( 'MABADI');
          IF SPELLINT = 8330 THEN PRINTSTR( 'LOKTOFEIT');
          IF SPELLINT = 5514 THEN PRINTSTR( 'MALIKTO');
          IF SPELLINT = 6673 THEN PRINTSTR( 'KADORTO')
      END;

Code from:	COMBAT4.TEXT

      BEGIN  (* CASTASPE P010801 *)
        DSPNAMES( BATG, BATI);
        PRINTSTR( 'CASTS A SPELL');
        IF BATTLERC[ BATG].A.TEMP04[ BATI].INAUDCNT > 0 THEN
          EXITCAST( 'WHICH FAILS TO BECOME AUDIBLE!');
        IF FIZZLES > 0 THEN
          EXITCAST( 'WHICH FIZZLES OUT');
        IF BATG = 0 THEN
          BEGIN
            CASTGR := BATTLERC[ 0].A.TEMP04[ BATI].VICTIM;
            IF (CASTGR > 0) AND (CASTGR < 5) THEN
              IF BATTLERC[ CASTGR].A.ALIVECNT > 0 THEN
                CASTI := BATI MOD BATTLERC[ CASTGR].A.ALIVECNT;
            SPELL := BATTLERC[ 0].A.TEMP04[ BATI].SPELLHSH;
          END
        ELSE
          BEGIN
            CASTGR := 0;
            CASTI  := BATTLERC[ BATG].A.TEMP04[ BATI].VICTIM;
            SPELL  := BATTLERC[ BATG].A.TEMP04[ BATI].SPELLHSH
          END;
        MVCURSOR( 1, 12);
        DOMAGE;
        DOPRIEST
      END;   (* CASTASPE P010801 *)

Code to:	COMBAT4.TEXT

      BEGIN  (* CASTASPE P010801 *)
        DSPNAMES( BATG, BATI);
        (* WC020 FROM -CASTS A SPELL- TO -CASTS - *)
        PRINTSTR( 'CASTS ');
        IF BATG = 0 THEN
          BEGIN
            CASTGR := BATTLERC[ 0].A.TEMP04[ BATI].VICTIM;
            IF (CASTGR > 0) AND (CASTGR < 5) THEN
              IF BATTLERC[ CASTGR].A.ALIVECNT > 0 THEN
                CASTI := BATI MOD BATTLERC[ CASTGR].A.ALIVECNT;
            SPELL := BATTLERC[ 0].A.TEMP04[ BATI].SPELLHSH;
          END
        ELSE
          BEGIN
            CASTGR := 0;
            CASTI  := BATTLERC[ BATG].A.TEMP04[ BATI].VICTIM;
            SPELL  := BATTLERC[ BATG].A.TEMP04[ BATI].SPELLHSH
          END;
        SHOWMP( SPELL); (* WC020 SHOW SPELL NAME *)
        IF BATTLERC[ BATG].A.TEMP04[ BATI].INAUDCNT > 0 THEN
          EXITCAST( 'WHICH FAILS TO BECOME AUDIBLE!');
        IF FIZZLES > 0 THEN
          EXITCAST( 'WHICH FIZZLES OUT');
        MVCURSOR( 1, 12);
        DOMAGE;
        DOPRIEST
      END;   (* CASTASPE P010801 *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC021 - Monsters Wrongly Casting Zilwan
=======================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	05-Feb-2023.

Contributors:	E. Labelle. DDG Ahab.

The issue:	Some monsters are casting the ZILWAN spell which does abolutely nothing to the player characters.

The fix:	Changed the monsters' casting of ZILWAN for MADALTO instead.

Why this fix:	Madalto was the only spell that made sense. Other high level spells like Makanito, Mamorlis, Lakanito, Masopic do nothing at all or nothing useful for the monsters.

Source disk:	Wiz1B.dsk

File:		COMBAT2.TEXT

Procedure:	PROCEDURE GETMAGSP( SPELLLEV: INTEGER);  (* P010618 *)
		
Code from:	
                6:  IF TWOTHIRD THEN
                      SPELLCAS := MADALTO
                    ELSE
                      SPELLCAS := ZILWAN;

Code to:
                6:  IF TWOTHIRD THEN
                      SPELLCAS := MADALTO
                    ELSE
                      SPELLCAS := MADALTO; (* WC021 FROM ZILWAN *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC022 - Treasure Tables Range Bug
=================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	06-Feb-2023.

Contributors:	E. Labelle, DDG Ahab, D. Molony.

The issue:	In short, the lower range of the treasure tables is off by two, and the upper range off by one.

The fix:	Adjust to code for the monsters' treasure to give the intended treasures.

Why this fix:	The monsters were not giving the intended range of treasures they were set to in the Wizardry database across all the treasure tables. The most blatant example: the monsters are not supposed to drop a Deadly Ring which is a one-time event in the game. The fix also takes care of a division by zero problem, i-e, x MOD 0.

Source disk:	Wiz1C.dsk

File:		REWARDS.TEXT

Procedure:	PPROCEDURE ITEMREWD;  (* P010D1D *)
		
Code from:	
            ITEMINDX := REWARDM.REWDCALC.ITEM.MININDX +
               (CALCULATE( 1, REWARDM.REWDCALC.ITEM.RANGE, 1)) +
               (REWARDM.REWDCALC.ITEM.MFACTOR * CHARIIII);

Code to:
              (* WC022 FIX TREASURE TABLE POINTERS *)
            ITEMINDX := REWARDM.REWDCALC.ITEM.MININDX +
               (RANDOM MOD (REWARDM.REWDCALC.ITEM.RANGE + 1)) +
               (REWARDM.REWDCALC.ITEM.MFACTOR * CHARIIII);

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC023 - Surprise Round Enhancement
==================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	07-Feb-2023.

Contributors:	E. Labelle. Suggested by DDG Ahab.

The issue:	Getting your party wiped out on round one because you got surprised by spellcasters or breathers kills the fun factor in the game.

The fix:	Modified the code to disallow casting spells and using breath weapons during surprise rounds for both monsters and characters.

Why this fix:	 Wizardry 3 alleviated this by disallowing spells during surprise rounds. Here we are doing the same and also disallowed breath weapons as well. For example: This way your party does not get wiped out on a surprise breath attack round from the Dragon Zombies.

Source disk:	Wiz1B.dsk

File:		COMBAT2.TEXT

Procedures:	PROCEDURE CACTION;  (* P010602 *) > BEGIN (* CACTION *)
		PROCEDURE ENATTACK;  (* P010614 *) > BEGIN (* ENATTACK *)
		
Code from:	
                      PRINTSTR( 'S)PELL  P)ARRY');
.
.
.
                        'S':  GETSPELL;
.
.
.
                            ENEMYSPL;
                            IF ATTCKTYP = 0 THEN
                              BREATHES;

Code to:
                      IF SURPRISE = 0 THEN
                          PRINTSTR( 'S)PELL  P)ARRY')
                        ELSE
                          PRINTSTR( 'P)ARRY'); (* WC023 *)
.
.
.
                        'S':  IF SURPRISE = 0 THEN GETSPELL; (* WC023 *)
.
.
.
                            IF SURPRISE = 0 THEN ENEMYSPL; (* WC023 *)
                            IF SURPRISE = 0 THEN
                              IF ATTCKTYP = 0 THEN
                                BREATHES; (* WC023 *)


Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC024 - Interim Release 09 Feb 2023
===================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	09-Feb-2023.

Contributors:	E. Labelle.

The issue:	Treasure tables 18 and 19 are off of their intended range. Gather all database fixes in one release.

Database fixes: Updated treasure tables 18 and 19 and merged the database fixes from Wizardry Restored v2.2. The entire list of database fixes can be found here: https://www.zimlab.com/wizardry/proving-grounds-v3

Why this release: 	Now that the WC022 Treasure Tables Range Bug has been fixed is is time to make an interim release by updating treasure tables 18 and 19 and merge the database fixes from Wizardry Restored v2.2.

Treasure tables change details:

Old Rewards Tables before code fix WC022:

				Min	Range	Intended	Intended	Actual		Actual	
				Index	Range	Minimum		Maximum		Minimum		Maximum
18C				79	13	80		92		81		93
19C				78	13	80		92		80		92


New Rewards Tables after code fix WC022, with Min Index and Range corrections:

				Min	Range	Intended	Intended	Actual		Actual
				Index		Minimum		Maximum		Minimum		Maximum
18C				80	12	80		92		80		92
19C				80	12	80		92		80		92	

Source disk:	Wiz1E.dsk

File:		OPTIONS.TEXT

Procedure:	SEGMENT PROCEDURE OPTIONS;  (* P070301 *)
				
Code from:	
    WRITE( '  VERSION 3.0 OF 04-JAN-23  SER:');

Code to:
    WRITE( '  VERSION 3.0 OF 09-FEB-23  SER:');

Final compiled file names:	SYSTEM.STARTUP and WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC025 - Fix Addlongs vs Experience Points
=========================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	10-Feb-2023.

Contributors:	E. Labelle. Information from DDG Ahab and Denis Molony. Solution from Thomas Ewers.

The issue:	The Addlongs procedure that adds two numbers has a bug where part of the first value is passed on to the second value because they have the same name thus having a addition/multiplication side effect. This causes the experience points of some monsters to be artificially high.

The fix:	 Updated the declaration of the procedure to have the second value as a constant.

Why this fix: 	To fix the Addlongs procedure bug. Also, this makes current monsters or future ones in another scenario to have a more predictable experience allocation.

Source disk:	Wiz1A.dsk

File:		WIZ.TEXT

Procedure:	PROCEDURE ADDLONGS (* P010005 *)
				
Code from:	

PROCEDURE ADDLONGS( VAR FIRST:  TWIZLONG;      (* P010005 *)
                    VAR SECOND: TWIZLONG); FORWARD;
                   
Code to:

PROCEDURE ADDLONGS( VAR FIRST:  TWIZLONG;      (* P010005 *)
                    SECOND: TWIZLONG); FORWARD;
                    (* WC025 FROM -VAR SECOND- TO -SECOND- *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC026 - Misspelling Bad Amount
==============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	11-Feb-2023.

Contributors:	E. Labelle.

The issue:	When trading gold between two characters, and the amount entered is invalid you get a message. The contraction of a word in that message is slightly annoying and unnecessary.

The fix:	Changed the message from "Bad Amt" to "Bad Amount".

Why this fix: 	Clarity. To remove the distration caused by the contraction of a word.

Source disk:	Wiz1C.dsk

File:		CAMP2.TEXT

Procedure:	PROCEDURE TRADGOLD;  (* P010C19 *)
				
Code from:	
              EXITTRAD( 'BAD AMT');
                   
Code to:
              EXITTRAD( 'BAD AMOUNT'); (* WC026 FROM -BAD AMT- *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC027 - Drain Only Once Per Combat Enhancement
==============================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	11-Feb-2023.

Contributors:	E. Labelle.

The issue:	Monsters can drain your characters several times during combat. This is killing the fun factor in the game.

The fix:	Added code for the monsters to not being able to drain your characters if they have already been drained. This includes a character drained by Haman or Mahaman. Although, casting successively Haman or Mahaman will drain your characters each time.

Why this fix: 	The draining effects are now working the same way they are in Wizardry 3 - Legacy of Llylgamyn.

Source disk:	Wiz1B.dsk

File:		COMBAT5.TEXT

Procedure:	PROCEDURE DRAINLEV;  (* P01090A *)
				
Code from:	
                IF CHARACTR[ MYVICTIM].WEPVSTY3[ 1][ 4] THEN
                  EXIT( DRAINLEV);
                   
Code to:
                IF DRAINED[ MYVICTIM] OR
                   CHARACTR[ MYVICTIM].WEPVSTY3[ 1][ 4] THEN
                  EXIT( DRAINLEV); (* WC027 ADD -DRAINED[ MYVICTIM] OR- *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC028 - Loktofeit
=================================

Status:		Fixed. Recompiled. Verified.

Date of change:	12-Feb-2023.

Contributors:	E. Labelle.

The issue:	The cast chance and penalty for using Loktofeit is such that it is never used.

The fix:	Updated the code so that the cast chance is the same as Wizardry 3 - Legacy of Llylgamyn which is (65 + Character Level)%.

Why this fix: 	To have the cast chance align with Legacy of Llylgamyn.

Source disk:	Wiz1B.dsk

File:		COMBAT4.TEXT

Procedure:	PROCEDURE SLOKTOFE;  (* P010818 *)
				
Code from:	
          IF (RANDOM MOD 100) >  2 * CHARACTR[ BATI].CHARLEV THEN
            BEGIN
              MVCURSOR( 1, 13);
              PRINTSTR( 'LOKTOFEIT FAILS!');
              EXIT( SLOKTOFE)
            END;            
Code to:
          IF (RANDOM MOD 100) >  65 + CHARACTR[ BATI].CHARLEV THEN
            BEGIN
              MVCURSOR( 1, 13);
              PRINTSTR( 'LOKTOFEIT FAILS!');
              EXIT( SLOKTOFE)
            END;

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC029 - Interim Release 14 Feb 2023
===================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	14-Feb-2023.

Contributors:	E. Labelle.

The issue:	Interim release due to several new fixes and enhancements since the last release. Also, corrected spelling of contracted words that also were missing the apostrophe.

The fix:	Updated text display of some words.

Why this fix: 	Interim release. Consistency.

Source disks:	Wiz1B. Wiz1C. Wiz1E.dsk

Files:		COMBAT2.TEXT, SHOPS.TEXT, CAMP.TEXT, OPTIONS.TEXT
				
Code from:	
                    PRINTSTR( 'YOU DONT KNOW THAT SPELL');
...

                    AASTRAA( 'YOU CANT CARRY ANYTHING MORE')
                    AASTRAA( '** WE DONT BUY CURSED ITEMS **')
                    AASTRAA( '** YOU CANT AFFORD THE FEE **');
...
                    EXITCAST( 'YOU CANT CAST IT')
                    EXITCAST( 'YOU CANT CAST IT');
                    EXITCAST( 'YOU CANT CAST IT');
...
                    WRITE( '  VERSION 3.0 OF 09-FEB-23  SER:');

Code to:
                    PRINTSTR( 'YOU DO NOT KNOW THAT SPELL'); (* WC029 *)
...

                    AASTRAA( 'YOU CANNOT CARRY ANYTHING MORE') (* WC029 *)
                    AASTRAA( '** WE DO NOT BUY CURSED ITEMS **') (* WC029 *)
                    AASTRAA( '** YOU CANNOT AFFORD THE FEE **'); (* WC029 *)
...
                    EXITCAST( 'YOU CANNOT CAST IT') (* WC029 *)
                    EXITCAST( 'YOU CANNOT CAST IT'); (* WC029 *)
                    EXITCAST( 'YOU CANNOT CAST IT'); (* WC029 *)
...
                    WRITE( '  VERSION 3.0 OF 14-FEB-23  SER:');

Final compiled file names:	SYSTEM.STARTUP and WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC030 - Ninja Enhancements
==========================================

Status:		Fixed. Recompiled. Verified.

Date of change:	27-Feb-2023.

Contributors:	Eric Labelle and DDG Ahab.

The issue:	Ninjas are not living up to their unarmed combat performance promise. Here is the Ninja definition in the Wizardry manual:

"NINJA - are inhuman fighting machines. They can use any weapons or
armor, but work best without any! When fighting without protection with
their bare hands, they can cause havoc and destruction, and may even kill
the strongest opponent with a single blow! Their great training gives them a
lower and lower ARMOR CLASS as they reach higher and higher levels of
ability. However, they get hit points as does a THIEF and gain no spells.
Finally, they must be EVIL"

Most of everything above concerning unarmed combat does not happen in-game. In 1981 you did not know that prior to playing the game. And if you succeeded (without cheating) in making a ninja, you found out that its unarmed performance was a total heart-breaking disappointment. The result is that essentially nobody played an unarmed ninja.

Also, to switch class to ninja you needed 17 in all attributes which is almost impossible to get before the end of the game.

The fix:	Made these code enhancements:

- The requirements to change class to ninja are now 15 in all attributes instead of 17. Must still be of evil alignment.
- Base bare hands damage increased from 2d4 to 2d8.
- Unarmed Armor Class improved from 1 point every 3 levels, to 1 point every level.
- Unarmed Combat Initiative Bonus of 1 point (10%) for every 3 levels. Gives the ninja more chances to strike the monsters first.

Note that the ninja has 1 extra attack per round compared to other fighter classes, this has not changed. Critical hit chance has not changed either.

Why this fix: 	Make it worthwhile to role-play an unarmed ninja.

Source disk:	Wiz1B.dsk

File:		UTILITIE2.TEXT

Procedure:	PROCEDURE INITSTUF;  (* P010124 *)
				
Code from:
            IF CLASS = NINJA THEN
              HPDAMRC.HPFAC := 4;
...
   IF CHARACTR[ CHARI].CLASS = NINJA THEN
            IF UNARMED THEN
              CHARACTR[ CHARI].ARMORCL := (CHARACTR[ CHARI].ARMORCL -
                (CHARACTR[ CHARI].CHARLEV DIV 3)) - 2

Code to:
            IF CLASS = NINJA THEN
              HPDAMRC.HPFAC := 8; (* WC030 FROM -4- TO -8- *)
...
          IF CHARACTR[ CHARI].CLASS = NINJA THEN
            IF UNARMED THEN
              CHARACTR[ CHARI].ARMORCL := (CHARACTR[ CHARI].ARMORCL -
                (CHARACTR[ CHARI].CHARLEV))
                (* WC030 FROM -CHARLEV DIV 3)) - 2- TO -CHARLEV))- *)

Source disk:	Wiz1B.dsk

File:		COMBAT2.TEXT

Procedure:	PROCEDURE CACTION;  (* P010602 *)

Code From:
	N/A

Code To:
...
        VAR
             POSSY    : INTEGER; (* WC030 *)
             UNARMED2 : BOOLEAN; (* WC030 *)
...

              (* WC030 *)
              IF CHARACTR[ MYCHARX].CLASS = NINJA THEN
              BEGIN
                UNARMED2 := TRUE;
                FOR POSSY := 1 TO CHARACTR[ MYCHARX].POSS.POSSCNT DO
                  IF CHARACTR[ MYCHARX].POSS.POSSESS[ POSSY].EQUIPED THEN
                    UNARMED2 := FALSE;
                IF UNARMED2 THEN
                  AGIL1TEN := AGIL1TEN - 
                              (CHARACTR[ MYCHARX].CHARLEV DIV 3)
              END;
...
                      (* PRINTSTR( ' INIT:'); WC030 *)
                      (* PRINTNUM( AGIL1TEN, 2); WC030 *)

Note: the last 2 lines above are remarked out, the code was used to verify that the bonus initiative worked.

Source disk:	Wiz1C.dsk

File:		ROLLER.TEXT

Procedure:	SEGMENT PROCEDURE ROLLER;   (* P010B01 *)

Code From:
        CHG2LST[ NINJA]   := (SIXATTR2[ STRENGTH] >= 17) AND
                             (SIXATTR2[ IQ] >= 17)       AND
                             (SIXATTR2[ PIETY] >= 17)    AND
                             (SIXATTR2[ VITALITY] >= 17) AND
                             (SIXATTR2[ AGILITY] >= 17)  AND
                             (SIXATTR2[ LUCK] >= 17)     AND
                             (CHARREC.ALIGN = EVIL);
Code To:
        (* WC030 FROM 17 TO 15 *)
        CHG2LST[ NINJA]   := (SIXATTR2[ STRENGTH] >= 15) AND
                             (SIXATTR2[ IQ] >= 15)       AND
                             (SIXATTR2[ PIETY] >= 15)    AND
                             (SIXATTR2[ VITALITY] >= 15) AND
                             (SIXATTR2[ AGILITY] >= 15)  AND
                             (SIXATTR2[ LUCK] >= 15)     AND
                             (CHARREC.ALIGN = EVIL);

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC031 - Mapiro Mahama Diromat
=============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	05-Mar-2023.

Contributors:	Eric Labelle, suggested by David Kilpatrick.

The issue:	On level 1, after coming back from the elevators, or from farming the Murphy's Ghosts, there is a shortcut back to the castle. The shortcut happens when you enter a certain room, and the mage therein sends you back to the castle after an incantation. The problem is that part of the message appears and disappears from the screen so fast that you cannot read it.

Here is the message:

A STRANGE GLOW SEEMS TO EMANATE FROM
THIS ROOM.  IN THE CENTER, A SMALLISH
MAN IN A LONG ROBE TURNS TOWARDS THE
PARTY AND SHOUTS,
   "BEGONE, STRANGERS!"
HE THEN BEGINS WAVING HIS HANDS, AND
INTONES THE WORDS,
   "MAPIRO MAHAMA DIROMAT"

The fix:	Added a delay after the incantation before going back to the castle.

Why this fix: 	Give the player a chance to read the message.

Source disk:	Wiz1B.dsk

File:		SPECIALS2.TEXT

Procedure:	PROCEDURE BCK2SHOP;  (* P01031E *)
				
Code from:
      BEGIN
        MAZELEV := 0;
        WRITE( CHR(12));
        XGOTO := XNEWMAZE
      END;

Code to:
      BEGIN
        PAUSE2; (* WC031 *)
        MAZELEV := 0;
        WRITE( CHR(12));
        XGOTO := XNEWMAZE
      END;

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC032 - Roster Out Characters
=============================================

Status:		Fixed. Recompiled. Verified.

Date of change:	06-Mar-2023.

Contributors:	Eric Labelle, information from Denis Molony.

The issue:	In the Training Grounds, the Roster of players does not always display characters that are "Out" in the dungeon. Note that characters that are "Out" cannot be added to the party at Gilgamesh's Tavern.

The fix:	Updated the code to display all characters that are "Out".

Why this fix: 	To display all the characters that are "Out" at the Training Grounds. Now there is an indication as to why a character cannot be added to the party.

Source disk:	Wiz1C.dsk

File:		ROLLER.TEXT

Procedure:	PROCEDURE DSP20NM;  (* P010B15 *)
				
Code from:
                IF CHARREC.INMAZE OR (CHARREC.LOSTXYL.LOCATION[ 1] <> 0) THEN
                  WRITE( ' OUT');

Code to:
                (* WC032 FROM -LOCATION [ 1]- TO -LOCATION [ 3]- *)
                IF CHARREC.INMAZE OR (CHARREC.LOSTXYL.LOCATION[ 3] <> 0) THEN
                  WRITE( ' OUT');

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC033 - Inventory Full Fix
==========================================

Status:		Fixed. Recompiled. Verified.

Date of change:	08-Mar-2023.

Contributors:	Eric Labelle.

The issue:	Before the fix, a random character was selected to receive a treasure item. If that character's inventory was full, then the item was lost. This meant you might not have gotten Werdna's amulet upon defeating him for example.

The fix:	Look at the entire party's inventory for space to receive an item. Display a message when the entire party's inventory is full.

Why this fix: 	To avoid having to continuously micro manage the party's inventory to ensure that there is enough space for treasure drops.

Source disk:	Wiz1C.dsk

File:		REWARDS.TEXT

Procedure:	PROCEDURE ITEMREWD;  (* P010D1D *)
				
Code from:
          BEGIN
            CHARXXXX := RANDOM MOD PARTYCNT;
            WHILE CHARACTR[ CHARXXXX].STATUS <> OK DO
              CHARXXXX := (CHARXXXX + 1) MOD PARTYCNT;
            IF CHARACTR[ CHARXXXX].POSS.POSSCNT = 8 THEN
              EXIT( ITEMREWD);  (* IF RANDOM CHARACTER IS OK AND HAS 8 
                                   POSSESSIONS,  THEN EXIT !! *)
          ...

Code to:
        VAR
             HASROOM : INTEGER; (* WC033 *)
             CHARYYYY: INTEGER; (* WC033 *)
             
          BEGIN
            (* BEGIN WC033 *)
            HASROOM := 0;
            FOR CHARYYYY := 0 TO PARTYCNT - 1 DO
              BEGIN
                IF CHARACTR[ CHARYYYY].POSS.POSSCNT < 8 THEN
                  BEGIN
                    HASROOM := 1;
                    CHARXXXX := CHARYYYY
                  END
              END;
            IF HASROOM = 0 THEN
              BEGIN
                MVCURSOR( 1, 12);
                PRINTSTR( 'PARTY INVENTORY FULL !');
                MVCURSOR( 1, 13);
                PRINTSTR( 'TREASURE LOST !');
                PAUSE2;
                EXIT( ITEMREWD)
              END;
            (* END WC033 *)
          ...

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC034 - Search for Item
=======================================

Status:		Fixed. Recompiled. Verified.

Date of change:	11-Mar-2023.

Contributors:	Eric Labelle.

The issue:	In the maze, the party enters areas where Wizardry tells a story and then asks you if you want to "Search (Y/N)?". If the party's inventory is full then nothing happens and that leaves the player wondering what is going on.

The fix:	Added messages to inform the player when the characters’ inventories are full as well as when the characters already have the item they are supposed to get.
	
Why this fix: 	To inform the player as to what is going on when responding yes to "Search (Y/N)?".

Source disk:	Wiz1B.dsk

File:		SPECIALS2.TEXT

Function:	FUNCTION GOTITEM
				
Code from:
      BEGIN
        GOTITEM := FALSE;
        WITH CHARACTR[ CHARX] DO
          BEGIN
            IF POSS.POSSCNT = 8 THEN
              EXIT( GOTITEM);
            FOR POSSX := 1 TO POSS.POSSCNT DO
              IF POSS.POSSESS[ POSSX].EQINDEX = ITEMX THEN
                EXIT( GOTITEM);
            CLRRECT( 1, 11, 38, 4);
            MVCURSOR( 1, 11);
            PRINTSTR( CHARACTR[ CHARX].NAME);
            PRINTSTR( ' GOT ITEM');
            POSSX := POSS.POSSCNT + 1;
            POSS.POSSCNT := POSSX;
            POSS.POSSESS[ POSSX].EQINDEX := ITEMX;
            POSS.POSSESS[ POSSX].EQUIPED := FALSE;
            POSS.POSSESS[ POSSX].CURSED  := FALSE
          END;
        GOTITEM := TRUE
      END;

Code to:
      BEGIN
        GOTITEM := FALSE;
        (* WC034 DISPLAY MESSAGES *)
        PAUSE1;
        CLRRECT( 1, 11, 38, 4);
        MVCURSOR( 1, 12);
        PRINTSTR( CHARACTR[ CHARX].NAME);
        WITH CHARACTR[ CHARX] DO
          BEGIN
            FOR POSSX := 1 TO POSS.POSSCNT DO
              IF POSS.POSSESS[ POSSX].EQINDEX = ITEMX THEN
                BEGIN
                  PRINTSTR( ' ALREADY HAS ONE');
                  EXIT( GOTITEM)
                END;
            
            IF POSS.POSSCNT = 8 THEN
              BEGIN
                PRINTSTR( ' IS FULL');
                EXIT( GOTITEM)
              END;
            
            PRINTSTR( ' GOT ITEM');
        (* END WC034 *)
            POSSX := POSS.POSSCNT + 1;
            POSS.POSSCNT := POSSX;
            POSS.POSSESS[ POSSX].EQINDEX := ITEMX;
            POSS.POSSESS[ POSSX].EQUIPED := FALSE;
            POSS.POSSESS[ POSSX].CURSED  := FALSE
          END;
        GOTITEM := TRUE
      END;

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC035 - Release 2023-03-17 and fixed a misspelling
==================================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	17-Mar-2023.

Contributors:	E. Labelle.

The result:	This if the first complete release of Wizardry Proving Grounds v3.0. Also, fixed a misspelling.

The adjustment:	Updated the release date on the boot disk. Fixed the misspelling of "Resurrects" when casting Haman or Mahaman.

Why this: 	Bugs and issues fixed. Enhancements done. Ready to distribute.

Source disks:	Wiz1E.dsk, Wiz1B.dsk

Files:		OPTIONS.TEXT, COMBAT4.TEXT
				
Code from:	
                    WRITE( '  VERSION 3.0 OF 14-FEB-23  SER:');

Code to:
                    WRITE( '  VERSION 3.0 OF 16-MAR-23  SER:');

Code from:	
            PRINTSTR( 'RESSURECTS AND ');

Code to:
            (* WC035 FROM -RESSURECTS- TO -RESURRECTS- *)
            PRINTSTR( 'RESURRECTS AND ');

Final compiled file names:	SYSTEM.STARTUP and WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC036 - Release 2023-03-23  in alignmentd with a ProDOS release
===============================================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	23-Mar-2023.

Contributors:	E. Labelle.

The result:	This a complete release of Wizardry Proving Grounds v3.0.

The adjustment:	Bypassed a copy protection check halt which is the same fix that was done on the boot side. Added a Q)uit option after leaving the game to really exit the game in order for the ProDOS version to send you back to ProDOS instead of having to reboot. Updated the date.

Why this: 	A released version that accomodates the ProDOS package.


Source disk:	Wiz1A.dsk

File:		WIZ.TEXT

Program:	PROGRAM WIZARDRY;
				
Code from:	
    WRITE( CHR( 12));
    GOTOXY( 0, 10);
    WRITE( '    PRESS [RETURN] FOR MORE WIZARDRY    ');
    READLN

Code to:
    (* WC036 - BEGIN *)
    WRITE( CHR( 12));
    GOTOXY( 4, 10);
    WRITE( 'PRESS [RETURN] FOR MORE WIZARDRY    ');
    GOTOXY( 12, 13);
    WRITE( 'OR Q)UIT THE GAME           ');
    REPEAT
      GETKEY
    UNTIL (INCHAR = 'Q') OR (INCHAR = CHR( CRETURN));
    IF INCHAR = 'Q' THEN
      BEGIN
        GOTOXY( 4, 16);
        WRITE( 'THANK YOU FOR PLAYING WIZARDRY!     ');
        PAUSE2;
        EXIT( WIZARDRY)
      END
    (* WC036 - END *)


Source disks:	Wiz1B.dsk

Files:		SPECIALS.TEXT

Procedure:	PROCEDURE COPYPROT;  (* P010310 *)

				
Code from:	
              IF GOODCOPY THEN

Code to:
              (* WC036 REMARKED OUT TO BYPASS COPY PROTECTION FAILURE *)
              (* IF GOODCOPY THEN *)


Source disks:	Wiz1E.dsk

Files:		OPTIONS.TEXT

Procedure:	SEGMENT PROCEDURE OPTIONS;  (* P070301 *)
				
Code from:	
                    WRITE( '  VERSION 3.0 OF 17-MA-23  SER:');

Code to:
                    WRITE( '  VERSION 3.0 OF 23-MAR-23  SER:');

Final compiled file names:	SYSTEM.STARTUP and WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Bug/Issue #:	WC037 - Disarm Trap Bug
=======================================

Status:		Fixed. Recompiled. Verified.

Date of change:	03-Apr-2023.

Contributors:	Eric Labelle. Bug reported by Reiska42. 

The issue:	This happens when finding a chest that is booby trapped with a trap of type 3 (Crossbow Bolt, Exploding Box, Splinters, Blades, and Stunner). Upon disarming the trap if you enter any valid trap name besides the current trap then nothing happens and you go back to the chest options. You can continue entering all the trap names and nothing will happen. The only way out is to open the chest, leave it, or enter the right trap name.

The fix:	Added the same code a in Wizardry III Legacy of Llylgamyn to fix this bug.
	
Why this fix: 	To make disarming chest traps work as intended.

Source disk:	Wiz1C.dsk

File:		REWARDS.TEXT

Procedure:	DISARM;  (* P010D18 *)
				
Code from:

            ELSE IF TRAPTYPE = 3 THEN
              BEGIN
                CASE TRAP3TYP OF
                  0:  IF TRAPSTR = 'CROSSBOW BOLT' THEN
                        DISARM;
                       
                  1:  IF TRAPSTR = 'EXPLODING BOX' THEN
                        DISARM;
                       
                  2:  IF TRAPSTR = 'SPLINTERS' THEN
                        DISARM;
                       
                  3:  IF TRAPSTR = 'BLADES' THEN
                        DISARM;
                       
                  4:  IF TRAPSTR = 'STUNNER' THEN
                        DISARM;
                END;
              END

Code to:

            ELSE IF TRAPTYPE = 3 THEN
              BEGIN
                CASE TRAP3TYP OF
                  0:  IF TRAPSTR = 'CROSSBOW BOLT' THEN
                        DISARM;
                       
                  1:  IF TRAPSTR = 'EXPLODING BOX' THEN
                        DISARM;
                       
                  2:  IF TRAPSTR = 'SPLINTERS' THEN
                        DISARM;
                       
                  3:  IF TRAPSTR = 'BLADES' THEN
                        DISARM;
                       
                  4:  IF TRAPSTR = 'STUNNER' THEN
                        DISARM;
                END;
                
                (* WC037 ADDED -DOTRAPDM- AS IN WIZ 3 *)
                DOTRAPDM
              END

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Enhancement #:	WC038 - Camp Screen Update
==========================================

Status:		Fixed. Recompiled. Verified.

Date of change:	03-Apr-2023.

Contributors:	Eric Labelle. Enhancement suggested by Reiska42.

The suggestion: Update the gold, hit points and status of a character when performing actions such as trading gold, or casting spells to cure hit points or ailments.

The action:	Added the necessary code to allow these enhancements.
	
Why this: 	It is nice now to see the screen updated on the fly when performing these actions.

Source disk:	Wiz1C.dsk

File:		CAMP.TEXT, CAMP2.TEXT

Procedure:	PROCEDURE DSPSPELS;  (* P010C04 *), PROCEDURE TRADITEM;  (* P010C1A *)
				
Code from:
        BEGIN
          WITH CHARACTR[ CAMPCHAR] DO
            BEGIN
              GOTOXY(  0, 9);
              WRITE( ' ' : 7);
              WRITE( ' MAGE ');
              FOR INDX := 1 TO 7 DO
                BEGIN
                  WRITE( MAGESP[ INDX]);
                  IF INDX < 7 THEN
                    WRITE( '/')
                END;
              WRITELN;
              WRITE( ' ' :6);
              WRITE( 'PRIEST ');
              FOR INDX := 1 TO 7 DO
                BEGIN
                  WRITE( PRIESTSP[ INDX]);
                  IF INDX < 7 THEN
                    WRITE( '/')
                END
            END
        END;

Code to:
        BEGIN
          WITH CHARACTR[ CAMPCHAR] DO
            BEGIN
              (* WC038 - BEGIN *)
              GOTOXY( 24, 2);
              PRNTLONG( GOLD);
              GOTOXY( 24, 6);
              WRITE( HPLEFT :3);
              GOTOXY( 24, 7);
              WRITE( SCNTOC.STATUS[ STATUS]);
              IF LOSTXYL.POISNAMT[ 1] > 0 THEN
                  WRITE( ' & POISONED')
                ELSE
                  WRITE( '           ');
              (* WC038 - END *)
              GOTOXY(  0, 9);
              WRITE( ' ' : 7);
              WRITE( ' MAGE ');
              FOR INDX := 1 TO 7 DO
                BEGIN
                  WRITE( MAGESP[ INDX]);
                  IF INDX < 7 THEN
                    WRITE( '/')
                END;
              WRITELN;
              WRITE( ' ' :6);
              WRITE( 'PRIEST ');
              FOR INDX := 1 TO 7 DO
                BEGIN
                  WRITE( PRIESTSP[ INDX]);
                  IF INDX < 7 THEN
                    WRITE( '/')
                END
            END
        END;
                
                (* WC037 ADDED -DOTRAPDM- AS IN WIZ 3 *)
                DOTRAPDM
              END

Code from:
        BEGIN (* DOTRADE *)
          DISPSTAT := FALSE;
          REPEAT
            TRADETO := GETCHARX( TRUE, 'TRADE WITH');
            IF TRADETO = -1 THEN
              EXIT( DOTRADE);
          UNTIL TRADETO <> CAMPCHAR;
          TRADGOLD;
          TRADITEM
        END;  (* DOTRADE *)

Code to: 
        BEGIN (* DOTRADE *)
          DISPSTAT := FALSE;
          REPEAT
            TRADETO := GETCHARX( TRUE, 'TRADE WITH');
            IF TRADETO = -1 THEN
              EXIT( DOTRADE);
          UNTIL TRADETO <> CAMPCHAR;
          TRADGOLD;
          DSPSPELS; (* WC038 - TO UPDATE GOLD AMOUNT *)
          TRADITEM
        END;  (* DOTRADE *)

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC039 - Release 09 Apr 2023 and Fix Maze Text Entry Overflow Crash
==================================================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	09-Apr-2023.

Contributors:	Eric Labelle. Bug reported by Reiska42.

The issue:	In the maze, when entering text for a spell name, chest trap name, time delay, or answer to a riddle, if you continue typing characters the text will overflow to next lines and eventually the game will crash.

The fix:	Restrict the length of the entry to the minimum necessary to prevent the game from crashing.
	
Why this fix: 	To prevent the game from crashing. But did not make it so short as to prevent answering a fairly long riddle of up to 22 characters. One can still corrupt the screen by overtyping but at least the game will not crash anymore.

Source disk:	Wiz1A.dsk

File:		WIZ2.TEXT

Procedure:	PROCEDURE GETSTR;
				
Code from:
                IF (INCHAR <> CHR( CRETURN)) AND (ORD( INCHAR) >= 32) THEN
                  BEGIN
                    MVCURSOR( WINXPOS + IPOS, WINYPOS);
                    PRINTCHR( INCHAR);
                    IPOS := IPOS + 1;
                    ASTRING[ IPOS] := INCHAR
                  END

Code to:
                IF (INCHAR <> CHR( CRETURN)) AND (ORD( INCHAR) >= 32) THEN
                  BEGIN
                    MVCURSOR( WINXPOS + IPOS, WINYPOS);
                    PRINTCHR( INCHAR);
                    (* WC039 ADDED -IF IPOS < 22 THEN- TO PREVENT A GAME *)
                    (* CRASH WHEN ENTERING TOO LONG A SPELL NAME IN COMBAT. *)
                    (* ALSO APPLIES TO ANSWERS TO RIDDLES, CHEST TRAPS, *)
                    (* AND ENTERING THE TIME DELAY *)
                    IF IPOS < 22 THEN IPOS := IPOS + 1;
                    ASTRING[ IPOS] := INCHAR
                  END

Source disks:	Wiz1E.dsk

Files:		OPTIONS.TEXT

Procedure:	SEGMENT PROCEDURE OPTIONS;  (* P070301 *)
				
Code from:	
                    WRITE( '  VERSION 3.0 OF 23-MAR-23  SER:');

Code to:
                    WRITE( '  VERSION 3.0 OF 09-APR-23  SER:');

Final compiled file name:	WIZARDRY.CODE

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.



Release #:	WC040 - Release 03 Aug 2023 - Pool and Divide Gold and More
===========================================================================

Status:		Fixed. Recompiled. Verified.

Date of change:	03-Aug-2023.

Contributors:	Eric Labelle. Thomas Ewers (Fix for Make Scenario bug).

Thanks:		Marshall Bockrath (Tips on Pascal segments sizes, it helped me to figure out where I could cram in the extra code for the Pool/Divide Gold enhancements).
		Todd Borax (Evil Shield +3 report).
		Chris Torrence (Transfer characters report).

Enhancements:	Added the possibility for a character to "Pool the Gold" of the entire party in his pocket. This can be done in Gilgamesh's, Boltac's, Adventurer's Inn and Camp. Furthermore, you can also "Divide the Gold" between all characters whilst inspecting your character at Gilgamesh's or Camp.

Enhancements:   Updated the code to allow characters to be transferred between scenario disks even if they are carrying quest items.

Fix:		On the boot side of Wizardry, there is a Utility to "Make Scenario Disk". An off-by-one error in the code had the top half part of the first monster picture overwritten with junk when making the scenario disk.
	
Consistency: 	The Evil Shield +3 armor class has been improved from 5 to 6 to be consistent with the armor protection of all the other shields.


Following are the programming code details
==========================================

Enhancement:	Pool and Divide Gold
------------------------------------

Source disk:	Wiz1A.dsk

File:		WIZ.TEXT

Procedure:	PROCEDURE POOLALLG
				
Code from:	(* ---------- BEGIN FORWARD DECLARATIONS ---------- *)

Code to:	(* ---------- BEGIN FORWARD DECLARATIONS ---------- *)
		PROCEDURE POOLALLG( CHAR4GLD: INTEGER); FORWARD; (* WC040 POOL GOLD *)



Source disk:	Wiz1A.dsk

File:		WIZ2.TEXT

Procedure:	PROCEDURE POOLALLG; (* WC040 POOL GOLD *)
				
Code from:	N/A.

Code to:
      PROCEDURE POOLALLG; (* WC040 POOL GOLD *)

      VAR
          ALOOP4 : INTEGER;
      
      BEGIN
        FOR ALOOP4 := 0 TO PARTYCNT -1 DO
          IF ALOOP4 <> CHAR4GLD THEN
            BEGIN
              WITH CHARACTR[ ALOOP4].GOLD DO
                BEGIN
                  ADDLONGS( CHARACTR[ CHAR4GLD].GOLD,
                  CHARACTR[ ALOOP4].GOLD);
                  HIGH := 0;
                  MID  := 0;
                  LOW  := 0
                END
            END
      END;



Source disk:	Wiz1C.dsk

File:		CAMP2.TEXT

Procedure:	PROCEDURE CAMPDO;  (* P010C1B *)
				
Code from:
          BEGIN  (* CAMPMENU *)
            WITH CHARACTR[ CAMPCHAR] DO
              BEGIN
                IF DISPSTAT THEN
                  DSPSTATS;
                GOTOXY( 0, 18);
                IF XGOTO = XINSPCT3 THEN
                  MENUTYPE := 0
                ELSE IF XGOTO = XINSPECT THEN
                  MENUTYPE := 1
                ELSE IF STATUS = OK THEN
                  MENUTYPE := 2
                ELSE
                  MENUTYPE := 1;
                  
                IF MENUTYPE = 2 THEN
                  BEGIN
                    WRITE( CHR( 11));
                    WRITELN( 'YOU MAY E)QUIP, D)ROP AN ITEM, T)RADE,');
                    WRITE( ' ' :8);
                    WRITELN( 'R)EAD SPELL BOOKS, CAST S)PELLS,');
                    WRITE( ' ' :8);
                    WRITELN( 'U)SE AN ITEM, I)DENTIFY AN ITEM,');
                    WRITE( ' ' :8);
                    WRITELN( 'OR L)EAVE.')
                  END
                ELSE IF MENUTYPE = 1 THEN
                  BEGIN
                    WRITE( CHR( 11));
                    WRITELN( 'YOU MAY E)QUIP, D)ROP AN ITEM, T)RADE,');
                    WRITE( ' ' :8);
                    WRITELN( 'R)EAD SPELL BOOKS, OR L)EAVE.')
                  END
                ELSE
                  BEGIN
                    WRITE( CHR( 11));
                    WRITELN( 'YOU MAY R)EAD SPELL BOOKS OR L)EAVE.')
                  END;
              END
          END;  (* CAMPMENU *)
          
          
        BEGIN (* CAMPDO *)
          CAMPMENU;
          DISPSTAT := TRUE;
          REPEAT
            GOTOXY( 41, 0);
            GETKEY
          UNTIL (INCHAR = 'R') OR (INCHAR = 'L') OR
                ((MENUTYPE > 0) AND
                 ((INCHAR = 'T') OR (INCHAR = 'D') OR (INCHAR = 'E'))) OR
                ((MENUTYPE > 1) AND
                 ((INCHAR = 'I') OR (INCHAR = 'S') OR (INCHAR = 'U')));
          
          CASE INCHAR OF
            'L':  EXIT( CAMPDO);
            'E':  IF MENUTYPE > 0 THEN
                    BEGIN
                      XGOTO := XEQPDSP;
                      LLBASE04 := CAMPCHAR;
                      EXIT( CAMP)
                    END;
            'R':  BEGIN
                    XGOTO := XCAMPSTF;
                    BASE12.GOTOX := XDONE;
                    LLBASE04 := CAMPCHAR;
                    EXIT( CAMP)
                  END;
            'D':  IF MENUTYPE > 0 THEN
                    DROPITEM;
            'I':  IF MENUTYPE = 2 THEN
                    IDENTIFY;
            'S':  IF MENUTYPE = 2 THEN
                    CASTSPEL( -1);
            'U':  IF MENUTYPE = 2 THEN
                    USEITEM;
            'T':  DOTRADE
           END
        END;  (* CAMPDO *)


Code to:
        PROCEDURE MENULST4; (* WC040 *)
          BEGIN
            WRITE( CHR( 11));
            WRITELN( 'YOU MAY E)QUIP, D)ROP AN ITEM, T)RADE,');
            WRITE( ' ' :8);
            WRITELN( 'POOL G)OLD, DIV)IDE GOLD,');
            WRITE( ' ' :8);
          END;
        

        PROCEDURE MENULST5; (* WC040 *)
          BEGIN
            WRITELN( 'R)EAD SPELL BOOKS, OR L)EAVE.')
          END;
        

          BEGIN  (* CAMPMENU *)
            WITH CHARACTR[ CAMPCHAR] DO
              BEGIN
                IF DISPSTAT THEN
                  DSPSTATS;
                GOTOXY( 0, 18);
                IF XGOTO = XINSPCT3 THEN
                  MENUTYPE := 0
                ELSE IF XGOTO = XINSPECT THEN
                  MENUTYPE := 1
                ELSE IF STATUS = OK THEN
                  MENUTYPE := 2
                ELSE
                  MENUTYPE := 1;
                  
                IF MENUTYPE = 2 THEN
                  BEGIN
                    MENULST4; (* WC040 *)
                    WRITELN( 'U)SE AN ITEM, I)DENTIFY AN ITEM,');
                    WRITE( ' ' :8);
                    WRITELN( 'CAST S)PELLS,');
                    WRITE( ' ' :8);
                    MENULST5 (* WC040 *)
                  END
                ELSE IF MENUTYPE = 1 THEN
                  BEGIN
                    MENULST4; (* WC040 *)
                    MENULST5 (* WC040 *)
                  END
                ELSE
                  BEGIN
                    WRITE( CHR( 11));
                    WRITE( 'YOU MAY ');
                    MENULST5 (* WC040 *)
                  END;
              END
          END;  (* CAMPMENU *)
      
    
      PROCEDURE DIVALLG( CHAR4GLD: INTEGER); (* WC040 *)
      
        VAR
          ALOOP4   : INTEGER;
          GOLD2DIV : TWIZLONG;
          GOLDLESS : TWIZLONG;
      
        BEGIN
          POOLALLG( CHAR4GLD);
          GOLD2DIV := CHARACTR[ CHAR4GLD].GOLD;
          DIVLONG( GOLD2DIV, PARTYCNT);
          GOLDLESS := GOLD2DIV;
          MULTLONG( GOLDLESS, PARTYCNT);
          SUBLONGS( CHARACTR[ CHAR4GLD].GOLD, GOLDLESS);
          FOR ALOOP4 := 0 TO PARTYCNT - 1 DO
            ADDLONGS( CHARACTR[ ALOOP4].GOLD, GOLD2DIV)
        END;

          
        BEGIN (* CAMPDO *)
          CAMPMENU;
          DISPSTAT := TRUE;
          REPEAT
            GOTOXY( 41, 0);
            GETKEY
          UNTIL (INCHAR = 'R') OR (INCHAR = 'L') OR
                ((MENUTYPE > 0) AND
                 ((INCHAR = 'T') OR (INCHAR = 'D') OR (INCHAR = 'E')
                  OR (INCHAR = 'G') OR (INCHAR = 'V'))) OR
                ((MENUTYPE > 1) AND
                 ((INCHAR = 'I') OR (INCHAR = 'S') OR (INCHAR = 'U')));
          
          CASE INCHAR OF
            'L':  EXIT( CAMPDO);
            'E':  IF MENUTYPE > 0 THEN
                    BEGIN
                      XGOTO := XEQPDSP;
                      LLBASE04 := CAMPCHAR;
                      EXIT( CAMP)
                    END;
            'R':  BEGIN
                    XGOTO := XCAMPSTF;
                    BASE12.GOTOX := XDONE;
                    LLBASE04 := CAMPCHAR;
                    EXIT( CAMP)
                  END;
            'D':  IF MENUTYPE > 0 THEN
                    DROPITEM;
            'G':  IF MENUTYPE > 0 THEN
                    POOLALLG( CAMPCHAR); (* WC040 POOL GOLD *)
            'V':  IF MENUTYPE > 0 THEN
                    DIVALLG( CAMPCHAR); (* WC040 DIVIDE GOLD *)
            'I':  IF MENUTYPE = 2 THEN
                    IDENTIFY;
            'S':  IF MENUTYPE = 2 THEN
                    CASTSPEL( -1);
            'U':  IF MENUTYPE = 2 THEN
                    USEITEM;
            'T':  DOTRADE
           END
        END;  (* CAMPDO *)



Source disk:	Wiz1C.dsk

File:		CASTLE2.TEXT

Procedures:	PROCEDURE ADVNTINN;  (* P010A0F *)
		PROCEDURE INNMENU;  (* P010A11 *)
				
Code from:

    PROCEDURE ADVNTINN;  (* P010A0F *)
    
      CONST
           STABLES  = 65;
           COTS     = 66;
           ECONOMY  = 67;
           MERCHANT = 68;
           ROYAL    = 69;
.
.
.
      PROCEDURE INNMENU;  (* P010A11 *)
      
        BEGIN
          GOTOXY( 0, 13);
          WRITE( CHR( 11));
          WRITE( '   WELCOME ');
          WRITE( CHARACTR[ PARTYX].NAME);
          WRITELN( '. WE HAVE:');
          WRITELN;
          WRITELN(  '[A] THE STABLES (FREE!)');
          WRITELN(  '[B] COTS. 10 GP/WEEK.');
          WRITELN(  '[C] ECONOMY ROOMS. 50 GP/WEEK.');
          WRITELN(  '[D] MERCHANT SUITES. 200 GP/WEEK.');
          WRITELN(  '[E] ROYAL SUITES. 500 GP/WEEK.');
          WRITE(    '    OR [RETURN] TO LEAVE')
        END;
.
.
.
      BEGIN  (* ADVNTINN *)
        REPEAT
          GETWHO;
          IF CHARACTR[ PARTYX].STATUS = OK THEN
            REPEAT
              UNITCLEAR( 1);
              INNMENU;
              GOTOXY( 41, 0);
              GETKEY;
              CASE ORD( INCHAR) OF
                 STABLES:  TAKENAP(  0,   0);
                    COTS:  TAKENAP(  1,  10);
                 ECONOMY:  TAKENAP(  3,  50);
                MERCHANT:  TAKENAP(  7, 200);
                   ROYAL:  TAKENAP( 10, 500);
              END;
              CHARINFO( PARTYX)
            UNTIL (INCHAR = CHR( CRETURN)) OR
                  (CHARACTR[ PARTYX].STATUS <> OK)
        UNTIL FALSE
      END;  (* ADVNTINN *)


Code to: 

    PROCEDURE ADVNTINN;  (* P010A0F *)
    
      CONST
           STABLES  = 65;
           COTS     = 66;
           ECONOMY  = 67;
           MERCHANT = 68;
           ROYAL    = 69;
           PGOLD    = 71; (* WC040 *)
.
.
.
      PROCEDURE INNMENU;  (* P010A11 *)
      
        BEGIN
          GOTOXY( 0, 13);
          WRITE( CHR( 11));
          WRITE( '   WELCOME ');
          WRITE( CHARACTR[ PARTYX].NAME);
          WRITELN( '. WE HAVE:');
          WRITELN;
          WRITELN(  '[A] THE STABLES (FREE!)');
          WRITELN(  '[B] COTS. 10 GP/WEEK.');
          WRITELN(  '[C] ECONOMY ROOMS. 50 GP/WEEK.');
          WRITELN(  '[D] MERCHANT SUITES. 200 GP/WEEK.');
          WRITELN(  '[E] ROYAL SUITES. 500 GP/WEEK.');
          WRITELN;
          WRITELN(  '[G] POOL PARTY GOLD.'); (* WC040 *)
          WRITELN;
          WRITE(    '    OR [RETURN] TO LEAVE')
        END;
.
.
.
      BEGIN  (* ADVNTINN *)
        REPEAT
          GETWHO;
          IF CHARACTR[ PARTYX].STATUS = OK THEN
            REPEAT
              UNITCLEAR( 1);
              INNMENU;
              GOTOXY( 41, 0);
              GETKEY;
              CASE ORD( INCHAR) OF
                 STABLES:  TAKENAP(  0,   0);
                    COTS:  TAKENAP(  1,  10);
                 ECONOMY:  TAKENAP(  3,  50);
                MERCHANT:  TAKENAP(  7, 200);
                   ROYAL:  TAKENAP( 10, 500);
                   PGOLD:  POOLALLG( PARTYX); (* WC040 *)
              END;
              CHARINFO( PARTYX)
            UNTIL (INCHAR = CHR( CRETURN)) OR
                  (CHARACTR[ PARTYX].STATUS <> OK)
        UNTIL FALSE
      END;  (* ADVNTINN *)



Source disk:	Wiz1B.dsk

File:		SHOPS.TEXT

Procedure:	PROCEDURE DOPLAYER;  (* P01020B *)
				
Code from:
        BEGIN (* DOPLAYER *)
          REPEAT
            GOTOXY( 0, 13);
            WRITE( CHR( 11));
            WRITE( '      WELCOME ');
            WRITE(  CHARACTR[ CHARI].NAME);
            WRITELN;
            WRITE( '     YOU HAVE ');
            PRNTLONG( CHARACTR[ CHARI].GOLD);
            WRITELN( ' GOLD');
            WRITELN;
            WRITELN( 'YOU MAY B)UY  AN ITEM,');
            WRITELN( '        S)ELL AN ITEM, HAVE AN ITEM');
            WRITELN( '        U)NCURSED,  OR HAVE AN ITEM');
            WRITELN( '        I)DENTIFIED, OR L)EAVE');
            GOTOXY( 41, 0);
            GETKEY;
                           
            CASE INCHAR OF
              'U': SELLIDUN( UNCURSE);
              'I': SELLIDUN( IDENTIFY);
              'S': SELLIDUN( SELL);
              'B': DOBUY;
              'L': EXIT( DOPLAYER);
            END
          UNTIL FALSE
        END; (* DOPLAYER *)

Code to:
        BEGIN (* DOPLAYER *)
          REPEAT
            GOTOXY( 0, 13);
            WRITE( CHR( 11));
            WRITE( '      WELCOME ');
            WRITE(  CHARACTR[ CHARI].NAME);
            WRITELN;
            WRITE( '     YOU HAVE ');
            PRNTLONG( CHARACTR[ CHARI].GOLD);
            WRITELN( ' GOLD');
            WRITELN;
            WRITELN( 'YOU MAY POOL G)OLD, B)UY  AN ITEM,'); (* WC040 *)
            WRITELN( '        S)ELL AN ITEM, HAVE AN ITEM');
            WRITELN( '        U)NCURSED,  OR HAVE AN ITEM');
            WRITELN( '        I)DENTIFIED, OR L)EAVE');
            GOTOXY( 41, 0);
            GETKEY;
                           
            CASE INCHAR OF
              'G': POOLALLG( CHARI); (* WC040 *)
              'U': SELLIDUN( UNCURSE);
              'I': SELLIDUN( IDENTIFY);
              'S': SELLIDUN( SELL);
              'B': DOBUY;
              'L': EXIT( DOPLAYER);
            END
          UNTIL FALSE
        END; (* DOPLAYER *)



Enhancement:	Allow characters to be transferred between scenario disks even if they are carrying quest items.
------------------------------------

Source disk:	Wiz1E.dsk

File:		WIZUTILC.TEXT

Procedure:	PROCEDURE REMOVCHR;  (* P070118 *)
				
Code from:	The code below has been remarked out.

Code to:	
      (* WC040 REMARKED OUT TO ALLOW TRANSFER OF QUEST ITEMS *)
      (* PROCEDURE BADITEM; *)  (* P070119 *)
      
        (* BEGIN
          WRITELN;
          WRITELN( '** CHAR HAS NON-XFERRABLE ITEMS **');
          PRESSRET;
          EXIT( TRANSFER)
        END; *)
.
.
.
        (* WC040 REMARKED OUT TO ALLOW TRANSFER OF QUEST ITEMS *)
        (* FOR PLAYERI := 1 TO PLAYREC2.POSS.POSSCNT DO
          IF PLAYREC2.POSS.POSSESS[ PLAYERI].EQINDEX > 93 THEN
            BADITEM; *)



Fix:		On the boot side of Wizardry, there is a Utility to "Make Scenario Disk". An off-by-one error in the code had the top half part of the first monster picture overwritten with junk when making the scenario disk.
------------------------------------

Source disk:	Wiz1E.dsk

File:		WIZUTILC.TEXT

Procedure:	PROCEDURE MAKESCEN;  (* P07011C *)
				
Code from:
      FOR TEMPI := 0 TO SCNTOC.RECPERDK[ ZCHAR] DO
        WRCHARAC( CHARREC0, TEMPI);

Code to:
      (* WC040 FROM 'SCNTOC.RECPERDK[ ZCHAR]' TO
       'SCNTOC.RECPERDK[ ZCHAR] - 1' *)
      (* THIS ERROR BY 1 WAS OVERWRITING PART OF THE FIRST MONSTER PICTURE *)
      FOR TEMPI := 0 TO SCNTOC.RECPERDK[ ZCHAR] - 1 DO
        WRCHARAC( CHARREC0, TEMPI);



Update:		Database Update
-------------------------------

Source disks:	Scenario Disk

Files:		SCENARIO.DATA

From:		Evil Shield +3 armor class 5

To:		Evil Shield +3 armor class 6



Update:		Release Date
----------------------------

Source disks:	Wiz1E.dsk

Files:		OPTIONS.TEXT

Procedure:	SEGMENT PROCEDURE OPTIONS;  (* P070301 *)
				
Code from:	
    (* ST001 CHANGE VERSION AND DATE DISPLAY AS NEEDED *)
    WRITE( '  VERSION 3.0 OF 09-APR-23  SER:');
    WRITELN( SERIAL);

Code to:
    (* ST001 CHANGE VERSION AND DATE DISPLAY AS NEEDED *)
    WRITE( '  VERSION 3.0 OF 03-AUG-23  SER:');
    WRITELN( SERIAL);



Final compiled file names:	WIZARDRY.CODE, SYSTEM.STARTUP

Destination disks:		Any Wizardry Proving Grounds boot and scenario disks.