home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Select: Games 3
/
cd.iso
/
games
/
dcg303
/
control.scr
< prev
next >
Wrap
Text File
|
1993-05-23
|
17KB
|
548 lines
!
! CONTROL.SCR
!
! This script manages some independent functions of the game system. The
! script is called by the game driver at certain points during game play,
! and the entry points are numeric (@0, @1, @2..) instead of the usual entry
! points (@TALK, @GET, ..).
!
! QUICK SUMMARY OF ENTRY POINTS:
!
! :@0 - Time Control. Executed once every minute (game time).
! :@1 - Resting. Executed when party decides to rest ('C'amp-Out)
! :@2 - Leave Party. Removes a party member. ('V'acate command)
!
!---------------------------------------------------------------------------!
:@0 ! Entry Point @0 : Time Control Script !
!---------------------------------------------------------------------------!
!
! This script will start execution at this label once per minute during
! regular play. This does not include battles or when the party is resting.
!
! Time is controled by seting the following variables from any script:
!
! Variable Default Description
! ------------------- ------- --------------------------------
! MovesPerMinute 2 # of moves per game 'minute'
! MinutesInAnHour 60 # of minutes in an game 'hour'
! HoursInADay 24 # of hour in a game 'day'
! DaysInAMonth 30 # of days in a game 'month'
! MonthsInAYear 12 # of months in a game 'year'
!
! The CURRENT time is obtained (and modified) by setting the following
! variables:
!
! year Current Year (Range -32767 to 32767)
! month Current Month (Range 0 to MonthsInAYear - 1)
! day Current Day (Range 0 to DaysInAMonth - 1)
! hour Current Hour (Range 0 to HoursInADay - 1)
! minute Current Minute (Range 0 to MinutesInADay - 1)
!
! Note that the year, month, day, hour and minute variables are automaticly
! updated by the game driver, but you can modify these variables just like
! any other one.
!
L255 = group.current; ! Save current party spokesperson !
L254 = FALSE; ! Have NOT created a random monster !
dec( group.energy ); ! Get Tired !
! Once an hour.. !
if minute = 0 then
! Create a random monster 1 out of every 5 times (approx) !
if random(5) = 0 then
if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
gosub NEWMONSTER;
endif;
endif;
! Check to see if you have food.. !
if group.food <= group.size then
if group.food = 0 then
writeln( "You have no food.." );
else
writeln( "You are running out of food.." );
endif;
endif;
endif;
! Every quarter of an hour !
L25 = max(MinutesInAnHour / 4 + 1,2);
if NOT(minute % L25) then
! Group must rest within 2 hours or start suffering damage !
if group.energy < MinutesInAnHour * 2 then
if group.energy > 0 then
writeln( "You must rest soon.." );
else
writeln( "You are exhausted.." );
endif;
endif;
! Check for poison, hunger and exhaustion !
foreach player do
if player.hp > 0 then
if player.poisoned then
s0 = "poisoning";
gosub HITPLAYER;
elsif player.energy = 0 and group.food = 0 then
s0 = "hunger";
gosub HITPLAYER;
elsif group.energy <= 0 then
s0 = "exhaustion";
gosub HITPLAYER;
endif;
endif;
endfor;
endif;
!
! The following controls healing and recovery of power. You can
! change the rate of healing by using a different value, but remember
! that the power heal value (8 below) should be a MULTIPLE of the
! first number (4) or it will not work.
!
if minute % 4 = 0 and group.energy > 0 then
foreach player do
if group.food or player.energy then
gosub HEAL_HP;
! Every 8 (twice as slow) restore power
if minute % 8 = 0 then
gosub HEAL_PWR;
endif;
endif;
endfor;
endif;
if world.type = ARENA and L254 = FALSE then
gosub NEWMONSTER;
endif;
! Go back with same selected spokesperson.. !
group.current = L255;
CONTINUE;
!---------------------------------------------------------------------------!
:@1 ! Entry Point @1 : Party decides to rest (CAMP OUT) !
!---------------------------------------------------------------------------!
!
! First, all temporary magical effects are eliminated by reducing any
! attribute that exceeds the maximum value for the same attribute.
!
! Armor, Shields, Rings and Amulets re-apply their effect (if any).
!
! The group rests for a third of a day, in one hour increments. For
! each hour rested, the group gains 4 hours of 'wake-up' energy. This
! means the group should be able to go one and a third days without
! sleep.
!
! Random monsters may appear, but not too often.
!
write( "Resting.." );
L255 = group.current; ! Save current party spokesperson !
L254 = FALSE; ! Have NOT created a random monster !
foreach player do
! First, get rid of temporary magical increases in attributes !
player.str = min(player.str,player.mstr);
player.aim = min(player.aim,player.maim);
player.dex = min(player.dex,player.mdex);
player.spd = min(player.spd,player.mspd);
player.pwr = min(player.pwr,player.mpwr);
player.hp = min(player.hp, player.mhp);
player.iq = min(player.iq, player.miq);
player.ac = min(player.ac, player.mac);
if player.armor.count or player.shield.count then
if player.armor.cursed or player.shield.cursed then
player.ac = 0;
else
inc( player.ac, player.armor.ac + player.shield.ac );
endif;
endif;
if player.ring.count and player.ring.charges then
curritem = player.ring;
gosub M1_INVOKE;
endif;
if player.amulet.count and player.ring.charges then
curritem = player.amulet;
gosub M1_INVOKE;
endif;
endfor;
! # of hours to rest is one third of a day !
for L253 = 1 to HoursInADay / 3 + 1 do
! Each hour of sleep gives 4 hours of energy !
if group.energy + MinutesInAnHour * 4 > 32767 then
group.energy = 32767;
else
inc( group.energy, MinutesInAnHour * 4 );
endif;
for L252 = 0 to MinutesInAnHour / 2 do
foreach player do
if group.food or player.energy then
gosub HEAL_HP;
if L252 % 2 then
gosub HEAL_PWR;
endif;
endif;
endfor;
endfor;
! Check to see if random monsters appear !
if world.type = OUTDOORS or world.type = DUNGEON or world.type = HAUNTED then
if random(17) = 0 then
gosub NEWMONSTER;
if L254 then
writeln( "You wake up under attack.." );
FIGHT; ! Wake up and fight.. !
endif;
endif;
endif;
endfor;
group.current = L255; ! Go back to original spokes person !
STOP;
!---------------------------------------------------------------------------!
:@2 ! Entry Point @2 : Leave Party !
!---------------------------------------------------------------------------!
!
! The currently selected member is the one that will attempt to leave the
! party.
!
! NOTE: When the game player selects 'V'acate, he/she is asked to select
! which player. The script for the player is invoked if it has a :@DROP
! entry point. If the script terminates with CONTINUE or the script does
! NOT have an :@DROP entry, this script will be executed.
!
if player.index = 0 then
writeln( "YOU can't leave the party!" );
STOP;
endif;
if player.hp = 0 then
writeln( "You leave ", player.name, "'s body where it lays.." );
elsif player.hp < 2 then
writeln( "You abandon ", player.name, ", who is almost dead.." );
else
writeln( player.name, " leaves the group." );
endif;
LEAVE(player.index);
STOP;
!
! SUBROUTINE: HEAL_HP
!
! Heal the players with the passage of time
!
:HEAL_HP
! alive and not sick !
if player.hp > 0 and not player.poisoned then
dec( player.energy );
if player.energy <= 0 then
if group.food > 0 then
dec( group.food );
player.energy = 255;
else
writeln( player.name, " goes hungry!" );
return;
endif;
endif;
if player.hp < player.mhp then
inc( player.hp );
endif;
endif;
return;
!
! SUBROUTINE: HEAL_PWR
!
! Restore magic points withthe passage of time..
!
:HEAL_PWR
if player.hp > 0 and player.energy > 0 and player.pwr < player.mpwr then
inc( player.pwr );
if player.class = ELF and player.pwr < player.mpwr then
inc( player.pwr ); ! Do elves faster.. !
endif;
endif;
return;
!
! SUBROUTINE to create a Random Monster
!
:NEWMONSTER
! Try to find a position for the monster up to 8 times..
for L3 = 1 to 8 do
L0 = group.x + random(8) - 4;
L1 = group.y + random(8) - 4;
if L0 < 0 then L0 = 0; endif;
if L1 < 0 then L1 = 0; endif;
if L0 >= world.x then L0 = world.x - 1; endif;
if L1 >= world.y then L1 = world.y - 1; endif;
if L0 <> player.x or L1 <> player.y then
L2 = world.density(L0,L1);
if L2 = FLAT or L2 = ROUGH or L2 = VERY_ROUGH then
! Create a LAND-BASED monster !
L2 = random(3); ! Small, Medium or Large (0-2) !
L3 = random(L2+3); ! Select a graphics block for that size (0-4) !
if world.type = DUNGEON then
L4 = DEFCAVEBLK( L3 ); ! Leader !
L5 = DEFCAVEBLK( random(L3+1) ); ! Follower !
L6 = CAVE_MONSTER;
elsif world.type = HAUNTED then
L4 = DEFSPOOKBLK( L3 ); ! Leader !
L5 = DEFSPOOKBLK( random(L3+1) ); ! Follower !
L6 = SPOOK_MONSTER;
else
! OUTDOORS or ARENA !
L4 = DEFLANDBLK( L3 ); ! Leader !
L5 = DEFLANDBLK( random(L3+1) ); ! Follower !
L6 = LAND_MONSTER;
endif;
goto DOIT;
elsif L2 = DEEP_WATER then
! Create a WATER-BOUND monster !
L2 = random(3); ! Small, Medium, Large (0-2) !
if random(5) = 0 then ! Pirate Ship (SPECIAL CASE) !
L4 = DEFWATERBLK(4); ! Fifth water monster is a ship !
L5 = DEFWATERBLK(4); ! Followers are ships also !
else
L3 = random(L2+2); ! Select a graphics block for that size (0-3) !
L4 = DEFWATERBLK( L3 ); ! Leader !
L5 = DEFWATERBLK( random(L3+1) ); ! Follower !
endif;
L6 = WATER_MONSTER;
goto DOIT;
endif;
endif;
endfor;
return; ! Tried 8 Times, give up !
:DOIT
new(npc,L0,L1,L4);
npc.type = HOSTILE; ! NPC Type
npc.stats = defstat(L2); ! Statistics Record
npc.block2 = L5; ! Followers (if any)
npc.class = L6; ! Monster Class
! Gold carried
if world.type = ARENA then
npc.value = random(50)+1; ! Very little money (Up to 5 gold pieces) !
else
npc.value = 0;
endif;
!
! # of monsters in the group. The formula is based on L2 (monster size).
! If small (L2=0), then # = random( group.size + 6 ) + 1
! If medium (L2=1), then # = random( group.size + 3 ) + 1
! if large (L2=2), then # = random( group.size ) + 1
npc.count = random( group.size + (2 - L2) * 3 ) + 1;
L254 = TRUE; ! Monster has been created !
return;
!
! This SUBROUTINE will hit every player in the group by using the
! subroutine HITPLAYER.
!
:HITGROUP
foreach player do
gosub HITPLAYER;
endfor;
return;
!
! This SUBROUTINE will decrement the hit points of the current
! group member. It checks to see if the player has died or lost
! consciousnes. The variable S0 contains the reason for the hit.
!
:HITPLAYER
if player.hp > 0 then
dec( player.hp );
if player.hp = 0 then
writeln( player.name, " has died of ", s0, "!" );
elsif player.hp = 1 then
writeln( player.name, " has fainted from ", s0, "!" );
else
writeln( player.name, " weakens!" );
endif;
endif;
return;
!------------------------------------------------------------------------!
!
! SUBROUTINE: M1_INVOKE
!
! Type 1 Magic - Affects the person invoking the magic..
!
! This code is equivalent to the one in OBJECT.SCR. When resting,
! rings and amulets that have magical properties will re-invoke their
! effect when you wake up.
!
!------------------------------------------------------------------------!
:M1_INVOKE
!------------------------------------------------------------------------!
if curritem.cursed then
if curritem.permanent then
writeln( "WARNING: Cursed Item with permanent effect not recommended!");
curritem.permanent = FALSE;
endif;
endif;
if curritem.charges < 255 then
dec(curritem.charges); ! 255 means forever !
endif;
on curritem.class goto
M1_NONE, M1_CURE, M1_HEAL, M1_POISON, M1_RESTORE,
M1_STR, M1_DEX, M1_SPD, M1_AIM, M1_AC,
M1_HP, M1_IQ, M1_PWR;
:M1_NONE
return;
:M1_CURE
if player.poisoned then
player.poisoned = 0;
writeln( player.name, " is now cured." );
endif;
return;
:M1_HEAL
if player.hp > 0 and player.hp < player.mhp then
if curritem.units > 0 then
L0 = curritem.units; ! always heals the same points !
else
L0 = random(player.mhp - player.hp)+1; ! heal a random number of points !
endif;
if player.hp + L0 < player.mhp then
writeln( player.name, " heals ", L0, " hit points.." );
inc( player.hp, L0 );
else
writeln( player.name, " has been completely healed!" );
player.hp = player.mhp;
endif;
endif;
return;
:M1_POISON
if NOT player.poisoned then
player.poisoned = TRUE;
writeln( player.name, " is poisoned!" );
endif;
return;
:M1_RESTORE
if player.hp < player.mhp then
player.hp = player.mhp;
writeln( player.name, " is completely healed!" );
endif;
return;
:M1_STR
if curritem.cursed then
player.str = 0;
else
inc( player.hp, curritem.units );
if curritem.permanent then
inc( player.mhp, curritem.units );
endif;
writeln( player.name, "'s strength increased by ", curritem.units, "!" );
endif;
return;
:M1_DEX
if curritem.cursed then
player.dex = 0;
else
inc( player.dex, curritem.units );
if curritem.permanent then
inc( player.mdex, curritem.units );
endif;
writeln( player.name, "'s dexterity increased by ", curritem.units, "!" );
endif;
return;
:M1_SPD
if curritem.cursed then
player.spd = 0;
else
inc( player.spd, curritem.units );
if curritem.permanent then
inc( player.mspd, curritem.units );
endif;
writeln( player.name, "'s speed increased by ", curritem.units, "!" );
endif;
return;
:M1_AIM
if curritem.cursed then
player.aim = 0;
else
inc( player.aim, curritem.units );
if curritem.permanent then
inc( player.maim, curritem.units );
endif;
writeln( player.name, "'s aim increased by ", curritem.units, "!" );
endif;
return;
:M1_AC
if curritem.cursed then
player.ac = 0;
else
inc( player.ac, curritem.units );
if curritem.permanent then
inc( player.mac, curritem.units );
endif;
writeln( player.name, "'s armor class increased by ", curritem.units, "!" );
endif;
return;
:M1_HP
if curritem.cursed then
player.hp = player.hp / 3 + 1;
else
inc( player.hp, curritem.units );
if curritem.permanent then
inc( player.mhp, curritem.units );
endif;
writeln( player.name, "'s hit points increased by ", curritem.units, "!" );
endif;
return;
:M1_IQ
if curritem.cursed then
player.iq = 0;
else
inc( player.iq, curritem.units );
if curritem.permanent then
inc( player.miq, curritem.units );
endif;
writeln( player.name, "'s i.q. increased by ", curritem.units, "!" );
endif;
return;
:M1_PWR
if player.class = ELF or player.class = WIZARD then
if curritem.cursed then
player.pwr = 0;
else
inc( player.pwr, curritem.units );
if curritem.permanent then
inc( player.mpwr, curritem.units );
endif;
writeln( player.name, "'s power increased by ", curritem.units, "!" );
endif;
else
write( player.name, " has a headache all night long.." );
if player.hp < 3 then
writeln( " and dies!" );
player.hp = 0;
else
writeln;
dec( player.hp, 2 );
endif;
endif;
return;