Started adding skills.

This commit is contained in:
2021-02-13 20:32:58 -08:00
parent a5344abeb0
commit 137d6f7c43
10 changed files with 315 additions and 10 deletions

View File

@@ -7,8 +7,12 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
E210B83025B426570083EAC5 /* ProficiencyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B82F25B426570083EAC5 /* ProficiencyType.swift */; }; E20209D325D8DD9600EFE733 /* Skill+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209D225D8DD9600EFE733 /* Skill+CoreDataClass.swift */; };
E210B83525B428A30083EAC5 /* AdvantageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B83425B428A30083EAC5 /* AdvantageType.swift */; }; E20209E825D8DEC100EFE733 /* AbilityScore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209E725D8DEC100EFE733 /* AbilityScore.swift */; };
E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209F225D8E04300EFE733 /* ProficiencyType.swift */; };
E20209F525D8E04300EFE733 /* AdvantageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209F325D8E04300EFE733 /* AdvantageType.swift */; };
E20209FB25D8E19100EFE733 /* SkillViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209F925D8E19100EFE733 /* SkillViewModel.swift */; };
E20209FC25D8E19100EFE733 /* MonsterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E20209FA25D8E19100EFE733 /* MonsterViewModel.swift */; };
E210B83A25B42D980083EAC5 /* MCProficiencyPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B83925B42D980083EAC5 /* MCProficiencyPicker.swift */; }; E210B83A25B42D980083EAC5 /* MCProficiencyPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B83925B42D980083EAC5 /* MCProficiencyPicker.swift */; };
E210B83F25B42DAB0083EAC5 /* MCAdvantagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B83E25B42DAB0083EAC5 /* MCAdvantagePicker.swift */; }; E210B83F25B42DAB0083EAC5 /* MCAdvantagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E210B83E25B42DAB0083EAC5 /* MCAdvantagePicker.swift */; };
E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */; }; E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */; };
@@ -51,8 +55,12 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
E210B82F25B426570083EAC5 /* ProficiencyType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProficiencyType.swift; sourceTree = "<group>"; }; E20209D225D8DD9600EFE733 /* Skill+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Skill+CoreDataClass.swift"; sourceTree = "<group>"; };
E210B83425B428A30083EAC5 /* AdvantageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvantageType.swift; sourceTree = "<group>"; }; E20209E725D8DEC100EFE733 /* AbilityScore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbilityScore.swift; sourceTree = "<group>"; };
E20209F225D8E04300EFE733 /* ProficiencyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProficiencyType.swift; sourceTree = "<group>"; };
E20209F325D8E04300EFE733 /* AdvantageType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvantageType.swift; sourceTree = "<group>"; };
E20209F925D8E19100EFE733 /* SkillViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkillViewModel.swift; sourceTree = "<group>"; };
E20209FA25D8E19100EFE733 /* MonsterViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonsterViewModel.swift; sourceTree = "<group>"; };
E210B83925B42D980083EAC5 /* MCProficiencyPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCProficiencyPicker.swift; sourceTree = "<group>"; }; E210B83925B42D980083EAC5 /* MCProficiencyPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCProficiencyPicker.swift; sourceTree = "<group>"; };
E210B83E25B42DAB0083EAC5 /* MCAdvantagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCAdvantagePicker.swift; sourceTree = "<group>"; }; E210B83E25B42DAB0083EAC5 /* MCAdvantagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCAdvantagePicker.swift; sourceTree = "<group>"; };
E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Monster+CoreDataClass.swift"; sourceTree = "<group>"; }; E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Monster+CoreDataClass.swift"; sourceTree = "<group>"; };
@@ -108,6 +116,16 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
E20209E625D8DEB600EFE733 /* Enums */ = {
isa = PBXGroup;
children = (
E20209F325D8E04300EFE733 /* AdvantageType.swift */,
E20209F225D8E04300EFE733 /* ProficiencyType.swift */,
E20209E725D8DEC100EFE733 /* AbilityScore.swift */,
);
path = Enums;
sourceTree = "<group>";
};
E2570FAC25B1AC520055B23B = { E2570FAC25B1AC520055B23B = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -193,9 +211,11 @@
E257101225B1B2790055B23B /* Models */ = { E257101225B1B2790055B23B /* Models */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E20209FA25D8E19100EFE733 /* MonsterViewModel.swift */,
E20209F925D8E19100EFE733 /* SkillViewModel.swift */,
E20209E625D8DEB600EFE733 /* Enums */,
E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */, E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */,
E210B82F25B426570083EAC5 /* ProficiencyType.swift */, E20209D225D8DD9600EFE733 /* Skill+CoreDataClass.swift */,
E210B83425B428A30083EAC5 /* AdvantageType.swift */,
); );
path = Models; path = Models;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -337,6 +357,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
E20209FB25D8E19100EFE733 /* SkillViewModel.swift in Sources */,
E2570FC225B1AC550055B23B /* Persistence.swift in Sources */, E2570FC225B1AC550055B23B /* Persistence.swift in Sources */,
E2570FBB25B1AC520055B23B /* ContentView.swift in Sources */, E2570FBB25B1AC520055B23B /* ContentView.swift in Sources */,
E2570FC525B1AC550055B23B /* MonsterCards.xcdatamodeld in Sources */, E2570FC525B1AC550055B23B /* MonsterCards.xcdatamodeld in Sources */,
@@ -348,13 +369,16 @@
E2B5285925B3028700AAA69E /* EditMonster.swift in Sources */, E2B5285925B3028700AAA69E /* EditMonster.swift in Sources */,
E2570FF525B1ADEB0055B23B /* Dashboard.swift in Sources */, E2570FF525B1ADEB0055B23B /* Dashboard.swift in Sources */,
E257100425B1AF4A0055B23B /* SearchBar.swift in Sources */, E257100425B1AF4A0055B23B /* SearchBar.swift in Sources */,
E20209F525D8E04300EFE733 /* AdvantageType.swift in Sources */,
E20209FC25D8E19100EFE733 /* MonsterViewModel.swift in Sources */,
E2570FFF25B1AE180055B23B /* Library.swift in Sources */, E2570FFF25B1AE180055B23B /* Library.swift in Sources */,
E2BD703125B3BBB90058ED69 /* MCStepperField.swift in Sources */, E2BD703125B3BBB90058ED69 /* MCStepperField.swift in Sources */,
E210B83525B428A30083EAC5 /* AdvantageType.swift in Sources */, E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */,
E2570FFA25B1AE020055B23B /* Collections.swift in Sources */, E2570FFA25B1AE020055B23B /* Collections.swift in Sources */,
E2570FB925B1AC520055B23B /* MonsterCardsApp.swift in Sources */, E2570FB925B1AC520055B23B /* MonsterCardsApp.swift in Sources */,
E210B83025B426570083EAC5 /* ProficiencyType.swift in Sources */, E20209D325D8DD9600EFE733 /* Skill+CoreDataClass.swift in Sources */,
E2BD702C25B3A8D70058ED69 /* MCTextField.swift in Sources */, E2BD702C25B3A8D70058ED69 /* MCTextField.swift in Sources */,
E20209E825D8DEC100EFE733 /* AbilityScore.swift in Sources */,
E210B83F25B42DAB0083EAC5 /* MCAdvantagePicker.swift in Sources */, E210B83F25B42DAB0083EAC5 /* MCAdvantagePicker.swift in Sources */,
E26CDA2B25CFB38E00E3F50D /* MCArmorTypePicker.swift in Sources */, E26CDA2B25CFB38E00E3F50D /* MCArmorTypePicker.swift in Sources */,
); );

