From 970f78ffe53980ceb5bb30591053c12342ed5ae1 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Thu, 2 Mar 2023 04:04:44 -0800 Subject: [PATCH] Adds spending virtue points. --- TODO.md | 80 ++++++++++++++++++++++++++++++++--- dos/sbf/sbf.bas | 109 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 157 insertions(+), 32 deletions(-) diff --git a/TODO.md b/TODO.md index 257067b..b02fe60 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,6 @@ # High Priority -* Calculate conscience. * Calculate conviction. * Calculate instinct. -* Calculate self-control. -* Calculate courage. * Calculate roadValue aka humanity in VtM, and something else in WtA. * Calculate willpower. * Input/Print derangements. These are only for Malkavian vampires. @@ -14,7 +11,6 @@ * VtDA has malks so it would need this. * WtA doesn't obviously have them, but it may have something else that requires a specific question/addition to CharacterType. * Make this generic if possible. -* Spending virtue points # Low Priority * Add freebie points see page 92 VtM @@ -40,12 +36,21 @@ * Would be a neat thing to do it by character age where an old enough VtM character either gets additional access to VtDA stuff or for certain things only has access to VtDA stuff. * Allowing them to also spend points on any of the VtDA talents/skills/knowledges/backgrounds/disciplines, but only let them choose VtDA clans. * Extract the menu stuff to it's own bas file. + * https://qb64.com/wiki/TYPE + * https://qb64.com/wiki/$INCLUDE + * lib.BI - Type definitions. Include at the beginning of program. + * Include any dim, const, shared, or data. + * lib.BM - Sub/Function definitions. Include at the end of program. * pm, PrintMenu, PrintMenuWithValues * MenuItem/NewMenuItem * MenuStyle/NewMenuStyle * GetRandomMenuItem * GetChoice? * GetRandomInt? +* Extract each of the top-level menu items into their own files. +* Extract CharacterType and it's associated funcs/subs to their own files. (CharacterType.bi, CharacterType.bm) +* Extract show character sheet and save character to their own files or maybe put them in the CharacterType files. +* Extract the ui utility funcs/subs into their own files. MakeFit*, itos$, ... * Add support for roads. * VtM only has one. Humanity. * If there is only one like this then choose it and don't ask. @@ -85,8 +90,9 @@ * Maybe just say fuck it and leave that up to the user to know it's too long when it gets cut off. * We also like keeping it like this because it suggests "other" genders better than a freeform string. * In a text-based ui it may seem like male/female are the expected options and users would likely not even consider that there are other options. -* Move the ruleset dims/constants/getters/setters out into separate bas files. - * Probably 1 file per system +* Move the ruleset dims/constants/getters/setters out into separate bi/bm files. + * Probably 1 pair of files per system + * Really wish we had function pointers so each ruleset object could be a bunch of fn pointers instead of each stub method being a giant ass select case. * Maybe keep stubs for the functions in the main bas that call the rulset specific versions. * This would work if we can't sanely load/unload the other bas files at runtime. * Create a Rulesets array and RULESET_* constants. @@ -97,3 +103,65 @@ * Imagine telling someone you've created to many classes of character. You need to close and reopen the program if you want to create any new classes, but you can create more of the old ones. # Uncategorized +* Remove count being passed in and instead check UBOUND and LBOUND. + * Add an assert for when labels() and values() arrays don't have the same bounds. +* Look into DECLARE LIBRARY to add ruleset plugin support. +* Consider using _MEM to put arrays into CharacterType for things like attributes, abilities, disciplines, backgrounds, ... +* Add an icon with $EXEICON +* Look into _TITLE. + * Assuming it lets us set the window title. + * Wiki page currently 404's + * https://qb64.com/wiki/_TITLE + * https://qb64.com/wiki/_TITLE$ +* Add version info with $VERSIONINFO:key=value + * Keys are + * Comments + * CompanyName + * FileDescription + * FileVersion + * InternalName + * LegalCopyright + * LegalTrademarks + * OriginalFilename + * ProductName + * ProductVersion + * Web + * FILEVERSION# + * PRODUCTVERSION# + * `$VERSIONINFO:CompanyName=Your company name goes here` + * `$VERSIONINFO:FILEVERSION#=1,0,0,0` + * `$VERSIONINFO:PRODUCTVERSION#=1,0,0,0` +* Look into error logging. + * Ideally create an abstracted LogError sub that throws an error in debug mode but silently does nothing in a non-debug build. + * _ASSERT + * https://qb64.com/wiki/ERROR + * https://qb64.com/wiki/ERROR-Codes + * Custom error codes from 100 to 199 + * Maybe use 27 - Out of paper. +* Use LogError in all of the SELECT CASE blocks without a CASE ELSE to throw an unknown index error. +* Sort virtues better on the character sheet. + * Why are conviction and instinct between them? +* Start work on ports + * Mainly the C++ port. + * Consider a python port to refresh my python skills. + * Assembly port? + * For what arch though? x86, x86_64, aarch64 + * NDS/3DS + * PSP/PSVita + * Wii/WiiU + * Xbox One + * PS4/PS5? Not sure if there's an easily available dev mode. + * Switch hehe + * Maybe nes, but text input will suck. + * Add a GUI. ick. +* MakeFitS + * Spread inputs + * `MakeFitS$(strings$ as string, length as integer, padChar as string) + * No real good way to use this without array literals. + * Building an array of strings to call it just makes the code less readable +* Consider removing the pad parameter from all the MakeFit* functions. + * We're only ever using a single space char. +* Support other screen sizes and running in a proper resizable terminal. + +# Reference +* QB64 Wiki [https://qb64.com/wiki] diff --git a/dos/sbf/sbf.bas b/dos/sbf/sbf.bas index 413b92f..2086b38 100644 --- a/dos/sbf/sbf.bas +++ b/dos/sbf/sbf.bas @@ -19,6 +19,7 @@ Const TRUE = Not FALSE Const DISCIPLINE_POINTS = 3 Const BACKGROUND_POINTS = 5 +Const VIRTUE_POINTS = 7 Const INITIAL_GENERATION = 13 ' Each set of these index constants "NAME_*" should start at 1 and go up to NAMES_COUNT without leaving any holes. @@ -104,6 +105,13 @@ Const DISCIPLINE_VICISSITUDE = 24 Const DISCIPLINES_COUNT = 24 Dim Shared Disciplines(1 To DISCIPLINES_COUNT) As String +' Virtues +Const VIRTUE_SELF_CONTROL = 1 +Const VIRTUE_COURAGE = 2 +Const VIRTUE_CONSCIENCE = 3 +Const VIRTUES_COUNT = 3 +Dim Shared Virtues(1 To VIRTUES_COUNT) As String + ' These should probably be renamed like PHYSICAL_ATTRIBUTE_STRENGTH instead. Const ATTRIBUTE_STRENGTH = 1 Const ATTRIBUTE_DEXTERITY = 2 @@ -413,6 +421,11 @@ Sub InitializeMemory Disciplines(DISCIPLINE_THAUMATURGY) = "Thaumaturgy" Disciplines(DISCIPLINE_VICISSITUDE) = "Vicissitude" + ' Virtues + Virtues(VIRTUE_SELF_CONTROL) = "Self-Control" + Virtues(VIRTUE_COURAGE) = "Courage" + Virtues(VIRTUE_CONSCIENCE) = "Conscience" + ' Physical Attributes PhysicalAttributes(ATTRIBUTE_STRENGTH) = "Strength" PhysicalAttributeAbbreviations(ATTRIBUTE_STRENGTH) = "Str." @@ -656,7 +669,7 @@ Function MakeFitR$ (text As String, length As Integer, pad As String) End Function Function MakeFitB$ (prefix As String, suffix As String, length As Integer, pad As String) - MakeFitB$ = MakeFitL$(MakeFitL$(prefix, length - Len(suffix), pad), length, pad) + MakeFitB$ = MakeFitL$(MakeFitL$(prefix, length - Len(suffix), pad) + suffix, length, pad) End Function Function MaxI (val1 As Integer, val2 As Integer) @@ -667,6 +680,17 @@ Function MaxI (val1 As Integer, val2 As Integer) End If End Function +Sub SetVirtue (ch As CharacterType, index As Integer, value As Integer) + Select Case index + Case VIRTUE_SELF_CONTROL + ch.selfControl = value + Case VIRTUE_COURAGE + ch.courage = value + Case VIRTUE_CONSCIENCE + ch.conscience = value + End Select +End Sub + Sub SetDiscipline (ch As CharacterType, index As Integer, value As Integer) Select Case index Case DISCIPLINE_ANIMALISM @@ -720,6 +744,19 @@ Sub SetDiscipline (ch As CharacterType, index As Integer, value As Integer) End Select End Sub +Function GetVirtue (ch As CharacterType, index As Integer) + value = 0 + Select Case index + Case VIRTUE_SELF_CONTROL + value = ch.selfControl + Case VIRTUE_COURAGE + value = ch.courage + Case VIRTUE_CONSCIENCE + value = ch.conscience + End Select + GetVirtue = value +End Function + Function GetDiscipline (ch As CharacterType, index As Integer) Select Case index Case DISCIPLINE_ANIMALISM @@ -774,11 +811,19 @@ Function GetDiscipline (ch As CharacterType, index As Integer) End Function Sub FillDisciplines (ch As CharacterType, disciplines() As Integer) + ReDim disciplines(1 To DISCIPLINES_COUNT) As Integer For index = 1 To DISCIPLINES_COUNT disciplines(index) = GetDiscipline(ch, index) Next End Sub +Sub FillVirtues (ch As CharacterType, values() As Integer) + ReDim values(1 To VIRTUES_COUNT) As Integer + For index = 1 To VIRTUES_COUNT + values(index) = GetVirtue(ch, index) + Next +End Sub + Sub SetTalent (ch As CharacterType, index As Integer, value As Integer) Select Case index Case TALENT_ACTING @@ -1109,15 +1154,16 @@ Sub NewCharacter (ch As CharacterType) ch.clan = 0 ch.nature = 0 ch.demeanor = 0 - ch.conscience = 0 - ch.selfControl = 0 - ch.courage = 0 ch.conviction = 0 ch.instinct = 0 ch.generation = 13 ch.roadName = "" ch.roadValue = 0 ch.willpower = 0 + ' Virtues + ch.selfControl = 1 + ch.courage = 1 + ch.conscience = 1 ' Arrays/Objects ' Abilities (Talents/Skills/Knowledges) @@ -1329,7 +1375,6 @@ Sub CGGetBackgrounds (ch As CharacterType) Dim backgroundValues(BACKGROUNDS_COUNT) As Integer While backgroundPoints > 0 Cls - Print "Which background do you want to spend 1 of your " + itos$(backgroundPoints) + " background points on?" 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) @@ -1355,14 +1400,23 @@ Sub CGGetRoad (ch As CharacterType) End Sub Sub CGSpendVirtuePoints (ch As CharacterType) - ' TODO: Spend virtue points - 'Conscience 1 - 'Self-Control 1 - 'Courage 1 - 'Which virtue do you wish to add one of your 7 points to? - ch.conscience = 1 - ch.selfControl = 4 - ch.courage = 5 + ' 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?") + Call SetVirtue(ch, virtue, GetVirtue(ch, virtue) + 1) + virtuePoints = virtuePoints - 1 + Wend + + ' These are VtDA specific. Conscience/Conviction, Self-Control/Instinct, and Courage are the virtues there. + ' TODO: figure out what to do about them. + ch.conviction = 2 + ch.instinct = 3 End Sub ' Ignore this warning ch is not used yet because the sub is not implemented yet. @@ -1382,10 +1436,6 @@ Sub CharacterGenerator () Call CGGetRoad(ch) Call CGSpendVirtuePoints(ch) - ' TODO: We don't know what to call these two. Figure that out and maybe make it a sub. These next few could all be one sub if related. - ch.conviction = 2 - ch.instinct = 3 - ' TODO: figure out how to actually calculate generation; seems like a combination of 13 or 15 depending on clan and your generation background count ' Generation starts at 13 and goes down 1 point per point of the "generation" background. ch.generation = INITIAL_GENERATION - GetBackground(ch, BACKGROUND_GENERATION) @@ -1452,9 +1502,9 @@ Sub ShowCharacterSheet (ch As CharacterType) 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$(Str$(ch.attr_strength), 7, " ") + " App. " + MakeFitL$(Str$(ch.attr_appearance), 7, " ") + " Int. " + MakeFitL$(Str$(ch.attr_intelligence), 5, " ") + " º Concept: " + MakeFitL$(ch.concept$, 28, " ") + " º" - Print "º Dex. " + MakeFitL$(Str$(ch.attr_dexterity), 7, " ") + " Cha. " + MakeFitL$(Str$(ch.attr_charisma), 7, " ") + " Per. " + MakeFitL$(Str$(ch.attr_perception), 5, " ") + " ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" - Print "º Sta. " + MakeFitL$(Str$(ch.attr_stamina), 7, " ") + " Man. " + MakeFitL$(Str$(ch.attr_manipulation), 7, " ") + " Wit. " + MakeFitL$(Str$(ch.attr_wits), 5, " ") + " º Derangements: º" + 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 "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ Regression,__________________________ º" Print "º Disciplines: º _____________________________________ º" Print "º " + MakeFitL$(disciplineStrings(0), 36, " ") + " º _____________________________________ º" @@ -1475,15 +1525,16 @@ Sub ShowCharacterSheet (ch As CharacterType) 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, " ") + Str$(GetTalent(ch, index)), 25, " ") + " " + MakeFitC(MakeFitL$(Skills(index) + ":", 14, " ") + Str$(GetSkill(ch, index)), 25, " ") + " " + MakeFitC(MakeFitL$(Knowledges(index) + ":", 14, " ") + Str$(GetKnowledge(ch, index)), 24, " ") + " º" + 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, " ") + " º " + MakeFitL$(MakeFitL$("Conscience:", 14, " ") + MakeFitR$(Str$(ch.conscience), 2, " "), 37, " ") + " º" - Print "º " + MakeFitL$(backgroundStrings(1), 36, " ") + " º " + MakeFitL$(MakeFitR$("Conviction:", 14, " ") + MakeFitR$(Str$(ch.conviction), 2, " "), 37, " ") + " º" - Print "º " + MakeFitL$(backgroundStrings(2), 36, " ") + " º " + MakeFitL$(MakeFitR$("Instinct:", 14, " ") + MakeFitR$(Str$(ch.instinct), 2, " "), 37, " ") + " º" - Print "º " + MakeFitL$(backgroundStrings(3), 36, " ") + " º " + MakeFitL$(MakeFitR$("Self-Control:", 14, " ") + MakeFitR$(Str$(ch.selfControl), 2, " "), 37, " ") + " º" - Print "º " + MakeFitL$(backgroundStrings(4), 36, " ") + " º " + MakeFitL$(MakeFitR$("Courage:", 14, " ") + MakeFitR$(Str$(ch.courage), 2, " "), 37, " ") + " º" + Print " " + MakeFitB$("Conscience:", itos$(ch.conscience), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(0), 36, " ") + " º " + MakeFitB$("Conscience:", itos$(ch.conscience), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(1), 36, " ") + " º " + MakeFitB$("Conviction:", itos$(ch.conviction), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(2), 36, " ") + " º " + MakeFitB$("Instinct:", itos$(ch.instinct), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(3), 36, " ") + " º " + MakeFitB$("Self-Control:", itos$(ch.selfControl), 37, " ") + " º" + Print "º " + MakeFitL$(backgroundStrings(4), 36, " ") + " º " + MakeFitB$("Courage:", itos$(ch.courage), 37, " ") + " º" Print "ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹" Print "º <> º" Print "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ" @@ -1659,6 +1710,7 @@ Sub FillAttributeAbbreviationsInGroup (group As Integer, abbreviations() As Stri End Sub Sub Test + 'End End Sub Sub AdjustMenuStyle (style As MenuStyle, items() As MenuItem, count As Integer, ignoreValue As Integer) @@ -1768,3 +1820,8 @@ End Function Function GetBackgroundPoints () GetBackgroundPoints = BACKGROUND_POINTS End Function + +Function GetVirtuePoints () + GetVirtuePoints = VIRTUE_POINTS +End Function +