home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Games 3 / cd.iso / games / dcg303xa / control.scr < prev    next >
Text File  |  1993-05-23  |  17KB  |  548 lines

  1. !
  2. ! CONTROL.SCR
  3. !
  4. ! This script manages some independent functions of the game system.  The
  5. ! script is called by the game driver at certain points during game play,
  6. ! and the entry points are numeric (@0, @1, @2..) instead of the usual entry
  7. ! points (@TALK, @GET, ..).
  8. !
  9. ! QUICK SUMMARY OF ENTRY POINTS:
  10. !
  11. ! :@0 - Time Control.  Executed once every minute (game time).
  12. ! :@1 - Resting.       Executed when party decides to rest ('C'amp-Out)
  13. ! :@2 - Leave Party.   Removes a party member. ('V'acate command)
  14. !
  15.  
  16. !---------------------------------------------------------------------------!
  17. :@0 ! Entry Point @0 : Time Control Script                                  !
  18. !---------------------------------------------------------------------------!
  19. !
  20. ! This script will start execution at this label once per minute during
  21. ! regular play.  This does not include battles or when the party is resting.
  22. !
  23. ! Time is controled by seting the following variables from any script:
  24. !
  25. !   Variable             Default  Description
  26. !   -------------------  -------  --------------------------------
  27. !   MovesPerMinute             2  # of moves per game 'minute'
  28. !   MinutesInAnHour           60  # of minutes in an game 'hour'
  29. !   HoursInADay               24  # of hour in a game 'day'
  30. !   DaysInAMonth              30  # of days in a game 'month'
  31. !   MonthsInAYear             12  # of months in a game 'year'
  32. !   
  33. ! The CURRENT time is obtained (and modified) by setting the following
  34. ! variables:
  35. !
  36. !   year                 Current Year   (Range -32767 to 32767)
  37. !   month                Current Month  (Range 0 to MonthsInAYear - 1)
  38. !   day                  Current Day    (Range 0 to DaysInAMonth  - 1)
  39. !   hour                 Current Hour   (Range 0 to HoursInADay   - 1)
  40. !   minute               Current Minute (Range 0 to MinutesInADay - 1)
  41. !
  42. ! Note that the year, month, day, hour and minute variables are automaticly
  43. ! updated by the game driver, but you can modify these variables just like
  44. ! any other one.
  45. !
  46.  
  47.   L255 = group.current; ! Save current party spokesperson   !
  48.   L254 = FALSE;         ! Have NOT created a random monster !
  49.   dec( group.energy );  ! Get Tired !
  50.  
  51. ! Once an hour.. !
  52. if minute = 0 then 
  53.   ! Create a random monster 1 out of every 5 times (approx) !
  54.   if random(5) = 0 then
  55.     if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
  56.       gosub NEWMONSTER;
  57.     endif;
  58.   endif;
  59.   ! Check to see if you have food.. !
  60.   if group.food <= group.size then
  61.     if group.food = 0 then
  62.       writeln( "You have no food.." );
  63.     else
  64.       writeln( "You are running out of food.." );
  65.     endif;
  66.   endif;
  67. endif;
  68.  
  69. ! Every quarter of an hour !
  70. L25 = max(MinutesInAnHour / 4 + 1,2);
  71. if NOT(minute % L25) then
  72.   ! Group must rest within 2 hours or start suffering damage !
  73.   if group.energy < MinutesInAnHour * 2 then 
  74.     if group.energy > 0 then
  75.       writeln( "You must rest soon.." );
  76.     else
  77.       writeln( "You are exhausted.." );
  78.     endif;
  79.   endif;
  80.   ! Check for poison, hunger and exhaustion !
  81.   foreach player do
  82.     if player.hp > 0 then
  83.       if player.poisoned then
  84.         s0 = "poisoning";
  85.         gosub HITPLAYER;
  86.       elsif player.energy = 0 and group.food = 0 then
  87.         s0 = "hunger";
  88.         gosub HITPLAYER;
  89.       elsif group.energy <= 0 then
  90.         s0 = "exhaustion";
  91.         gosub HITPLAYER;
  92.       endif;
  93.     endif;
  94.   endfor;
  95. endif;
  96.  
  97. !
  98. ! The following controls healing and recovery of power.  You can
  99. ! change the rate of healing by using a different value, but remember
  100. ! that the power heal value (8 below) should be a MULTIPLE of the
  101. ! first number (4) or it will not work.
  102. !
  103. if minute % 4 = 0 and group.energy > 0 then
  104.   foreach player do
  105.     if group.food or player.energy then
  106.       gosub HEAL_HP;
  107.       ! Every 8 (twice as slow) restore power
  108.       if minute % 8 = 0 then
  109.         gosub HEAL_PWR;
  110.       endif;
  111.     endif;
  112.   endfor;
  113. endif;
  114.  
  115. if world.type = ARENA and L254 = FALSE then
  116.   gosub NEWMONSTER;
  117. endif;
  118.  
  119. ! Go back with same selected spokesperson.. !
  120. group.current = L255;
  121. CONTINUE;
  122.  
  123. !---------------------------------------------------------------------------!
  124. :@1 ! Entry Point @1 : Party decides to rest (CAMP OUT)                     !
  125. !---------------------------------------------------------------------------!
  126. !
  127. ! First, all temporary magical effects are eliminated by reducing any 
  128. ! attribute that exceeds the maximum value for the same attribute.
  129. !
  130. ! Armor, Shields, Rings and Amulets re-apply their effect (if any).
  131. !
  132. ! The group rests for a third of a day, in one hour increments.  For
  133. ! each hour rested, the group gains 4 hours of 'wake-up' energy.  This
  134. ! means the group should be able to go one and a third days without 
  135. ! sleep.
  136. !
  137. ! Random monsters may appear, but not too often.
  138. !
  139.   write( "Resting.." );
  140.   L255 = group.current; ! Save current party spokesperson   !
  141.   L254 = FALSE;         ! Have NOT created a random monster !
  142.   foreach player do
  143.     ! First, get rid of temporary magical increases in attributes !
  144.     player.str = min(player.str,player.mstr);
  145.     player.aim = min(player.aim,player.maim);
  146.     player.dex = min(player.dex,player.mdex);
  147.     player.spd = min(player.spd,player.mspd);
  148.     player.pwr = min(player.pwr,player.mpwr);
  149.     player.hp  = min(player.hp, player.mhp);
  150.     player.iq  = min(player.iq, player.miq);
  151.     player.ac  = min(player.ac, player.mac);
  152.     if player.armor.count or player.shield.count then
  153.       if player.armor.cursed or player.shield.cursed then
  154.         player.ac = 0;
  155.       else
  156.         inc( player.ac, player.armor.ac + player.shield.ac );
  157.       endif;
  158.     endif;
  159.     if player.ring.count and player.ring.charges then
  160.       curritem = player.ring;
  161.       gosub M1_INVOKE;
  162.     endif;
  163.     if player.amulet.count and player.ring.charges then
  164.       curritem = player.amulet;
  165.       gosub M1_INVOKE;
  166.     endif;
  167.   endfor;
  168.   ! # of hours to rest is one third of a day !
  169.   for L253 = 1 to HoursInADay / 3 + 1 do 
  170.     ! Each hour of sleep gives 4 hours of energy !
  171.     if group.energy + MinutesInAnHour * 4 > 32767 then
  172.       group.energy = 32767;
  173.     else
  174.       inc( group.energy, MinutesInAnHour * 4 );
  175.     endif;
  176.     for L252 = 0 to MinutesInAnHour / 2 do
  177.       foreach player do
  178.        if group.food or player.energy then
  179.           gosub HEAL_HP;
  180.           if L252 % 2 then
  181.             gosub HEAL_PWR;
  182.           endif;
  183.         endif;
  184.       endfor;
  185.     endfor;
  186.     ! Check to see if random monsters appear !
  187.     if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
  188.       if random(17) = 0 then
  189.         gosub NEWMONSTER;
  190.         if L254 then
  191.           writeln( "You wake up under attack.." );
  192.           FIGHT;       ! Wake up and fight.. !
  193.         endif;
  194.       endif;
  195.     endif;
  196.   endfor;
  197.   group.current = L255; ! Go back to original spokes person !
  198.   STOP;
  199.  
  200. !---------------------------------------------------------------------------!
  201. :@2 ! Entry Point @2 : Leave Party                                          !
  202. !---------------------------------------------------------------------------!
  203. !
  204. ! The currently selected member is the one that will attempt to leave the
  205. ! party. 
  206. !
  207. ! NOTE: When the game player selects 'V'acate, he/she is asked to select
  208. ! which player. The script for the player is invoked if it has a :@DROP
  209. ! entry point. If the script terminates with CONTINUE or the script does
  210. ! NOT have an :@DROP entry, this script will be executed.
  211. !
  212.  
  213.   if player.index = 0 then
  214.     writeln( "YOU can't leave the party!" );
  215.     STOP;
  216.   endif;
  217.   if player.hp = 0 then
  218.     writeln( "You leave ", player.name, "'s body where it lays.." );
  219.   elsif player.hp < 2 then
  220.     writeln( "You abandon ", player.name, ", who is almost dead.." );
  221.   else
  222.     writeln( player.name, " leaves the group." );
  223.   endif;
  224.   LEAVE(player.index);
  225.   STOP;
  226.  
  227. !
  228. ! SUBROUTINE: HEAL_HP
  229. !
  230. ! Heal the players with the passage of time
  231. !
  232. :HEAL_HP
  233.   ! alive and not sick !
  234.   if player.hp > 0 and not player.poisoned then
  235.     dec( player.energy );
  236.     if player.energy <= 0 then
  237.       if group.food > 0 then
  238.         dec( group.food );
  239.         player.energy = 255;
  240.       else
  241.         writeln( player.name, " goes hungry!" );
  242.         return;
  243.       endif;
  244.     endif;
  245.     if player.hp < player.mhp then
  246.       inc( player.hp );
  247.     endif;
  248.   endif;
  249.   return;
  250.  
  251. !
  252. ! SUBROUTINE: HEAL_PWR
  253. !
  254. ! Restore magic points withthe passage of time..
  255. !
  256. :HEAL_PWR
  257.   if player.hp > 0 and player.energy > 0 and player.pwr < player.mpwr then
  258.     inc( player.pwr );
  259.     if player.class = ELF and player.pwr < player.mpwr then
  260.       inc( player.pwr ); ! Do elves faster.. !
  261.     endif;
  262.   endif;
  263.   return;
  264.  
  265. !
  266. ! SUBROUTINE to create a Random Monster
  267. !
  268. :NEWMONSTER
  269.   ! Try to find a position for the monster up to 8 times..
  270.   for L3 = 1 to 8 do
  271.     L0 = group.x + random(8) - 4;
  272.     L1 = group.y + random(8) - 4;
  273.     if L0 < 0 then L0 = 0; endif;
  274.     if L1 < 0 then L1 = 0; endif;
  275.     if L0 >= world.x then L0 = world.x - 1; endif;
  276.     if L1 >= world.y then L1 = world.y - 1; endif;
  277.     if L0 <> player.x or L1 <> player.y then
  278.       L2 = world.density(L0,L1);
  279.       if L2 = FLAT or L2 = ROUGH or L2 = VERY_ROUGH then
  280.         ! Create a LAND-BASED monster !
  281.         L2 = random(3);    ! Small, Medium or Large (0-2) !
  282.         L3 = random(L2+3); ! Select a graphics block for that size (0-4) !
  283.         if world.type = DUNGEON then
  284.           L4 = DEFCAVEBLK( L3 );            ! Leader   !
  285.           L5 = DEFCAVEBLK( random(L3+1) );  ! Follower !
  286.           L6 = CAVE_MONSTER;
  287.         elsif world.type = HAUNTED then
  288.           L4 = DEFSPOOKBLK( L3 );           ! Leader   !
  289.           L5 = DEFSPOOKBLK( random(L3+1) ); ! Follower !
  290.           L6 = SPOOK_MONSTER;
  291.         else
  292.           ! OUTDOORS or ARENA !
  293.           L4 = DEFLANDBLK( L3 );            ! Leader   !
  294.           L5 = DEFLANDBLK( random(L3+1) );  ! Follower !
  295.           L6 = LAND_MONSTER;
  296.         endif;
  297.         goto DOIT;
  298.       elsif L2 = DEEP_WATER then
  299.         ! Create a WATER-BOUND monster !
  300.         L2 = random(3);        ! Small, Medium, Large (0-2) !
  301.         if random(5) = 0 then  ! Pirate Ship (SPECIAL CASE) !
  302.           L4 = DEFWATERBLK(4); ! Fifth water monster is a ship !
  303.           L5 = DEFWATERBLK(4); ! Followers are ships also !
  304.         else
  305.           L3 = random(L2+2); ! Select a graphics block for that size (0-3) !
  306.           L4 = DEFWATERBLK( L3 );            ! Leader   !
  307.           L5 = DEFWATERBLK( random(L3+1) );  ! Follower !
  308.         endif;
  309.         L6 = WATER_MONSTER;
  310.         goto DOIT;
  311.       endif;
  312.     endif;
  313.   endfor;
  314.   return; ! Tried 8 Times, give up !
  315.  
  316. :DOIT
  317.   new(npc,L0,L1,L4);
  318.   npc.type   = HOSTILE;       ! NPC Type
  319.   npc.stats  = defstat(L2);   ! Statistics Record
  320.   npc.block2 = L5;            ! Followers (if any)
  321.   npc.class  = L6;            ! Monster Class
  322.  
  323.   ! Gold carried
  324.   if world.type = ARENA then
  325.     npc.value = random(50)+1; ! Very little money (Up to 5 gold pieces) !
  326.   else
  327.     npc.value = 0;
  328.   endif;
  329.  
  330.   !
  331.   ! # of monsters in the group.  The formula is based on L2 (monster size).
  332.   ! If small  (L2=0), then # = random( group.size + 6 ) + 1
  333.   ! If medium (L2=1), then # = random( group.size + 3 ) + 1
  334.   ! if large  (L2=2), then # = random( group.size ) + 1
  335.   npc.count = random( group.size + (2 - L2) * 3 ) + 1;
  336.  
  337.   L254 = TRUE; ! Monster has been created !
  338.   return;
  339.  
  340. !
  341. ! This SUBROUTINE will hit every player in the group by using the
  342. ! subroutine HITPLAYER.
  343. !
  344. :HITGROUP
  345.   foreach player do
  346.     gosub HITPLAYER;
  347.   endfor;
  348.   return;
  349.  
  350. !
  351. ! This SUBROUTINE will decrement the hit points of the current
  352. ! group member.  It checks to see if the player has died or lost
  353. ! consciousnes.  The variable S0 contains the reason for the hit.
  354. !
  355. :HITPLAYER
  356.   if player.hp > 0 then
  357.     dec( player.hp );
  358.     if player.hp = 0 then
  359.       writeln( player.name, " has died of ", s0, "!" );
  360.     elsif player.hp = 1 then
  361.       writeln( player.name, " has fainted from ", s0, "!" );
  362.     else
  363.       writeln( player.name, " weakens!" );
  364.     endif;
  365.   endif;
  366.   return;
  367.  
  368.  
  369. !------------------------------------------------------------------------!
  370. !
  371. ! SUBROUTINE: M1_INVOKE
  372. !
  373. ! Type 1 Magic - Affects the person invoking the magic..
  374. !
  375. ! This code is equivalent to the one in OBJECT.SCR.  When resting, 
  376. ! rings and amulets that have magical properties will re-invoke their
  377. ! effect when you wake up.
  378. !
  379. !------------------------------------------------------------------------!
  380. :M1_INVOKE
  381. !------------------------------------------------------------------------!
  382.  
  383.   if curritem.cursed then
  384.     if curritem.permanent then
  385.       writeln( "WARNING: Cursed Item with permanent effect not recommended!");
  386.       curritem.permanent = FALSE;
  387.     endif;
  388.   endif;
  389.  
  390.   if curritem.charges < 255 then
  391.     dec(curritem.charges);  ! 255 means forever !
  392.   endif;
  393.  
  394.   on curritem.class goto
  395.     M1_NONE,    M1_CURE,    M1_HEAL,    M1_POISON,    M1_RESTORE,
  396.     M1_STR,     M1_DEX,     M1_SPD,     M1_AIM,       M1_AC,
  397.     M1_HP,      M1_IQ,      M1_PWR;
  398.  
  399. :M1_NONE
  400.   return;
  401.  
  402. :M1_CURE
  403.   if player.poisoned then
  404.     player.poisoned = 0;
  405.     writeln( player.name, " is now cured." );
  406.   endif;
  407.   return;
  408.  
  409. :M1_HEAL
  410.   if player.hp > 0 and player.hp < player.mhp then
  411.     if curritem.units > 0 then
  412.       L0 = curritem.units;                   ! always heals the same points !
  413.     else
  414.       L0 = random(player.mhp - player.hp)+1; ! heal a random number of points !
  415.     endif;
  416.     if player.hp + L0 < player.mhp then
  417.       writeln( player.name, " heals ", L0, " hit points.." );
  418.       inc( player.hp, L0 );
  419.     else
  420.       writeln( player.name, " has been completely healed!" );
  421.       player.hp = player.mhp;
  422.     endif;
  423.   endif;
  424.   return;
  425.  
  426. :M1_POISON
  427.   if NOT player.poisoned then
  428.     player.poisoned = TRUE;
  429.     writeln( player.name, " is poisoned!" );
  430.   endif;
  431.   return;
  432.  
  433. :M1_RESTORE
  434.   if player.hp < player.mhp then
  435.     player.hp = player.mhp;
  436.     writeln( player.name, " is completely healed!" );
  437.   endif;
  438.   return;
  439.  
  440. :M1_STR
  441.   if curritem.cursed then
  442.     player.str = 0;
  443.   else
  444.     inc( player.hp, curritem.units );
  445.     if curritem.permanent then
  446.       inc( player.mhp, curritem.units );
  447.     endif;
  448.     writeln( player.name, "'s strength increased by ", curritem.units, "!" );
  449.   endif;
  450.   return;
  451.  
  452. :M1_DEX
  453.   if curritem.cursed then
  454.     player.dex = 0;
  455.   else
  456.     inc( player.dex, curritem.units );
  457.     if curritem.permanent then
  458.       inc( player.mdex, curritem.units );
  459.     endif;
  460.     writeln( player.name, "'s dexterity increased by ", curritem.units, "!" );
  461.   endif;
  462.   return;
  463.  
  464. :M1_SPD
  465.   if curritem.cursed then
  466.     player.spd = 0;
  467.   else
  468.     inc( player.spd, curritem.units );
  469.     if curritem.permanent then
  470.       inc( player.mspd, curritem.units );
  471.     endif;
  472.     writeln( player.name, "'s speed increased by ", curritem.units, "!" );
  473.   endif;
  474.   return;
  475.  
  476. :M1_AIM
  477.   if curritem.cursed then
  478.     player.aim = 0;
  479.   else
  480.     inc( player.aim, curritem.units );
  481.     if curritem.permanent then
  482.       inc( player.maim, curritem.units );
  483.     endif;
  484.     writeln( player.name, "'s aim increased by ", curritem.units, "!" );
  485.   endif;
  486.   return;
  487.  
  488. :M1_AC
  489.   if curritem.cursed then
  490.     player.ac = 0;
  491.   else
  492.     inc( player.ac, curritem.units );
  493.     if curritem.permanent then
  494.       inc( player.mac, curritem.units );
  495.     endif;
  496.     writeln( player.name, "'s armor class increased by ", curritem.units, "!" );
  497.   endif;
  498.   return;
  499.  
  500. :M1_HP
  501.   if curritem.cursed then
  502.     player.hp = player.hp / 3 + 1;
  503.   else
  504.     inc( player.hp, curritem.units );
  505.     if curritem.permanent then
  506.       inc( player.mhp, curritem.units );
  507.     endif;
  508.     writeln( player.name, "'s hit points increased by ", curritem.units, "!" );
  509.   endif;
  510.   return;
  511.  
  512. :M1_IQ
  513.   if curritem.cursed then
  514.     player.iq = 0;
  515.   else
  516.     inc( player.iq, curritem.units );
  517.     if curritem.permanent then
  518.       inc( player.miq, curritem.units );
  519.     endif;
  520.     writeln( player.name, "'s i.q. increased by ", curritem.units, "!" );
  521.   endif;
  522.   return;
  523.  
  524. :M1_PWR
  525.   if player.class = ELF or player.class = WIZARD then
  526.     if curritem.cursed then
  527.       player.pwr = 0;
  528.     else
  529.       inc( player.pwr, curritem.units );
  530.       if curritem.permanent then
  531.         inc( player.mpwr, curritem.units );
  532.       endif;
  533.       writeln( player.name, "'s power increased by ", curritem.units, "!" );
  534.     endif;
  535.   else
  536.     write( player.name, " has a headache all night long.." );
  537.     if player.hp < 3 then
  538.       writeln( " and dies!" );
  539.       player.hp = 0;
  540.     else
  541.       writeln;
  542.       dec( player.hp, 2 );
  543.     endif;
  544.   endif;
  545.   return;
  546.     
  547.  
  548.