AltSystem/docs/5-build_skills.md

132 lines
No EOL
8.2 KiB
Markdown
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature: Build Skills tab
The second tab of the addon will follow these [designs](./build_skills_tab_design.png).
## Acceptance Criteria
- This screen should show the same skills we use in the main screen, which come from the TRP profile
- The skills should be sorted by level
- The skill list should be scrollable, with the "Save" button pinned/sticky to the bottom
## Editing skills
- The user should be able to edit the name, level, and numerical score of each skill
- Edits should not be saved until the user explicitly clicks the "Save" button
### Skill Level and Value
- When a skill level is selected, the numerical score dropdown should update to only allow values within the skill level
- Inept: 0
- Novice: 1-5
- Adept: 6-10
- Expert: 11-19
- Master: 20
### Deleting skills
- Clicking the "Delete" button should remove the skill from the list
### Adding Skills
- Clicking the "Add a Row" button should add a new skill row to the list
- Default values for the new skill should be:
- Name: Skillname
- Level: Novice
- Value: 1
### Saving Skills
- When clicking the "Save" button:
- Newly added skills should be added to the TRP profile
- Existing skills should be updated in the TRP profile
- Skills that were deleted should also be removed from the TRP profile
- Icons should not be changed
## References
- Refer to [Data.lua](../Data.lua) for details on how we currently fetch the skills from TRP
- Refer to the TRP3 source code in case it's necessary [here](https://github.com/Total-RP/Total-RP-3)
---
## Implementation Plan
### 1. Add a `SaveSkills` function to Data.lua
- Create `AltSystem.Data:SaveSkills(editedSkills)` that writes skills back to the TRP3 profile
- Access the TRP3 profile via `TRP3_API.profile.getData("player/characteristics")` to get the `characteristics.PS` (personality traits) array
- For each edited skill, update or insert entries in `PS`:
- `LT` = skill name
- `RT` = level keyword (e.g. "Novice", "Adept", etc.)
- `V2` = numeric value (020)
- `IC` = preserve existing icon (do not change); for new skills, use a sensible default icon (e.g. `"inv_misc_questionmark"`)
- Remove any PS entries that were deleted by the user
- After writing, call `TRP3_API.dashboard.showCharacteristics()` or fire the appropriate TRP3 event if needed to refresh TRP3's own UI
- **Edge case:** If the TRP3 API is unavailable, show a warning message and abort save
### 2. Extract skill-level constants into shared lookup tables in Data.lua
- The acceptance criteria defines value ranges per level (Inept: 0, Novice: 15, Adept: 610, Expert: 1119, Master: 20)
- `SKILL_KEYWORD_RANGES` already exists but excludes Inept/Master min-max correctly for the Build tab's needs; extend or create a new table `AltSystem.Data.SkillValueRanges` that is accessible from UI.lua:
```
{ Inept = {min=0, max=0}, Novice = {min=1, max=5}, Adept = {min=6, max=10}, Expert = {min=11, max=19}, Master = {min=20, max=20} }
```
- Create `AltSystem.Data.SkillLevelOrder` — an ordered array `{"Inept", "Novice", "Adept", "Expert", "Master"}` for populating the level dropdown in display order
- Create a helper `AltSystem.Data:GetDefaultValueForLevel(level)` that returns the minimum value for that level (used when the user changes level to auto-set the value)
### 3. Add a function to read raw skills (with numeric values) from TRP3 in Data.lua
- Currently `RefreshSkills()` converts TRP3 traits into `{name, level, modifier}` — the Build tab needs the raw **numeric value** and the **icon** as well
- Create `AltSystem.Data:GetEditableSkills()` that returns an array of `{name, level, value, icon}` for each valid skill trait in the TRP3 profile (excluding Base Roll and Unskilled, which are system-generated entries)
- Sort the returned skills by level using `AltSystem.Data.SkillLevelOrder` ordering (Inept first, Master last) — matching the acceptance criteria "sorted by level"
- Reuse existing helpers `FindSkillKeyword` and `ParseSkillLevel` (promote them from local to module-level if needed, or call internally)
### 4. Build the Build Skills tab UI (new file: BuildSkillsUI.lua)
- Create a new file to keep UI.lua manageable; register it in `AltSystem.toc` between `UI.lua` and `Roll.lua`
- Create `AltSystem:CreateBuildSkillsContent(parentFrame)` called from `CreateMainFrame` in UI.lua (replacing the placeholder)
- **Layout structure:**
- **Info text** at top — two golden/yellow paragraphs explaining that skills come from TRP (matches mockup)
- **"Skill list" section header**
- **Column headers**: Name, Level, Value (bold golden text)
- **Scrollable skill list** — a `ScrollFrame` containing dynamically created skill rows
- **"Add A Row" button** — anchored below the last skill row, inside the scroll child
- **"Save Skills to TRP" button** — pinned/sticky at the bottom of the tab, outside the scroll frame
### 5. Implement editable skill rows
- Each skill row is a frame containing:
- **Name**: `EditBox` (text input) — pre-filled with current skill name
- **Level**: `DropdownButton` (WowStyle1DropdownTemplate) — options: Inept, Novice, Adept, Expert, Master
- **Value**: `DropdownButton` — options dynamically generated based on selected level (e.g. Novice → 1,2,3,4,5)
- **Delete button**: A button with a trash-can icon/red texture that removes the row
- Store all row data in a local working copy array (`editableSkills`), not directly in `AltSystem.Data.Skills`
- When the **level dropdown** changes:
- Update the value dropdown options to only show valid values for the new level
- Auto-set the value to the minimum for that level (e.g. switching to Adept → value becomes 6)
- **Row management:**
- `CreateSkillRow(parent, index, skillData)` — creates or recycles a row frame
- `RefreshSkillRows()` — rebuilds/repositions all rows and updates scroll child height
- Deleting a row removes it from `editableSkills` and calls `RefreshSkillRows()`
### 6. Implement "Add A Row" functionality
- Clicking "Add A Row" inserts a new entry into `editableSkills`:
- `{ name = "Skillname", level = "Novice", value = 1, icon = "inv_misc_questionmark", isNew = true }`
- Calls `RefreshSkillRows()` to render the new row
- The scroll frame should auto-scroll to show the new row
### 7. Implement "Save Skills to TRP" functionality
- On click, call `AltSystem.Data:SaveSkills(editableSkills)` which:
1. Reads current `characteristics.PS` from TRP3
2. Rebuilds the PS array: keeps non-skill traits untouched, updates/adds/removes skill traits based on `editableSkills`
3. Writes the updated PS back to the TRP3 profile data
4. Calls `RefreshSkills()` so the Use Skills tab dropdown reflects the changes immediately
- Show a confirmation message (print to chat or a brief on-screen text) on successful save
- **Edge cases:**
- Empty skill list: allowed — just remove all skill traits from PS
- Duplicate skill names: allowed (TRP3 doesn't enforce uniqueness)
- Unsaved changes + tab switch: no confirmation dialog required (per spec, changes are just lost)
### 8. Wire up tab switching to populate Build Skills tab
- In `SelectTab(2)` (UI.lua), call `AltSystem:RefreshBuildSkillsList()` to reload skills from TRP3 into the working copy
- This ensures the Build tab always shows the latest TRP3 data when opened, and any unsaved edits are discarded on tab switch
### 9. Update AltSystem.toc
- Add `BuildSkillsUI.lua` to the file list (after `UI.lua`, before `Roll.lua`)
### 10. Testing checklist
- [ ] Build Skills tab shows skills from TRP3 profile, sorted by level
- [ ] Skill name is editable via text input
- [ ] Level dropdown shows all 5 levels; changing level updates value dropdown options and auto-selects minimum value
- [ ] Value dropdown only shows values valid for the current level
- [ ] Delete button removes the row immediately
- [ ] "Add A Row" adds a row with defaults (Skillname, Novice, 1)
- [ ] Skill list scrolls when rows exceed visible area
- [ ] "Save" button is always visible (pinned to bottom)
- [ ] Save writes correct data to TRP3 profile (LT, RT, V2, IC preserved)
- [ ] Save does not modify icons of existing skills
- [ ] After save, Use Skills tab dropdown reflects the updated skills
- [ ] Switching tabs discards unsaved changes and reloads from TRP3
- [ ] Works correctly with 0 skills (empty profile)
- [ ] Works correctly with many skills (20+) — scroll behavior