home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TP_ADV.ZIP / LIST1305.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-11-21  |  17.4 KB  |  581 lines

  1. Program ObjAdv;
  2.  
  3. Uses
  4.   CRT;
  5.  
  6. Const
  7.   Blank : Char = ' ';
  8.  
  9. Type
  10.   Location = Object
  11.                X,
  12.                Y : Byte;
  13.                Symbol : Char;
  14.                Constructor Init ( newChar : Char; newX, newY : Byte );
  15.                Function GetX : Byte;
  16.                Function GetY : Byte;
  17.                Procedure Move ( newX, newY : Byte );
  18.                Procedure Show; Virtual;
  19.                Procedure Hide; Virtual;
  20.              End;
  21.   ThingPtr = ^Thing;
  22.   Thing    = Object ( Location )
  23.                Name : String;
  24.                Data : ShortInt;
  25.                Constructor Init ( newName : String; newChar : Char; newX,
  26.                                   newY : Byte );
  27.                Procedure Get;
  28.                Procedure Put ( newX, newY : Byte );
  29.                Function Swing : Byte; Virtual;
  30.                Function GetAC : ShortInt; Virtual;
  31.                Procedure SetAC ( newAC : ShortInt ); Virtual;
  32.              End;
  33.   Weapon   = Object ( Thing )
  34.                Constructor Init ( newName : String; newX, newY : Byte;
  35.                                   newDamage : ShortInt );
  36.                Function Swing : Byte; Virtual;
  37.              End;
  38.   Armor    = Object ( Thing )
  39.                Constructor Init ( newName : String; newX, newY : Byte;
  40.                                   newAC : ShortInt );
  41.                Function GetAC : ShortInt; Virtual;
  42.                Procedure SetAC ( newAC : ShortInt ); Virtual;
  43.              End;
  44.   BeingPtr = ^Being;
  45.   Being    = Object ( Location )
  46.                Name : String;
  47.                BaseDamage,
  48.                Health,
  49.                Weilding,
  50.                Wearing : Byte;
  51.                Inventory : Array [1..20] of ThingPtr;
  52.                Constructor Init ( newName : String; newX, newY : Byte;
  53.                                   newDamage, newHealth, newWeapon,
  54.                                   newArmor : Byte );
  55.                Procedure TakeHit ( toHit, damage : Byte );
  56.                Function Swing : Byte;
  57.                Procedure Weild ( obj : ThingPtr );
  58.                Procedure Wear ( obj : ThingPtr );
  59.              End;
  60.   Player   = Object ( Being )
  61.                Constructor Init ( newName : String; newX, newY : Byte;
  62.                                   newDamage, newHealth, newWeapon,
  63.                                   newArmor : Byte );
  64.              End;
  65.   Monster  = Object ( Being )
  66.                Constructor Init ( newName : String; newX, newY : Byte;
  67.                                   newDamage, newHealth, newWeapon,
  68.                                   newArmor : Byte );
  69.              End;
  70.   Area     = Object
  71.                x1, y1,
  72.                x2, y2 : Byte;
  73.                ObjBeing : Array [1..20] of BeingPtr;
  74.                Constructor Init ( newX1, newY1, newX2, newY2 : Byte );
  75.                Procedure AddBeingToRoom ( bPtr : BeingPtr );
  76.                Procedure MoveBeing ( Var creature : Being; posX,
  77.                                      posY : Byte );
  78.                Function Position ( locX, locY : Byte ) : BeingPtr;
  79.              End;
  80.  
  81. Var
  82.   mw,
  83.   pw : Weapon;
  84.   ma,
  85.   pa : Armor;
  86.   pp : Player;
  87.   mm : Monster;
  88.   a  : Area;
  89.   ch : Char;
  90.   status : Boolean;
  91.   windY  : Byte;
  92.  
  93. Procedure SwitchWindow;
  94. { This procedure allows the program to switch between the status }
  95. { window and the playing window. The global variable STATUS is   }
  96. { used to indicate which is the current window. When switching   }
  97. { back to the playing window, WINDY is updated to contain the    }
  98. { current Y position in the status window.                       }
  99.  
  100. Begin
  101.   status := Not status;
  102.   If status Then
  103.   Begin
  104.     Window ( 61, 1, 80, 25 );      { Activate the status window }
  105.     TextColor ( Black );
  106.     TextBackground ( LightGray );
  107.     GotoXY ( 1, windY );
  108.   End
  109.   Else
  110.   Begin
  111.     windY := WhereY;               { Store the status Window Y }
  112.     Window ( 1, 1, 60, 25 );       { Activate the player window }
  113.     TextColor ( LightGray );
  114.     TextBackground ( Black );
  115.   End;
  116. End;
  117.  
  118.  
  119. { /////////////////////////////////////////////////////////////////// }
  120. { //////////////////////// Location's Methods /////////////////////// }
  121. { /////////////////////////////////////////////////////////////////// }
  122. {
  123.  X,
  124.  Y : Byte;
  125.  Symbol : Char;
  126. }
  127.  
  128. Constructor Location.Init ( newChar : Char; newX, newY : Byte );
  129. { Initialize the instance of Location }
  130. Begin
  131.   X := NewX;
  132.   Y := NewY;
  133.   Symbol := NewChar;
  134. End;
  135.  
  136. Procedure Location.Move ( newX, newY : Byte );
  137. { Move the X,Y position of the instance. There is a special case   }
  138. { involved with an instance of location. If the X and Y values are }
  139. { 0, then the instance is not to be drawn.  The reason for this is }
  140. { that the instance has been destroyed or is in possesion of the   }
  141. { player.                                                          }
  142. Begin
  143.   Hide;
  144.   X := NewX;
  145.   Y := NewY;
  146.   If NOT ( ( X = 0 ) AND ( Y = 0 ) ) Then
  147.     Show;
  148. End;
  149.  
  150. Function Location.GetX : Byte;
  151. { Return the value of the X field }
  152. Begin
  153.   GetX := X;
  154. End;
  155.  
  156. Function Location.GetY : Byte;
  157. { Return the value of the Y field }
  158. Begin
  159.   GetY := Y;
  160. End;
  161.  
  162. Procedure Location.Show;
  163. { Write the symbol of the instance on the screen at the location }
  164. { stored in fields X and Y.                                      }
  165. Begin
  166.   GotoXY ( X, Y );
  167.   Write ( Symbol );
  168. End;
  169.  
  170. Procedure Location.Hide;
  171. { Remove the symbol of the instance from the screen at the location }
  172. { stored in fields X and Y.                                         }
  173. Begin
  174.   GotoXY ( X, Y );
  175.   Write ( Blank );
  176. End;
  177.  
  178. { /////////////////////////////////////////////////////////////////// }
  179. { ///////////////////////// Thing's Methods ///////////////////////// }
  180. { /////////////////////////////////////////////////////////////////// }
  181. {
  182.  X,
  183.  Y : Byte;
  184.  Symbol : Char;
  185.  Name : String;
  186.  Data : ShortInt;
  187. }
  188.  
  189. Constructor Thing.Init ( newName : String; newChar : Char; newX,
  190.                          newY : Byte );
  191. { Initialize the instance of Thing. Also, call Thing's immediate }
  192. { ancestor to initialize it's fields.                            }
  193. Begin
  194.   Location.Init ( newChar, newX, newY );
  195.   Name := NewName;
  196.   Data := ShortInt ( $FF );
  197. End;
  198.  
  199. Procedure Thing.Get;
  200. { Unused in this program, but can be used later for picking up }
  201. { things that are in an Area.                                  }
  202. Begin
  203.   Location.Move ( 0, 0 );
  204. End;
  205.  
  206. Procedure Thing.Put ( newX, newY : Byte );
  207. { Unused in this program, but can be used later for droping }
  208. { things in an Area.                                        }
  209. Begin
  210.   Location.Move ( newX, newY );
  211. End;
  212.  
  213. Function Thing.Swing : Byte;
  214. { Defined as a base value for all things. Default value of a }
  215. { swing is set to 0. If a descendant object is to be usable  }
  216. { as a weapon, this method should be replaced.               }
  217. Begin
  218.   Swing := 0;
  219. End;
  220.  
  221. Function Thing.GetAC : ShortInt;
  222. { Defined as a base value for all things. Default value of AC  }
  223. { is set to 0. If a descendant object is to be usable as Armor }
  224. { then this method should be replaced.                         }
  225. Begin
  226.   GetAC := 0;
  227. End;
  228.  
  229. Procedure Thing.SetAC ( newAC : ShortInt );
  230. { Unused in this program. This method is a base for all things. }
  231. { If a descendant object is to be usable as Armor, then this    }
  232. { method should be replaced.                                    }
  233. Begin
  234. End;
  235.  
  236. { /////////////////////////////////////////////////////////////////// }
  237. { //////////////////////// Weapon's Methods ///////////////////////// }
  238. { /////////////////////////////////////////////////////////////////// }
  239. {
  240.  X,
  241.  Y : Byte;
  242.  Symbol : Char;
  243.  Name : String;
  244.  Data : ShortInt;
  245. }
  246.  
  247. Constructor Weapon.Init ( NewName : String; NewX, NewY : Byte;
  248.                           NewDamage : ShortInt );
  249. { Initialize the instance of Weapon. Then call Weapon's immediate }
  250. { ancestor to initialize it's values.                             }
  251. Begin
  252.   Thing.Init ( NewName, '|', NewX, NewY );
  253.   Data := NewDamage;
  254. End;
  255.  
  256. Function Weapon.Swing : Byte;
  257. { This is the replacement procedure for Thing. This will compute }
  258. { a random amount of damage that the swinging of the weapon will }
  259. { produce. The random value is based on the DATA field of the    }
  260. { object.                                                        }
  261. Begin
  262.   Swing := Random ( data ) + 1;
  263. End;
  264.  
  265. { /////////////////////////////////////////////////////////////////// }
  266. { ///////////////////////// Armor's Methods ///////////////////////// }
  267. { /////////////////////////////////////////////////////////////////// }
  268. {
  269.  X,
  270.  Y : Byte;
  271.  Symbol : Char;
  272.  Name : String;
  273.  Data : ShortInt;
  274. }
  275.  
  276. Constructor Armor.Init ( NewName : String; NewX, NewY : Byte;
  277.                          NewAC : ShortInt );
  278. { Initialize the instance of Armor. Then call Armor's immediate }
  279. { ancestor to initialize it's values.                           }
  280. Begin
  281.   Thing.Init ( NewName, '#', NewX, NewY );
  282.   Data := NewAC;
  283. End;
  284.  
  285. Function Armor.GetAC : ShortInt;
  286. { This is the replacement procedure for Thing. This will return }
  287. { the Armor Class of the instance. The AC is stored in the DATA }
  288. { field of the object.                                          }
  289. Begin
  290.   GetAC := Data;
  291. End;
  292.  
  293. Procedure Armor.SetAC ( newAC : ShortInt );
  294. { Unused in this program. This is the replacement procedure for }
  295. { Thing. This could be used to modify the Armor Class of the    }
  296. { instance. The AC is stored in the DATA field of the object.   }
  297. Begin
  298.   Data := newAC;
  299. End;
  300.  
  301. { /////////////////////////////////////////////////////////////////// }
  302. { ///////////////////////// Being's Methods ///////////////////////// }
  303. { /////////////////////////////////////////////////////////////////// }
  304. {
  305.  X,
  306.  Y : Byte;
  307.  Symbol : Char;
  308.  Name : String;
  309.  BaseDamage,
  310.  Health,
  311.  Weilding,
  312.  Wearing : Byte;
  313.  Inventory : Array [1..20] of ThingPtr;
  314. }
  315.  
  316. Constructor Being.Init ( NewName : String; NewX, NewY : Byte; NewDamage,
  317.                          NewHealth, NewWeapon, NewArmor : Byte );
  318. { Initialize the instance of Being. Also, call Being's immediate }
  319. { ancestor to initialize it's fields.                            }
  320. Begin
  321.   Location.Init ( Symbol, NewX, NewY );
  322.   Name := NewName;
  323.   BaseDamage := NewDamage;
  324.   Health := NewHealth;
  325.   Weilding := NewWeapon;
  326.   Wearing := NewArmor;
  327.   FillChar ( Inventory, SizeOf ( Inventory ), 0 );
  328. End;
  329.  
  330. Procedure Being.TakeHit ( ToHit, Damage : Byte );
  331. { This procedure takes two parameters. The first parameter is }
  332. { a number from 1-100 that indicates whether this instance of }
  333. { being will be hit. The second parameter determines how much }
  334. { damage the instance will take for the hit.                  }
  335. Var
  336.   tmp : Byte;
  337. Begin
  338.   If ( Wearing = 0 ) Then
  339.     tmp := 10
  340.   Else
  341.     tmp := Inventory [Wearing]^.GetAC;
  342.   tmp := 10 * ( 10 - tmp );     { Compute the Armor class of the instance }
  343.   SwitchWindow;
  344.   If ( ToHit <= tmp ) Then
  345.   Begin
  346.     WriteLn ( 'A hit! For ',Damage,' points of damage!' );
  347.     If ( ( health - damage ) <= 0 ) Then
  348.     Begin
  349.       health := 0;
  350.       SwitchWindow;
  351.       hide;
  352.       SwitchWindow;
  353.       WriteLn ( 'You killed the monster.' );
  354.     End
  355.     Else
  356.       health := health - damage;
  357.   End
  358.   Else
  359.     WriteLn ( 'A miss.' );
  360.   SwitchWindow;
  361. End;
  362.  
  363. Function Being.Swing : Byte;
  364. { Return how much damage the instance will give for an attack }
  365. { with the current weapon of the instance.                    }
  366. Var
  367.   tmp : Byte;
  368. Begin
  369.   tmp := Inventory [Weilding]^.Swing;
  370.   If ( tmp = 0 ) Then
  371.     tmp := Random ( 4 ) + 1;
  372.   Swing := tmp;
  373. End;
  374.  
  375. Procedure Being.Weild ( obj : ThingPtr );
  376. { Set the weapon that the instance is going to weild }
  377. Var
  378.   tmp : Byte;
  379. Begin
  380.   tmp := 1;
  381.   While ( tmp <= 20 ) AND ( Inventory [tmp] <> NIL ) Do
  382.     Inc ( tmp );
  383.   If ( tmp > 20 ) Then
  384.     WriteLn ( 'Overloaded, can not weild that item' )
  385.   Else
  386.   Begin
  387.     Inventory [ tmp ] := obj;
  388.     Weilding := tmp;
  389.   End;
  390. End;
  391.  
  392. Procedure Being.Wear ( obj : ThingPtr );
  393. { Set the armor class that the instance will wear }
  394. Var
  395.   tmp : Byte;
  396. Begin
  397.   tmp := 1;
  398.   While ( tmp <= 20 ) AND ( Inventory [tmp] <> NIL ) Do
  399.     Inc ( tmp );
  400.   If ( tmp > 20 ) Then
  401.     WriteLn ( 'Overloaded, can not wear that item' )
  402.   Else
  403.   Begin
  404.     Inventory [ tmp ] := obj;
  405.     Wearing := tmp;
  406.   End;
  407. End;
  408.  
  409. { /////////////////////////////////////////////////////////////////// }
  410. { //////////////////////// Player's Methods ///////////////////////// }
  411. { /////////////////////////////////////////////////////////////////// }
  412. {
  413.  X,
  414.  Y : Byte;
  415.  Symbol : Char;
  416.  Name : String;
  417.  BaseDamage,
  418.  Health,
  419.  Weilding,
  420.  Wearing : Byte;
  421.  Inventory : Array [1..20] of ThingPtr;
  422. }
  423.  
  424. Constructor Player.Init ( newName : String; newX, newY : Byte; newDamage,
  425.                           newHealth, newWeapon, newArmor : Byte );
  426. { Initialize the instance of Player. Also, call Player's immediate }
  427. { ancestor to initialize it's fields.                              }
  428. Begin
  429.   Symbol := '@';  { This is the symbol that the player is represented by }
  430.   Being.Init ( newName, newX, newY, newDamage, newHealth, newWeapon,
  431.                newArmor );
  432. End;
  433.  
  434. { /////////////////////////////////////////////////////////////////// }
  435. { //////////////////////// Monster's Methods //////////////////////// }
  436. { /////////////////////////////////////////////////////////////////// }
  437. {
  438.  X,
  439.  Y : Byte;
  440.  Symbol : Char;
  441.  Name : String;
  442.  BaseDamage,
  443.  Health,
  444.  Weilding,
  445.  Wearing : Byte;
  446.  Inventory : Array [1..20] of ThingPtr;
  447. }
  448.  
  449. Constructor Monster.Init ( newName : String; newX, newY : Byte; newDamage,
  450.                            newHealth, newWeapon, newArmor : Byte );
  451. { Initialize the instance of Monster. Also, call Monster's immediate }
  452. { ancestor to initialize it's fields.                                }
  453. Begin
  454.   Symbol := '*';  { This is the symbol that the monster is represented by }
  455.   Being.Init ( newName, newX, newY, newDamage, newHealth, newWeapon,
  456.                newArmor );
  457. End;
  458.  
  459. { /////////////////////////////////////////////////////////////////// }
  460. { ////////////////////////// Area's Methods ///////////////////////// }
  461. { /////////////////////////////////////////////////////////////////// }
  462. {
  463.  ObjBeing : Array [1..20] of BeingPtr;
  464. }
  465.  
  466. Constructor Area.Init ( newX1, newY1, newX2, newY2 : Byte );
  467. { Initialize the instance of Area. Area represents a room. }
  468. { The parameters determine the boundries of the room.      }
  469. Begin
  470.   FillChar ( ObjBeing, SizeOf ( ObjBeing ), 0 );
  471.   x1 := newX1;
  472.   y1 := newY1;
  473.   x2 := newX2;
  474.   y2 := newY2;
  475. End;
  476.  
  477. Procedure Area.AddBeingToRoom ( bPtr : BeingPtr );
  478. { Add an instance of Being to the Area. }
  479. Var
  480.   tmp : Byte;
  481. Begin
  482.   tmp := 1;
  483.   While ( tmp <= 20 ) AND ( ObjBeing [tmp] <> NIL ) Do
  484.     Inc ( tmp );
  485.   If ( tmp <= 20 ) Then
  486.     ObjBeing [ tmp ] := bPtr;
  487. End;
  488.  
  489. Function Area.Position ( locX, locY : Byte ) : BeingPtr;
  490. { Return an instance of Being (if any) at the X,Y position }
  491. { specified. NIL will be returned if no instance exists at }
  492. { the specified location.                                  }
  493. Var
  494.   tmp : Byte;
  495. Begin
  496.   tmp := 1;
  497.   While ( tmp <= 20 ) AND NOT ( ( ObjBeing [tmp]^.X = locX ) AND
  498.         ( ObjBeing [tmp]^.Y = locY ) ) AND ( ObjBeing [tmp] <> NIL ) Do
  499.     Inc ( tmp );
  500.   If ( tmp <= 20 ) AND ( ObjBeing [tmp] <> NIL ) AND
  501.      ( ObjBeing [tmp]^.Health > 0 ) Then
  502.     Position := ObjBeing [tmp]
  503.   Else
  504.     Position := NIL;
  505. End;
  506.  
  507. Procedure Area.MoveBeing ( Var creature : Being; posX, posY : Byte );
  508. { Move an instance of Being to a new X,Y location if no other   }
  509. { instance is at that location. If a being is at that location, }
  510. { then attack it.                                               }
  511. Var
  512.   tmpNum : Byte;
  513.   tmpObj : BeingPtr;
  514. Begin
  515.   tmpNum := 1;
  516.   While ( tmpNum <= 20 ) AND ( @creature <> ObjBeing [tmpNum] ) Do
  517.     Inc ( tmpNum );
  518.   If ( tmpNum <= 20 ) Then
  519.   Begin
  520.     If ( posX >= x1 ) AND ( posX <= x2 ) AND
  521.        ( posY >= y1 ) AND ( posY <= y2 ) Then
  522.     Begin
  523.       tmpObj := position ( posX, posY );
  524.       If ( tmpObj = NIL ) Then
  525.         creature.Move ( posX, posY )
  526.       Else
  527.         tmpObj^.TakeHit ( Random ( 100 ), creature.Swing );
  528.     End;
  529.   End;
  530. End;
  531.  
  532. Begin
  533.   mw.Init ( 'Long Sword', 0, 0, 8 );
  534.   ma.Init ( 'Leather', 0, 0, 8 );
  535.   mm.Init ( 'Orc', 10, 10, 4, 8, 0, 0 );
  536.   mm.Wear ( @ma );
  537.   mm.Weild ( @mw );
  538.  
  539.   pw.Init ( 'Long Sword', 0, 0, 8 );
  540.   pa.Init ( 'Chain', 0, 0, 6 );
  541.   pp.Init ( 'Elf', 14, 14, 4, 8, 0, 0 );
  542.   pp.Wear ( @pa );
  543.   pp.Weild ( @pw );
  544.  
  545.   a.Init ( 1, 1, 60, 24 );
  546.   a.AddBeingToRoom ( @mm );
  547.   a.AddBeingToRoom ( @pp );
  548.  
  549.   Randomize;
  550.   status := TRUE;
  551.   SwitchWindow;     { Initialize the playing window }
  552.   ClrScr;
  553.   SwitchWindow;     { Initialize the status window }
  554.   ClrScr;
  555.   SwitchWindow;     { Activate the playing window }
  556.   pp.Show;
  557.   mm.Show;
  558.   Repeat
  559.     ch := ReadKey;
  560.     Case ch of
  561.       #0 : Begin
  562.              ch := ReadKey;
  563.              Case ch of
  564.                #72 : Begin { Up }
  565.                        a.MoveBeing ( pp, pp.GetX, pp.GetY-1 );
  566.                      End;
  567.                #75 : Begin { Left }
  568.                        a.MoveBeing ( pp, pp.GetX-1, pp.GetY );
  569.                      End;
  570.                #77 : Begin { Right }
  571.                        a.MoveBeing ( pp, pp.GetX+1, pp.GetY );
  572.                      End;
  573.                #80 : Begin { Down }
  574.                        a.MoveBeing ( pp, pp.GetX, pp.GetY+1 );
  575.                      End;
  576.              End;
  577.            End;
  578.       End;
  579.   Until ( ch = #27 )
  580. End.
  581.