static void DoMedUnit(gamebook.Scenario SC, cwords.MPU MP, int Sec) { /* The medical unit is the player character's best friend. It will */ /* heal all injuries and status conditions instantly... until the */ /* player crashes it by trying to hack the medical database, that is. */ rpgmenus.RPGMenu RPM = rpgmenus.CreateRPGMenu(Crt.Color.Red, Crt.Color.Red, Crt.Color.LightRed, WDM.UCM_X + 2, WDM.UCM_Y + 2, WDM.UCM_X2 - 2, WDM.UCM_Y2 - 2); rpgmenus.AddRPGMenuItem(RPM, "Treat Injuries", 1); rpgmenus.AddRPGMenuItem(RPM, "View Records", 2); rpgmenus.AddRPGMenuItem(RPM, "Standby Mode", -1); int N; do { N = rpgmenus.SelectMenu(RPM, rpgmenus.RPMNoCleanup); switch (N) { case 1: HealAllInjuries(SC); break; case 2: TexBrowser(SC, MP, Sec, "MEDICAL RECORDS"); break; } }while (N != -1); }
static void MightActivateTrap(gamebook.Scenario SC) { /*The PC has just stepped on a trap. It might be activated.*/ /*Check and see.*/ /*R stands for Revealed. It's true if the trap is visible*/ /*to the player, false if it's still hidden.*/ bool R = SC.gb.map[SC.PC.m.x - 1, SC.PC.m.y - 1].trap > 0; /*A trap which the player has detected isn't likely to go off,*/ /*but it still might. A trap which hasn't been detected*/ /*by the PC will almost certainly go off.*/ int LS = rpgdice.RollStep(dcchars.PCLuckSave(SC.PC)); if (R && LS < AvoidVisibleTrap) { dccombat.SpringTrap(SC, SC.PC.m.x, SC.PC.m.y); } else if (!R && LS < AvoidTrapTarget) { dccombat.SpringTrap(SC, SC.PC.m.x, SC.PC.m.y); } else if (!R) { dccombat.RevealTrap(SC, SC.PC.m.x, SC.PC.m.y); } }
static void DropItem(gamebook.Scenario SC, dcitems.DCItem I) { /*The player wants to drop an item.*/ dcitems.DelinkDCItem(ref SC.PC.inv, I); dcitems.PlaceDCItem(SC.gb, SC.ig, I, SC.PC.m.x, SC.PC.m.y); RefreshBackPack(SC); }
static bool EqpMenu(gamebook.Scenario SC) { /*This procedure will do all the stuff needed for the*/ /*Equipment menu. Return TRUE if the player should remain*/ /*in the inventory screen, FALSE otherwise.*/ int n = -1; do { n = rpgmenus.SelectMenu(EqpRPM, rpgmenus.RPMNoCleanup); rpgmenus.DisplayMenu(EqpRPM); if (n > 0) { ChangeItem(SC, n); } }while (n != -1 && n != BMK_SwitchCode); if (n == BMK_SwitchCode) { return(true); } return(false); }
static dcitems.DCItem SelectItem(gamebook.Scenario SC, int IK) { /*Create a menu, then query the user for an item which*/ /*corresponds to the kind IK. Return null if either no*/ /*such items are present in the inventory, or if the user*/ /*cancels item selection.*/ //var // RPM: RPGMenuPtr; /*Our menu.*/ // i: DCItemPtr; // t: Integer; /*Create the menu. It's gonna use the InvWindow.*/ rpgmenus.RPGMenu RPM = rpgmenus.CreateRPGMenu(Crt.Color.Black, Crt.Color.Green, Crt.Color.LightGreen, WDM.InvWin_X, WDM.InvWin_Y, WDM.InvWin_X2, WDM.InvWin_Y2); RPM.dBorColor = Crt.Color.White; RPM.dTexColor = DscColor; RPM.dx1 = WDM.DscWin_X; RPM.dy1 = WDM.DscWin_Y; RPM.dx2 = WDM.DscWin_X2; RPM.dy2 = WDM.DscWin_Y2; /*Add one menu item for each appropriate item in the Inventory.*/ dcitems.DCItem i = SC.PC.inv; int t = 1; while (i != null) { if (i.ikind == IK) { rpgmenus.AddRPGMenuItem(RPM, dcitems.ItemNameLong(i), t, dcitems.ItemDesc(i)); } i = i.next; t += 1; } /*Error check- make sure there are items present in the list!!!*/ if (RPM.firstItem == null) { return(null); } /*Sort the menu alphabetically.*/ rpgmenus.RPMSortAlpha(RPM); /*Next, select the item.*/ t = rpgmenus.SelectMenu(RPM, rpgmenus.RPMNormal); if (t == -1) { i = null; } else { i = dcitems.LocateItem(SC.PC.inv, t); } /*Show the complete inventory list again.*/ rpgmenus.DisplayMenu(InvRPM); return(i); }
static void ChangeItem(gamebook.Scenario SC, int Slot) { /*Change the item that's currently equipped in equipment*/ /*slot Slot. If there are other items that could go there,*/ /*select one of them for use. If not, just unequip the item.*/ /*UnEquip the item in the slot.*/ if (SC.PC.eqp[Slot - 1] != null) { UnEquipItem(SC, Slot); } /*Select a new item, of appropriate type, from the menu.*/ dcitems.DCItem I = SelectItem(SC, Slot); /*Equip it. Any item currently in this slot will be sent to*/ /*the Inventory.*/ if (I != null) { EquipItem(SC, I); } RefreshBackPack(SC); DisplayPCStats(SC); }
static void CreateInvMenu(gamebook.Scenario SC) { /*Create the inventory menu, and store it in InvRPM*/ /*Initialize the menu.*/ InvRPM = rpgmenus.CreateRPGMenu(Crt.Color.Black, Crt.Color.Green, Crt.Color.LightGreen, WDM.InvWin_X, WDM.InvWin_Y, WDM.InvWin_X2, WDM.InvWin_Y2); InvRPM.dBorColor = Crt.Color.White; InvRPM.dTexColor = DscColor; InvRPM.dx1 = WDM.DscWin_X; InvRPM.dy1 = WDM.DscWin_Y; InvRPM.dx2 = WDM.DscWin_X2; InvRPM.dy2 = WDM.DscWin_Y2; /*Add the MenuKeys.*/ rpgmenus.AddRPGMenuKey(InvRPM, BMK_SwitchKey, BMK_SwitchCode); rpgmenus.AddRPGMenuKey(InvRPM, BMK_DropKey, BMK_DropCode); /*Add a MenuItem for each object in the player's inventory.*/ dcitems.DCItem i = SC.PC.inv; int t = 1; while (i != null) { rpgmenus.AddRPGMenuItem(InvRPM, dcitems.ItemNameLong(i), t, dcitems.ItemDesc(i)); i = i.next; t += 1; } /*Sort the menu alphabetically.*/ rpgmenus.RPMSortAlpha(InvRPM); }
public static bool PCCheckXP(gamebook.Scenario SC) { /*Display XP level, current XP, and XP needed.*/ rpgtext.DCGameMessage(String.Format("Level {0} : {1} / {2} XP.", SC.PC.lvl, SC.PC.XP, gamebook.XPNeeded(SC.PC.lvl + 1))); return(false); }
static bool DamageTarget(gamebook.Scenario SC, int TX, int TY, int MOS, AttackRequest AR, int DMG, ref AttackReport Rep) { //{Do DMG damage to whatever happens to be sitting at map} //{location TX,TY.} //{MOS is the Margin Of Success} //M: texmodel.Model; bool exparrot = false; if (SC.gb.mog.IsSet(TX, TY)) { //{It's a model. Do something appropriate to it.} texmodel.Model M = texmodel.FindModelXY(SC.gb.mlist, TX, TY); switch (M.kind) { case critters.MKIND_Critter: exparrot = DamageCritter(SC, critters.LocateCritter(M, SC.CList), MOS, AR, DMG, ref Rep); break; case dcchars.MKIND_Character: exparrot = DamagePC(SC, MOS, AR.ATT, DMG); break; } } return(exparrot); }
static void CreateEqpMenu(gamebook.Scenario SC) { /*Create the equipment menu, and store it in EqpRPM*/ /*Initialize the menu.*/ EqpRPM = rpgmenus.CreateRPGMenu(Crt.Color.Black, Crt.Color.Green, Crt.Color.LightGreen, WDM.EqpWin_X, WDM.EqpWin_Y, WDM.EqpWin_X2, WDM.EqpWin_Y2); EqpRPM.dBorColor = Crt.Color.White; EqpRPM.dTexColor = DscColor; EqpRPM.dx1 = WDM.DscWin_X; EqpRPM.dy1 = WDM.DscWin_Y; EqpRPM.dx2 = WDM.DscWin_X2; EqpRPM.dy2 = WDM.DscWin_Y2; /*Add the MenuKeys.*/ rpgmenus.AddRPGMenuKey(EqpRPM, BMK_SwitchKey, BMK_SwitchCode); /*Add one MenuItem for each Equipment Slot.*/ for (int t = 1; t <= dcchars.NumEquipSlots; ++t) { string m = dcchars.EquipSlotName[t - 1]; if (SC.PC.eqp[t - 1] != null) { m = m + " " + dcitems.ItemNameLong(SC.PC.eqp[t - 1]); } rpgmenus.AddRPGMenuItem(EqpRPM, m, t, dcitems.ItemDesc(SC.PC.eqp[t - 1])); } }
public static void RevealTrap(gamebook.Scenario SC, int TX, int TY) { //{Reveal the trap at location X,Y so that the player will} //{be able to see it.} SC.gb.map[TX - 1, TY - 1].trap = Math.Abs(SC.gb.map[TX - 1, TY - 1].trap); texmaps.DisplayTile(SC.gb, TX, TY); }
public static AttackReport ProcessAttack(gamebook.Scenario SC, AttackRequest AR) { //{We have a filled-out AttackRequest structure. Process it.} AttackReport Rep; if (AR.ATT.Contains(spells.AA_LineAttack)) { Rep = LineAttack(SC, AR); } else if (AR.ATT.Contains(spells.AA_BlastAttack)) { Rep = BlastAttack(SC, AR); } else if (AR.ATT.Contains(spells.AA_SmokeAttack)) { Rep = SmokeAttack(SC, AR); } else { Rep = DirectFire(SC, AR); } if (AR.Attacker.kind == dcchars.MKIND_Character && Rep.XPV > 0) { gamebook.DoleExperience(SC, Rep.XPV); } return(Rep); }
static void ProcessIfYesNo(ref string Event, gamebook.Scenario SC) { /* Two values are supplied as the arguments for this procedure. */ /* If the first is biggest, that's a success. */ /* find out the label of the prompt to print. */ string L = texutil.ExtractWord(ref Event); /* Locate the message from the SCENE variable. */ string msg = LocateEvent(SC, "MSG" + L); /* If such a message exists, print it. */ if (msg != "") { rpgtext.DCGameMessage(msg + " (Y/N)"); } else { rpgtext.DCGameMessage("Yes or No? (Y/N)"); } /* Check for success or failure. */ if (rpgtext.YesNo()) { IfSuccess(ref Event); } else { IfFailure(ref Event, SC); } }
static int ScriptValue(ref string Event, gamebook.Scenario SC) { /* Normally, numerical values will be stored as constants. */ /* Sometimes we may want to do algebra, or use the result of */ /* scenario variables as the parameters for commands. That's */ /* what this function is for. */ string SMsg = texutil.ExtractWord(ref Event); int SV = 0; /* If the first character is one of the value commands, */ /* process the string as appropriate. */ if (char.ToUpper(SMsg[0]) == 'V') { /* Use the contents of a variable instead of a constant. */ texutil.DeleteFirstChar(ref SMsg); int VCode = texutil.ExtractValue(ref SMsg); SV = plotbase.NAttValue(SC.NA, plotbase.NAG_ScriptVar, VCode); } else if (char.ToUpper(SMsg[0]) == 'P') { /* Use one of the Player values instead of a constant. */ texutil.DeleteFirstChar(ref SMsg); if (char.ToUpper(SMsg[0]) == 'L') { SV = PlayVal_Leakage(SC); } } else { /* No command was given, so this must be a constant value. */ SV = texutil.ExtractValue(ref SMsg); } return(SV); }
static void TheDisplay(gamebook.Scenario SC) { /*This procedure sets up the BackPack display.*/ Crt.Window(WDM.EqpWin_X, WDM.EqpWin_Y, WDM.PCSWin_X2, WDM.InvWin_Y2); Crt.ClrScr(); Crt.Window(1, 1, WDM.CON_WIDTH, WDM.CON_HEIGHT); rpgtext.LovelyBox(Crt.Color.LightGray, WDM.EqpWin_X, WDM.EqpWin_Y, WDM.InvWin_X2, WDM.InvWin_Y2); Crt.TextColor(Crt.Color.Green); Crt.GotoXY(WDM.EqpWin_X + 2, WDM.EqpWin_Y2); Crt.TextColor(Crt.Color.LightGray); for (int t = 1; t <= WDM.EqpWin_WIDTH - 3; ++t) { Crt.Write((char)205); } Crt.TextColor(Crt.Color.Green); rpgtext.LovelyBox(Crt.Color.DarkGray, WDM.PCSWin_X, WDM.PCSWin_Y, WDM.PCSWin_X2, WDM.PCSWin_Y2); DisplayPCStats(SC); Crt.TextColor(Crt.Color.DarkGray); Crt.GotoXY(WDM.PCSWin_X, WDM.PCSWin_Y2 + 1); Crt.Write("/ - Mode d - Drop"); Crt.GotoXY(WDM.PCSWin_X, WDM.PCSWin_Y2 + 2); Crt.Write("[SPACE] - Default Item Action"); Crt.GotoXY(WDM.PCSWin_X, WDM.PCSWin_Y2 + 3); Crt.Write("[ESC] - Exit"); }
public static bool PCRepeat(gamebook.Scenario SC) { /*The PC wants to do something or another repeatedly.*/ SC.PC.repCount = 80; SC.PC.repState = 0; return(false); }
public static bool PCEnter(gamebook.Scenario SC) { /*The player just hit the "enter location" key- < or >*/ /*All this procedure does is to set up a trigger.*/ gamebook.SetTrigger(SC, gamebook.PLT_EnterCom, texmaps.GetTerr(SC.gb, SC.PC.m.x, SC.PC.m.y)); return(true); }
//{This unit handles two distinct things: Spells and Item} //{effects.} public static void ProcessSpell(gamebook.Scenario SC, spells.SpellDesc S) { //{The PC is invoking spell S. This may be through psi} //{powers or through the use of an item. Whatever the case,} //{determine the results.} switch (S.eff) { case spells.EFF_ShootAttack: ShootAttack(SC, S); break; case spells.EFF_CloseAttack: CloseAttack(SC, S); break; case spells.EFF_Residual: Residual(SC, S); break; case spells.EFF_Healing: Healing(SC, S); break; case spells.EFF_MagicMap: MagicMap(SC, S); break; case spells.EFF_StatAttack: StatAttack(SC, S); break; case spells.EFF_CureStatus: CureStatus(SC, S); break; case spells.EFF_Teleport: Teleport(SC, S); break; case spells.EFF_SenseAura: SenseAura(SC, S); break; } }
static int PlayVal_Leakage(gamebook.Scenario SC) { /* Return a Leakage value for the PC, in the range of 0 to 10. */ /* A low value indicates that more of the PC's armor is airtight; */ /* a high value indicates that the PC really ought to invest in */ /* some scuba gear or something. */ int Leak = 0; /* The helmet contributes 5 leakage points, the body 3, the arms and */ /* legs one each. */ if (SC.PC.eqp[dcchars.ES_Head - 1] == null || !dcitems.CCap[SC.PC.eqp[dcchars.ES_Head - 1].icode - 1].atmSealed) { Leak += 5; } if (SC.PC.eqp[dcchars.ES_Body - 1] == null || !dcitems.CArmor[SC.PC.eqp[dcchars.ES_Body - 1].icode - 1].atmSealed) { Leak += 3; } if (SC.PC.eqp[dcchars.ES_Hand - 1] == null || !dcitems.CGlove[SC.PC.eqp[dcchars.ES_Hand - 1].icode - 1].atmSealed) { Leak += 1; } if (SC.PC.eqp[dcchars.ES_Foot - 1] == null || !dcitems.CShoe[SC.PC.eqp[dcchars.ES_Foot - 1].icode - 1].atmSealed) { Leak += 1; } return(Leak); }
static bool CloseAttack(gamebook.Scenario SC, spells.SpellDesc S) { //{This spell zaps something, just like a melee attack.} rpgtext.DCAppendMessage("Direction?"); //{Select a direction. Make sure an appropriate direction was chosen.} int D; bool success = int.TryParse(rpgtext.RPGKey().ToString(), out D); if (!success || D == 5) { return(false); } dccombat.AttackRequest AR = new dccombat.AttackRequest(); AR.HitRoll = S.p1; AR.Damage = S.step; AR.Range = -1; AR.Attacker = SC.PC.m; AR.TX = SC.PC.m.x + texmaps.VecDir[D - 1, 0]; AR.TY = SC.PC.m.y + texmaps.VecDir[D - 1, 1]; AR.DF = gamebook.DF_Mystic; AR.C = S.c; AR.ATT = S.ATT; AR.Desc = S.cdesc; dccombat.ProcessAttack(SC, AR); return(true); }
static int QuickSpell(gamebook.Scenario SC) { //{Locate a spell based on its quicklink char.} rpgtext.DCPointMessage(" which spell? [a-z/A-Z] code, or [*] for menu"); char A = rpgtext.RPGKey(); rpgtext.DCPointMessage(" "); int it = -1; spells.SpellMem S; if (A == '*') { it = ChooseSpell(SC); } else if (char.ToUpper(A) >= 'A' && char.ToUpper(A) <= 'Z') { it = -1; S = SC.PC.spell; while (S != null) { if (S.mnem == A) { it = S.code; } S = S.next; } } return(it); }
static bool Residual(gamebook.Scenario SC, spells.SpellDesc S) { //{Add a residual type to the PC's status list.} plotbase.SetNAtt(ref SC.PC.SF, statusfx.NAG_StatusChange, S.step, S.p1 * 10); //{Just in case this is a FarSight type spell, do an update.} if (S.step == statusfx.SEF_VisionBonus) { SC.gb.POV.range = dcchars.PCVisionRange(SC.PC); texmaps.UpdatePOV(SC.gb.POV, SC.gb); texmaps.ApplyPOV(SC.gb.POV, SC.gb); } ; //{Display message.} if (S.step >= 0) { rpgtext.DCAppendMessage("Done."); } else { rpgtext.DCAppendMessage("You are " + statusfx.NegSFName[Math.Abs(S.step) + 1].ToLower() + "!"); } return(true); }
public static void BrownianMotion(gamebook.Scenario SC) { /*All of the clouds in the FOG section of the scenario are gonna*/ /*drift around lonely as a cloud. Forcewalls are just gonna sit*/ /*where they are.*/ cwords.Cloud C = SC.Fog; while (C != null) { /*Save the location of the next cloud in the list.*/ cwords.Cloud C2 = C.next; if (SC.ComTime >= C.Duration) { /*This cloud has reached the } of its lifespan.*/ gamebook.Excommunicate(SC, C.M); cwords.RemoveCloud(ref SC.Fog, C, SC.gb); } else if (cwords.CloudMan[C.Kind - 1].pass) { /*Clouds which cannot be moved through are forcewalls,*/ /*and stay where they're to. Other clouds drift.*/ /*Do drifting now.*/ if (rpgdice.Random(3) != 1) { texmaps.MoveModel(C.M, SC.gb, C.M.x + rpgdice.Random(2) - rpgdice.Random(2), C.M.y + rpgdice.Random(2) - rpgdice.Random(2)); } } /*Move to the next cloud.*/ C = C2; } }
static bool ShootAttack(gamebook.Scenario SC, spells.SpellDesc S) { //{This spell shoots something, just like a missile attack.} rpgtext.DCAppendMessage("Select Target: "); texmaps.Point TP = looker.SelectPoint(SC, true, true, SC.PC.target); //{Check to make sure a target was selected, and also} //{the the player isn't trying to shoot himself.} if (TP.x == -1) { return(false); } if (TP.x == SC.PC.m.x && TP.y == SC.PC.m.y) { return(false); } dccombat.AttackRequest AR = new dccombat.AttackRequest(); AR.HitRoll = S.p1; AR.Damage = S.step; AR.Range = S.p2; AR.Attacker = SC.PC.m; AR.TX = TP.x; AR.TY = TP.y; AR.DF = gamebook.DF_Mystic; AR.C = S.c; AR.ATT = S.ATT; AR.Desc = S.cdesc; dccombat.ProcessAttack(SC, AR); return(true); }
static void TryToBreed(gamebook.Scenario SC, critters.Critter C) { /* A breeding monster will reproduce if: */ /* - there are less than the max number of monsters on board */ /* - there is a free spot somewhere close to the breeder */ if (critters.NumberOfCritters(SC.CList) < rpgtext.CHART_MaxMonsters) { /* Determine a direction in which to generate the new */ /* monster. The direction can't be "5". */ int D = rpgdice.Random(8) + 1; if (D > 4) { D += 1; } int X = C.M.x + texmaps.VecDir[D - 1, 0]; int Y = C.M.y + texmaps.VecDir[D - 1, 1]; /* Do the checks to make sure this spot is good for adding */ /* a monster. */ if (texmaps.OnTheMap(X, Y) && texmaps.TerrPass[SC.gb.map[X - 1, Y - 1].terr - 1] > 0) { if (!texmodel.ModelPresent(SC.gb.mog, X, Y)) { critters.AddCritter(ref SC.CList, SC.gb, C.crit, X, Y); } } } }
public static int AvoidTrapTarget = 15; /*Avoiding traps is easier for critters.*/ static texmaps.WalkReport WalkCritter(gamebook.Scenario SC, int DX, int DY) { /*Move the monster to wherever it's going. NOTE: C might be*/ /*made null by this static void, if killed by a trap!*/ texmaps.WalkReport it; /*Is there a door in the way? If so, forget movement... Open*/ /*the door instead. If the monster can't open the door, attack*/ /*it and maybe it'll be destroyed.*/ /*Perform the movement.*/ it = texmaps.MoveModel(SC.CAct.M, SC.gb, SC.CAct.M.x + DX, SC.CAct.M.y + DY); if (it.go && !SC.CAct.Spotted) { if (texmaps.TileLOS(SC.gb.POV, SC.CAct.M.x, SC.CAct.M.y) && texmaps.OnTheScreen(SC.gb, SC.CAct.M.x, SC.CAct.M.y)) { gamebook.UpdateMonsterMemory(SC, SC.CAct); } } /*Check for traps here. Robots & Zombies don't set off traps;*/ /*other critter types might.*/ if (it.go && SC.gb.map[SC.CAct.M.x - 1, SC.CAct.M.y - 1].trap != 0 && SC.CAct.M.gfx != 'R' && SC.CAct.M.gfx != '@') { if (rpgdice.RollStep(critters.MonMan[SC.CAct.crit - 1].Sense) < AvoidTrapTarget) { dccombat.SpringTrap(SC, SC.CAct.M.x, SC.CAct.M.y); } } return(it); }
static void CheckForSecretDoors(gamebook.Scenario SC, int Mode) { /*Check the PC's immediate vicinity for secret doors. Reveal*/ /*any that are found. Use Mode == 0 for walking, Mode == 1 for*/ /*searching.*/ for (int X = SC.PC.m.x - 1; X <= SC.PC.m.x + 1; ++X) { for (int Y = SC.PC.m.y - 1; Y <= SC.PC.m.y + 1; ++Y) { if (texmaps.OnTheMap(X, Y) && SC.gb.map[X - 1, Y - 1].terr == texmaps.HiddenServicePanel) { if (rpgdice.RollStep(dcchars.PCDetection(SC.PC)) >= (SpotDoorTarget - Mode * 5)) { /*A door has been detected!*/ rpgtext.DCGameMessage("You have discovered a service panel."); SC.gb.map[X - 1, Y - 1].terr = texmaps.ClosedServicePanel; texmaps.DisplayTile(SC.gb, X, Y); rpgtext.GamePause(); gamebook.DoleExperience(SC, 1); /*A Player who detects a secret door will stop repeated actions.*/ SC.PC.repCount = 0; } } } } }
static void CheckForTraps(gamebook.Scenario SC, int Mode) { /*Check the PC's immediate vicinity for traps. Reveal any*/ /*that are found. Use Mode == 0 for walking, Mode == 1 for*/ /*searching.*/ for (int X = SC.PC.m.x - 1; X <= SC.PC.m.x + 1; ++X) { for (int Y = SC.PC.m.y - 1; Y <= SC.PC.m.y + 1; ++Y) { if (texmaps.OnTheMap(X, Y) && (SC.gb.map[X - 1, Y - 1].trap < 0)) { if (rpgdice.RollStep(dcchars.PCDetection(SC.PC)) >= (SpotTrapTarget - Mode * 10)) { /*A trap has been detected!*/ rpgtext.DCGameMessage(TrapDetectionMsg[rpgdice.Random(TrapDetectionMsg.Length)]); dccombat.RevealTrap(SC, X, Y); rpgtext.GamePause(); /*A Player who detects a trap will stop repeated actions.*/ SC.PC.repCount = 0; gamebook.DoleExperience(SC, 2); } } } } }
static int ChooseSpell(gamebook.Scenario SC) { //{Create a menu from the PC's spell list. Query for a spell.} //{Return whatever spell was chosen, or -1 for Cancel.} string instr = "[SPACE] to cast, [/] to quickmark"; int QMval = -10; rpgtext.DCPointMessage(" which spell?"); int it = QMval; do { //{Display instructions} rpgtext.GameMessage(instr, MX1, DY2, MX2, DY2 + 2, IColor, BColor); //{Create the menu.} rpgmenus.RPGMenu RPM = rpgmenus.CreateRPGMenu(BColor, SColor, IColor, MX1, MY1, MX2, MY2); RPM.dx1 = MX1; RPM.dy1 = DY1; RPM.dx2 = MX2; RPM.dy2 = DY2; rpgmenus.AddRPGMenuKey(RPM, '/', QMval); spells.SpellMem S = SC.PC.spell; while (S != null) { if (S.mnem == ' ') { rpgmenus.AddRPGMenuItem(RPM, spells.SpellMan[S.code - 1].name, S.code, spells.SpellMan[S.code - 1].Desc); } else { rpgmenus.AddRPGMenuItem(RPM, spells.SpellMan[S.code - 1].name + " [" + S.mnem + "]", S.code, spells.SpellMan[S.code - 1].Desc); rpgmenus.AddRPGMenuKey(RPM, S.mnem, S.code); } S = S.next; } rpgmenus.RPMSortAlpha(RPM); //{Make a menu selection.} it = rpgmenus.SelectMenu(RPM, rpgmenus.RPMNoCleanup); //{Check to see if the PC wants to QuickMark a spell.} if (it == QMval) { SetQuickLink(SC, rpgmenus.RPMLocateByPosition(RPM, RPM.selectItem).value); } }while (it == QMval); //{Redisplay the map.} texmaps.DisplayMap(SC.gb); rpgtext.DCPointMessage(" "); return(it); }
public static int StepOnBlood = 0; /*How many bloody tiles the PC has walked on.*/ /*This constant is used to prevent boring the*/ /*PC by printing the same message over and over again.*/ static void CheckMonsterMemory(gamebook.Scenario SC) { /*The player has either moved or otherwise changed the*/ /*field of vision.*/ texmodel.Model M; critters.Critter C; /*Set the boundaries for our search.*/ int X1 = SC.PC.m.x - SC.gb.POV.range; if (X1 < 1) { X1 = 1; } int Y1 = SC.PC.m.y - SC.gb.POV.range; if (Y1 < 1) { Y1 = 1; } int X2 = SC.PC.m.x + SC.gb.POV.range; if (X2 > texmodel.XMax) { X2 = texmodel.XMax; } int Y2 = SC.PC.m.y + SC.gb.POV.range; if (Y2 > texmodel.YMax) { Y2 = texmodel.YMax; } for (int X = X1; X <= X2; ++X) { for (int Y = Y1; Y <= Y2; ++Y) { /*First, check that the square is visible, there's a model present and that it's on the screen.*/ if (texmaps.TileLOS(SC.gb.POV, X, Y) && texmodel.ModelPresent(SC.gb.mog, X, Y) && texmaps.OnTheScreen(SC.gb, X, Y)) { M = texmodel.FindModelXY(SC.gb.mlist, X, Y); if (M.kind == critters.MKIND_Critter) { C = critters.LocateCritter(M, SC.CList); if (C.Target == SC.PC.m) { SC.PC.repCount = 0; } if (!C.Spotted) { /*Seeing an unknown creature will cause the PC to stop repeditive actions.*/ SC.PC.repCount = 0; gamebook.UpdateMonsterMemory(SC, C); } } } } } }