First working version

This commit is contained in:
Gonçalo Correia 2026-04-11 16:05:04 +01:00
commit 150e52842e
12 changed files with 515 additions and 0 deletions

10
.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

6
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/AltSystem.iml" filepath="$PROJECT_DIR$/AltSystem.iml" />
</modules>
</component>
</project>

11
AltSystem.iml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="LUA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="Lua" jdkType="Lua SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

12
AltSystem.toc Normal file
View file

@ -0,0 +1,12 @@
## Interface: 120001
## Title: AltSystem
## Notes: Enhances RP gameplay with a custom rolling system
## Author: Goncalo
## Version: 1.0.0
## Dependencies: totalRP3, totalRP3_Extended
## SavedVariables: AltSystemDB
Data.lua
Core.lua
UI.lua
Roll.lua

97
Core.lua Normal file
View file

@ -0,0 +1,97 @@
-- AltSystem Core
-- Addon initialization, slash command registration, and TRP3 integration.
AltSystem = AltSystem or {}
AltSystem.State = {
selectedSkillIndex = 1,
selectedItemIndex = 1, -- 1 = No item
selectedDefenseIndex = 1, -- 1 = Base armor
shieldEnabled = false,
}
-- Initialization on ADDON_LOADED
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")
frame:SetScript("OnEvent", function(self, event, arg1)
if event == "ADDON_LOADED" and arg1 == "AltSystem" then
AltSystem:Init()
elseif event == "PLAYER_LOGIN" then
AltSystem:RegisterTRP3Button()
AltSystem:RegisterMinimapButton()
end
end)
function AltSystem:Init()
-- Register slash command /altsystem
SLASH_ALTSYSTEM1 = "/altsystem"
SlashCmdList["ALTSYSTEM"] = function()
AltSystem:ToggleWindow()
end
print("|cff00ccffAltSystem|r loaded. Type /altsystem to open.")
end
function AltSystem:ToggleWindow()
if AltSystem.MainFrame then
if AltSystem.MainFrame:IsShown() then
AltSystem.MainFrame:Hide()
else
AltSystem.MainFrame:Show()
end
end
end
-- TRP3 toolbar button registration
function AltSystem:RegisterTRP3Button()
if TRP3_API and TRP3_API.toolbar then
local toolbarButton = {
id = "altsystem_toolbar_btn",
icon = "Interface\\Icons\\INV_Misc_Dice_02",
tooltip = "AltSystem",
tooltipSub = "Open the AltSystem rolling window",
onClick = function()
AltSystem:ToggleWindow()
end,
}
TRP3_API.toolbar.toolbarAddButton(toolbarButton)
end
end
-- Minimap button using LibDBIcon (lightweight fallback if not available)
function AltSystem:RegisterMinimapButton()
-- Simple minimap button without external libraries
local minimapButton = CreateFrame("Button", "AltSystemMinimapButton", Minimap)
minimapButton:SetSize(32, 32)
minimapButton:SetFrameStrata("MEDIUM")
minimapButton:SetFrameLevel(8)
minimapButton:SetPoint("TOPLEFT", Minimap, "TOPLEFT", 2, -2)
local icon = minimapButton:CreateTexture(nil, "ARTWORK")
icon:SetTexture("Interface\\Icons\\INV_Misc_Dice_02")
icon:SetSize(20, 20)
icon:SetPoint("CENTER")
local border = minimapButton:CreateTexture(nil, "OVERLAY")
border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
border:SetSize(54, 54)
border:SetPoint("TOPLEFT", -2, 2)
minimapButton:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
minimapButton:SetScript("OnClick", function()
AltSystem:ToggleWindow()
end)
minimapButton:SetScript("OnEnter", function(self)
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
GameTooltip:AddLine("AltSystem")
GameTooltip:AddLine("Click to toggle the rolling window", 1, 1, 1)
GameTooltip:Show()
end)
minimapButton:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
end

44
Data.lua Normal file
View file

