ui change

This commit is contained in:
Rory Hinnen
2026-09-07 13:48:32 -05:00
parent 2c10c7c093
commit ac4d4a670a
4 changed files with 71 additions and 45 deletions
+61 -39
View File
@@ -223,6 +223,8 @@ struct MainView: View {
.font(.system(size: controlSize)) .font(.system(size: controlSize))
Text("Modifier") Text("Modifier")
} }
.disabled(current.torrent || current.psychic)
.opacity((current.torrent || current.psychic) ? 0.4 : 1.0)
Spacer() Spacer()
VStack { VStack {
Text("Blow Up") Text("Blow Up")
@@ -231,16 +233,16 @@ struct MainView: View {
Image(systemName: "die.face.6") Image(systemName: "die.face.6")
.foregroundColor(.primary) .foregroundColor(.primary)
} }
.disabled(current.blowupUsed)
Button(action: { current.applyBlowup(face: .five) }) { Button(action: { current.applyBlowup(face: .five) }) {
Image(systemName: "die.face.5") Image(systemName: "die.face.5")
.foregroundColor(.primary) .foregroundColor(.primary)
} }
.disabled(current.blowupUsed)
} }
.padding() .padding()
.font(.system(size: controlSize)) .font(.system(size: controlSize))
} }
.disabled(current.blowupUsed || current.torrent)
.opacity((current.blowupUsed || current.torrent) ? 0.4 : 1.0)
Spacer() Spacer()
} }
HStack { HStack {
@@ -258,29 +260,39 @@ struct MainView: View {
.font(.system(size: controlSize)) .font(.system(size: controlSize))
} }
.padding(.horizontal) .padding(.horizontal)
.disabled(current.torrent)
.opacity(current.torrent ? 0.4 : 1.0)
HStack {
Toggle("Torrent", isOn: $current.torrent)
Spacer()
Toggle("Psychic", isOn: $current.psychic)
.disabled(current.torrent)
.opacity(current.torrent ? 0.4 : 1.0)
}
.padding(.horizontal)
} }
.padding() .padding()
} }
//MARK: die views //MARK: die views
@ViewBuilder func die(whichDie: Dice.DiceType) -> some View { @ViewBuilder func die(whichDie: Dice.DiceType) -> some View {
let size = 30.0 let size = 22.0
let displayColorHit = (whichDie.rawValue >= current.cutoff.rawValue) ? Color.red : Color.primary let displayColorHit = (whichDie.rawValue >= current.cutoff.rawValue) ? Color.red : Color.primary
let displayColorArmor = (whichDie.rawValue <= current.cutoff.rawValue) ? Color.red : Color.primary let displayColorArmor = (whichDie.rawValue <= current.cutoff.rawValue) ? Color.red : Color.primary
let displayColorArmorText = (whichDie.rawValue < current.cutoff.rawValue) ? Color.red : Color.primary let displayColorArmorText = (whichDie.rawValue < current.cutoff.rawValue) ? Color.red : Color.primary
HStack{ VStack(spacing: 2) {
Text(String(current.dice.value(which: whichDie)))
.foregroundColor(current.state == .armour ?
displayColorArmorText : displayColorHit)
.frame(minWidth: 44, alignment: .trailing)
Image(systemName: "die.face." + String(whichDie.rawValue) + ".fill") Image(systemName: "die.face." + String(whichDie.rawValue) + ".fill")
.foregroundColor(current.state == .armour ? .foregroundColor(current.state == .armour ?
displayColorArmor : displayColorHit) displayColorArmor : displayColorHit)
Text(String(current.dice.value(which: whichDie)))
.foregroundColor(current.state == .armour ?
displayColorArmorText : displayColorHit)
.frame(minWidth: 30, alignment: .center)
} }
.font(.system(size: size)) .font(.system(size: size))
.padding(2) .padding(4)
.frame(maxWidth: .infinity)
.gesture(TapGesture().onEnded { .gesture(TapGesture().onEnded {
if current.state == .hit { if current.state == .hit {
if whichDie.rawValue != 1 { if whichDie.rawValue != 1 {
@@ -292,7 +304,7 @@ struct MainView: View {
} }
@ViewBuilder func diePool() -> some View { @ViewBuilder func diePool() -> some View {
VStack(alignment: .leading) { HStack(spacing: 0) {
ForEach(Dice.DiceType.allCases.reversed(), id: \.rawValue) { i in ForEach(Dice.DiceType.allCases.reversed(), id: \.rawValue) { i in
die(whichDie: i) die(whichDie: i)
} }
@@ -325,37 +337,47 @@ struct MainView: View {
if current.state == .armour {myCircle()} if current.state == .armour {myCircle()}
Text(RollState.armour.print())}} Text(RollState.armour.print())}}
}.font(.system(size: 60)) }.font(.system(size: 60))
VStack{ VStack(spacing: 12) {
HStack { HStack(spacing: 12) {
VStack { Button(action: { showFillView.toggle() }) {
Button(action: { showFillView.toggle() }) { VStack(spacing: 4) {
VStack(spacing: 2) { Text("Dice Pool")
Text("Dice Pool") .font(.caption)
.font(.caption) Text(String(current.total))
Text(String(current.total)) .font(.system(size: 28, weight: .black))
.font(.system(size: 28, weight: .black))
}
.padding(.horizontal, 20)
.padding(.vertical, 8)
.background(Color(blue).opacity(0.35))
.clipShape(RoundedRectangle(cornerRadius: 10))
.foregroundColor(.primary)
} }
.sheet(isPresented: $showFillView, .frame(maxWidth: .infinity)
onDismiss: { current.resetPool() }) { .padding(.vertical, 12)
VStack { .background(Color.white)
AddToPool() .clipShape(RoundedRectangle(cornerRadius: 10))
Button("Accept", action: {showFillView.toggle()}) .foregroundColor(.black)
.padding(20) }
} .sheet(isPresented: $showFillView,
onDismiss: { current.resetPool() }) {
VStack {
AddToPool()
Button("Accept", action: {showFillView.toggle()})
.padding(20)
} }
Button(action: current.incrementState) { }
buttons(color: red, label: current.state.text(), value: current.result) Button(action: current.incrementState) {
VStack(spacing: 4) {
Text(current.state.text())
.font(.caption)
Text(String(current.result))
.font(.system(size: 28, weight: .black))
} }
}.padding(.leading, padSize) .frame(maxWidth: .infinity)
Spacer() .padding(.vertical, 12)
diePool().padding(.trailing, padSize) .background(Color.white)
}.frame(maxHeight: 285) .clipShape(RoundedRectangle(cornerRadius: 10))
.foregroundColor(.black)
}
}
.padding()
.background(Color.black)
.clipShape(RoundedRectangle(cornerRadius: 14))
diePool()
stateView() stateView()
}.padding() }.padding()
} }
+1 -1
View File
@@ -148,7 +148,7 @@ struct Dice {
func armour(die: Int, invulnerable: Bool, save: Int, armourPenetration: Int) -> Int { func armour(die: Int, invulnerable: Bool, save: Int, armourPenetration: Int) -> Int {
var total = 0 var total = 0
switch invulnerable ? save : (save - armourPenetration) { switch invulnerable ? save : (save + armourPenetration) {
case 7...: case 7...:
total = six + five + four + three + two + one total = six + five + four + three + two + one
case 6: case 6:
+6 -2
View File
@@ -152,6 +152,8 @@ class Roll: ObservableObject {
@Published var saveHasRerolled = false @Published var saveHasRerolled = false
@Published var blowupUsed = false @Published var blowupUsed = false
@Published var torrent = false
@Published var psychic = false
// calculated variables // calculated variables
var totalDigits: [Int] { var totalDigits: [Int] {
@@ -216,7 +218,9 @@ class Roll: ObservableObject {
var hit: Int { var hit: Int {
get { get {
return self.dice.hit(die: total, cutoff: self.hitCutoff.rawValue, modifier: self.modifier.rawValue) if torrent { return total }
let mod = psychic ? Dice.RollModifiers.none.rawValue : modifier.rawValue
return self.dice.hit(die: total, cutoff: self.hitCutoff.rawValue, modifier: mod)
} }
} }
@@ -383,7 +387,7 @@ class Roll: ObservableObject {
cutoff = woundCutoff cutoff = woundCutoff
case .armour: case .armour:
mode = saveRerollMode mode = saveRerollMode
cutoff = invulnerable ? armourSave : (armourSave - armourPenetration) cutoff = invulnerable ? armourSave : (armourSave + armourPenetration)
} }
switch mode { switch mode {
+2 -2
View File
@@ -1,6 +1,6 @@
- [ ] Update graphics to clarify roll context (to hit / to wound / armor save) #focus/professional - [ ] Update graphics to clarify roll context (to hit / to wound / armor save) #focus/professional
- [ ] Add stacking flat hit/wound modifier input, capped at net ±1 #focus/professional - [x] Add stacking flat hit/wound modifier input, capped at net ±1 #focus/professional
- [ ] Add reroll mode selector (none / reroll 1s / reroll all failed / reroll all) #focus/professional - [x] Add reroll mode selector (none / reroll 1s / reroll all failed / reroll all) #focus/professional
- [ ] Add critical-trigger layer keyed off unmodified natural 6s (Sustained Hits, Lethal Hits, Devastating Wounds, Anti-X) #focus/professional - [ ] Add critical-trigger layer keyed off unmodified natural 6s (Sustained Hits, Lethal Hits, Devastating Wounds, Anti-X) #focus/professional
- [ ] Add "ignore all modifiers" flag (Psychic) #focus/professional - [ ] Add "ignore all modifiers" flag (Psychic) #focus/professional
- [ ] Add "auto-success, no roll" flag (Torrent) #focus/professional - [ ] Add "auto-success, no roll" flag (Torrent) #focus/professional