* Define properties for objects * @param first Local ID of the first object. * @param last Local ID of the last object. * @param prop The property to change. * @param buf The property value. * @return ChangeInfoResult. */
| 74 | * @return ChangeInfoResult. |
| 75 | */ |
| 76 | static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteReader &buf) |
| 77 | { |
| 78 | ChangeInfoResult ret = CIR_SUCCESS; |
| 79 | |
| 80 | if (last > NUM_OBJECTS_PER_GRF) { |
| 81 | GrfMsg(1, "ObjectChangeInfo: Too many objects loaded ({}), max ({}). Ignoring.", last, NUM_OBJECTS_PER_GRF); |
| 82 | return CIR_INVALID_ID; |
| 83 | } |
| 84 | |
| 85 | /* Allocate object specs if they haven't been allocated already. */ |
| 86 | if (_cur_gps.grffile->objectspec.size() < last) _cur_gps.grffile->objectspec.resize(last); |
| 87 | |
| 88 | for (uint id = first; id < last; ++id) { |
| 89 | auto &spec = _cur_gps.grffile->objectspec[id]; |
| 90 | |
| 91 | if (prop != 0x08 && spec == nullptr) { |
| 92 | /* If the object property 08 is not yet set, ignore this property */ |
| 93 | ChangeInfoResult cir = IgnoreObjectProperty(prop, buf); |
| 94 | if (cir > ret) ret = cir; |
| 95 | continue; |
| 96 | } |
| 97 | |
| 98 | switch (prop) { |
| 99 | case 0x08: { // Class ID |
| 100 | /* Allocate space for this object. */ |
| 101 | if (spec == nullptr) { |
| 102 | spec = std::make_unique<ObjectSpec>(); |
| 103 | spec->views = 1; // Default for NewGRFs that don't set it. |
| 104 | spec->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1) |
| 105 | } |
| 106 | |
| 107 | /* Swap classid because we read it in BE. */ |
| 108 | uint32_t classid = buf.ReadDWord(); |
| 109 | spec->class_index = ObjectClass::Allocate(std::byteswap(classid)); |
| 110 | break; |
| 111 | } |
| 112 | |
| 113 | case 0x09: { // Class name |
| 114 | AddStringForMapping(GRFStringID{buf.ReadWord()}, [spec = spec.get()](StringID str) { ObjectClass::Get(spec->class_index)->name = str; }); |
| 115 | break; |
| 116 | } |
| 117 | |
| 118 | case 0x0A: // Object name |
| 119 | AddStringForMapping(GRFStringID{buf.ReadWord()}, &spec->name); |
| 120 | break; |
| 121 | |
| 122 | case 0x0B: // Climate mask |
| 123 | spec->climate = LandscapeTypes{buf.ReadByte()}; |
| 124 | break; |
| 125 | |
| 126 | case 0x0C: // Size |
| 127 | spec->size = buf.ReadByte(); |
| 128 | if (GB(spec->size, 0, 4) == 0 || GB(spec->size, 4, 4) == 0) { |
| 129 | GrfMsg(0, "ObjectChangeInfo: Invalid object size requested (0x{:X}) for object id {}. Ignoring.", spec->size, id); |
| 130 | spec->size = OBJECT_SIZE_1X1; |
| 131 | } |
| 132 | break; |
| 133 |
no test coverage detected