@ -0,0 +1,44 @@
-- AltSystem Data Definitions
-- Contains dummy skill data, item options, defense options, and modifier constants.
AltSystem = AltSystem or {}
AltSystem.Data = {}
-- Skill levels and their modifiers
AltSystem.Data.SkillLevels = {
["Novice"] = -2,
["Adept"] = 0,
["Expert"] = 2,
["Master"] = 4,
}
-- Dummy skill data: each skill has a name, icon, and level
AltSystem.Data.Skills = {
{ name = "Swordsmanship", icon = "Interface\\Icons\\INV_Sword_04", level = "Expert" },
{ name = "Archery", icon = "Interface\\Icons\\INV_Weapon_Bow_05", level = "Adept" },
{ name = "Fire Magic", icon = "Interface\\Icons\\Spell_Fire_FlameBolt", level = "Master" },
{ name = "Healing", icon = "Interface\\Icons\\Spell_Holy_FlashHeal", level = "Novice" },
{ name = "Stealth", icon = "Interface\\Icons\\Ability_Stealth", level = "Adept" },
}
-- Pre-compute modifier for each skill based on its level
for _, skill in ipairs(AltSystem.Data.Skills) do
skill.modifier = AltSystem.Data.SkillLevels[skill.level] or 0
end
-- Item options: name and modifier (first entry = no item)
AltSystem.Data.Items = {
{ name = "No item", modifier = 0 },
{ name = "Rare item", modifier = 3 },
{ name = "Epic item", modifier = 5 },
}
-- Defense options: name and modifier
AltSystem.Data.Defenses = {
{ name = "Base armor", modifier = 0 },
{ name = "Extra small armor", modifier = 1 },
{ name = "Extra large armor", modifier = 2 },
}
-- Shield modifier
AltSystem.Data.ShieldModifier = 1

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# AltSystem
This project is a WoW Addon, designed to enhance RP gameplay while using a specific rolling system.
The rolling system relies on TRP3 and TRP3:Enhanced addons, so these are explicit dependencies.
## Features
- Main features defined in the /docs folder
## Installation
To use AltSystem, ensure you have the following addons installed:
- TRP3
- TRP3:Enhanced
Follow the installation instructions for these addons before installing AltSystem.

85
Roll.lua Normal file
View file

@ -0,0 +1,85 @@
-- AltSystem Roll Logic
-- Handles /roll 20, captures the result, and applies modifiers.
AltSystem = AltSystem or {}
local pendingRollType = nil -- "attack" or "defense"
-- Perform a roll: triggers the WoW native /roll 20 command
function AltSystem:PerformRoll(rollType)
pendingRollType = rollType
RandomRoll(1, 20)
end
-- Listen for the system message that contains the roll result
local rollListener = CreateFrame("Frame")
rollListener:RegisterEvent("CHAT_MSG_SYSTEM")
rollListener:SetScript("OnEvent", function(self, event, message)
if not pendingRollType then return end
-- Match the roll result pattern: "PlayerName rolls X (1-20)"
local roll = message:match("rolls (%d+) %(1%-20%)")
if not roll then return end
local rollValue = tonumber(roll)
local rollType = pendingRollType
pendingRollType = nil
AltSystem:CalculateAndDisplayResult(rollType, rollValue)
end)
-- Calculate the final result based on the roll type and selected modifiers
function AltSystem:CalculateAndDisplayResult(rollType, rollValue)
local state = AltSystem.State
local skill = AltSystem.Data.Skills[state.selectedSkillIndex]
local item = AltSystem.Data.Items[state.selectedItemIndex]
local skillMod = skill and skill.modifier or 0
local itemMod = item and item.modifier or 0
local total = rollValue
local breakdown = "Roll: " .. rollValue
if rollType == "attack" then
-- Attack Roll = roll + skill modifier + item modifier
total = rollValue + skillMod + itemMod
breakdown = breakdown .. "\nSkill: " .. FormatModifier(skillMod)
if itemMod ~= 0 then
breakdown = breakdown .. " | Item: " .. FormatModifier(itemMod)
end
breakdown = breakdown .. "\n|cffffd100Attack Total: " .. total .. "|r"
elseif rollType == "defense" then
-- Defense Roll = roll + skill modifier + item modifier + defense modifier + shield modifier
local defense = AltSystem.Data.Defenses[state.selectedDefenseIndex]
local defenseMod = defense and defense.modifier or 0
local shieldMod = state.shieldEnabled and AltSystem.Data.ShieldModifier or 0
total = rollValue + skillMod + itemMod + defenseMod + shieldMod
breakdown = breakdown .. "\nSkill: " .. FormatModifier(skillMod)
if itemMod ~= 0 then
breakdown = breakdown .. " | Item: " .. FormatModifier(itemMod)
end
breakdown = breakdown .. "\nDefense: " .. FormatModifier(defenseMod)
if shieldMod ~= 0 then
breakdown = breakdown .. " | Shield: " .. FormatModifier(shieldMod)
end
breakdown = breakdown .. "\n|cff00ccffDefense Total: " .. total .. "|r"
end
if AltSystem.ResultText then
AltSystem.ResultText:SetText(breakdown)
end
end
-- Format a modifier value with sign
function FormatModifier(value)
if value >= 0 then
return "+" .. value
else
return tostring(value)
end
end

