Advertisement
Guest User

ccc_inc_misc for nwn/prc

a guest
May 12th, 2015
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 80.53 KB | None | 0 0
  1. #include "ccc_inc_misc"
  2.  
  3. // sets up the header and the choices for each stage of the convoCC
  4. void DoHeaderAndChoices(int nStage);
  5.  
  6. // processes the player choices for each stage of the convoCC
  7. int HandleChoice(int nStage, int nChoice);
  8.  
  9. void DoHeaderAndChoices(int nStage)
  10. {
  11.     string sText;
  12.     string sName;
  13.     int i = 0; // loop counter
  14.     switch(nStage)
  15.     {
  16.         case STAGE_INTRODUCTION: {
  17.             sText = "This is the PRC Conversation Character Creator (CCC).\n";
  18.             sText+= "This is a replicate of the bioware character creator, but it will allow you to select custom content at level 1. ";
  19.             sText+= "Simply follow the step by step instructions and select what you want. ";
  20.             sText+= "If you dont get all the options you think you should at a stage, select one, then select No at the confirmation step.";
  21.             SetHeader(sText);
  22.             // setup the choices
  23.             AddChoice("continue", 0);
  24.             MarkStageSetUp(nStage);
  25.             break;
  26.         }
  27.         case STAGE_GENDER: {
  28.             sText = GetStringByStrRef(158);
  29.             SetHeader(sText);
  30.             // set up the choices
  31.             Do2daLoop("gender", "name", GetPRCSwitch(FILE_END_GENDER));
  32.             MarkStageSetUp(nStage);
  33.             break;
  34.         }
  35.         case STAGE_GENDER_CHECK: {
  36.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  37.             sText+= GetStringByStrRef(StringToInt(Get2DACache("gender", "NAME", GetLocalInt(OBJECT_SELF, "Gender"))));
  38.             sText+= "\n"+GetStringByStrRef(16824210);
  39.             SetHeader(sText);
  40.             // choices Y/N
  41.             AddChoice(GetStringByStrRef(4753), -1); // no
  42.             AddChoice(GetStringByStrRef(4752), 1); // yes
  43.             MarkStageSetUp(nStage);
  44.             break;
  45.         }
  46.         case STAGE_RACE: {
  47.             sText = GetStringByStrRef(162); // Select a Race for your Character
  48.             SetHeader(sText);
  49.             // set up choices
  50.             // try with waiting set up first
  51.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  52.             DelayCommand(0.01, DoRacialtypesLoop());
  53.             MarkStageSetUp(nStage);
  54.             SetDefaultTokens();
  55.             break;
  56.         }
  57.         case STAGE_RACE_CHECK: {
  58.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  59.             sText += GetStringByStrRef(StringToInt(Get2DACache("racialtypes", "Name", GetLocalInt(OBJECT_SELF, "Race"))));
  60.             sText += "\n";
  61.             sText+= GetStringByStrRef(StringToInt(Get2DACache("racialtypes", "Description", GetLocalInt(OBJECT_SELF, "Race"))));
  62.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  63.             SetHeader(sText);
  64.             // choices Y/N
  65.             AddChoice(GetStringByStrRef(4753), -1); // no
  66.             AddChoice(GetStringByStrRef(4752), 1); // yes
  67.             MarkStageSetUp(nStage);
  68.             break;
  69.         }
  70.         case STAGE_CLASS: {
  71.             sText = GetStringByStrRef(61920); // Select a Class for Your Character
  72.             SetHeader(sText);
  73.             // set up choices
  74.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  75.             DelayCommand(0.01, DoClassesLoop());
  76.             MarkStageSetUp(nStage);
  77.             SetDefaultTokens();
  78.             break;
  79.         }
  80.         case STAGE_CLASS_CHECK: {
  81.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  82.             sText += GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", GetLocalInt(OBJECT_SELF, "Class"))));
  83.             sText += "\n";
  84.             sText+= GetStringByStrRef(StringToInt(Get2DACache("classes", "Description", GetLocalInt(OBJECT_SELF, "Class"))));
  85.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  86.             SetHeader(sText);
  87.             // choices Y/N
  88.             AddChoice(GetStringByStrRef(4753), -1); // no
  89.             AddChoice(GetStringByStrRef(4752), 1); // yes
  90.             MarkStageSetUp(nStage);
  91.             break;
  92.         }
  93.         case STAGE_ALIGNMENT: {
  94.             sText = GetStringByStrRef(111); // Select an Alignment for your Character
  95.             SetHeader(sText);
  96.             // get the restriction info from classes.2da
  97.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  98.             int nClass = GetLocalInt(OBJECT_SELF, "Class");
  99.             int iAlignRestrict = HexToInt(Get2DACache("classes", "AlignRestrict",nClass));
  100.             int iAlignRstrctType = HexToInt(Get2DACache("classes", "AlignRstrctType",nClass));
  101.             int iInvertRestrict = HexToInt(Get2DACache("classes", "InvertRestrict",nClass));
  102.             // set up choices
  103.             if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  104.                 AddChoice(GetStringByStrRef(112), 112);
  105.             if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  106.                 AddChoice(GetStringByStrRef(115), 115);
  107.             if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  108.                 AddChoice(GetStringByStrRef(118), 118);
  109.             if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  110.                 AddChoice(GetStringByStrRef(113), 113);
  111.             if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  112.                 AddChoice(GetStringByStrRef(116), 116);
  113.             if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  114.                 AddChoice(GetStringByStrRef(119), 119);
  115.             if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  116.                 AddChoice(GetStringByStrRef(114), 114);
  117.             if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  118.                 AddChoice(GetStringByStrRef(117), 117);
  119.             if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict))
  120.                 AddChoice(GetStringByStrRef(120), 120);
  121.             DelayCommand(0.01, DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting"));
  122.             MarkStageSetUp(nStage);
  123.             break;
  124.         }
  125.         case STAGE_ALIGNMENT_CHECK: {
  126.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  127.             int nStrRef = GetLocalInt(OBJECT_SELF, "AlignChoice"); // strref for the alignment
  128.             sText += GetStringByStrRef(nStrRef);
  129.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  130.             SetHeader(sText);
  131.             // choices Y/N
  132.             AddChoice(GetStringByStrRef(4753), -1); // no
  133.             AddChoice(GetStringByStrRef(4752), 1); // yes
  134.             MarkStageSetUp(nStage);
  135.             break;
  136.         }
  137.         case STAGE_ABILITY: {
  138.             // the first time through this stage set everything up
  139.             if(GetLocalInt(OBJECT_SELF, "Str") == 0)
  140.             {
  141.                 // get the starting points to allocate
  142.                 int nPoints = GetPRCSwitch(PRC_CONVOCC_STAT_POINTS);
  143.                 if(nPoints == 0)
  144.                     nPoints = 30; // default
  145.                 SetLocalInt(OBJECT_SELF, "Points", nPoints);
  146.                 // get the max stat level (before racial modifiers)
  147.                 int nMaxStat = GetPRCSwitch(PRC_CONVOCC_MAX_STAT);
  148.                 if(nMaxStat == 0)
  149.                     nMaxStat = 18; // default
  150.                 SetLocalInt(OBJECT_SELF, "MaxStat", nMaxStat);
  151.                 // set the starting stat values
  152.                 SetLocalInt(OBJECT_SELF, "Str", 8);
  153.                 SetLocalInt(OBJECT_SELF, "Dex", 8);
  154.                 SetLocalInt(OBJECT_SELF, "Con", 8);
  155.                 SetLocalInt(OBJECT_SELF, "Int", 8);
  156.                 SetLocalInt(OBJECT_SELF, "Wis", 8);
  157.                 SetLocalInt(OBJECT_SELF, "Cha", 8);
  158.             }
  159.             sText = GetStringByStrRef(130) + "\n"; // Select Ability Scores for your Character
  160.             sText += GetStringByStrRef(138) + ": "; // Remaining Points
  161.             sText += IntToString(GetLocalInt(OBJECT_SELF, "Points"));
  162.             SetHeader(sText);
  163.             // get the racial adjustment
  164.             int nRace = GetLocalInt(OBJECT_SELF, "Race");
  165.             string sStrAdjust = Get2DACache("racialtypes", "StrAdjust", nRace);
  166.             string sDexAdjust = Get2DACache("racialtypes", "DexAdjust", nRace);
  167.             string sConAdjust = Get2DACache("racialtypes", "ConAdjust", nRace);
  168.             string sIntAdjust = Get2DACache("racialtypes", "IntAdjust", nRace);
  169.             string sWisAdjust = Get2DACache("racialtypes", "WisAdjust", nRace);
  170.             string sChaAdjust = Get2DACache("racialtypes", "ChaAdjust", nRace);
  171.             // set up the choices in "<statvalue> (racial <+/-modifier>) <statname>. Cost to increase <cost>" format
  172.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Str"), GetStringByStrRef(135), sStrAdjust, ABILITY_STRENGTH);
  173.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Dex"), GetStringByStrRef(133), sDexAdjust, ABILITY_DEXTERITY);
  174.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Con"), GetStringByStrRef(132), sConAdjust, ABILITY_CONSTITUTION);
  175.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Int"), GetStringByStrRef(134), sIntAdjust, ABILITY_INTELLIGENCE);
  176.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Wis"), GetStringByStrRef(136), sWisAdjust, ABILITY_WISDOM);
  177.             AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Cha"), GetStringByStrRef(131), sChaAdjust, ABILITY_CHARISMA);
  178.             MarkStageSetUp(nStage);
  179.             break;
  180.         }
  181.         case STAGE_ABILITY_CHECK: {
  182.             sText = GetStringByStrRef(16824209) + "\n"; // You have selected:
  183.             // get the racial adjustment
  184.             int nRace = GetLocalInt(OBJECT_SELF, "Race");
  185.             string sStrAdjust = Get2DACache("racialtypes", "StrAdjust", nRace);
  186.             string sDexAdjust = Get2DACache("racialtypes", "DexAdjust", nRace);
  187.             string sConAdjust = Get2DACache("racialtypes", "ConAdjust", nRace);
  188.             string sIntAdjust = Get2DACache("racialtypes", "IntAdjust", nRace);
  189.             string sWisAdjust = Get2DACache("racialtypes", "WisAdjust", nRace);
  190.             string sChaAdjust = Get2DACache("racialtypes", "ChaAdjust", nRace);
  191.             sText += GetStringByStrRef(135) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Str") + StringToInt(sStrAdjust)) + "\n"; // str
  192.             sText += GetStringByStrRef(133) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Dex") + StringToInt(sDexAdjust)) + "\n"; // dex
  193.             sText += GetStringByStrRef(132) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Con") + StringToInt(sConAdjust)) + "\n"; // con
  194.             sText += GetStringByStrRef(134) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Int") + StringToInt(sIntAdjust)) + "\n"; // int
  195.             sText += GetStringByStrRef(136) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Wis") + StringToInt(sWisAdjust)) + "\n"; // wis
  196.             sText += GetStringByStrRef(131) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Cha") + StringToInt(sChaAdjust)) + "\n"; // cha
  197.             sText += "\n" + GetStringByStrRef(16824210); // Is this correct?
  198.             SetHeader(sText);
  199.             // choices Y/N
  200.             AddChoice(GetStringByStrRef(4753), -1); // no
  201.             AddChoice(GetStringByStrRef(4752), 1); // yes
  202.             MarkStageSetUp(nStage);
  203.             break;
  204.         }
  205.         case STAGE_SKILL: {
  206.             // the first time through this stage set everything up
  207.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  208.             if(nPoints == 0)
  209.             {
  210.                 SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  211.                 //calculate number of points
  212.                 nPoints += StringToInt(Get2DACache("classes", "SkillPointBase", GetLocalInt(OBJECT_SELF, "Class")));
  213.                 // calculate the intelligence bonus/penalty
  214.                 int nInt = GetLocalInt(OBJECT_SELF, "Int");
  215.                 int nRace = GetLocalInt(OBJECT_SELF, "Race");
  216.                 nPoints += (nInt-10+StringToInt(Get2DACache("racialtypes", "IntAdjust", nRace)))/2;
  217.                 if(GetPRCSwitch(PRC_CONVOCC_SKILL_MULTIPLIER))
  218.                     nPoints *= GetPRCSwitch(PRC_CONVOCC_SKILL_MULTIPLIER);
  219.                 else
  220.                     nPoints *= 4;
  221.                 // humans get an extra 4 skill points at level 1
  222.                 if (GetLocalInt(OBJECT_SELF, "Race") == RACIAL_TYPE_HUMAN)
  223.                     nPoints += 4;
  224.                 nPoints += GetPRCSwitch(PRC_CONVOCC_SKILL_BONUS);
  225.                 // minimum of 4, regardless of int
  226.                 if(nPoints < 4)
  227.                     nPoints = 4;
  228.                 SetLocalInt(OBJECT_SELF, "Points", nPoints);
  229.                 DelayCommand(0.01, DoSkillsLoop());
  230.             }
  231.             else
  232.                 DoSkillsLoop();
  233.             // do header
  234.             sText = GetStringByStrRef(396) + "\n"; // Allocate skill points
  235.             sText += GetStringByStrRef(395) + ": "; // Remaining Points
  236.             sText += IntToString(GetLocalInt(OBJECT_SELF, "Points"));
  237.             SetHeader(sText);
  238.             /* Hack - Returning to the skill selection stage, restore the
  239.              * offset to be the same as it was choosing the skill.
  240.              */
  241.             if(GetLocalInt(OBJECT_SELF, "SkillListChoiceOffset"))
  242.             {
  243.                 SetLocalInt(OBJECT_SELF, DYNCONV_CHOICEOFFSET, GetLocalInt(OBJECT_SELF, "SkillListChoiceOffset") - 1);
  244.                 DeleteLocalInt(OBJECT_SELF, "SkillListChoiceOffset");
  245.             }
  246.             MarkStageSetUp(nStage);
  247.             SetDefaultTokens();
  248.             break;
  249.         }
  250.         case STAGE_SKILL_CHECK: {
  251.             sText = GetStringByStrRef(16824209) + "\n"; // You have selected:
  252.             if(GetPRCSwitch(PRC_CONVOCC_ALLOW_SKILL_POINT_ROLLOVER))
  253.             {
  254.                 sText += "Stored skill points: ";
  255.                 sText += IntToString(GetLocalInt(OBJECT_SELF, "SavedSkillPoints")) + "\n";
  256.             }
  257.             // loop through the "Skills" array
  258.             for(i=0; i <= GetPRCSwitch(FILE_END_SKILLS); i++) // the array can't be bigger than the skills 2da
  259.             {
  260.                 if(array_get_int(OBJECT_SELF, "Skills",i) != 0) // if there are points in the skill, add it to the header
  261.                 {
  262.                     sText+= GetStringByStrRef(StringToInt(Get2DACache("skills", "Name", i)));
  263.                     sText+= " "+IntToString(array_get_int(OBJECT_SELF, "Skills",i))+"\n";
  264.                 }
  265.             }
  266.             sText += "\n" + GetStringByStrRef(16824210); // Is this correct?
  267.             SetHeader(sText);
  268.             // choices Y/N
  269.             AddChoice(GetStringByStrRef(4753), -1); // no
  270.             AddChoice(GetStringByStrRef(4752), 1); // yes
  271.             MarkStageSetUp(nStage);
  272.             break;
  273.         }
  274.         case STAGE_FEAT: {
  275.             sText = GetStringByStrRef(397) + "\n"; // Select Feats
  276.             sText += GetStringByStrRef(398) + ": "; // Feats remaining
  277.             // if it's the first time through, work out the number of feats
  278.             int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points");
  279.             if (!nFeatsRemaining) // first time through
  280.             {
  281.                 nFeatsRemaining = 1; // always have at least 1
  282.                 // check for quick to master
  283.                 nFeatsRemaining += GetLocalInt(OBJECT_SELF, "QTM");
  284.                 // set how many times to go through this stage
  285.                 SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining);
  286.                 // mark skill focus feat prereq here so it's only done once
  287.                 // note: any other skill that is restricted to certain classes needs to be added here
  288.                 // and the local ints deleted in the STAGE_BONUS_FEAT_CHECK case of HandleChoice()
  289.                 // and it enforced in CheckSkillPrereq()
  290.                 // UMD and animal empathy are the only ones so far
  291.                 MarkSkillFocusPrereq(SKILL_ANIMAL_EMPATHY, "bHasAnimalEmpathy");
  292.                 MarkSkillFocusPrereq(SKILL_USE_MAGIC_DEVICE, "bHasUMD");
  293.             }
  294.             // check for bonus feat(s) from class - show the player the total feats
  295.             // even though class bonuses are a different stage
  296.             int nClass = GetLocalInt(OBJECT_SELF, "Class");
  297.             nFeatsRemaining += StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable", nClass), "Bonus", 0));
  298.             sText += IntToString(nFeatsRemaining);
  299.             SetHeader(sText);
  300.             // do feat list
  301.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  302.             if (array_exists(OBJECT_SELF, "CachedChoiceTokens"))
  303.             {
  304.                 // add cached choices to convo
  305.                 AddChoicesFromCache();
  306.                 DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting");
  307.             }
  308.             else
  309.             {
  310.                 DoFeatLoop();
  311.             }
  312.             MarkStageSetUp(nStage);
  313.             SetDefaultTokens();
  314.             break;
  315.         }
  316.         case STAGE_FEAT_CHECK: {
  317.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  318.             // get feat
  319.             int nFeat = array_get_int(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1));
  320.             // alertness fix
  321.             if (nFeat == -1)
  322.                 nFeat = 0;
  323.             sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))) + "\n"; // name
  324.             sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "DESCRIPTION", nFeat))) + "\n"; // description
  325.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  326.             SetHeader(sText);
  327.             // choices Y/N
  328.             AddChoice(GetStringByStrRef(4753), -1); // no
  329.             AddChoice(GetStringByStrRef(4752), 1); // yes
  330.             MarkStageSetUp(nStage);
  331.             break;
  332.         }
  333.         case STAGE_BONUS_FEAT: {
  334.             sText = GetStringByStrRef(397) + "\n"; // Select Feats
  335.             sText += GetStringByStrRef(398) + ": "; // Feats remaining
  336.             int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points");
  337.             if (!nFeatsRemaining) // first time through
  338.             {
  339.                 // check for bonus feat(s) from class
  340.                 int nClass = GetLocalInt(OBJECT_SELF, "Class");
  341.                 nFeatsRemaining += StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable", nClass), "Bonus", 0));
  342.                 // set how many times to go through this stage
  343.                 SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining);
  344.             }
  345.             sText += IntToString(nFeatsRemaining);
  346.             SetHeader(sText);
  347.             // do feat list
  348.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  349.             if (array_exists(OBJECT_SELF, "CachedChoiceTokens"))
  350.             {
  351.                 // add cached choices to convo
  352.                 AddChoicesFromCache();
  353.                 DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting");
  354.             }
  355.             else
  356.             {
  357.                 DoBonusFeatLoop();
  358.             }
  359.             MarkStageSetUp(nStage);
  360.             SetDefaultTokens();
  361.             break;
  362.         }
  363.         case STAGE_BONUS_FEAT_CHECK: {
  364.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  365.             // get feat
  366.             int nFeat = array_get_int(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1));
  367.             sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))) + "\n"; // name
  368.             sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "DESCRIPTION", nFeat))) + "\n"; // description
  369.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  370.             SetHeader(sText);
  371.             // choices Y/N
  372.             AddChoice(GetStringByStrRef(4753), -1); // no
  373.             AddChoice(GetStringByStrRef(4752), 1); // yes
  374.             MarkStageSetUp(nStage);
  375.             break;
  376.         }
  377.         case STAGE_WIZ_SCHOOL: {
  378.             sText = GetStringByStrRef(381); // Select a School of Magic
  379.             SetHeader(sText);
  380.             // choices
  381.             if(GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS))
  382.             {
  383.                 AddChoice(GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", 9))), 9);
  384.             }
  385.             else
  386.             {
  387.                 for(i = 0; i < 9; i++)
  388.                 {
  389.                     AddChoice(GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", i))), i);
  390.                 }
  391.             }
  392.             MarkStageSetUp(nStage);
  393.             break;
  394.         }
  395.         case STAGE_WIZ_SCHOOL_CHECK: {
  396.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  397.             sText+= GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", GetLocalInt(OBJECT_SELF, "School"))));
  398.             sText+= "\n\n";
  399.             sText+= GetStringByStrRef(StringToInt(Get2DACache("spellschools", "Description", GetLocalInt(OBJECT_SELF, "School"))));
  400.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  401.             SetHeader(sText);
  402.             // choices Y/N
  403.             AddChoice(GetStringByStrRef(4753), -1); // no
  404.             AddChoice(GetStringByStrRef(4752), 1); // yes
  405.             MarkStageSetUp(nStage);
  406.             break;
  407.         }
  408.         case STAGE_SPELLS_0: {
  409.             // if the first time through, set up the number of cantrips to pick
  410.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  411.             int nClass = GetLocalInt(OBJECT_SELF, "Class");
  412.             if(nPoints == 0)
  413.             {
  414.                 // set up the number of spells to pick
  415.                 // get the cls_spkn_***2da to use
  416.                 string sSpkn = Get2DACache("classes", "SpellKnownTable", nClass);
  417.                 // set the number of spells to pick
  418.                 nPoints = StringToInt(Get2DACache(sSpkn, "SpellLevel0", 0));
  419.                 SetLocalInt(OBJECT_SELF, "Points", nPoints);
  420.                 // don't want to be waiting every time
  421.                 SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  422.             }
  423.             sText = GetStringByStrRef(372) + "\n"; // Select Cantrips
  424.             sText += GetStringByStrRef(371) + ": "; // Remaining Spells
  425.             sText += IntToString(nPoints);
  426.             SetHeader(sText);
  427.             // choices, uses nStage to see if it's listing level 0 or level 1 spells
  428.             DoSpellsLoop(nStage);
  429.             MarkStageSetUp(nStage);
  430.             SetDefaultTokens();
  431.             break;
  432.         }
  433.         case STAGE_SPELLS_1: {
  434.             // if the first time through, set up the number of spells to pick
  435.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  436.             int nClass = GetLocalInt(OBJECT_SELF, "Class");
  437.             if(nPoints == 0)
  438.             {
  439.                 switch(nClass)
  440.                 {
  441.                     case CLASS_TYPE_WIZARD: {
  442.                         // spells to pick is 3 + int modifier
  443.                         int nIntMod = GetLocalInt(OBJECT_SELF, "Int");
  444.                         nIntMod += StringToInt(Get2DACache("racialtypes", "IntAdjust", GetLocalInt(OBJECT_SELF, "Race")));
  445.                         nIntMod = (nIntMod - 10)/2;
  446.                         nPoints = 3 + nIntMod;
  447.                         break;
  448.                     }
  449.                     case CLASS_TYPE_SORCERER: {
  450.                         // get the cls_spkn_***2da to use
  451.                         string sSpkn = Get2DACache("classes", "SpellKnownTable", nClass);
  452.                         // set the number of spells to pick
  453.                         nPoints = StringToInt(Get2DACache(sSpkn, "SpellLevel1", 0));
  454.                         break;
  455.                     }
  456.                 }
  457.                 SetLocalInt(OBJECT_SELF, "Points", nPoints);
  458.                 // don't want to be waiting every time
  459.                 SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  460.             }
  461.             sText = GetStringByStrRef(368) + "\n"; // Select Spells for your Character
  462.             sText += GetStringByStrRef(371) + ": "; // Remaining Spells
  463.             sText += IntToString(GetLocalInt(OBJECT_SELF, "Points"));
  464.             SetHeader(sText);
  465.             // choices, uses nStage to see if it's listing level 0 or level 1 spells
  466.             DoSpellsLoop(nStage);
  467.             MarkStageSetUp(nStage);
  468.             SetDefaultTokens();
  469.             break;
  470.         }
  471.         case STAGE_SPELLS_CHECK: {
  472.             sText = GetStringByStrRef(16824209) + "\n"; // You have selected:
  473.             int spellID = 0;
  474.             sText += GetStringByStrRef(691) + " - \n"; // Cantrips
  475.             // loop through the spell choices
  476.             for (i = 0; i < array_get_size(OBJECT_SELF, "SpellLvl0"); i++)
  477.             {
  478.                 spellID = array_get_int(OBJECT_SELF, "SpellLvl0", i);
  479.                 sText+= GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellID)));
  480.                 sText += "\n";
  481.             }
  482.             sText += GetStringByStrRef(61924) + " - \n"; // Level 1 Spells
  483.             // loop through the spell choices
  484.             for (i = 0; i < array_get_size(OBJECT_SELF, "SpellLvl1"); i++)
  485.             {
  486.                 spellID = array_get_int(OBJECT_SELF, "SpellLvl1", i);
  487.                 sText+= GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellID)));
  488.                 sText += "\n";
  489.             }
  490.             sText+= "\n"+GetStringByStrRef(16824210); // Is this correct?
  491.             SetHeader(sText);
  492.             // choices Y/N
  493.             AddChoice(GetStringByStrRef(4753), -1); // no
  494.             AddChoice(GetStringByStrRef(4752), 1); // yes
  495.             MarkStageSetUp(nStage);
  496.             break;
  497.         }
  498.         case STAGE_FAMILIAR: {
  499.             int nClass = GetLocalInt(OBJECT_SELF, "Class");
  500.             sText = GetStringByStrRef(5607) + "\n"; // Choose a Familiar for your Character
  501.             sText += "(" + GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", nClass))) + ")";
  502.             SetHeader(sText);
  503.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  504.             // do choices
  505.             if (nClass == CLASS_TYPE_DRUID)
  506.                 Do2daLoop("hen_companion", "strref", GetPRCSwitch(FILE_END_ANIMALCOMP));
  507.             else // wizard or sorc
  508.                 Do2daLoop("hen_familiar", "strref", GetPRCSwitch(FILE_END_FAMILIAR));
  509.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", FALSE);
  510.             FloatingTextStringOnCreature("Done", OBJECT_SELF, FALSE);
  511.             MarkStageSetUp(nStage);
  512.             SetDefaultTokens();
  513.             break;
  514.         }
  515.         case STAGE_FAMILIAR_CHECK: {
  516.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  517.             if (GetLocalInt(OBJECT_SELF, "Class") == CLASS_TYPE_DRUID)
  518.             {
  519.                 int nCompanion = GetLocalInt(OBJECT_SELF, "Companion");
  520.                 sText += GetStringByStrRef(StringToInt(Get2DACache("hen_companion", "STRREF", nCompanion)));
  521.                 sText += "\n";
  522.                 sText += GetStringByStrRef(StringToInt(Get2DACache("hen_companion", "DESCRIPTION", nCompanion)));
  523.                 sText += "\n";
  524.             }
  525.             else
  526.             {
  527.                 int nFamiliar = GetLocalInt(OBJECT_SELF, "Familiar");
  528.                 sText += GetStringByStrRef(StringToInt(Get2DACache("hen_familiar", "STRREF", nFamiliar)));
  529.                 sText += "\n";
  530.                 sText += GetStringByStrRef(StringToInt(Get2DACache("hen_familiar", "DESCRIPTION", nFamiliar)));
  531.                 sText += "\n";
  532.             }
  533.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  534.             SetHeader(sText);
  535.             // choices Y/N
  536.             AddChoice(GetStringByStrRef(4753), -1); // no
  537.             AddChoice(GetStringByStrRef(4752), 1); // yes
  538.             MarkStageSetUp(nStage);
  539.             break;
  540.         }
  541.         case STAGE_DOMAIN: {
  542.             sText = GetStringByStrRef(5982); // Pick Cleric Domain
  543.             SetHeader(sText);
  544.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  545.             // choices
  546.             DoDomainsLoop();
  547.             MarkStageSetUp(nStage);
  548.             SetDefaultTokens();
  549.             break;
  550.         }
  551.         case STAGE_DOMAIN_CHECK1: {
  552.             sText = GetStringByStrRef(16824209) + "\n"; // You have selected:
  553.             // first domain
  554.             int nDomain = GetLocalInt(OBJECT_SELF,"Domain1");
  555.             // fix for air domain being 0
  556.             if (nDomain == -1)
  557.                 nDomain = 0;
  558.             sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Name", nDomain))) + "\n";
  559.             sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Description", nDomain))) + "\n";
  560.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  561.             SetHeader(sText);
  562.             // choices Y/N
  563.             AddChoice(GetStringByStrRef(4753), -1); // no
  564.             AddChoice(GetStringByStrRef(4752), 1); // yes
  565.             MarkStageSetUp(nStage);
  566.             break;
  567.         }
  568.         case STAGE_DOMAIN_CHECK2: {
  569.             sText = GetStringByStrRef(16824209) + "\n"; // You have selected:
  570.             // second domain
  571.             int nDomain = GetLocalInt(OBJECT_SELF,"Domain2");
  572.             // fix for air domain being 0
  573.             if (nDomain == -1)
  574.                 nDomain = 0;
  575.             sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Name", nDomain))) + "\n";
  576.             sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Description", nDomain))) + "\n";
  577.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  578.             SetHeader(sText);
  579.             // choices Y/N
  580.             AddChoice(GetStringByStrRef(4753), -1); // no
  581.             AddChoice(GetStringByStrRef(4752), 1); // yes
  582.             MarkStageSetUp(nStage);
  583.             break;
  584.         }
  585.         case STAGE_APPEARANCE: {
  586.             sText = GetStringByStrRef(124); // Select the Appearance of your Character
  587.             SetHeader(sText);
  588.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  589.             if(GetPRCSwitch(PRC_CONVOCC_USE_RACIAL_APPEARANCES)) // restrict to what is given in the 2da
  590.                 SetupRacialAppearances();
  591.             else
  592.                 DoAppearanceLoop();
  593.             MarkStageSetUp(nStage);
  594.             SetDefaultTokens();
  595.             break;
  596.         }
  597.         case STAGE_APPEARANCE_CHECK: {
  598.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  599.             int nAppearance = GetLocalInt(OBJECT_SELF, "Appearance");
  600.             int nStrRef = StringToInt(Get2DACache("appearance", "STRING_REF", nAppearance));
  601.             if(nStrRef)
  602.                 sText += GetStringByStrRef(nStrRef);
  603.             else
  604.                 sText += Get2DACache("appearance", "LABEL", nAppearance);
  605.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  606.             SetHeader(sText);
  607.             // choices Y/N
  608.             AddChoice(GetStringByStrRef(4753), -1); // no
  609.             AddChoice(GetStringByStrRef(4752), 1); // yes
  610.             MarkStageSetUp(nStage);
  611.             break;
  612.         }
  613.         case STAGE_PORTRAIT: {
  614.             sText = GetStringByStrRef(7383); // Select a portrait
  615.             SetHeader(sText);
  616.             if(GetPRCSwitch(PRC_CONVOCC_ALLOW_TO_KEEP_PORTRAIT))
  617.                 AddChoice("Keep existing portrait.", -1);
  618.             // if(GetPRCSwitch(PRC_CONVOCC_USE_RACIAL_PORTRAIT))
  619.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  620.             DoPortraitsLoop();
  621.             MarkStageSetUp(nStage);
  622.             SetDefaultTokens();
  623.             break;
  624.         }
  625.         case STAGE_PORTRAIT_CHECK: {
  626.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  627.             int nPortrait = GetPortraitId(OBJECT_SELF);
  628.             sText += Get2DACache("portraits", "BaseResRef", nPortrait);
  629.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  630.             SetHeader(sText);
  631.             // choices Y/N
  632.             AddChoice("View this portrait.", 2);
  633.             AddChoice(GetStringByStrRef(4753), -1); // no
  634.             AddChoice(GetStringByStrRef(4752), 1); // yes
  635.             MarkStageSetUp(nStage);
  636.             break;
  637.         }
  638.         case STAGE_SOUNDSET: {
  639.             sText = GetStringByStrRef(7535); // Select a sound set
  640.             SetHeader(sText);
  641.             if(GetPRCSwitch(PRC_CONVOCC_ALLOW_TO_KEEP_VOICESET))
  642.                 AddChoice("keep existing soundset.", -1);
  643.             SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE);
  644.             DoSoundsetLoop();
  645.             MarkStageSetUp(nStage);
  646.             SetDefaultTokens();
  647.             break;
  648.         }
  649.         case STAGE_SOUNDSET_CHECK: {
  650.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  651.             int nSoundset = GetLocalInt(OBJECT_SELF, "Soundset");
  652.             sText += GetStringByStrRef(StringToInt(Get2DACache("soundset", "STRREF", nSoundset)));
  653.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  654.             SetHeader(sText);
  655.             // choices Y/N
  656.             AddChoice("Listen to this soundset.", 2);
  657.             AddChoice(GetStringByStrRef(4753), -1); // no
  658.             AddChoice(GetStringByStrRef(4752), 1); // yes
  659.             MarkStageSetUp(nStage);
  660.             break;
  661.         }
  662.         case STAGE_HEAD: {
  663.             sText = GetStringByStrRef(124); // Select the Appearance of your Character
  664.             sText += "(" + GetStringByStrRef(123) + ")"; // Head
  665.             SetHeader(sText);
  666.             AddChoice("keep existing head", -1);
  667.             SetupHeadChoices();
  668.             MarkStageSetUp(nStage);
  669.             SetDefaultTokens();
  670.             break;
  671.         }
  672.         case STAGE_HEAD_CHECK: {
  673.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  674.             SetHeader(sText);
  675.             // choices Y/N
  676.             AddChoice(GetStringByStrRef(4753), -1); // no
  677.             AddChoice(GetStringByStrRef(4752), 1); // yes
  678.             MarkStageSetUp(nStage);
  679.             break;
  680.         }
  681.         case STAGE_TATTOO: {
  682.             sText = GetStringByStrRef(124); // Select the Appearance of your Character
  683.             sText += "(" + GetStringByStrRef(1591) + ")"; // Tattoo
  684.             SetHeader(sText);
  685.             AddChoice("keep current tatoos", -1);
  686.             AddChoice("torso", CREATURE_PART_TORSO);
  687.             AddChoice("right shin", CREATURE_PART_RIGHT_SHIN);
  688.             AddChoice("left shin", CREATURE_PART_LEFT_SHIN);
  689.             AddChoice("right thigh", CREATURE_PART_RIGHT_THIGH);
  690.             AddChoice("left thigh", CREATURE_PART_LEFT_THIGH);
  691.             AddChoice("right forearm", CREATURE_PART_RIGHT_FOREARM);
  692.             AddChoice("left forearm", CREATURE_PART_LEFT_FOREARM);
  693.             AddChoice("right bicep", CREATURE_PART_RIGHT_BICEP);
  694.             AddChoice("left bicep", CREATURE_PART_LEFT_BICEP);
  695.             MarkStageSetUp(nStage);
  696.             break;
  697.         }
  698.         case STAGE_TATTOO_CHECK: {
  699.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  700.             SetHeader(sText);
  701.             // choices Y/N
  702.             AddChoice(GetStringByStrRef(4753), -1); // no
  703.             AddChoice(GetStringByStrRef(4752), 1); // yes
  704.             MarkStageSetUp(nStage);
  705.             break;
  706.         }
  707.         case STAGE_WINGS: {
  708.             sText = GetStringByStrRef(124); // Select the Appearance of your Character
  709.             sText += "(" + GetStringByStrRef(2409) + ")"; // Wings
  710.             SetHeader(sText);
  711.             DoWingmodelLoop();
  712.             MarkStageSetUp(nStage);
  713.             break;
  714.         }
  715.         case STAGE_WINGS_CHECK: {
  716.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  717.             int nWingType = GetCreatureWingType();
  718.             sText += Get2DACache("wingmodel", "label", nWingType);
  719.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  720.             SetHeader(sText);
  721.             // choices Y/N
  722.             AddChoice(GetStringByStrRef(4753), -1); // no
  723.             AddChoice(GetStringByStrRef(4752), 1); // yes
  724.             MarkStageSetUp(nStage);
  725.             break;
  726.         }
  727.         case STAGE_TAIL: {
  728.             sText = GetStringByStrRef(124); // Select the Appearance of your Character
  729.             sText += "(" + GetStringByStrRef(2410) + ")"; // Tail
  730.             SetHeader(sText);
  731.             DoTailmodelLoop();
  732.             MarkStageSetUp(nStage);
  733.             break;
  734.         }
  735.         case STAGE_TAIL_CHECK: {
  736.             sText = GetStringByStrRef(16824209) + " "; // You have selected:
  737.             int nTailType = GetCreatureTailType();
  738.             sText += Get2DACache("tailmodel", "label", nTailType);
  739.             sText += "\n"+GetStringByStrRef(16824210); // Is this correct?
  740.             SetHeader(sText);
  741.             // choices Y/N
  742.             AddChoice(GetStringByStrRef(4753), -1); // no
  743.             AddChoice(GetStringByStrRef(4752), 1); // yes
  744.             MarkStageSetUp(nStage);
  745.             break;
  746.         }
  747.         case STAGE_SKIN_COLOUR: {
  748.             sText = "Pick a colour category ";
  749.             sText += "(" + GetStringByStrRef(128) + ")"; // Skin Color
  750.             SetHeader(sText);
  751.             AddChoice("Keep current skin colour", -1);
  752.             AddChoice("Tan colours", 1);
  753.             AddChoice("Sand & Rose brown", 2);
  754.             AddChoice("Tan-Greys and blues", 3);
  755.             AddChoice("Gold and obsidian", 4);
  756.             AddChoice("Greens", 5);
  757.             AddChoice("Greys and reds", 6);
  758.             AddChoice("Bright blues, greens and yellows", 7);
  759.             // new colours
  760.             AddChoice("Metallic & pure white and black", 8);
  761.             AddChoice("Smoky Group 1", 9);
  762.             AddChoice("Smoky Group 2", 10);
  763.             AddChoice("Smoky Group 3", 11);
  764.             AddChoice("Smoky Group 4", 12);
  765.             AddChoice("Black Cherry & Cinnamon", 13);
  766.             AddChoice("Hunter Green & Druid Green", 14);
  767.             AddChoice("Graveyard Fog & Chestnut", 15);
  768.             AddChoice("Clay & Toasted Ash", 16);
  769.             AddChoice("Snail Brown & Cobalt Blue", 17);
  770.             AddChoice("Midnight Blue & Peacock Green", 18);
  771.             AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19);
  772.             AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20);
  773.             AddChoice("Sugar Plum, Ice Blue, Black, & White", 21);
  774.             AddChoice("Greens, Mystics, & Browns", 22);
  775.             MarkStageSetUp(nStage);
  776.             SetDefaultTokens();
  777.             break;
  778.         }
  779.         case STAGE_SKIN_COLOUR_CHOICE: {
  780.             sText = "Pick a colour ";
  781.             sText += "(" + GetStringByStrRef(128) + ")"; // Skin Color
  782.             SetHeader(sText);
  783.             int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  784.             AddColourChoices(nStage, nCategory);
  785.             MarkStageSetUp(nStage);
  786.             SetDefaultTokens();
  787.             break;
  788.         }
  789.         case STAGE_SKIN_COLOUR_CHECK: {
  790.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  791.             SetHeader(sText);
  792.             // choices Y/N
  793.             AddChoice(GetStringByStrRef(4753), -1); // no
  794.             AddChoice(GetStringByStrRef(4752), 1); // yes
  795.             MarkStageSetUp(nStage);
  796.             break;
  797.         }
  798.         case STAGE_HAIR_COLOUR: {
  799.             sText = "Pick a colour category ";
  800.             sText += "(" + GetStringByStrRef(125) + ")"; // Hair Color
  801.             SetHeader(sText);
  802.             AddChoice("Keep current hair colour", -1);
  803.             AddChoice("Chestnuts and Reds", 1);
  804.             AddChoice("Blondes and Browns", 2);
  805.             AddChoice("White, Greys and Black", 3);
  806.             AddChoice("Blues", 4);
  807.             AddChoice("Greens", 5);
  808.             AddChoice("Spring Greens and Yellows", 6);
  809.             AddChoice("Oranges and Pinks", 7);
  810.             // new colours
  811.             AddChoice("Metallic & pure white and black", 8);
  812.             AddChoice("Smoky Group 1", 9);
  813.             AddChoice("Smoky Group 2", 10);
  814.             AddChoice("Smoky Group 3", 11);
  815.             AddChoice("Smoky Group 4", 12);
  816.             AddChoice("Black Cherry & Cinnamon", 13);
  817.             AddChoice("Hunter Green & Druid Green", 14);
  818.             AddChoice("Graveyard Fog & Chestnut", 15);
  819.             AddChoice("Clay & Toasted Ash", 16);
  820.             AddChoice("Snail Brown & Cobalt Blue", 17);
  821.             AddChoice("Midnight Blue & Peacock Green", 18);
  822.             AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19);
  823.             AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20);
  824.             AddChoice("Sugar Plum, Ice Blue, Black, & White", 21);
  825.             AddChoice("Greens, Mystics, & Browns", 22);
  826.             MarkStageSetUp(nStage);
  827.             SetDefaultTokens();
  828.             break;
  829.         }
  830.         case STAGE_HAIR_COLOUR_CHOICE: {
  831.             sText = "Pick a colour ";
  832.             sText += "(" + GetStringByStrRef(125) + ")"; // Hair Color
  833.             SetHeader(sText);
  834.             int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  835.             AddColourChoices(nStage, nCategory);
  836.             MarkStageSetUp(nStage);
  837.             SetDefaultTokens();
  838.             break;
  839.         }
  840.         case STAGE_HAIR_COLOUR_CHECK: {
  841.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  842.             SetHeader(sText);
  843.             // choices Y/N
  844.             AddChoice(GetStringByStrRef(4753), -1); // no
  845.             AddChoice(GetStringByStrRef(4752), 1); // yes
  846.             MarkStageSetUp(nStage);
  847.             break;
  848.         }
  849.         case STAGE_TATTOO1_COLOUR: {
  850.             sText = "Pick a colour category ";
  851.             sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors
  852.             SetHeader(sText);
  853.             AddChoice("Keep current tattoo 1 colour", -1);
  854.             AddChoice("Tan/Brown & Tan/Red", 1);
  855.             AddChoice("Tan/Yellow & Tan/Grey", 2);
  856.             AddChoice("Olive, White, Grey & Charcoal", 3);
  857.             AddChoice("Blue, Aqua, Teal & Green", 4);
  858.             AddChoice("Yellow, Orange, Red & Pink", 5);
  859.             AddChoice("Purple, Violet & Shiny/Metallic group 1", 6);
  860.             AddChoice("Shiny/Metallic group 2", 7);
  861.             // new colours
  862.             AddChoice("Metallic & pure white and black", 8);
  863.             AddChoice("Smoky Group 1", 9);
  864.             AddChoice("Smoky Group 2", 10);
  865.             AddChoice("Smoky Group 3", 11);
  866.             AddChoice("Smoky Group 4", 12);
  867.             AddChoice("Black Cherry & Cinnamon", 13);
  868.             AddChoice("Hunter Green & Druid Green", 14);
  869.             AddChoice("Graveyard Fog & Chestnut", 15);
  870.             AddChoice("Clay & Toasted Ash", 16);
  871.             AddChoice("Snail Brown & Cobalt Blue", 17);
  872.             AddChoice("Midnight Blue & Peacock Green", 18);
  873.             AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19);
  874.             AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20);
  875.             AddChoice("Sugar Plum, Ice Blue, Black, & White", 21);
  876.             AddChoice("Greens, Mystics, & Browns", 22);
  877.             MarkStageSetUp(nStage);
  878.             SetDefaultTokens();
  879.             break;
  880.         }
  881.         case STAGE_TATTOO1_COLOUR_CHOICE: {
  882.             sText = "Pick a colour ";
  883.             sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors
  884.             SetHeader(sText);
  885.             int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  886.             AddColourChoices(nStage, nCategory);
  887.             MarkStageSetUp(nStage);
  888.             SetDefaultTokens();
  889.             break;
  890.         }
  891.         case STAGE_TATTOO1_COLOUR_CHECK: {
  892.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  893.             SetHeader(sText);
  894.             // choices Y/N
  895.             AddChoice(GetStringByStrRef(4753), -1); // no
  896.             AddChoice(GetStringByStrRef(4752), 1); // yes
  897.             MarkStageSetUp(nStage);
  898.             break;
  899.         }
  900.         case STAGE_TATTOO2_COLOUR: {
  901.             sText = "Pick a colour category ";
  902.             sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors
  903.             SetHeader(sText);
  904.             AddChoice("Keep current tattoo 2 colour", -1);
  905.             AddChoice("Tan/Brown & Tan/Red", 1);
  906.             AddChoice("Tan/Yellow & Tan/Grey", 2);
  907.             AddChoice("Olive, White, Grey & Charcoal", 3);
  908.             AddChoice("Blue, Aqua, Teal & Green", 4);
  909.             AddChoice("Yellow, Orange, Red & Pink", 5);
  910.             AddChoice("Purple, Violet & Shiny/Metallic group 1", 6);
  911.             AddChoice("Shiny/Metallic group 2", 7);
  912.             // new colours
  913.             AddChoice("Metallic & pure white and black", 8);
  914.             AddChoice("Smoky Group 1", 9);
  915.             AddChoice("Smoky Group 2", 10);
  916.             AddChoice("Smoky Group 3", 11);
  917.             AddChoice("Smoky Group 4", 12);
  918.             AddChoice("Black Cherry & Cinnamon", 13);
  919.             AddChoice("Hunter Green & Druid Green", 14);
  920.             AddChoice("Graveyard Fog & Chestnut", 15);
  921.             AddChoice("Clay & Toasted Ash", 16);
  922.             AddChoice("Snail Brown & Cobalt Blue", 17);
  923.             AddChoice("Midnight Blue & Peacock Green", 18);
  924.             AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19);
  925.             AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20);
  926.             AddChoice("Sugar Plum, Ice Blue, Black, & White", 21);
  927.             AddChoice("Greens, Mystics, & Browns", 22);
  928.             MarkStageSetUp(nStage);
  929.             SetDefaultTokens();
  930.             break;
  931.         }
  932.         case STAGE_TATTOO2_COLOUR_CHOICE: {
  933.             sText = "Pick a colour ";
  934.             sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors
  935.             SetHeader(sText);
  936.             int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  937.             AddColourChoices(nStage, nCategory);
  938.             MarkStageSetUp(nStage);
  939.             SetDefaultTokens();
  940.             break;
  941.         }
  942.         case STAGE_TATTOO2_COLOUR_CHECK: {
  943.             sText = "\n"+GetStringByStrRef(16824210); // Is this correct?
  944.             SetHeader(sText);
  945.             // choices Y/N
  946.             AddChoice(GetStringByStrRef(4753), -1); // no
  947.             AddChoice(GetStringByStrRef(4752), 1); // yes
  948.             MarkStageSetUp(nStage);
  949.             break;
  950.         }
  951.         case FINAL_STAGE: {
  952.             sText = "Your character will now be generated. As part of this process, you will be booted. Please exit NWN completely before rejoining.";
  953.             SetHeader(sText);
  954.             AddChoice("Make Character", 1);
  955.             MarkStageSetUp(nStage);
  956.             // give the PC the woodsman outfit so they don't have to be naked
  957.             CreateItemOnObject("NW_CLOTH001", OBJECT_SELF);
  958.             break;
  959.         }
  960.         default:
  961.             DoDebug("ccc_inc_convo: DoHeaderAndChoices(): Unknown nStage value: " + IntToString(nStage));
  962.     }
  963. }
  964.  
  965. int HandleChoice(int nStage, int nChoice)
  966. {
  967.     switch(nStage)
  968.     {
  969.         case STAGE_INTRODUCTION:
  970.             nStage++;
  971.             break;
  972.  
  973.         case STAGE_GENDER:
  974.             SetLocalInt(OBJECT_SELF, "Gender", nChoice);
  975.             nStage++;
  976.             break;
  977.  
  978.         case STAGE_GENDER_CHECK: {
  979.             if(nChoice == 1)
  980.                 nStage++;
  981.             else // go back to pick gender
  982.             {
  983.                 nStage = STAGE_GENDER;
  984.                 MarkStageNotSetUp(STAGE_GENDER_CHECK, OBJECT_SELF);
  985.                 MarkStageNotSetUp(STAGE_GENDER, OBJECT_SELF);
  986.                 DeleteLocalInt(OBJECT_SELF, "Gender");
  987.             }
  988.             break;
  989.         }
  990.         case STAGE_RACE:
  991.             SetLocalInt(OBJECT_SELF, "Race", nChoice);
  992.             nStage++;
  993.             break;
  994.         case STAGE_RACE_CHECK: {
  995.             if(nChoice == 1)
  996.             {
  997.                 nStage++;
  998.                 DoCutscene(OBJECT_SELF);
  999.                 // store racial feat variables
  1000.                 AddRaceFeats(GetLocalInt(OBJECT_SELF, "Race"));
  1001.             }
  1002.             else // go back and pick race
  1003.             {
  1004.                 nStage = STAGE_RACE;
  1005.                 MarkStageNotSetUp(STAGE_RACE_CHECK, OBJECT_SELF);
  1006.                 MarkStageNotSetUp(STAGE_RACE, OBJECT_SELF);
  1007.                 DeleteLocalInt(OBJECT_SELF, "Race");
  1008.             }
  1009.             break;
  1010.         }
  1011.         case STAGE_CLASS:
  1012.             SetLocalInt(OBJECT_SELF, "Class", nChoice);
  1013.             nStage++;
  1014.             break;
  1015.         case STAGE_CLASS_CHECK: {
  1016.             if(nChoice == 1)
  1017.             {
  1018.                 nStage++;
  1019.                 // add class feats
  1020.                 AddClassFeats(GetLocalInt(OBJECT_SELF, "Class"));
  1021.                 // now for hitpoints (without con alteration)
  1022.                 SetLocalInt(OBJECT_SELF, "HitPoints",
  1023.                     StringToInt(Get2DACache("classes", "HitDie",
  1024.                         GetLocalInt(OBJECT_SELF, "Class"))));
  1025.             }
  1026.             else // go back and pick class
  1027.             {
  1028.                 nStage = STAGE_CLASS;
  1029.                 MarkStageNotSetUp(STAGE_CLASS_CHECK, OBJECT_SELF);
  1030.                 MarkStageNotSetUp(STAGE_CLASS, OBJECT_SELF);
  1031.                 DeleteLocalInt(OBJECT_SELF, "Class");
  1032.             }
  1033.             break;
  1034.         }
  1035.         case STAGE_ALIGNMENT: {
  1036.             // for stage check later
  1037.             SetLocalInt(OBJECT_SELF, "AlignChoice", nChoice);
  1038.             switch(nChoice)
  1039.             {
  1040.                 case 112: //lawful good
  1041.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85);
  1042.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 85);
  1043.                     break;
  1044.                 case 115: //neutral good
  1045.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50);
  1046.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 85);
  1047.                     break;
  1048.                 case 118: //chaotic good
  1049.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15);
  1050.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 85);
  1051.                     break;
  1052.                 case 113: //lawful neutral
  1053.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85);
  1054.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 50);
  1055.                     break;
  1056.                 case 116: //true neutral
  1057.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50);
  1058.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 50);
  1059.                     break;
  1060.                 case 119: //chaotic neutral
  1061.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15);
  1062.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 50);
  1063.                     break;
  1064.                 case 114: //lawful evil
  1065.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85);
  1066.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 15);
  1067.                     break;
  1068.                 case 117: //neutral evil
  1069.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50);
  1070.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 15);
  1071.                     break;
  1072.                 case 120: //chaotic evil
  1073.                     SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15);
  1074.                     SetLocalInt(OBJECT_SELF, "GoodEvil", 15);
  1075.                     break;
  1076.                 default:
  1077.                     DoDebug("Duh, that clearly didn't work right");
  1078.             }
  1079.             nStage++;
  1080.             break;
  1081.         }
  1082.         case STAGE_ALIGNMENT_CHECK: {
  1083.             if(nChoice == 1)
  1084.             {
  1085.                 nStage++;
  1086.             }
  1087.             else // go back and pick alignment
  1088.             {
  1089.                 nStage = STAGE_ALIGNMENT;
  1090.                 MarkStageNotSetUp(STAGE_ALIGNMENT_CHECK, OBJECT_SELF);
  1091.                 MarkStageNotSetUp(STAGE_ALIGNMENT, OBJECT_SELF);
  1092.                 DeleteLocalInt(OBJECT_SELF, "AlignChoice");
  1093.                 DeleteLocalInt(OBJECT_SELF, "LawfulChaotic");
  1094.                 DeleteLocalInt(OBJECT_SELF, "GoodEvil");
  1095.             }
  1096.             break;
  1097.         }
  1098.         case STAGE_ABILITY: {
  1099.             int nAbilityScore;
  1100.             switch(nChoice)
  1101.             {
  1102.                 case ABILITY_STRENGTH:
  1103.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Str"));
  1104.                     SetLocalInt(OBJECT_SELF, "Str", nAbilityScore);
  1105.                     break;
  1106.                 case ABILITY_DEXTERITY:
  1107.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Dex"));
  1108.                     SetLocalInt(OBJECT_SELF, "Dex", nAbilityScore);
  1109.                     break;
  1110.                 case ABILITY_CONSTITUTION:
  1111.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Con"));
  1112.                     SetLocalInt(OBJECT_SELF, "Con", nAbilityScore);
  1113.                     break;
  1114.                 case ABILITY_INTELLIGENCE:
  1115.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Int"));
  1116.                     SetLocalInt(OBJECT_SELF, "Int", nAbilityScore);
  1117.                     break;
  1118.                 case ABILITY_WISDOM:
  1119.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Wis"));
  1120.                     SetLocalInt(OBJECT_SELF, "Wis", nAbilityScore);
  1121.                     break;
  1122.                 case ABILITY_CHARISMA:
  1123.                     nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Cha"));
  1124.                     SetLocalInt(OBJECT_SELF, "Cha", nAbilityScore);
  1125.                     break;
  1126.             }
  1127.             int nPoints = GetLocalInt(OBJECT_SELF, "Points"); // new total
  1128.             if (nPoints) // if there's still points to allocate
  1129.             {
  1130.                 // resets the stage so that the convo choices reflect the new ability scores
  1131.                 ClearCurrentStage();
  1132.             }
  1133.             else
  1134.                 nStage++; // go to next stage
  1135.             break;
  1136.         }
  1137.         case STAGE_ABILITY_CHECK:{
  1138.             if(nChoice == 1)
  1139.             {
  1140.                 nStage++;
  1141.             }
  1142.             else // go back and reselect ability score
  1143.             {
  1144.                 nStage = STAGE_ABILITY;
  1145.                 MarkStageNotSetUp(STAGE_ABILITY_CHECK, OBJECT_SELF);
  1146.                 MarkStageNotSetUp(STAGE_ABILITY, OBJECT_SELF);
  1147.                 DeleteLocalInt(OBJECT_SELF, "Str");
  1148.                 DeleteLocalInt(OBJECT_SELF, "Dex");
  1149.                 DeleteLocalInt(OBJECT_SELF, "Con");
  1150.                 DeleteLocalInt(OBJECT_SELF, "Int");
  1151.                 DeleteLocalInt(OBJECT_SELF, "Wis");
  1152.                 DeleteLocalInt(OBJECT_SELF, "Cha");
  1153.             }
  1154.             break;
  1155.         }
  1156.         case STAGE_SKILL: {
  1157.             // first time through, create the skills array
  1158.             if(!array_exists(OBJECT_SELF, "Skills"))
  1159.                 array_create(OBJECT_SELF, "Skills");
  1160.             // get current points
  1161.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  1162.             if(GetChoice(OBJECT_SELF) == -2) // save all remaining points
  1163.             {
  1164.                 SetLocalInt(OBJECT_SELF, "SavedSkillPoints", nPoints);
  1165.                 nPoints = 0;    
  1166.             }
  1167.             else // chosen a skill to increase
  1168.             {
  1169.                 // get the cls_skill_*** 2da to use
  1170.                 string sFile = Get2DACache("classes", "SkillsTable", GetLocalInt(OBJECT_SELF, "Class"));
  1171.                 // work out what line in skills.2da it corresponds to
  1172.                 int nSkillIndex = StringToInt(Get2DAString(sFile, "SkillIndex", nChoice));
  1173.                 //increase the points in that skill
  1174.                 // the array index is the line number in skills.2da
  1175.                 array_set_int(OBJECT_SELF, "Skills", nSkillIndex,
  1176.                     array_get_int(OBJECT_SELF, "Skills", nSkillIndex)+1);
  1177.                 //decrease points remaining
  1178.                 // see if it's class or cross-class
  1179.                 int nClassSkill = StringToInt(Get2DAString(sFile, "ClassSkill", nChoice));
  1180.                 if (nClassSkill) // class skill
  1181.                     nPoints -= 1;
  1182.                 else // cross class skill
  1183.                     nPoints -= 2;
  1184.             }
  1185.             // store new points total
  1186.             SetLocalInt(OBJECT_SELF, "Points", nPoints);
  1187.             if (nPoints) // still some left to allocate
  1188.             {
  1189.                 // Store offset so that if the user decides not to take the power,
  1190.                 // we can return to the same page in the power list instead of resetting to the beginning
  1191.                 // Store the value +1 in order to be able to differentiate between offset 0 and undefined
  1192.                 SetLocalInt(OBJECT_SELF, "SkillListChoiceOffset", GetLocalInt(OBJECT_SELF, DYNCONV_CHOICEOFFSET) + 1);
  1193.                 ClearCurrentStage();
  1194.             }
  1195.             else
  1196.                 nStage++;
  1197.             break;
  1198.         }
  1199.         case STAGE_SKILL_CHECK: {
  1200.             if (nChoice == 1)
  1201.                 nStage++;
  1202.             else
  1203.             {
  1204.                 nStage = STAGE_SKILL;
  1205.                 MarkStageNotSetUp(STAGE_SKILL_CHECK, OBJECT_SELF);
  1206.                 MarkStageNotSetUp(STAGE_SKILL, OBJECT_SELF);
  1207.                 DeleteLocalInt(OBJECT_SELF, "SavedSkillPoints");
  1208.                 DeleteLocalInt(OBJECT_SELF, "Points");
  1209.                 array_delete(OBJECT_SELF, "Skills");
  1210.             }
  1211.             break;
  1212.         }
  1213.         case STAGE_FEAT: {
  1214.             int nArraySize = array_get_size(OBJECT_SELF, "Feats");
  1215.             // alertness fix
  1216.             if (nChoice == 0)
  1217.                 nChoice = -1;
  1218.             // add the feat chosen to the feat array
  1219.             array_set_int(OBJECT_SELF, "Feats", array_get_size(OBJECT_SELF, "Feats"), nChoice);
  1220.             nStage++;
  1221.             break;
  1222.         }
  1223.         case STAGE_FEAT_CHECK: {
  1224.             if (nChoice == 1)
  1225.             {
  1226.                 // delete the stored convo choice list
  1227.                 ClearCachedChoices();
  1228.                 // decrement the number of feats left to pick
  1229.                 int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points");
  1230.                 --nFeatsRemaining;
  1231.                 // check new number of feats left
  1232.                 if (nFeatsRemaining == 0)
  1233.                 {
  1234.                     // no more feats left to pick
  1235.                     // if there's a bonus feat to pick, go to next stage
  1236.                     nFeatsRemaining = StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable",
  1237.                         GetLocalInt(OBJECT_SELF, "Class")), "Bonus", 0));
  1238.                     if (nFeatsRemaining)
  1239.                     {
  1240.                         // go to bonus feat stage
  1241.                         nStage = STAGE_BONUS_FEAT;
  1242.                     }
  1243.                     else
  1244.                     {
  1245.                         // go to next stage after that the PC qualifies for
  1246.                         nStage = GetNextCCCStage(nStage);
  1247.                     }
  1248.                 }
  1249.                 else
  1250.                 {
  1251.                     // go back to feat stage to pick next feat
  1252.                     nStage = STAGE_FEAT;
  1253.                     MarkStageNotSetUp(STAGE_FEAT_CHECK, OBJECT_SELF);
  1254.                     MarkStageNotSetUp(STAGE_FEAT, OBJECT_SELF);
  1255.                 }
  1256.                 SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining);
  1257.             }
  1258.             else
  1259.             {
  1260.                 nStage = STAGE_FEAT;
  1261.                 MarkStageNotSetUp(STAGE_FEAT_CHECK, OBJECT_SELF);
  1262.                 MarkStageNotSetUp(STAGE_FEAT, OBJECT_SELF);
  1263.                 // delete the chosen feat
  1264.                 if(array_shrink(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)) != SDL_SUCCESS)
  1265.                     DoDebug("No feats array!");
  1266.             }
  1267.             break;
  1268.         }
  1269.         case STAGE_BONUS_FEAT: {
  1270.             int nArraySize = array_get_size(OBJECT_SELF, "Feats");
  1271.             // alertness fix
  1272.             if (nChoice == 0)
  1273.                 nChoice = -1;
  1274.             // add the feat chosen to the feat array
  1275.             array_set_int(OBJECT_SELF, "Feats", array_get_size(OBJECT_SELF, "Feats"), nChoice);
  1276.             nStage++;
  1277.             break;
  1278.         }
  1279.         case STAGE_BONUS_FEAT_CHECK: {
  1280.             if (nChoice == 1)
  1281.             {
  1282.                 // delete the stored convo choice list
  1283.                 ClearCachedChoices();
  1284.                 // decrement the number of feats left to pick
  1285.                 int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points");
  1286.                 --nFeatsRemaining;
  1287.                 // check new number of feats left
  1288.                 if (nFeatsRemaining == 0)
  1289.                 {
  1290.                     // no more feats left to pick
  1291.                     // tidy up locals
  1292.                     DeleteLocalInt(OBJECT_SELF, "bHasAnimalEmpathy");
  1293.                     DeleteLocalInt(OBJECT_SELF, "bHasUMD");
  1294.                     // go to next stage after that the PC qualifies for
  1295.                     nStage = GetNextCCCStage(nStage);
  1296.                 }
  1297.                 else
  1298.                 {
  1299.                     // go back to feat stage to pick next feat
  1300.                     nStage = STAGE_BONUS_FEAT;
  1301.                     MarkStageNotSetUp(STAGE_BONUS_FEAT_CHECK, OBJECT_SELF);
  1302.                     MarkStageNotSetUp(STAGE_BONUS_FEAT, OBJECT_SELF);
  1303.                 }
  1304.                 SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining);
  1305.             }
  1306.             else
  1307.             {
  1308.                 nStage = STAGE_BONUS_FEAT;
  1309.                 MarkStageNotSetUp(STAGE_BONUS_FEAT_CHECK, OBJECT_SELF);
  1310.                 MarkStageNotSetUp(STAGE_BONUS_FEAT, OBJECT_SELF);
  1311.                 // delete the chosen feat
  1312.                 if(array_shrink(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)) != SDL_SUCCESS)
  1313.                     DoDebug("No feats array!");
  1314.             }
  1315.             break;
  1316.         }
  1317.         case STAGE_WIZ_SCHOOL: {
  1318.             SetLocalInt(OBJECT_SELF, "School", GetChoice());
  1319.             nStage++;
  1320.             break;
  1321.         }
  1322.         case STAGE_WIZ_SCHOOL_CHECK: {
  1323.             if(nChoice == 1)
  1324.             {
  1325.                 // go to next stage after that the PC qualifies for
  1326.                 nStage = GetNextCCCStage(nStage);
  1327.                 // add cantrips - wizards know all of them so don't need to choose
  1328.                 SetWizCantrips(GetLocalInt(OBJECT_SELF, "School"));
  1329.             }
  1330.             else // go back and pick the school again
  1331.             {
  1332.                 nStage = STAGE_WIZ_SCHOOL;
  1333.                 MarkStageNotSetUp(STAGE_WIZ_SCHOOL_CHECK, OBJECT_SELF);
  1334.                 MarkStageNotSetUp(STAGE_WIZ_SCHOOL, OBJECT_SELF);
  1335.                 DeleteLocalInt(OBJECT_SELF, "School");
  1336.             }
  1337.             break;
  1338.         }
  1339.         case STAGE_SPELLS_0: {
  1340.             // create the array first time through
  1341.             if (!array_exists(OBJECT_SELF, "SpellLvl0"))
  1342.                 array_create(OBJECT_SELF, "SpellLvl0");
  1343.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  1344.             // add the choice to the spells known array
  1345.             array_set_int(OBJECT_SELF, "SpellLvl0", array_get_size(OBJECT_SELF, "SpellLvl0"), nChoice);
  1346.             // decrement the number of spells left to select
  1347.             SetLocalInt(OBJECT_SELF, "Points", --nPoints);
  1348.             if (nPoints) // still some left to allocate
  1349.                 ClearCurrentStage();
  1350.             else // go to next stage after that the PC qualifies for
  1351.                 nStage = GetNextCCCStage(nStage);
  1352.             break;
  1353.         }
  1354.         case STAGE_SPELLS_1: {
  1355.             // create the array first time through
  1356.             if (!array_exists(OBJECT_SELF, "SpellLvl1"))
  1357.                 array_create(OBJECT_SELF, "SpellLvl1");
  1358.             int nPoints = GetLocalInt(OBJECT_SELF, "Points");
  1359.             // add the choice to the spells known array
  1360.             array_set_int(OBJECT_SELF, "SpellLvl1", array_get_size(OBJECT_SELF, "SpellLvl1"), nChoice);
  1361.             // decrement the number of spells left to select
  1362.             SetLocalInt(OBJECT_SELF, "Points", --nPoints);
  1363.             if (nPoints) // still some left to allocate
  1364.                 ClearCurrentStage();
  1365.             else // go to next stage after that the PC qualifies for
  1366.                 nStage = GetNextCCCStage(nStage);
  1367.             break;
  1368.         }
  1369.         case STAGE_SPELLS_CHECK: {
  1370.             if(nChoice == 1)
  1371.             {
  1372.                 // go to next stage after that the PC qualifies for
  1373.                 nStage = GetNextCCCStage(nStage);
  1374.                 int nClass = GetLocalInt(OBJECT_SELF, "Class");
  1375.                 // get the cls_spgn_***2da to use
  1376.                 string sSpgn = Get2DACache("classes", "SpellGainTable", nClass);
  1377.                 int nSpellsPerDay;
  1378.                 // level 1 spells
  1379.                 if (array_exists(OBJECT_SELF, "SpellLvl1"))
  1380.                 {
  1381.                     nSpellsPerDay = StringToInt(Get2DACache(sSpgn, "SpellLevel1", 0));
  1382.                     SetLocalInt(OBJECT_SELF, "SpellsPerDay1", nSpellsPerDay);
  1383.                 }
  1384.                 // cantrips
  1385.                 if (array_exists(OBJECT_SELF, "SpellLvl0"))
  1386.                 {
  1387.                     nSpellsPerDay = StringToInt(Get2DACache(sSpgn, "SpellLevel0", 0));
  1388.                     SetLocalInt(OBJECT_SELF, "SpellsPerDay0", nSpellsPerDay);
  1389.                 }
  1390.             }
  1391.             else // go back and pick the spells again
  1392.             {
  1393.                 // hacky...but returns the right stage, depending on the class
  1394.                 nStage = GetNextCCCStage(STAGE_WIZ_SCHOOL_CHECK);
  1395.                 MarkStageNotSetUp(STAGE_SPELLS_CHECK, OBJECT_SELF);
  1396.                 MarkStageNotSetUp(STAGE_SPELLS_1, OBJECT_SELF);
  1397.                 MarkStageNotSetUp(STAGE_SPELLS_0, OBJECT_SELF);
  1398.                 DeleteLocalInt(OBJECT_SELF, "Points");
  1399.                 array_delete(OBJECT_SELF, "SpellLvl1");
  1400.                 if(nStage == STAGE_SPELLS_0)
  1401.                 {
  1402.                     // if the new value of nStage takes us back to picking cantrips,
  1403.                     // then also delete the level 0 array
  1404.                     array_delete(OBJECT_SELF, "SpellLvl0");
  1405.                 }
  1406.             }
  1407.             break;
  1408.         }
  1409.         case STAGE_FAMILIAR: {
  1410.             if(GetLocalInt(OBJECT_SELF, "Class") == CLASS_TYPE_DRUID)
  1411.                 SetLocalInt(OBJECT_SELF, "Companion", nChoice);
  1412.             else // sorc or wiz
  1413.                 SetLocalInt(OBJECT_SELF, "Familiar", nChoice);
  1414.             nStage++;
  1415.             break;
  1416.         }
  1417.         case STAGE_FAMILIAR_CHECK: {
  1418.             if (nChoice == 1)
  1419.                 nStage = GetNextCCCStage(nStage);
  1420.             else
  1421.             {
  1422.                 nStage = STAGE_FAMILIAR;
  1423.                 MarkStageNotSetUp(STAGE_FAMILIAR_CHECK, OBJECT_SELF);
  1424.                 MarkStageNotSetUp(STAGE_FAMILIAR, OBJECT_SELF);
  1425.                 DeleteLocalInt(OBJECT_SELF, "Familiar");
  1426.                 DeleteLocalInt(OBJECT_SELF, "Companion");
  1427.             }
  1428.             break;
  1429.         }
  1430.         case STAGE_DOMAIN: {
  1431.             // if this is the first domain chosen
  1432.             if (GetLocalInt(OBJECT_SELF, "Domain1") == 0)
  1433.             {
  1434.                 // fix for air domain being 0
  1435.                 if (nChoice == 0)
  1436.                     nChoice = -1;
  1437.                 SetLocalInt(OBJECT_SELF, "Domain1", nChoice);
  1438.                 nStage = STAGE_DOMAIN_CHECK1;
  1439.             }
  1440.             else // second domain
  1441.             {
  1442.                 // fix for air domain being 0
  1443.                 if (nChoice == 0)
  1444.                     nChoice = -1;
  1445.                 SetLocalInt(OBJECT_SELF, "Domain2", nChoice);
  1446.                 nStage = STAGE_DOMAIN_CHECK2;
  1447.             }    
  1448.             break;
  1449.         }
  1450.         case STAGE_DOMAIN_CHECK1: {
  1451.             if (nChoice == 1)
  1452.             {
  1453.                 nStage = STAGE_DOMAIN;
  1454.                 MarkStageNotSetUp(STAGE_DOMAIN_CHECK1);
  1455.                 MarkStageNotSetUp(STAGE_DOMAIN);
  1456.             }
  1457.             else
  1458.             {
  1459.                 nStage = STAGE_DOMAIN;
  1460.                 MarkStageNotSetUp(STAGE_DOMAIN_CHECK1);
  1461.                 MarkStageNotSetUp(STAGE_DOMAIN);
  1462.                 DeleteLocalInt(OBJECT_SELF,"Domain1");
  1463.                 DeleteLocalInt(OBJECT_SELF,"Domain2");
  1464.             }
  1465.             break;
  1466.         }
  1467.         case STAGE_DOMAIN_CHECK2: {
  1468.             if (nChoice == 1)
  1469.             {
  1470.                 nStage++;
  1471.                 // add domain feats
  1472.                 AddDomainFeats();
  1473.             }
  1474.             else
  1475.             {
  1476.                 nStage = STAGE_DOMAIN;
  1477.                 MarkStageNotSetUp(STAGE_DOMAIN_CHECK2);
  1478.                 MarkStageNotSetUp(STAGE_DOMAIN);
  1479.                 DeleteLocalInt(OBJECT_SELF,"Domain1");
  1480.                 DeleteLocalInt(OBJECT_SELF,"Domain2");
  1481.             }
  1482.             break;
  1483.         }
  1484.         case STAGE_APPEARANCE: {
  1485.             if (nChoice == -1) // no change
  1486.             {
  1487.                 SetLocalInt(OBJECT_SELF, "Appearance", GetAppearanceType(OBJECT_SELF));
  1488.                 nStage = STAGE_PORTRAIT;
  1489.             }
  1490.             else
  1491.             {
  1492.                 SetLocalInt(OBJECT_SELF, "Appearance", nChoice);
  1493.                 SetCreatureAppearanceType(OBJECT_SELF, nChoice);
  1494.                 // change the appearance
  1495.                 DoCutscene(OBJECT_SELF);
  1496.                 nStage++;
  1497.             }
  1498.             break;
  1499.         }
  1500.         case STAGE_APPEARANCE_CHECK: {
  1501.             if (nChoice == 1)
  1502.             {
  1503.                 nStage++;
  1504.             }
  1505.             else
  1506.             {
  1507.                 nStage = STAGE_APPEARANCE;
  1508.                 MarkStageNotSetUp(STAGE_APPEARANCE_CHECK, OBJECT_SELF);
  1509.                 MarkStageNotSetUp(STAGE_APPEARANCE, OBJECT_SELF);
  1510.                 DeleteLocalInt(OBJECT_SELF, "Appearance");
  1511.             }
  1512.             break;
  1513.         }
  1514.         case STAGE_PORTRAIT: {
  1515.             if (nChoice == -1) // no change
  1516.             {
  1517.                 nStage = STAGE_SOUNDSET;
  1518.             }
  1519.             else
  1520.             {
  1521.                 // change the portrait
  1522.                 SetPortraitId(OBJECT_SELF, nChoice);
  1523.                 // change the clone's portrait
  1524.                 object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1525.                 SetPortraitId(oClone, nChoice);
  1526.                 nStage++;
  1527.             }
  1528.             break;
  1529.         }
  1530.         case STAGE_PORTRAIT_CHECK: {
  1531.             if (nChoice == 2)
  1532.             {
  1533.                 object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1534.                 ActionExamine(oClone);
  1535.                 // DelayCommand(1.0, ActionExamine(oClone));
  1536.                 // DelayCommand(2.0, ActionExamine(oClone));
  1537.             }
  1538.             else if (nChoice == 1)
  1539.             {
  1540.                 nStage++;
  1541.             }
  1542.             else
  1543.             {
  1544.                 nStage = STAGE_PORTRAIT;
  1545.                 MarkStageNotSetUp(STAGE_PORTRAIT_CHECK, OBJECT_SELF);
  1546.                 MarkStageNotSetUp(STAGE_PORTRAIT, OBJECT_SELF);
  1547.             }
  1548.             break;
  1549.         }
  1550.         case STAGE_SOUNDSET: {
  1551.             if (nChoice == -1) // no change
  1552.             {
  1553.                 SetLocalInt(OBJECT_SELF, "Soundset", nChoice);
  1554.                 nStage = GetNextCCCStage(nStage, FALSE);
  1555.             }
  1556.             else
  1557.             {
  1558.                 // store the choice
  1559.                 SetLocalInt(OBJECT_SELF, "Soundset", nChoice);
  1560.                 // modify the clone
  1561.                 DoCutscene(OBJECT_SELF);
  1562.                 nStage++;
  1563.             }
  1564.             break;
  1565.         }
  1566.         case STAGE_SOUNDSET_CHECK: {
  1567.             if (nChoice == 2)
  1568.             {
  1569.                 object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1570.                 PlayVoiceChat(0 , oClone);
  1571.             }
  1572.             else if (nChoice == 1)
  1573.             {
  1574.                 // set up colour defaults here to make sure they don't reset for non-player type appearances
  1575.                 SetLocalInt(OBJECT_SELF, "Skin", -1);
  1576.                 SetLocalInt(OBJECT_SELF, "Hair", -1);
  1577.                 SetLocalInt(OBJECT_SELF, "TattooColour1", -1);
  1578.                 SetLocalInt(OBJECT_SELF, "TattooColour2", -1);
  1579.                 nStage = GetNextCCCStage(nStage, FALSE);
  1580.             }
  1581.             else
  1582.             {
  1583.                 nStage = STAGE_SOUNDSET;
  1584.                 MarkStageNotSetUp(STAGE_SOUNDSET_CHECK, OBJECT_SELF);
  1585.                 MarkStageNotSetUp(STAGE_SOUNDSET, OBJECT_SELF);
  1586.                 DeleteLocalInt(OBJECT_SELF, "Soundset");
  1587.             }
  1588.             break;
  1589.         }
  1590.         case STAGE_HEAD: {
  1591.             if (nChoice == -1) // no change
  1592.             {
  1593.                 nStage = GetNextCCCStage(nStage, FALSE);
  1594.             }
  1595.             else
  1596.             {
  1597.                 // change the head
  1598.                 SetCreatureBodyPart(CREATURE_PART_HEAD, nChoice);
  1599.                 // modify the clone's head
  1600.                 object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1601.                 SetCreatureBodyPart(CREATURE_PART_HEAD, nChoice, oClone);
  1602.                 nStage++;
  1603.             }
  1604.             break;
  1605.         }
  1606.         case STAGE_HEAD_CHECK: {
  1607.             if (nChoice == 1)
  1608.             {
  1609.                 nStage = GetNextCCCStage(nStage, FALSE);
  1610.             }
  1611.             else
  1612.             {
  1613.                 nStage = STAGE_HEAD;
  1614.                 MarkStageNotSetUp(STAGE_HEAD_CHECK, OBJECT_SELF);
  1615.                 MarkStageNotSetUp(STAGE_HEAD, OBJECT_SELF);
  1616.             }
  1617.             break;
  1618.         }
  1619.         case STAGE_TATTOO: {
  1620.             if (nChoice == -1) // no change
  1621.             {
  1622.                 nStage = GetNextCCCStage(nStage, FALSE);
  1623.             }
  1624.             else
  1625.             {
  1626.                 int nTattooed = GetCreatureBodyPart(nChoice, OBJECT_SELF);
  1627.                 if(nTattooed == 1)
  1628.                     nTattooed = 2;
  1629.                 else if(nTattooed == 2)
  1630.                     nTattooed = 1;
  1631.                 // change the tattoo on the clone
  1632.                 SetCreatureBodyPart(nChoice, nTattooed,
  1633.                     GetLocalObject(OBJECT_SELF, "Clone"));
  1634.                 // change the tattoo on the PC
  1635.                 SetCreatureBodyPart(nChoice, nTattooed);
  1636.             }
  1637.             break;
  1638.         }
  1639.         case STAGE_TATTOO_CHECK: {
  1640.             if (nChoice == 1)
  1641.             {
  1642.                 nStage = GetNextCCCStage(nStage, FALSE);
  1643.             }
  1644.             else
  1645.             {
  1646.                 nStage = STAGE_TATTOO;
  1647.                 MarkStageNotSetUp(STAGE_TATTOO_CHECK, OBJECT_SELF);
  1648.                 MarkStageNotSetUp(STAGE_TATTOO, OBJECT_SELF);
  1649.             }
  1650.             break;
  1651.         }
  1652.         case STAGE_WINGS: {
  1653.             SetCreatureWingType(nChoice);
  1654.             // alter the clone
  1655.             object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1656.             SetCreatureWingType(nChoice, oClone);
  1657.             nStage++;
  1658.             break;
  1659.         }
  1660.         case STAGE_WINGS_CHECK: {
  1661.             if (nChoice == 1)
  1662.             {
  1663.                 nStage = GetNextCCCStage(nStage, FALSE);
  1664.             }
  1665.             else
  1666.             {
  1667.                 nStage = STAGE_WINGS;
  1668.                 MarkStageNotSetUp(STAGE_WINGS_CHECK, OBJECT_SELF);
  1669.                 MarkStageNotSetUp(STAGE_WINGS, OBJECT_SELF);
  1670.             }
  1671.             break;
  1672.         }
  1673.         case STAGE_TAIL: {
  1674.             SetCreatureTailType(nChoice);
  1675.             // alter the clone
  1676.             object oClone = GetLocalObject(OBJECT_SELF, "Clone");
  1677.             SetCreatureTailType(nChoice, oClone);
  1678.             nStage++;
  1679.             break;
  1680.         }
  1681.         case STAGE_TAIL_CHECK: {
  1682.             if (nChoice == 1)
  1683.             {
  1684.                 nStage = GetNextCCCStage(nStage, FALSE);
  1685.             }
  1686.             else
  1687.             {
  1688.                 nStage = STAGE_TAIL;
  1689.                 MarkStageNotSetUp(STAGE_TAIL_CHECK, OBJECT_SELF);
  1690.                 MarkStageNotSetUp(STAGE_TAIL, OBJECT_SELF);
  1691.             }
  1692.             break;
  1693.         }
  1694.         case STAGE_SKIN_COLOUR: {
  1695.             if (nChoice == -1) // keep existing
  1696.             {
  1697.                 nStage = STAGE_SKIN_COLOUR_CHECK;
  1698.                 SetLocalInt(OBJECT_SELF, "Skin", -1);
  1699.             }
  1700.             else
  1701.             {
  1702.                 SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice);
  1703.                 nStage++;
  1704.             }
  1705.             break;
  1706.         }
  1707.         case STAGE_SKIN_COLOUR_CHOICE: {
  1708.             SetLocalInt(OBJECT_SELF, "Skin", nChoice);
  1709.             // change the clone
  1710.             DoCutscene(OBJECT_SELF);
  1711.             nStage++;
  1712.             break;
  1713.         }
  1714.         case STAGE_SKIN_COLOUR_CHECK: {
  1715.             if (nChoice == 1)
  1716.             {
  1717.                 nStage++;
  1718.             }
  1719.             else
  1720.             {
  1721.                 nStage = STAGE_SKIN_COLOUR;
  1722.                 MarkStageNotSetUp(STAGE_SKIN_COLOUR_CHECK, OBJECT_SELF);
  1723.                 MarkStageNotSetUp(STAGE_SKIN_COLOUR_CHOICE, OBJECT_SELF);
  1724.                 MarkStageNotSetUp(STAGE_SKIN_COLOUR, OBJECT_SELF);
  1725.                 DeleteLocalInt(OBJECT_SELF, "Skin");
  1726.             }
  1727.             DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  1728.             break;
  1729.         }
  1730.         case STAGE_HAIR_COLOUR: {
  1731.             if (nChoice == -1) // keep existing
  1732.             {
  1733.                 nStage = STAGE_HAIR_COLOUR_CHECK;
  1734.                 SetLocalInt(OBJECT_SELF, "Hair", -1);
  1735.             }
  1736.             else
  1737.             {
  1738.                 SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice);
  1739.                 nStage++;
  1740.             }
  1741.             break;
  1742.         }
  1743.         case STAGE_HAIR_COLOUR_CHOICE: {
  1744.             SetLocalInt(OBJECT_SELF, "Hair", nChoice);
  1745.             // change the clone
  1746.             DoCutscene(OBJECT_SELF);
  1747.             nStage++;
  1748.             break;
  1749.         }
  1750.         case STAGE_HAIR_COLOUR_CHECK: {
  1751.             if (nChoice == 1)
  1752.             {
  1753.                 nStage++;
  1754.             }
  1755.             else
  1756.             {
  1757.                 nStage = STAGE_HAIR_COLOUR;
  1758.                 MarkStageNotSetUp(STAGE_HAIR_COLOUR_CHECK, OBJECT_SELF);
  1759.                 MarkStageNotSetUp(STAGE_HAIR_COLOUR_CHOICE, OBJECT_SELF);
  1760.                 MarkStageNotSetUp(STAGE_HAIR_COLOUR, OBJECT_SELF);
  1761.                 DeleteLocalInt(OBJECT_SELF, "Hair");
  1762.             }
  1763.             DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  1764.             break;
  1765.         }
  1766.         case STAGE_TATTOO1_COLOUR: {
  1767.             if (nChoice == -1) // keep existing
  1768.             {
  1769.                 nStage = STAGE_TATTOO1_COLOUR_CHECK;
  1770.                 SetLocalInt(OBJECT_SELF, "TattooColour1", -1);
  1771.             }
  1772.             else
  1773.             {
  1774.                 SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice);
  1775.                 nStage++;
  1776.             }
  1777.             break;
  1778.         }
  1779.         case STAGE_TATTOO1_COLOUR_CHOICE: {
  1780.             SetLocalInt(OBJECT_SELF, "TattooColour1", nChoice);
  1781.             // change the clone
  1782.             DoCutscene(OBJECT_SELF);
  1783.             nStage++;
  1784.             break;
  1785.         }
  1786.         case STAGE_TATTOO1_COLOUR_CHECK: {
  1787.             if (nChoice == 1)
  1788.             {
  1789.                 nStage++;
  1790.             }
  1791.             else
  1792.             {
  1793.                 nStage = STAGE_TATTOO1_COLOUR;
  1794.                 MarkStageNotSetUp(STAGE_TATTOO1_COLOUR_CHECK, OBJECT_SELF);
  1795.                 MarkStageNotSetUp(STAGE_TATTOO1_COLOUR_CHOICE, OBJECT_SELF);
  1796.                 MarkStageNotSetUp(STAGE_TATTOO1_COLOUR, OBJECT_SELF);
  1797.                 DeleteLocalInt(OBJECT_SELF, "TattooColour1");
  1798.             }
  1799.             DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  1800.             break;
  1801.         }
  1802.         case STAGE_TATTOO2_COLOUR: {
  1803.             if (nChoice == -1) // keep existing
  1804.             {
  1805.                 nStage = STAGE_TATTOO2_COLOUR_CHECK;
  1806.                 SetLocalInt(OBJECT_SELF, "TattooColour2", -1);
  1807.             }
  1808.             else
  1809.             {
  1810.                 SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice);
  1811.                 nStage++;
  1812.             }
  1813.             break;
  1814.         }
  1815.         case STAGE_TATTOO2_COLOUR_CHOICE: {
  1816.             SetLocalInt(OBJECT_SELF, "TattooColour2", nChoice);
  1817.             // change the clone
  1818.             DoCutscene(OBJECT_SELF);
  1819.             nStage++;
  1820.             break;
  1821.         }
  1822.         case STAGE_TATTOO2_COLOUR_CHECK: {
  1823.             if (nChoice == 1)
  1824.             {
  1825.                 nStage = FINAL_STAGE;
  1826.             }
  1827.             else
  1828.             {
  1829.                 nStage = STAGE_TATTOO2_COLOUR;
  1830.                 MarkStageNotSetUp(STAGE_TATTOO2_COLOUR_CHECK, OBJECT_SELF);
  1831.                 MarkStageNotSetUp(STAGE_TATTOO2_COLOUR_CHOICE, OBJECT_SELF);
  1832.                 MarkStageNotSetUp(STAGE_TATTOO2_COLOUR, OBJECT_SELF);
  1833.                 DeleteLocalInt(OBJECT_SELF, "TattooColour2");
  1834.             }
  1835.             DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED");
  1836.             break;
  1837.         }
  1838.         case FINAL_STAGE: {
  1839.             ExecuteScript("prc_ccc_make_pc", OBJECT_SELF);
  1840.             AllowExit(DYNCONV_EXIT_FORCE_EXIT);
  1841.             break;
  1842.         }
  1843.     }
  1844.     return nStage;
  1845. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement