home *** CD-ROM | disk | FTP | other *** search
- !
- ! 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;
-
- ! Every other minute, restore some hit points !
- if minute % 2 = 0 and group.energy > 0 then
- foreach player do
- gosub HEAL_HP;
- if minute % 4 = 0 then
- gosub HEAL_PWR;
- 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 !
- inc( group.energy, MinutesInAnHour * 4 );
- for L252 = 0 to MinutesInAnHour / 2 do
- foreach player do
- gosub HEAL_HP;
- if L252 % 2 then
- gosub HEAL_PWR;
- 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
- if player.hp > 0 and not player.poisoned then ! alive and not sick !
- dec( player.energy );
- if player.energy = 0 then
- if group.food > 0 then
- dec( group.food );
- player.energy = 255;
- else
- writeln( player.name, " is hungry, but you have no food!" );
- 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;
-
-
-