12
12
#include " cached_options.h"
13
13
#include " calendar.h"
14
14
#include " cata_utility.h"
15
- #include " catacharset .h"
15
+ #include " color .h"
16
16
#include " condition.h"
17
17
#include " creature.h"
18
18
#include " damage.h"
@@ -743,79 +743,87 @@ void mon_effect_data::load( const JsonObject &jo )
743
743
}
744
744
}
745
745
746
- void mtype::load ( const JsonObject &jo, const std::string &src )
746
+ void mount_item_data::deserialize ( const JsonObject &jo )
747
747
{
748
- bool strict = src == " dda" ;
748
+ optional ( jo, false , " tied" , tied, itype_id () );
749
+ optional ( jo, false , " tack" , tack, itype_id () );
750
+ optional ( jo, false , " armor" , armor, itype_id () );
751
+ optional ( jo, false , " storage" , storage, itype_id () );
752
+ }
749
753
754
+ void revive_type::deserialize ( const JsonObject &jo )
755
+ {
756
+ // FIXME: reader for read_condition
757
+ read_condition ( jo, " condition" , condition, true );
758
+ if ( jo.has_string ( " monster" ) ) {
759
+ mandatory ( jo, false , " monster" , revive_mon );
760
+ } else {
761
+ mandatory ( jo, false , " monster_group" , revive_monster_group );
762
+ }
763
+ }
764
+
765
+ void mtype::load ( const JsonObject &jo, const std::string &src )
766
+ {
750
767
MonsterGenerator &gen = MonsterGenerator::generator ();
751
768
752
769
name.make_plural ();
753
770
mandatory ( jo, was_loaded, " name" , name );
754
771
755
772
optional ( jo, was_loaded, " description" , description );
756
773
757
- assign ( jo, " ascii_picture" , picture_id );
774
+ optional ( jo, was_loaded , " ascii_picture" , picture_id );
758
775
759
- if ( jo.has_member ( " material" ) ) {
760
- mat.clear ();
761
- for ( const std::string &m : jo.get_tags ( " material" ) ) {
762
- mat.emplace ( m, 1 );
763
- mat_portion_total += 1 ;
764
- }
765
- }
766
- if ( mat.empty () ) { // Assign a default "flesh" material to prevent crash (#48988)
767
- mat.emplace ( material_flesh, 1 );
768
- mat_portion_total += 1 ;
776
+ // Assign a default "flesh" material to prevent crash (#48988)
777
+ optional ( jo, was_loaded, " material" , mat, weighted_string_id_reader<material_id, int > {1 }, {{{material_flesh, 1 }}} );
778
+ mat_portion_total = 0 ;
779
+ for ( const std::pair<const material_id, int > &pr : mat ) {
780
+ mat_portion_total += pr.second ;
769
781
}
782
+
770
783
optional ( jo, was_loaded, " species" , species, string_id_reader<::species_type> {} );
771
784
optional ( jo, was_loaded, " categories" , categories, auto_flags_reader<> {} );
772
785
773
786
// See monfaction.cpp
774
- if ( !was_loaded || jo. has_member ( " default_faction" ) ) {
775
- default_faction = mfaction_str_id ( jo. get_string ( " default_faction " ) );
776
- }
787
+ mandatory ( jo, was_loaded, " default_faction" , default_faction );
788
+
789
+ mandatory ( jo, was_loaded, " symbol " , sym, unicode_symbol_reader );
777
790
778
- if ( !was_loaded || jo.has_member ( " symbol" ) ) {
779
- sym = jo.get_string ( " symbol" );
780
- if ( utf8_width ( sym ) != 1 ) {
781
- jo.throw_error_at ( " symbol" , " monster symbol should be exactly one console cell width" );
782
- }
783
- }
784
791
if ( was_loaded && jo.has_member ( " copy-from" ) && looks_like.empty () ) {
785
792
looks_like = jo.get_string ( " copy-from" );
786
793
}
787
- jo. read ( " looks_like" , looks_like );
794
+ optional ( jo, was_loaded, " looks_like" , looks_like , looks_like );
788
795
789
- assign ( jo, " bodytype" , bodytype );
790
- assign ( jo, " color" , color );
791
- assign ( jo, " volume" , volume, strict, 0_ml );
792
- assign ( jo, " weight" , weight, strict, 0_gram );
796
+ optional ( jo, was_loaded , " bodytype" , bodytype );
797
+ optional ( jo, was_loaded, " color" , color, nc_color_reader{}, c_white );
798
+ optional ( jo, was_loaded, " volume" , volume, units_bound_reader<units::volume> { 0_ml } );
799
+ optional ( jo, was_loaded, " weight" , weight, units_bound_reader<units::mass> { 0_gram } );
793
800
794
801
optional ( jo, was_loaded, " phase" , phase, make_flag_reader ( gen.phase_map , " phase id" ),
795
802
phase_id::SOLID );
796
803
797
- assign ( jo, " diff" , difficulty_base, strict, 0 );
798
- assign ( jo, " hp" , hp, strict, 1 );
799
- assign ( jo, " speed" , speed, strict, 0 );
800
- assign ( jo, " aggression" , agro, strict, -100 , 100 );
801
- assign ( jo, " morale" , morale, strict );
802
- assign ( jo, " stomach_size" , stomach_size, strict );
803
- assign ( jo, " amount_eaten" , amount_eaten, strict );
804
+ optional ( jo, was_loaded, " diff" , difficulty_base, numeric_bound_reader<int > {0 }, 0 );
805
+ optional ( jo, was_loaded, " hp" , hp, numeric_bound_reader<int > {1 } );
806
+ optional ( jo, was_loaded, " speed" , speed, numeric_bound_reader<int > {0 }, 0 );
807
+ optional ( jo, was_loaded, " aggression" , agro, numeric_bound_reader<int > {-100 , 100 }, 0 );
808
+ optional ( jo, was_loaded, " morale" , morale, 0 );
809
+ optional ( jo, was_loaded, " stomach_size" , stomach_size, 0 );
804
810
805
- assign ( jo, " tracking_distance" , tracking_distance, strict, 3 );
811
+ optional ( jo, was_loaded, " tracking_distance" , tracking_distance, numeric_bound_reader<int > {3 },
812
+ 8 );
806
813
807
- assign ( jo, " mountable_weight_ratio" , mountable_weight_ratio, strict );
814
+ optional ( jo, was_loaded, " mountable_weight_ratio" , mountable_weight_ratio, 0 . 2f );
808
815
809
- assign ( jo, " attack_cost" , attack_cost, strict, 0 );
810
- assign ( jo, " melee_skill" , melee_skill, strict , 0 );
811
- assign ( jo, " melee_dice" , melee_dice, strict , 0 );
812
- assign ( jo, " melee_dice_sides" , melee_sides, strict , 0 );
816
+ optional ( jo, was_loaded, " attack_cost" , attack_cost, numeric_bound_reader< int > { 0 }, 100 );
817
+ optional ( jo, was_loaded, " melee_skill" , melee_skill, numeric_bound_reader< int > { 0 } , 0 );
818
+ optional ( jo, was_loaded, " melee_dice" , melee_dice, numeric_bound_reader< int > { 0 } , 0 );
819
+ optional ( jo, was_loaded, " melee_dice_sides" , melee_sides, numeric_bound_reader< int > { 0 } , 0 );
813
820
optional ( jo, was_loaded, " melee_dice_ap" , melee_dice_ap, 0 );
814
821
815
- assign ( jo, " grab_strength" , grab_strength, strict, 0 );
822
+ optional ( jo, was_loaded, " grab_strength" , grab_strength, numeric_bound_reader< int > { 0 }, 1 );
816
823
817
- assign ( jo, " dodge" , sk_dodge, strict, 0 );
824
+ optional ( jo, was_loaded, " dodge" , sk_dodge, numeric_bound_reader< int > { 0 } );
818
825
826
+ // FIXME: load resistances by reader class
819
827
if ( jo.has_object ( " armor" ) ) {
820
828
armor = load_resistances_instance ( jo.get_object ( " armor" ) );
821
829
}
@@ -907,7 +915,8 @@ void mtype::load( const JsonObject &jo, const std::string &src )
907
915
}
908
916
}
909
917
910
- assign ( jo, " status_chance_multiplier" , status_chance_multiplier, strict, 0 .0f , 5 .0f );
918
+ optional ( jo, was_loaded, " status_chance_multiplier" , status_chance_multiplier, numeric_bound_reader{0 .0f , 5 .0f },
919
+ 1 .f );
911
920
912
921
if ( !was_loaded || jo.has_array ( " families" ) ) {
913
922
families.clear ();
@@ -935,27 +944,8 @@ void mtype::load( const JsonObject &jo, const std::string &src )
935
944
optional ( jo, was_loaded, " absorb_move_cost_min" , absorb_move_cost_min, 1 );
936
945
optional ( jo, was_loaded, " absorb_move_cost_max" , absorb_move_cost_max, -1 );
937
946
938
- if ( jo.has_member ( " absorb_material" ) ) {
939
- absorb_material.clear ();
940
- if ( jo.has_array ( " absorb_material" ) ) {
941
- for ( std::string mat : jo.get_string_array ( " absorb_material" ) ) {
942
- absorb_material.emplace_back ( mat );
943
- }
944
- } else {
945
- absorb_material.emplace_back ( jo.get_string ( " absorb_material" ) );
946
- }
947
- }
948
-
949
- if ( jo.has_member ( " no_absorb_material" ) ) {
950
- no_absorb_material.clear ();
951
- if ( jo.has_array ( " no_absorb_material" ) ) {
952
- for ( std::string mat : jo.get_string_array ( " no_absorb_material" ) ) {
953
- no_absorb_material.emplace_back ( mat );
954
- }
955
- } else {
956
- no_absorb_material.emplace_back ( jo.get_string ( " no_absorb_material" ) );
957
- }
958
- }
947
+ optional ( jo, was_loaded, " absorb_material" , absorb_material );
948
+ optional ( jo, was_loaded, " no_absorb_material" , no_absorb_material );
959
949
960
950
optional ( jo, was_loaded, " bleed_rate" , bleed_rate, 100 );
961
951
@@ -999,8 +989,8 @@ void mtype::load( const JsonObject &jo, const std::string &src )
999
989
}
1000
990
1001
991
1002
- assign ( jo, " vision_day" , vision_day, strict, 0 );
1003
- assign ( jo, " vision_night" , vision_night, strict, 0 );
992
+ optional ( jo, was_loaded, " vision_day" , vision_day, numeric_bound_reader{ 0 }, 40 );
993
+ optional ( jo, was_loaded, " vision_night" , vision_night, numeric_bound_reader{ 0 }, 1 );
1004
994
1005
995
optional ( jo, was_loaded, " regenerates" , regenerates, 0 );
1006
996
optional ( jo, was_loaded, " regenerates_in_dark" , regenerates_in_dark, false );
@@ -1032,26 +1022,9 @@ void mtype::load( const JsonObject &jo, const std::string &src )
1032
1022
optional ( jo, was_loaded, " mech_str_bonus" , mech_str_bonus, 0 );
1033
1023
optional ( jo, was_loaded, " mech_battery" , mech_battery, itype_id () );
1034
1024
1035
- if ( jo.has_object ( " mount_items" ) ) {
1036
- JsonObject jo_mount_items = jo.get_object ( " mount_items" );
1037
- optional ( jo_mount_items, was_loaded, " tied" , mount_items.tied , itype_id () );
1038
- optional ( jo_mount_items, was_loaded, " tack" , mount_items.tack , itype_id () );
1039
- optional ( jo_mount_items, was_loaded, " armor" , mount_items.armor , itype_id () );
1040
- optional ( jo_mount_items, was_loaded, " storage" , mount_items.storage , itype_id () );
1041
- }
1042
-
1043
- if ( jo.has_array ( " revive_forms" ) ) {
1044
- revive_type foo;
1045
- for ( JsonObject jo_form : jo.get_array ( " revive_forms" ) ) {
1046
- read_condition ( jo_form, " condition" , foo.condition , true );
1047
- if ( jo_form.has_string ( " monster" ) ) {
1048
- mandatory ( jo_form, was_loaded, " monster" , foo.revive_mon );
1049
- } else {
1050
- mandatory ( jo_form, was_loaded, " monster_group" , foo.revive_monster_group );
1051
- }
1052
- revive_types.push_back ( foo );
1053
- }
1054
- }
1025
+ optional ( jo, was_loaded, " mount_items" , mount_items );
1026
+
1027
+ optional ( jo, was_loaded, " revive_forms" , revive_types );
1055
1028
1056
1029
optional ( jo, was_loaded, " zombify_into" , zombify_into, string_id_reader<::mtype> {},
1057
1030
mtype_id () );
@@ -1061,28 +1034,12 @@ void mtype::load( const JsonObject &jo, const std::string &src )
1061
1034
1062
1035
optional ( jo, was_loaded, " aggro_character" , aggro_character, true );
1063
1036
1064
- if ( jo.has_array ( " attack_effs" ) ) {
1065
- atk_effs.clear ();
1066
- for ( const JsonObject effect_jo : jo.get_array ( " attack_effs" ) ) {
1067
- mon_effect_data effect;
1068
- effect.load ( effect_jo );
1069
- atk_effs.push_back ( std::move ( effect ) );
1070
- }
1071
- }
1037
+ optional ( jo, was_loaded, " attack_effs" , atk_effs );
1072
1038
1073
1039
optional ( jo, was_loaded, " melee_damage" , melee_damage );
1074
1040
1075
- if ( jo.has_array ( " scents_tracked" ) ) {
1076
- for ( const std::string line : jo.get_array ( " scents_tracked" ) ) {
1077
- scents_tracked.emplace ( line );
1078
- }
1079
- }
1080
-
1081
- if ( jo.has_array ( " scents_ignored" ) ) {
1082
- for ( const std::string line : jo.get_array ( " scents_ignored" ) ) {
1083
- scents_ignored.emplace ( line );
1084
- }
1085
- }
1041
+ optional ( jo, was_loaded, " scents_tracked" , scents_tracked );
1042
+ optional ( jo, was_loaded, " scents_ignored" , scents_ignored );
1086
1043
1087
1044
if ( jo.has_member ( " death_drops" ) ) {
1088
1045
death_drops =
@@ -1091,38 +1048,19 @@ void mtype::load( const JsonObject &jo, const std::string &src )
1091
1048
}
1092
1049
1093
1050
assign ( jo, " harvest" , harvest );
1051
+ // FIXME: assign doesn't trigger issues that optional does???
1052
+ // optional( jo, was_loaded, "harvest", harvest, harvest_id::NULL_ID() );
1094
1053
1095
1054
optional ( jo, was_loaded, " dissect" , dissect );
1096
1055
1097
1056
optional ( jo, was_loaded, " decay" , decay );
1098
1057
1099
- if ( jo.has_array ( " shearing" ) ) {
1100
- std::vector<shearing_entry> entries;
1101
- for ( JsonObject shearing_entry : jo.get_array ( " shearing" ) ) {
1102
- struct shearing_entry entry {};
1103
- entry.load ( shearing_entry );
1104
- entries.emplace_back ( entry );
1105
- }
1106
- shearing = shearing_data ( entries );
1107
- }
1058
+ optional ( jo, was_loaded, " shearing" , shearing );
1108
1059
1109
1060
optional ( jo, was_loaded, " speed_description" , speed_desc, speed_description_DEFAULT );
1110
1061
optional ( jo, was_loaded, " death_function" , mdeath_effect );
1111
1062
1112
- if ( jo.has_array ( " emit_fields" ) ) {
1113
- JsonArray jar = jo.get_array ( " emit_fields" );
1114
- if ( jar.has_string ( 0 ) ) { // TEMPORARY until 0.F
1115
- for ( const std::string id : jar ) {
1116
- emit_fields.emplace ( emit_id ( id ), 1_seconds );
1117
- }
1118
- } else {
1119
- while ( jar.has_more () ) {
1120
- JsonObject obj = jar.next_object ();
1121
- emit_fields.emplace ( emit_id ( obj.get_string ( " emit_id" ) ),
1122
- read_from_json_string<time_duration>( obj.get_member ( " delay" ), time_duration::units ) );
1123
- }
1124
- }
1125
- }
1063
+ optional ( jo, was_loaded, " emit_fields" , emit_fields, named_pair_reader<emit_id, time_duration> {" emit_id" , " delay" } );
1126
1064
1127
1065
if ( jo.has_member ( " special_when_hit" ) ) {
1128
1066
JsonArray jsarr = jo.get_array ( " special_when_hit" );
0 commit comments