Adds DTO classes to help load a monster file from https://tetra-cube.com/dnd/dnd-statblock.html

This commit is contained in:
2021-04-04 01:41:41 -07:00
parent cd2be8490f
commit c09c332758
7 changed files with 504 additions and 0 deletions

View File

@@ -23,6 +23,12 @@
E216B7BC260C691400FB205F /* EditChallengeRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7BB260C691400FB205F /* EditChallengeRating.swift */; };
E216B7C1260C6B6000FB205F /* MCChallengeRatingPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */; };
E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */; };
E219247B261989B400C84E12 /* MonsterDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247A261989B400C84E12 /* MonsterDTO.swift */; };
E2192480261989F700C84E12 /* SavingThrowDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219247F261989F700C84E12 /* SavingThrowDTO.swift */; };
E219248526198A1200C84E12 /* SkillDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219248426198A1200C84E12 /* SkillDTO.swift */; };
E219248A26198A5400C84E12 /* TraitDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219248926198A5400C84E12 /* TraitDTO.swift */; };
E219248F26198A6A00C84E12 /* DamageTypeDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219248E26198A6A00C84E12 /* DamageTypeDTO.swift */; };
E219249426198A8200C84E12 /* LanguageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = E219249326198A8200C84E12 /* LanguageDTO.swift */; };
E24ACE502607326E009BF703 /* EditBasicInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24ACE4F2607326E009BF703 /* EditBasicInfo.swift */; };
E24ACE562607EE94009BF703 /* EditArmor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24ACE552607EE94009BF703 /* EditArmor.swift */; };
E24ACE5B2607F0F2009BF703 /* EditSpeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24ACE5A2607F0F2009BF703 /* EditSpeed.swift */; };
@@ -96,6 +102,12 @@
E216B7BB260C691400FB205F /* EditChallengeRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditChallengeRating.swift; sourceTree = "<group>"; };
E216B7C0260C6B6000FB205F /* MCChallengeRatingPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCChallengeRatingPicker.swift; sourceTree = "<group>"; };
E2182E6225B22F8A00DFAEF8 /* Monster+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Monster+CoreDataClass.swift"; sourceTree = "<group>"; };
E219247A261989B400C84E12 /* MonsterDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterDTO.swift; sourceTree = "<group>"; };
E219247F261989F700C84E12 /* SavingThrowDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavingThrowDTO.swift; sourceTree = "<group>"; };
E219248426198A1200C84E12 /* SkillDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillDTO.swift; sourceTree = "<group>"; };
E219248926198A5400C84E12 /* TraitDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraitDTO.swift; sourceTree = "<group>"; };
E219248E26198A6A00C84E12 /* DamageTypeDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamageTypeDTO.swift; sourceTree = "<group>"; };
E219249326198A8200C84E12 /* LanguageDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageDTO.swift; sourceTree = "<group>"; };
E24ACE4F2607326E009BF703 /* EditBasicInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditBasicInfo.swift; sourceTree = "<group>"; };
E24ACE552607EE94009BF703 /* EditArmor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditArmor.swift; sourceTree = "<group>"; };
E24ACE5A2607F0F2009BF703 /* EditSpeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSpeed.swift; sourceTree = "<group>"; };
@@ -289,6 +301,12 @@
E20209F925D8E19100EFE733 /* SkillViewModel.swift */,
E2CB0DE0260887ED00142591 /* StringViewModel.swift */,
E20209E625D8DEB600EFE733 /* Enums */,
E219247A261989B400C84E12 /* MonsterDTO.swift */,
E219249326198A8200C84E12 /* LanguageDTO.swift */,
E219247F261989F700C84E12 /* SavingThrowDTO.swift */,
E219248426198A1200C84E12 /* SkillDTO.swift */,
E219248926198A5400C84E12 /* TraitDTO.swift */,
E219248E26198A6A00C84E12 /* DamageTypeDTO.swift */,
);
path = Models;
sourceTree = "<group>";
@@ -444,6 +462,7 @@
E216B799260C2DF200FB205F /* EditLanguages.swift in Sources */,
E2570FBB25B1AC520055B23B /* ContentView.swift in Sources */,
E24ACE502607326E009BF703 /* EditBasicInfo.swift in Sources */,
E219249426198A8200C84E12 /* LanguageDTO.swift in Sources */,
E254F90E260D19A0009295A5 /* EditTraits.swift in Sources */,
E2570FC525B1AC550055B23B /* MonsterCards.xcdatamodeld in Sources */,
E2182E6425B22F8A00DFAEF8 /* Monster+CoreDataClass.swift in Sources */,
@@ -451,8 +470,10 @@
E210B83A25B42D980083EAC5 /* MCProficiencyPicker.swift in Sources */,
E2570FF025B1ADC10055B23B /* Search.swift in Sources */,
E257100925B1B2480055B23B /* MonsterDetail.swift in Sources */,
E219248526198A1200C84E12 /* SkillDTO.swift in Sources */,
E2D473FD25B532C900CB36D7 /* Color+Hex.swift in Sources */,
E2B5285925B3028700AAA69E /* EditMonster.swift in Sources */,
E219247B261989B400C84E12 /* MonsterDTO.swift in Sources */,
E2CB0DD72608720000142591 /* StringHelper.swift in Sources */,
E2570FF525B1ADEB0055B23B /* Dashboard.swift in Sources */,
E2CB0DB826081A2F00142591 /* MCAbilityScorePicker.swift in Sources */,
@@ -469,6 +490,7 @@
E2CB0DCA26086E8300142591 /* ArmorType.swift in Sources */,
E24ACE562607EE94009BF703 /* EditArmor.swift in Sources */,
E2CB0DE1260887ED00142591 /* StringViewModel.swift in Sources */,
E219248F26198A6A00C84E12 /* DamageTypeDTO.swift in Sources */,
E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */,
E2CB0DC526086E5F00142591 /* SizeType.swift in Sources */,
E254F906260D0818009295A5 /* AbilityViewModel.swift in Sources */,
@@ -476,12 +498,14 @@
E24ACE5B2607F0F2009BF703 /* EditSpeed.swift in Sources */,
E2570FB925B1AC520055B23B /* MonsterCardsApp.swift in Sources */,
E254F913260D1F6D009295A5 /* EditTrait.swift in Sources */,
E2192480261989F700C84E12 /* SavingThrowDTO.swift in Sources */,
E216B7B7260C5A9800FB205F /* ChallengeRatingViewModel.swift in Sources */,
E20209D325D8DD9600EFE733 /* Skill+CoreDataClass.swift in Sources */,
E24ACE652607F55D009BF703 /* EditSavingThrows.swift in Sources */,
E2BD702C25B3A8D70058ED69 /* MCTextField.swift in Sources */,
E216B7BC260C691400FB205F /* EditChallengeRating.swift in Sources */,
E20209E825D8DEC100EFE733 /* AbilityScore.swift in Sources */,
E219248A26198A5400C84E12 /* TraitDTO.swift in Sources */,
E210B83F25B42DAB0083EAC5 /* MCAdvantagePicker.swift in Sources */,
E216B7C1260C6B6000FB205F /* MCChallengeRatingPicker.swift in Sources */,
E26CDA2B25CFB38E00E3F50D /* MCArmorTypePicker.swift in Sources */,

