@@ -46,6 +46,12 @@ public struct Creature: Equatable, Sendable {
4646 public var xpLair : Int ? = nil
4747 }
4848
49+ public enum ConditionImmunity : Equatable , Hashable , Sendable {
50+ case condition( Condition )
51+ case conditional( Set < ConditionImmunity > , preNote: String ? = nil , note: String ? = nil , conditional: Bool ? = nil )
52+ case special( String )
53+ }
54+
4955 @MemberwiseInit ( . public)
5056 public struct CreatureType : Equatable , Sendable {
5157 public enum Choice : Equatable , Sendable {
@@ -70,6 +76,24 @@ public struct Creature: Equatable, Sendable {
7076 public var note : String ? = nil
7177 }
7278
79+ public enum DamageImmunity : Equatable , Hashable , Sendable {
80+ case damage( DamageType )
81+ case conditional( Set < DamageImmunity > , preNote: String ? = nil , note: String ? = nil , conditional: Bool ? = nil )
82+ case special( String )
83+ }
84+
85+ public enum DamageResistance : Equatable , Hashable , Sendable {
86+ case damage( DamageType )
87+ case conditional( Set < DamageResistance > , preNote: String ? = nil , note: String ? = nil , conditional: Bool ? = nil )
88+ case special( String )
89+ }
90+
91+ public enum DamageVulnerability : Equatable , Hashable , Sendable {
92+ case damage( DamageType )
93+ case conditional( Set < DamageVulnerability > , preNote: String ? = nil , note: String ? = nil , conditional: Bool ? = nil )
94+ case special( String )
95+ }
96+
7397 @MemberwiseInit ( . public)
7498 public struct Gear : Equatable , Sendable {
7599 @Init ( label: " _ " )
@@ -185,6 +209,11 @@ public struct Creature: Equatable, Sendable {
185209 public var languages : Set < String > ? = nil
186210 public var proficiencyBonus : String ? = nil
187211 public var challengeRating : ChallengeRating ? = nil
212+
213+ public var damageVulnerability : Set < DamageVulnerability > ? = nil
214+ public var damageResistance : Set < DamageResistance > ? = nil
215+ public var damageImmunity : Set < DamageImmunity > ? = nil
216+ public var conditionImmunity : Set < ConditionImmunity > ? = nil
188217}
189218
190219// MARK: - Codable
@@ -227,6 +256,10 @@ extension Creature: Codable {
227256 case languages
228257 case proficiencyBonus = " pbNote "
229258 case challengeRating = " cr "
259+ case damageVulnerability = " vulnerable "
260+ case damageResistance = " resist "
261+ case damageImmunity = " immune "
262+ case conditionImmunity = " conditionImmune "
230263 }
231264}
232265
@@ -377,6 +410,57 @@ extension Creature.ChallengeRating: Codable {
377410
378411}
379412
413+ extension Creature . ConditionImmunity : Codable {
414+ enum CodingKeys : String , CodingKey {
415+ case conditions = " conditionImmune "
416+ case preNote
417+ case note
418+ case conditional = " cond "
419+ }
420+
421+ enum SpecialCodingKeys : String , CodingKey {
422+ case special
423+ }
424+
425+ public init ( from decoder: any Decoder ) throws {
426+ if let container = try ? decoder. singleValueContainer ( ) ,
427+ let value = try ? container. decode ( Condition . self)
428+ {
429+ self = . condition( value)
430+ } else if let container = try ? decoder. container ( keyedBy: SpecialCodingKeys . self) ,
431+ let value = try ? container. decode ( String . self, forKey: . special)
432+ {
433+ self = . special( value)
434+ } else {
435+ let container = try decoder. container ( keyedBy: CodingKeys . self)
436+ self = . conditional(
437+ try container. decode ( Set< Creature . ConditionImmunity> . self , forKey: . conditions) ,
438+ preNote: try container. decodeIfPresent ( String . self, forKey: . preNote) ,
439+ note: try container. decodeIfPresent ( String . self, forKey: . note) ,
440+ conditional: try container. decodeIfPresent ( Bool . self, forKey: . conditional)
441+ )
442+ }
443+ }
444+
445+ public func encode( to encoder: any Encoder ) throws {
446+ switch self {
447+ case . condition( let value) :
448+ var container = encoder. singleValueContainer ( )
449+ try container. encode ( value)
450+ case . special( let value) :
451+ var container = encoder. container ( keyedBy: SpecialCodingKeys . self)
452+ try container. encode ( value, forKey: . special)
453+ case . conditional( let conditions, let preNote, let note, let cond) :
454+ var container = encoder. container ( keyedBy: CodingKeys . self)
455+ try container. encode ( conditions, forKey: . conditions)
456+ try container. encodeIfPresent ( preNote, forKey: . preNote)
457+ try container. encodeIfPresent ( note, forKey: . note)
458+ try container. encodeIfPresent ( cond, forKey: . conditional)
459+ }
460+ }
461+
462+ }
463+
380464extension Creature . CreatureType . Choice : Codable {
381465 enum ChoiceCodingKeys : String , CodingKey {
382466 case choose
@@ -448,6 +532,159 @@ extension Creature.CreatureType: Codable {
448532 }
449533}
450534
535+ extension Creature . DamageImmunity : Codable {
536+ enum CodingKeys : String , CodingKey {
537+ case damageTypes = " immune "
538+ case preNote
539+ case note
540+ case conditional = " cond "
541+ }
542+
543+ enum SpecialCodingKeys : String , CodingKey {
544+ case special
545+ }
546+
547+ public init ( from decoder: any Decoder ) throws {
548+ if let container = try ? decoder. singleValueContainer ( ) ,
549+ let value = try ? container. decode ( DamageType . self)
550+ {
551+ self = . damage( value)
552+ } else if let container = try ? decoder. container ( keyedBy: SpecialCodingKeys . self) ,
553+ let value = try ? container. decode ( String . self, forKey: . special)
554+ {
555+ self = . special( value)
556+ } else {
557+ let container = try decoder. container ( keyedBy: CodingKeys . self)
558+ self = . conditional(
559+ try container. decode ( Set< Creature . DamageImmunity> . self , forKey: . damageTypes) ,
560+ preNote: try container. decodeIfPresent ( String . self, forKey: . preNote) ,
561+ note: try container. decodeIfPresent ( String . self, forKey: . note) ,
562+ conditional: try container. decodeIfPresent ( Bool . self, forKey: . conditional)
563+ )
564+ }
565+ }
566+
567+ public func encode( to encoder: any Encoder ) throws {
568+ switch self {
569+ case . damage( let value) :
570+ var container = encoder. singleValueContainer ( )
571+ try container. encode ( value)
572+ case . special( let value) :
573+ var container = encoder. container ( keyedBy: SpecialCodingKeys . self)
574+ try container. encode ( value, forKey: . special)
575+ case . conditional( let damageTypes, let preNote, let note, let cond) :
576+ var container = encoder. container ( keyedBy: CodingKeys . self)
577+ try container. encode ( damageTypes, forKey: . damageTypes)
578+ try container. encodeIfPresent ( preNote, forKey: . preNote)
579+ try container. encodeIfPresent ( note, forKey: . note)
580+ try container. encodeIfPresent ( cond, forKey: . conditional)
581+ }
582+ }
583+
584+ }
585+
586+ extension Creature . DamageResistance : Codable {
587+ enum CodingKeys : String , CodingKey {
588+ case damageTypes = " resist "
589+ case preNote
590+ case note
591+ case conditional = " cond "
592+ }
593+
594+ enum SpecialCodingKeys : String , CodingKey {
595+ case special
596+ }
597+
598+ public init ( from decoder: any Decoder ) throws {
599+ if let container = try ? decoder. singleValueContainer ( ) ,
600+ let value = try ? container. decode ( DamageType . self)
601+ {
602+ self = . damage( value)
603+ } else if let container = try ? decoder. container ( keyedBy: SpecialCodingKeys . self) ,
604+ let value = try ? container. decode ( String . self, forKey: . special)
605+ {
606+ self = . special( value)
607+ } else {
608+ let container = try decoder. container ( keyedBy: CodingKeys . self)
609+ self = . conditional(
610+ try container. decode ( Set< Creature . DamageResistance> . self , forKey: . damageTypes) ,
611+ preNote: try container. decodeIfPresent ( String . self, forKey: . preNote) ,
612+ note: try container. decodeIfPresent ( String . self, forKey: . note) ,
613+ conditional: try container. decodeIfPresent ( Bool . self, forKey: . conditional)
614+ )
615+ }
616+ }
617+
618+ public func encode( to encoder: any Encoder ) throws {
619+ switch self {
620+ case . damage( let value) :
621+ var container = encoder. singleValueContainer ( )
622+ try container. encode ( value)
623+ case . special( let value) :
624+ var container = encoder. container ( keyedBy: SpecialCodingKeys . self)
625+ try container. encode ( value, forKey: . special)
626+ case . conditional( let damageTypes, let preNote, let note, let cond) :
627+ var container = encoder. container ( keyedBy: CodingKeys . self)
628+ try container. encode ( damageTypes, forKey: . damageTypes)
629+ try container. encodeIfPresent ( preNote, forKey: . preNote)
630+ try container. encodeIfPresent ( note, forKey: . note)
631+ try container. encodeIfPresent ( cond, forKey: . conditional)
632+ }
633+ }
634+
635+ }
636+
637+ extension Creature . DamageVulnerability : Codable {
638+ enum CodingKeys : String , CodingKey {
639+ case damageTypes = " vulnerable "
640+ case preNote
641+ case note
642+ case conditional = " cond "
643+ }
644+
645+ enum SpecialCodingKeys : String , CodingKey {
646+ case special
647+ }
648+
649+ public init ( from decoder: any Decoder ) throws {
650+ if let container = try ? decoder. singleValueContainer ( ) ,
651+ let value = try ? container. decode ( DamageType . self)
652+ {
653+ self = . damage( value)
654+ } else if let container = try ? decoder. container ( keyedBy: SpecialCodingKeys . self) ,
655+ let value = try ? container. decode ( String . self, forKey: . special)
656+ {
657+ self = . special( value)
658+ } else {
659+ let container = try decoder. container ( keyedBy: CodingKeys . self)
660+ self = . conditional(
661+ try container. decode ( Set< Creature . DamageVulnerability> . self , forKey: . damageTypes) ,
662+ preNote: try container. decodeIfPresent ( String . self, forKey: . preNote) ,
663+ note: try container. decodeIfPresent ( String . self, forKey: . note) ,
664+ conditional: try container. decodeIfPresent ( Bool . self, forKey: . conditional)
665+ )
666+ }
667+ }
668+
669+ public func encode( to encoder: any Encoder ) throws {
670+ switch self {
671+ case . damage( let value) :
672+ var container = encoder. singleValueContainer ( )
673+ try container. encode ( value)
674+ case . special( let value) :
675+ var container = encoder. container ( keyedBy: SpecialCodingKeys . self)
676+ try container. encode ( value, forKey: . special)
677+ case . conditional( let damageTypes, let preNote, let note, let cond) :
678+ var container = encoder. container ( keyedBy: CodingKeys . self)
679+ try container. encode ( damageTypes, forKey: . damageTypes)
680+ try container. encodeIfPresent ( preNote, forKey: . preNote)
681+ try container. encodeIfPresent ( note, forKey: . note)
682+ try container. encodeIfPresent ( cond, forKey: . conditional)
683+ }
684+ }
685+
686+ }
687+
451688extension Creature . Gear : Codable {
452689 enum CodingKeys : String , CodingKey {
453690 case item
0 commit comments