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 MoveMapCursor(texmaps.GameBoard gb, int D, ref texmaps.Point p) { //{Move the map cursor point. This can be used for the Select} //{Target routine, or for the PCLook routine. In any case,} //{the big point is to make sure that the point doesn't go off} //{the screen.} if (texmaps.OnTheScreen(gb, p.x + texmaps.VecDir[D - 1, 0], p.y + texmaps.VecDir[D - 1, 1])) { p.x += texmaps.VecDir[D - 1, 0]; p.y += texmaps.VecDir[D - 1, 1]; } }
public static bool PCTosser(gamebook.Scenario SC) { /*The PC wants to throw a grenade.*/ /*The majority of this unit was simply copied from above.*/ /*Select a grenade to toss.*/ dcitems.DCItem Grn = backpack.PromptItem(SC, dcitems.IKIND_Grenade); if (Grn == null) { return(false); } /*Start the standard firing stuff.*/ rpgtext.DCGameMessage("Throw grenade - 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); } /*Check to make sure the target point is within the PC's*/ /*maximum throwing range.*/ if (texmaps.Range(SC.PC.m, TP.x, TP.y) > dcchars.PCThrowRange(SC.PC)) { rpgtext.DCPointMessage("Out of range!"); return(false); } dccombat.AttackRequest AR = new dccombat.AttackRequest(); AR.HitRoll = dcchars.PCThrowSkill(SC.PC); AR.Damage = dcitems.CGrn[Grn.icode - 1].DMG; AR.Range = dcitems.CGrn[Grn.icode - 1].DMG; AR.Attacker = SC.PC.m; AR.TX = TP.x; AR.TY = TP.y; AR.DF = gamebook.DF_Physical; AR.C = Crt.Color.Yellow; AR.ATT = dcitems.CGrn[Grn.icode].ATT; if (AR.ATT.Contains(spells.AA_LineAttack) || AR.ATT.Contains(spells.AA_BlastAttack) || AR.ATT.Contains(spells.AA_SmokeAttack)) { AR.Desc = "throw " + dcitems.ItemNameShort(Grn); } else { AR.Desc = "throw " + dcitems.ItemNameShort(Grn) + " at"; } dccombat.AttackReport Rep = dccombat.ProcessAttack(SC, AR); /*Consume the grenade.*/ dcitems.ConsumeDCItem(ref SC.PC.inv, Grn, 1); return(true); }
public static bool PCShooting(gamebook.Scenario SC, bool SeekModel) { /*The player wants to shoot something. Select a target and*/ /*let fly!*/ /*Error check- make sure the PC has a missile weapon equipped!*/ if (SC.PC.eqp[dcchars.ES_MissileWeapon - 1] == null) { rpgtext.DCGameMessage("No missile weapon equipped!"); return(false); } else if (SC.PC.eqp[dcchars.ES_MissileWeapon - 1].charge == 0) { rpgtext.DCGameMessage("Out of ammo!"); return(false); } rpgtext.DCGameMessage("Targeting - Select Target: "); texmaps.Point TP = looker.SelectPoint(SC, true, SeekModel, 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 = dcchars.PCMissileSkill(SC.PC); AR.Damage = dcchars.PCMissileDamage(SC.PC); AR.Range = dcchars.PCMissileRange(SC.PC); AR.Attacker = SC.PC.m; AR.TX = TP.x; AR.TY = TP.y; AR.DF = gamebook.DF_Physical; AR.C = Crt.Color.LightRed; if (SC.PC.eqp[dcchars.ES_MissileWeapon - 1].state != 0) { /*If special ammunition is being used, add its attack attributes to the string.*/ AR.Damage = AR.Damage + dcitems.CSpecAmmo[Math.Abs(SC.PC.eqp[dcchars.ES_MissileWeapon - 1].state) - 1].DMG; if (AR.Damage < 1) { AR.Damage = 1; } AR.HitRoll = AR.HitRoll + dcitems.CSpecAmmo[Math.Abs(SC.PC.eqp[dcchars.ES_MissileWeapon - 1].state) - 1].ACC; if (AR.HitRoll < 1) { AR.HitRoll = 1; } AR.ATT = dcitems.CSpecAmmo[Math.Abs(SC.PC.eqp[dcchars.ES_MissileWeapon - 1].state) - 1].ATT + dcitems.CGuns[SC.PC.eqp[dcchars.ES_MissileWeapon - 1].icode - 1].ATT; } else { AR.ATT = dcitems.CGuns[SC.PC.eqp[dcchars.ES_MissileWeapon - 1].icode - 1].ATT; } if (AR.ATT.Contains(spells.AA_LineAttack) || AR.ATT.Contains(spells.AA_BlastAttack) || AR.ATT.Contains(spells.AA_SmokeAttack)) { AR.Desc = "fire " + dcitems.ItemNameShort(SC.PC.eqp[dcchars.ES_MissileWeapon - 1]); } else { AR.Desc = "fire " + dcitems.ItemNameShort(SC.PC.eqp[dcchars.ES_MissileWeapon - 1]) + " at"; } dccombat.AttackReport Rep = dccombat.ProcessAttack(SC, AR); /*Reduce the weapon's AMMO count, unless using infinite shot weapon.*/ if (SC.PC.eqp[dcchars.ES_MissileWeapon - 1].charge > -1) { SC.PC.eqp[dcchars.ES_MissileWeapon - 1].charge -= 1; } return(true); }
static AttackReport BlastAttack(gamebook.Scenario SC, AttackRequest AR) { //{This attack is, like, a big explosion or something.} //{Initialize values.} AttackReport Rep = new AttackReport(); Rep.ItHit = false; Rep.Fatal = false; Rep.Damage = 0; Rep.XPV = 0; int BRad = spells.AAVal(AR.ATT, spells.AA_BlastAttack); if (BRad < 0) { BRad = 0; } bool Vis = false; //{Check to see if the shot hit the desired spot} if (AR.Range != 0 && rpgdice.RollStep(AR.HitRoll) > texmaps.Range(AR.Attacker, AR.TX, AR.TY) / AR.Range + BlastBaseTarget) { //{roll for deviation} //{We'll use X for the total range right now.} int X = texmaps.Range(AR.Attacker, AR.TX, AR.TY) / 2; if (X < 2) { X = 2; } AR.TX += rpgdice.Random(X) - rpgdice.Random(X); AR.TY += rpgdice.Random(X) - rpgdice.Random(X); } //{Check to make sure our grenade isn't trying to bounce through a wall.} if (texmaps.CalcObscurement(AR.Attacker, AR.TX, AR.TY, SC.gb) == -1) { texmaps.Point P = texmaps.LocateStop(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY); AR.TX = P.x; AR.TY = P.y; } //{Do the initial message here, if appropriate} if (texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y)) { //{Print message saying what's going on.} if (AR.Attacker.kind == dcchars.MKIND_Character) { rpgtext.DCGameMessage("You " + AR.Desc + "."); } else { rpgtext.DCGameMessage(gamebook.ModelName(SC, AR.Attacker) + AR.Desc + "."); } } //{Display the path of the projectile, if appropriate.} if (texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y) || texmaps.TileLOS(SC.gb.POV, AR.TX, AR.TY)) { texfx.DisplayShot(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY, AR.C, true); } for (int X = AR.TX - BRad; X <= AR.TX + BRad; ++X) { for (int Y = AR.TY - BRad; Y <= AR.TY + BRad; ++Y) { int O = texmaps.CalcObscurement(X, Y, AR.TX, AR.TY, SC.gb); if (O > -1 && O < AR.Damage) { if (texmaps.TileLOS(SC.gb.POV, X, Y)) { //{This square will be affected by the blast.} texmaps.MapSplat(SC.gb, '*', AR.C, X, Y, true); Vis = true; } if (texmodel.ModelPresent(SC.gb.mog, X, Y)) { //{Determine the defense roll of the target.} int DRoll = RollDefenses(SC, AR, X, Y); //{Determine the attack roll of the attacker.} int ARoll = rpgdice.RollStep(AR.HitRoll); //{Determine the target's name. Modify for PC.} string tname = gamebook.ModelName(SC, texmodel.FindModelXY(SC.gb.mlist, X, Y)); if (tname == "you") { tname = "You"; } int Dmg = 0; if (ARoll > DRoll) { //{Hit!} Rep.ItHit = true; Dmg = RollDamage(AR.Damage - O); } else if (ARoll > DRoll / 2) { //{Partial hit! Half damage!} Rep.ItHit = true; Dmg = RollDamage(AR.Damage + 1 - O) / 2; } if (Dmg > 0) { //{Blast Attacks never score critical hits.} bool f = DamageTarget(SC, X, Y, 0, AR, Dmg, ref Rep); Rep.Damage += Dmg; if (f) { Rep.Fatal = true; } if (texmaps.TileLOS(SC.gb.POV, X, Y)) { if (f) { rpgtext.DCAppendMessage(tname + " died!"); } else if (tname == "You") { rpgtext.DCAppendMessage("You are hit!"); } else if (Dmg > 0) { rpgtext.DCAppendMessage(tname + " is hit!"); } else if (Dmg < 0) { rpgtext.DCAppendMessage(tname + " is healed!"); } } } } } } } if (Vis) { texfx.Delay(); //{Restore the display.} for (int X = AR.TX - BRad; X <= AR.TX + BRad; ++X) { for (int Y = AR.TY - BRad; Y <= AR.TY; ++Y) { texmaps.DisplayTile(SC.gb, X, Y); } } } return(Rep); }
static AttackReport LineAttack(gamebook.Scenario SC, AttackRequest AR) { //{The attack being processed is a line attack. It keeps going,} //{affecting every model it touches, until it runs out of range} //{or until it hits a wall.} //{Begin by making sure the Range is an appropriate value.} if (AR.Range < 2) { AR.Range = 2; } //{Initialize values.} AttackReport Rep = new AttackReport(); Rep.ItHit = false; Rep.Fatal = false; Rep.Damage = 0; Rep.XPV = 0; //{Do the initial message here, if appropriate} if (texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y)) { //{Print message saying what's going on.} if (AR.Attacker.kind == dcchars.MKIND_Character) { rpgtext.DCGameMessage("You " + AR.Desc + "."); } else { rpgtext.DCGameMessage(gamebook.ModelName(SC, AR.Attacker) + " " + AR.Desc + "."); } } for (int t = 1; t <= AR.Range; ++t) { //{Calculate the current target square.} texmaps.Point P = texmaps.SolveLine(AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY, t); if (texmodel.ModelPresent(SC.gb.mog, P.x, P.y)) { //{Determine the defense roll of the target.} int DRoll = RollDefenses(SC, AR, P.x, P.y); //{Determine the attack roll of the attacker.} int ARoll = rpgdice.RollStep(AR.HitRoll); //{Determine the target's name. Modify for PC.} string tname = gamebook.ModelName(SC, texmodel.FindModelXY(SC.gb.mlist, P.x, P.y)); if (tname == "you") { tname = "You"; } int Dmg = 0; if (ARoll > DRoll) { //{Hit!} Rep.ItHit = true; Dmg = RollDamage(AR.Damage); texmaps.MapSplat(SC.gb, '*', AR.C, P.x, P.y, false); } else if (ARoll > DRoll / 2) { //{Partial hit! Half damage!} Rep.ItHit = true; Dmg = RollDamage((AR.Damage + 1) / 2); texmaps.MapSplat(SC.gb, '+', AR.C, P.x, P.y, false); } else { //{Complete miss!} Dmg = 0; texmaps.MapSplat(SC.gb, '-', AR.C, P.x, P.y, false); } if (Dmg > 0) { //{Line Attacks never score critical hits.} bool f = DamageTarget(SC, P.x, P.y, 0, AR, Dmg, ref Rep); Rep.Damage += Dmg; if (f) { Rep.Fatal = true; } if (texmaps.TileLOS(SC.gb.POV, P.x, P.y)) { if (f) { rpgtext.DCAppendMessage(tname + " died!"); } else if (tname == "You") { rpgtext.DCAppendMessage("You are hit!"); } else if (Dmg > 0) { rpgtext.DCAppendMessage(tname + " is hit!"); } else if (Dmg < 0) { rpgtext.DCAppendMessage(tname + " is healed!"); } } } } else { //{ There's no model here. Just do the gfx.} texmaps.MapSplat(SC.gb, '+', AR.C, P.x, P.y, false); } //{ If visible, do an animation delay. if (texmaps.TileLOS(SC.gb.POV, P.x, P.y)) { texfx.DelayDiv(2); } //{If there's a wall here, break the loop.} if (texmaps.TerrPass[texmaps.GetTerr(SC.gb, P.x, P.y) - 1] < 1) { break; } } //{Clean up the display.} for (int t = 1; t <= AR.Range; ++t) { //{Calculate the current target square.} texmaps.Point P = texmaps.SolveLine(AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY, t); texmaps.DisplayTile(SC.gb, P.x, P.y); } return(Rep); }
static AttackReport DirectFire(gamebook.Scenario SC, AttackRequest AR) { //{The attack being invoked is a regular, old fashioned,} //{direct fire attack.} int O = 0; //{Do some checking for missile attacks.} if (AR.Range > -1) { //{Determine obscurement. If the target can't be seen,} //{switch TX,TY to whatever obstacle is in the way.} O = texmaps.CalcObscurement(AR.Attacker, AR.TX, AR.TY, SC.gb); if (O == -1) { texmaps.Point P = texmaps.LocateBlock(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY); AR.TX = P.x; AR.TY = P.y; O = texmaps.CalcObscurement(AR.Attacker, AR.TX, AR.TY, SC.gb); } //{Calculate range modifier.} if (AR.Range > 0) { O += texmaps.Range(AR.Attacker, AR.TX, AR.TY) / AR.Range; } else { O += texmaps.Range(AR.Attacker, AR.TX, AR.TY); } } else { //{It's a melee attack. No obscurement.} O = 0; } //{Determine the visibility status of the attacker and target.} bool AVis = texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y); bool TVis = texmaps.TileLOS(SC.gb.POV, AR.TX, AR.TY); //{Initialize Attack Report} AttackReport Rep = new AttackReport(); Rep.Fatal = false; Rep.XPV = 0; string msg = ""; string tname = ""; if (SC.gb.mog.IsSet(AR.TX, AR.TY)) { tname = gamebook.ModelName(SC, texmodel.FindModelXY(SC.gb.mlist, AR.TX, AR.TY)); } else { tname = texmaps.TerrName[SC.gb.map[AR.TX - 1, AR.TY - 1].terr - 1]; } //{Announce the attack.} if (AVis || TVis) { if (AVis) { msg = gamebook.ModelName(SC, AR.Attacker); } else { msg = "Something"; } if (AR.Desc != "" && rpgdice.Random(3) == 1) { if (AR.Attacker.kind == dcchars.MKIND_Character) { msg = "You " + AR.Desc + " "; } else { msg += " " + AR.Desc + " "; } } else { if (AR.Attacker.kind == dcchars.MKIND_Character) { msg = "You attack "; } else { msg += " attacks "; } } if (TVis) { msg += tname; } else { msg += "something"; } } //{Determine the defense roll of the target.} int DefRoll = RollDefenses(SC, AR, AR.TX, AR.TY); //{Determine the attack roll of the attacker.} int ARoll = rpgdice.RollStep(AR.HitRoll) - O; //{Add punctuation to our message string, then print.} if (msg.Length > 0) { if (rpgdice.Random(8) == 5) { msg += "... "; } else if (ARoll > 50) { msg += "!!! "; } else if (ARoll > 25) { msg += "! "; } else if (ARoll > 5) { msg += ". "; } else { if (rpgdice.Random(5) == 1) { msg += "? "; } else { msg += ", sort of... "; } } } int MOS = 0; if (ARoll > DefRoll) { //{The attack hit! Do whatever needs to be done...} //{Determine Margin of Success} if (DefRoll > 0) { MOS = ARoll / DefRoll - 1; } else { MOS = ARoll / 10; } //{There's a maximum value for MOS, based on magnitude of the roll.} if (ARoll < 15) { MOS = 0; } else if (MOS > (ARoll - 10) / 5) { MOS = (ARoll - 10) / 5; } //{Determine Damage Bonus} int DBonus = rpgdice.Random(MOS + 1); MOS -= DBonus; if (MOS > 4) { DBonus += MOS - 4; MOS = 4; } Rep.ItHit = true; Rep.Damage = RollDamage(AR.Damage + (DBonus * 3)); if (msg.Length > 0) { msg += "The attack hit!"; } } else { //{ The attack missed!Again, do whatever needs to be done...} Rep.ItHit = false; if (rpgdice.Random(3) == 2 && TVis) { msg += tname + " dodged the attack."; } else if (msg.Length > 0) { msg += "The attack missed."; } } if (msg.Length > 0) { rpgtext.DCGameMessage(msg); msg = ""; } if (TVis || AVis) { texfx.DisplayShot(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY, AR.C, Rep.ItHit); } //{Damage the target now, after the shot has been displayed.} if (Rep.ItHit) { Rep.Fatal = DamageTarget(SC, AR.TX, AR.TY, MOS, AR, Rep.Damage, ref Rep); if (TVis && Rep.Damage > 0) { msg += Rep.Damage.ToString() + " damage!"; } else if (TVis && Rep.Damage < 0) { msg += Math.Abs(Rep.Damage).ToString() + " HP restored!"; } else if (TVis && Rep.Damage == 0) { msg += " No damage!"; } } if (Rep.Fatal && TVis) { msg += " " + tname + " died!"; } if (msg.Length > 0) { rpgtext.DCAppendMessage(msg); } return(Rep); }
static AttackReport SmokeAttack(gamebook.Scenario SC, AttackRequest AR) { //{This attack will just cause lots of smoke.} // Rep: AttackReport; //SKind,BRad,Dur: int; {Smoke Kind, Blast Radius, Duration} //X,Y: int; //P: Point; //{Initialize values.} AttackReport Rep = new AttackReport(); Rep.ItHit = true; Rep.Fatal = false; Rep.Damage = 0; Rep.XPV = 0; int SKind = spells.AAVal(AR.ATT, spells.AA_SmokeAttack); int BRad = spells.AAVal(AR.ATT, spells.AA_Value); int Dur = spells.AAVal(AR.ATT, spells.AA_Duration); if (Dur < 1) { Dur = 1; } //{Check to see if the shot hit the desired spot} if (AR.Range != 0 && rpgdice.RollStep(AR.HitRoll) > texmaps.Range(AR.Attacker, AR.TX, AR.TY) / AR.Range + BlastBaseTarget) { //{roll for deviation} //{We'll use X for the total range right now.} int X = texmaps.Range(AR.Attacker, AR.TX, AR.TY) / 2; if (X < 2) { X = 2; } AR.TX += rpgdice.Random(X) - rpgdice.Random(X); AR.TY += rpgdice.Random(X) - rpgdice.Random(X); Rep.ItHit = false; } //{Check to make sure our grenade isn't trying to bounce through a wall.} if (texmaps.CalcObscurement(AR.Attacker, AR.TX, AR.TY, SC.gb) == -1) { texmaps.Point P = texmaps.LocateStop(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY); AR.TX = P.x; AR.TY = P.y; } //{Do the initial message here, if appropriate} if (texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y)) { //{Print message saying what's going on.} if (AR.Attacker.kind == dcchars.MKIND_Character) { rpgtext.DCGameMessage("You " + AR.Desc + "."); } else { rpgtext.DCGameMessage(gamebook.ModelName(SC, AR.Attacker) + AR.Desc + "."); } } //{Display the path of the projectile, if appropriate.} if (texmaps.TileLOS(SC.gb.POV, AR.Attacker.x, AR.Attacker.y) || texmaps.TileLOS(SC.gb.POV, AR.TX, AR.TY)) { texfx.DisplayShot(SC.gb, AR.Attacker.x, AR.Attacker.y, AR.TX, AR.TY, AR.C, true); } //{Go through every point in the blast radius. If appropriate, add} //{a cloud to each one.} for (int X = AR.TX - BRad; X <= AR.TX + BRad; ++X) { for (int Y = AR.TY - BRad; Y <= AR.TY + BRad; ++Y) { if (texmaps.CalcObscurement(X, Y, AR.TX, AR.TY, SC.gb) > -1 && texmaps.TerrPass[texmaps.GetTerr(SC.gb, X, Y) - 1] > 0) { cwords.AddCloud(ref SC.Fog, SC.gb, SKind, X, Y, SC.ComTime + (Dur * 12) + rpgdice.RollStep(6)); } } } //{Return the attack report, for what it's worth.} return(Rep); }
//{What is this? It's the unit which supports the 'Look'} //{command. Basically, it provides a UI for the user to select} //{a map tile which is currently on-screen.} public static texmaps.Point SelectPoint(gamebook.Scenario SC, bool Render, bool SeekModel, texmodel.Model M) { //{This function is a UI utility. It allows a target} //{square to be chosen, centered on the POV model.} //{If CANCEL is chosen instead of a target, the X value} //{of the returned point will be set to -1.} if (SeekModel) { if (M == null) { M = NextVisibleModel(SC.gb, M); } else if (!texmaps.TileLOS(SC.gb.POV, M.x, M.y) || !texmaps.OnTheScreen(SC.gb, M.x, M.y)) { M = NextVisibleModel(SC.gb, M); } } texmaps.Point p = new texmaps.Point(); if (M != null) { //{Start the point selector centered on the selected model.} p.x = M.x; p.y = M.y; } else { //{Start the point centered on the POV origin.} p.x = SC.gb.POV.m.x; p.y = SC.gb.POV.m.y; } //{Start the loop.} char A = ' '; do { //{Indicate the point.} if (Render) { texfx.IndicatePath(SC.gb, SC.gb.POV.m.x, SC.gb.POV.m.y, p.x, p.y, true); } else { texmaps.HighlightTile(SC.gb, p.x, p.y); } rpgtext.DCPointMessage(gamebook.TileName(SC, p.x, p.y)); //{Get player input and act upon it.} A = rpgtext.RPGKey(); //{Deindicate the point.} if (Render) { texfx.DeIndicatePath(SC.gb, SC.gb.POV.m.x, SC.gb.POV.m.y, p.x, p.y); } else { texmaps.DisplayTile(SC.gb, p.x, p.y); } if (A == rpgtext.KMap[1].key) { MoveMapCursor(SC.gb, 1, ref p); } else if (A == rpgtext.KMap[2].key) { MoveMapCursor(SC.gb, 2, ref p); } else if (A == rpgtext.KMap[3].key) { MoveMapCursor(SC.gb, 3, ref p); } else if (A == rpgtext.KMap[4].key) { MoveMapCursor(SC.gb, 4, ref p); } else if (A == rpgtext.KMap[6].key) { MoveMapCursor(SC.gb, 6, ref p); } else if (A == rpgtext.KMap[7].key) { MoveMapCursor(SC.gb, 7, ref p); } else if (A == rpgtext.KMap[8].key) { MoveMapCursor(SC.gb, 8, ref p); } else if (A == rpgtext.KMap[9].key) { MoveMapCursor(SC.gb, 9, ref p); } else if (A == (char)9) { M = NextVisibleModel(SC.gb, M); if (M != null) { p.x = M.x; p.y = M.y; } } }while (A != ' ' && A != (char)27 && A != rpgtext.KMap[14].key && A != rpgtext.KMap[15].key); if (A == (char)27) { p.x = -1; } return(p); }