/
draco_ii.sp
1046 lines (942 loc) · 37.3 KB
/
draco_ii.sp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/local/bin/spar
-- Draco II
pragma annotate( summary, "draco_ii" )
@( description, "Survive a hostile wilderness and slay monsters." )
@( description, "Originally written in AppleSoft BASIC" )
@( description, "by Ken O. Burtch circa 1980" )
@( description, "Adapted to SparForte in April 2003" )
@( description, "Usage: draco_ii" )
@( author, "Ken O. Burtch" );
pragma ada_95; -- enforce Ada 95 rules and style
procedure draco_ii is
-- Terminal Control
--
-- Linux/UNIX tput returns a string to control the terminal display
tty_inverse : string; -- inverse print
tty_normal : string; -- normal print
-- General Player Info
type import_string is new string;
LOGNAME : constant import_string := "unknown";-- Linux/UNIX user login name
pragma import( shell, LOGNAME ); -- get it from the environment
damage_to_creature : integer; -- inflicted on creature (E)
damage_to_player : integer; -- inflicted on player (D)
type a_status is (no_status, alive, dead);
status : a_status := alive; -- player's current status
score : integer := 0; -- the socre
quest_bonus : natural; -- quest bonus for level
specter_paralysis : boolean := false; -- specter can paralyze player
type an_attribute is new float; -- attributes are a unique type
dex : an_attribute; -- player dexterity
strength : an_attribute; -- player strength
hit_points : integer; -- hit points
level_distance : integer; -- total level distance
distance : integer; -- distance left (DT)
water : float; -- water left (W)
-- Player Weapon
--
-- There are 4 weapons: the cursed club, the bow (dexterity), the mace
-- (dexterity+strength) and the sword (strength).
type a_weapon is (no_weapon, club, bow, mace, sword);
weapon : a_weapon; -- player weapon
weapon_name : string; -- name as text
weapon_damage : float; -- damage (attribute adjusted)
-- Creatures
--
-- There are 6 creatures: a giant, a wolf, a serpent, a druid, a dragon and
-- a specter.
type a_creature is (no_creature, dork, wolf, serpent, druid, draco, specter );
creature : a_creature; -- current creature (C)
creature_here : boolean; -- true if creature present (C1)
creature_hp : integer; -- creature hit points (CP)
creature_max : integer; -- creature's maximum hit poins (C2)
creature_description : string; -- description when creature here (CN)
creature_name : string; -- the creature name as text
creature_evade : string; -- message when creature evades (CV)
creature_attack1 : string; -- message for light attack (CA(0))
creature_attack2 : string; -- message for medium attack (CA(1))
creature_attack3 : string; -- message for fierce attack (CA(2))
creature_damage1 : positive; -- damage for light attack (CD(0))
creature_damage2 : positive; -- damage for medium attack (CD(1))
creature_damage3 : positive; -- damage for fierce attack (CD(2))
-- Items
--
-- There are 4 magic items: a lightning staff, a magic spear, a potion of
-- healing and a ring of fire resistance.
type an_item is (no_item, staff, spear, potion, ring );
has_item : array( staff..ring ) of boolean;
staff_charge : integer; -- number of staff uses left (CH)
spear_damage : integer; -- amount of damage from spear (SD)
-- Game variables
round : natural; -- round or turn (SP)
level : natural := 0; -- current level (L)
high_name : string := "nobody"; -- high score player
high_score : integer := 0; -- high score (HS)
high_level : integer := 0; -- high score level
player_cmd : character; -- player's last command (CM)
-- get high score: retrieve high score from file (if the file exists).
procedure get_high_score is
f : file_type;
begin
if files.exists( "./draco_score.txt" ) then
open( f, in_file, "./draco_score.txt" );
high_name := get_line( f );
high_score := numerics.value( get_line( f ) );
high_level := numerics.value( get_line( f ) );
close( f );
end if;
end get_high_score;
-- set high score: write new high score to file. If file doesn't exist,
-- create it.
procedure set_high_score is
f : file_type;
begin
create( f, out_file, "./draco_score.txt" );
put_line( f, LOGNAME );
put_line( f, high_score );
put_line( f, level );
close( f );
end set_high_score;
-- set attributes: generate a new set of player attributes. Where did this
-- formula come from? I don't remember...
procedure set_attributes is
begin
strength := -3;
dex := -3;
while dex < -2 and strength < -2 loop
dex := (9.5 - numerics.rnd(14)+2 ) / 2;
strength := (9.5 - numerics.rnd(14)+2 ) / 2;
end loop;
end set_attributes;
-- chose weapon: allow the player to chose a weapon at the start of the
-- game or after his weapon was replaced with the cursed club.
procedure choose_weapon is
ch : character;
begin
put_line( "Strength =" & strings.image( numerics.rounding( strength*2 ) ) );
put_line( "Dexterity =" & strings.image( numerics.rounding( dex*2 ) ) );
new_line;
put_line( "Chose a weapon:" );
weapon := no_weapon;
while weapon = no_weapon loop
put( "Bow, Mace or Sword? (B/M/S) *" & ASCII.BS );
ch := inkey;
put_line( ch );
case ch is
when 'b'|'B' =>
weapon := bow;
weapon_name := "bow";
weapon_damage := 4 + dex;
when 'm'|'M' =>
weapon := mace;
weapon_name := "mace";
weapon_damage := 6+ (strength + dex)/2;
when 's'|'S' =>
weapon := sword;
weapon_name := "sword";
weapon_damage := 8 + strength;
when others =>
put_line( "Pardon?" );
end case;
end loop;
end choose_weapon;
-- new level: start a new level, chose a creature.
procedure new_level is
begin
level := level + 1;
hit_points := 20;
water := 20;
creature_here := false;
quest_bonus := 0;
round := 0;
case level is
when 1 => creature := dork;
when 2 => creature := wolf;
when 3 => creature := serpent;
when 4 => creature := druid;
when 5 => creature := draco;
when others => creature := specter;
end case;
case creature is
when dork =>
creature_description := "Dork the Witless stalks you.";
creature_name := "giant";
creature_evade := "It bounces harmlessly off his armor.";
creature_attack1 := "Dork the Witless tries to stomp you.";
creature_damage1 := 3;
creature_attack2 := "He pounds you with his mighty fists!";
creature_damage2 := 4;
creature_attack3 := "He heaves a rock at your miniscule body!!";
creature_damage3 := 5;
when wolf =>
creature_description := "Something lurks in the shadows.";
creature_name := "wolf";
creature_evade := "It dodges your attack.";
creature_attack1 := "It lashes out with its claws.";
creature_damage1 := 3;
creature_attack2 := "The wolf snaps at your arm!";
creature_damage2 := 4;
creature_attack3 := "It leaps at your chest, eyes gleaming brightly!!";
creature_damage3 := 6;
when serpent =>
creature_description := "Something lurks in the shadows.";
creature_name := "giant serpent";
creature_evade := "It slithers away.";
creature_attack1 := "It coils around you and squeezes!";
creature_damage1 := 5;
creature_attack2 := "You trip and fall, uncoordinated oaf.";
creature_damage2 := 3;
creature_attack3 := "The serpent attacks, venom burning holes in the earth!!";
creature_damage3 := 7;
when druid =>
creature_description := "An evil druid smiles.";
creature_name := "druid";
creature_evade := "The druid forms a magic barrier and laughs menacingly!";
creature_attack1 := "He lashes out with his dagger.";
creature_damage1 := 4;
creature_attack2 := "With a sudden gesture, a fireball hurls towards you!";
creature_damage2 := 5;
creature_attack3 := "He raises his scepter and a bolt of power erupts!!";
creature_damage3 := 7;
when draco =>
creature_description := "Draco the Red circles overhead.";
creature_name := "dragon";
creature_evade := "Your weapon bounces harmlessly off its scales.";
creature_attack1 := "It lashes out with its claws.";
creature_damage1 := 4;
creature_attack2 := "Draco rains fireballs down upon you!";
creature_damage2 := 6;
creature_attack3 := "A river of deadly fire descends!!";
creature_damage3 := 9;
when others =>
creature_description := "A grim specter materializes. Poof!";
creature_name := "specter";
creature_evade := "He dissolves before your eyes!";
creature_attack1 := "A ghostly blade lashes out.";
creature_damage1 := 4;
creature_attack2 := "YOU ARE PETRIFIED WITH HORROR!";
creature_damage2 := 1;
creature_attack3 := "A cold hand reaches out for your life!!";
creature_damage3 := 4;
end case;
creature_hp := 25 + (level-1) * 9;
creature_max := creature_hp;
level_distance := 50 * integer( level );
distance := level_distance;
end new_level;
-- show status: show the player's statistics (review stats).
procedure show_status is
begin
put_line( "You have:" );
put_line( strings.image( numerics.rounding( strength * 2 ) ) & " points of strength" );
put_line( strings.image( numerics.rounding( dex * 2 ) ) & " points of dexterity" );
put_line( " carrying a " & weapon_name );
new_line;
put_line( "with" & strings.image( numerics.rounding( water/2*10 ) ) & "% of water in your bottle" );
put_line( "and" & strings.image( hit_points / 2 * 10 ) & "% of full health" );
end show_status;
-- Main Script begins
begin
-- Initialize Draco II
-- Inverse printing. First try terminfo (Linux), then termcap (FreeBSD).
tty_inverse := `tput( "smso" );`;
if tty_inverse = "" then
tty_inverse := `tput( "so" );`;
end if;
tty_normal := `tput( "rmso" );`;
if tty_normal = "" then
tty_normal := `tput( "se" );`;
end if;
clear;
put_line( tty_inverse & "Draco II" & tty_normal );
new_line;
put_line( "Survive a hostile wilderness and slay monsters." );
put_line( "Originally written by Ken O. Burtch circa 1980" );
new_line;
get_high_score;
put( "Top Dragon Slayer:" & strings.image( high_score ) );
put( " level" & strings.image( high_level ) );
put_line( " by " & high_name );
new_line;
set_attributes;
choose_weapon;
-- Player has no magic items
for i in staff..ring loop
has_item( i ) := false;
end loop;
put( "Press any key to begin *" & ASCII.BS );
declare
ch : character;
begin
ch := inkey;
end;
-- Game loop: loop for each level
loop
-- Start a new level. Player's weapon the club? Let 'im change it.
new_level;
if weapon = club then
new_line;
choose_weapon;
end if;
-- Main loop: loop for each round
loop
-- clear damage from monster and player
damage_to_player := 0;
damage_to_creature := 0;
-- check to see if the creature appears every 4 rounds
if creature /= no_creature then
if float(round)/4.0 = numerics.truncation(round/4) then
creature_here := numerics.rnd(2)=1;
end if;
end if;
-- display menu
clear;
put_line( tty_inverse & "Draco II" & tty_normal );
new_line;
put_line( "1) Evade 2) Strike with " & weapon_name );
put_line( "3) Search for water 4) Run like crazy" );
put_line( "5) Proceed 6) Surrender R) Review stats" );
if has_item( staff ) then
put_line( "7) Wave staff" );
end if;
if has_item( spear ) then
put_line( "8) Throw spear" );
end if;
if has_item( potion ) then
put_line( "9) Drink potion" );
end if;
if has_item( ring ) then
put_line( "The anti-fire ring magic is automatic." );
end if;
new_line;
put( "(Level" & strings.image( level ) & ")" );
put_line( " There are" & strings.image( distance ) & " miles to go." );
new_line;
-- Creature not around? Then it slowly heals...
if not creature_here then
creature_hp := creature_hp + 1;
if creature_hp > creature_max then
creature_hp := creature_max;
end if;
put_line( "There is no danger to be seen." );
end if;
-- Basic stat changes that happen every round
round := round + 1;
water := water - 0.5;
hit_points := hit_points + 0.2;
-- Basic Stats check
if water > 0 and water < 7 then
put_line( tty_inverse & "Water's Low" & tty_normal );
end if;
if hit_points < 5 then
put_line( tty_inverse & "You're badly wounded" & tty_normal );
elsif hit_points < 10 then
put_line( tty_inverse & "You're in rough shape" & tty_normal );
end if;
if creature_here then
put_line( creature_description );
if creature_hp < 10 then
put_line( tty_inverse & "Blood gushes from its wounds" & tty_normal );
end if;
-- Creature attack
declare
attack : constant positive := numerics.rnd( 5 );
begin
case attack is
when 1|2 =>
put_line( creature_attack1 );
damage_to_player := integer( numerics.rnd( creature_damage1 ) );
when 3 =>
put_line( creature_attack2 );
damage_to_player := integer( numerics.rnd( creature_damage2 ) );
if (creature = druid or creature = draco) and has_item( ring ) then
damage_to_player := damage_to_player/2;
elsif creature = specter then
damage_to_player := 0;
damage_to_creature := damage_to_creature/2;
hit_points := hit_points - damage_to_player;
creature_hp := creature_hp + damage_to_creature;
specter_paralysis := true;
end if;
when 4 =>
put_line( creature_attack3 );
damage_to_player := integer( numerics.rnd( creature_damage3 ) );
if creature = draco and has_item( ring ) then
damage_to_player := damage_to_player/2;
end if;
if creature = specter and numerics.rnd(20) = 1 then
put( tty_inverse );
put( "You scream, and your lifeless soul becomes a specter!!!" );
put_line( tty_normal );
elsif creature = draco then
damage_to_player := damage_to_player/2;
end if;
when others =>
null;
end case;
end;
else
declare
scene : positive := numerics.rnd( 100 );
maybe : constant boolean := numerics.rnd(2)=1;
begin
if scene <= 5 then -- rare scenes
case scene is
when 1 =>
declare
gypsie_distance : constant positive := numerics.rnd(7)+2;
begin
put( "You travel" );
put( gypsie_distance );
put( " miles with a band of gypsies!" );
distance := distance - integer(gypsie_distance);
end;
when 2 =>
put_line( "A Ty Fighter soars through the air leaving" );
put_line( "a blaze of incadescent destruction." );
put_line( "It promptly vanishes into hyperspace!!" );
-- graphics effects
put_line( "WOW!" );
when 3 =>
put_line( "You drink from a magic spring that restores you!" );
water := 20;
hit_points := hit_points + integer(numerics.rnd(8))+3;
if hit_points > 20 then
hit_points := 20;
end if;
when 4 =>
declare
ch : character;
door : integer;
reward : positive;
reward_bonus : natural;
begin
put_line( "From the turret of a dark castle you hear a terrified scream" );
put_line( "for help! A strong hero is required! What will you do?" );
put_line( "1) Check it out 2) Keep going" );
ch := inkey;
put_line( ch );
if ch /= "1" then
put_line( "Fine, you gutless swine." );
else
door := integer(numerics.rnd(15))+hit_points/8+(strength+dex)/2;
if door < 10 then
new_line;
put_line( "The evil lord of the castle feeds you to his pet tiger!" );
status := dead;
exit;
else
new_line;
put_line( "You attack the castle, storming through the gates." );
put_line( "You rescue the beautiful princess!!" );
reward := numerics.rnd( 10 );
new_line;
put( "Her father awards you with " );
case reward is
when 1 =>
put_line( "a priceless ancient crown." );
reward_bonus := 99;
when 2 =>
put_line( "a rare gold scepter." );
reward_bonus := 70;
when 3 =>
put_line( "bags of brilliant perls." );
reward_bonus := 50;
when 4 =>
put_line( "gorgeous furs." );
reward_bonus := 40;
when 5 =>
put_line( "a beautiful ruby." );
reward_bonus := 30;
when 6 =>
put_line( "a dazzling emerald." );
reward_bonus := 25;
when 7 =>
put_line( "gold coins." );
reward_bonus := 20;
when 8 =>
put_line( "a sliver ring." );
reward_bonus := 10;
when 9 =>
put_line( "a splendid lute." );
reward_bonus := 5;
when others =>
put_line( "his thanks." );
reward_bonus := 0;
end case;
quest_bonus := quest_bonus + reward_bonus;
delay 1.0;
put( tty_inverse & "BONUS: " & tty_normal );
put_line( reward_bonus );
end if;
end if;
end;
when 5 =>
put_line( "Oh, no! An evil cleric has transformed your magificent weapon" );
put_line( "into a useless stick!" );
weapon := club;
weapon_name := "club";
weapon_damage := 3;
when others =>
null;
end case;
else -- common scenes
scene := numerics.rnd( 19 );
case scene is
when 1 =>
put_line( "Oops! Fell into a hidden pit." );
hit_points := hit_points - integer(numerics.rnd(3));
when 2 =>
put_line( "You enter an enchanted forest." );
if has_item( spear ) then
spear_damage := spear_damage/2;
put_line( "*** Your spear seems weaker." );
end if;
if has_item( staff ) then
if staff_charge > 0 then
staff_charge := integer(numerics.rnd(positive(staff_charge)));
end if;
staff_charge := integer(numerics.rnd(5))-staff_charge;
put_line( "*** Your staff glows faintly." );
end if;
when 3 =>
if has_item( potion ) and maybe then
put_line( "You fall, and your vial shatters!" );
has_item( potion ) := false;
end if;
when 4 =>
put_line( "You spend the night at an inn." );
water := water + 3;
hit_points := hit_points + 1;
if score > 0 then
score := score - 1;
end if;
when 5 =>
if not has_item( staff ) and maybe then
put_line( "An ancient staff lies in the dust." );
has_item( staff ) := true;
staff_charge := integer(numerics.rnd( 4 )) + 1;
end if;
when 6 =>
put_line( "You become lost in the wilderness." );
distance := distance + integer(numerics.rnd( 7 )) - 4;
when 7 =>
if not has_item( potion ) and maybe then
put_line( "An unopened vial lies on the ground." );
has_item( potion ) := true;
end if;
when 8 =>
put_line( "This is an ashen wasteland left by Draco." );
when 9 =>
if not has_item( spear ) and maybe then
put_line( "A dwarvish warrior gives you his spear to aid you on your quest." );
has_item( spear ) := true;
spear_damage := 10;
end if;
when 10 =>
put_line( "You traverse a burning desert!" );
water := water - float(numerics.rnd( 3 ));
when 11 =>
if not has_item( ring ) and maybe then
put_line( "A golden ring lies on the earth." );
has_item( ring ) := true;
end if;
when 12 =>
if player_cmd = '3' then
water := water + 3;
end if;
put_line( "You swim a peaceful river." );
when 13 =>
declare
stolen_points : constant positive := numerics.rnd(30);
begin
put_line( "A band of thieves attacked in the night." );
if score <= 0 then
put_line( "But you have no treasure to steal." );
else
put( "They take" & tty_inverse );
put( stolen_points );
put_line( tty_normal & " points of treasure!" );
score := score - integer( stolen_points );
end if;
end;
when 14 =>
declare
bad_luck : constant positive := numerics.rnd( 4 );
begin
if has_item( ring ) then
case bad_luck is
when 1 =>
put_line( "Your ring is lost while swimming a river." );
has_item( ring ) := false;
when 2 =>
put_line( "Your ring vanishes without a trace." );
has_item( ring ) := false;
when others =>
put_line( "You catch a pickpocket trying to steal your ring." );
end case;
end if;
end;
when 15 =>
put_line( "You follow a trail through the mountains." );
distance := distance - 3;
when 16 =>
if player_cmd = '3' and maybe then
put_line( "The spring from which you drink is poison." );
status := dead;
else
put_line( "You avoid a foul-smelling pond." );
end if;
when 17 =>
put_line( "You rest beneath a golden-leaved tree." );
hit_points := hit_points + 0.5;
when 18 =>
declare
strange_luck : constant positive := numerics.rnd( 7 );
gold : constant positive := numerics.rnd( 60 )+20;
begin
if maybe then
put_line( "You meet an old hermit" );
case strange_luck is
when 1 =>
put_line( "who gives you water!" );
water := water + float(numerics.rnd(4))+5;
when 2 =>
if creature /= no_creature then
put_line( "who informs your pursuer of your presence." );
creature_here := true;
else
put_line( "who threatens and mumbles." );
end if;
when 3 =>
if hit_points < 15 then
put_line( "who helps treat your wounds." );
hit_points := hit_points + integer(numerics.rnd(4))+5;
if hit_points > 20 then
hit_points := 20;
end if;
else
put_line( "who throws rocks at you." );
hit_points := hit_points - 1;
end if;
when 4 =>
put_line( "who gives you directions." );
distance := distance - integer(numerics.rnd(3))+3;
when 5 =>
put( "who gives you" & tty_inverse );
put( gold );
put( tty_normal & " gold pieces!" );
when 6 =>
put( "who tells you long-winded stories that go no where." );
when others =>
put( "who tells you he was once a handsome frog" );
put( " before some princess kissed him." );
end case;
end if;
end;
when 19 =>
put_line( "You meet a wandering band of elves." );
when others =>
put_line( "internal error: missing scene case" );
end case;
end if;
end;
end if;
-- pre status check: if player dead, stop now.
if water <= 0 then
put_line( tty_inverse & "Gasp!! You are out of water!" & tty_normal );
put_line( "You die alone in the wilderness." );
status := dead;
elsif hit_points <= 0 then
status := dead;
end if;
-- Level complete or dead? No more to do.
if distance <= 0 or status = dead then
exit;
end if;
-- Player Command
if specter_paralysis then
specter_paralysis := false;
else
loop
new_line;
put( "What will you do? *" & ASCII.BS );
player_cmd := inkey;
put_line( player_cmd );
-- Handle player's command
case player_cmd is
when '1' =>
-- evade
if creature_here then
if numerics.rnd(2) = 1 then
put_line( "You dive behind some boulders." );
damage_to_player := 0.5;
else
if damage_to_player > 0 then
damage_to_player := integer( numerics.rnd( positive( damage_to_player ) ) );
end if;
damage_to_player := damage_to_player - integer(dex);
if damage_to_player < 1 then
damage_to_player := 1;
end if;
if damage_to_player < 3 then
put_line( "You avoid the worst of his attack." );
else
put_line( "There is no escape!" );
end if;
end if;
exit;
else
put_line( "Why? There is no enemy." );
end if;
when '2' =>
-- attack
if creature_here then
declare
creature_evades : boolean;
begin
if weapon = bow then
creature_evades := numerics.rnd(4)=1;
else
creature_evades := numerics.rnd(3)=1;
end if;
damage_to_creature := integer( numerics.rnd( positive( weapon_damage ) ) );
if creature_evades then
put_line( creature_evade );
damage_to_creature := 0;
elsif weapon = bow then
put_line( "Ttwwaanngg!!" );
if damage_to_creature > 3 then
delay 0.5;
put_line( "Good shot!!!" );
end if;
else
put_line( "Pow!!" );
if (damage_to_creature > 5 and weapon = mace) or
(damage_to_creature > 7 and weapon = sword) then
delay 0.5;
put_line( "Great swing!!!" );
elsif damage_to_creature = 3 and weapon = club then
delay 0.5;
put_line( "Bonk!" );
end if;
end if;
end;
exit;
else
put_line( "Why? There is no enemy." );
end if;
when '3' =>
-- search for water
declare
water_found : constant boolean := numerics.rnd(3)=1;
begin
if water_found then
put_line( "You find a spring and fill your waterbottle." );
water := 20.0;
else
put_line( "Nothing around." );
water := water - 0.5;
end if;
end;
exit;
when '4' =>
-- run like crazy
water := water - 2.0;
damage_to_player := damage_to_player * 2 / 3;
hit_points := hit_points - 0.2;
distance := numerics.rounding( distance -
integer( numerics.rnd( numerics.ceiling( hit_points/3) ) )
- hit_points/4 );
put_line( "OK" );
exit;
when '5' =>
-- proceed
distance := distance - integer( numerics.rnd( 7 ) );
water := water - 0.5;
put_line( "OK" );
exit;
when '6' =>
-- surrender
put_line( "You surrender." );
status := dead;
exit;
when '7' =>
-- magic staff
if creature_here then
if has_item( staff ) then
staff_charge := staff_charge - 1;
if staff_charge < 0 then
staff_charge := 0;
put_line( "Nothing happens!" );
elsif creature = dork then
put_line( "Your blast tickles Dork into fits of uncontrolled laughter." );
else
put_line( "A bolt of lightning strikes the enemy!" );
damage_to_creature := integer( numerics.rnd(4) )+3;
if creature = specter then
damage_to_creature := damage_to_creature * 4;
put_line( "The specter howls with rage!" );
end if;
end if;
exit;
else
put_line( "Wave what?" );
end if;
else
put_line( "Why? There is no enemy." );
end if;
when '8' =>
-- magic spear
if creature_here then
if has_item( spear ) then
has_item( spear ) := false;
if creature = serpent then
put_line( "The spear bounces harmlessly against its scales." );
else
put_line( "With a groan, you heave the javelin and it pierces its chest!" );
damage_to_creature := integer(numerics.rnd( 4 )) + spear_damage;
if creature = draco then
damage_to_creature := damage_to_creature * 4;
put_line( "The dragon screams in pain!" );
end if;
end if;
exit;
else
put_line( "Throw what?" );
end if;
else
put_line( "Why? There is no enemy." );
end if;
when '9' =>
-- magic potion
if has_item( potion ) then
has_item( potion ) := false;
if level > 2 and hit_points < 5 then
put_line( "As if you really had any other option..." );
delay 2.0;
elsif level > 2 and hit_points > 15 then
put_line( "What a waste..." );
delay 2.0;
end if;
put_line( "Gulping down the potion, your wounds are magically healed." );
hit_points := 20;
exit;
else
put_line( "Drink what?" );
end if;
when 'r'|'R' =>
-- review stats
show_status;
when others =>
put_line( "Pardon?" );
end case;
end loop;
end if; -- paralysis
-- post command tests
hit_points := hit_points - damage_to_player;
if hit_points <= 0 then
status := dead;
end if;
if distance <= 0 or status = dead then
exit;
end if;
-- apply battle damage
if creature /= no_creature then
creature_hp := creature_hp - damage_to_creature;
if creature_hp <= 0 then
declare
ch : character;
bonus_points : constant natural := level * 20;
begin
new_line;
put_line( "You have defeated the " & creature_name & "." );
delay 1.0;
put( tty_inverse & "BONUS: " & tty_normal );
put_line( bonus_points );
quest_bonus := quest_bonus + bonus_points;
creature := no_creature;
creature_here := false;
put( "Press any key *" & ASCII.BS );
ch := inkey;
end;
else
delay 2.0;
end if;
else
delay 2.0;
end if;
end loop; -- main (round) loop
-- Level Complete
if status = alive then
declare
item_bonus : natural := 0;
level_bonus : natural := 0;
begin
clear;
put_line( tty_inverse & "Draco II" & tty_normal );
new_line;
put( "Congratulations! You made it through level" );
put( level );
put_line( "!!" );
new_line;
for i in staff..ring loop
if has_item( i ) then
item_bonus := item_bonus + 10;
end if;
end loop;
put( "Score: " );
put( score, "ZZZZZ9" );
new_line;
new_line;
delay 1.0;
put( "Quest bonus: " );
put( quest_bonus, "ZZZZZ9" );
new_line;
delay 0.5;
put( "Item bonus: " );
put( item_bonus, "ZZZZZ9" );
new_line;
level_bonus := numerics.rounding( (level_distance * 10) / round + level * 10 );
delay 0.5;
put( "Level bonus: " );
put( level_bonus, "ZZZZZ9" );