View File

@@ -0,0 +1,53 @@
//
// AbilityScore.swift
// MonsterCards
//
// Created by Tom Hicks on 1/18/21.
//
import Foundation
enum AbilityScore: String, CaseIterable, Identifiable {
case strength = "strength"
case dexterity = "dexterity"
case constitution = "constitution"
case intelligence = "intelligence"
case wisdom = "wisdom"
case charisma = "charisma"
var id: AbilityScore { self }
var displayName: String {
switch self {
case .strength:
return "Strength"
case .dexterity:
return "Dexterity"
case .constitution:
return "Constitution"
case .intelligence:
return "Intelligence"
case .wisdom:
return "Wisdom"
case .charisma:
return "Charisma"
}
}
var shortDisplayName: String {
switch self {
case .strength:
return "STR"
case .dexterity:
return "DEX"
case .constitution:
return "CON"
case .intelligence:
return "INT"
case .wisdom:
return "WIS"
case .charisma:
return "CHA"
}
}
}

View File

@@ -137,6 +137,23 @@ public class Monster: NSManagedObject {
return Int(floor(Double((score - 10)) / 2.0)) return Int(floor(Double((score - 10)) / 2.0))
} }
func abilityModifierForAbilityScore(_ abilityScore: AbilityScore) -> Int {
switch abilityScore {
case .strength:
return strengthModifier;
case .dexterity:
return dexterityModifier
case .constitution:
return constitutionModifier
case .intelligence:
return intelligenceModifier
case .wisdom:
return wisdomModifier
case .charisma:
return charismaModifier
}
}
var strengthModifier: Int { var strengthModifier: Int {
get { get {
return Monster.abilityModifierForScore(Int(strengthScore)) return Monster.abilityModifierForScore(Int(strengthScore))
@@ -587,6 +604,21 @@ public class Monster: NSManagedObject {
} }
} }
// MARK: Skills
var skillsDescription: String {
get {
return ""
}
}
var skillsArray: [Skill] {
let set = skills as? Set<Skill> ?? []
return set.sorted {
$0.wrappedName < $1.wrappedName
}
}
// MARK: End // MARK: End
} }