190
UI.lua Normal file
View file

@ -0,0 +1,190 @@
-- AltSystem UI
-- Creates the main dialog window with all interface elements.
-- Uses the modern DropdownButton API (WoW 10.2.5+ / 12.0+).
AltSystem = AltSystem or {}
local WINDOW_WIDTH = 300
local WINDOW_HEIGHT = 380
local PADDING = 12
local ROW_HEIGHT = 30
local LABEL_WIDTH = 80
-- Helper: Create a modern dropdown (WowStyle1DropdownTemplate)
local function CreateDropdown(parent, name, yOffset, labelText, options, defaultIndex, onSelect)
local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
label:SetPoint("TOPLEFT", parent, "TOPLEFT", PADDING, yOffset)
label:SetText(labelText)
label:SetWidth(LABEL_WIDTH)
label:SetJustifyH("LEFT")
local selectedIndex = defaultIndex or 1
local dropdown = CreateFrame("DropdownButton", name, parent, "WowStyle1DropdownTemplate")
dropdown:SetPoint("LEFT", label, "RIGHT", 4, 0)
dropdown:SetWidth(160)
dropdown:SetupMenu(function(dropdown, rootDescription)
for i, option in ipairs(options) do
rootDescription:CreateRadio(
option.text,
function(data) return data == selectedIndex end,
function(data)
selectedIndex = data
if onSelect then onSelect(data, options[data]) end
end,
i
)
end
end)
return dropdown
end
function AltSystem:CreateMainFrame()
if AltSystem.MainFrame then return end
-- Main frame
local f = CreateFrame("Frame", "AltSystemMainFrame", UIParent, "BasicFrameTemplateWithInset")
f:SetSize(WINDOW_WIDTH, WINDOW_HEIGHT)
f:SetPoint("CENTER")
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", f.StartMoving)
f:SetScript("OnDragStop", f.StopMovingOrSizing)
f:SetClampedToScreen(true)
f.TitleBg:SetHeight(30)
f.title = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
f.title:SetPoint("TOPLEFT", f.TitleBg, "TOPLEFT", 5, -3)
f.title:SetText("AltSystem")
-- Track current Y offset for layout
local yPos = -40
-------------------------
-- Skill dropdown
-------------------------
local skillOptions = {}
for _, skill in ipairs(AltSystem.Data.Skills) do
local levelMod = skill.modifier
local sign = levelMod >= 0 and "+" or ""
table.insert(skillOptions, {
text = skill.name .. " (" .. skill.level .. " " .. sign .. levelMod .. ")",
icon = skill.icon,
})
end
CreateDropdown(f, "AltSystemSkillDropdown", yPos, "Skill:", skillOptions, AltSystem.State.selectedSkillIndex,
function(index)
AltSystem.State.selectedSkillIndex = index
end)
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Item dropdown
-------------------------
local itemOptions = {}
for _, item in ipairs(AltSystem.Data.Items) do
local sign = item.modifier >= 0 and "+" or ""
local modText = item.modifier ~= 0 and (" (" .. sign .. item.modifier .. ")") or ""
table.insert(itemOptions, {
text = item.name .. modText,
})
end
CreateDropdown(f, "AltSystemItemDropdown", yPos, "Item:", itemOptions, AltSystem.State.selectedItemIndex,
function(index)
AltSystem.State.selectedItemIndex = index
end)
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Defense dropdown
-------------------------
local defenseOptions = {}
for _, def in ipairs(AltSystem.Data.Defenses) do
local sign = def.modifier >= 0 and "+" or ""
local modText = " (" .. sign .. def.modifier .. ")"
table.insert(defenseOptions, {
text = def.name .. modText,
})
end
CreateDropdown(f, "AltSystemDefenseDropdown", yPos, "Defense:", defenseOptions, AltSystem.State.selectedDefenseIndex,
function(index)
AltSystem.State.selectedDefenseIndex = index
end)
yPos = yPos - ROW_HEIGHT - 8
-------------------------
-- Shield checkbox
-------------------------
local shieldLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
shieldLabel:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
shieldLabel:SetText("Shield:")
shieldLabel:SetWidth(LABEL_WIDTH)
shieldLabel:SetJustifyH("LEFT")
local shieldCheck = CreateFrame("CheckButton", "AltSystemShieldCheck", f, "UICheckButtonTemplate")
shieldCheck:SetPoint("LEFT", shieldLabel, "RIGHT", -6, 0)
shieldCheck:SetChecked(AltSystem.State.shieldEnabled)
local shieldText = shieldCheck:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
shieldText:SetPoint("LEFT", shieldCheck, "RIGHT", 2, 0)
shieldText:SetText("+1 modifier")
shieldCheck:SetScript("OnClick", function(self)
AltSystem.State.shieldEnabled = self:GetChecked()
end)
yPos = yPos - ROW_HEIGHT - 12
-------------------------
-- Roll buttons
-------------------------
local btnWidth = (WINDOW_WIDTH - PADDING * 3) / 2
local attackBtn = CreateFrame("Button", "AltSystemAttackRollBtn", f, "UIPanelButtonTemplate")
attackBtn:SetSize(btnWidth, 28)
attackBtn:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
attackBtn:SetText("Attack Roll")
local defenseBtn = CreateFrame("Button", "AltSystemDefenseRollBtn", f, "UIPanelButtonTemplate")
defenseBtn:SetSize(btnWidth, 28)
defenseBtn:SetPoint("TOPRIGHT", f, "TOPRIGHT", -PADDING, yPos)
defenseBtn:SetText("Defense Roll")
yPos = yPos - 40
-------------------------
-- Roll result area
-------------------------
local resultBg = CreateFrame("Frame", nil, f, "InsetFrameTemplate")
resultBg:SetPoint("TOPLEFT", f, "TOPLEFT", PADDING, yPos)
resultBg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -PADDING, PADDING)
local resultText = resultBg:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
resultText:SetPoint("CENTER")
resultText:SetText("Roll result will appear here")
resultText:SetJustifyH("CENTER")
resultText:SetWidth(resultBg:GetWidth() - 10)
AltSystem.ResultText = resultText
-- Button click handlers
attackBtn:SetScript("OnClick", function()
AltSystem:PerformRoll("attack")
end)
defenseBtn:SetScript("OnClick", function()
AltSystem:PerformRoll("defense")
end)
f:Hide()
AltSystem.MainFrame = f
end
-- Create the frame on file load so it's ready when Init runs
AltSystem:CreateMainFrame()

