Map Editor

RD Core / Commit #3

Commit Map Editor

Alex Alex committed 18/10/2026 23:40 main Patch
436 files +250,791 -0
A RD_Map_Editor/source/items.h +475-0 View file
@@ -0,0 +1,475 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_ITEMS_H_
19+#define RME_ITEMS_H_
20+
21+#include "filehandle.h"
22+#include "brush_enums.h"
23+
24+class Brush;
25+class GroundBrush;
26+class WallBrush;
27+class CarpetBrush;
28+class TableBrush;
29+class HouseBrush;
30+class HouseExitBrush;
31+class OptionalBorderBrush;
32+class EraserBrush;
33+class SpawnBrush;
34+class DoorBrush;
35+class FlagBrush;
36+class RAWBrush;
37+
38+class ItemType;
39+class GameSprite;
40+class GameSprite;
41+class ItemDatabase;
42+
43+extern ItemDatabase g_items;
44+
45+typedef uint8_t attribute_t;
46+typedef uint32_t flags_t;
47+typedef uint16_t datasize_t;
48+
49+enum ItemGroup_t {
50+ ITEM_GROUP_NONE = 0,
51+ ITEM_GROUP_GROUND,
52+ ITEM_GROUP_CONTAINER,
53+ ITEM_GROUP_WEAPON,
54+ ITEM_GROUP_AMMUNITION,
55+ ITEM_GROUP_ARMOR,
56+ ITEM_GROUP_RUNE,
57+ ITEM_GROUP_TELEPORT,
58+ ITEM_GROUP_MAGICFIELD,
59+ ITEM_GROUP_WRITEABLE,
60+ ITEM_GROUP_KEY,
61+ ITEM_GROUP_SPLASH,
62+ ITEM_GROUP_FLUID,
63+ ITEM_GROUP_DOOR,
64+ ITEM_GROUP_DEPRECATED,
65+ ITEM_GROUP_PODIUM,
66+ ITEM_GROUP_LAST
67+};
68+
69+enum ItemTypes_t {
70+ ITEM_TYPE_NONE = 0,
71+ ITEM_TYPE_DEPOT,
72+ ITEM_TYPE_MAILBOX,
73+ ITEM_TYPE_TRASHHOLDER,
74+ ITEM_TYPE_CONTAINER,
75+ ITEM_TYPE_DOOR,
76+ ITEM_TYPE_MAGICFIELD,
77+ ITEM_TYPE_TELEPORT,
78+ ITEM_TYPE_BED,
79+ ITEM_TYPE_KEY,
80+ ITEM_TYPE_PODIUM,
81+ ITEM_TYPE_LAST
82+};
83+
84+enum SlotPositionBits : uint32_t {
85+ SLOTP_WHEREEVER = 0xFFFFFFFF,
86+ SLOTP_HEAD = 1 << 0,
87+ SLOTP_NECKLACE = 1 << 1,
88+ SLOTP_BACKPACK = 1 << 2,
89+ SLOTP_ARMOR = 1 << 3,
90+ SLOTP_RIGHT = 1 << 4,
91+ SLOTP_LEFT = 1 << 5,
92+ SLOTP_LEGS = 1 << 6,
93+ SLOTP_FEET = 1 << 7,
94+ SLOTP_RING = 1 << 8,
95+ SLOTP_AMMO = 1 << 9,
96+ SLOTP_DEPOT = 1 << 10,
97+ SLOTP_TWO_HAND = 1 << 11,
98+ SLOTP_HAND = (SLOTP_LEFT | SLOTP_RIGHT)
99+};
100+
101+enum WeaponType_t : uint8_t {
102+ WEAPON_NONE,
103+ WEAPON_SWORD,
104+ WEAPON_CLUB,
105+ WEAPON_AXE,
106+ WEAPON_SHIELD,
107+ WEAPON_DISTANCE,
108+ WEAPON_WAND,
109+ WEAPON_AMMO,
110+};
111+
112+/////////OTB specific//////////////
113+
114+enum rootattrib_t {
115+ ROOT_ATTR_VERSION = 0x01
116+};
117+
118+enum itemattrib_t {
119+ ITEM_ATTR_FIRST = 0x10,
120+ ITEM_ATTR_SERVERID = ITEM_ATTR_FIRST,
121+ ITEM_ATTR_CLIENTID,
122+ ITEM_ATTR_NAME,
123+ ITEM_ATTR_DESCR,
124+ ITEM_ATTR_SPEED,
125+ ITEM_ATTR_SLOT,
126+ ITEM_ATTR_MAXITEMS,
127+ ITEM_ATTR_WEIGHT,
128+ ITEM_ATTR_WEAPON,
129+ ITEM_ATTR_AMU,
130+ ITEM_ATTR_ARMOR,
131+ ITEM_ATTR_MAGLEVEL,
132+ ITEM_ATTR_MAGFIELDTYPE,
133+ ITEM_ATTR_WRITEABLE,
134+ ITEM_ATTR_ROTATETO,
135+ ITEM_ATTR_DECAY,
136+ ITEM_ATTR_SPRITEHASH,
137+ ITEM_ATTR_MINIMAPCOLOR,
138+ ITEM_ATTR_07,
139+ ITEM_ATTR_08,
140+ ITEM_ATTR_LIGHT,
141+
142+ // 1-byte aligned
143+ ITEM_ATTR_DECAY2,
144+ ITEM_ATTR_WEAPON2,
145+ ITEM_ATTR_AMU2,
146+ ITEM_ATTR_ARMOR2,
147+ ITEM_ATTR_WRITEABLE2,
148+ ITEM_ATTR_LIGHT2,
149+ ITEM_ATTR_TOPORDER,
150+ ITEM_ATTR_WRITEABLE3,
151+
152+ ITEM_ATTR_WAREID,
153+ ITEM_ATTR_CLASSIFICATION,
154+
155+ ITEM_ATTR_LAST
156+};
157+
158+enum itemflags_t {
159+ FLAG_UNPASSABLE = 1 << 0,
160+ FLAG_BLOCK_MISSILES = 1 << 1,
161+ FLAG_BLOCK_PATHFINDER = 1 << 2,
162+ FLAG_HAS_ELEVATION = 1 << 3,
163+ FLAG_USEABLE = 1 << 4,
164+ FLAG_PICKUPABLE = 1 << 5,
165+ FLAG_MOVEABLE = 1 << 6,
166+ FLAG_STACKABLE = 1 << 7,
167+ FLAG_FLOORCHANGEDOWN = 1 << 8,
168+ FLAG_FLOORCHANGENORTH = 1 << 9,
169+ FLAG_FLOORCHANGEEAST = 1 << 10,
170+ FLAG_FLOORCHANGESOUTH = 1 << 11,
171+ FLAG_FLOORCHANGEWEST = 1 << 12,
172+ FLAG_ALWAYSONTOP = 1 << 13,
173+ FLAG_READABLE = 1 << 14,
174+ FLAG_ROTABLE = 1 << 15,
175+ FLAG_HANGABLE = 1 << 16,
176+ FLAG_HOOK_EAST = 1 << 17,
177+ FLAG_HOOK_SOUTH = 1 << 18,
178+ FLAG_CANNOTDECAY = 1 << 19,
179+ FLAG_ALLOWDISTREAD = 1 << 20,
180+ FLAG_UNUSED = 1 << 21,
181+ FLAG_CLIENTCHARGES = 1 << 22,
182+ FLAG_IGNORE_LOOK = 1 << 23
183+};
184+
185+enum slotsOTB_t {
186+ OTB_SLOT_DEFAULT,
187+ OTB_SLOT_HEAD,
188+ OTB_SLOT_BODY,
189+ OTB_SLOT_LEGS,
190+ OTB_SLOT_BACKPACK,
191+ OTB_SLOT_WEAPON,
192+ OTB_SLOT_2HAND,
193+ OTB_SLOT_FEET,
194+ OTB_SLOT_AMULET,
195+ OTB_SLOT_RING,
196+ OTB_SLOT_HAND,
197+};
198+
199+enum ShootTypeOtb_t {
200+ OTB_SHOOT_NONE = 0,
201+ OTB_SHOOT_BOLT = 1,
202+ OTB_SHOOT_ARROW = 2,
203+ OTB_SHOOT_FIRE = 3,
204+ OTB_SHOOT_ENERGY = 4,
205+ OTB_SHOOT_POISONARROW = 5,
206+ OTB_SHOOT_BURSTARROW = 6,
207+ OTB_SHOOT_THROWINGSTAR = 7,
208+ OTB_SHOOT_THROWINGKNIFE = 8,
209+ OTB_SHOOT_SMALLSTONE = 9,
210+ OTB_SHOOT_SUDDENDEATH = 10,
211+ OTB_SHOOT_LARGEROCK = 11,
212+ OTB_SHOOT_SNOWBALL = 12,
213+ OTB_SHOOT_POWERBOLT = 13,
214+ OTB_SHOOT_SPEAR = 14,
215+ OTB_SHOOT_POISONFIELD = 15,
216+ OTB_SHOOT_INFERNALBOLT = 16
217+};
218+
219+// 1-byte aligned structs
220+#pragma pack(1)
221+
222+struct VERSIONINFO {
223+ uint32_t dwMajorVersion;
224+ uint32_t dwMinorVersion;
225+ uint32_t dwBuildNumber;
226+ uint8_t CSDVersion[128];
227+};
228+
229+struct decayBlock2 {
230+ uint16_t decayTo;
231+ uint16_t decayTime;
232+};
233+
234+struct weaponBlock2 {
235+ uint8_t weaponType;
236+ uint8_t amuType;
237+ uint8_t shootType;
238+ uint8_t attack;
239+ uint8_t defence;
240+};
241+
242+struct amuBlock2 {
243+ uint8_t amuType;
244+ uint8_t shootType;
245+ uint8_t attack;
246+};
247+
248+struct armorBlock2 {
249+ uint16_t armor;
250+ double weight;
251+ uint16_t slot_position;
252+};
253+
254+struct writeableBlock2 {
255+ uint16_t readOnlyId;
256+};
257+
258+struct lightBlock2 {
259+ uint16_t lightLevel;
260+ uint16_t lightColor;
261+};
262+
263+struct writeableBlock3 {
264+ uint16_t readOnlyId;
265+ uint16_t maxTextLen;
266+};
267+
268+#pragma pack()
269+
270+class ItemType {
271+private:
272+ ItemType(const ItemType&) { }
273+
274+public:
275+ ItemType();
276+ ~ItemType();
277+
278+ bool isGroundTile() const {
279+ return (group == ITEM_GROUP_GROUND);
280+ }
281+ bool isSplash() const {
282+ return (group == ITEM_GROUP_SPLASH);
283+ }
284+ bool isFluidContainer() const {
285+ return (group == ITEM_GROUP_FLUID);
286+ }
287+
288+ bool isClientCharged() const {
289+ return client_chargeable;
290+ }
291+ bool isExtraCharged() const {
292+ return !client_chargeable && extra_chargeable;
293+ }
294+
295+ bool isDepot() const {
296+ return (type == ITEM_TYPE_DEPOT);
297+ }
298+ bool isMailbox() const {
299+ return (type == ITEM_TYPE_MAILBOX);
300+ }
301+ bool isTrashHolder() const {
302+ return (type == ITEM_TYPE_TRASHHOLDER);
303+ }
304+ bool isContainer() const {
305+ return (type == ITEM_TYPE_CONTAINER);
306+ }
307+ bool isDoor() const {
308+ return (type == ITEM_TYPE_DOOR);
309+ }
310+ bool isMagicField() const {
311+ return (type == ITEM_TYPE_MAGICFIELD);
312+ }
313+ bool isTeleport() const {
314+ return (type == ITEM_TYPE_TELEPORT);
315+ }
316+ bool isBed() const {
317+ return (type == ITEM_TYPE_BED);
318+ }
319+ bool isKey() const {
320+ return (type == ITEM_TYPE_KEY);
321+ }
322+ bool isPodium() const {
323+ return (type == ITEM_TYPE_PODIUM);
324+ }
325+
326+ bool isStackable() const {
327+ return stackable;
328+ }
329+ bool isMetaItem() const {
330+ return is_metaitem;
331+ }
332+
333+ bool isFloorChange() const;
334+
335+ GameSprite* sprite;
336+ uint16_t id;
337+ uint16_t clientID;
338+ Brush* brush;
339+ Brush* doodad_brush;
340+ Brush* collection_brush;
341+ RAWBrush* raw_brush;
342+ bool is_metaitem;
343+ // This is needed as a consequence of the item palette & the raw palette
344+ // using the same brushes ("others" category consists of items with this
345+ // flag set to false)
346+ bool has_raw;
347+ bool in_other_tileset;
348+
349+ ItemGroup_t group;
350+ ItemTypes_t type;
351+
352+ uint16_t volume;
353+ uint16_t maxTextLen;
354+ // uint16_t writeOnceItemId;
355+ uint16_t slot_position;
356+ uint8_t weapon_type;
357+ uint8_t classification = 0; // 12.81
358+ uint16_t ground_equivalent;
359+ uint32_t border_group;
360+ bool has_equivalent; // True if any item has this as ground_equivalent
361+ bool wall_hate_me; // (For wallbrushes, regard this as not part of the wall)
362+
363+ std::string name;
364+ std::string editorsuffix;
365+ std::string description;
366+
367+ float weight;
368+ // It might be useful to be able to extrapolate this information in the future
369+ int attack;
370+ int defense;
371+ int armor;
372+ uint32_t charges;
373+ bool client_chargeable;
374+ bool extra_chargeable;
375+ bool ignoreLook;
376+
377+ bool isHangable;
378+ bool hookEast;
379+ bool hookSouth;
380+ bool canReadText;
381+ bool canWriteText;
382+ bool allowDistRead;
383+ bool replaceable;
384+ bool decays;
385+
386+ bool stackable;
387+ bool moveable;
388+ bool alwaysOnBottom;
389+ bool pickupable;
390+ bool rotable;
391+ bool isBorder;
392+ bool isOptionalBorder;
393+ bool isWall;
394+ bool isBrushDoor;
395+ bool isOpen; // door or window physically open
396+ bool isLocked; // door key locked
397+ bool isTable;
398+ bool isCarpet;
399+
400+ bool floorChangeDown;
401+ bool floorChangeNorth;
402+ bool floorChangeSouth;
403+ bool floorChangeEast;
404+ bool floorChangeWest;
405+ bool floorChange;
406+
407+ bool unpassable;
408+ bool blockPickupable;
409+ bool blockMissiles;
410+ bool blockPathfinder;
411+ bool hasElevation;
412+
413+ int alwaysOnTopOrder;
414+ uint16_t rotateTo;
415+ BorderType border_alignment;
416+
417+ bool hasLight;
418+
419+
420+};
421+
422+class ItemDatabase {
423+public:
424+ ItemDatabase();
425+ ~ItemDatabase();
426+
427+ void clear();
428+
429+ ItemType& operator[](size_t id) {
430+ return getItemType(id);
431+ }
432+ uint16_t getMaxID() const {
433+ return max_item_id;
434+ }
435+
436+ bool typeExists(int id) const;
437+ ItemType& getItemType(int id);
438+ ItemType& getItemIdByClientID(int spriteId);
439+
440+ bool loadFromOtb(const FileName& datafile, wxString& error, wxArrayString& warnings);
441+ bool loadFromGameXml(const FileName& datafile, wxString& error, wxArrayString& warnings);
442+ bool loadItemFromGameXml(pugi::xml_node itemNode, int id);
443+ bool loadMetaItem(pugi::xml_node node);
444+
445+ // typedef std::map<int32_t, ItemType*> ItemMap;
446+ typedef contigous_vector<ItemType*> ItemMap;
447+ typedef std::map<std::string, ItemType*> ItemNameMap;
448+ ItemMap items;
449+
450+ // Version information
451+ uint32_t MajorVersion;
452+ uint32_t MinorVersion;
453+ uint32_t BuildNumber;
454+
455+protected:
456+ bool loadFromOtbVer1(BinaryNode* itemNode, wxString& error, wxArrayString& warnings);
457+ bool loadFromOtbVer2(BinaryNode* itemNode, wxString& error, wxArrayString& warnings);
458+ bool loadFromOtbVer3(BinaryNode* itemNode, wxString& error, wxArrayString& warnings);
459+
460+protected:
461+ // Count of GameSprite types
462+ uint16_t item_count;
463+ uint16_t effect_count;
464+ uint16_t monster_count;
465+ uint16_t distance_count;
466+
467+ uint16_t minclientID;
468+ uint16_t maxclientID;
469+ uint16_t max_item_id;
470+
471+ friend class GameSprite;
472+ friend class Item;
473+};
474+
475+#endif
A RD_Map_Editor/source/item_attributes.cpp +391-0 View file
@@ -0,0 +1,391 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#include "main.h"
19+
20+#include "item_attributes.h"
21+#include "filehandle.h"
22+
23+ItemAttributes::ItemAttributes() :
24+ attributes(nullptr) {
25+ ////
26+}
27+
28+ItemAttributes::ItemAttributes(const ItemAttributes& o) {
29+ if (o.attributes) {
30+ attributes = newd ItemAttributeMap(*o.attributes);
31+ }
32+}
33+
34+ItemAttributes::~ItemAttributes() {
35+ clearAllAttributes();
36+}
37+
38+void ItemAttributes::createAttributes() {
39+ if (!attributes) {
40+ attributes = newd ItemAttributeMap;
41+ }
42+}
43+
44+void ItemAttributes::clearAllAttributes() {
45+ if (attributes) {
46+ delete attributes;
47+ }
48+ attributes = nullptr;
49+}
50+
51+ItemAttributeMap ItemAttributes::getAttributes() const {
52+ if (attributes) {
53+ return *attributes;
54+ }
55+ return ItemAttributeMap();
56+}
57+
58+void ItemAttributes::setAttribute(const std::string& key, const ItemAttribute& value) {
59+ createAttributes();
60+ (*attributes)[key] = value;
61+}
62+
63+void ItemAttributes::setAttribute(const std::string& key, const std::string& value) {
64+ createAttributes();
65+ (*attributes)[key].set(value);
66+}
67+
68+void ItemAttributes::setAttribute(const std::string& key, int32_t value) {
69+ createAttributes();
70+ (*attributes)[key].set(value);
71+}
72+
73+void ItemAttributes::setAttribute(const std::string& key, double value) {
74+ createAttributes();
75+ (*attributes)[key].set(value);
76+}
77+
78+void ItemAttributes::setAttribute(const std::string& key, bool value) {
79+ createAttributes();
80+ (*attributes)[key].set(value);
81+}
82+
83+void ItemAttributes::eraseAttribute(const std::string& key) {
84+ if (!attributes) {
85+ return;
86+ }
87+
88+ ItemAttributeMap::iterator iter = attributes->find(key);
89+
90+ if (iter != attributes->end()) {
91+ attributes->erase(iter);
92+ }
93+}
94+
95+const std::string* ItemAttributes::getStringAttribute(const std::string& key) const {
96+ if (!attributes) {
97+ return nullptr;
98+ }
99+
100+ ItemAttributeMap::iterator iter = attributes->find(key);
101+ if (iter != attributes->end()) {
102+ return iter->second.getString();
103+ }
104+ return nullptr;
105+}
106+
107+const int32_t* ItemAttributes::getIntegerAttribute(const std::string& key) const {
108+ if (!attributes) {
109+ return nullptr;
110+ }
111+
112+ ItemAttributeMap::iterator iter = attributes->find(key);
113+ if (iter != attributes->end()) {
114+ return iter->second.getInteger();
115+ }
116+ return nullptr;
117+}
118+
119+const double* ItemAttributes::getFloatAttribute(const std::string& key) const {
120+ if (!attributes) {
121+ return nullptr;
122+ }
123+
124+ ItemAttributeMap::iterator iter = attributes->find(key);
125+ if (iter != attributes->end()) {
126+ return iter->second.getFloat();
127+ }
128+ return nullptr;
129+}
130+
131+const bool* ItemAttributes::getBooleanAttribute(const std::string& key) const {
132+ if (!attributes) {
133+ return nullptr;
134+ }
135+
136+ ItemAttributeMap::iterator iter = attributes->find(key);
137+ if (iter != attributes->end()) {
138+ return iter->second.getBoolean();
139+ }
140+ return nullptr;
141+}
142+
143+bool ItemAttributes::hasStringAttribute(const std::string& key) const {
144+ return getStringAttribute(key) != nullptr;
145+}
146+
147+bool ItemAttributes::hasIntegerAttribute(const std::string& key) const {
148+ return getIntegerAttribute(key) != nullptr;
149+}
150+
151+bool ItemAttributes::hasFloatAttribute(const std::string& key) const {
152+ return getFloatAttribute(key) != nullptr;
153+}
154+
155+bool ItemAttributes::hasBooleanAttribute(const std::string& key) const {
156+ return getBooleanAttribute(key) != nullptr;
157+}
158+
159+// Attribute type
160+// Can hold either int, bool or std::string
161+// Without using newd to allocate them
162+
163+ItemAttribute::ItemAttribute() :
164+ type(ItemAttribute::NONE) {
165+ ////
166+}
167+
168+ItemAttribute::ItemAttribute(const std::string& str) :
169+ type(ItemAttribute::STRING) {
170+ new (data) std::string(str);
171+}
172+
173+ItemAttribute::ItemAttribute(int32_t i) :
174+ type(ItemAttribute::INTEGER) {
175+ *reinterpret_cast<int*>(data) = i;
176+}
177+
178+ItemAttribute::ItemAttribute(double f) :
179+ type(ItemAttribute::DOUBLE) {
180+ *reinterpret_cast<double*>(data) = f;
181+}
182+
183+ItemAttribute::ItemAttribute(bool b) {
184+ *reinterpret_cast<bool*>(data) = b;
185+}
186+
187+ItemAttribute::ItemAttribute(const ItemAttribute& o) :
188+ type(ItemAttribute::NONE) {
189+ *this = o;
190+}
191+
192+ItemAttribute& ItemAttribute::operator=(const ItemAttribute& o) {
193+ if (&o == this) {
194+ return *this;
195+ }
196+
197+ clear();
198+ type = o.type;
199+ if (type == STRING) {
200+ new (data) std::string(*reinterpret_cast<const std::string*>(&o.data));
201+ } else if (type == INTEGER) {
202+ *reinterpret_cast<int32_t*>(data) = *reinterpret_cast<const int32_t*>(&o.data);
203+ } else if (type == FLOAT) {
204+ *reinterpret_cast<float*>(data) = *reinterpret_cast<const float*>(&o.data);
205+ } else if (type == DOUBLE) {
206+ *reinterpret_cast<double*>(data) = *reinterpret_cast<const double*>(&o.data);
207+ } else if (type == BOOLEAN) {
208+ *reinterpret_cast<bool*>(data) = *reinterpret_cast<const bool*>(&o.data);
209+ } else {
210+ type = NONE;
211+ }
212+
213+ return *this;
214+}
215+
216+ItemAttribute::~ItemAttribute() {
217+ clear();
218+}
219+
220+void ItemAttribute::clear() {
221+ if (type == STRING) {
222+ (reinterpret_cast<std::string*>(&data))->~basic_string();
223+ type = NONE;
224+ }
225+}
226+
227+void ItemAttribute::set(const std::string& str) {
228+ clear();
229+ type = STRING;
230+ new (data) std::string(str);
231+}
232+
233+void ItemAttribute::set(int32_t i) {
234+ clear();
235+ type = INTEGER;
236+ *reinterpret_cast<int32_t*>(&data) = i;
237+}
238+
239+void ItemAttribute::set(double y) {
240+ clear();
241+ type = DOUBLE;
242+ *reinterpret_cast<double*>(&data) = y;
243+}
244+
245+void ItemAttribute::set(bool b) {
246+ clear();
247+ type = BOOLEAN;
248+ *reinterpret_cast<bool*>(&data) = b;
249+}
250+
251+const std::string* ItemAttribute::getString() const {
252+ if (type == STRING) {
253+ return reinterpret_cast<const std::string*>(&data);
254+ }
255+ return nullptr;
256+}
257+
258+const int32_t* ItemAttribute::getInteger() const {
259+ if (type == INTEGER) {
260+ return reinterpret_cast<const int32_t*>(&data);
261+ }
262+ return nullptr;
263+}
264+
265+const double* ItemAttribute::getFloat() const {
266+ if (type == DOUBLE) {
267+ return reinterpret_cast<const double*>(&data);
268+ }
269+ return nullptr;
270+}
271+
272+const bool* ItemAttribute::getBoolean() const {
273+ if (type == BOOLEAN) {
274+ return reinterpret_cast<const bool*>(&data);
275+ }
276+ return nullptr;
277+}
278+
279+bool ItemAttributes::unserializeAttributeMap(const IOMap& maphandle, BinaryNode* stream) {
280+ uint16_t n;
281+ if (stream->getU16(n)) {
282+ createAttributes();
283+
284+ std::string key;
285+ ItemAttribute attrib;
286+
287+ while (n--) {
288+ if (!stream->getString(key)) {
289+ return false;
290+ }
291+ if (!attrib.unserialize(maphandle, stream)) {
292+ return false;
293+ }
294+ (*attributes)[key] = attrib;
295+ }
296+ }
297+ return true;
298+}
299+
300+void ItemAttributes::serializeAttributeMap(const IOMap& maphandle, NodeFileWriteHandle& f) const {
301+ // Maximum of 65535 attributes per item
302+ f.addU16(std::min((size_t)0xFFFF, attributes->size()));
303+
304+ ItemAttributeMap::const_iterator attribute = attributes->begin();
305+ int i = 0;
306+ while (attribute != attributes->end() && i <= 0xFFFF) {
307+ const std::string& key = attribute->first;
308+ if (key.size() > 0xFFFF) {
309+ f.addString(key.substr(0, 65535));
310+ } else {
311+ f.addString(key);
312+ }
313+
314+ attribute->second.serialize(maphandle, f);
315+ ++attribute, ++i;
316+ }
317+}
318+
319+bool ItemAttribute::unserialize(const IOMap& maphandle, BinaryNode* stream) {
320+ // Read type
321+ uint8_t rtype;
322+ stream->getU8(rtype);
323+
324+ // Read contents
325+ switch (rtype) {
326+ case STRING: {
327+ std::string str;
328+ if (!stream->getLongString(str)) {
329+ return false;
330+ }
331+ set(str);
332+ break;
333+ }
334+ case INTEGER: {
335+ uint32_t u32;
336+ if (!stream->getU32(u32)) {
337+ return false;
338+ }
339+ set(*reinterpret_cast<int32_t*>(&u32));
340+ break;
341+ }
342+ case FLOAT: {
343+ uint32_t u32;
344+ if (!stream->getU32(u32)) {
345+ return false;
346+ }
347+ set((double)*reinterpret_cast<float*>(&u32));
348+ break;
349+ }
350+ case DOUBLE: {
351+ uint64_t u64;
352+ if (!stream->getU64(u64)) {
353+ return false;
354+ }
355+ set(*reinterpret_cast<double*>(&u64));
356+ break;
357+ }
358+ case BOOLEAN: {
359+ uint8_t b;
360+ if (!stream->getU8(b)) {
361+ return false;
362+ }
363+ set(b != 0);
364+ }
365+ default:
366+ break;
367+ }
368+ return true;
369+}
370+
371+void ItemAttribute::serialize(const IOMap& maphandle, NodeFileWriteHandle& f) const {
372+ // Write type
373+ f.addU8((uint8_t)(type));
374+
375+ // Write contents
376+ switch (type) {
377+ case STRING:
378+ f.addLongString(*getString());
379+ break;
380+ case INTEGER:
381+ f.addU32(*(uint32_t*)getInteger());
382+ break;
383+ case DOUBLE:
384+ f.addU64(*(uint64_t*)getFloat());
385+ break;
386+ case BOOLEAN:
387+ f.addU8(*(uint8_t*)getBoolean());
388+ default:
389+ break;
390+ }
391+}
A RD_Map_Editor/source/item_attributes.h +115-0 View file
@@ -0,0 +1,115 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_ITEM_ATTRIBUTES_H_
19+#define RME_ITEM_ATTRIBUTES_H_
20+
21+#include <string>
22+#include <map>
23+
24+#include "filehandle.h"
25+
26+#include <boost/static_assert.hpp>
27+
28+class IOMap;
29+class ItemAttribute;
30+
31+class PropWriteStream;
32+class PropStream;
33+
34+class ItemAttribute {
35+public:
36+ ItemAttribute();
37+ ItemAttribute(const std::string& str);
38+ ItemAttribute(int32_t i);
39+ ItemAttribute(double f);
40+ ItemAttribute(bool b);
41+ ItemAttribute(const ItemAttribute& o);
42+ ItemAttribute& operator=(const ItemAttribute& o);
43+ ~ItemAttribute();
44+
45+ enum Type {
46+ STRING = 1,
47+ INTEGER = 2,
48+ FLOAT = 3,
49+ BOOLEAN = 4,
50+ DOUBLE = 5,
51+ NONE = 0
52+ } type;
53+
54+ void serialize(const IOMap& maphandle, NodeFileWriteHandle& f) const;
55+ bool unserialize(const IOMap& maphandle, BinaryNode* f);
56+
57+ void clear();
58+
59+ void set(const std::string& str);
60+ void set(int32_t i);
61+ void set(double f);
62+ void set(bool b);
63+
64+ const std::string* getString() const;
65+ const int32_t* getInteger() const;
66+ const double* getFloat() const;
67+ const bool* getBoolean() const;
68+
69+private:
70+ char data[sizeof(std::string) > sizeof(double) ? sizeof(std::string) : sizeof(double)];
71+};
72+
73+typedef std::map<std::string, ItemAttribute> ItemAttributeMap;
74+
75+class ItemAttributes {
76+public:
77+ ItemAttributes();
78+ ItemAttributes(const ItemAttributes& i);
79+ virtual ~ItemAttributes();
80+
81+ // Save / load
82+ void serializeAttributeMap(const IOMap& maphandle, NodeFileWriteHandle& f) const;
83+ bool unserializeAttributeMap(const IOMap& maphandle, BinaryNode* node);
84+
85+public:
86+ void setAttribute(const std::string& key, const ItemAttribute& attr);
87+ void setAttribute(const std::string& key, const std::string& value);
88+ void setAttribute(const std::string& key, int32_t value);
89+ void setAttribute(const std::string& key, double value);
90+ void setAttribute(const std::string& key, bool set);
91+
92+ // returns nullptr if the attribute is not set
93+ const std::string* getStringAttribute(const std::string& key) const;
94+ const int32_t* getIntegerAttribute(const std::string& key) const;
95+ const double* getFloatAttribute(const std::string& key) const;
96+ const bool* getBooleanAttribute(const std::string& key) const;
97+
98+ // Returns true if the attribute (of that type) exists
99+ bool hasStringAttribute(const std::string& key) const;
100+ bool hasIntegerAttribute(const std::string& key) const;
101+ bool hasFloatAttribute(const std::string& key) const;
102+ bool hasBooleanAttribute(const std::string& key) const;
103+
104+ void eraseAttribute(const std::string& key);
105+
106+ void clearAllAttributes();
107+ ItemAttributeMap getAttributes() const;
108+
109+protected:
110+ ItemAttributeMap* attributes;
111+
112+ void createAttributes();
113+};
114+
115+#endif
A RD_Map_Editor/source/json.h +27-0 View file
@@ -0,0 +1,27 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_JSON_H_
19+#define RME_JSON_H_
20+
21+#include "json/json_spirit.h"
22+
23+namespace json {
24+ using namespace json_spirit;
25+}
26+
27+#endif
A RD_Map_Editor/source/json/json_spirit.h +18-0 View file
@@ -0,0 +1,18 @@
1+#ifndef JSON_SPIRIT
2+#define JSON_SPIRIT
3+
4+// Copyright John W. Wilkinson 2007 - 2009.
5+// Distributed under the MIT License, see accompanying file LICENSE.txt
6+
7+// json spirit version 4.03
8+
9+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
10+# pragma once
11+#endif
12+
13+#include "json_spirit_value.h"
14+#include "json_spirit_reader.h"
15+#include "json_spirit_writer.h"
16+#include "json_spirit_utils.h"
17+
18+#endif
A RD_Map_Editor/source/json/json_spirit_error_position.h +56-0 View file
@@ -0,0 +1,56 @@
1+#ifndef JSON_SPIRIT_ERROR_POSITION
2+#define JSON_SPIRIT_ERROR_POSITION
3+
4+// Copyright John W. Wilkinson 2007 - 2009.
5+// Distributed under the MIT License, see accompanying file LICENSE.txt
6+
7+// json spirit version 4.03
8+
9+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
10+# pragma once
11+#endif
12+
13+#include <string>
14+
15+namespace json_spirit
16+{
17+ // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
18+ // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
19+ // functions that return a bool.
20+ //
21+ struct Error_position : std::runtime_error
22+ {
23+ Error_position();
24+ Error_position( unsigned int line, unsigned int column, const std::string& reason );
25+ bool operator==( const Error_position& lhs ) const;
26+ unsigned int line_;
27+ unsigned int column_;
28+ std::string reason_;
29+ };
30+
31+ inline Error_position::Error_position()
32+ : std::runtime_error("Error_position")
33+ , line_( 0 )
34+ , column_( 0 )
35+ {
36+ }
37+
38+ inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
39+ : std::runtime_error("Error_position")
40+ , line_( line )
41+ , column_( column )
42+ , reason_( reason )
43+ {
44+ }
45+
46+ inline bool Error_position::operator==( const Error_position& lhs ) const
47+ {
48+ if( this == &lhs ) return true;
49+
50+ return ( reason_ == lhs.reason_ ) &&
51+ ( line_ == lhs.line_ ) &&
52+ ( column_ == lhs.column_ );
53+}
54+}
55+
56+#endif
A RD_Map_Editor/source/json/json_spirit_reader.cpp +137-0 View file
@@ -0,0 +1,137 @@
1+// Copyright John W. Wilkinson 2007 - 2009.
2+// Distributed under the MIT License, see accompanying file LICENSE.txt
3+
4+// json spirit version 4.03
5+
6+#include "json_spirit_reader.h"
7+#include "json_spirit_reader_template.h"
8+
9+using namespace json_spirit;
10+
11+bool json_spirit::read( const std::string& s, Value& value )
12+{
13+ return read_string( s, value );
14+}
15+
16+void json_spirit::read_or_throw( const std::string& s, Value& value )
17+{
18+ read_string_or_throw( s, value );
19+}
20+
21+bool json_spirit::read( std::istream& is, Value& value )
22+{
23+ return read_stream( is, value );
24+}
25+
26+void json_spirit::read_or_throw( std::istream& is, Value& value )
27+{
28+ read_stream_or_throw( is, value );
29+}
30+
31+bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
32+{
33+ return read_range( begin, end, value );
34+}
35+
36+void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
37+{
38+ begin = read_range_or_throw( begin, end, value );
39+}
40+
41+#ifndef BOOST_NO_STD_WSTRING
42+
43+bool json_spirit::read( const std::wstring& s, wValue& value )
44+{
45+ return read_string( s, value );
46+}
47+
48+void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
49+{
50+ read_string_or_throw( s, value );
51+}
52+
53+bool json_spirit::read( std::wistream& is, wValue& value )
54+{
55+ return read_stream( is, value );
56+}
57+
58+void json_spirit::read_or_throw( std::wistream& is, wValue& value )
59+{
60+ read_stream_or_throw( is, value );
61+}
62+
63+bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
64+{
65+ return read_range( begin, end, value );
66+}
67+
68+void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
69+{
70+ begin = read_range_or_throw( begin, end, value );
71+}
72+
73+#endif
74+
75+bool json_spirit::read( const std::string& s, mValue& value )
76+{
77+ return read_string( s, value );
78+}
79+
80+void json_spirit::read_or_throw( const std::string& s, mValue& value )
81+{
82+ read_string_or_throw( s, value );
83+}
84+
85+bool json_spirit::read( std::istream& is, mValue& value )
86+{
87+ return read_stream( is, value );
88+}
89+
90+void json_spirit::read_or_throw( std::istream& is, mValue& value )
91+{
92+ read_stream_or_throw( is, value );
93+}
94+
95+bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
96+{
97+ return read_range( begin, end, value );
98+}
99+
100+void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
101+{
102+ begin = read_range_or_throw( begin, end, value );
103+}
104+
105+#ifndef BOOST_NO_STD_WSTRING
106+
107+bool json_spirit::read( const std::wstring& s, wmValue& value )
108+{
109+ return read_string( s, value );
110+}
111+
112+void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
113+{
114+ read_string_or_throw( s, value );
115+}
116+
117+bool json_spirit::read( std::wistream& is, wmValue& value )
118+{
119+ return read_stream( is, value );
120+}
121+
122+void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
123+{
124+ read_stream_or_throw( is, value );
125+}
126+
127+bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
128+{
129+ return read_range( begin, end, value );
130+}
131+
132+void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
133+{
134+ begin = read_range_or_throw( begin, end, value );
135+}
136+
137+#endif
A RD_Map_Editor/source/json/json_spirit_reader.h +62-0 View file
@@ -0,0 +1,62 @@
1+#ifndef JSON_SPIRIT_READER
2+#define JSON_SPIRIT_READER
3+
4+// Copyright John W. Wilkinson 2007 - 2009.
5+// Distributed under the MIT License, see accompanying file LICENSE.txt
6+
7+// json spirit version 4.03
8+
9+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
10+# pragma once
11+#endif
12+
13+#include "json_spirit_value.h"
14+#include "json_spirit_error_position.h"
15+#include <iostream>
16+
17+namespace json_spirit
18+{
19+ // functions to reads a JSON values
20+
21+ bool read( const std::string& s, Value& value );
22+ bool read( std::istream& is, Value& value );
23+ bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
24+
25+ void read_or_throw( const std::string& s, Value& value );
26+ void read_or_throw( std::istream& is, Value& value );
27+ void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
28+
29+#ifndef BOOST_NO_STD_WSTRING
30+
31+ bool read( const std::wstring& s, wValue& value );
32+ bool read( std::wistream& is, wValue& value );
33+ bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
34+
35+ void read_or_throw( const std::wstring& s, wValue& value );
36+ void read_or_throw( std::wistream& is, wValue& value );
37+ void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
38+
39+#endif
40+
41+ bool read( const std::string& s, mValue& value );
42+ bool read( std::istream& is, mValue& value );
43+ bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
44+
45+ void read_or_throw( const std::string& s, mValue& value );
46+ void read_or_throw( std::istream& is, mValue& value );
47+ void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
48+
49+#ifndef BOOST_NO_STD_WSTRING
50+
51+ bool read( const std::wstring& s, wmValue& value );
52+ bool read( std::wistream& is, wmValue& value );
53+ bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
54+
55+ void read_or_throw( const std::wstring& s, wmValue& value );
56+ void read_or_throw( std::wistream& is, wmValue& value );
57+ void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
58+
59+#endif
60+}
61+
62+#endif
Top