View File

@@ -0,0 +1,8 @@
//
// MonsterViewModel.swift
// MonsterCards
//
// Created by Tom Hicks on 1/18/21.
//
import Foundation

View File

@@ -0,0 +1,63 @@
//
// Skill+CoreDataClass.swift
// MonsterCards
//
// Created by Tom Hicks on 1/18/21.
//
//
import Foundation
import CoreData
@objc(Skill)
public class Skill: NSManagedObject {
var wrappedName: String {
get {
return name ?? ""
}
set {
name = newValue
}
}
var wrappedProficiency: ProficiencyType {
get {
return ProficiencyType.init(rawValue: proficiency ?? "") ?? .none
}
set {
proficiency = newValue.rawValue
}
}
var wrappedAbilityScore: AbilityScore {
get {
return AbilityScore.init(rawValue: abilityScoreName ?? "") ?? .strength
}
set {
abilityScoreName = newValue.rawValue
}
}
var modifier: Int64 {
get {
let proficiencyBonus = Double(monster?.proficiencyBonus ?? 0)
let abilityScoreModifier = Double(monster?.abilityModifierForAbilityScore(wrappedAbilityScore) ?? 0)
switch wrappedProficiency {
case .none:
return Int64(abilityScoreModifier)
case .proficient:
return Int64(abilityScoreModifier + proficiencyBonus)
case .expertise:
return Int64(abilityScoreModifier + 2 * proficiencyBonus)
}
}
}
var skillDescription: String {
get {
return String(format: "%@ %+d%@", name ?? "", modifier)
}
}
}

View File

@@ -0,0 +1,38 @@
//
// SkillViewModel.swift
// MonsterCards
//
// Created by Tom Hicks on 1/18/21.
//
import Foundation
class SkillViewModel: ObservableObject {
init(_ rawSkill: Skill?) {
if (rawSkill != nil) {
self.rawSkill = rawSkill
_name = rawSkill!.name ?? ""
} else {
_name = ""
}
}
var rawSkill: Skill?
private var _name: String = ""
var name: String {
get {
return _name
}
set {
if (newValue != _name) {
_name = newValue
// Notify changed name
}
if (rawSkill != nil) {
rawSkill!.name = newValue
}
}
}
}

View File

@@ -49,8 +49,16 @@
<attribute name="wisdomSavingThrowAdvantage" attributeType="String" defaultValueString="none"/> <attribute name="wisdomSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
<attribute name="wisdomSavingThrowProficiency" attributeType="String" defaultValueString="none"/> <attribute name="wisdomSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
<attribute name="wisdomScore" attributeType="Integer 64" defaultValueString="10" usesScalarValueType="YES"/> <attribute name="wisdomScore" attributeType="Integer 64" defaultValueString="10" usesScalarValueType="YES"/>
<relationship name="skills" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Skill" inverseName="monster" inverseEntity="Skill"/>
</entity>
<entity name="Skill" representedClassName="Skill" syncable="YES" codeGenerationType="category">
<attribute name="abilityScoreName" attributeType="String" defaultValueString=""/>
<attribute name="name" attributeType="String" defaultValueString=""/>
<attribute name="proficiency" attributeType="String" defaultValueString=""/>
<relationship name="monster" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Monster" inverseName="skills" inverseEntity="Monster"/>
</entity> </entity>
<elements> <elements>
<element name="Monster" positionX="-63" positionY="-18" width="128" height="763"/> <element name="Monster" positionX="-63" positionY="-18" width="128" height="778"/>
<element name="Skill" positionX="-63" positionY="135" width="128" height="103"/>
</elements> </elements>
</model> </model>