38
docs/1-interface.md Normal file
View file

@ -0,0 +1,38 @@
# Feature: Interface
- The addon's main interface is a simple dialog window.
- This window can be shown/hidden via:
- A slash command `/altsystem`
- A button inside the TRP toolbar
- A button in the minimap menu
## Window features
### Skill dropdown
- A small dropdown menu to select the skill to be used. (use dummy data for now)
- 1 skill per line
- Each skill has a name, an icon, a level (Novice, Adept, Expert, Master), and a corresponding modifier
- Novice: -2
- Adept: +0
- Expert: +2
- Master: +4
### Item dropdown
- A small dropdown menu to select if an item should be used or not.
- Default to no item selected
- Static data for available selections:
- Rare item (+3 modifier)
- Epic item (+5 modifier)
### Defense dropdown
- A small dropdown menu to select the defense to be used.
- Static data for available selections:
- Base armor (+0)
- Extra small armor (+1)
- Extra large armor (+2)
- Default to Base armor
### Shield checkbox
- A checkbox to select if a shield (+1) should be used or not.
- Default to unchecked
### Roll buttons
- Two buttons, each will perform the WoW native `/roll 20` command when clicked
### Roll result
- A small area, to show the result of the rolls based on which button was clicked
- The 'Attack Roll' button will show the sum of the roll, plus any skill and item modifiers
- The 'Defense Roll' button will show the sum of the roll, plus any skill, item, defense, and shield modifier

1
docs/2-skills.md Normal file
View file

@ -0,0 +1 @@
# Feature: Skills