diff --git a/Makefile b/Makefile index 615897d..1dbcd1a 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ BUNDLEFOLDER = $(BUILD_DIR)/$(BUNDLENAME) BUNDLEIDENTIFIER = com.majinnaibu.test.$(APPNAME) BUNDLESIGNATURE = SBF_ RESOURCES_DIR = Resources -APP_OBJECTS = main.o +APP_OBJECTS = Character.o Colors.o Menus.o FAT_LIBS = ncurses MANDATORY_TARGETS = Makefile @@ -75,11 +75,11 @@ app: $(BUILD_DIR)/$(CLIAPPNAME) $(SRC_DIR)/Info.plist $(RESOURCES_DIR)/en-US.lpr cp $(BUILD_DIR)/$(CLIAPPNAME) $(BUNDLEFOLDER)/Contents/MacOS/$(APPNAME) cp -r $(RESOURCES_DIR)/* $(BUNDLEFOLDER)/Contents/Resources/ -$(BUILD_DIR)/$(CLIAPPNAME): $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) $(patsubst %, $(BUILD_DIR)/lib/lib%.a, $(FAT_LIBS)) $(MANDATORY_TARGETS) - $(LD) $(LDFLAGS) -o $@ $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) +$(BUILD_DIR)/$(CLIAPPNAME): $(BUILD_DIR)/sbf.o $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) $(patsubst %, $(BUILD_DIR)/lib/lib%.a, $(FAT_LIBS)) $(MANDATORY_TARGETS) + $(LD) $(LDFLAGS) -o $@ $< $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) $(BUILD_DIR)/$(TESTAPPNAME): $(BUILD_DIR)/test.o $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) $(patsubst %, $(BUILD_DIR)/lib/lib%.a, $(FAT_LIBS)) $(MANDATORY_TARGETS) - $(LD) $(LDFLAGS) -o $@ $< + $(LD) $(LDFLAGS) -o $@ $< $(patsubst %, $(BUILD_DIR)/%, $(APP_OBJECTS)) $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/*.h $(MANDATORY_TARGETS) $(CC) $(CCFLAGS) -c -o $@ $< diff --git a/sbf-cpp/Character.cpp b/sbf-cpp/Character.cpp new file mode 100644 index 0000000..e119084 --- /dev/null +++ b/sbf-cpp/Character.cpp @@ -0,0 +1,782 @@ +#include "Character.h" + +namespace SBF { + + int GetNumAttributesInGroup(int groupId) { + switch (groupId) { + case kAttributeGroupPhysicalId: + return kPhysicalAttributesCount; + case kAttributeGroupSocialId: + return kSocialAttributesCount; + case kAttributeGroupMentalId: + return kMentalAttributesCount; + default: + return 0; + } + } + + CharacterType::CharacterType() { + // Scalars + name = L""; + player = L""; + chronicle = L""; + haven = L""; + concept = L""; + age = L""; + genderId = 0; + clanId = 0; + natureId = 0; + demeanorId = 0; + generation = 3; + roadName = L""; + roadValue = 0; + willpower = 0; + bloodPool = 0; + derangementId = -1; + + // Virtues + selfControl = 1; + courage = 1; + conscience = 1; + + // Arrays/Objects + // Abilities (Talents/Skills/Knowledges) + for (int groupId = 1; groupId <= kAbilityGroupsCount; groupId++) { + const int numAbilities = GetNumItemsForAbilityGroup(groupId); + for (int abilityId = 1; abilityId <= numAbilities; abilityId++) { + SetAbilityValue(groupId, abilityId, 0); + } + } + + // Attributes + for (int groupId = 1; groupId <= kAttributeGroupsCount; groupId++) { + const int numAttributes = GetNumAttributesInGroup(groupId); + for (int attributeId = 1; attributeId <= numAttributes; attributeId++) { + SetAttributeValue(groupId, attributeId, 1); + } + } + + // Backgrounds + for (int id = 0; id <= kBackgroundsCount; id++) { + SetBackgroundValue(id, 0); + } + + // Disciplines + for (int id = 0; id <= kDisciplinesCount; id++) { + SetDisciplineValue(id, 0); + } + } + + void CharacterType::SetDisciplineValue(int disciplineId, int value) { + switch (disciplineId) { + case kDisciplineAnimalismId: + discipline_animalism = value; + break; + case kDisciplineAuspexId: + discipline_auspex = value; + break; + case kDisciplineBardoId: + discipline_bardo = value; + break; + case kDisciplineCelerityId: + discipline_celerity = value; + break; + case kDisciplineChimestryId: + discipline_chimestry = value; + break; + case kDisciplineDementationId: + discipline_dementation = value; + break; + case kDisciplineDominateId: + discipline_dominate = value; + break; + case kDisciplineFortitudeId: + discipline_fortitude = value; + break; + case kDisciplineMelpomineeId: + discipline_melpominee = value; + break; + case kDisciplineMortisId: + discipline_mortis = value; + break; + case kDisciplineMytherceriaId: + discipline_mytherceria = value; + break; + case kDisciplineNecromancyId: + discipline_necromancy = value; + break; + case kDisciplineObeahId: + discipline_obeah = value; + break; + case kDisciplineObfuscateId: + discipline_obfuscate = value; + break; + case kDisciplineObtenebrationId: + discipline_obtenebration = value; + break; + case kDisciplinePotenceId: + discipline_potence = value; + break; + case kDisciplinePresenceId: + discipline_presence = value; + break; + case kDisciplineProteanId: + discipline_protean = value; + break; + case kDisciplineQuietusId: + discipline_quietus = value; + break; + case kDisciplineSerpentisId: + discipline_serpentis = value; + break; + case kDisciplineSpiritusId: + discipline_spiritus = value; + break; + case kDisciplineThanantosisId: + discipline_thanantosis = value; + break; + case kDisciplineThaumaturgyId: + discipline_thaumaturgy = value; + break; + case kDisciplineVicissitudeId: + discipline_vicissitude = value; + break; + } + } + + int CharacterType::GetDisciplineValue(int disciplineId) const { + switch (disciplineId) { + case kDisciplineAnimalismId: + return discipline_animalism; + case kDisciplineAuspexId: + return discipline_auspex; + case kDisciplineBardoId: + return discipline_bardo; + case kDisciplineCelerityId: + return discipline_celerity; + case kDisciplineChimestryId: + return discipline_chimestry; + case kDisciplineDementationId: + return discipline_dementation; + case kDisciplineDominateId: + return discipline_dominate; + case kDisciplineFortitudeId: + return discipline_fortitude; + case kDisciplineMelpomineeId: + return discipline_melpominee; + case kDisciplineMortisId: + return discipline_mortis; + case kDisciplineMytherceriaId: + return discipline_mytherceria; + case kDisciplineNecromancyId: + return discipline_necromancy; + case kDisciplineObeahId: + return discipline_obeah; + case kDisciplineObfuscateId: + return discipline_obfuscate; + case kDisciplineObtenebrationId: + return discipline_obtenebration; + case kDisciplinePotenceId: + return discipline_potence; + case kDisciplinePresenceId: + return discipline_presence; + case kDisciplineProteanId: + return discipline_protean; + case kDisciplineQuietusId: + return discipline_quietus; + case kDisciplineSerpentisId: + return discipline_serpentis; + case kDisciplineSpiritusId: + return discipline_spiritus; + case kDisciplineThanantosisId: + return discipline_thanantosis; + case kDisciplineThaumaturgyId: + return discipline_thaumaturgy; + case kDisciplineVicissitudeId: + return discipline_vicissitude; + default: + return 0; + } + } + + int GetDisciplinePoints() { + return kDisciplinePoints; + } + + void CharacterType::FillDisciplineValues(std::vector disciplineValues) const { + // TODO: This method sucks, but was needed in QBasic. + disciplineValues.clear(); + for (int id = 0; id <= kDisciplinesCount; id++) { + disciplineValues[id] = GetDisciplineValue(id); + } + } + + int GetVirtuePoints() { + return kVirtuePoints; + } + + void CharacterType::SetVirtueValue(int virtueId, int value) { + switch (virtueId) { + case kVirtueSelfControlId: + selfControl = value; + break; + case kVirtueCourageId: + courage = value; + break; + case kVirtueConscienceId: + conscience = value; + break; + } + } + + int CharacterType::GetVirtueValue(int virtueId) const { + switch (virtueId) { + case kVirtueSelfControlId: + return selfControl; + case kVirtueCourageId: + return courage; + case kVirtueConscienceId: + return conscience; + default: + return 0; + } + } + + void CharacterType::FillVirtueValues(std::vector virtueValues) const { + // TODO: This method sucks, but was needed in QBasic. + virtueValues.clear(); + for (int id = 0; id <= kVirtuesCount; id++) { + virtueValues[id] = GetVirtueValue(id); + } + } + + void CharacterType::FillAttributeValues(std::vector attributeValues, int attributeGroupId) const { + // TODO: This method sucks, but was needed in QBasic. + const int numAttributes = GetNumAttributesInGroup(attributeGroupId); + attributeValues.clear(); + for (int attributeId = 0; attributeId <= numAttributes; attributeId++) { + attributeValues[attributeId] = GetAttributeValue(attributeGroupId, attributeId); + } + } + + wstring GetAttributeLabel(int attributeGroupId, int attributeId) { + switch (attributeGroupId) { + case kAttributeGroupPhysicalId: + return kPhysicalAttributeLabels[attributeId]; + case kAttributeGroupSocialId: + return kSocialAttributeLabels[attributeId]; + case kAttributeGroupMentalId: + return kMentalAttributeLabels[attributeId]; + default: + return L""; + } + } + + void FillAttributeLabelsInGroup(std::vector attributeLabels, int attributeGroupId) { + attributeLabels.clear(); + switch (attributeGroupId) { + case kAttributeGroupPhysicalId: + for (int attributeId = 0; attributeId <= kPhysicalAttributesCount; attributeId++) { + attributeLabels[attributeId] = kPhysicalAttributeLabels[attributeId]; + } + break; + case kAttributeGroupSocialId: + for (int attributeId = 0; attributeId <= kSocialAttributesCount; attributeId++) { + attributeLabels[attributeId] = kSocialAttributeLabels[attributeId]; + } + break; + case kAttributeGroupMentalId: + for (int attributeId = 0; attributeId <= kMentalAttributesCount; attributeId++) { + attributeLabels[attributeId] = kMentalAttributeLabels[attributeId]; + } + break; + } + } + + void FillAttributeAbbreviationsInGroup(std::vector attributeAbbreviations, int attributeGroupId) { + attributeAbbreviations.clear(); + switch (attributeGroupId) { + case kAttributeGroupPhysicalId: + for (int attributeId = 0; attributeId <= kPhysicalAttributesCount; attributeId++) { + attributeAbbreviations[attributeId] = kPhysicalAttributeAbbreviations[attributeId]; + } + break; + case kAttributeGroupSocialId: + for (int attributeId = 0; attributeId <= kSocialAttributesCount; attributeId++) { + attributeAbbreviations[attributeId] = kSocialAttributeAbbreviations[attributeId]; + } + break; + case kAttributeGroupMentalId: + for (int attributeId = 0; attributeId <= kMentalAttributesCount; attributeId++) { + attributeAbbreviations[attributeId] = kMentalAttributeAbbreviations[attributeId]; + } + break; + } + } + + void CharacterType::SetAttributeValue(int attributeGroupId, int attributeId, int value) { + switch (attributeGroupId) { + case kAttributeGroupPhysicalId: + switch (attributeId) { + case kPhysicalAttributeStrengthId: + attr_strength = value; + break; + case kPhysicalAttributeDexterityId: + attr_dexterity = value; + break; + case kPhysicalAttributeStaminaId: + attr_stamina = value; + break; + } + break; + case kAttributeGroupSocialId: + switch (attributeId) { + case kSocialAttributeCharismaId: + attr_charisma = value; + break; + case kSocialAttributeManipulationId: + attr_manipulation = value; + break; + case kSocialAttributeAppearanceId: + attr_appearance = value; + break; + } + break; + case kAttributeGroupMentalId: + switch (attributeId) { + case kMentalAttributeIntelligenceId: + attr_intelligence = value; + break; + case kMentalAttributePerceptionId: + attr_perception = value; + break; + case kMentalAttributeWitsId: + attr_wits = value; + break; + } + break; + } + } + + int CharacterType::GetAttributeValue(int attributeGroupId, int attributeId) const { + switch (attributeGroupId) { + case kAttributeGroupPhysicalId: + switch (attributeId) { + case kPhysicalAttributeStrengthId: + return attr_strength; + case kPhysicalAttributeDexterityId: + return attr_dexterity; + case kPhysicalAttributeStaminaId: + return attr_stamina; + } + break; + case kAttributeGroupSocialId: + switch (attributeId) { + case kSocialAttributeCharismaId: + return attr_charisma; + case kSocialAttributeManipulationId: + return attr_manipulation; + case kSocialAttributeAppearanceId: + return attr_appearance; + } + break; + case kAttributeGroupMentalId: + switch (attributeId) { + case kMentalAttributeIntelligenceId: + return attr_intelligence; + case kMentalAttributePerceptionId: + return attr_perception; + case kMentalAttributeWitsId: + return attr_wits; + } + break; + } + return 0; + } + + int GetAttributePointsForRank (int rankId) { + switch (rankId) { + case kRankPrimaryId: + return 7; + case kRankSecondaryId: + return 5; + case kRankTertiaryId: + return 3; + } + return 0; + } + + void CharacterType::SetAbilityValue(int abilityGroupId, int abilityId, int value) { + switch (abilityGroupId) { + case kAbilityGroupTalentsId: + SetTalentValue(abilityId, value); + break; + case kAbilityGroupSkillsId: + SetSkillValue(abilityId, value); + break; + case kAbilityGroupKnowledgesId: + SetKnowledgeValue(abilityId, value); + break; + } + } + + int CharacterType::GetAbilityValue(int abilityGroupId, int abilityId) const { + switch(abilityGroupId) { + case kAbilityGroupTalentsId: + return GetTalentValue(abilityId); + case kAbilityGroupKnowledgesId: + return GetKnowledgeValue(abilityId); + case kAbilityGroupSkillsId: + return GetSkillValue(abilityId); + } + return 0; + } + + int GetAbilityPointsForRank(int rankId) { + switch (rankId) { + case kRankPrimaryId: + return 13; + case kRankSecondaryId: + return 9; + case kRankTertiaryId: + return 5; + } + return 0; + } + + void CharacterType::FillAbilityValues(std::vectorabilityValues, int abilityGroupId) const { + int numAbilities = GetNumItemsForAbilityGroup(abilityGroupId); + abilityValues.clear(); + for (int abilityId = 0; abilityId <= numAbilities; abilityId++) { + abilityValues[abilityId] = GetAbilityValue(abilityGroupId, abilityId); + } + } + + int GetNumItemsForAbilityGroup(int abilityGroupId) { + switch (abilityGroupId) { + case kAbilityGroupTalentsId: + return kTalentsCount; + case kAbilityGroupSkillsId: + return kSkillsCount; + case kAbilityGroupKnowledgesId: + return kKnowledgesCount; + } + return 0; + } + + wstring GetAbilityLabel(int abilityGroupId, int abilityId) { + switch (abilityGroupId) { + case kAbilityGroupTalentsId: + return kTalents[abilityId]; + case kAbilityGroupSkillsId: + return kSkills[abilityId]; + case kAbilityGroupKnowledgesId: + return kKnowledges[abilityId]; + } + return L""; + } + + void FillAbilitiesForAbilityGroup(std::vector abilities, int abilityGroupId) { + abilities.clear(); + int numAbilities = GetNumItemsForAbilityGroup(abilityGroupId); + switch (abilityGroupId) { + case kAbilityGroupTalentsId: + for (int talentId = 0; talentId <= numAbilities; talentId++) { + abilities[talentId] = kTalents[talentId]; + } + break; + case kAbilityGroupSkillsId: + for (int skillId = 0; skillId <= numAbilities; skillId++) { + abilities[skillId] = kSkills[skillId]; + } + break; + case kAbilityGroupKnowledgesId: + for (int knowledgeId = 0; knowledgeId <= numAbilities; knowledgeId++) { + abilities[knowledgeId] = kKnowledges[knowledgeId]; + } + break; + } + } + + void CharacterType::SetTalentValue(int talentId, int value) { + switch (talentId) { + case kTalentActingId: + talent_acting = value; + break; + case kTalentAlertnessId: + talent_alertness = value; + break; + case kTalentAthleticsId: + talent_athletics = value; + break; + case kTalentBrawlId: + talent_brawl = value; + break; + case kTalentDodgeId: + talent_dodge = value; + break; + case kTalentEmpathyId: + talent_empathy = value; + break; + case kTalentIntimidationId: + talent_intimidation = value; + break; + case kTalentLeadershipId: + talent_leadership = value; + break; + case kTalentStreetwiseId: + talent_streetwise = value; + break; + case kTalentSubterfugeId: + talent_subterfuge = value; + break; + + } + } + + int CharacterType::GetTalentValue(int talentId) const { + switch (talentId) { + case kTalentActingId: + return talent_acting; + case kTalentAlertnessId: + return talent_alertness; + case kTalentAthleticsId: + return talent_athletics; + case kTalentBrawlId: + return talent_brawl; + case kTalentDodgeId: + return talent_dodge; + case kTalentEmpathyId: + return talent_empathy; + case kTalentIntimidationId: + return talent_intimidation; + case kTalentLeadershipId: + return talent_leadership; + case kTalentStreetwiseId: + return talent_streetwise; + case kTalentSubterfugeId: + return talent_subterfuge; + } + return 0; + } + + void CharacterType::SetSkillValue(int skillId, int value) { + switch (skillId) { + case kSkillAnimalKenId: + skill_animalKen = value; + break; + case kSkillDriveId: + skill_drive = value; + break; + case kSkillEtiquetteId: + skill_etiquette = value; + break; + case kSkillFirearmsId: + skill_firearms = value; + break; + case kSkillMeleeId: + skill_melee = value; + break; + case kSkillMusicId: + skill_music = value; + break; + case kSkillRepairId: + skill_repair = value; + break; + case kSkillSecurityId: + skill_security = value; + break; + case kSkillStealthId: + skill_stealth = value; + break; + case kSkillSurvivalId: + skill_survival = value; + break; + } + } + + int CharacterType::GetSkillValue(int skillId) const { + switch (skillId) { + case kSkillAnimalKenId: + return skill_animalKen; + case kSkillDriveId: + return skill_drive; + case kSkillEtiquetteId: + return skill_etiquette; + case kSkillFirearmsId: + return skill_firearms; + case kSkillMeleeId: + return skill_melee; + case kSkillMusicId: + return skill_music; + case kSkillRepairId: + return skill_repair; + case kSkillSecurityId: + return skill_security; + case kSkillStealthId: + return skill_stealth; + case kSkillSurvivalId: + return skill_survival; + } + return 0; + } + + void CharacterType::SetKnowledgeValue(int knowledgeId, int value) { + switch (knowledgeId) { + case kKnowledgeBureaucracyId: + knowledge_bureaucracy = value; + break; + case kKnowledgeComputerId: + knowledge_computer = value; + break; + case kKnowledgeFinanceId: + knowledge_finance = value; + break; + case kKnowledgeInvestigationId: + knowledge_investigation = value; + break; + case kKnowledgeLawId: + knowledge_law = value; + break; + case kKnowledgeLinguisticsId: + knowledge_linguistics = value; + break; + case kKnowledgeMedicineId: + knowledge_medicine = value; + break; + case kKnowledgeOccultId: + knowledge_occult = value; + break; + case kKnowledgePoliticsId: + knowledge_politics = value; + break; + case kKnowledgeScienceId: + knowledge_science = value; + break; + } + } + + int CharacterType::GetKnowledgeValue(int knowledgeId) const { + switch (knowledgeId) { + case kKnowledgeBureaucracyId: + return knowledge_bureaucracy; + case kKnowledgeComputerId: + return knowledge_computer; + case kKnowledgeFinanceId: + return knowledge_finance; + case kKnowledgeInvestigationId: + return knowledge_investigation; + case kKnowledgeLawId: + return knowledge_law; + case kKnowledgeLinguisticsId: + return knowledge_linguistics; + case kKnowledgeMedicineId: + return knowledge_medicine; + case kKnowledgeOccultId: + return knowledge_occult; + case kKnowledgePoliticsId: + return knowledge_politics; + case kKnowledgeScienceId: + return knowledge_science; + } + return 0; + } + + void CharacterType::SetBackgroundValue(int backgroundId, int value) { + switch (backgroundId) { + case kBackgroundAlliesId: + background_allies = value; + break; + case kBackgroundContactsId: + background_contacts = value; + break; + case kBackgroundFameId: + background_fame = value; + break; + case kBackgroundGenerationId: + background_generation = value; + break; + case kBackgroundHerdId: + background_herd = value; + break; + case kBackgroundInfluenceId: + background_influence = value; + break; + case kBackgroundMentorId: + background_mentor = value; + break; + case kBackgroundResourcesId: + background_resources = value; + break; + case kBackgroundRetainersId: + background_retainers = value; + break; + case kBackgroundStatusId: + background_status = value; + break; + } + } + + int CharacterType::GetBackgroundValue(int backgroundId) const { + switch (backgroundId) { + case kBackgroundAlliesId: + return background_allies; + case kBackgroundContactsId: + return background_contacts; + case kBackgroundFameId: + return background_fame; + case kBackgroundGenerationId: + return background_generation; + case kBackgroundHerdId: + return background_herd; + case kBackgroundInfluenceId: + return background_influence; + case kBackgroundMentorId: + return background_mentor; + case kBackgroundResourcesId: + return background_resources; + case kBackgroundRetainersId: + return background_retainers; + case kBackgroundStatusId: + return background_status; + } + return 0; + } + + void CharacterType::FillBackgroundValues(std::vector backgroundValues) const { + backgroundValues.clear(); + for (int backgroundId = 0; backgroundId <= kBackgroundsCount; backgroundId++) { + backgroundValues[backgroundId] = GetBackgroundValue(backgroundId); + } + } + + int GetBackgroundPoints() { + return kBackgroundPoints; + } + + void NewDerangement(DerangementType& derangement, int id, wstring label, int textColor, wstring description) { + derangement.id = id; + derangement.label = label; + derangement.textColor = textColor; + derangement.description = description; + } + + wstring CharacterType::GetAllDerangementsLine() const { + // TODO: Replace this with a stringstream. + std::vector allDerangements; + FillDerangements(allDerangements); + wstring allDerangementsString = L""; + std::for_each(allDerangements.begin(), allDerangements.end(), [&allDerangementsString](DerangementType derangement) { + allDerangementsString += derangement.label + L", "; + }); + return allDerangementsString; + } + + void CharacterType::FillDerangements(std::vector derangements) const { + derangements.clear(); + if (derangementId > 0) { + derangements[0] = kDerangements[derangementId]; + } + } +} // End namespace SBF + \ No newline at end of file diff --git a/sbf-cpp/Character.h b/sbf-cpp/Character.h new file mode 100644 index 0000000..4c6df60 --- /dev/null +++ b/sbf-cpp/Character.h @@ -0,0 +1,846 @@ +#ifndef CHARACTER_H__ +#define CHARACTER_H__ +#include "Colors.h" +#include +#include +#include + +namespace SBF { + using std::wstring; + + const int kRankPrimaryId = 1; + const wstring kRankPrimaryLabel = L"Primary"; + const int kRankSecondaryId = 2; + const wstring kRankSecondaryLabel = L"Secondary"; + const int kRankTertiaryId = 3; + const wstring kRankTertiaryLabel = L"Tertiary"; + const int kRanksCount = 3; + struct RankType { + int id; + wstring label; + }; + const RankType kRanks[] { + {0, L""}, + {kRankPrimaryId, kRankPrimaryLabel}, + {kRankSecondaryId, kRankSecondaryLabel}, + {kRankTertiaryId, kRankTertiaryLabel}, + }; + + const int kClanAnarch = 1; + const wstring kClanAnarchLabel = L"Anarch"; + const int kClanAssamite = 2; + const wstring kClanAssamiteLabel = L"Assamite"; + const int kClanBaali = 3; + const wstring kClanBaaliLabel = L"Baali"; + const int kClanBrujah = 4; + const wstring kClanBrujahLabel = L"Brujah"; + const int kClanCaitiff = 5; + const wstring kClanCaitiffLabel = L"Caitiff"; + const int kClanCappadocian = 6; + const wstring kClanCappadocianLabel = L"Cappadocian"; + const int kClanGangrel = 7; + const wstring kClanGangrelLabel = L"Gangrel"; + const int kClanGiovanni = 8; + const wstring kClanGiovanniLabel = L"Giovanni"; + const int kClanInconnu = 9; + const wstring kClanInconnuLabel = L"Inconnu"; + const int kClanLasombra = 10; + const wstring kClanLasombraLabel = L"Lasombra"; + const int kClanMalkavian = 11; + const wstring kClanMalkavianLabel = L"Malkavian"; + const int kClanNosferatu = 12; + const wstring kClanNosferatuLabel = L"Nosferatu"; + const int kClanRavanos = 13; + const wstring kClanRavanosLabel = L"Ravanos"; + const int kClanSettite = 14; + const wstring kClanSettiteLabel = L"Settite"; + const int kClanToreador = 15; + const wstring kClanToreadorLabel = L"Toreador"; + const int kClanTremere = 16; + const wstring kClanTremereLabel = L"Tremere"; + const int kClanTzismice = 17; + const wstring kClanTzismiceLabel = L"Tzismice"; + const int kClanVentrue = 18; + const wstring kClanVentrueLabel = L"Ventrue"; + const int kClansCount = 18; + const wstring kClans[] = { + L"", + kClanAnarchLabel, + kClanAssamiteLabel, + kClanBaaliLabel, + kClanBrujahLabel, + kClanCaitiffLabel, + kClanCappadocianLabel, + kClanGiovanniLabel, + kClanInconnuLabel, + kClanLasombraLabel, + kClanMalkavianLabel, + kClanNosferatuLabel, + kClanRavanosLabel, + kClanSettiteLabel, + kClanToreadorLabel, + kClanTremereLabel, + kClanVentrueLabel, + }; + + const int kArchetypeArchitectId = 1; + const wstring kArchetypeArchitectLabel = L"Architect"; + const int kArchetypeAutocratId = 2; + const wstring kArchetypeAutocratLabel = L"Autocrat"; + const int kArchetypeBarbarianId = 3; + const wstring kArchetypeBarbarianLabel = L"Barbarian"; + const int kArchetypeBonVivantId = 4; + const wstring kArchetypeBonVivantLabel = L"Bon Vivant"; + const int kArchetypeBravoId = 5; + const wstring kArchetypeBravoLabel = L"Bravo"; + const int kArchetypeCaregiverId = 6; + const wstring kArchetypeCaregiverLabel = L"Caregiver"; + const int kArchetypeCaretakerId = 7; + const wstring kArchetypeCaretakerLabel = L"Caretaker"; + const int kArchetypeCelebrantId = 8; + const wstring kArchetypeCelebrantLabel = L"Celebrant"; + const int kArchetypeChildId = 9; + const wstring kArchetypeChildLabel = L"Child"; + const int kArchetypeConformist = 10; + const wstring kArchetypeConformistLabel = L"Conformist"; + const int kArchetypeConniverId = 11; + const wstring kArchetypeConniverLabel = L"Conniver"; + const int kArchetypeCurmudgeonId = 12; + const wstring kArchetypeCurmudgeonLabel = L"Curmudgeon"; + const int kArchetypeDefenderId = 13; + const wstring kArchetypeDefenderLabel = L"Defender"; + const int kArchetypeDeviantId = 14; + const wstring kArchetypeDeviantLabel = L"Deviant"; + const int kArchetypeDirectorId = 15; + const wstring kArchetypeDirectorLabel = L"Director"; + const int kArchetypeFanaticId = 16; + const wstring kArchetypeFanaticLabel = L"Fanatic"; + const int kArchetypeGallantId = 17; + const wstring kArchetypeGallantLabel = L"Gallant"; + const int kArchetypeInnovatorId = 18; + const wstring kArchetypeInnovatorLabel = L"Innovator"; + const int kArchetypeJesterId = 19; + const wstring kArchetypeJesterLabel = L"Jester"; + const int kArchetypeJudgeId = 20; + const wstring kArchetypeJudgeLabel = L"Judge"; + const int kArchetypeLoanerId = 21; + const wstring kArchetypeLoanerLabel = L"Loaner"; + const int kArchetypeMartyrId = 22; + const wstring kArchetypeMartyrLabel = L"Martyr"; + const int kArchetypeMonsterId = 23; + const wstring kArchetypeMonsterLabel = L"Monster"; + const int kArchetypePenitentId = 24; + const wstring kArchetypePenitentLabel = L"Penitent"; + const int kArchetypeRebelId = 25; + const wstring kArchetypeRebelLabel = L"Rebel"; + const int kArchetypeRogueId = 26; + const wstring kArchetypeRogueLabel = L"Rogue"; + const int kArchetypeSurvivorId = 27; + const wstring kArchetypeSurvivorLabel = L"Survivor"; + const int kArchetypeTraditionalistId = 28; + const wstring kArchetypeTraditionalistLabel = L"Traditionalist"; + const int kArchetypeTyrantId = 29; + const wstring kArchetypeTyrantLabel = L"Tyrant"; + const int kArchetypeVisionaryId = 30; + const wstring kArchetypeVisionaryLabel = L"Visionary"; + const int kArchetypesCount = 30; + const wstring kArchetypes[] = { + L"", + kArchetypeArchitectLabel, + kArchetypeAutocratLabel, + kArchetypeBarbarianLabel, + kArchetypeBonVivantLabel, + kArchetypeBravoLabel, + kArchetypeCaregiverLabel, + kArchetypeCaretakerLabel, + kArchetypeCelebrantLabel, + kArchetypeChildLabel, + kArchetypeConformistLabel, + kArchetypeConniverLabel, + kArchetypeCurmudgeonLabel, + kArchetypeDefenderLabel, + kArchetypeDeviantLabel, + kArchetypeDirectorLabel, + kArchetypeFanaticLabel, + kArchetypeGallantLabel, + kArchetypeInnovatorLabel, + kArchetypeJesterLabel, + kArchetypeJudgeLabel, + kArchetypeLoanerLabel, + kArchetypeMartyrLabel, + kArchetypeMonsterLabel, + kArchetypePenitentLabel, + kArchetypeRebelLabel, + kArchetypeRogueLabel, + kArchetypeSurvivorLabel, + kArchetypeTraditionalistLabel, + kArchetypeTyrantLabel, + kArchetypeVisionaryLabel, + }; + + const int kDisciplinePoints = 3; + const int kDisciplineAnimalismId = 1; + const wstring kDisciplineAnimalismLabel = L"Animalism"; + const int kDisciplineAuspexId = 2; + const wstring kDisciplineAuspexLabel = L"Auspex"; + const int kDisciplineBardoId = 3; + const wstring kDisciplineBardoLabel = L"Bardo"; + const int kDisciplineCelerityId = 4; + const wstring kDisciplineCelerityLabel = L"Celerity"; + const int kDisciplineChimestryId = 5; + const wstring kDisciplineChimestryLabel = L"Chimestry"; + const int kDisciplineDementationId = 6; + const wstring kDisciplineDementationLabel = L"Dementation"; + const int kDisciplineDominateId = 7; + const wstring kDisciplineDominateLabel = L"Dominate"; + const int kDisciplineFortitudeId = 8; + const wstring kDisciplineFortitudeLabel = L"Fortitude"; + const int kDisciplineMelpomineeId = 9; + const wstring kDisciplineMelpomineeLabel = L"Melpominee"; + const int kDisciplineMortisId = 10; + const wstring kDisciplineMortisLabel = L"Mortis"; + const int kDisciplineMytherceriaId = 11; + const wstring kDisciplineMytherceriaLabel = L"Mytherceria"; + const int kDisciplineNecromancyId = 12; + const wstring kDisciplineNecromancyLabel = L"Necromancy"; + const int kDisciplineObeahId = 13; + const wstring kDisciplineObeahLabel = L"Obeah"; + const int kDisciplineObfuscateId = 14; + const wstring kDisciplineObfuscateLabel = L"Obfuscate"; + const int kDisciplineObtenebrationId = 15; + const wstring kDisciplineObtenebrationLabel = L"Obtenebration"; + const int kDisciplinePotenceId = 16; + const wstring kDisciplinePotenceLabel = L"Potence"; + const int kDisciplinePresenceId = 17; + const wstring kDisciplinePresenceLabel = L"Presence"; + const int kDisciplineProteanId = 18; + const wstring kDisciplineProteanLabel = L"Protean"; + const int kDisciplineQuietusId = 19; + const wstring kDisciplineQuietusLabel = L"Quietus"; + const int kDisciplineSerpentisId = 20; + const wstring kDisciplineSerpentisLabel = L"Serpentis"; + const int kDisciplineSpiritusId = 21; + const wstring kDisciplineSpiritusLabel = L"Spiritus"; + const int kDisciplineThanantosisId = 22; + const wstring kDisciplineThanantosisLabel = L"Thanantosis"; + const int kDisciplineThaumaturgyId = 23; + const wstring kDisciplineThaumaturgyLabel = L"Thaumaturgy"; + const int kDisciplineVicissitudeId = 24; + const wstring kDisciplineVicissitudeLabel = L"Vicissitude"; + const int kDisciplinesCount = 24; + const wstring kDisciplines[] = { + L"", + kDisciplineAnimalismLabel, + kDisciplineAuspexLabel, + kDisciplineBardoLabel, + kDisciplineCelerityLabel, + kDisciplineChimestryLabel, + kDisciplineDementationLabel, + kDisciplineDominateLabel, + kDisciplineFortitudeLabel, + kDisciplineMelpomineeLabel, + kDisciplineMortisLabel, + kDisciplineMytherceriaLabel, + kDisciplineNecromancyLabel, + kDisciplineObeahLabel, + kDisciplineObfuscateLabel, + kDisciplineObtenebrationLabel, + kDisciplinePotenceLabel, + kDisciplinePresenceLabel, + kDisciplineProteanLabel, + kDisciplineQuietusLabel, + kDisciplineSerpentisLabel, + kDisciplineSpiritusLabel, + kDisciplineThanantosisLabel, + kDisciplineThaumaturgyLabel, + kDisciplineVicissitudeLabel, + }; + + const int kVirtuePoints = 7; + const int kVirtueSelfControlId = 1; + const wstring kVirtueSelfControlLabel = L"Self-Control"; + const int kVirtueCourageId = 2; + const wstring kVirtueCourageLabel = L"Courage"; + const int kVirtueConscienceId = 3; + const wstring kVirtueConscienceLabel = L"Conscience"; + const int kVirtuesCount = 3; + const wstring kVirtues[] = { + L"", + kVirtueSelfControlLabel, + kVirtueCourageLabel, + kVirtueConscienceLabel, + }; + + const int kPhysicalAttributeStrengthId = 1; + const wstring kPhysicalAttributeStrengthLabel = L"Strength"; + const wstring kPhysicalAttributeStrengthAbbreviation = L"Str."; + const int kPhysicalAttributeDexterityId = 2; + const wstring kPhysicalAttributeDexterityLabel = L"Dexterity"; + const wstring kPhysicalAttributeDexterityAbbreviation = L"Dex."; + const int kPhysicalAttributeStaminaId = 3; + const wstring kPhysicalAttributeStaminaLabel = L"Stamina"; + const wstring kPhysicalAttributeStaminaAbbreviation = L"Sta."; + const int kPhysicalAttributesCount = 3; + const wstring kPhysicalAttributeLabels[] = { + L"", + kPhysicalAttributeStrengthLabel, + kPhysicalAttributeDexterityLabel, + kPhysicalAttributeStaminaLabel, + }; + const wstring kPhysicalAttributeAbbreviations[] = { + L"", + kPhysicalAttributeStrengthAbbreviation, + kPhysicalAttributeDexterityAbbreviation, + kPhysicalAttributeStaminaAbbreviation, + }; + + const int kSocialAttributeCharismaId = 1; + const wstring kSocialAttributeCharismaLabel = L"Charisma"; + const wstring kSocialAttributeCharismaAbbreviation = L"Cha."; + const int kSocialAttributeManipulationId = 2; + const wstring kSocialAttributeManipulationLabel = L"Manipulation"; + const wstring kSocialAttributeManipulationAbbreviation = L"Man."; + const int kSocialAttributeAppearanceId = 3; + const wstring kSocialAttributeAppearanceLabel = L"Appearance"; + const wstring kSocialAttributeAppearanceAbbreviation = L"App."; + const int kSocialAttributesCount = 3; + const wstring kSocialAttributeLabels[] = { + L"", + kSocialAttributeCharismaLabel, + kSocialAttributeManipulationLabel, + kSocialAttributeAppearanceLabel, + }; + const wstring kSocialAttributeAbbreviations[] = { + L"", + kSocialAttributeCharismaAbbreviation, + kSocialAttributeManipulationAbbreviation, + kSocialAttributeAppearanceAbbreviation, + }; + + const int kMentalAttributeIntelligenceId = 1; + const wstring kMentalAttributeIntelligenceLabel = L"Intelligence"; + const wstring kMentalAttributeIntelligenceAbbreviation = L"Int."; + const int kMentalAttributePerceptionId = 2; + const wstring kMentalAttributePerceptionLabel = L"Perception"; + const wstring kMentalAttributePerceptionAbbreviation = L"Per."; + const int kMentalAttributeWitsId = 3; + const wstring kMentalAttributeWitsLabel = L"Wits"; + const wstring kMentalAttributeWitsAbbreviation = L"Wits"; + const int kMentalAttributesCount = 3; + const wstring kMentalAttributeLabels[] = { + L"", + kMentalAttributeIntelligenceLabel, + kMentalAttributePerceptionLabel, + kMentalAttributeWitsLabel, + }; + const wstring kMentalAttributeAbbreviations[] = { + L"", + kMentalAttributeIntelligenceLabel, + kMentalAttributePerceptionAbbreviation, + kMentalAttributeWitsAbbreviation, + }; + + const int kAttributeGroupPhysicalId = 1; + const wstring kAttributeGroupPhysicalLabel = L"Physical"; + const int kAttributeGroupSocialId = 2; + const wstring kAttributeGroupSocialLabel = L"Social"; + const int kAttributeGroupMentalId = 3; + const wstring kAttributeGroupMentalLabel = L"Mental"; + const int kAttributeGroupsCount = 3; + const wstring kAttributeGroups[] = { + L"", + kAttributeGroupPhysicalLabel, + kAttributeGroupSocialLabel, + kAttributeGroupMentalLabel, + }; + + const int kAbilityGroupTalentsId = 1; + const wstring kAbilityGroupTalentsSingular = L"Talent"; + const wstring kAbilityGroupTalentsPlural = L"Talents"; + const int kAbilityGroupSkillsId = 2; + const wstring kAbilityGroupSkillsSingular = L"Skill"; + const wstring kAbilityGroupSkillsPlural = L"Skills"; + const int kAbilityGroupKnowledgesId = 3; + const wstring kAbilityGroupKnowledgesSingular = L"Skill"; + const wstring kAbilityGroupKnowledgesPlural = L"Skills"; + const int kAbilityGroupsCount = 3; + struct AbilityType { + int id; + wstring singular; + wstring plural; + }; + const AbilityType kAbilityGroups[] { + {0, L"", L""}, + {kAbilityGroupTalentsId, kAbilityGroupTalentsSingular, kAbilityGroupTalentsPlural}, + {kAbilityGroupSkillsId, kAbilityGroupSkillsSingular, kAbilityGroupSkillsPlural}, + {kAbilityGroupKnowledgesId, kAbilityGroupKnowledgesSingular, kAbilityGroupKnowledgesPlural}, + }; + + const int kTalentActingId = 1; + const wstring kTalentActingLabel = L"Acting"; + const int kTalentAlertnessId = 2; + const wstring kTalentAlertnessLabel = L"Alertness"; + const int kTalentAthleticsId = 3; + const wstring kTalentAthleticsLabel = L"Athletics"; + const int kTalentBrawlId = 4; + const wstring kTalentBrawlLabel = L"Brawl"; + const int kTalentDodgeId = 5; + const wstring kTalentDodgeLabel = L"Dodge"; + const int kTalentEmpathyId = 6; + const wstring kTalentEmpathyLabel = L"Empathty"; + const int kTalentIntimidationId = 7; + const wstring kTalentIntimidationLabel = L"Intimidation"; + const int kTalentLeadershipId = 8; + const wstring kTalentLeadershipLabel = L"Leadership"; + const int kTalentStreetwiseId = 9; + const wstring kTalentStreetwiseLabel = L"Streetwise"; + const int kTalentSubterfugeId = 10; + const wstring kTalentSubterfugeLabel = L"Subterfuge"; + const int kTalentsCount = 10; + const wstring kTalents[] = { + L"", + kTalentActingLabel, + kTalentAlertnessLabel, + kTalentAthleticsLabel, + kTalentBrawlLabel, + kTalentDodgeLabel, + kTalentEmpathyLabel, + kTalentIntimidationLabel, + kTalentLeadershipLabel, + kTalentStreetwiseLabel, + kTalentSubterfugeLabel, + }; + + const int kSkillAnimalKenId = 1; + const wstring kSkillAnimalKenLabel = L"AnimalKen"; + const int kSkillDriveId = 2; + const wstring kSkillDriveLabel = L"Drive"; + const int kSkillEtiquetteId = 3; + const wstring kSkillEtiquetteLabel = L"Etiquette"; + const int kSkillFirearmsId = 4; + const wstring kSkillFirearmsLabel = L"Firearms"; + const int kSkillMeleeId = 5; + const wstring kSkillMeleeLabel = L"Melee"; + const int kSkillMusicId = 6; + const wstring kSkillMusicLabel = L"Music"; + const int kSkillRepairId = 7; + const wstring kSkillRepairLabel = L"Repair"; + const int kSkillSecurityId = 8; + const wstring kSkillSecurityLabel = L"Security"; + const int kSkillStealthId = 9; + const wstring kSkillStealthLabel = L"Stealth"; + const int kSkillSurvivalId = 10; + const wstring kSkillSurvivalLabel = L"Survival"; + const int kSkillsCount = 10; + const wstring kSkills[] = { + L"", + kSkillAnimalKenLabel, + kSkillDriveLabel, + kSkillEtiquetteLabel, + kSkillFirearmsLabel, + kSkillMeleeLabel, + kSkillMusicLabel, + kSkillRepairLabel, + kSkillSecurityLabel, + kSkillStealthLabel, + kSkillSurvivalLabel, + }; + + const int kKnowledgeBureaucracyId = 1; + const wstring kKnowledgeBureaucracyLabel = L"Bureaucracy"; + const int kKnowledgeComputerId = 2; + const wstring kKnowledgeComputerLabel = L"Computer"; + const int kKnowledgeFinanceId = 3; + const wstring kKnowledgeFinanceLabel = L"Finance"; + const int kKnowledgeInvestigationId = 4; + const wstring kKnowledgeInvestigationLabel = L"Investigation"; + const int kKnowledgeLawId = 5; + const wstring kKnowledgeLawLabel = L"Law"; + const int kKnowledgeLinguisticsId = 6; + const wstring kKnowledgeLinguisticsLabel = L"Linguistics"; + const int kKnowledgeMedicineId = 7; + const wstring kKnowledgeMedicineLabel = L"Medicine"; + const int kKnowledgeOccultId = 8; + const wstring kKnowledgeOccultLabel = L"Occult"; + const int kKnowledgePoliticsId = 9; + const wstring kKnowledgePoliticsLabel = L"Politics"; + const int kKnowledgeScienceId = 10; + const wstring kKnowledgeScienceLabel = L"Science"; + const int kKnowledgesCount = 10; + const wstring kKnowledges[] = { + L"", + kKnowledgeBureaucracyLabel, + kKnowledgeComputerLabel, + kKnowledgeFinanceLabel, + kKnowledgeInvestigationLabel, + kKnowledgeLawLabel, + kKnowledgeLinguisticsLabel, + kKnowledgeMedicineLabel, + kKnowledgeOccultLabel, + kKnowledgePoliticsLabel, + kKnowledgeScienceLabel, + }; + + const int kBackgroundPoints = 5; + const int kBackgroundAlliesId = 1; + const wstring kBackgroundAlliesLabel = L"Allies"; + const int kBackgroundContactsId = 2; + const wstring kBackgroundContactsLabel = L"Contacts"; + const int kBackgroundFameId = 3; + const wstring kBackgroundFameLabel = L"Fame"; + const int kBackgroundGenerationId = 4; + const wstring kBackgroundGenerationLabel = L"Generation"; + const int kBackgroundHerdId = 5; + const wstring kBackgroundHerdLabel = L"Herd"; + const int kBackgroundInfluenceId = 6; + const wstring kBackgroundInfluenceLabel = L"Influence"; + const int kBackgroundMentorId = 7; + const wstring kBackgroundMentorLabel = L"Mentor"; + const int kBackgroundResourcesId = 8; + const wstring kBackgroundResourcesLabel = L"Resources"; + const int kBackgroundRetainersId = 9; + const wstring kBackgroundRetainersLabel = L"Retainers"; + const int kBackgroundStatusId = 10; + const wstring kBackgroundStatusLabel = L"Status"; + const int kBackgroundsCount = 10; + const wstring kBackgroundLabels[] = { + L"", + kBackgroundAlliesLabel, + kBackgroundContactsLabel, + kBackgroundFameLabel, + kBackgroundGenerationLabel, + kBackgroundHerdLabel, + kBackgroundInfluenceLabel, + kBackgroundMentorLabel, + kBackgroundResourcesLabel, + kBackgroundRetainersLabel, + kBackgroundStatusLabel, + }; + + const int kGenderMaleId = 1; + const wstring kGenderMaleLabel = L"Male"; + const int kGenderFemaleId = 2; + const wstring kGenderFemaleLabel = L"Female"; + const int kGenderTransMaleId = 3; + const wstring kGenderTransMaleLabel = L"Trans-Male"; + const int kGenderTransFemaleId = 4; + const wstring kGenderTransFemaleLabel = L"Trans-Female"; + const int kGenderNonBinaryId = 5; + const wstring kGenderNonBinaryLabel = L"Non-Binary"; + const int kGendersCount = 5; + const wstring kGenderLabels[] = { + L"", + kGenderMaleLabel, + kGenderFemaleLabel, + kGenderTransMaleLabel, + kGenderTransFemaleLabel, + kGenderNonBinaryLabel, + }; + + struct DerangementType { + int id; + wstring label; + wstring description; + uint8_t textColor; + }; + + const int kDerangementAmnesiaId = 1; + const uint8_t kDerangementAmnesiaTextColor= kColorDarkRed; + const wstring kDerangementAmnesiaLabel = L"Amnesia"; + const wstring kDerangementAmnesiaDescription = LR"---(You forget a segment of your past. Additionally in some cases a character can forget abilities and be unable to use them for the duration.)---"; + const int kDerangementDelusionsOfGrandeurId = 2; + const uint8_t kDerangementDelusionsOfGrandeurTextColor= kColorDarkMagenta; + const wstring kDerangementDelusionsOfGrandeurLabel = L"Delusions of Grandeur"; + const wstring kDerangementDelusionsOfGrandeurDescription = LR"---(You imagine you are better than you are.)---"; + const int kDerangementFantasyId = 3; + const uint8_t kDerangementFantasyTextColor= kColorDarkOrange; + const wstring kDerangementFantasyLabel = L"Fantasy"; + const wstring kDerangementFantasyDescription = LR"---(You enter a self-created world where you are the forgotten hero.)---"; + const int kDerangementManicDepressionId = 4; + const uint8_t kDerangementManicDepressionTextColor= kColorDarkWhite; + const wstring kDerangementManicDepressionLabel = L"Manic-Depression"; + const wstring kDerangementManicDepressionDescription = LR"---(You sink into deep and fitful depressions, showing no interest in anything which used to captivate your interests. You will go along with others rather than use the energy to resist. Occasional fits of great energy grab hold of you, and you will work for hours or even days on your projects. During this time you will resist even the need for sleep as you burn up blood and Willpower on your schemes.)---"; + const int kDerangementMultiplePersonalitiesId = 5; + const uint8_t kDerangementMultiplePersonalitiesTextColor= kColorDarkBlue; + const wstring kDerangementMultiplePersonalitiesLabel = L"Multiple Personalities"; + const wstring kDerangementMultiplePersonalitiesDescription = LR"---(You possess a number of new personalities. You have amore than one Mature, and will switch between them. Thus you regain Willpower points in defferent ways at defferent times)---"; + const int kDerangementObsessionId = 6; + const uint8_t kDerangementObsessionTextColor= kColorBrightGreen; + const wstring kDerangementObsessionLabel = L"Obsession"; + const wstring kDerangementObsessionDescription = LR"---(You become obsessed with some interest or fetish.)---"; + const int kDerangementOvercompensationId = 7; + const uint8_t kDerangementOvercompensationTextColor= kColorBrightCyan; + const wstring kDerangementOvercompensationLabel = L"Overcompensation"; + const wstring kDerangementOvercompensationDescription = LR"---(You make up for your moral weaknesses by playing up your strengths to an extreme. You don't think you can frenzy and won't stop it.)---"; + const int kDerangementParanoiaId = 8; + const uint8_t kDerangementParanoiaTextColor= kColorBrightRed; + const wstring kDerangementParanoiaLabel = L"Paranoia"; + const wstring kDerangementParanoiaDescription = LR"---(You are convinced that you are being hunted. You hold even your closest Friends under suspicion.)---"; + const int kDerangementPerfectionId = 9; + const uint8_t kDerangementPerfectionTextColor= kColorBrightMagenta; + const wstring kDerangementPerfectionLabel = L"Perfection"; + const wstring kDerangementPerfectionDescription = LR"---(All your energy is directed toward preventing anything from going wong. When it does you must make a self-control roll or frenzy.)---"; + const int kDerangementRegressionId = 10; + const uint8_t kDerangementRegressionTextColor= kColorBrightYellow; + const wstring kDerangementRegressionLabel = L"Regression"; + const wstring kDerangementRegressionDescription = LR"---(You become childlike retreating to an earlier time when less was expected of you Willpower is regained inthe way a Child's is.)---"; + const DerangementType kDerangementAmnesia = { + kDerangementAmnesiaId, + kDerangementAmnesiaLabel, + kDerangementAmnesiaDescription, + kDerangementAmnesiaTextColor, + }; + const DerangementType kDerangementDelusionsOfGrandeur = { + kDerangementDelusionsOfGrandeurId, + kDerangementDelusionsOfGrandeurLabel, + kDerangementDelusionsOfGrandeurDescription, + kDerangementDelusionsOfGrandeurTextColor, + }; + const DerangementType kDerangementFantasy = { + kDerangementFantasyId, + kDerangementFantasyLabel, + kDerangementFantasyDescription, + kDerangementFantasyTextColor, + }; + const DerangementType kDerangementManicDepression = { + kDerangementManicDepressionId, + kDerangementManicDepressionLabel, + kDerangementManicDepressionDescription, + kDerangementManicDepressionTextColor, + }; + const DerangementType kDerangementMultiplePersonalities = { + kDerangementMultiplePersonalitiesId, + kDerangementMultiplePersonalitiesLabel, + kDerangementMultiplePersonalitiesDescription, + kDerangementMultiplePersonalitiesTextColor, + }; + const DerangementType kDerangementObsession = { + kDerangementObsessionId, + kDerangementObsessionLabel, + kDerangementObsessionDescription, + kDerangementObsessionTextColor, + }; + const DerangementType kDerangementOvercompensation = { + kDerangementOvercompensationId, + kDerangementOvercompensationLabel, + kDerangementOvercompensationDescription, + kDerangementOvercompensationTextColor, + }; + const DerangementType kDerangementParanoia = { + kDerangementParanoiaId, + kDerangementParanoiaLabel, + kDerangementParanoiaDescription, + kDerangementParanoiaTextColor, + }; + const DerangementType kDerangementPerfection = { + kDerangementPerfectionId, + kDerangementPerfectionLabel, + kDerangementPerfectionDescription, + kDerangementPerfectionTextColor, + }; + const DerangementType kDerangementRegression = { + kDerangementRegressionId, + kDerangementRegressionLabel, + kDerangementRegressionDescription, + kDerangementRegressionTextColor, + }; + const int kDerangementsCount = 10; + + const uint8_t kDerangementTextColors[] = { + 0, + kDerangementAmnesiaTextColor, + kDerangementDelusionsOfGrandeurTextColor, + kDerangementFantasyTextColor, + kDerangementManicDepressionTextColor, + kDerangementMultiplePersonalitiesTextColor, + kDerangementObsessionTextColor, + kDerangementOvercompensationTextColor, + kDerangementParanoiaTextColor, + kDerangementPerfectionTextColor, + kDerangementRegressionTextColor, + }; + + const wstring kDerangementLabels[] = { + L"", + kDerangementAmnesiaLabel, + kDerangementDelusionsOfGrandeurLabel, + kDerangementFantasyLabel, + kDerangementManicDepressionLabel, + kDerangementMultiplePersonalitiesLabel, + kDerangementObsessionLabel, + kDerangementOvercompensationLabel, + kDerangementParanoiaLabel, + kDerangementPerfectionLabel, + kDerangementRegressionLabel, + }; + + const wstring kDerangementDescriptions[] = { + L"", + kDerangementAmnesiaDescription, + kDerangementDelusionsOfGrandeurDescription, + kDerangementFantasyDescription, + kDerangementManicDepressionDescription, + kDerangementMultiplePersonalitiesDescription, + kDerangementObsessionDescription, + kDerangementOvercompensationDescription, + kDerangementParanoiaDescription, + kDerangementPerfectionDescription, + kDerangementRegressionDescription, + }; + + const DerangementType kDerangements[] = { + {0, L"", L"", 0}, + kDerangementAmnesia, + kDerangementDelusionsOfGrandeur, + kDerangementFantasy, + kDerangementManicDepression, + kDerangementMultiplePersonalities, + kDerangementObsession, + kDerangementOvercompensation, + kDerangementParanoia, + kDerangementPerfection, + kDerangementRegression, + }; + + int GetDisciplinePoints(); + int GetNumItemsForAbilityGroup(int abilityGroupId); + + class CharacterType { + public: + CharacterType(); + void FillAbilityValues(std::vectorabilityValues, int abilityGroupId) const; + void FillAttributeValues(std::vector attributeValues, int groupId) const; + void FillBackgroundValues(std::vector backgroundValues) const; + void FillDisciplineValues(std::vector disciplineValues) const; + void FillDerangements(std::vector derangements) const; + void FillVirtueValues(std::vector virtueValues) const; + int GetAbilityValue(int abilityGroupId, int abilityId) const; + int GetAttributeValue(int attributeGroupId, int abilityId) const; + int GetBackgroundValue(int backgroundId) const; + wstring GetAllDerangementsLine() const; + int GetDisciplineValue(int disciplineId) const; + int GetKnowledgeValue(int knowledgeId) const; + int GetSkillValue(int skillId) const; + int GetTalentValue(int talentId) const; + int GetVirtueValue(int virtueId) const; + void SetAbilityValue(int abilityGroupId, int abilityId, int value); + void SetAttributeValue(int attributeGroupId, int attributeId, int value); + void SetBackgroundValue(int backgroundId, int value); + void SetDisciplineValue(int disciplineId, int value); + void SetKnowledgeValue(int knowledgeId, int value); + void SetSkillValue(int skillId, int value); + void SetTalentValue(int talentId, int value); + void SetVirtueValue(int virtueId, int value); + + wstring name; + wstring player; + wstring chronicle; + wstring haven; + wstring concept; + wstring age; + int genderId; + int clanId; + int natureId; + int demeanorId; + int conscience; + int selfControl; + int courage; + int generation; + wstring roadName; + int roadValue; + int willpower; + int bloodPool; + int derangementId; + + private: + // Disciplines + int discipline_animalism; + int discipline_auspex; + int discipline_bardo; + int discipline_celerity; + int discipline_chimestry; + int discipline_dementation; + int discipline_dominate; + int discipline_fortitude; + int discipline_melpominee; + int discipline_mortis; + int discipline_mytherceria; + int discipline_necromancy; + int discipline_obeah; + int discipline_obfuscate; + int discipline_obtenebration; + int discipline_potence; + int discipline_presence; + int discipline_protean; + int discipline_quietus; + int discipline_serpentis; + int discipline_spiritus; + int discipline_thanantosis; + int discipline_thaumaturgy; + int discipline_vicissitude; + + // Attributes + int attr_strength; + int attr_dexterity; + int attr_stamina; + int attr_appearance; + int attr_charisma; + int attr_manipulation; + int attr_intelligence; + int attr_perception; + int attr_wits; + + // Talents + int talent_acting; + int talent_alertness; + int talent_athletics; + int talent_brawl; + int talent_dodge; + int talent_empathy; + int talent_intimidation; + int talent_leadership; + int talent_streetwise; + int talent_subterfuge; + + // Skills + int skill_animalKen; + int skill_drive; + int skill_etiquette; + int skill_firearms; + int skill_melee; + int skill_music; + int skill_repair; + int skill_security; + int skill_stealth; + int skill_survival; + + // Knowledges + int knowledge_bureaucracy; + int knowledge_computer; + int knowledge_finance; + int knowledge_investigation; + int knowledge_law; + int knowledge_linguistics; + int knowledge_medicine; + int knowledge_occult; + int knowledge_politics; + int knowledge_science; + + // Backgrounds + int background_allies; + int background_contacts; + int background_fame; + int background_generation; + int background_herd; + int background_influence; + int background_mentor; + int background_resources; + int background_retainers; + int background_status; + }; + + int GetVirtuePoints(); + +} // End namespace SBF + +#endif // !defined CHARACTER_H__ diff --git a/sbf-cpp/Colors.cpp b/sbf-cpp/Colors.cpp new file mode 100644 index 0000000..eb63ebc --- /dev/null +++ b/sbf-cpp/Colors.cpp @@ -0,0 +1,23 @@ +#include "Colors.h" + +namespace SBF { + + // TODO: Update these if they're wrong. They should be the initial color pair. + static uint8_t g_foregroundColor = kColorDarkWhite; + static uint8_t g_backgroundColor = kColorDarkBlack; + static uint16_t g_color; + + void SetForegroundColor(uint8_t foregroundColor) { + g_foregroundColor = foregroundColor; + // TODO: update g_color with g_foregroundColor and g_backgroundColor. + } + uint8_t GetForegroundColor() { + return g_foregroundColor; + } + + // ncurses color pair + uint16_t GetColor() { + return g_color; + } + +} // End namespace SBF diff --git a/sbf-cpp/Colors.h b/sbf-cpp/Colors.h new file mode 100644 index 0000000..e9677b0 --- /dev/null +++ b/sbf-cpp/Colors.h @@ -0,0 +1,33 @@ +#ifndef COLORS_H__ +#define COLORS_H__ +#include + +namespace SBF { + + const uint8_t kColorDarkBlack = 0; + const uint8_t kColorDarkBlue = 1; + const uint8_t kColorDarkGreen = 2; + const uint8_t kColorDarkCyan = 3; + const uint8_t kColorDarkRed = 4; + const uint8_t kColorDarkMagenta = 5; + const uint8_t kColorDarkOrange = 6; + const uint8_t kColorDarkYellow = 6; + const uint8_t kColorDarkWhite = 7; + const uint8_t kColorBrightBlack = 8; + const uint8_t kColorBrightBlue = 9; + const uint8_t kColorBrightGreen = 10; + const uint8_t kColorBrightCyan = 11; + const uint8_t kColorBrightRed = 12; + const uint8_t kColorBrightMagenta = 13; + const uint8_t kColorBrightOrange = 14; + const uint8_t kColorBrightYellow = 14; + const uint8_t kColorBrightWhite = 15; + + void SetForegroundColor(uint8_t foregroundColor); + uint8_t GetForegroundColor(); + // ncurses color pair + uint16_t GetColor(); + +} // End namespace SBF + +#endif diff --git a/sbf-cpp/Menus.cpp b/sbf-cpp/Menus.cpp new file mode 100644 index 0000000..d8b8928 --- /dev/null +++ b/sbf-cpp/Menus.cpp @@ -0,0 +1,180 @@ +#include "Menus.h" + +namespace SBF { + + int GetRandomMenuItemId (std::vector items); + void BuildMenu(std::vector items, std::vector labels); + void BuildMenuWithValues(std::vector items, std::vector labels, std::vector values); + void BuildMenuWithColors(std::vector items, std::vector labels, std::vector colors); + void AdjustMenuStyle(MenuStyle& style, std::vector items, bool ignoreValue); + void PrintMenu(std::vector items, MenuStyle style); + wstring GetTitle(MenuItem item, MenuStyle style); + wstring GetTitleWithoutValue(MenuItem item, MenuStyle style); + void NewMenuStyle(MenuStyle& style); + void NewMenuItem(MenuItem& item, wstring label, int id); + void NewMenuItemWithValue(MenuItem& item, wstring label, int id, int value); + void NewMenuItemWithColor(MenuItem& item, wstring label, int id, uint8_t color); + +} // End namespace SBF + +/* +Function GetRandomMenuItemId (items() As MenuItem, count As Integer) + numVisibleItems = 0 + Dim visibleItems(count) As Integer + For i = 1 To count + If items(i).isVisible Then + visibleItems(numVisibleItems) = i + numVisibleItems = numVisibleItems + 1 + End If + Next + i = GetRandomInt(0, numVisibleItems - 1) + GetRandomMenuItemId = visibleItems(i) +End Function + +Sub BuildMenu (items() As MenuItem, labels() As String, count As Integer) + For i = 1 To count + Dim mi As MenuItem + Call NewMenuItem(mi, labels(i), i) + items(i) = mi + Next +End Sub + + +Sub BuildMenuWithValues (items() As MenuItem, labels() As String, values() As Integer, count As Integer) + For i = 1 To count + Dim mi As MenuItem + Call NewMenuItemWithValue(mi, labels(i), i, values(i)) + items(i) = mi + Next +End Sub + +Sub BuildMenuWithColors (items() As MenuItem, labels() As String, colors() As Integer) + ' Check array bounds + If LBound(items) <> 1 Or LBound(colors) <> 1 Or UBound(items) <> UBound(colors) Then End + + count = UBound(items) + For i = 1 To count + Dim mi As MenuItem + Call NewMenuItemWithColor(mi, labels(i), colors(i), i) + items(i) = mi + Next +End Sub + +Sub AdjustMenuStyle (style As MenuStyle, items() As MenuItem, count As Integer, ignoreValue As Integer) + maxIdWidth = 0 + maxItemWidth = 0 + maxValueWidth = 0 + + For i = 1 To count + If items(i).isVisible Then + maxIdWidth = MaxI(maxIdWidth, Len(itos$(items(i).id))) + maxItemWidth = MaxI(maxItemWidth, Len(items(i).label + style.labelValueSeparator)) + maxValueWidth = MaxI(maxValueWidth, Len(itos$(items(i).value))) + End If + Next + If style.showRandom Then + maxIdWidth = MaxI(maxIdWidth, Len("0")) + maxItemWidth = MaxI(maxItemWidth, Len(style.randomItemName)) + End If + style.idWidth = maxIdWidth + style.labelWidth = maxItemWidth + If Not ignoreValue Then style.valueWidth = maxValueWidth Else style.valueWidth = 0 +End Sub + +Sub PrintMenu (items() As MenuItem, count As Integer, style As MenuStyle) + Dim randomItem As MenuItem + Call NewMenuItem(randomItem, style.randomItemName, style.randomItemId) + If count <= 10 Then + For i = 1 To count + If items(i).isVisible Then + If style.useColors Then + oldColor = GetColor + SetColor (items(i).color) + End If + Print GetTitle$(items(i), style) + If style.useColors Then + Call SetColor(oldColor) + End If + End If + Next + If style.showRandom Then + Print GetTitleWithoutValue$(randomItem, style) + End If + Else + Dim emptyItem As MenuItem + Call NewMenuItem(emptyItem, "", 0) + itemWidth = Len(GetTitle$(emptyItem, style)) + itemsPerRow = style.screenWidth \ (itemWidth + Len(style.menuItemSpacer)) + columnWidth = style.screenWidth \ itemsPerRow + + column = 0 + For i = 1 To count + If items(i).isVisible Then + itemText$ = GetTitle$(items(i), style) + If column <> (itemsPerRow - 1) Then + If i <> count Or style.showRandom Then + textLength = Len(itemText$) + itemText$ = MakeFitL$(RTrim$(itemText$) + style.menuItemSpacer, textLength + Len(style.menuItemSpacer), " ") + End If + End If + Print MakeFitC$(itemText$, columnWidth, " "); + End If + column = (column + 1) Mod itemsPerRow + If column = 0 Then Print "" + Next + If style.showRandom Then + Print MakeFitC$(GetTitleWithoutValue$(randomItem, style), columnWidth, " ") + End If + End If +End Sub + +Function GetTitle$ (mi As MenuItem, ms As MenuStyle) + id$ = itos$(mi.id) + label$ = mi.label + If ms.valueWidth > 0 Then label$ = label$ + ms.labelValueSeparator + value$ = itos$(mi.value) + GetTitle$ = MakeFitR$(id$, ms.idWidth, " ") + ms.idLabelSeparator + MakeFitL$(label$, ms.labelWidth, " ") + MakeFitR$(value$, ms.valueWidth, " ") +End Function + +Function GetTitleWithoutValue$ (mi As MenuItem, ms As MenuStyle) + GetTitleWithoutValue$ = MakeFitR$(itos(mi.id), ms.idWidth, " ") + ms.idLabelSeparator + MakeFitL$(mi.label, ms.labelWidth + ms.valueWidth + Len(ms.labelValueSeparator), " ") +End Function + +Sub NewMenuStyle (ms As MenuStyle) + ms.idWidth = 0 + ms.labelWidth = 0 + ms.valueWidth = 0 + ms.screenWidth = 80 + ms.randomItemName = "Random" + ms.randomItemId = 0 + ms.idLabelSeparator = " = " + ms.labelValueSeparator = ": " + ms.menuItemSpacer = ", " + ms.showRandom = TRUE + ms.useColors = FALSE +End Sub + +Sub NewMenuItem (mi As MenuItem, label As String, id As Integer) + mi.id = id + mi.label = label + mi.value = 0 + mi.color = COLOR_DEFAULT + mi.isVisible = TRUE +End Sub + +Sub NewMenuItemWithValue (mi As MenuItem, label As String, id As Integer, value As Integer) + mi.id = id + mi.label = label + mi.value = value + mi.color = COLOR_DEFAULT + mi.isVisible = TRUE +End Sub + +Sub NewMenuItemWithColor (mi As MenuItem, label As String, textColor As Integer, id As Integer) + mi.id = id + mi.label = label + mi.value = 0 + mi.color = textColor + mi.isVisible = TRUE +End Sub +*/ diff --git a/sbf-cpp/Menus.h b/sbf-cpp/Menus.h new file mode 100644 index 0000000..8e973d1 --- /dev/null +++ b/sbf-cpp/Menus.h @@ -0,0 +1,51 @@ +#ifndef MENUS_H__ +#define MENUS_H__ +namespace SBF { + struct MenuStyle; + struct MenuItem; +} +// End forward declarations +#include +#include + +namespace SBF { + using std::wstring; + + struct MenuStyle { + int idWidth; + int labelWidth; + int valueWidth; + int screenWidth; + wstring randomItemName; + int randomItemId; + wstring idLabelSeparator; + wstring labelValueSeparator; + wstring menuItemSpacer; + bool showRandom; + bool useColors; + }; + + struct MenuItem { + wstring label; + int id; + int value; + int color; + bool isVisible; + }; + + int GetRandomMenuItemId (std::vector items); + void BuildMenu(std::vector items, std::vector labels); + void BuildMenuWithValues(std::vector items, std::vector labels, std::vector values); + void BuildMenuWithColors(std::vector items, std::vector labels, std::vector colors); + void AdjustMenuStyle(MenuStyle& style, std::vector items, bool ignoreValue); + void PrintMenu(std::vector items, MenuStyle style); + wstring GetTitle(MenuItem item, MenuStyle style); + wstring GetTitleWithoutValue(MenuItem item, MenuStyle style); + void NewMenuStyle(MenuStyle& style); + void NewMenuItem(MenuItem& item, wstring label, int id); + void NewMenuItemWithValue(MenuItem& item, wstring label, int id, int value); + void NewMenuItemWithColor(MenuItem& item, wstring label, int id, uint8_t color); + +} // End namespace SBF + +#endif // !defined MENUS_H__ diff --git a/sbf-cpp/sbf.cpp b/sbf-cpp/sbf.cpp index 33ecc06..386c4a2 100644 --- a/sbf-cpp/sbf.cpp +++ b/sbf-cpp/sbf.cpp @@ -1,4 +1,5 @@ #define _XOPEN_SOURCE_EXTENDED +#include "sbf.h" #include #include #include diff --git a/sbf-cpp/sbf.h b/sbf-cpp/sbf.h new file mode 100644 index 0000000..bf21854 --- /dev/null +++ b/sbf-cpp/sbf.h @@ -0,0 +1,811 @@ +#include "Colors.h" +#include "Menus.h" +#include "Character.h" +#include + +namespace SBF { + using std::wstring; + + const int kInitialGeneration = 13; + + + + + +/* + +$Debug +' Setup +Randomize Timer +Call InitializeMemory +' Run "tests" at startup. Uncomment the end instruction to see the output and not run the rest of the program. +Call Test +Call SplashScreen +Call MainMenu + +' This initializes shared variables. +Sub InitializeMemory + Call Initialize_Character_Lib + + Dim rank As RankType + Call NewRank(rank, RANK_PRIMARY, RANK_PRIMARY_LABEL) + Ranks(RANK_PRIMARY) = rank + Call NewRank(rank, RANK_SECONDARY, RANK_SECONDARY_LABEL) + Ranks(RANK_SECONDARY) = rank + Call NewRank(rank, RANK_TERTIARY, RANK_TERTIARY_LABEL) + Ranks(RANK_TERTIARY) = rank + + Dim ability As AbilityType + Call NewAbility(ability, ABILITY_TALENTS_ID, ABILITY_TALENTS_SINGULAR, ABILITY_TALENTS_PLURAL) + Abilities(ABILITY_TALENTS_ID) = ability + Call NewAbility(ability, ABILITY_SKILLS_ID, ABILITY_SKILLS_SINGULAR, ABILITY_SKILLS_PLURAL) + Abilities(ABILITY_SKILLS_ID) = ability + Call NewAbility(ability, ABILITY_KNOWLEDGES_ID, ABILITY_SKILLS_SINGULAR, ABILITY_SKILLS_PLURAL) + Abilities(ABILITY_KNOWLEDGES_ID) = ability +End Sub + +Sub NewAbility (ability As AbilityType, id As Integer, singular As String, plural As String) + ability.id = id + ability.singular = singular + ability.plural = plural +End Sub + +Sub NewRank (rank As RankType, id As Integer, label As String) + rank.id = id + rank.label = label +End Sub + +Sub SplashScreen + ' Splash screen + Cls ' " " + Print "Welcome to Tom's Storyteller's Best Friend. This is a program that is meant to" + Print "aid storytellers in running Vampire: the Masquerade Chronicles and Vampire: the" + Print "Dark Ages Chronicles. This program could aid in running campaigns for other" + Print "role-playing games especially those from White Wolf(tm). If you would like" + Print "anything added please open a github issue. https://github.com/headhunter45/sbf" + Print " Press any key to continue" + While InKey$ = "" + Wend +End Sub + +Sub MainMenu + ' Main menu + choice = 0 + Do + Cls + Print "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" + Print "º What are you going to do? º" + Print "º 1 = Character Generator º" + Print "º 2 = Character Generator for Dummies º" + Print "º 3 = Combat Computer º" + Print "º 4 = Dice Roller º" + Print "º 5 = Random Character Generator º" + Print "º 6 = º" + Print "º 7 = Vehicle Generator º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º 0 = End º" + Print "º º" + Print "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" + choice = GetChoice(0, 7) + Select Case choice + Case 1 + CharacterGenerator + Case 2 + CharacterGeneratorForDummies + Case 3 + CombatComputer + Case 4 + DiceRoller + Case 5 + RandomCharacterGenerator + Case 7 + VehicleGenerator + End Select + Loop Until choice = 0 +End Sub + +' This sub is not called. It is here so it can be copied whenever I need to make a new bordered screen. +Sub BlankScreen + Print "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "º º" + Print "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" +End Sub + +Function GetChoice (min As Integer, max As Integer) + Dim choice + Do + Input choice + Loop Until choice <= max And choice >= min + GetChoice = choice +End Function + +Function GetMenuChoice (items() As MenuItem, style As MenuStyle, count As Integer) + ' Only allow random id or an id from a visible menuitem. + choice = -1 + acceptChoice = FALSE + Do + Input choice + If style.showRandom And choice = style.randomItemId Then acceptChoice = TRUE + For i = 1 To count + If choice = items(i).id And items(i).isVisible Then + acceptChoice = TRUE + Exit For + End If + Next + Loop Until acceptChoice + GetMenuChoice = choice +End Function + +Function GetRandomInt (min As Integer, max As Integer) + GetRandomInt = Int(Rnd * (max - min + 1)) + min +End Function + +Function MaxI (val1 As Integer, val2 As Integer) + If (val1 > val2) Then + MaxI = val1 + Else + MaxI = val2 + End If +End Function + +Function ChooseStringId (labels() As String, style As MenuStyle, count As Integer, prompt As String) + Cls + ReDim mnuItems(1 To count) As MenuItem + Call BuildMenu(mnuItems(), labels(), count) + Call AdjustMenuStyle(style, mnuItems(), count, TRUE) + Print prompt + Call PrintMenu(mnuItems(), count, style) + choice = GetMenuChoice(mnuItems(), style, count) + If choice = style.randomItemId Then choice = GetRandomMenuItemId(mnuItems(), count) + ChooseStringId = choice +End Function + +Function ChooseStringIdWithValues (labels() As String, values() As Integer, style As MenuStyle, count As Integer, prompt As String) + Cls + Dim mnuItems(1 To count) As MenuItem + Call BuildMenuWithValues(mnuItems(), labels(), values(), count) + Call AdjustMenuStyle(style, mnuItems(), count, FALSE) + Print prompt + Call PrintMenu(mnuItems(), count, style) + choice = GetMenuChoice(mnuItems(), style, count) + If choice = style.randomItemId Then choice = GetRandomMenuItemId(mnuItems(), count) + ChooseStringIdWithValues = choice +End Function + +Function ChooseStringIdWithColors (labels() As String, colors() As Integer, style As MenuStyle, prompt As String) + Cls + ' Check array bounds + If LBound(labels) <> 1 Or LBound(colors) <> 1 Or UBound(labels) <> UBound(colors) Then + ChooseStringIdWithColors = -1 + End + End If + + count = UBound(labels) + Dim mnuItems(1 To count) As MenuItem + Call BuildMenuWithColors(mnuItems(), labels(), colors()) + Call AdjustMenuStyle(style, mnuItems(), count, TRUE) + Print prompt + Call PrintMenu(mnuItems(), count, style) + choice = GetMenuChoice(mnuItems(), style, count) + If choice = style.randomItemId Then choice = GetRandomMenuItemId(mnuItems(), count) + ChooseStringIdWithColors = choice +End Function + +Function ChooseMenuItemId (items() As MenuItem, style As MenuStyle, count As Integer, prompt As String, ignoreValue As Integer) + Cls + Call AdjustMenuStyle(style, items(), count, ignoreValue) + Print prompt + Call PrintMenu(items(), count, style) + choice = GetMenuChoice(items(), style, count) + If choice = style.randomItemId Then choice = GetRandomMenuItemId(items(), count) + ChooseMenuItemId = choice +End Function + +Sub CGGetHeader (ch As CharacterType) + Cls + Dim ms As MenuStyle + Call NewMenuStyle(ms) + Input "What is the character's name? ", ch.name + Input "Who is the player? ", ch.player + Input "What chronicle is the character going to be used for? ", ch.chronicle + Input "What is the character's Haven? ", ch.haven + Input "What is the character's concept? ", ch.concept + Input "How old is the character? ", ch.age + ch.gender = ChooseStringId(Genders(), ms, GENDERS_COUNT, "What is the character's gender?") + ch.clan = ChooseStringId(Clans(), ms, CLANS_COUNT, "What clan is the character from?") + ch.nature = ChooseStringId(Archetypes(), ms, ARCHETYPES_COUNT, "What is the character's nature?") + ch.demeanor = ChooseStringId(Archetypes(), ms, ARCHETYPES_COUNT, "What is the character's demeanor?") +End Sub + +Sub CGGetDisciplines (ch As CharacterType) + ' Spend discipline points. + Dim ms As MenuStyle + Call NewMenuStyle(ms) + disciplinePoints = GetDisciplinePoints + Dim disciplineValues(DISCIPLINES_COUNT) As Integer + While disciplinePoints > 0 + Cls + Call FillDisciplines(ch, disciplineValues()) + discipline = ChooseStringIdWithValues(Disciplines(), disciplineValues(), ms, DISCIPLINES_COUNT, "Which discipline do you want to spend 1 of your " + itos$(disciplinePoints) + " points on?") + Call SetDiscipline(ch, discipline, GetDiscipline(ch, discipline) + 1) + disciplinePoints = disciplinePoints - 1 + Wend +End Sub + +Sub CGGetAttributes (ch As CharacterType) + Dim msWithoutValues As MenuStyle + Call NewMenuStyle(msWithoutValues) + Dim msWithValues As MenuStyle + Call NewMenuStyle(msWithValues) + Dim attributeRanks(1 To ATTRIBUTE_GROUPS_COUNT) As Integer + + ' Attribute groups menu (physical/social/mental) + Dim mnuAttributeGroups(1 To ATTRIBUTE_GROUPS_COUNT) As MenuItem + Dim mi As MenuItem + For i = 1 To ATTRIBUTE_GROUPS_COUNT + Call NewMenuItem(mi, AttributeGroups(i), i) + mnuAttributeGroups(i) = mi + Next + + ' Choose attribute group priorities. + groupSum = 0 + rankSum = 1 + For i = 1 To ATTRIBUTE_GROUPS_COUNT - 1 + nextGroup = ChooseMenuItemId(mnuAttributeGroups(), msWithoutValues, ATTRIBUTE_GROUPS_COUNT, "Choose your " + LCase$(Ranks(i).label) + " attribute?", TRUE) + mnuAttributeGroups(nextGroup).isVisible = FALSE + attributeRanks(nextGroup) = i + rankSum = rankSum + i + 1 + groupSum = groupSum + nextGroup + Next + ' General formula for last choice given 1 to count based indexing is this + ' (Sum from 1 to count) - (Sum of all previous choice IDs) + ' Sum(1..AllAttributesCount)-Sum(Choice[1]..Choice[AllAttributesCount-1]) + lastGroup = rankSum - groupSum + attributeRanks(lastGroup) = ATTRIBUTE_GROUPS_COUNT + + ' Spend attribute points + For group = 1 To ATTRIBUTE_GROUPS_COUNT + count = GetNumAttributesInGroup(group) + ReDim attributes(1 To count) As String + Call FillAttributesInGroup(group, attributes()) + rank = attributeRanks(group) + ReDim values(1 To count) As Integer + For attrPoints = GetAttributePointsForRank(rank) To 1 Step -1 + Call FillAttributeValues(ch, values(), group) + attribute = ChooseStringIdWithValues(attributes(), values(), msWithValues, count, "Which " + LCase$(AttributeGroups(group)) + " attribute do you want to spend 1 of your " + itos$(attrPoints) + " points on?") + Call SetAttributeValue(ch, group, attribute, GetAttributeValue(ch, group, attribute) + 1) + Next + Next +End Sub + +Sub CGGetAbilities (ch As CharacterType) + Dim msWithoutValues As MenuStyle + Call NewMenuStyle(msWithoutValues) + Dim msWithValues As MenuStyle + Call NewMenuStyle(msWithValues) + Dim abilityRanks(1 To ABILITY_GROUPS_COUNT) As Integer + + ' Ability groups menu (talents/skills/knowledges) + Dim mnuAbilityGroups(1 To ABILITY_GROUPS_COUNT) As MenuItem + Dim mi As MenuItem + For i = 1 To ABILITY_GROUPS_COUNT + Call NewMenuItem(mi, AbilityGroups(i), i) + mnuAbilityGroups(i) = mi + Next + + ' Choose ability group priorities + groupSum = 0 + rankSum = 1 + For i = 1 To ABILITY_GROUPS_COUNT - 1 + nextAbility = ChooseMenuItemId(mnuAbilityGroups(), msWithoutValues, ABILITY_GROUPS_COUNT, "Choose your " + LCase$(Ranks(i).label) + " ability?", TRUE) + mnuAbilityGroups(nextAbility).isVisible = FALSE + abilityRanks(nextAbility) = i + rankSum = rankSum + i + 1 + groupSum = groupSum + nextAbility + Next + ' General formula for last choice given 1 to count based indexing is this + ' (Sum from 1 to count) - (Sum of all previous choice IDs) + ' Sum(1..AllAttributesCount)-Sum(Choice[1]..Choice[AllAttributesCount-1]) + lastGroup = rankSum - groupSum + abilityRanks(lastGroup) = ABILITY_GROUPS_COUNT + + ' Spend ability points + For group = 1 To ABILITY_GROUPS_COUNT + count = GetNumItemsForAbilityGroup(group) + ReDim abilityNames(1 To count) As String + Call FillAbilitiesForAbilityGroup(group, abilityNames()) + rank = abilityRanks(group) + ReDim values(1 To count) As Integer + For abilityPoints = GetAbilityPointsForRank(rank) To 1 Step -1 + Call FillAbilityValues(ch, values(), group) + ability = ChooseStringIdWithValues(abilityNames(), values(), msWithValues, count, "Which " + LCase$(Abilities(i).singular) + " would you like to spend 1 of your " + itos$(abilityPoints) + " points on?") + Call SetAbilityValue(ch, group, ability, GetAbilityValue(ch, group, ability) + 1) + Next + Next +End Sub + +Sub CGGetBackgrounds (ch As CharacterType) + ' Spend background points + Dim ms As MenuStyle + Call NewMenuStyle(ms) + backgroundPoints = GetBackgroundPoints + Dim backgroundValues(BACKGROUNDS_COUNT) As Integer + While backgroundPoints > 0 + Cls + Call FillBackgrounds(ch, backgroundValues()) + background = ChooseStringIdWithValues(Backgrounds(), backgroundValues(), ms, BACKGROUNDS_COUNT, "Which background do you want to spend 1 of your " + itos$(backgroundPoints) + " points on?") + Call SetBackground(ch, background, GetBackground(ch, background) + 1) + backgroundPoints = backgroundPoints - 1 + Wend +End Sub + +Sub CGGetRoad (ch As CharacterType) + ch.roadName = "Humanity" +End Sub + +Sub CGSpendVirtuePoints (ch As CharacterType) + ' Spend virtue points + Dim ms As MenuStyle + Call NewMenuStyle(ms) + virtuePoints = GetVirtuePoints + + Dim values(1 To VIRTUES_COUNT) As Integer + While virtuePoints > 0 + Call FillVirtues(ch, values()) + virtue = ChooseStringIdWithValues(Virtues(), values(), ms, VIRTUES_COUNT, "Which virtue do you want to spend 1 of your " + itos$(virtuePoints) + " points on?") + If virtue = 0 Then virtue = GetRandomInt(1, VIRTUES_COUNT) + Call SetVirtue(ch, virtue, GetVirtue(ch, virtue) + 1) + virtuePoints = virtuePoints - 1 + Wend +End Sub + +Sub CGGetDerangement (ch As CharacterType) + If ch.clan = CLAN_MALKAVIAN Then + ' If the clan is malkavian then pick a derangement. + Dim ms As MenuStyle + Call NewMenuStyle(ms) + ms.useColors = TRUE + + ch.derangementId = ChooseStringIdWithColors(DerangementLabels(), DerangementColors(), ms, "Which derangement do you want?") + If ch.derangementId = 0 Then ch.derangementId = GetRandomInt(1, DERANGEMENTS_COUNT) + End If +End Sub + +Sub CGSpendFreebiePoints (ch As CharacterType) +End Sub + +' Ignore this warning ch is not used yet because the sub is not implemented yet. +Sub SaveCharacterSheet (ch As CharacterType) + ' Where do you want the file to be saved? (default is C:\Windows\Desktop)? + ' What do you want the file to be called? (default is CHAR1)? + + 'CHAR1.TXT + '/------------------------------------------------------------------------------\ + '| Name: sadf | Sex: Male Generation: 12 | + '| Clan: Brujah | Age: mmmmmm | + '|--------------------------------------| Player: fdsa | + '| Attributes | Chronicle: jfjf | + '| Physical Social Mental | Haven: kkkkkk | + '| Str. 5 App. 2 Int. 1 | Concept: llllll | + '| Dex. 3 Cha. 2 Per. 1 |---------------------------------------| + '| Sta. 2 Man. 4 Wit. 4 | Derangements: | + '|--------------------------------------| _____________________________________ | + '| Disciplines: | _____________________________________ | + '| Obtenebration | _____________________________________ | + '| Obtenebration | _____________________________________ | + '| Obtenebration | _____________________________________ | + '|------------------------------------------------------------------------------| + '| Beast: 8 | Nature: Fanatic | + '| Willpower: 2 | Demeanor: Architect | + '|------------------------------------------------------------------------------| + '| Abilities | + '| Talents Skills Knowledges | + '| Acting: 6 Animal Ken: 2 Bureaucracy: 1 | + '| Alertness: 2 Drive: 2 Computer: 2 | + '| Athletics: 2 Etiquette: 2 Finance: 1 | + '| Brawl: 1 Firearms: 1 Investigation: 1 | + '| Dodge: 1 Melee: 1 Law: 0 | + '| Empathy: 1 Music: 1 Linguistics: 0 | + '| Intimidation: 0 Repair: 0 Medecine: 0 | + '| Leadership: 0 Security: 0 Occult: 0 | + '| Streetwise: 0 Stealth: 0 Politics: 0 | + '| Subterfuge: 0 Survival: 0 Science: 0 | + '|------------------------------------------------------------------------------| + '| Backgrounds: | Virtues: | + '| Allies | Conscience: 0 | + '| Contacts | Conviction: 3 | + '| Contacts | Instinct: 5 | + '| Fame | Self-Control: 0 | + '| Generation | Courage: 2 | + '|--------------------------------------/ | + '| | + '\------------------------------------------------------------------------------/ + 'CHAR2.TXT + '/------------------------------------------------------------------------------\ + '| Name: _______________________________| Sex: Female Generation: 13 | + '| Clan: Lasombra | Age: ________________________________ | + '|--------------------------------------| Player: _____________________________ | + '| Attributes | Chronicle: __________________________ | + '| Physical Social Mental | Haven: ______________________________ | + '| Str. 2 App. 3 Int. 3 | Concept: ____________________________ | + '| Dex. 1 Cha. 2 Per. 5 |---------------------------------------| + '| Sta. 3 Man. 3 Wit. 2 | Derangements: | + '|--------------------------------------| _____________________________________ | + '| Disciplines: | _____________________________________ | + '| Vicissitude | _____________________________________ | + '| Spiritus | _____________________________________ | + '| Auspex | _____________________________________ | + '|------------------------------------------------------------------------------| + '| Chivalry: 7 | Nature: Autocrat | + '| Willpower: 3 | Demeanor: Defender | + '|------------------------------------------------------------------------------| + '| Abilities | + '| Talents Skills Knowledges | + '| Acting: 0 Animal Ken: 0 Bureaucracy: 2 | + '| Alertness: 2 Drive: 0 Computer: 3 | + '| Athletics: 1 Etiquette: 1 Finance: 2 | + '| Brawl: 1 Firearms: 1 Investigation: 1 | + '| Dodge: 2 Melee: 1 Law: 0 | + '| Empathy: 0 Music: 0 Linguistics: 2 | + '| Intimidation: 1 Repair: 1 Medecine: 1 | + '| Leadership: 0 Security: 1 Occult: 1 | + '| Streetwise: 0 Stealth: 0 Politics: 0 | + '| Subterfuge: 2 Survival: 0 Science: 1 | + '|------------------------------------------------------------------------------| + '| Backgrounds: | Virtues: | + '| Contacts | Conscience: 2 | + '| Influence | Conviction: 0 | + '| Allies | Instinct: 0 | + '| Herd | Self-Control: 5 | + '| Status | Courage: 3 | + '|--------------------------------------/ | + '| | + '\------------------------------------------------------------------------------/ + 'RANDY.TXT + '/------------------------------------------------------------------------------\ + '| Name: Randy | Sex: Female Generation: 12 | + '| Clan: Gangrel | Age: ________________________________ | + '|--------------------------------------| Player: _____________________________ | + '| Attributes | Chronicle: __________________________ | + '| Physical Social Mental | Haven: ______________________________ | + '| Str. 3 App. 1 Int. 2 | Concept: ____________________________ | + '| Dex. 6 Cha. 3 Per. 3 |---------------------------------------| + '| Sta. 1 Man. 2 Wit. 3 | Derangements: | + '|--------------------------------------| _____________________________________ | + '| Disciplines: | _____________________________________ | + '| Animalism | _____________________________________ | + '| Celerity | _____________________________________ | + '| Mortis | _____________________________________ | + '|------------------------------------------------------------------------------| + '| Devil: 7 | Nature: Traditionalist | + '| Willpower: 3 | Demeanor: Bon vivant | + '|------------------------------------------------------------------------------| + '| Abilities | + '| Talents Skills Knowledges | + '| Acting: 1 Animal Ken: 0 Bureaucracy: 1 | + '| Alertness: 2 Drive: 0 Computer: 0 | + '| Athletics: 1 Etiquette: 0 Finance: 1 | + '| Brawl: 1 Firearms: 0 Investigation: 3 | + '| Dodge: 1 Melee: 0 Law: 1 | + '| Empathy: 1 Music: 0 Linguistics: 3 | + '| Intimidation: 1 Repair: 0 Medecine: 0 | + '| Leadership: 0 Security: 2 Occult: 2 | + '| Streetwise: 0 Stealth: 1 Politics: 2 | + '| Subterfuge: 1 Survival: 2 Science: 0 | + '|------------------------------------------------------------------------------| + '| Backgrounds: | Virtues: | + '| Retainers | Conscience: 0 | + '| Contacts | Conviction: 2 | + '| Retainers | Instinct: 5 | + '| Generation | Self-Control: 0 | + '| Herd | Courage: 3 | + '|--------------------------------------/ | + '| | + '\------------------------------------------------------------------------------/ + + +End Sub + +Sub CharacterGenerator () + Dim ch As CharacterType + Call NewCharacter(ch) + Call CGGetHeader(ch) + Call CGGetDisciplines(ch) + Call CGGetAttributes(ch) + Call CGGetAbilities(ch) + Call CGGetBackgrounds(ch) + Call CGGetRoad(ch) + Call CGSpendVirtuePoints(ch) + Call CGGetDerangement(ch) + + ' Generation starts at 13 and goes down 1 point per point of the "generation" background. + ch.generation = INITIAL_GENERATION - GetBackground(ch, BACKGROUND_GENERATION) + + ' Willpower + ch.willpower = ch.courage + ' Humanity + ch.roadValue = ch.conscience + ch.selfControl + ' Blood Pool - The only die roll. + ch.bloodPool = GetRandomInt(1, 10) + + ' Spend freebie points + Call CGSpendFreebiePoints(ch) + + Call SaveCharacterSheet(ch) + Call ShowCharacterSheet(ch) +End Sub + +Sub ShowCharacterSheet (ch As CharacterType) + Dim disciplineValues(DISCIPLINES_COUNT) As Integer + Call FillDisciplines(ch, disciplineValues()) + + Dim backgroundValues(BACKGROUNDS_COUNT) As Integer + Call FillBackgrounds(ch, backgroundValues()) + + '... 0123456789 + '160  ¡¢£¤¥¦§¨© + '170 ª«¬­®¯°±²³ + '180 ´µ¶·¸¹º»¼½ + '190 ¾¿ÀÁÂÃÄÅÆÇ + '200 ÈÉÊËÌÍÎÏÐÑ + '210 ÒÓÔÕÖרÙÚÛ + '220 ÜÝÞßàáâãäåå + '230 æçèéêë2ìíîï + ' enquote forms s/^([ɺÈÍÌ].*[»º¼¹])$/print "$1"/g + + Dim disciplineStrings(3) As String + disciplineStringsIndex = 0 + For index = 1 To DISCIPLINES_COUNT + If disciplineValues(index) > 0 Then + suffix$ = "" + If disciplineValues(index) > 1 Then + suffix$ = " x" + itos$(disciplineValues(index)) + End If + disciplineStrings(disciplineStringsIndex) = Disciplines(index) + suffix$ + disciplineStringsIndex = disciplineStringsIndex + 1 + End If + Next + + Dim backgroundStrings(5) As String + backgroundStringsIndex = 0 + For index = 1 To BACKGROUNDS_COUNT + If backgroundValues(index) > 0 Then + suffix$ = "" + If backgroundValues(index) > 1 Then + suffix$ = " x" + itos$(backgroundValues(index)) + End If + backgroundStrings$(backgroundStringsIndex) = Backgrounds(index) + suffix$ + backgroundStringsIndex = backgroundStringsIndex + 1 + End If + Next + Dim derangementStrings(5) As String + allDerangementsLine$ = GetAllDerangementsLine$(ch) + + Call MakeWrapLines(derangementStrings(), allDerangementsLine$, 37, 5) + + Cls + Print "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" + Print "º Name: " + MakeFitL$(ch.name, 30, " ") + " º Gender: " + MakeFitL$(Genders(ch.gender), 14, " ") + " Generation: " + MakeFitR$(itos$(ch.generation), 2, " ") + " º" + Print "º Clan: " + MakeFitL$(Clans(ch.clan), 30, " ") + " º Age: " + MakeFitL$(ch.age$, 32, " ") + " º" + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ Player: " + MakeFitL$(ch.player$, 29, " ") + " º" + Print "º Attributes º Chronicle: " + MakeFitL$(ch.chronicle$, 26, " ") + " º" + Print "º Physical Social Mental º Haven: " + MakeFitL$(ch.haven$, 30, " ") + " º" + Print "º Str. " + MakeFitL$(itos$(ch.attr_strength), 7, " ") + " App. " + MakeFitL$(itos$(ch.attr_appearance), 7, " ") + " Int. " + MakeFitL$(itos$(ch.attr_intelligence), 5, " ") + " º Concept: " + MakeFitL$(ch.concept$, 28, " ") + " º" + Print "º Dex. " + MakeFitL$(itos$(ch.attr_dexterity), 7, " ") + " Cha. " + MakeFitL$(itos$(ch.attr_charisma), 7, " ") + " Per. " + MakeFitL$(itos$(ch.attr_perception), 5, " ") + " ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" + Print "º Sta. " + MakeFitL$(itos$(ch.attr_stamina), 7, " ") + " Man. " + MakeFitL$(itos$(ch.attr_manipulation), 7, " ") + " Wit. " + MakeFitL$(itos$(ch.attr_wits), 5, " ") + " º Derangements: º" + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ " + derangementStrings(0) + " º" + Print "º Disciplines: º " + derangementStrings(1) + " º" + Print "º " + MakeFitL$(disciplineStrings(0), 36, " ") + " º " + MakeFitL$(derangementStrings(2), 37, "_") + " º" + Print "º " + MakeFitL$(disciplineStrings(1), 36, " ") + " º " + MakeFitL$(derangementStrings(3), 37, "_") + " º" + Print "º " + MakeFitL$(disciplineStrings(2), 36, " ") + " º " + MakeFitL$(derangementStrings(4), 37, "_") + " º" + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" + Print "º " + MakeFitL$(ch.roadName + ": " + itos$(ch.roadValue), 36, " ") + " º Nature: " + MakeFitL$(Archetypes(ch.nature), 29, " ") + " º" + Print "º Willpower: " + MakeFitL$(itos$(ch.willpower), 25, " ") + " º Demeanor: " + MakeFitL$(Archetypes(ch.demeanor), 27, " ") + " º" + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" + Print "º º" + Print "º º" + Print "º º" + Print "º <> º" + Print "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" + Call PressAnyKeyToContinue + + Print "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" + Print "º " + MakeFitC$("Abilities", 76, " ") + " º" + Print "º " + MakeFitC$("Talents", 25, " ") + " " + MakeFitC$("Skills", 25, " ") + " " + MakeFitC$("Knowledges", 24, " ") + " º" + For index = 1 To 10 + Print "º " + MakeFitC(MakeFitL$(Talents(index) + ":", 14, " ") + itos$(GetTalent(ch, index)), 25, " ") + " " + MakeFitC(MakeFitL$(Skills(index) + ":", 14, " ") + itos$(GetSkill(ch, index)), 25, " ") + " " + MakeFitC(MakeFitL$(Knowledges(index) + ":", 14, " ") + itos$(GetKnowledge(ch, index)), 24, " ") + " º" + Next + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" + Print "º Backgrounds: º Virtues: º" + Print "º " + MakeFitL$(backgroundStrings(0), 36, " ") + " º " + MakeFitB$("Conscience:", itos$(ch.conscience), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(1), 36, " ") + " º " + MakeFitB$("Self-Control:", itos$(ch.selfControl), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(2), 36, " ") + " º " + MakeFitB$("Courage:", itos$(ch.courage), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(3), 36, " ") + " º " + MakeFitL$("", 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(4), 36, " ") + " º " + MakeFitL$("", 37, " ") + " º" + Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" + Print "º <> º" + Print "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" + Call PressAnyKeyToContinue +End Sub + +' Simpler character generator with fewer questions and more things done randomly without asking. +Sub CharacterGeneratorForDummies + Print "CharacterGeneratorForDummies" +End Sub + +' Maybe just remove this. It's kinda pointless. It asks some questions and calculates a contested roll. +' C1 dice pool, C1 difficulty, C2 dice pool, C2 difficulty, then rolls all the dice and does the math. +' In practice it's just slower than rolling the dice +Sub CombatComputer + Print "CombatComputer" +End Sub + +' Asks for a number of dice and a difficulty. Rolls the dice, calculates botches and successes. +Sub DiceRoller + Print "DiceRoller" +End Sub + +' Like the character generator if you choose random for everything. Should do random names/ages too, but doesn't yet. +Sub RandomCharacterGenerator + Print "RandomCharacterGenerator" +End Sub + +' This had a function at one point but got taken out. Will only come back if the disassembly can figure it out. +Sub Choice6 + Print "Unnamed choice 6" +End Sub + +' Like the character generator but for vehicles. Much simpler with fewer questions. Prints a vehicle sheet when done. Never finished and crashes mid way through currently. +Sub VehicleGenerator + Print "VehicleGenerator" +End Sub + +Sub PressAnyKeyToContinue () + While InKey$ = "": Wend +End Sub + +' String functions +Function itos$ (num As Integer) + itos$ = LTrim$(Str$(num)) +End Function + +Function MakeFitL$ (text As String, length As Integer, pad As String) + MakeFitL = Left$(text + String$(length, pad), length) +End Function + +Function MakeFitC$ (text As String, length As Integer, pad As String) + TextLength = Len(text) + LeftPadLength = MaxI(0, length - TextLength) \ 2 + RightPadLength = MaxI(0, length - TextLength - LeftPadLength) + LeftPad$ = String$(LeftPadLength, pad) + RightPad$ = String$(RightPadLength, pad) + TotalChop = MaxI(0, TextLength - length) + LeftChop = TotalChop \ 2 + 1 + MakeFitC = LeftPad$ + Mid$(text, LeftChop, length) + RightPad$ +End Function + +Function MakeFitR$ (text As String, length As Integer, pad As String) + MakeFitR = Right$(String$(length, pad) + text, length) +End Function + +Function MakeFitB$ (prefix As String, suffix As String, length As Integer, pad As String) + MakeFitB$ = MakeFitL$(MakeFitL$(prefix, length - Len(suffix), pad) + suffix, length, pad) +End Function + +Function GetIndexOf (fullString As String, targetString As String, startIndex As Integer) + GetIndexOf = -1 + targetLength = Len(targetString) + If targetLength <= 0 Then + GetIndexOf = startIndex + Exit Function + End If + + position = startIndex + 1 + length = Len(fullString) + Do + currString$ = Mid$(fullString, position, targetLength) + position = position + 1 + Loop While position <= length And currString$ <> targetString + If currString$ = targetString Then GetIndexOf = position - 2 +End Function + +Function GetCharAt$ (text As String, index As Integer) + length = Len(text) + If length <= 0 Or index < 0 Or index >= length Then + GetCharAt$ = "" + Exit Function + End If + GetCharAt$ = Mid$(text, index + 1, 1) +End Function + +Function GetSubstring$ (text As String, start As Integer, length As Integer) + GetSubstring$ = Mid$(text, start + 1, length) +End Function + +Sub MakeWrapLines (lines() As String, text As String, maxWidth As Integer, maxLines As Integer) + ReDim lines(maxLines) As String + lineCount = 0 + thisLine$ = "" + nextChunk$ = "" + thisLineStartPosition = 0 + thisLineCurrentPosition = 0 + nextSpace = -1 + textLength = Len(text) + + While (lineCount < maxLines) + nextSpace = GetIndexOf(text, " ", thisLineCurrentPosition) + If nextSpace < 0 Then nextSpace = textLength + nextChunk$ = GetSubstring(text, thisLineCurrentPosition, nextSpace - thisLineCurrentPosition) + nextChunkLength = Len(nextChunk$) + If nextChunkLength > 0 Then + needsSpace = Len(thisLine$) > 0 + If needsSpace Then + thisLine$ = thisLine$ + " " + End If + thisLineLength = Len(thisLine$) + If nextChunkLength > maxWidth Then + nextChunk$ = GetSubstring(text, thisLineCurrentPosition, maxWidth - thisLineLength) + nextSpace = thisLineStartPosition + maxWidth + thisLine$ = thisLine$ + nextChunk$ + thisLineCurrentPosition = nextSpace + ElseIf thisLineLength + nextChunkLength > maxWidth Then + thisLine$ = MakeFitL$(thisLine$, maxWidth, " ") + Else + thisLine$ = thisLine$ + nextChunk$ + thisLineCurrentPosition = nextSpace + 1 + End If + thisLineLength = Len(thisLine$) + Else + thisLineCurrentPosition = nextSpace + 1 + End If + If thisLineLength >= maxWidth Or thisLineCurrentPosition > textLength Then + thisLine$ = MakeFitL$(thisLine$, maxWidth, "_") + lines(lineCount) = thisLine$ + lineCount = lineCount + 1 + thisLine$ = "" + thisLineLength = Len(thisLine$) + thisLineStartPosition = thisLineCurrentPosition + End If + Wend +End Sub + +'$include: 'colors.bm' +'$include: 'menus.bm' +'$include: 'character.bm' + +Sub Test + 'End +End Sub + +*/ +} // End namespace SBF