#include "ccc_inc_misc" // sets up the header and the choices for each stage of the convoCC void DoHeaderAndChoices(int nStage); // processes the player choices for each stage of the convoCC int HandleChoice(int nStage, int nChoice); void DoHeaderAndChoices(int nStage) { string sText; string sName; int i = 0; // loop counter switch(nStage) { case STAGE_INTRODUCTION: { sText = "This is the PRC Conversation Character Creator (CCC).\n"; sText+= "This is a replicate of the bioware character creator, but it will allow you to select custom content at level 1. "; sText+= "Simply follow the step by step instructions and select what you want. "; sText+= "If you dont get all the options you think you should at a stage, select one, then select No at the confirmation step."; SetHeader(sText); // setup the choices AddChoice("continue", 0); MarkStageSetUp(nStage); break; } case STAGE_GENDER: { sText = GetStringByStrRef(158); SetHeader(sText); // set up the choices Do2daLoop("gender", "name", GetPRCSwitch(FILE_END_GENDER)); MarkStageSetUp(nStage); break; } case STAGE_GENDER_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: sText+= GetStringByStrRef(StringToInt(Get2DACache("gender", "NAME", GetLocalInt(OBJECT_SELF, "Gender")))); sText+= "\n"+GetStringByStrRef(16824210); SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_RACE: { sText = GetStringByStrRef(162); // Select a Race for your Character SetHeader(sText); // set up choices // try with waiting set up first SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); DelayCommand(0.01, DoRacialtypesLoop()); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_RACE_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: sText += GetStringByStrRef(StringToInt(Get2DACache("racialtypes", "Name", GetLocalInt(OBJECT_SELF, "Race")))); sText += "\n"; sText+= GetStringByStrRef(StringToInt(Get2DACache("racialtypes", "Description", GetLocalInt(OBJECT_SELF, "Race")))); sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_CLASS: { sText = GetStringByStrRef(61920); // Select a Class for Your Character SetHeader(sText); // set up choices SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); DelayCommand(0.01, DoClassesLoop()); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_CLASS_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: sText += GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", GetLocalInt(OBJECT_SELF, "Class")))); sText += "\n"; sText+= GetStringByStrRef(StringToInt(Get2DACache("classes", "Description", GetLocalInt(OBJECT_SELF, "Class")))); sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_ALIGNMENT: { sText = GetStringByStrRef(111); // Select an Alignment for your Character SetHeader(sText); // get the restriction info from classes.2da SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); int nClass = GetLocalInt(OBJECT_SELF, "Class"); int iAlignRestrict = HexToInt(Get2DACache("classes", "AlignRestrict",nClass)); int iAlignRstrctType = HexToInt(Get2DACache("classes", "AlignRstrctType",nClass)); int iInvertRestrict = HexToInt(Get2DACache("classes", "InvertRestrict",nClass)); // set up choices if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(112), 112); if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(115), 115); if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_GOOD,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(118), 118); if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(113), 113); if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(116), 116); if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_NEUTRAL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(119), 119); if(GetIsValidAlignment(ALIGNMENT_LAWFUL, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(114), 114); if(GetIsValidAlignment(ALIGNMENT_NEUTRAL, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(117), 117); if(GetIsValidAlignment(ALIGNMENT_CHAOTIC, ALIGNMENT_EVIL,iAlignRestrict, iAlignRstrctType, iInvertRestrict)) AddChoice(GetStringByStrRef(120), 120); DelayCommand(0.01, DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting")); MarkStageSetUp(nStage); break; } case STAGE_ALIGNMENT_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nStrRef = GetLocalInt(OBJECT_SELF, "AlignChoice"); // strref for the alignment sText += GetStringByStrRef(nStrRef); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_ABILITY: { // the first time through this stage set everything up if(GetLocalInt(OBJECT_SELF, "Str") == 0) { // get the starting points to allocate int nPoints = GetPRCSwitch(PRC_CONVOCC_STAT_POINTS); if(nPoints == 0) nPoints = 30; // default SetLocalInt(OBJECT_SELF, "Points", nPoints); // get the max stat level (before racial modifiers) int nMaxStat = GetPRCSwitch(PRC_CONVOCC_MAX_STAT); if(nMaxStat == 0) nMaxStat = 18; // default SetLocalInt(OBJECT_SELF, "MaxStat", nMaxStat); // set the starting stat values SetLocalInt(OBJECT_SELF, "Str", 8); SetLocalInt(OBJECT_SELF, "Dex", 8); SetLocalInt(OBJECT_SELF, "Con", 8); SetLocalInt(OBJECT_SELF, "Int", 8); SetLocalInt(OBJECT_SELF, "Wis", 8); SetLocalInt(OBJECT_SELF, "Cha", 8); } sText = GetStringByStrRef(130) + "\n"; // Select Ability Scores for your Character sText += GetStringByStrRef(138) + ": "; // Remaining Points sText += IntToString(GetLocalInt(OBJECT_SELF, "Points")); SetHeader(sText); // get the racial adjustment int nRace = GetLocalInt(OBJECT_SELF, "Race"); string sStrAdjust = Get2DACache("racialtypes", "StrAdjust", nRace); string sDexAdjust = Get2DACache("racialtypes", "DexAdjust", nRace); string sConAdjust = Get2DACache("racialtypes", "ConAdjust", nRace); string sIntAdjust = Get2DACache("racialtypes", "IntAdjust", nRace); string sWisAdjust = Get2DACache("racialtypes", "WisAdjust", nRace); string sChaAdjust = Get2DACache("racialtypes", "ChaAdjust", nRace); // set up the choices in " (racial <+/-modifier>) . Cost to increase " format AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Str"), GetStringByStrRef(135), sStrAdjust, ABILITY_STRENGTH); AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Dex"), GetStringByStrRef(133), sDexAdjust, ABILITY_DEXTERITY); AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Con"), GetStringByStrRef(132), sConAdjust, ABILITY_CONSTITUTION); AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Int"), GetStringByStrRef(134), sIntAdjust, ABILITY_INTELLIGENCE); AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Wis"), GetStringByStrRef(136), sWisAdjust, ABILITY_WISDOM); AddAbilityChoice(GetLocalInt(OBJECT_SELF, "Cha"), GetStringByStrRef(131), sChaAdjust, ABILITY_CHARISMA); MarkStageSetUp(nStage); break; } case STAGE_ABILITY_CHECK: { sText = GetStringByStrRef(16824209) + "\n"; // You have selected: // get the racial adjustment int nRace = GetLocalInt(OBJECT_SELF, "Race"); string sStrAdjust = Get2DACache("racialtypes", "StrAdjust", nRace); string sDexAdjust = Get2DACache("racialtypes", "DexAdjust", nRace); string sConAdjust = Get2DACache("racialtypes", "ConAdjust", nRace); string sIntAdjust = Get2DACache("racialtypes", "IntAdjust", nRace); string sWisAdjust = Get2DACache("racialtypes", "WisAdjust", nRace); string sChaAdjust = Get2DACache("racialtypes", "ChaAdjust", nRace); sText += GetStringByStrRef(135) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Str") + StringToInt(sStrAdjust)) + "\n"; // str sText += GetStringByStrRef(133) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Dex") + StringToInt(sDexAdjust)) + "\n"; // dex sText += GetStringByStrRef(132) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Con") + StringToInt(sConAdjust)) + "\n"; // con sText += GetStringByStrRef(134) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Int") + StringToInt(sIntAdjust)) + "\n"; // int sText += GetStringByStrRef(136) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Wis") + StringToInt(sWisAdjust)) + "\n"; // wis sText += GetStringByStrRef(131) + ": " + IntToString(GetLocalInt(OBJECT_SELF, "Cha") + StringToInt(sChaAdjust)) + "\n"; // cha sText += "\n" + GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_SKILL: { // the first time through this stage set everything up int nPoints = GetLocalInt(OBJECT_SELF, "Points"); if(nPoints == 0) { SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); //calculate number of points nPoints += StringToInt(Get2DACache("classes", "SkillPointBase", GetLocalInt(OBJECT_SELF, "Class"))); // calculate the intelligence bonus/penalty int nInt = GetLocalInt(OBJECT_SELF, "Int"); int nRace = GetLocalInt(OBJECT_SELF, "Race"); nPoints += (nInt-10+StringToInt(Get2DACache("racialtypes", "IntAdjust", nRace)))/2; if(GetPRCSwitch(PRC_CONVOCC_SKILL_MULTIPLIER)) nPoints *= GetPRCSwitch(PRC_CONVOCC_SKILL_MULTIPLIER); else nPoints *= 4; // humans get an extra 4 skill points at level 1 if (GetLocalInt(OBJECT_SELF, "Race") == RACIAL_TYPE_HUMAN) nPoints += 4; nPoints += GetPRCSwitch(PRC_CONVOCC_SKILL_BONUS); // minimum of 4, regardless of int if(nPoints < 4) nPoints = 4; SetLocalInt(OBJECT_SELF, "Points", nPoints); DelayCommand(0.01, DoSkillsLoop()); } else DoSkillsLoop(); // do header sText = GetStringByStrRef(396) + "\n"; // Allocate skill points sText += GetStringByStrRef(395) + ": "; // Remaining Points sText += IntToString(GetLocalInt(OBJECT_SELF, "Points")); SetHeader(sText); /* Hack - Returning to the skill selection stage, restore the * offset to be the same as it was choosing the skill. */ if(GetLocalInt(OBJECT_SELF, "SkillListChoiceOffset")) { SetLocalInt(OBJECT_SELF, DYNCONV_CHOICEOFFSET, GetLocalInt(OBJECT_SELF, "SkillListChoiceOffset") - 1); DeleteLocalInt(OBJECT_SELF, "SkillListChoiceOffset"); } MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SKILL_CHECK: { sText = GetStringByStrRef(16824209) + "\n"; // You have selected: if(GetPRCSwitch(PRC_CONVOCC_ALLOW_SKILL_POINT_ROLLOVER)) { sText += "Stored skill points: "; sText += IntToString(GetLocalInt(OBJECT_SELF, "SavedSkillPoints")) + "\n"; } // loop through the "Skills" array for(i=0; i <= GetPRCSwitch(FILE_END_SKILLS); i++) // the array can't be bigger than the skills 2da { if(array_get_int(OBJECT_SELF, "Skills",i) != 0) // if there are points in the skill, add it to the header { sText+= GetStringByStrRef(StringToInt(Get2DACache("skills", "Name", i))); sText+= " "+IntToString(array_get_int(OBJECT_SELF, "Skills",i))+"\n"; } } sText += "\n" + GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_FEAT: { sText = GetStringByStrRef(397) + "\n"; // Select Feats sText += GetStringByStrRef(398) + ": "; // Feats remaining // if it's the first time through, work out the number of feats int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points"); if (!nFeatsRemaining) // first time through { nFeatsRemaining = 1; // always have at least 1 // check for quick to master nFeatsRemaining += GetLocalInt(OBJECT_SELF, "QTM"); // set how many times to go through this stage SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining); // mark skill focus feat prereq here so it's only done once // note: any other skill that is restricted to certain classes needs to be added here // and the local ints deleted in the STAGE_BONUS_FEAT_CHECK case of HandleChoice() // and it enforced in CheckSkillPrereq() // UMD and animal empathy are the only ones so far MarkSkillFocusPrereq(SKILL_ANIMAL_EMPATHY, "bHasAnimalEmpathy"); MarkSkillFocusPrereq(SKILL_USE_MAGIC_DEVICE, "bHasUMD"); } // check for bonus feat(s) from class - show the player the total feats // even though class bonuses are a different stage int nClass = GetLocalInt(OBJECT_SELF, "Class"); nFeatsRemaining += StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable", nClass), "Bonus", 0)); sText += IntToString(nFeatsRemaining); SetHeader(sText); // do feat list SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); if (array_exists(OBJECT_SELF, "CachedChoiceTokens")) { // add cached choices to convo AddChoicesFromCache(); DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting"); } else { DoFeatLoop(); } MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_FEAT_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: // get feat int nFeat = array_get_int(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)); // alertness fix if (nFeat == -1) nFeat = 0; sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))) + "\n"; // name sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "DESCRIPTION", nFeat))) + "\n"; // description sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_BONUS_FEAT: { sText = GetStringByStrRef(397) + "\n"; // Select Feats sText += GetStringByStrRef(398) + ": "; // Feats remaining int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points"); if (!nFeatsRemaining) // first time through { // check for bonus feat(s) from class int nClass = GetLocalInt(OBJECT_SELF, "Class"); nFeatsRemaining += StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable", nClass), "Bonus", 0)); // set how many times to go through this stage SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining); } sText += IntToString(nFeatsRemaining); SetHeader(sText); // do feat list SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); if (array_exists(OBJECT_SELF, "CachedChoiceTokens")) { // add cached choices to convo AddChoicesFromCache(); DeleteLocalInt(OBJECT_SELF, "DynConv_Waiting"); } else { DoBonusFeatLoop(); } MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_BONUS_FEAT_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: // get feat int nFeat = array_get_int(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)); sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "FEAT", nFeat))) + "\n"; // name sText += GetStringByStrRef(StringToInt(Get2DACache("feat", "DESCRIPTION", nFeat))) + "\n"; // description sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_WIZ_SCHOOL: { sText = GetStringByStrRef(381); // Select a School of Magic SetHeader(sText); // choices if(GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS)) { AddChoice(GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", 9))), 9); } else { for(i = 0; i < 9; i++) { AddChoice(GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", i))), i); } } MarkStageSetUp(nStage); break; } case STAGE_WIZ_SCHOOL_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: sText+= GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", GetLocalInt(OBJECT_SELF, "School")))); sText+= "\n\n"; sText+= GetStringByStrRef(StringToInt(Get2DACache("spellschools", "Description", GetLocalInt(OBJECT_SELF, "School")))); sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_SPELLS_0: { // if the first time through, set up the number of cantrips to pick int nPoints = GetLocalInt(OBJECT_SELF, "Points"); int nClass = GetLocalInt(OBJECT_SELF, "Class"); if(nPoints == 0) { // set up the number of spells to pick // get the cls_spkn_***2da to use string sSpkn = Get2DACache("classes", "SpellKnownTable", nClass); // set the number of spells to pick nPoints = StringToInt(Get2DACache(sSpkn, "SpellLevel0", 0)); SetLocalInt(OBJECT_SELF, "Points", nPoints); // don't want to be waiting every time SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); } sText = GetStringByStrRef(372) + "\n"; // Select Cantrips sText += GetStringByStrRef(371) + ": "; // Remaining Spells sText += IntToString(nPoints); SetHeader(sText); // choices, uses nStage to see if it's listing level 0 or level 1 spells DoSpellsLoop(nStage); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SPELLS_1: { // if the first time through, set up the number of spells to pick int nPoints = GetLocalInt(OBJECT_SELF, "Points"); int nClass = GetLocalInt(OBJECT_SELF, "Class"); if(nPoints == 0) { switch(nClass) { case CLASS_TYPE_WIZARD: { // spells to pick is 3 + int modifier int nIntMod = GetLocalInt(OBJECT_SELF, "Int"); nIntMod += StringToInt(Get2DACache("racialtypes", "IntAdjust", GetLocalInt(OBJECT_SELF, "Race"))); nIntMod = (nIntMod - 10)/2; nPoints = 3 + nIntMod; break; } case CLASS_TYPE_SORCERER: { // get the cls_spkn_***2da to use string sSpkn = Get2DACache("classes", "SpellKnownTable", nClass); // set the number of spells to pick nPoints = StringToInt(Get2DACache(sSpkn, "SpellLevel1", 0)); break; } } SetLocalInt(OBJECT_SELF, "Points", nPoints); // don't want to be waiting every time SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); } sText = GetStringByStrRef(368) + "\n"; // Select Spells for your Character sText += GetStringByStrRef(371) + ": "; // Remaining Spells sText += IntToString(GetLocalInt(OBJECT_SELF, "Points")); SetHeader(sText); // choices, uses nStage to see if it's listing level 0 or level 1 spells DoSpellsLoop(nStage); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SPELLS_CHECK: { sText = GetStringByStrRef(16824209) + "\n"; // You have selected: int spellID = 0; sText += GetStringByStrRef(691) + " - \n"; // Cantrips // loop through the spell choices for (i = 0; i < array_get_size(OBJECT_SELF, "SpellLvl0"); i++) { spellID = array_get_int(OBJECT_SELF, "SpellLvl0", i); sText+= GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellID))); sText += "\n"; } sText += GetStringByStrRef(61924) + " - \n"; // Level 1 Spells // loop through the spell choices for (i = 0; i < array_get_size(OBJECT_SELF, "SpellLvl1"); i++) { spellID = array_get_int(OBJECT_SELF, "SpellLvl1", i); sText+= GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", spellID))); sText += "\n"; } sText+= "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_FAMILIAR: { int nClass = GetLocalInt(OBJECT_SELF, "Class"); sText = GetStringByStrRef(5607) + "\n"; // Choose a Familiar for your Character sText += "(" + GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", nClass))) + ")"; SetHeader(sText); SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); // do choices if (nClass == CLASS_TYPE_DRUID) Do2daLoop("hen_companion", "strref", GetPRCSwitch(FILE_END_ANIMALCOMP)); else // wizard or sorc Do2daLoop("hen_familiar", "strref", GetPRCSwitch(FILE_END_FAMILIAR)); SetLocalInt(OBJECT_SELF, "DynConv_Waiting", FALSE); FloatingTextStringOnCreature("Done", OBJECT_SELF, FALSE); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_FAMILIAR_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: if (GetLocalInt(OBJECT_SELF, "Class") == CLASS_TYPE_DRUID) { int nCompanion = GetLocalInt(OBJECT_SELF, "Companion"); sText += GetStringByStrRef(StringToInt(Get2DACache("hen_companion", "STRREF", nCompanion))); sText += "\n"; sText += GetStringByStrRef(StringToInt(Get2DACache("hen_companion", "DESCRIPTION", nCompanion))); sText += "\n"; } else { int nFamiliar = GetLocalInt(OBJECT_SELF, "Familiar"); sText += GetStringByStrRef(StringToInt(Get2DACache("hen_familiar", "STRREF", nFamiliar))); sText += "\n"; sText += GetStringByStrRef(StringToInt(Get2DACache("hen_familiar", "DESCRIPTION", nFamiliar))); sText += "\n"; } sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_DOMAIN: { sText = GetStringByStrRef(5982); // Pick Cleric Domain SetHeader(sText); SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); // choices DoDomainsLoop(); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_DOMAIN_CHECK1: { sText = GetStringByStrRef(16824209) + "\n"; // You have selected: // first domain int nDomain = GetLocalInt(OBJECT_SELF,"Domain1"); // fix for air domain being 0 if (nDomain == -1) nDomain = 0; sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Name", nDomain))) + "\n"; sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Description", nDomain))) + "\n"; sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_DOMAIN_CHECK2: { sText = GetStringByStrRef(16824209) + "\n"; // You have selected: // second domain int nDomain = GetLocalInt(OBJECT_SELF,"Domain2"); // fix for air domain being 0 if (nDomain == -1) nDomain = 0; sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Name", nDomain))) + "\n"; sText += GetStringByStrRef(StringToInt(Get2DACache("domains", "Description", nDomain))) + "\n"; sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_APPEARANCE: { sText = GetStringByStrRef(124); // Select the Appearance of your Character SetHeader(sText); SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); if(GetPRCSwitch(PRC_CONVOCC_USE_RACIAL_APPEARANCES)) // restrict to what is given in the 2da SetupRacialAppearances(); else DoAppearanceLoop(); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_APPEARANCE_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nAppearance = GetLocalInt(OBJECT_SELF, "Appearance"); int nStrRef = StringToInt(Get2DACache("appearance", "STRING_REF", nAppearance)); if(nStrRef) sText += GetStringByStrRef(nStrRef); else sText += Get2DACache("appearance", "LABEL", nAppearance); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_PORTRAIT: { sText = GetStringByStrRef(7383); // Select a portrait SetHeader(sText); if(GetPRCSwitch(PRC_CONVOCC_ALLOW_TO_KEEP_PORTRAIT)) AddChoice("Keep existing portrait.", -1); // if(GetPRCSwitch(PRC_CONVOCC_USE_RACIAL_PORTRAIT)) SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); DoPortraitsLoop(); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_PORTRAIT_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nPortrait = GetPortraitId(OBJECT_SELF); sText += Get2DACache("portraits", "BaseResRef", nPortrait); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice("View this portrait.", 2); AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_SOUNDSET: { sText = GetStringByStrRef(7535); // Select a sound set SetHeader(sText); if(GetPRCSwitch(PRC_CONVOCC_ALLOW_TO_KEEP_VOICESET)) AddChoice("keep existing soundset.", -1); SetLocalInt(OBJECT_SELF, "DynConv_Waiting", TRUE); DoSoundsetLoop(); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SOUNDSET_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nSoundset = GetLocalInt(OBJECT_SELF, "Soundset"); sText += GetStringByStrRef(StringToInt(Get2DACache("soundset", "STRREF", nSoundset))); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice("Listen to this soundset.", 2); AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_HEAD: { sText = GetStringByStrRef(124); // Select the Appearance of your Character sText += "(" + GetStringByStrRef(123) + ")"; // Head SetHeader(sText); AddChoice("keep existing head", -1); SetupHeadChoices(); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_HEAD_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_TATTOO: { sText = GetStringByStrRef(124); // Select the Appearance of your Character sText += "(" + GetStringByStrRef(1591) + ")"; // Tattoo SetHeader(sText); AddChoice("keep current tatoos", -1); AddChoice("torso", CREATURE_PART_TORSO); AddChoice("right shin", CREATURE_PART_RIGHT_SHIN); AddChoice("left shin", CREATURE_PART_LEFT_SHIN); AddChoice("right thigh", CREATURE_PART_RIGHT_THIGH); AddChoice("left thigh", CREATURE_PART_LEFT_THIGH); AddChoice("right forearm", CREATURE_PART_RIGHT_FOREARM); AddChoice("left forearm", CREATURE_PART_LEFT_FOREARM); AddChoice("right bicep", CREATURE_PART_RIGHT_BICEP); AddChoice("left bicep", CREATURE_PART_LEFT_BICEP); MarkStageSetUp(nStage); break; } case STAGE_TATTOO_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_WINGS: { sText = GetStringByStrRef(124); // Select the Appearance of your Character sText += "(" + GetStringByStrRef(2409) + ")"; // Wings SetHeader(sText); DoWingmodelLoop(); MarkStageSetUp(nStage); break; } case STAGE_WINGS_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nWingType = GetCreatureWingType(); sText += Get2DACache("wingmodel", "label", nWingType); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_TAIL: { sText = GetStringByStrRef(124); // Select the Appearance of your Character sText += "(" + GetStringByStrRef(2410) + ")"; // Tail SetHeader(sText); DoTailmodelLoop(); MarkStageSetUp(nStage); break; } case STAGE_TAIL_CHECK: { sText = GetStringByStrRef(16824209) + " "; // You have selected: int nTailType = GetCreatureTailType(); sText += Get2DACache("tailmodel", "label", nTailType); sText += "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_SKIN_COLOUR: { sText = "Pick a colour category "; sText += "(" + GetStringByStrRef(128) + ")"; // Skin Color SetHeader(sText); AddChoice("Keep current skin colour", -1); AddChoice("Tan colours", 1); AddChoice("Sand & Rose brown", 2); AddChoice("Tan-Greys and blues", 3); AddChoice("Gold and obsidian", 4); AddChoice("Greens", 5); AddChoice("Greys and reds", 6); AddChoice("Bright blues, greens and yellows", 7); // new colours AddChoice("Metallic & pure white and black", 8); AddChoice("Smoky Group 1", 9); AddChoice("Smoky Group 2", 10); AddChoice("Smoky Group 3", 11); AddChoice("Smoky Group 4", 12); AddChoice("Black Cherry & Cinnamon", 13); AddChoice("Hunter Green & Druid Green", 14); AddChoice("Graveyard Fog & Chestnut", 15); AddChoice("Clay & Toasted Ash", 16); AddChoice("Snail Brown & Cobalt Blue", 17); AddChoice("Midnight Blue & Peacock Green", 18); AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19); AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20); AddChoice("Sugar Plum, Ice Blue, Black, & White", 21); AddChoice("Greens, Mystics, & Browns", 22); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SKIN_COLOUR_CHOICE: { sText = "Pick a colour "; sText += "(" + GetStringByStrRef(128) + ")"; // Skin Color SetHeader(sText); int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); AddColourChoices(nStage, nCategory); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_SKIN_COLOUR_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_HAIR_COLOUR: { sText = "Pick a colour category "; sText += "(" + GetStringByStrRef(125) + ")"; // Hair Color SetHeader(sText); AddChoice("Keep current hair colour", -1); AddChoice("Chestnuts and Reds", 1); AddChoice("Blondes and Browns", 2); AddChoice("White, Greys and Black", 3); AddChoice("Blues", 4); AddChoice("Greens", 5); AddChoice("Spring Greens and Yellows", 6); AddChoice("Oranges and Pinks", 7); // new colours AddChoice("Metallic & pure white and black", 8); AddChoice("Smoky Group 1", 9); AddChoice("Smoky Group 2", 10); AddChoice("Smoky Group 3", 11); AddChoice("Smoky Group 4", 12); AddChoice("Black Cherry & Cinnamon", 13); AddChoice("Hunter Green & Druid Green", 14); AddChoice("Graveyard Fog & Chestnut", 15); AddChoice("Clay & Toasted Ash", 16); AddChoice("Snail Brown & Cobalt Blue", 17); AddChoice("Midnight Blue & Peacock Green", 18); AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19); AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20); AddChoice("Sugar Plum, Ice Blue, Black, & White", 21); AddChoice("Greens, Mystics, & Browns", 22); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_HAIR_COLOUR_CHOICE: { sText = "Pick a colour "; sText += "(" + GetStringByStrRef(125) + ")"; // Hair Color SetHeader(sText); int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); AddColourChoices(nStage, nCategory); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_HAIR_COLOUR_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_TATTOO1_COLOUR: { sText = "Pick a colour category "; sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors SetHeader(sText); AddChoice("Keep current tattoo 1 colour", -1); AddChoice("Tan/Brown & Tan/Red", 1); AddChoice("Tan/Yellow & Tan/Grey", 2); AddChoice("Olive, White, Grey & Charcoal", 3); AddChoice("Blue, Aqua, Teal & Green", 4); AddChoice("Yellow, Orange, Red & Pink", 5); AddChoice("Purple, Violet & Shiny/Metallic group 1", 6); AddChoice("Shiny/Metallic group 2", 7); // new colours AddChoice("Metallic & pure white and black", 8); AddChoice("Smoky Group 1", 9); AddChoice("Smoky Group 2", 10); AddChoice("Smoky Group 3", 11); AddChoice("Smoky Group 4", 12); AddChoice("Black Cherry & Cinnamon", 13); AddChoice("Hunter Green & Druid Green", 14); AddChoice("Graveyard Fog & Chestnut", 15); AddChoice("Clay & Toasted Ash", 16); AddChoice("Snail Brown & Cobalt Blue", 17); AddChoice("Midnight Blue & Peacock Green", 18); AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19); AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20); AddChoice("Sugar Plum, Ice Blue, Black, & White", 21); AddChoice("Greens, Mystics, & Browns", 22); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_TATTOO1_COLOUR_CHOICE: { sText = "Pick a colour "; sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors SetHeader(sText); int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); AddColourChoices(nStage, nCategory); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_TATTOO1_COLOUR_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case STAGE_TATTOO2_COLOUR: { sText = "Pick a colour category "; sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors SetHeader(sText); AddChoice("Keep current tattoo 2 colour", -1); AddChoice("Tan/Brown & Tan/Red", 1); AddChoice("Tan/Yellow & Tan/Grey", 2); AddChoice("Olive, White, Grey & Charcoal", 3); AddChoice("Blue, Aqua, Teal & Green", 4); AddChoice("Yellow, Orange, Red & Pink", 5); AddChoice("Purple, Violet & Shiny/Metallic group 1", 6); AddChoice("Shiny/Metallic group 2", 7); // new colours AddChoice("Metallic & pure white and black", 8); AddChoice("Smoky Group 1", 9); AddChoice("Smoky Group 2", 10); AddChoice("Smoky Group 3", 11); AddChoice("Smoky Group 4", 12); AddChoice("Black Cherry & Cinnamon", 13); AddChoice("Hunter Green & Druid Green", 14); AddChoice("Graveyard Fog & Chestnut", 15); AddChoice("Clay & Toasted Ash", 16); AddChoice("Snail Brown & Cobalt Blue", 17); AddChoice("Midnight Blue & Peacock Green", 18); AddChoice("Royal Purple, Mountain Blue, & Sea Foam Green", 19); AddChoice("Spring Green, Honey Gold, Copper Coin & Berry Ice", 20); AddChoice("Sugar Plum, Ice Blue, Black, & White", 21); AddChoice("Greens, Mystics, & Browns", 22); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_TATTOO2_COLOUR_CHOICE: { sText = "Pick a colour "; sText += "(" + GetStringByStrRef(337) + ")"; // Tattoo Colors SetHeader(sText); int nCategory = GetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); AddColourChoices(nStage, nCategory); MarkStageSetUp(nStage); SetDefaultTokens(); break; } case STAGE_TATTOO2_COLOUR_CHECK: { sText = "\n"+GetStringByStrRef(16824210); // Is this correct? SetHeader(sText); // choices Y/N AddChoice(GetStringByStrRef(4753), -1); // no AddChoice(GetStringByStrRef(4752), 1); // yes MarkStageSetUp(nStage); break; } case FINAL_STAGE: { sText = "Your character will now be generated. As part of this process, you will be booted. Please exit NWN completely before rejoining."; SetHeader(sText); AddChoice("Make Character", 1); MarkStageSetUp(nStage); // give the PC the woodsman outfit so they don't have to be naked CreateItemOnObject("NW_CLOTH001", OBJECT_SELF); break; } default: DoDebug("ccc_inc_convo: DoHeaderAndChoices(): Unknown nStage value: " + IntToString(nStage)); } } int HandleChoice(int nStage, int nChoice) { switch(nStage) { case STAGE_INTRODUCTION: nStage++; break; case STAGE_GENDER: SetLocalInt(OBJECT_SELF, "Gender", nChoice); nStage++; break; case STAGE_GENDER_CHECK: { if(nChoice == 1) nStage++; else // go back to pick gender { nStage = STAGE_GENDER; MarkStageNotSetUp(STAGE_GENDER_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_GENDER, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Gender"); } break; } case STAGE_RACE: SetLocalInt(OBJECT_SELF, "Race", nChoice); nStage++; break; case STAGE_RACE_CHECK: { if(nChoice == 1) { nStage++; DoCutscene(OBJECT_SELF); // store racial feat variables AddRaceFeats(GetLocalInt(OBJECT_SELF, "Race")); } else // go back and pick race { nStage = STAGE_RACE; MarkStageNotSetUp(STAGE_RACE_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_RACE, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Race"); } break; } case STAGE_CLASS: SetLocalInt(OBJECT_SELF, "Class", nChoice); nStage++; break; case STAGE_CLASS_CHECK: { if(nChoice == 1) { nStage++; // add class feats AddClassFeats(GetLocalInt(OBJECT_SELF, "Class")); // now for hitpoints (without con alteration) SetLocalInt(OBJECT_SELF, "HitPoints", StringToInt(Get2DACache("classes", "HitDie", GetLocalInt(OBJECT_SELF, "Class")))); } else // go back and pick class { nStage = STAGE_CLASS; MarkStageNotSetUp(STAGE_CLASS_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_CLASS, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Class"); } break; } case STAGE_ALIGNMENT: { // for stage check later SetLocalInt(OBJECT_SELF, "AlignChoice", nChoice); switch(nChoice) { case 112: //lawful good SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85); SetLocalInt(OBJECT_SELF, "GoodEvil", 85); break; case 115: //neutral good SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50); SetLocalInt(OBJECT_SELF, "GoodEvil", 85); break; case 118: //chaotic good SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15); SetLocalInt(OBJECT_SELF, "GoodEvil", 85); break; case 113: //lawful neutral SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85); SetLocalInt(OBJECT_SELF, "GoodEvil", 50); break; case 116: //true neutral SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50); SetLocalInt(OBJECT_SELF, "GoodEvil", 50); break; case 119: //chaotic neutral SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15); SetLocalInt(OBJECT_SELF, "GoodEvil", 50); break; case 114: //lawful evil SetLocalInt(OBJECT_SELF, "LawfulChaotic", 85); SetLocalInt(OBJECT_SELF, "GoodEvil", 15); break; case 117: //neutral evil SetLocalInt(OBJECT_SELF, "LawfulChaotic", 50); SetLocalInt(OBJECT_SELF, "GoodEvil", 15); break; case 120: //chaotic evil SetLocalInt(OBJECT_SELF, "LawfulChaotic", 15); SetLocalInt(OBJECT_SELF, "GoodEvil", 15); break; default: DoDebug("Duh, that clearly didn't work right"); } nStage++; break; } case STAGE_ALIGNMENT_CHECK: { if(nChoice == 1) { nStage++; } else // go back and pick alignment { nStage = STAGE_ALIGNMENT; MarkStageNotSetUp(STAGE_ALIGNMENT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_ALIGNMENT, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "AlignChoice"); DeleteLocalInt(OBJECT_SELF, "LawfulChaotic"); DeleteLocalInt(OBJECT_SELF, "GoodEvil"); } break; } case STAGE_ABILITY: { int nAbilityScore; switch(nChoice) { case ABILITY_STRENGTH: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Str")); SetLocalInt(OBJECT_SELF, "Str", nAbilityScore); break; case ABILITY_DEXTERITY: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Dex")); SetLocalInt(OBJECT_SELF, "Dex", nAbilityScore); break; case ABILITY_CONSTITUTION: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Con")); SetLocalInt(OBJECT_SELF, "Con", nAbilityScore); break; case ABILITY_INTELLIGENCE: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Int")); SetLocalInt(OBJECT_SELF, "Int", nAbilityScore); break; case ABILITY_WISDOM: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Wis")); SetLocalInt(OBJECT_SELF, "Wis", nAbilityScore); break; case ABILITY_CHARISMA: nAbilityScore = IncreaseAbilityScore(GetLocalInt(OBJECT_SELF, "Cha")); SetLocalInt(OBJECT_SELF, "Cha", nAbilityScore); break; } int nPoints = GetLocalInt(OBJECT_SELF, "Points"); // new total if (nPoints) // if there's still points to allocate { // resets the stage so that the convo choices reflect the new ability scores ClearCurrentStage(); } else nStage++; // go to next stage break; } case STAGE_ABILITY_CHECK:{ if(nChoice == 1) { nStage++; } else // go back and reselect ability score { nStage = STAGE_ABILITY; MarkStageNotSetUp(STAGE_ABILITY_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_ABILITY, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Str"); DeleteLocalInt(OBJECT_SELF, "Dex"); DeleteLocalInt(OBJECT_SELF, "Con"); DeleteLocalInt(OBJECT_SELF, "Int"); DeleteLocalInt(OBJECT_SELF, "Wis"); DeleteLocalInt(OBJECT_SELF, "Cha"); } break; } case STAGE_SKILL: { // first time through, create the skills array if(!array_exists(OBJECT_SELF, "Skills")) array_create(OBJECT_SELF, "Skills"); // get current points int nPoints = GetLocalInt(OBJECT_SELF, "Points"); if(GetChoice(OBJECT_SELF) == -2) // save all remaining points { SetLocalInt(OBJECT_SELF, "SavedSkillPoints", nPoints); nPoints = 0; } else // chosen a skill to increase { // get the cls_skill_*** 2da to use string sFile = Get2DACache("classes", "SkillsTable", GetLocalInt(OBJECT_SELF, "Class")); // work out what line in skills.2da it corresponds to int nSkillIndex = StringToInt(Get2DAString(sFile, "SkillIndex", nChoice)); //increase the points in that skill // the array index is the line number in skills.2da array_set_int(OBJECT_SELF, "Skills", nSkillIndex, array_get_int(OBJECT_SELF, "Skills", nSkillIndex)+1); //decrease points remaining // see if it's class or cross-class int nClassSkill = StringToInt(Get2DAString(sFile, "ClassSkill", nChoice)); if (nClassSkill) // class skill nPoints -= 1; else // cross class skill nPoints -= 2; } // store new points total SetLocalInt(OBJECT_SELF, "Points", nPoints); if (nPoints) // still some left to allocate { // Store offset so that if the user decides not to take the power, // we can return to the same page in the power list instead of resetting to the beginning // Store the value +1 in order to be able to differentiate between offset 0 and undefined SetLocalInt(OBJECT_SELF, "SkillListChoiceOffset", GetLocalInt(OBJECT_SELF, DYNCONV_CHOICEOFFSET) + 1); ClearCurrentStage(); } else nStage++; break; } case STAGE_SKILL_CHECK: { if (nChoice == 1) nStage++; else { nStage = STAGE_SKILL; MarkStageNotSetUp(STAGE_SKILL_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_SKILL, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "SavedSkillPoints"); DeleteLocalInt(OBJECT_SELF, "Points"); array_delete(OBJECT_SELF, "Skills"); } break; } case STAGE_FEAT: { int nArraySize = array_get_size(OBJECT_SELF, "Feats"); // alertness fix if (nChoice == 0) nChoice = -1; // add the feat chosen to the feat array array_set_int(OBJECT_SELF, "Feats", array_get_size(OBJECT_SELF, "Feats"), nChoice); nStage++; break; } case STAGE_FEAT_CHECK: { if (nChoice == 1) { // delete the stored convo choice list ClearCachedChoices(); // decrement the number of feats left to pick int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points"); --nFeatsRemaining; // check new number of feats left if (nFeatsRemaining == 0) { // no more feats left to pick // if there's a bonus feat to pick, go to next stage nFeatsRemaining = StringToInt(Get2DACache(Get2DACache("Classes", "BonusFeatsTable", GetLocalInt(OBJECT_SELF, "Class")), "Bonus", 0)); if (nFeatsRemaining) { // go to bonus feat stage nStage = STAGE_BONUS_FEAT; } else { // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); } } else { // go back to feat stage to pick next feat nStage = STAGE_FEAT; MarkStageNotSetUp(STAGE_FEAT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_FEAT, OBJECT_SELF); } SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining); } else { nStage = STAGE_FEAT; MarkStageNotSetUp(STAGE_FEAT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_FEAT, OBJECT_SELF); // delete the chosen feat if(array_shrink(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)) != SDL_SUCCESS) DoDebug("No feats array!"); } break; } case STAGE_BONUS_FEAT: { int nArraySize = array_get_size(OBJECT_SELF, "Feats"); // alertness fix if (nChoice == 0) nChoice = -1; // add the feat chosen to the feat array array_set_int(OBJECT_SELF, "Feats", array_get_size(OBJECT_SELF, "Feats"), nChoice); nStage++; break; } case STAGE_BONUS_FEAT_CHECK: { if (nChoice == 1) { // delete the stored convo choice list ClearCachedChoices(); // decrement the number of feats left to pick int nFeatsRemaining = GetLocalInt(OBJECT_SELF, "Points"); --nFeatsRemaining; // check new number of feats left if (nFeatsRemaining == 0) { // no more feats left to pick // tidy up locals DeleteLocalInt(OBJECT_SELF, "bHasAnimalEmpathy"); DeleteLocalInt(OBJECT_SELF, "bHasUMD"); // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); } else { // go back to feat stage to pick next feat nStage = STAGE_BONUS_FEAT; MarkStageNotSetUp(STAGE_BONUS_FEAT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_BONUS_FEAT, OBJECT_SELF); } SetLocalInt(OBJECT_SELF, "Points", nFeatsRemaining); } else { nStage = STAGE_BONUS_FEAT; MarkStageNotSetUp(STAGE_BONUS_FEAT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_BONUS_FEAT, OBJECT_SELF); // delete the chosen feat if(array_shrink(OBJECT_SELF, "Feats", (array_get_size(OBJECT_SELF, "Feats") - 1)) != SDL_SUCCESS) DoDebug("No feats array!"); } break; } case STAGE_WIZ_SCHOOL: { SetLocalInt(OBJECT_SELF, "School", GetChoice()); nStage++; break; } case STAGE_WIZ_SCHOOL_CHECK: { if(nChoice == 1) { // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); // add cantrips - wizards know all of them so don't need to choose SetWizCantrips(GetLocalInt(OBJECT_SELF, "School")); } else // go back and pick the school again { nStage = STAGE_WIZ_SCHOOL; MarkStageNotSetUp(STAGE_WIZ_SCHOOL_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_WIZ_SCHOOL, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "School"); } break; } case STAGE_SPELLS_0: { // create the array first time through if (!array_exists(OBJECT_SELF, "SpellLvl0")) array_create(OBJECT_SELF, "SpellLvl0"); int nPoints = GetLocalInt(OBJECT_SELF, "Points"); // add the choice to the spells known array array_set_int(OBJECT_SELF, "SpellLvl0", array_get_size(OBJECT_SELF, "SpellLvl0"), nChoice); // decrement the number of spells left to select SetLocalInt(OBJECT_SELF, "Points", --nPoints); if (nPoints) // still some left to allocate ClearCurrentStage(); else // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); break; } case STAGE_SPELLS_1: { // create the array first time through if (!array_exists(OBJECT_SELF, "SpellLvl1")) array_create(OBJECT_SELF, "SpellLvl1"); int nPoints = GetLocalInt(OBJECT_SELF, "Points"); // add the choice to the spells known array array_set_int(OBJECT_SELF, "SpellLvl1", array_get_size(OBJECT_SELF, "SpellLvl1"), nChoice); // decrement the number of spells left to select SetLocalInt(OBJECT_SELF, "Points", --nPoints); if (nPoints) // still some left to allocate ClearCurrentStage(); else // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); break; } case STAGE_SPELLS_CHECK: { if(nChoice == 1) { // go to next stage after that the PC qualifies for nStage = GetNextCCCStage(nStage); int nClass = GetLocalInt(OBJECT_SELF, "Class"); // get the cls_spgn_***2da to use string sSpgn = Get2DACache("classes", "SpellGainTable", nClass); int nSpellsPerDay; // level 1 spells if (array_exists(OBJECT_SELF, "SpellLvl1")) { nSpellsPerDay = StringToInt(Get2DACache(sSpgn, "SpellLevel1", 0)); SetLocalInt(OBJECT_SELF, "SpellsPerDay1", nSpellsPerDay); } // cantrips if (array_exists(OBJECT_SELF, "SpellLvl0")) { nSpellsPerDay = StringToInt(Get2DACache(sSpgn, "SpellLevel0", 0)); SetLocalInt(OBJECT_SELF, "SpellsPerDay0", nSpellsPerDay); } } else // go back and pick the spells again { // hacky...but returns the right stage, depending on the class nStage = GetNextCCCStage(STAGE_WIZ_SCHOOL_CHECK); MarkStageNotSetUp(STAGE_SPELLS_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_SPELLS_1, OBJECT_SELF); MarkStageNotSetUp(STAGE_SPELLS_0, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Points"); array_delete(OBJECT_SELF, "SpellLvl1"); if(nStage == STAGE_SPELLS_0) { // if the new value of nStage takes us back to picking cantrips, // then also delete the level 0 array array_delete(OBJECT_SELF, "SpellLvl0"); } } break; } case STAGE_FAMILIAR: { if(GetLocalInt(OBJECT_SELF, "Class") == CLASS_TYPE_DRUID) SetLocalInt(OBJECT_SELF, "Companion", nChoice); else // sorc or wiz SetLocalInt(OBJECT_SELF, "Familiar", nChoice); nStage++; break; } case STAGE_FAMILIAR_CHECK: { if (nChoice == 1) nStage = GetNextCCCStage(nStage); else { nStage = STAGE_FAMILIAR; MarkStageNotSetUp(STAGE_FAMILIAR_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_FAMILIAR, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Familiar"); DeleteLocalInt(OBJECT_SELF, "Companion"); } break; } case STAGE_DOMAIN: { // if this is the first domain chosen if (GetLocalInt(OBJECT_SELF, "Domain1") == 0) { // fix for air domain being 0 if (nChoice == 0) nChoice = -1; SetLocalInt(OBJECT_SELF, "Domain1", nChoice); nStage = STAGE_DOMAIN_CHECK1; } else // second domain { // fix for air domain being 0 if (nChoice == 0) nChoice = -1; SetLocalInt(OBJECT_SELF, "Domain2", nChoice); nStage = STAGE_DOMAIN_CHECK2; } break; } case STAGE_DOMAIN_CHECK1: { if (nChoice == 1) { nStage = STAGE_DOMAIN; MarkStageNotSetUp(STAGE_DOMAIN_CHECK1); MarkStageNotSetUp(STAGE_DOMAIN); } else { nStage = STAGE_DOMAIN; MarkStageNotSetUp(STAGE_DOMAIN_CHECK1); MarkStageNotSetUp(STAGE_DOMAIN); DeleteLocalInt(OBJECT_SELF,"Domain1"); DeleteLocalInt(OBJECT_SELF,"Domain2"); } break; } case STAGE_DOMAIN_CHECK2: { if (nChoice == 1) { nStage++; // add domain feats AddDomainFeats(); } else { nStage = STAGE_DOMAIN; MarkStageNotSetUp(STAGE_DOMAIN_CHECK2); MarkStageNotSetUp(STAGE_DOMAIN); DeleteLocalInt(OBJECT_SELF,"Domain1"); DeleteLocalInt(OBJECT_SELF,"Domain2"); } break; } case STAGE_APPEARANCE: { if (nChoice == -1) // no change { SetLocalInt(OBJECT_SELF, "Appearance", GetAppearanceType(OBJECT_SELF)); nStage = STAGE_PORTRAIT; } else { SetLocalInt(OBJECT_SELF, "Appearance", nChoice); SetCreatureAppearanceType(OBJECT_SELF, nChoice); // change the appearance DoCutscene(OBJECT_SELF); nStage++; } break; } case STAGE_APPEARANCE_CHECK: { if (nChoice == 1) { nStage++; } else { nStage = STAGE_APPEARANCE; MarkStageNotSetUp(STAGE_APPEARANCE_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_APPEARANCE, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Appearance"); } break; } case STAGE_PORTRAIT: { if (nChoice == -1) // no change { nStage = STAGE_SOUNDSET; } else { // change the portrait SetPortraitId(OBJECT_SELF, nChoice); // change the clone's portrait object oClone = GetLocalObject(OBJECT_SELF, "Clone"); SetPortraitId(oClone, nChoice); nStage++; } break; } case STAGE_PORTRAIT_CHECK: { if (nChoice == 2) { object oClone = GetLocalObject(OBJECT_SELF, "Clone"); ActionExamine(oClone); // DelayCommand(1.0, ActionExamine(oClone)); // DelayCommand(2.0, ActionExamine(oClone)); } else if (nChoice == 1) { nStage++; } else { nStage = STAGE_PORTRAIT; MarkStageNotSetUp(STAGE_PORTRAIT_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_PORTRAIT, OBJECT_SELF); } break; } case STAGE_SOUNDSET: { if (nChoice == -1) // no change { SetLocalInt(OBJECT_SELF, "Soundset", nChoice); nStage = GetNextCCCStage(nStage, FALSE); } else { // store the choice SetLocalInt(OBJECT_SELF, "Soundset", nChoice); // modify the clone DoCutscene(OBJECT_SELF); nStage++; } break; } case STAGE_SOUNDSET_CHECK: { if (nChoice == 2) { object oClone = GetLocalObject(OBJECT_SELF, "Clone"); PlayVoiceChat(0 , oClone); } else if (nChoice == 1) { // set up colour defaults here to make sure they don't reset for non-player type appearances SetLocalInt(OBJECT_SELF, "Skin", -1); SetLocalInt(OBJECT_SELF, "Hair", -1); SetLocalInt(OBJECT_SELF, "TattooColour1", -1); SetLocalInt(OBJECT_SELF, "TattooColour2", -1); nStage = GetNextCCCStage(nStage, FALSE); } else { nStage = STAGE_SOUNDSET; MarkStageNotSetUp(STAGE_SOUNDSET_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_SOUNDSET, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Soundset"); } break; } case STAGE_HEAD: { if (nChoice == -1) // no change { nStage = GetNextCCCStage(nStage, FALSE); } else { // change the head SetCreatureBodyPart(CREATURE_PART_HEAD, nChoice); // modify the clone's head object oClone = GetLocalObject(OBJECT_SELF, "Clone"); SetCreatureBodyPart(CREATURE_PART_HEAD, nChoice, oClone); nStage++; } break; } case STAGE_HEAD_CHECK: { if (nChoice == 1) { nStage = GetNextCCCStage(nStage, FALSE); } else { nStage = STAGE_HEAD; MarkStageNotSetUp(STAGE_HEAD_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_HEAD, OBJECT_SELF); } break; } case STAGE_TATTOO: { if (nChoice == -1) // no change { nStage = GetNextCCCStage(nStage, FALSE); } else { int nTattooed = GetCreatureBodyPart(nChoice, OBJECT_SELF); if(nTattooed == 1) nTattooed = 2; else if(nTattooed == 2) nTattooed = 1; // change the tattoo on the clone SetCreatureBodyPart(nChoice, nTattooed, GetLocalObject(OBJECT_SELF, "Clone")); // change the tattoo on the PC SetCreatureBodyPart(nChoice, nTattooed); } break; } case STAGE_TATTOO_CHECK: { if (nChoice == 1) { nStage = GetNextCCCStage(nStage, FALSE); } else { nStage = STAGE_TATTOO; MarkStageNotSetUp(STAGE_TATTOO_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_TATTOO, OBJECT_SELF); } break; } case STAGE_WINGS: { SetCreatureWingType(nChoice); // alter the clone object oClone = GetLocalObject(OBJECT_SELF, "Clone"); SetCreatureWingType(nChoice, oClone); nStage++; break; } case STAGE_WINGS_CHECK: { if (nChoice == 1) { nStage = GetNextCCCStage(nStage, FALSE); } else { nStage = STAGE_WINGS; MarkStageNotSetUp(STAGE_WINGS_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_WINGS, OBJECT_SELF); } break; } case STAGE_TAIL: { SetCreatureTailType(nChoice); // alter the clone object oClone = GetLocalObject(OBJECT_SELF, "Clone"); SetCreatureTailType(nChoice, oClone); nStage++; break; } case STAGE_TAIL_CHECK: { if (nChoice == 1) { nStage = GetNextCCCStage(nStage, FALSE); } else { nStage = STAGE_TAIL; MarkStageNotSetUp(STAGE_TAIL_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_TAIL, OBJECT_SELF); } break; } case STAGE_SKIN_COLOUR: { if (nChoice == -1) // keep existing { nStage = STAGE_SKIN_COLOUR_CHECK; SetLocalInt(OBJECT_SELF, "Skin", -1); } else { SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice); nStage++; } break; } case STAGE_SKIN_COLOUR_CHOICE: { SetLocalInt(OBJECT_SELF, "Skin", nChoice); // change the clone DoCutscene(OBJECT_SELF); nStage++; break; } case STAGE_SKIN_COLOUR_CHECK: { if (nChoice == 1) { nStage++; } else { nStage = STAGE_SKIN_COLOUR; MarkStageNotSetUp(STAGE_SKIN_COLOUR_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_SKIN_COLOUR_CHOICE, OBJECT_SELF); MarkStageNotSetUp(STAGE_SKIN_COLOUR, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Skin"); } DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); break; } case STAGE_HAIR_COLOUR: { if (nChoice == -1) // keep existing { nStage = STAGE_HAIR_COLOUR_CHECK; SetLocalInt(OBJECT_SELF, "Hair", -1); } else { SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice); nStage++; } break; } case STAGE_HAIR_COLOUR_CHOICE: { SetLocalInt(OBJECT_SELF, "Hair", nChoice); // change the clone DoCutscene(OBJECT_SELF); nStage++; break; } case STAGE_HAIR_COLOUR_CHECK: { if (nChoice == 1) { nStage++; } else { nStage = STAGE_HAIR_COLOUR; MarkStageNotSetUp(STAGE_HAIR_COLOUR_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_HAIR_COLOUR_CHOICE, OBJECT_SELF); MarkStageNotSetUp(STAGE_HAIR_COLOUR, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "Hair"); } DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); break; } case STAGE_TATTOO1_COLOUR: { if (nChoice == -1) // keep existing { nStage = STAGE_TATTOO1_COLOUR_CHECK; SetLocalInt(OBJECT_SELF, "TattooColour1", -1); } else { SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice); nStage++; } break; } case STAGE_TATTOO1_COLOUR_CHOICE: { SetLocalInt(OBJECT_SELF, "TattooColour1", nChoice); // change the clone DoCutscene(OBJECT_SELF); nStage++; break; } case STAGE_TATTOO1_COLOUR_CHECK: { if (nChoice == 1) { nStage++; } else { nStage = STAGE_TATTOO1_COLOUR; MarkStageNotSetUp(STAGE_TATTOO1_COLOUR_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_TATTOO1_COLOUR_CHOICE, OBJECT_SELF); MarkStageNotSetUp(STAGE_TATTOO1_COLOUR, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "TattooColour1"); } DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); break; } case STAGE_TATTOO2_COLOUR: { if (nChoice == -1) // keep existing { nStage = STAGE_TATTOO2_COLOUR_CHECK; SetLocalInt(OBJECT_SELF, "TattooColour2", -1); } else { SetLocalInt(OBJECT_SELF, "CATEGORY_SELECTED", nChoice); nStage++; } break; } case STAGE_TATTOO2_COLOUR_CHOICE: { SetLocalInt(OBJECT_SELF, "TattooColour2", nChoice); // change the clone DoCutscene(OBJECT_SELF); nStage++; break; } case STAGE_TATTOO2_COLOUR_CHECK: { if (nChoice == 1) { nStage = FINAL_STAGE; } else { nStage = STAGE_TATTOO2_COLOUR; MarkStageNotSetUp(STAGE_TATTOO2_COLOUR_CHECK, OBJECT_SELF); MarkStageNotSetUp(STAGE_TATTOO2_COLOUR_CHOICE, OBJECT_SELF); MarkStageNotSetUp(STAGE_TATTOO2_COLOUR, OBJECT_SELF); DeleteLocalInt(OBJECT_SELF, "TattooColour2"); } DeleteLocalInt(OBJECT_SELF, "CATEGORY_SELECTED"); break; } case FINAL_STAGE: { ExecuteScript("prc_ccc_make_pc", OBJECT_SELF); AllowExit(DYNCONV_EXIT_FORCE_EXIT); break; } } return nStage; }