View File

@@ -0,0 +1,42 @@
//
// DamageTypeDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct DamageTypeDTO {
var name: String
var note: String
var type: String
}
private enum DamageTypeDTOCodingKeys: String, CodingKey {
case name = "name"
case note = "note"
case type = "type"
}
extension DamageTypeDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DamageTypeDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? ""
self.note = (try? container.decode(String.self, forKey: .note)) ?? ""
self.type = (try? container.decode(String.self, forKey: .type)) ?? ""
}
}
extension DamageTypeDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: DamageTypeDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.note, forKey: .note)
try container.encode(self.type, forKey: .type)
}
}

View File

@@ -0,0 +1,38 @@
//
// LanguageDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct LanguageDTO {
var name: String
var speaks: Bool
}
private enum LanguageDTOCodingKeys: String, CodingKey {
case name = "name"
case speaks = "speaks"
}
extension LanguageDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: LanguageDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? ""
self.speaks = (try? container.decode(Bool.self, forKey: .speaks)) ?? false
}
}
extension LanguageDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: LanguageDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.speaks, forKey: .speaks)
}
}

View File

@@ -0,0 +1,278 @@
//
// MonsterDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct MonsterDTO {
var name: String
var type: String
var alignment: String
var size: String
var hitDice: Int
var armorName: String
var otherArmorDesc: String
var shieldBonus: Int
var natArmorBonus: Int
var speed: Int
var burrowSpeed: Int
var climbSpeed: Int
var flySpeed: Int
var hover: Bool
var swimSpeed: Int
var speedDesc: String
var customSpeed: Bool
var strPoints: Int
var dexPoints: Int
var conPoints: Int
var intPoints: Int
var wisPoints: Int
var chaPoints: Int
var cr: String
var customCr: String
var customProf: Int
var hpText: String
var sthrows: [SavingThrowDTO]
var skills: [SkillDTO]
var actions: [TraitDTO]
var legendaryDescription: String
var legendaries: [TraitDTO]
var reactions: [TraitDTO]// TODO: verify this
var abilities: [TraitDTO]
var damageTypes: [DamageTypeDTO]
var conditions: [DamageTypeDTO] // TODO: figure this out
var languages: [LanguageDTO]
var telepathy: Int
var understandsBut: String
var blindsight: Int
var blind: Bool
var darkvision: Int
var tremorsense: Int
var truesight: Int
var tag: String
var customHP: Bool
var isLegendary: Bool
var isLair: Bool
var lairDescription: String
var lairDescriptionEnd: String
var isRegional: Bool
var regionalDescription: String
var regionalDescriptionEnd: String
// var properties: [???] // TODO: figure this out
var lairs: [TraitDTO]
var regionals: [TraitDTO]
var specialDamage: [DamageTypeDTO]
var shortName: String
var doubleColumns: Bool
var separationPoint: Int
var damage: [DamageTypeDTO] // TODO: figure this out
}
enum MonsterDTOCodingKeys: String, CodingKey {
case name = "name"
case type = "type"
case alignment = "alignment"
case size = "size"
case hitDice = "hitDice"
case armorName = "armorName"
case otherArmorDesc = "otherArmorDesc"
case shieldBonus = "shieldBonus"
case natArmorBonus = "natArmorBonus"
case speed = "speed"
case burrowSpeed = "burrowSpeed"
case climbSpeed = "climbSpeed"
case flySpeed = "flySpeed"
case hover = "hover"
case swimSpeed = "swimSpeed"
case speedDesc = "speedDesc"
case customSpeed = "customSpeed"
case strPoints = "strPoints"
case dexPoints = "dexPoints"
case conPoints = "conPoints"
case intPoints = "intPoints"
case wisPoints = "wisPoints"
case chaPoints = "chaPoints"
case cr = "cr"
case customCr = "customCr"
case customProf = "customProf"
case hpText = "hpText"
case sthrows = "sthrows"
case skills = "skills"
case actions = "actions"
case legendaryDescription = "legendaryDescription"
case legendaries = "legendaries"
case reactions = "reactions"
case abilities = "abilities"
case damageTypes = "damageTypes"
case conditions = "conditions"
case languages = "languages"
case telepathy = "telepathy"
case understandsBut = "understandsBut"
case blindsight = "blindsight"
case blind = "blind"
case darkvision = "darkvision"
case tremorsense = "tremorsense"
case truesight = "truesight"
case tag = "tag"
case customHP = "customHP"
case isLegendary = "isLegendary"
case isLair = "isLair"
case lairDescription = "lairDescription"
case lairDescriptionEnd = "lairDescriptionEnd"
case isRegional = "isRegional"
case regionalDescription = "regionalDescription"
case regionalDescriptionEnd = "regionalDescriptionEnd"
case properties = "properties"
case lairs = "lairs"
case regionals = "regionals"
case specialDamage = "specialDamage"
case shortName = "shortName"
case doubleColumns = "doubleColumns"
case separationPoint = "separationPoint"
case damage = "damage"
}
extension MonsterDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: MonsterDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? "Imported Monster"
self.type = (try? container.decode(String.self, forKey: .type)) ?? ""
self.alignment = (try? container.decode(String.self, forKey: .alignment)) ?? ""
self.size = (try? container.decode(String.self, forKey: .size)) ?? ""
self.hitDice = (try? container.decode(Int.self, forKey: .hitDice)) ?? 0
self.armorName = (try? container.decode(String.self, forKey: .armorName)) ?? ""
self.otherArmorDesc = (try? container.decode(String.self, forKey: .otherArmorDesc)) ?? ""
self.shieldBonus = (try? container.decode(Int.self, forKey: .shieldBonus)) ?? 0
self.natArmorBonus = (try? container.decode(Int.self, forKey: .natArmorBonus)) ?? 0
self.speed = (try? container.decode(Int.self, forKey: .speed)) ?? 0
self.burrowSpeed = (try? container.decode(Int.self, forKey: .burrowSpeed)) ?? 0
self.climbSpeed = (try? container.decode(Int.self, forKey: .climbSpeed)) ?? 0
self.flySpeed = (try? container.decode(Int.self, forKey: .flySpeed)) ?? 0
self.hover = (try? container.decode(Bool.self, forKey: .hover)) ?? false
self.swimSpeed = (try? container.decode(Int.self, forKey: .swimSpeed)) ?? 0
self.speedDesc = (try? container.decode(String.self, forKey: .speedDesc)) ?? ""
self.customSpeed = (try? container.decode(Bool.self, forKey: .customSpeed)) ?? false
self.strPoints = (try? container.decode(Int.self, forKey: .strPoints)) ?? 0
self.dexPoints = (try? container.decode(Int.self, forKey: .dexPoints)) ?? 0
self.conPoints = (try? container.decode(Int.self, forKey: .conPoints)) ?? 0
self.intPoints = (try? container.decode(Int.self, forKey: .intPoints)) ?? 0
self.wisPoints = (try? container.decode(Int.self, forKey: .wisPoints)) ?? 0
self.chaPoints = (try? container.decode(Int.self, forKey: .chaPoints)) ?? 0
self.cr = (try? container.decode(String.self, forKey: .cr)) ?? ""
self.customCr = (try? container.decode(String.self, forKey: .customCr)) ?? ""
self.customProf = (try? container.decode(Int.self, forKey: .customProf)) ?? 0
self.hpText = (try? container.decode(String.self, forKey: .hpText)) ?? ""
self.legendaryDescription = (try? container.decode(String.self, forKey: .legendaryDescription)) ?? ""
self.understandsBut = (try? container.decode(String.self, forKey: .understandsBut)) ?? ""
self.tag = (try? container.decode(String.self, forKey: .tag)) ?? ""
self.lairDescription = (try? container.decode(String.self, forKey: .lairDescription)) ?? ""
self.lairDescriptionEnd = (try? container.decode(String.self, forKey: .lairDescriptionEnd)) ?? ""
self.regionalDescription = (try? container.decode(String.self, forKey: .regionalDescription)) ?? ""
self.regionalDescriptionEnd = (try? container.decode(String.self, forKey: .regionalDescriptionEnd)) ?? ""
self.shortName = (try? container.decode(String.self, forKey: .shortName)) ?? ""
self.telepathy = (try? container.decode(Int.self, forKey: .telepathy)) ?? 0
self.blindsight = (try? container.decode(Int.self, forKey: .blindsight)) ?? 0
self.darkvision = (try? container.decode(Int.self, forKey: .darkvision)) ?? 0
self.tremorsense = (try? container.decode(Int.self, forKey: .tremorsense)) ?? 0
self.truesight = (try? container.decode(Int.self, forKey: .truesight)) ?? 0
self.separationPoint = (try? container.decode(Int.self, forKey: .separationPoint)) ?? 0
self.blind = (try? container.decode(Bool.self, forKey: .blind)) ?? false
self.customHP = (try? container.decode(Bool.self, forKey: .customHP)) ?? false
self.isLegendary = (try? container.decode(Bool.self, forKey: .isLegendary)) ?? false
self.isLair = (try? container.decode(Bool.self, forKey: .isLair)) ?? false
self.isRegional = (try? container.decode(Bool.self, forKey: .isRegional)) ?? false
self.doubleColumns = (try? container.decode(Bool.self, forKey: .doubleColumns)) ?? false
// properties is always an empty array
// self.properties = (try? container.decode([String].self, forKey: .properties)) ?? []
self.lairs = (try? container.decode([TraitDTO].self, forKey: .lairs)) ?? []
self.regionals = (try? container.decode([TraitDTO].self, forKey: .regionals)) ?? []
self.specialDamage = (try? container.decode([DamageTypeDTO].self, forKey: .specialDamage)) ?? []
self.damage = (try? container.decode([DamageTypeDTO].self, forKey: .damage)) ?? []
self.conditions = (try? container.decode([DamageTypeDTO].self, forKey: .conditions)) ?? []
self.sthrows = (try? container.decode([SavingThrowDTO].self, forKey: .sthrows)) ?? []
self.skills = (try? container.decode([SkillDTO].self, forKey: .skills)) ?? []
self.actions = (try? container.decode([TraitDTO].self, forKey: .actions)) ?? []
self.legendaries = (try? container.decode([TraitDTO].self, forKey: .legendaries)) ?? []
self.reactions = (try? container.decode([TraitDTO].self, forKey: .reactions)) ?? []
self.abilities = (try? container.decode([TraitDTO].self, forKey: .abilities)) ?? []
self.damageTypes = (try? container.decode([DamageTypeDTO].self, forKey: .damageTypes)) ?? []
self.languages = (try? container.decode([LanguageDTO].self, forKey: .languages)) ?? []
}
}
extension MonsterDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: MonsterDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.type, forKey: .type)
try container.encode(self.alignment, forKey: .alignment)
try container.encode(self.size, forKey: .size)
try container.encode(self.hitDice, forKey: .hitDice)
try container.encode(self.armorName, forKey: .armorName)
try container.encode(self.otherArmorDesc, forKey: .otherArmorDesc)
try container.encode(self.shieldBonus, forKey: .shieldBonus)
try container.encode(self.natArmorBonus, forKey: .natArmorBonus)
try container.encode(self.speed, forKey: .speed)
try container.encode(self.burrowSpeed, forKey: .burrowSpeed)
try container.encode(self.climbSpeed, forKey: .climbSpeed)
try container.encode(self.flySpeed, forKey: .flySpeed)
try container.encode(self.hover, forKey: .hover)
try container.encode(self.swimSpeed, forKey: .swimSpeed)
try container.encode(self.speedDesc, forKey: .speedDesc)
try container.encode(self.customSpeed, forKey: .customSpeed)
try container.encode(self.strPoints, forKey: .strPoints)
try container.encode(self.dexPoints, forKey: .dexPoints)
try container.encode(self.conPoints, forKey: .conPoints)
try container.encode(self.intPoints, forKey: .intPoints)
try container.encode(self.wisPoints, forKey: .wisPoints)
try container.encode(self.chaPoints, forKey: .chaPoints)
try container.encode(self.cr, forKey: .cr)
try container.encode(self.customCr, forKey: .customCr)
try container.encode(self.customProf, forKey: .customProf)
try container.encode(self.hpText, forKey: .hpText)
try container.encode(self.sthrows, forKey: .sthrows)
try container.encode(self.skills, forKey: .skills)
try container.encode(self.actions, forKey: .actions)
try container.encode(self.legendaryDescription, forKey: .legendaryDescription)
try container.encode(self.legendaries, forKey: .legendaries)
try container.encode(self.reactions, forKey: .reactions)
try container.encode(self.abilities, forKey: .abilities)
try container.encode(self.damageTypes, forKey: .damageTypes)
try container.encode(self.conditions, forKey: .conditions)
try container.encode(self.languages, forKey: .languages)
try container.encode(self.telepathy, forKey: .telepathy)
try container.encode(self.understandsBut, forKey: .understandsBut)
try container.encode(self.blindsight, forKey: .blindsight)
try container.encode(self.blind, forKey: .blind)
try container.encode(self.darkvision, forKey: .darkvision)
try container.encode(self.tremorsense, forKey: .tremorsense)
try container.encode(self.truesight, forKey: .truesight)
try container.encode(self.tag, forKey: .tag)
try container.encode(self.customHP, forKey: .customHP)
try container.encode(self.isLegendary, forKey: .isLegendary)
try container.encode(self.isLair, forKey: .isLair)
try container.encode(self.lairDescription, forKey: .lairDescription)
try container.encode(self.lairDescriptionEnd, forKey: .lairDescriptionEnd)
try container.encode(self.isRegional, forKey: .isRegional)
try container.encode(self.regionalDescription, forKey: .regionalDescription)
try container.encode(self.regionalDescriptionEnd, forKey: .regionalDescriptionEnd)
// try container.encode(self.properties, forKey: .properties)
try container.encode(self.lairs, forKey: .lairs)
try container.encode(self.regionals, forKey: .regionals)
try container.encode(self.specialDamage, forKey: .specialDamage)
try container.encode(self.shortName, forKey: .shortName)
try container.encode(self.doubleColumns, forKey: .doubleColumns)
try container.encode(self.separationPoint, forKey: .separationPoint)
try container.encode(self.damage, forKey: .damage)
}
}

