static void StashItem(dcchars.DCChar PC, dcitems.DCItem it) { //{ The new PC has been given an item. Decide where to stick it, } //{ and provide whatever accessories it has coming. } if (it.ikind == dcitems.IKIND_Gun) { //{The weapon starts out fully loaded.} it.charge = dcitems.CGuns[it.icode - 1].magazine; //{Give the player some ammo for the gun.} dcitems.DCItem I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Ammo; I.icode = dcitems.CGuns[it.icode - 1].caliber; //{Decide how many bullets to dole out.} if (dcitems.CGuns[it.icode - 1].caliber >= dcitems.CAL_Energy) { //{Energy, napalm, and other special ammo weapons} //{don't get as many reloads.} I.charge = 3 + rpgdice.Random(6); } else if (it.icode == 9 || it.icode == 14) { //{ Ammo for a shotgun. } I.charge = dcitems.CGuns[it.icode - 1].magazine * 2 + rpgdice.Random(10); } else { I.charge = dcitems.CGuns[it.icode - 1].magazine; if (I.charge < 10) { I.charge = 10; } I.charge = (I.charge * 3) + rpgdice.Random(20); } dcitems.MergeDCItem(ref PC.inv, I); //{ For shotguns, include some scatter ammunition. } if (it.icode == 9 || it.icode == 14) { I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Ammo; I.icode = 100 + dcitems.CGuns[it.icode - 1].caliber; I.charge = dcitems.CGuns[it.icode - 1].magazine + rpgdice.Random(10); dcitems.MergeDCItem(ref PC.inv, I); } } //{ If equippable, equip the item. Otherwise, stash it. } if (it.ikind > 0 && PC.eqp[it.ikind - 1] == null) { PC.eqp[it.ikind - 1] = it; } else { dcitems.MergeDCItem(ref PC.inv, it); } }
static void GiveKatana(dcchars.DCChar PC) { //{ All Samurai start the game with a Katana. } dcitems.DCItem I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Wep; I.icode = 5; StashItem(PC, I); }
static void IntroStory(dcchars.DCChar PC) { //{Create an introductory story for the PC.} //{Display it in a special message window.} string Or1 = "You are from "; string Or2 = ", "; string Or3 = "."; string Ar2 = "Oddly, the station gave no response to your docking request. You pull into an open shuttle bay and prepare to disembark."; const int X1 = 15; const int Y1 = 5; const int X2 = 65; const int Y2 = 20; //{Set up the screen.} Crt.ClrScr(); rpgtext.LovelyBox(Crt.Color.LightBlue, X1, Y1, X2, Y2); Crt.Window(X1 + 1, Y1 + 1, X2 - 1, Y2 - 1); Crt.TextColor(Crt.Color.Green); //{Generate the PC's origin.} PC.bgOrigin = Or1 + RandomWorld() + Or2 + RandomWDesc() + Or3; //{Generate the PC's history.} //{Generate the PC's reason for arriving at DeadCold.} PC.bgArrival = RandomArrival(PC); //{Generate an introduction to the station.} //{Print the information.} rpgtext.Delineate(PC.bgOrigin, X2 - X1 - 1, 1); if (Crt.WhereX() != 1) { Crt.Write('\n'); } Crt.Write('\n'); rpgtext.Delineate(PC.bgArrival, X2 - X1 - 1, 1); if (Crt.WhereX() != 1) { Crt.Write('\n'); } Crt.Write('\n'); rpgtext.Delineate(Ar2, X2 - X1 - 1, 1); rpgtext.RPGKey(); Crt.Window(1, 1, WDM.CON_WIDTH, WDM.CON_HEIGHT); Crt.ClrScr(); }
static bool PCCanAct(dcchars.DCChar PC) { /*Return TRUE if the PC is capable of acting*/ /*right now, FALSE if it is for any reason incapacitated.*/ if (plotbase.NAttValue(PC.SF, statusfx.NAG_StatusChange, statusfx.SEF_Paralysis) != 0) { return(false); } else if (plotbase.NAttValue(PC.SF, statusfx.NAG_StatusChange, statusfx.SEF_Sleep) != 0) { return(false); } return(true); }
static void GiveBasicStuff(dcchars.DCChar PC) { //{ All PCs start with a few free items. } //{ 3 Trauma Fixes, 3 Antidotes. } dcitems.DCItem I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Food; I.icode = 25; I.charge = 3; StashItem(PC, I); I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Food; I.icode = 30; I.charge = 3; StashItem(PC, I); }
static void PickItemFromChart(dcchars.DCChar PC, int Chart, ref int pts) { //{ Select an item from one of the starting equipment charts, } //{ stash it in the PC's inventory, then decrement PTS by an } //{ appropriate amount. } //{ Decide what item from the chart to generate. } int N = rpgdice.Random(10); //{ Actually create the item record. } dcitems.DCItem I = new dcitems.DCItem(); I.ikind = ItemChart[Chart - 1, N, 0]; I.icode = ItemChart[Chart - 1, N, 1]; pts -= ItemChart[Chart - 1, N, 2]; //{ Stick the item in the PC's inventory. } StashItem(PC, I); }
static void RollGHStats(dcchars.DCChar PC, int Pts) { //{ Randomly allocate PTS points to all of the character's } //{ stats using the same basic method as in my other game, GearHead. } //{ *** NOTE: IF THE CHAR ALREADY HAD STAT VALUES SET, THESE WILL BE LOST *** } //{ Error Check - Is this a character!? } if (PC == null) { return; } int t; //{ Set all stat values to minimum. } for (t = 0; t < 8; ++t) { PC.stat[t] = 1; } Pts -= 8; //{ Keep processing until we run out of stat points to allocate. } while (Pts > 0) { //{ T will now point to the stat slot to improve. } t = rpgdice.Random(8); //{ If the stat selected is under the max value, } //{ improve it. If it is at or above the max value, } //{ there's a one in three chance of improving it. } if (PC.stat[t] < 15) { PC.stat[t] += 1; Pts -= 1; } else if (rpgdice.Random(2) == 1) { PC.stat[t] += 1; Pts -= 1; } } }
//{This unit holds the character generator. That's it.} //{Originally, I had that procedure placed in dcchars,} //{but it was pretty big, so I decided to make a spinoff} //{unit just for it.} public static void SelectPCSpells(dcchars.DCChar PC) { //{The PC has just gone up a level. Choose some spells from} //{the appropriate list. const string msg = "You can learn new psi powers"; const Crt.Color BColor = Crt.Color.LightGray; const Crt.Color IColor = Crt.Color.LightMagenta; const Crt.Color SColor = Crt.Color.Magenta; const int MX1 = 16; const int MY1 = 6; const int MX2 = 65; const int MY2 = 18; const int DY1 = 18; const int DY2 = 22; rpgmenus.RPGMenu RPM; //{Set up the screen.} rpgtext.GameMessage(msg, MX1, MY1 - 2, MX2, MY1, SColor, BColor); //{Determine the PC's spell college. If none, pick one at} //{random, just for the hey of it.} int CoP = dcchars.JobSchool[PC.job - 1]; if (CoP == 0) { CoP = rpgdice.Random(1, spells.NumSchool + 1); } //{Keep selecting spells for as long as the PC needs to.} while (PC.skill[dcchars.SKILL_LearnSpell] > 0) { //{Create the spell menu.} RPM = rpgmenus.CreateRPGMenu(BColor, SColor, IColor, MX1, MY1, MX2, MY2); RPM.dx1 = MX1; RPM.dy1 = DY1; RPM.dx2 = MX2; RPM.dy2 = DY2; //{Add an item for each unlearned spell in the PC's} //{school. First, loop through all the spells up to} //{the PC's competency, which is (lvl + 1) div 2.} int Max = (PC.lvl + 1) / 2; if (Max > spells.NumLevel) { Max = spells.NumLevel; } for (int l = 1; l <= Max; ++l) { for (int t = 1; t <= 5; ++t) { //{Does the PC already know this spell?} if (spells.SpellCollege[CoP - 1, l - 1, t - 1] != 0 && spells.LocateSpellMem(PC.spell, spells.SpellCollege[CoP - 1, l - 1, t - 1]) == null) { //{Add a menu item for this spell.} rpgmenus.AddRPGMenuItem(RPM, spells.SpellMan[spells.SpellCollege[CoP - 1, l - 1, t - 1] - 1].name, spells.SpellCollege[CoP - 1, l - 1, t - 1], spells.SpellMan[spells.SpellCollege[CoP - 1, l - 1, t - 1] - 1].Desc); } } } //{If the menu is empty, leave immediately.} if (RPM.numItem == 0) { return; } //{Sort the menu.} rpgmenus.RPMSortAlpha(RPM); //{Select a spell from the menu. No canceling allowed!} int S = rpgmenus.SelectMenu(RPM, rpgmenus.RPMNoCancel); //{Add the selected spell to the PC's list.} spells.AddSpellMem(ref PC.spell, S); //{Decrement the PC's LearnSpell number.} PC.skill[dcchars.SKILL_LearnSpell] -= 1; } }
static string RandomArrival(dcchars.DCChar PC) { //{Print a story explaining how the character arrived at Dead Cold.} //{There are three possible paths- the PC could have responded to} //{the station's defense call, the PC could have happened here by} //{accident, or the PC could have come here willingly.} string it = ""; //{Decide which of the three paths the PC will take.} int P = rpgdice.Random(3); if (P == 0) { //{Distress call} it = "While travelling to " + RandomWorld() + ", your ship recieved a distress call from space station Dead Cold."; if (PC.job == 4 || PC.job == 9) { if (rpgdice.Random(3) == 1) { it += Pir; } else { it += DCall; } } else if (PC.job == 2 || PC.job == 5) { if (rpgdice.Random(3) == 1) { it += Mys; } else { it += DCall; } } else { if (rpgdice.Random(20) == 7) { it += Mys; } else if (rpgdice.Random(20) == 13) { it += Pir; } else { it += DCall; } } } else if (P == 1) { //{Accidental arrival} it = "While travelling to " + RandomWorld() + ", your ship "; if (rpgdice.Random(2) == 1) { //{Attacked!} it += "was attacked by " + Att[rpgdice.Random(NumAtt)] + " and seriously damaged."; } else if (rpgdice.Random(2) == 1) { //{Meteor!} it += "was hit by a meteor."; } else { //{Out of gas!} it += "started to leak fuel."; } it += Harbor; } else { //{Purposeful arrival} it = "You have come to Dead Cold bearing " + Car[rpgdice.Random(NumCar)]; } return(it); }
static void DoleEquipment(dcchars.DCChar PC) { //{ Give out starting equipment to the PC based on job and luck. } // { First, determine how many points the character will get } //{ for generation. } int Pts = 25 + rpgdice.Random(PC.stat[dcchars.STAT_Luck]); //{ Generate the needed equipment - primary weapon, clothes, } //{ and shoes. } //{ If the character is a Samurai, give him his Katana now. } if (PC.job == 7) { Pts = Pts - 12; GiveKatana(PC); } //{ All characters get some free stuff. Add that now. } GiveBasicStuff(PC); //{ Primary Weapon - decide which chart to use. } int N = rpgdice.Random(10); PickItemFromChart(PC, PrimaryGear[PC.job - 1, N], ref Pts); //{ Clothes and Shoes } PickItemFromChart(PC, ArmorChart[PC.job - 1], ref Pts); PickItemFromChart(PC, ShoeChart[PC.job - 1], ref Pts); //{ If there are points left over, give secondary equipment. } if (Pts > 0) { N = rpgdice.Random(10); PickItemFromChart(PC, SecondaryGear[PC.job - 1, N], ref Pts); } //{ Roll to see if this character gets gloves or a hat. } if (Pts > 0 && rpgdice.Random(100) < HatsChance[PC.job - 1]) { PickItemFromChart(PC, HatsChart[PC.job - 1], ref Pts); } if (Pts > 0 && rpgdice.Random(100) < GloveChance[PC.job - 1]) { PickItemFromChart(PC, GloveChart[PC.job - 1], ref Pts); } //{ Spend the remaining points on tertiary equipment. } while (Pts > 0) { //{ Extra equipment has a 50% chance of coming from the } //{ job-specific chart and a 50% chance of coming from } //{ the general items chart. } if (rpgdice.Random(2) == 1) { N = rpgdice.Random(10); PickItemFromChart(PC, ExtraGear[PC.job, N], ref Pts); } else { N = rpgdice.Random(10); PickItemFromChart(PC, ExtraGear[0, N], ref Pts); } } }
public static dcchars.DCChar RollNewChar() { //{We're going to generate a new game character from scratch.} //{Return NIL if the character creation process was cancelled.} const string instructions = "Select one of the avaliable jobs from the menu. Press ESC to reroll stats, or select Cancel to exit."; //var // pc: dccharptr; // opt: rpgmenuptr; {The menu holding avaliable jobs.} // t,tt: Integer; {Loop counters} // q: boolean; {Apparently, for this procedure, I've forgotten about useful variable names. It's hot and I'm tired.} // I: DCItemPtr; int t, tt; //{Allocate memory for the character.} dcchars.DCChar PC = new dcchars.DCChar(); //{Initilize Job to -1} PC.job = -1; //{Clear the screen} Crt.ClrScr(); //{Display the stat names} Crt.TextColor(Crt.Color.Cyan); for (t = 1; t <= 8; ++t) { Crt.GotoXY(12, t * 2 + 3); Crt.Write(dcchars.StatName[t - 1] + " :"); } //{Start a loop. We'll stay in the loop until a character is selected.} while (PC.job == -1) { //{Give a short message on how to use the character generator} rpgtext.GameMessage(instructions, 2, 1, 79, 4, Crt.Color.Green, Crt.Color.LightBlue); //{Set the text color} Crt.TextColor(Crt.Color.White); //{Roll the character's stats.} RollGHStats(PC, 100 + rpgdice.Random(20)); for (t = 1; t <= 8; ++t) { //{display the stat onscreen.} Crt.GotoXY(35, t * 2 + 3); Crt.Write(" "); Crt.GotoXY(35, t * 2 + 3); Crt.Write(PC.stat[t - 1].ToString()); } //{determine which jobs are open to this character, and} //{add them to our RPGMenu.} //{First, allocate the menu.} rpgmenus.RPGMenu opt = rpgmenus.CreateRPGMenu(Crt.Color.LightBlue, Crt.Color.Blue, Crt.Color.LightCyan, 46, 7, 65, 17); //{Initialize the description elements.} opt.dx1 = 2; opt.dx2 = 79; opt.dy1 = 20; opt.dy2 = 24; opt.dTexColor = Crt.Color.Green; for (t = 1; t <= dcchars.NumJobs; ++t) { //{Initialize q to true} bool q = true; //{Check each stat} for (tt = 1; tt <= 8; ++tt) { if (PC.stat[tt - 1] < dcchars.JobStat[t - 1, tt - 1]) { q = false; } } //{If q is still true, this job may be chosen.} if (q) { rpgmenus.AddRPGMenuItem(opt, dcchars.JobName[t - 1], t, dcchars.JobDesc[t - 1]); } } //{Get the jobs in alphabetical order} rpgmenus.RPMSortAlpha(opt); //{Add a CANCEL to the list} rpgmenus.AddRPGMenuItem(opt, " Cancel", 0, null); //{Ask for a selection} PC.job = rpgmenus.SelectMenu(opt, rpgmenus.RPMNoCleanup); PC.m = null; } //{If the player selected cancel, dispose of the PC record.} if (PC.job == 0) { PC = null; } else { //{Copy skill ranks} for (t = 1; t <= dcchars.NumSkill; t++) { PC.skill[t - 1] = dcchars.JobSkill[PC.job - 1, t - 1]; } //{Set HP, HPMax, and other initial values.} PC.HPMax = PC.stat[dcchars.STAT_Toughness] + dcchars.JobHitDie[PC.job - 1] + dcchars.BaseHP; PC.HP = PC.HPMax; PC.MPMax = PC.stat[dcchars.STAT_Willpower] / 2 + dcchars.JobMojoDie[PC.job - 1] + rpgdice.Random(dcchars.JobMojoDie[PC.job - 1]); PC.MP = PC.MPMax; PC.target = null; PC.carbs = 50; PC.lvl = 1; PC.XP = 0; PC.repCount = 0; PC.inv = null; for (t = 1; t <= dcchars.NumEquipSlots; ++t) { PC.eqp[t - 1] = null; } PC.SF = null; PC.spell = null; //{Give some basic equipment.} DoleEquipment(PC); //{Add the PC's meals.} for (t = 1; t <= 5; ++t) { dcitems.DCItem I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Food; I.icode = JobXFood[PC.job, rpgdice.Random(10)]; I.charge = 1; dcitems.MergeDCItem(ref PC.inv, I); } //{Add the PC's snacks.} int total = rpgdice.Random(5) + 1; for (t = 1; t <= total; ++t) { dcitems.DCItem I = new dcitems.DCItem(); I.ikind = dcitems.IKIND_Food; //{Decide upon what kind of food to give, based on job.} if (rpgdice.Random(3) == 2) { I.icode = JobXFood[0, rpgdice.Random(10)]; } else { I.icode = JobXFood[PC.job, rpgdice.Random(10)]; } I.charge = rpgdice.Random(3) + 1; dcitems.MergeDCItem(ref PC.inv, I); } //{ Input a name. } rpgtext.GameMessage("NAME: ", 2, 1, 79, 4, Crt.Color.LightGreen, Crt.Color.LightBlue); Crt.GotoXY(9, 2); Crt.CursorOn(); PC.name = rpgtext.ReadLine(); Crt.CursorOff(); if (PC.name != "") { //{ Generate an introduction. } IntroStory(PC); //{Add spells, if appropriate.} if (PC.skill[dcchars.SKILL_LearnSpell] > 0) { SelectPCSpells(PC); } } else { PC = null; } } return(PC); }