View File

@@ -54,7 +54,8 @@ struct EditMonster: View {
@State private var monsterWisdomSavingThrowAdvantage: AdvantageType = .none @State private var monsterWisdomSavingThrowAdvantage: AdvantageType = .none
@State private var monsterCharismaSavingThrowProficiency: ProficiencyType = .none @State private var monsterCharismaSavingThrowProficiency: ProficiencyType = .none
@State private var monsterCharismaSavingThrowAdvantage: AdvantageType = .none @State private var monsterCharismaSavingThrowAdvantage: AdvantageType = .none
@State private var monsterSkills: [Skill] = []
var body: some View { var body: some View {
List { List {
@@ -258,6 +259,50 @@ struct EditMonster: View {
} }
} }
.textCase(nil) .textCase(nil)
Section(header: HStack {
Text("Skills")
Spacer()
Button(action: addSkill) {
Image(systemName:"plus")
}
}) {
VStack {
// ForEach((1...10).reversed(), id: \.self) {
// Text("\($0)")
// }
// List(monster.skillsArray) {_ in
// Text ("Name")
// }
ForEach(monsterSkills, id: \.self) { skill in
VStack {
Text("---")
Text(skill.wrappedName)
Text(skill.wrappedProficiency.displayName)
Text(skill.wrappedAbilityScore.displayName)
}
}
}
}
.textCase(nil)
// Section(header: HStack {
// Text("Skills")
// Spacer()
// Button(action: addSkill) {
// Image(systemName:"plus")
// }
// }) {
// VStack {
//// let skills2: [Skill] = monster.skills?.allObjects)
// ForEach(monster.allSkills)) { skill in
// Text("A SKill")
// }
// }
//// ForEach(arrayLiteral: Array(monster.skills)) { skill in
//// Text("A Skill")
//// }
// }
// .textCase(nil)
} }
.onAppear(perform: copyMonsterToLocal) .onAppear(perform: copyMonsterToLocal)
.toolbar(content: { .toolbar(content: {
@@ -273,6 +318,29 @@ struct EditMonster: View {
.navigationBarBackButtonHidden(true) .navigationBarBackButtonHidden(true)
} }
private func addSkill() {
print("Add Skill pressed")
let newSkill = Skill.init(context: viewContext)
newSkill.name = "Acrobatics"
newSkill.wrappedAbilityScore = .dexterity
newSkill.wrappedProficiency = .proficient
monster.addToSkills(newSkill);
// newSkill.monster = monster
// monster.addSkill(newSkill)
// (monster.skills as! NSMutableSet).add(newSkill)
// var s1: NSMutableSet = ["A", "S", "D", "F"]
// var s2: Set = ["A", "S", "D", "F"]
// s1.add
//
do {
try viewContext.save()
monsterSkills = monster.skillsArray
} catch {
print("error")
}
}
private func dismissView() { private func dismissView() {
self.presentationMode.wrappedValue.dismiss() self.presentationMode.wrappedValue.dismiss()
} }
@@ -376,6 +444,17 @@ struct EditMonster: View {
monster.wisdomSavingThrowAdvantageEnum = monsterWisdomSavingThrowAdvantage monster.wisdomSavingThrowAdvantageEnum = monsterWisdomSavingThrowAdvantage
monster.charismaSavingThrowProficiencyEnum = monsterCharismaSavingThrowProficiency monster.charismaSavingThrowProficiencyEnum = monsterCharismaSavingThrowProficiency
monster.charismaSavingThrowAdvantageEnum = monsterCharismaSavingThrowAdvantage monster.charismaSavingThrowAdvantageEnum = monsterCharismaSavingThrowAdvantage
monster.skills?.forEach { s in
let skill = s as! Skill
if (!monsterSkills.contains(skill)) {
monster.removeFromSkills(skill)
}
}
monster.skillsArray.forEach { skill in
if (!(monster.skills?.contains(skill) ?? false)) {
monster.addToSkills(skill)
}
}
} }
} }