View File

@@ -0,0 +1,38 @@
//
// SavingThrowDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct SavingThrowDTO {
var name: String
var order: Int
}
private enum SavingThrowDTOCodingKeys: String, CodingKey {
case name = "name"
case order = "order"
}
extension SavingThrowDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: SavingThrowDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? ""
self.order = (try? container.decode(Int.self, forKey: .order)) ?? 0
}
}
extension SavingThrowDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: SavingThrowDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.order, forKey: .order)
}
}

View File

@@ -0,0 +1,42 @@
//
// SkillDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct SkillDTO {
var name: String
var stat: String
var note: String
}
private enum SkillDTOCodingKeys: String, CodingKey {
case name = "name"
case stat = "stat"
case note = "note"
}
extension SkillDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: SkillDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? ""
self.note = (try? container.decode(String.self, forKey: .note)) ?? ""
self.stat = (try? container.decode(String.self, forKey: .stat)) ?? ""
}
}
extension SkillDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: SkillDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.note, forKey: .note)
try container.encode(self.stat, forKey: .stat)
}
}

View File

@@ -0,0 +1,42 @@
//
// TraitDTO.swift
// MonsterCards
//
// Created by Tom Hicks on 3/28/21.
//
import Foundation
struct TraitDTO {
var name: String
var note: String
var desc: String
}
private enum TraitDTOCodingKeys: String, CodingKey {
case name = "name"
case note = "note"
case desc = "desc"
}
extension TraitDTO: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: TraitDTOCodingKeys.self)
self.name = (try? container.decode(String.self, forKey: .name)) ?? ""
self.note = (try? container.decode(String.self, forKey: .note)) ?? ""
self.desc = (try? container.decode(String.self, forKey: .desc)) ?? ""
}
}
extension TraitDTO: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: TraitDTOCodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encode(self.note, forKey: .note)
try container.encode(self.desc, forKey: .desc)
}
}