summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--res/maps.xml8
-rw-r--r--res/maps.xsd92
-rw-r--r--src/components/map_collision.cpp16
-rw-r--r--src/game.cpp164
-rw-r--r--src/game.h7
-rw-r--r--src/map.cpp107
-rw-r--r--src/map.h35
-rw-r--r--src/world.cpp134
-rw-r--r--src/world.h21
-rw-r--r--tools/mapedit/src/frame.cpp188
-rw-r--r--tools/mapedit/src/map.cpp162
-rw-r--r--tools/mapedit/src/map.h44
-rw-r--r--tools/mapedit/src/widget.cpp16
-rw-r--r--tools/mapedit/src/world.cpp397
15 files changed, 620 insertions, 772 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c9084e..c5e8f71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -53,6 +53,7 @@ add_executable(Aromatherapy
53 src/game.cpp 53 src/game.cpp
54 src/muxer.cpp 54 src/muxer.cpp
55 src/entityfactory.cpp 55 src/entityfactory.cpp
56 src/world.cpp
56 src/components/map_collision.cpp 57 src/components/map_collision.cpp
57 src/components/map_render.cpp 58 src/components/map_render.cpp
58 src/components/physics_body.cpp 59 src/components/physics_body.cpp
diff --git a/res/maps.xml b/res/maps.xml index 594cd18..444e59f 100644 --- a/res/maps.xml +++ b/res/maps.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="ISO-8859-1"?> 1<?xml version="1.0" encoding="ISO-8859-1"?>
2<world><nextmapid>5</nextmapid><lastmap>4</lastmap><root>0</root><startpos id="0" pos="203,44"/><map id="0"><name>Everything Is Embarrassing</name><environment>0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,18,9,8,10,8,11,8,10,10,8,11,8,9,10,21,0, 2<world nextmap="5" lastmap="4" startx="203" starty="44" startmap="0"><root>0</root><map id="0" title="Everything Is Embarrassing" expanded="true"><environment type="0">0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,18,9,8,10,8,11,8,10,10,8,11,8,9,10,21,0,
30,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,22,21, 30,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,22,21,
40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, 40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,
50,19,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, 50,19,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,
@@ -23,7 +23,7 @@
230,0,0,0,24,3,1,2,1,1,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,27,1,3,2,26,0,0,0,0,0,0, 230,0,0,0,24,3,1,2,1,1,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,27,1,3,2,26,0,0,0,0,0,0,
241,2,3,1,25,0,0,0,0,0,20,0,0,0,0,0,0,19,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,27,1,2,2,4,3,1, 241,2,3,1,25,0,0,0,0,0,20,0,0,0,0,0,0,19,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,27,1,2,2,4,3,1,
250,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0, 250,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,
26</environment><leftmap type="warp" map="1"/><rightmap type="wall"/><upmap type="wall"/><downmap type="wall"/><entities/><child>1</child><child>4</child><expanded>1</expanded></map><map id="1"><name>It's A Trap!</name><environment>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 26</environment><adjacent dir="left" type="warp" map="1" /><child>1</child><child>4</child></map><map id="1" title="It's A Trap!"><environment type="0">0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0, 270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,
280,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0, 280,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,
290,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 290,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -47,7 +47,7 @@
470,0,0,27,2,2,3,3,3,4,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 470,0,0,27,2,2,3,3,3,4,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
480,20,0,0,0,0,0,19,0,0,27,1,1,1,2,2,2,26,0,0,0,0,0,0,0,0,0,0,24,4,2,2,1,3,2,2,1,2,2,3, 480,20,0,0,0,0,0,19,0,0,27,1,1,1,2,2,2,26,0,0,0,0,0,0,0,0,0,0,24,4,2,2,1,3,2,2,1,2,2,3,
490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,19,0,0,0,0,0, 490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,19,0,0,0,0,0,
50</environment><leftmap type="wall"/><rightmap type="warp" map="0"/><upmap type="wall"/><downmap type="warp" map="4"/><entities><entity><entity-type>checkpoint</entity-type><entity-position>262,156</entity-position></entity></entities></map><map id="4"><name>The Visitors</name><environment>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0, 50</environment><entity type="checkpoint" x="262" y="156" /><adjacent dir="right" type="warp" map="0" /><adjacent dir="down" type="warp" map="4" /></map><map id="4" title="The Visitors"><environment type="0">0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
510,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,20,0,0,0,0, 510,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,20,0,0,0,0,
520,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0, 520,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
530,0,0,0,19,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0, 530,0,0,0,19,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
@@ -71,4 +71,4 @@
710,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0, 710,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
720,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0, 720,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0, 730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
74</environment><leftmap type="wall"/><rightmap type="wall"/><upmap type="warp" map="1"/><downmap type="wall"/><entities/></map></world> 74</environment><adjacent dir="up" type="warp" map="1" /><adjacent dir="down" type="wrap" /></map></world>
diff --git a/res/maps.xsd b/res/maps.xsd new file mode 100644 index 0000000..9d36fab --- /dev/null +++ b/res/maps.xsd
@@ -0,0 +1,92 @@
1<?xml version="1.0"?>
2<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3 <xs:simpleType name="map">
4 <xs:restriction base="xs:integer">
5 <xs:minInclusive value="0" />
6 </xs:restriction>
7 </xs:simpleType>
8
9 <xs:simpleType name="move-type">
10 <xs:restriction base="xs:string">
11 <xs:enumeration value="wall" />
12 <xs:enumeration value="wrap" />
13 <xs:enumeration value="warp" />
14 <xs:enumeration value="reverseWarp" />
15 </xs:restriction>
16 </xs:simpleType>
17
18 <xs:simpleType name="direction">
19 <xs:restriction base="xs:string">
20 <xs:enumeration value="left" />
21 <xs:enumeration value="right" />
22 <xs:enumeration value="up" />
23 <xs:enumeration value="down" />
24 </xs:restriction>
25 </xs:simpleType>
26
27 <xs:element name="world">
28 <xs:complexType>
29 <xs:sequence>
30 <xs:element name="root" type="map" maxOccurs="unbounded" />
31
32 <xs:element name="map" maxOccurs="unbounded">
33 <xs:complexType>
34 <xs:sequence>
35 <xs:element name="environment">
36 <xs:complexType>
37 <xs:simpleContent>
38 <xs:extension base="xs:string">
39 <xs:attribute name="type" use="required">
40 <xs:simpleType>
41 <xs:restriction base="xs:integer">
42 <xs:minInclusive value="0" />
43 <xs:maxExclusive value="5" />
44 </xs:restriction>
45 </xs:simpleType>
46 </xs:attribute>
47 </xs:extension>
48 </xs:simpleContent>
49 </xs:complexType>
50 </xs:element>
51
52 <xs:element name="entity" minOccurs="0" maxOccurs="unbounded">
53 <xs:complexType>
54 <xs:attribute name="type" type="xs:string" use="required" />
55 <xs:attribute name="x" type="xs:integer" use="required" />
56 <xs:attribute name="y" type="xs:integer" use="required" />
57 </xs:complexType>
58 </xs:element>
59
60 <xs:element name="adjacent" minOccurs="0" maxOccurs="4">
61 <xs:complexType>
62 <xs:attribute name="dir" type="direction" use="required" />
63 <xs:attribute name="type" type="move-type" use="required" />
64 <xs:attribute name="map" type="map" default="0" />
65 </xs:complexType>
66 </xs:element>
67
68 <xs:element name="child" type="map" minOccurs="0" maxOccurs="unbounded" />
69 </xs:sequence>
70
71 <xs:attribute name="id" type="xs:integer" use="required" />
72 <xs:attribute name="expanded" type="xs:boolean" default="false" />
73 <xs:attribute name="title" use="required">
74 <xs:simpleType>
75 <xs:restriction base="xs:string">
76 <xs:maxLength value="40" />
77 </xs:restriction>
78 </xs:simpleType>
79 </xs:attribute>
80 </xs:complexType>
81 </xs:element>
82 </xs:sequence>
83
84 <xs:attribute name="nextmap" type="map" default="0" />
85 <xs:attribute name="lastmap" type="map" default="0" />
86 <xs:attribute name="startx" type="xs:integer" use="required" />
87 <xs:attribute name="starty" type="xs:integer" use="required" />
88 <xs:attribute name="startmap" type="map" use="required" />
89 </xs:complexType>
90 </xs:element>
91
92</xs:schema>
diff --git a/src/components/map_collision.cpp b/src/components/map_collision.cpp index 9adad26..83ad33d 100644 --- a/src/components/map_collision.cpp +++ b/src/components/map_collision.cpp
@@ -5,10 +5,10 @@
5 5
6MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map) 6MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map)
7{ 7{
8 addCollision(-6, 0, GAME_HEIGHT, Direction::left, collisionFromMoveType(map.getLeftMoveType())); 8 addCollision(-6, 0, GAME_HEIGHT, Direction::left, collisionFromMoveType(map.getAdjacent(Map::MoveDir::Left).type));
9 addCollision(GAME_WIDTH+6, 0, GAME_HEIGHT, Direction::right, collisionFromMoveType(map.getRightMoveType())); 9 addCollision(GAME_WIDTH+6, 0, GAME_HEIGHT, Direction::right, collisionFromMoveType(map.getAdjacent(Map::MoveDir::Right).type));
10 addCollision(-7, 0, GAME_WIDTH, Direction::up, collisionFromMoveType(map.getUpMoveType())); 10 addCollision(-7, 0, GAME_WIDTH, Direction::up, collisionFromMoveType(map.getAdjacent(Map::MoveDir::Up).type));
11 addCollision(GAME_HEIGHT+6, 0, GAME_WIDTH, Direction::down, collisionFromMoveType(map.getDownMoveType())); 11 addCollision(GAME_HEIGHT+6, 0, GAME_WIDTH, Direction::down, collisionFromMoveType(map.getAdjacent(Map::MoveDir::Down).type));
12 12
13 for (int i=0; i<MAP_WIDTH*MAP_HEIGHT; i++) 13 for (int i=0; i<MAP_WIDTH*MAP_HEIGHT; i++)
14 { 14 {
@@ -189,16 +189,16 @@ void MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli
189 { 189 {
190 if (dir == Direction::left) 190 if (dir == Direction::left)
191 { 191 {
192 game.loadMap(game.getMap(map.getLeftMapID()), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second)); 192 game.loadMap(game.getWorld().getMap(map.getAdjacent(Map::MoveDir::Left).map), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second));
193 } else if (dir == Direction::right) 193 } else if (dir == Direction::right)
194 { 194 {
195 game.loadMap(game.getMap(map.getRightMapID()), std::make_pair(-collider.size.first/2, old_position.second)); 195 game.loadMap(game.getWorld().getMap(map.getAdjacent(Map::MoveDir::Right).map), std::make_pair(-collider.size.first/2, old_position.second));
196 } else if (dir == Direction::up) 196 } else if (dir == Direction::up)
197 { 197 {
198 game.loadMap(game.getMap(map.getUpMapID()), std::make_pair(old_position.first, GAME_HEIGHT-collider.size.second/2)); 198 game.loadMap(game.getWorld().getMap(map.getAdjacent(Map::MoveDir::Up).map), std::make_pair(old_position.first, GAME_HEIGHT-collider.size.second/2));
199 } else if (dir == Direction::down) 199 } else if (dir == Direction::down)
200 { 200 {
201 game.loadMap(game.getMap(map.getDownMapID()), std::make_pair(old_position.first, -collider.size.second/2)); 201 game.loadMap(game.getWorld().getMap(map.getAdjacent(Map::MoveDir::Down).map), std::make_pair(old_position.first, -collider.size.second/2));
202 } 202 }
203 } else if (collision.type == Collision::Type::reverse) 203 } else if (collision.type == Collision::Type::reverse)
204 { 204 {
diff --git a/src/game.cpp b/src/game.cpp index 4a08744..673c804 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -1,6 +1,5 @@
1#include "game.h" 1#include "game.h"
2#include <cstdlib> 2#include <cstdlib>
3#include <libxml/parser.h>
4#include "renderer.h" 3#include "renderer.h"
5#include "muxer.h" 4#include "muxer.h"
6#include "map.h" 5#include "map.h"
@@ -11,164 +10,11 @@
11#include "components/map_collision.h" 10#include "components/map_collision.h"
12#include "consts.h" 11#include "consts.h"
13 12
14Game::Game(const char* mapfile) 13Game::Game(const char* mapfile) : world(mapfile)
15{ 14{
16 // Load maps
17 xmlDocPtr doc = xmlParseFile(mapfile);
18 if (doc == nullptr)
19 {
20 exit(2);
21 }
22
23 xmlNodePtr top = xmlDocGetRootElement(doc);
24 if (top == nullptr)
25 {
26 exit(2);
27 }
28
29 if (xmlStrcmp(top->name, (const xmlChar*) "world"))
30 {
31 exit(2);
32 }
33
34 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
35 {
36 if (!xmlStrcmp(node->name, (const xmlChar*) "startpos"))
37 {
38 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
39 if (idKey == 0) exit(2);
40 startMap = atoi((char*) idKey);
41 xmlFree(idKey);
42
43 xmlChar* posKey = xmlGetProp(node, (xmlChar*) "pos");
44 if (posKey == 0) exit(2);
45 sscanf((char*) posKey, "%d,%d", &startPos.first, &startPos.second);
46 xmlFree(posKey);
47 } else if (!xmlStrcmp(node->name, (const xmlChar*) "map"))
48 {
49 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
50 if (idKey == 0) exit(2);
51 int theId = atoi((char*) idKey);
52 xmlFree(idKey);
53
54 Map map {theId};
55
56 for (xmlNodePtr mapNode = node->xmlChildrenNode; mapNode != NULL; mapNode = mapNode->next)
57 {
58 if (!xmlStrcmp(mapNode->name, (const xmlChar*) "name"))
59 {
60 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
61 if (key != 0)
62 {
63 map.setTitle((char*) key);
64 }
65
66 xmlFree(key);
67 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "environment"))
68 {
69 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
70 int* mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
71 mapdata[0] = atoi(strtok((char*) key, ",\n"));
72 for (int i=1; i<(MAP_WIDTH*MAP_HEIGHT); i++)
73 {
74 mapdata[i] = atoi(strtok(NULL, ",\n"));
75 }
76 map.setMapdata(mapdata);
77 xmlFree(key);
78 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "leftmap"))
79 {
80 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
81 if (typeKey == 0) exit(2);
82 map.setLeftMoveType(Map::moveTypeForShort((char*) typeKey));
83 xmlFree(typeKey);
84
85 if (Map::moveTypeTakesMap(map.getLeftMoveType()))
86 {
87 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
88 if (idKey == 0) exit(2);
89 map.setLeftMapID(atoi((char*) idKey));
90 xmlFree(idKey);
91 }
92 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "rightmap"))
93 {
94 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
95 if (typeKey == 0) exit(2);
96 map.setRightMoveType(Map::moveTypeForShort((char*) typeKey));
97 xmlFree(typeKey);
98
99 if (Map::moveTypeTakesMap(map.getRightMoveType()))
100 {
101 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
102 if (idKey == 0) exit(2);
103 map.setRightMapID(atoi((char*) idKey));
104 xmlFree(idKey);
105 }
106 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "upmap"))
107 {
108 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
109 if (typeKey == 0) exit(2);
110 map.setUpMoveType(Map::moveTypeForShort((char*) typeKey));
111 xmlFree(typeKey);
112
113 if (Map::moveTypeTakesMap(map.getUpMoveType()))
114 {
115 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
116 if (idKey == 0) exit(2);
117 map.setUpMapID(atoi((char*) idKey));
118 xmlFree(idKey);
119 }
120 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "downmap"))
121 {
122 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
123 if (typeKey == 0) exit(2);
124 map.setDownMoveType(Map::moveTypeForShort((char*) typeKey));
125 xmlFree(typeKey);
126
127 if (Map::moveTypeTakesMap(map.getDownMoveType()))
128 {
129 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
130 if (idKey == 0) exit(2);
131 map.setDownMapID(atoi((char*) idKey));
132 xmlFree(idKey);
133 }
134 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "entities"))
135 {
136 for (xmlNodePtr entityNode = mapNode->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next)
137 {
138 if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity"))
139 {
140 Map::EntityData data;
141
142 for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next)
143 {
144 if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type"))
145 {
146 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
147 data.name = (char*) key;
148 xmlFree(key);
149 } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position"))
150 {
151 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
152 sscanf((char*) key, "%d,%d", &data.position.first, &data.position.second);
153 xmlFree(key);
154 }
155 }
156
157 map.addEntity(data);
158 }
159 }
160 }
161 }
162
163 maps[theId] = map;
164 }
165 }
166
167 xmlFreeDoc(doc);
168
169 // Set up entities 15 // Set up entities
170 player = std::make_shared<Entity>(); 16 player = std::make_shared<Entity>();
171 player->position = startPos; 17 player->position = world.getStartingPosition();
172 player->size = std::make_pair(10.0,12.0); 18 player->size = std::make_pair(10.0,12.0);
173 19
174 auto player_input = std::make_shared<UserMovementComponent>(); 20 auto player_input = std::make_shared<UserMovementComponent>();
@@ -180,7 +26,7 @@ Game::Game(const char* mapfile)
180 auto player_anim = std::make_shared<PlayerSpriteComponent>(); 26 auto player_anim = std::make_shared<PlayerSpriteComponent>();
181 player->addComponent(player_anim); 27 player->addComponent(player_anim);
182 28
183 Map& startingMap = maps[startMap]; 29 const Map& startingMap = world.getStartingMap();
184 save = {&startingMap, player->position}; 30 save = {&startingMap, player->position};
185 31
186 loadMap(startingMap, player->position); 32 loadMap(startingMap, player->position);
@@ -326,7 +172,7 @@ void Game::playerDie()
326 }); 172 });
327} 173}
328 174
329const Map& Game::getMap(int id) const 175const World& Game::getWorld() const
330{ 176{
331 return maps.at(id); 177 return world;
332} 178}
diff --git a/src/game.h b/src/game.h index 3f0fcc8..dd4b2f7 100644 --- a/src/game.h +++ b/src/game.h
@@ -6,6 +6,7 @@
6#include <list> 6#include <list>
7#include <map> 7#include <map>
8#include "map.h" 8#include "map.h"
9#include "world.h"
9 10
10class Entity; 11class Entity;
11struct GLFWwindow; 12struct GLFWwindow;
@@ -24,14 +25,11 @@ class Game {
24 void saveGame(); 25 void saveGame();
25 void schedule(double time, std::function<void ()> callback); 26 void schedule(double time, std::function<void ()> callback);
26 void playerDie(); 27 void playerDie();
27 const Map& getMap(int id) const; 28 const World& getWorld() const;
28 29
29 private: 30 private:
30 friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); 31 friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
31 32
32 std::map<int, Map> maps;
33 int startMap;
34 std::pair<int, int> startPos;
35 std::list<std::shared_ptr<Entity>> entities; 33 std::list<std::shared_ptr<Entity>> entities;
36 std::list<std::shared_ptr<Entity>> nextEntities; 34 std::list<std::shared_ptr<Entity>> nextEntities;
37 std::pair<double, double> nextPosition; 35 std::pair<double, double> nextPosition;
@@ -41,6 +39,7 @@ class Game {
41 Savefile save; 39 Savefile save;
42 std::list<std::pair<double, std::function<void ()>>> scheduled; 40 std::list<std::pair<double, std::function<void ()>>> scheduled;
43 bool shouldQuit = false; 41 bool shouldQuit = false;
42 World world;
44}; 43};
45 44
46#endif 45#endif
diff --git a/src/map.cpp b/src/map.cpp index fa940ef..c4f31d1 100644 --- a/src/map.cpp +++ b/src/map.cpp
@@ -20,14 +20,7 @@ Map::Map(const Map& map)
20 20
21 id = map.id; 21 id = map.id;
22 title = map.title; 22 title = map.title;
23 leftMap = map.leftMap; 23 adjacents = map.adjacents;
24 rightMap = map.rightMap;
25 downMap = map.downMap;
26 upMap = map.upMap;
27 leftType = map.leftType;
28 rightType = map.rightType;
29 upType = map.upType;
30 downType = map.downType;
31 entities = map.entities; 24 entities = map.entities;
32} 25}
33 26
@@ -52,14 +45,7 @@ void swap(Map& first, Map& second)
52{ 45{
53 std::swap(first.mapdata, second.mapdata); 46 std::swap(first.mapdata, second.mapdata);
54 std::swap(first.title, second.title); 47 std::swap(first.title, second.title);
55 std::swap(first.leftMap, second.leftMap); 48 std::swap(first.adjacents, second.adjacents);
56 std::swap(first.rightMap, second.rightMap);
57 std::swap(first.downMap, second.downMap);
58 std::swap(first.upMap, second.upMap);
59 std::swap(first.leftType, second.leftType);
60 std::swap(first.rightType, second.rightType);
61 std::swap(first.upType, second.upType);
62 std::swap(first.downType, second.downType);
63 std::swap(first.id, second.id); 49 std::swap(first.id, second.id);
64 std::swap(first.entities, second.entities); 50 std::swap(first.entities, second.entities);
65} 51}
@@ -109,44 +95,24 @@ Map::MoveType Map::moveTypeForShort(std::string str)
109 return MoveType::Wall; 95 return MoveType::Wall;
110} 96}
111 97
112Map::MoveType Map::getLeftMoveType() const 98Map::MoveDir Map::moveDirForShort(std::string str)
113{ 99{
114 return leftType; 100 if (str == "right") return MoveDir::Right;
115} 101 if (str == "up") return MoveDir::Up;
116 102 if (str == "down") return MoveDir::Down;
117Map::MoveType Map::getRightMoveType() const 103
118{ 104 return MoveDir::Left;
119 return rightType;
120}
121
122Map::MoveType Map::getUpMoveType() const
123{
124 return upType;
125}
126
127Map::MoveType Map::getDownMoveType() const
128{
129 return downType;
130}
131
132int Map::getLeftMapID() const
133{
134 return leftMap;
135}
136
137int Map::getRightMapID() const
138{
139 return rightMap;
140}
141
142int Map::getUpMapID() const
143{
144 return upMap;
145} 105}
146 106
147int Map::getDownMapID() const 107static const Map::Adjacent defaultAdjacent {};
108const Map::Adjacent& Map::getAdjacent(MoveDir dir) const
148{ 109{
149 return downMap; 110 if (adjacents.count(dir) > 0)
111 {
112 return adjacents.at(dir);
113 } else {
114 return defaultAdjacent;
115 }
150} 116}
151 117
152bool Map::moveTypeTakesMap(MoveType type) 118bool Map::moveTypeTakesMap(MoveType type)
@@ -171,44 +137,11 @@ void Map::setTitle(std::string title)
171 this->title = title; 137 this->title = title;
172} 138}
173 139
174void Map::setLeftMoveType(MoveType type) 140void Map::setAdjacent(MoveDir dir, MoveType type, int map)
175{
176 leftType = type;
177}
178
179void Map::setRightMoveType(MoveType type)
180{
181 rightType = type;
182}
183
184void Map::setUpMoveType(MoveType type)
185{
186 upType = type;
187}
188
189void Map::setDownMoveType(MoveType type)
190{
191 downType = type;
192}
193
194void Map::setLeftMapID(int id)
195{
196 leftMap = id;
197}
198
199void Map::setRightMapID(int id)
200{
201 rightMap = id;
202}
203
204void Map::setUpMapID(int id)
205{
206 upMap = id;
207}
208
209void Map::setDownMapID(int id)
210{ 141{
211 downMap = id; 142 Adjacent& cur = adjacents[dir];
143 cur.type = type;
144 if (map != -1) cur.map = map;
212} 145}
213 146
214void Map::addEntity(EntityData& data) 147void Map::addEntity(EntityData& data)
diff --git a/src/map.h b/src/map.h index 1234dbb..4e661ab 100644 --- a/src/map.h +++ b/src/map.h
@@ -3,6 +3,7 @@
3 3
4#include <string> 4#include <string>
5#include <list> 5#include <list>
6#include <map>
6 7
7class Entity; 8class Entity;
8 9
@@ -23,25 +24,31 @@ class Map {
23 ReverseWarp 24 ReverseWarp
24 }; 25 };
25 26
27 enum class MoveDir {
28 Left,
29 Right,
30 Up,
31 Down
32 };
33
26 struct EntityData { 34 struct EntityData {
27 std::string name; 35 std::string name;
28 std::pair<int, int> position; 36 std::pair<int, int> position;
29 }; 37 };
30 38
39 struct Adjacent {
40 MoveType type = MoveType::Wall;
41 int map = -1;
42 };
43
31 static MoveType moveTypeForShort(std::string str); 44 static MoveType moveTypeForShort(std::string str);
45 static MoveDir moveDirForShort(std::string str);
32 static bool moveTypeTakesMap(MoveType type); 46 static bool moveTypeTakesMap(MoveType type);
33 47
34 int getID() const; 48 int getID() const;
35 const int* getMapdata() const; 49 const int* getMapdata() const;
36 std::string getTitle() const; 50 std::string getTitle() const;
37 MoveType getLeftMoveType() const; 51 const Adjacent& getAdjacent(MoveDir dir) const;
38 MoveType getRightMoveType() const;
39 MoveType getUpMoveType() const;
40 MoveType getDownMoveType() const;
41 int getLeftMapID() const;
42 int getRightMapID() const;
43 int getUpMapID() const;
44 int getDownMapID() const;
45 52
46 void createEntities(std::list<std::shared_ptr<Entity>>& entities) const; 53 void createEntities(std::list<std::shared_ptr<Entity>>& entities) const;
47 bool operator==(const Map& other) const; 54 bool operator==(const Map& other) const;
@@ -49,22 +56,14 @@ class Map {
49 56
50 void setMapdata(int* mapdata); 57 void setMapdata(int* mapdata);
51 void setTitle(std::string title); 58 void setTitle(std::string title);
52 void setLeftMoveType(MoveType type); 59 void setAdjacent(MoveDir dir, MoveType type, int map);
53 void setRightMoveType(MoveType type);
54 void setUpMoveType(MoveType type);
55 void setDownMoveType(MoveType type);
56 void setLeftMapID(int id);
57 void setRightMapID(int id);
58 void setUpMapID(int id);
59 void setDownMapID(int id);
60 void addEntity(EntityData& data); 60 void addEntity(EntityData& data);
61 private: 61 private:
62 int* mapdata; 62 int* mapdata;
63 std::string title; 63 std::string title;
64 int id; 64 int id;
65 std::list<EntityData> entities; 65 std::list<EntityData> entities;
66 MoveType leftType, rightType, upType, downType; 66 std::map<MoveDir, Adjacent> adjacents;
67 int leftMap, rightMap, upMap, downMap;
68}; 67};
69 68
70#endif 69#endif
diff --git a/src/world.cpp b/src/world.cpp new file mode 100644 index 0000000..17288fa --- /dev/null +++ b/src/world.cpp
@@ -0,0 +1,134 @@
1#include "world.h"
2#include <libxml/parser.h>
3#include "consts.h"
4
5World::World(const char* filename)
6{
7 xmlDocPtr doc = xmlParseFile(filename);
8 if (doc == nullptr)
9 {
10 exit(2);
11 }
12
13 xmlNodePtr top = xmlDocGetRootElement(doc);
14 if (top == nullptr)
15 {
16 exit(2);
17 }
18
19 if (xmlStrcmp(top->name, (const xmlChar*) "world"))
20 {
21 exit(2);
22 }
23
24 xmlChar* startxKey = xmlGetProp(top, (xmlChar*) "startx");
25 if (startxKey == 0) exit(2);
26 startX = atoi((char*) startxKey);
27 xmlFree(startxKey);
28
29 xmlChar* startyKey = xmlGetProp(top, (xmlChar*) "starty");
30 if (startyKey == 0) exit(2);
31 startY = atoi((char*) startyKey);
32 xmlFree(startyKey);
33
34 xmlChar* startmapKey = xmlGetProp(top, (xmlChar*) "startmap");
35 if (startxKey == 0) exit(2);
36 startMap = atoi((char*) startmapKey);
37 xmlFree(startmapKey);
38
39 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
40 {
41 if (!xmlStrcmp(node->name, (const xmlChar*) "map"))
42 {
43 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
44 if (idKey == 0) exit(2);
45 int theId = atoi((char*) idKey);
46 xmlFree(idKey);
47
48 maps.emplace(theId, theId);
49 Map& map = maps[theId];
50
51 xmlChar* titleKey = xmlGetProp(node, (xmlChar*) "title");
52 if (titleKey == 0) exit(2);
53 map.setTitle((char*) titleKey);
54 xmlFree(titleKey);
55
56 for (xmlNodePtr mapNode = node->xmlChildrenNode; mapNode != NULL; mapNode = mapNode->next)
57 {
58 if (!xmlStrcmp(mapNode->name, (const xmlChar*) "environment"))
59 {
60 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
61 int* mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
62 mapdata[0] = atoi(strtok((char*) key, ",\n"));
63 for (int i=1; i<(MAP_WIDTH*MAP_HEIGHT); i++)
64 {
65 mapdata[i] = atoi(strtok(NULL, ",\n"));
66 }
67 map.setMapdata(mapdata);
68 xmlFree(key);
69 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "entity"))
70 {
71 Map::EntityData data;
72
73 xmlChar* typeKey = xmlGetProp(mapNode, (const xmlChar*) "type");
74 if (typeKey == 0) exit(2);
75 data.name = (char*) typeKey;
76 xmlFree(typeKey);
77
78 xmlChar* xKey = xmlGetProp(mapNode, (const xmlChar*) "x");
79 if (xKey == 0) exit(2);
80 data.position.first = atoi((char*) xKey);
81 xmlFree(xKey);
82
83 xmlChar* yKey = xmlGetProp(mapNode, (const xmlChar*) "y");
84 if (yKey == 0) exit(2);
85 data.position.second = atoi((char*) yKey);
86 xmlFree(yKey);
87
88 map.addEntity(data);
89 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "adjacent"))
90 {
91 Map::MoveDir direction;
92 Map::MoveType moveType;
93 int mapId = 0;
94
95 xmlChar* dirKey = xmlGetProp(mapNode, (const xmlChar*) "dir");
96 if (dirKey == 0) exit(2);
97 direction = Map::moveDirForShort((char*) dirKey);
98 xmlFree(dirKey);
99
100 xmlChar* typeKey = xmlGetProp(mapNode, (const xmlChar*) "type");
101 if (typeKey == 0) exit(2);
102 moveType = Map::moveTypeForShort((char*) typeKey);
103 xmlFree(typeKey);
104
105 xmlChar* mapIdKey = xmlGetProp(mapNode, (const xmlChar*) "map");
106 if (mapIdKey != 0)
107 {
108 mapId = atoi((char*) mapIdKey);
109 }
110 xmlFree(mapIdKey);
111
112 map.setAdjacent(direction, moveType, mapId);
113 }
114 }
115 }
116 }
117
118 xmlFreeDoc(doc);
119}
120
121const Map& World::getMap(int id) const
122{
123 return maps.at(id);
124}
125
126const Map& World::getStartingMap() const
127{
128 return maps.at(startMap);
129}
130
131std::pair<int, int> World::getStartingPosition() const
132{
133 return std::make_pair(startX, startY);
134}
diff --git a/src/world.h b/src/world.h new file mode 100644 index 0000000..f566487 --- /dev/null +++ b/src/world.h
@@ -0,0 +1,21 @@
1#ifndef WORLD_H
2#define WORLD_H
3
4#include <map>
5#include "map.h"
6
7class World {
8 public:
9 World(const char* filename);
10 const Map& getMap(int id) const;
11 const Map& getStartingMap() const;
12 std::pair<int, int> getStartingPosition() const;
13
14 private:
15 std::map<int, Map> maps;
16 int startMap;
17 int startX;
18 int startY;
19};
20
21#endif /* end of include guard: WORLD_H */
diff --git a/tools/mapedit/src/frame.cpp b/tools/mapedit/src/frame.cpp index cc45c29..06102f7 100644 --- a/tools/mapedit/src/frame.cpp +++ b/tools/mapedit/src/frame.cpp
@@ -190,22 +190,22 @@ MapeditFrame::MapeditFrame(World* world) : wxFrame(NULL, wxID_ANY, "Map Editor")
190 wxStaticText* leftmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Leftmap Action:"); 190 wxStaticText* leftmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Leftmap Action:");
191 wxChoice* leftmapChoice = new wxChoice(propertyEditor, LEFTMAP_TYPE_CHOICE); 191 wxChoice* leftmapChoice = new wxChoice(propertyEditor, LEFTMAP_TYPE_CHOICE);
192 wxComboCtrl* leftmapCombo = new wxComboCtrl(propertyEditor, LEFTMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY); 192 wxComboCtrl* leftmapCombo = new wxComboCtrl(propertyEditor, LEFTMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
193 leftmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getLeftMoveMapID())); 193 leftmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getAdjacent(Map::MoveDir::Left).map));
194 194
195 wxStaticText* rightmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Rightmap Action:"); 195 wxStaticText* rightmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Rightmap Action:");
196 wxChoice* rightmapChoice = new wxChoice(propertyEditor, RIGHTMAP_TYPE_CHOICE); 196 wxChoice* rightmapChoice = new wxChoice(propertyEditor, RIGHTMAP_TYPE_CHOICE);
197 wxComboCtrl* rightmapCombo = new wxComboCtrl(propertyEditor, RIGHTMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY); 197 wxComboCtrl* rightmapCombo = new wxComboCtrl(propertyEditor, RIGHTMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
198 rightmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getRightMoveMapID())); 198 rightmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getAdjacent(Map::MoveDir::Right).map));
199 199
200 wxStaticText* upmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Upmap Action:"); 200 wxStaticText* upmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Upmap Action:");
201 wxChoice* upmapChoice = new wxChoice(propertyEditor, UPMAP_TYPE_CHOICE); 201 wxChoice* upmapChoice = new wxChoice(propertyEditor, UPMAP_TYPE_CHOICE);
202 wxComboCtrl* upmapCombo = new wxComboCtrl(propertyEditor, UPMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY); 202 wxComboCtrl* upmapCombo = new wxComboCtrl(propertyEditor, UPMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
203 upmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getUpMoveMapID())); 203 upmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getAdjacent(Map::MoveDir::Up).map));
204 204
205 wxStaticText* downmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Downmap Action:"); 205 wxStaticText* downmapLabel = new wxStaticText(propertyEditor, wxID_ANY, "Downmap Action:");
206 wxChoice* downmapChoice = new wxChoice(propertyEditor, DOWNMAP_TYPE_CHOICE); 206 wxChoice* downmapChoice = new wxChoice(propertyEditor, DOWNMAP_TYPE_CHOICE);
207 wxComboCtrl* downmapCombo = new wxComboCtrl(propertyEditor, DOWNMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY); 207 wxComboCtrl* downmapCombo = new wxComboCtrl(propertyEditor, DOWNMAP_MAP_CHOICE, "", wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
208 downmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getDownMoveMapID())); 208 downmapCombo->SetPopupControl(new MapSelectComboPopup(mapTree, currentMap->getAdjacent(Map::MoveDir::Down).map));
209 209
210 for (auto type : Map::listMoveTypes()) 210 for (auto type : Map::listMoveTypes())
211 { 211 {
@@ -674,157 +674,169 @@ void MapeditFrame::OnThreeMovingSash(wxSplitterEvent& event)
674 674
675void MapeditFrame::OnSetLeftmapType(wxCommandEvent&) 675void MapeditFrame::OnSetLeftmapType(wxCommandEvent&)
676{ 676{
677 wxChoice* leftmapChoice = (wxChoice*) wxWindow::FindWindowById(LEFTMAP_TYPE_CHOICE, this); 677 wxChoice* choice = (wxChoice*) wxWindow::FindWindowById(LEFTMAP_TYPE_CHOICE, this);
678 wxComboCtrl* leftmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(LEFTMAP_MAP_CHOICE, this); 678 wxComboCtrl* combo = (wxComboCtrl*) wxChoice::FindWindowById(LEFTMAP_MAP_CHOICE, this);
679 679 Map::MoveDir dir = Map::MoveDir::Left;
680 Map::MoveType old = currentMap->getLeftMoveType();
681 Map::MoveType newt = ((MoveTypeCtr*) leftmapChoice->GetClientData(leftmapChoice->GetSelection()))->type;
682 680
681 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
682 Map::MoveType newt = ((MoveTypeCtr*) choice->GetClientData(choice->GetSelection()))->type;
683 commitAction(std::make_shared<Undoable>("Set Leftmap Action", [=] () { 683 commitAction(std::make_shared<Undoable>("Set Leftmap Action", [=] () {
684 leftmapChoice->SetSelection(leftmapChoice->FindString(Map::stringForMoveType(newt))); 684 choice->SetSelection(choice->FindString(Map::stringForMoveType(newt)));
685 currentMap->setLeftMoveType(newt); 685 currentMap->setAdjacent(dir, newt);
686 leftmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getLeftMoveType())); 686 combo->Enable(Map::moveTypeTakesMap(newt));
687 }, [=] () { 687 }, [=] () {
688 leftmapChoice->SetSelection(leftmapChoice->FindString(Map::stringForMoveType(old))); 688 choice->SetSelection(choice->FindString(Map::stringForMoveType(adjacent.type)));
689 currentMap->setLeftMoveType(old); 689 currentMap->setAdjacent(dir, adjacent.type);
690 leftmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getLeftMoveType())); 690 combo->Enable(Map::moveTypeTakesMap(adjacent.type));
691 })); 691 }));
692} 692}
693 693
694void MapeditFrame::OnSetLeftmapMap(wxCommandEvent&) 694void MapeditFrame::OnSetLeftmapMap(wxCommandEvent&)
695{ 695{
696 wxComboCtrl* leftmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(LEFTMAP_MAP_CHOICE, this); 696 wxComboCtrl* combo = (wxComboCtrl*) wxWindow::FindWindowById(LEFTMAP_MAP_CHOICE, this);
697 MapSelectComboPopup* popup = (MapSelectComboPopup*) leftmapCombo->GetPopupControl(); 697 Map::MoveDir dir = Map::MoveDir::Left;
698 int old = currentMap->getLeftMoveMapID(); 698
699 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
700 MapSelectComboPopup* popup = (MapSelectComboPopup*) combo->GetPopupControl();
701 int old = adjacent.map;
699 int newt = popup->GetSelectedMapID(); 702 int newt = popup->GetSelectedMapID();
700 703
701 if (old == newt) return; 704 if (old == newt) return;
702 705
703 commitAction(std::make_shared<Undoable>("Set Leftmap Map", [=] () { 706 commitAction(std::make_shared<Undoable>("Set Leftmap Map", [=] () {
704 popup->SetSelectedMapID(newt); 707 popup->SetSelectedMapID(newt);
705 leftmapCombo->SetValue(world->getMap(newt)->getTitle()); 708 combo->SetValue(world->getMap(newt)->getTitle());
706 currentMap->setLeftMoveMapID(newt); 709 currentMap->setAdjacent(dir, adjacent.type, newt);
707 }, [=] () { 710 }, [=] () {
708 popup->SetSelectedMapID(old); 711 popup->SetSelectedMapID(old);
709 leftmapCombo->SetValue(world->getMap(old)->getTitle()); 712 combo->SetValue(world->getMap(old)->getTitle());
710 currentMap->setLeftMoveMapID(old); 713 currentMap->setAdjacent(dir, adjacent.type, old);
711 })); 714 }));
712} 715}
713 716
714void MapeditFrame::OnSetRightmapType(wxCommandEvent&) 717void MapeditFrame::OnSetRightmapType(wxCommandEvent&)
715{ 718{
716 wxChoice* rightmapChoice = (wxChoice*) wxWindow::FindWindowById(RIGHTMAP_TYPE_CHOICE, this); 719 wxChoice* choice = (wxChoice*) wxWindow::FindWindowById(RIGHTMAP_TYPE_CHOICE, this);
717 wxComboCtrl* rightmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(RIGHTMAP_MAP_CHOICE, this); 720 wxComboCtrl* combo = (wxComboCtrl*) wxChoice::FindWindowById(RIGHTMAP_MAP_CHOICE, this);
718 721 Map::MoveDir dir = Map::MoveDir::Right;
719 Map::MoveType old = currentMap->getRightMoveType();
720 Map::MoveType newt = ((MoveTypeCtr*) rightmapChoice->GetClientData(rightmapChoice->GetSelection()))->type;
721 722
723 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
724 Map::MoveType newt = ((MoveTypeCtr*) choice->GetClientData(choice->GetSelection()))->type;
722 commitAction(std::make_shared<Undoable>("Set Rightmap Action", [=] () { 725 commitAction(std::make_shared<Undoable>("Set Rightmap Action", [=] () {
723 rightmapChoice->SetSelection(rightmapChoice->FindString(Map::stringForMoveType(newt))); 726 choice->SetSelection(choice->FindString(Map::stringForMoveType(newt)));
724 currentMap->setRightMoveType(newt); 727 currentMap->setAdjacent(dir, newt);
725 rightmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getRightMoveType())); 728 combo->Enable(Map::moveTypeTakesMap(newt));
726 }, [=] () { 729 }, [=] () {
727 rightmapChoice->SetSelection(rightmapChoice->FindString(Map::stringForMoveType(old))); 730 choice->SetSelection(choice->FindString(Map::stringForMoveType(adjacent.type)));
728 currentMap->setRightMoveType(old); 731 currentMap->setAdjacent(dir, adjacent.type);
729 rightmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getRightMoveType())); 732 combo->Enable(Map::moveTypeTakesMap(adjacent.type));
730 })); 733 }));
731} 734}
732 735
733void MapeditFrame::OnSetRightmapMap(wxCommandEvent&) 736void MapeditFrame::OnSetRightmapMap(wxCommandEvent&)
734{ 737{
735 wxComboCtrl* rightmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(RIGHTMAP_MAP_CHOICE, this); 738 wxComboCtrl* combo = (wxComboCtrl*) wxWindow::FindWindowById(RIGHTMAP_MAP_CHOICE, this);
736 MapSelectComboPopup* popup = (MapSelectComboPopup*) rightmapCombo->GetPopupControl(); 739 Map::MoveDir dir = Map::MoveDir::Right;
737 int old = currentMap->getRightMoveMapID(); 740
741 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
742 MapSelectComboPopup* popup = (MapSelectComboPopup*) combo->GetPopupControl();
743 int old = adjacent.map;
738 int newt = popup->GetSelectedMapID(); 744 int newt = popup->GetSelectedMapID();
739 745
740 if (old == newt) return; 746 if (old == newt) return;
741 747
742 commitAction(std::make_shared<Undoable>("Set Rightmap Map", [=] () { 748 commitAction(std::make_shared<Undoable>("Set Rightmap Map", [=] () {
743 popup->SetSelectedMapID(newt); 749 popup->SetSelectedMapID(newt);
744 rightmapCombo->SetValue(world->getMap(newt)->getTitle()); 750 combo->SetValue(world->getMap(newt)->getTitle());
745 currentMap->setRightMoveMapID(newt); 751 currentMap->setAdjacent(dir, adjacent.type, newt);
746 }, [=] () { 752 }, [=] () {
747 popup->SetSelectedMapID(old); 753 popup->SetSelectedMapID(old);
748 rightmapCombo->SetValue(world->getMap(old)->getTitle()); 754 combo->SetValue(world->getMap(old)->getTitle());
749 currentMap->setRightMoveMapID(old); 755 currentMap->setAdjacent(dir, adjacent.type, old);
750 })); 756 }));
751} 757}
752 758
753void MapeditFrame::OnSetUpmapType(wxCommandEvent&) 759void MapeditFrame::OnSetUpmapType(wxCommandEvent&)
754{ 760{
755 wxChoice* upmapChoice = (wxChoice*) wxWindow::FindWindowById(UPMAP_TYPE_CHOICE, this); 761 wxChoice* choice = (wxChoice*) wxWindow::FindWindowById(UPMAP_TYPE_CHOICE, this);
756 wxComboCtrl* upmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(UPMAP_MAP_CHOICE, this); 762 wxComboCtrl* combo = (wxComboCtrl*) wxChoice::FindWindowById(UPMAP_MAP_CHOICE, this);
757 763 Map::MoveDir dir = Map::MoveDir::Up;
758 Map::MoveType old = currentMap->getUpMoveType();
759 Map::MoveType newt = ((MoveTypeCtr*) upmapChoice->GetClientData(upmapChoice->GetSelection()))->type;
760 764
765 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
766 Map::MoveType newt = ((MoveTypeCtr*) choice->GetClientData(choice->GetSelection()))->type;
761 commitAction(std::make_shared<Undoable>("Set Upmap Action", [=] () { 767 commitAction(std::make_shared<Undoable>("Set Upmap Action", [=] () {
762 upmapChoice->SetSelection(upmapChoice->FindString(Map::stringForMoveType(newt))); 768 choice->SetSelection(choice->FindString(Map::stringForMoveType(newt)));
763 currentMap->setUpMoveType(newt); 769 currentMap->setAdjacent(dir, newt);
764 upmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getUpMoveType())); 770 combo->Enable(Map::moveTypeTakesMap(newt));
765 }, [=] () { 771 }, [=] () {
766 upmapChoice->SetSelection(upmapChoice->FindString(Map::stringForMoveType(old))); 772 choice->SetSelection(choice->FindString(Map::stringForMoveType(adjacent.type)));
767 currentMap->setUpMoveType(old); 773 currentMap->setAdjacent(dir, adjacent.type);
768 upmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getUpMoveType())); 774 combo->Enable(Map::moveTypeTakesMap(adjacent.type));
769 })); 775 }));
770} 776}
771 777
772void MapeditFrame::OnSetUpmapMap(wxCommandEvent&) 778void MapeditFrame::OnSetUpmapMap(wxCommandEvent&)
773{ 779{
774 wxComboCtrl* upmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(UPMAP_MAP_CHOICE, this); 780 wxComboCtrl* combo = (wxComboCtrl*) wxWindow::FindWindowById(UPMAP_MAP_CHOICE, this);
775 MapSelectComboPopup* popup = (MapSelectComboPopup*) upmapCombo->GetPopupControl(); 781 Map::MoveDir dir = Map::MoveDir::Up;
776 int old = currentMap->getUpMoveMapID(); 782
783 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
784 MapSelectComboPopup* popup = (MapSelectComboPopup*) combo->GetPopupControl();
785 int old = adjacent.map;
777 int newt = popup->GetSelectedMapID(); 786 int newt = popup->GetSelectedMapID();
778 787
779 if (old == newt) return; 788 if (old == newt) return;
780 789
781 commitAction(std::make_shared<Undoable>("Set Upmap Map", [=] () { 790 commitAction(std::make_shared<Undoable>("Set Upmap Map", [=] () {
782 popup->SetSelectedMapID(newt); 791 popup->SetSelectedMapID(newt);
783 upmapCombo->SetValue(world->getMap(newt)->getTitle()); 792 combo->SetValue(world->getMap(newt)->getTitle());
784 currentMap->setUpMoveMapID(newt); 793 currentMap->setAdjacent(dir, adjacent.type, newt);
785 }, [=] () { 794 }, [=] () {
786 popup->SetSelectedMapID(old); 795 popup->SetSelectedMapID(old);
787 upmapCombo->SetValue(world->getMap(old)->getTitle()); 796 combo->SetValue(world->getMap(old)->getTitle());
788 currentMap->setUpMoveMapID(old); 797 currentMap->setAdjacent(dir, adjacent.type, old);
789 })); 798 }));
790} 799}
791 800
792void MapeditFrame::OnSetDownmapType(wxCommandEvent&) 801void MapeditFrame::OnSetDownmapType(wxCommandEvent&)
793{ 802{
794 wxChoice* downmapChoice = (wxChoice*) wxWindow::FindWindowById(DOWNMAP_TYPE_CHOICE, this); 803 wxChoice* choice = (wxChoice*) wxWindow::FindWindowById(DOWNMAP_TYPE_CHOICE, this);
795 wxComboCtrl* downmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(DOWNMAP_MAP_CHOICE, this); 804 wxComboCtrl* combo = (wxComboCtrl*) wxChoice::FindWindowById(DOWNMAP_MAP_CHOICE, this);
796 805 Map::MoveDir dir = Map::MoveDir::Down;
797 Map::MoveType old = currentMap->getDownMoveType();
798 Map::MoveType newt = ((MoveTypeCtr*) downmapChoice->GetClientData(downmapChoice->GetSelection()))->type;
799 806
807 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
808 Map::MoveType newt = ((MoveTypeCtr*) choice->GetClientData(choice->GetSelection()))->type;
800 commitAction(std::make_shared<Undoable>("Set Downmap Action", [=] () { 809 commitAction(std::make_shared<Undoable>("Set Downmap Action", [=] () {
801 downmapChoice->SetSelection(downmapChoice->FindString(Map::stringForMoveType(newt))); 810 choice->SetSelection(choice->FindString(Map::stringForMoveType(newt)));
802 currentMap->setDownMoveType(newt); 811 currentMap->setAdjacent(dir, newt);
803 downmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getDownMoveType())); 812 combo->Enable(Map::moveTypeTakesMap(newt));
804 }, [=] () { 813 }, [=] () {
805 downmapChoice->SetSelection(downmapChoice->FindString(Map::stringForMoveType(old))); 814 choice->SetSelection(choice->FindString(Map::stringForMoveType(adjacent.type)));
806 currentMap->setDownMoveType(old); 815 currentMap->setAdjacent(dir, adjacent.type);
807 downmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getDownMoveType())); 816 combo->Enable(Map::moveTypeTakesMap(adjacent.type));
808 })); 817 }));
809} 818}
810 819
811void MapeditFrame::OnSetDownmapMap(wxCommandEvent&) 820void MapeditFrame::OnSetDownmapMap(wxCommandEvent&)
812{ 821{
813 wxComboCtrl* downmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(DOWNMAP_MAP_CHOICE, this); 822 wxComboCtrl* combo = (wxComboCtrl*) wxWindow::FindWindowById(DOWNMAP_MAP_CHOICE, this);
814 MapSelectComboPopup* popup = (MapSelectComboPopup*) downmapCombo->GetPopupControl(); 823 Map::MoveDir dir = Map::MoveDir::Down;
815 int old = currentMap->getDownMoveMapID(); 824
825 Map::Adjacent adjacent = currentMap->getAdjacent(dir);
826 MapSelectComboPopup* popup = (MapSelectComboPopup*) combo->GetPopupControl();
827 int old = adjacent.map;
816 int newt = popup->GetSelectedMapID(); 828 int newt = popup->GetSelectedMapID();
817 829
818 if (old == newt) return; 830 if (old == newt) return;
819 831
820 commitAction(std::make_shared<Undoable>("Set Downmap Map", [=] () { 832 commitAction(std::make_shared<Undoable>("Set Downmap Map", [=] () {
821 popup->SetSelectedMapID(newt); 833 popup->SetSelectedMapID(newt);
822 downmapCombo->SetValue(world->getMap(newt)->getTitle()); 834 combo->SetValue(world->getMap(newt)->getTitle());
823 currentMap->setDownMoveMapID(newt); 835 currentMap->setAdjacent(dir, adjacent.type, newt);
824 }, [=] () { 836 }, [=] () {
825 popup->SetSelectedMapID(old); 837 popup->SetSelectedMapID(old);
826 downmapCombo->SetValue(world->getMap(old)->getTitle()); 838 combo->SetValue(world->getMap(old)->getTitle());
827 currentMap->setDownMoveMapID(old); 839 currentMap->setAdjacent(dir, adjacent.type, old);
828 })); 840 }));
829} 841}
830 842
@@ -924,20 +936,20 @@ void MapeditFrame::SelectMap(Map* map)
924 wxComboCtrl* upmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(UPMAP_MAP_CHOICE, this); 936 wxComboCtrl* upmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(UPMAP_MAP_CHOICE, this);
925 wxComboCtrl* downmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(DOWNMAP_MAP_CHOICE, this); 937 wxComboCtrl* downmapCombo = (wxComboCtrl*) wxWindow::FindWindowById(DOWNMAP_MAP_CHOICE, this);
926 938
927 leftmapChoice->SetSelection(leftmapChoice->FindString(Map::stringForMoveType(currentMap->getLeftMoveType()))); 939 leftmapChoice->SetSelection(leftmapChoice->FindString(Map::stringForMoveType(currentMap->getAdjacent(Map::MoveDir::Left).type)));
928 rightmapChoice->SetSelection(rightmapChoice->FindString(Map::stringForMoveType(currentMap->getRightMoveType()))); 940 rightmapChoice->SetSelection(rightmapChoice->FindString(Map::stringForMoveType(currentMap->getAdjacent(Map::MoveDir::Right).type)));
929 upmapChoice->SetSelection(upmapChoice->FindString(Map::stringForMoveType(currentMap->getUpMoveType()))); 941 upmapChoice->SetSelection(upmapChoice->FindString(Map::stringForMoveType(currentMap->getAdjacent(Map::MoveDir::Up).type)));
930 downmapChoice->SetSelection(downmapChoice->FindString(Map::stringForMoveType(currentMap->getDownMoveType()))); 942 downmapChoice->SetSelection(downmapChoice->FindString(Map::stringForMoveType(currentMap->getAdjacent(Map::MoveDir::Down).type)));
931 943
932 leftmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getLeftMoveType())); 944 leftmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getAdjacent(Map::MoveDir::Left).type));
933 rightmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getRightMoveType())); 945 rightmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getAdjacent(Map::MoveDir::Right).type));
934 upmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getUpMoveType())); 946 upmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getAdjacent(Map::MoveDir::Up).type));
935 downmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getDownMoveType())); 947 downmapCombo->Enable(Map::moveTypeTakesMap(currentMap->getAdjacent(Map::MoveDir::Down).type));
936 948
937 leftmapCombo->SetValue(world->getMap(currentMap->getLeftMoveMapID())->getTitle()); 949 leftmapCombo->SetValue(world->getMap(currentMap->getAdjacent(Map::MoveDir::Left).map)->getTitle());
938 rightmapCombo->SetValue(world->getMap(currentMap->getRightMoveMapID())->getTitle()); 950 rightmapCombo->SetValue(world->getMap(currentMap->getAdjacent(Map::MoveDir::Right).map)->getTitle());
939 upmapCombo->SetValue(world->getMap(currentMap->getUpMoveMapID())->getTitle()); 951 upmapCombo->SetValue(world->getMap(currentMap->getAdjacent(Map::MoveDir::Up).map)->getTitle());
940 downmapCombo->SetValue(world->getMap(currentMap->getDownMoveMapID())->getTitle()); 952 downmapCombo->SetValue(world->getMap(currentMap->getAdjacent(Map::MoveDir::Down).map)->getTitle());
941} 953}
942 954
943wxTreeItemId MapeditFrame::MoveTreeNode(wxTreeItemId toCopy, wxTreeItemId newParent) 955wxTreeItemId MapeditFrame::MoveTreeNode(wxTreeItemId toCopy, wxTreeItemId newParent)
diff --git a/tools/mapedit/src/map.cpp b/tools/mapedit/src/map.cpp index fb675e8..a099e29 100644 --- a/tools/mapedit/src/map.cpp +++ b/tools/mapedit/src/map.cpp
@@ -21,14 +21,7 @@ Map::Map(const Map& map)
21 treeItemId = map.treeItemId; 21 treeItemId = map.treeItemId;
22 children = map.children; 22 children = map.children;
23 hidden = map.hidden; 23 hidden = map.hidden;
24 leftType = map.leftType; 24 adjacents = map.adjacents;
25 rightType = map.rightType;
26 upType = map.upType;
27 downType = map.downType;
28 leftMap = map.leftMap;
29 rightMap = map.rightMap;
30 downMap = map.downMap;
31 upMap = map.upMap;
32} 25}
33 26
34Map::Map(Map&& map) : Map(-1, map.world) 27Map::Map(Map&& map) : Map(-1, map.world)
@@ -58,14 +51,7 @@ void swap(Map& first, Map& second)
58 std::swap(first.treeItemId, second.treeItemId); 51 std::swap(first.treeItemId, second.treeItemId);
59 std::swap(first.children, second.children); 52 std::swap(first.children, second.children);
60 std::swap(first.hidden, second.hidden); 53 std::swap(first.hidden, second.hidden);
61 std::swap(first.leftType, second.leftType); 54 std::swap(first.adjacents, second.adjacents);
62 std::swap(first.rightType, second.rightType);
63 std::swap(first.upType, second.upType);
64 std::swap(first.downType, second.downType);
65 std::swap(first.leftMap, second.leftMap);
66 std::swap(first.rightMap, second.rightMap);
67 std::swap(first.downMap, second.downMap);
68 std::swap(first.upMap, second.upMap);
69} 55}
70 56
71std::list<Map::MoveType> Map::listMoveTypes() 57std::list<Map::MoveType> Map::listMoveTypes()
@@ -78,9 +64,9 @@ std::string Map::stringForMoveType(MoveType type)
78 switch (type) 64 switch (type)
79 { 65 {
80 case MoveType::Wall: return "Wall"; 66 case MoveType::Wall: return "Wall";
81 case MoveType::Warp: return "Warp"; 67 case MoveType::Warp: return "Teleport";
82 case MoveType::Wrap: return "Wrap"; 68 case MoveType::Wrap: return "Wrap";
83 case MoveType::ReverseWarp: return "Reverse Warp"; 69 case MoveType::ReverseWarp: return "Reverse Teleport";
84 } 70 }
85} 71}
86 72
@@ -106,6 +92,17 @@ std::string Map::shortForMoveType(MoveType type)
106 } 92 }
107} 93}
108 94
95std::string Map::shortForMoveDir(MoveDir dir)
96{
97 switch (dir)
98 {
99 case MoveDir::Left: return "left";
100 case MoveDir::Right: return "right";
101 case MoveDir::Up: return "up";
102 case MoveDir::Down: return "down";
103 }
104}
105
109Map::MoveType Map::moveTypeForShort(std::string str) 106Map::MoveType Map::moveTypeForShort(std::string str)
110{ 107{
111 if (str == "wrap") return MoveType::Wrap; 108 if (str == "wrap") return MoveType::Wrap;
@@ -115,6 +112,15 @@ Map::MoveType Map::moveTypeForShort(std::string str)
115 return MoveType::Wall; 112 return MoveType::Wall;
116} 113}
117 114
115Map::MoveDir Map::moveDirForShort(std::string str)
116{
117 if (str == "right") return MoveDir::Right;
118 if (str == "up") return MoveDir::Up;
119 if (str == "down") return MoveDir::Down;
120
121 return MoveDir::Left;
122}
123
118int Map::getID() const 124int Map::getID() const
119{ 125{
120 return id; 126 return id;
@@ -167,47 +173,21 @@ bool Map::getHidden() const
167 return hidden; 173 return hidden;
168} 174}
169 175
170Map::MoveType Map::getLeftMoveType() const 176const std::map<Map::MoveDir, Map::Adjacent>& Map::getAdjacents() const
171{
172 return leftType;
173}
174
175Map::MoveType Map::getRightMoveType() const
176{
177 return rightType;
178}
179
180Map::MoveType Map::getUpMoveType() const
181{ 177{
182 return upType; 178 return adjacents;
183} 179}
184 180
185Map::MoveType Map::getDownMoveType() const 181const Map::Adjacent& Map::getAdjacent(MoveDir direction) const
186{ 182{
187 return downType; 183 if (adjacents.count(direction) > 0)
188} 184 {
189 185 return adjacents.at(direction);
190int Map::getLeftMoveMapID() const 186 } else {
191{ 187 return defaultAdjacent;
192 return leftMap; 188 }
193}
194
195int Map::getRightMoveMapID() const
196{
197 return rightMap;
198}
199
200int Map::getUpMoveMapID() const
201{
202 return upMap;
203}
204
205int Map::getDownMoveMapID() const
206{
207 return downMap;
208} 189}
209 190
210
211void Map::setTitle(std::string title, bool dirty) 191void Map::setTitle(std::string title, bool dirty)
212{ 192{
213 this->title = title; 193 this->title = title;
@@ -279,79 +259,11 @@ void Map::setHidden(bool hid)
279 hidden = hid; 259 hidden = hid;
280} 260}
281 261
282void Map::setLeftMoveType(Map::MoveType move, bool dirty) 262void Map::setAdjacent(MoveDir direction, MoveType type, int map, bool dirty)
283{
284 leftType = move;
285
286 if (dirty)
287 {
288 world->setDirty(true);
289 }
290}
291
292void Map::setRightMoveType(Map::MoveType move, bool dirty)
293{
294 rightType = move;
295
296 if (dirty)
297 {
298 world->setDirty(true);
299 }
300}
301
302void Map::setUpMoveType(Map::MoveType move, bool dirty)
303{
304 upType = move;
305
306 if (dirty)
307 {
308 world->setDirty(true);
309 }
310}
311
312void Map::setDownMoveType(Map::MoveType move, bool dirty)
313{
314 downType = move;
315
316 if (dirty)
317 {
318 world->setDirty(true);
319 }
320}
321
322void Map::setLeftMoveMapID(int id, bool dirty)
323{
324 leftMap = id;
325
326 if (dirty)
327 {
328 world->setDirty(true);
329 }
330}
331
332void Map::setRightMoveMapID(int id, bool dirty)
333{
334 rightMap = id;
335
336 if (dirty)
337 {
338 world->setDirty(true);
339 }
340}
341
342void Map::setUpMoveMapID(int id, bool dirty)
343{
344 upMap = id;
345
346 if (dirty)
347 {
348 world->setDirty(true);
349 }
350}
351
352void Map::setDownMoveMapID(int id, bool dirty)
353{ 263{
354 downMap = id; 264 Adjacent& cur = adjacents[direction];
265 cur.type = type;
266 if (map != -1) cur.map = map;
355 267
356 if (dirty) 268 if (dirty)
357 { 269 {
diff --git a/tools/mapedit/src/map.h b/tools/mapedit/src/map.h index 46e5790..c7f5b30 100644 --- a/tools/mapedit/src/map.h +++ b/tools/mapedit/src/map.h
@@ -7,6 +7,7 @@
7#include <list> 7#include <list>
8#include <memory> 8#include <memory>
9#include <wx/treectrl.h> 9#include <wx/treectrl.h>
10#include <map>
10 11
11class MapObject; 12class MapObject;
12class World; 13class World;
@@ -64,6 +65,13 @@ class Map {
64 Map& operator= (Map other); 65 Map& operator= (Map other);
65 friend void swap(Map& first, Map& second); 66 friend void swap(Map& first, Map& second);
66 67
68 enum class MoveDir {
69 Left,
70 Right,
71 Up,
72 Down
73 };
74
67 enum class MoveType { 75 enum class MoveType {
68 Wall, 76 Wall,
69 Wrap, 77 Wrap,
@@ -71,11 +79,18 @@ class Map {
71 ReverseWarp 79 ReverseWarp
72 }; 80 };
73 81
82 struct Adjacent {
83 MoveType type = MoveType::Wall;
84 int map = 0;
85 };
86
74 static std::list<MoveType> listMoveTypes(); 87 static std::list<MoveType> listMoveTypes();
75 static std::string stringForMoveType(MoveType type); 88 static std::string stringForMoveType(MoveType type);
76 static bool moveTypeTakesMap(MoveType type); 89 static bool moveTypeTakesMap(MoveType type);
77 static std::string shortForMoveType(MoveType type); 90 static std::string shortForMoveType(MoveType type);
91 static std::string shortForMoveDir(MoveDir dir);
78 static MoveType moveTypeForShort(std::string str); 92 static MoveType moveTypeForShort(std::string str);
93 static MoveDir moveDirForShort(std::string str);
79 94
80 int getID() const; 95 int getID() const;
81 std::string getTitle() const; 96 std::string getTitle() const;
@@ -86,14 +101,8 @@ class Map {
86 bool getExpanded() const; 101 bool getExpanded() const;
87 World* getWorld() const; 102 World* getWorld() const;
88 bool getHidden() const; 103 bool getHidden() const;
89 MoveType getLeftMoveType() const; 104 const std::map<MoveDir, Adjacent>& getAdjacents() const;
90 MoveType getRightMoveType() const; 105 const Adjacent& getAdjacent(MoveDir direction) const;
91 MoveType getUpMoveType() const;
92 MoveType getDownMoveType() const;
93 int getLeftMoveMapID() const;
94 int getRightMoveMapID() const;
95 int getUpMoveMapID() const;
96 int getDownMoveMapID() const;
97 106
98 void setTitle(std::string title, bool dirty = true); 107 void setTitle(std::string title, bool dirty = true);
99 void setTileAt(int x, int y, int tile, bool dirty = true); 108 void setTileAt(int x, int y, int tile, bool dirty = true);
@@ -104,14 +113,7 @@ class Map {
104 void addChild(int id); 113 void addChild(int id);
105 void setExpanded(bool exp); 114 void setExpanded(bool exp);
106 void setHidden(bool hid); 115 void setHidden(bool hid);
107 void setLeftMoveType(MoveType move, bool dirty = true); 116 void setAdjacent(MoveDir direction, MoveType type, int map = -1, bool dirty = true);
108 void setRightMoveType(MoveType move, bool dirty = true);
109 void setUpMoveType(MoveType move, bool dirty = true);
110 void setDownMoveType(MoveType move, bool dirty = true);
111 void setLeftMoveMapID(int id, bool dirty = true);
112 void setRightMoveMapID(int id, bool dirty = true);
113 void setUpMoveMapID(int id, bool dirty = true);
114 void setDownMoveMapID(int id, bool dirty = true);
115 117
116 private: 118 private:
117 int id; 119 int id;
@@ -123,14 +125,8 @@ class Map {
123 wxTreeItemId treeItemId; 125 wxTreeItemId treeItemId;
124 bool expanded = false; 126 bool expanded = false;
125 bool hidden = false; 127 bool hidden = false;
126 MoveType leftType = MoveType::Wall; 128 std::map<MoveDir, Adjacent> adjacents;
127 MoveType rightType = MoveType::Wall; 129 const Adjacent defaultAdjacent {};
128 MoveType upType = MoveType::Wall;
129 MoveType downType = MoveType::Wall;
130 int leftMap = 0;
131 int rightMap = 0;
132 int upMap = 0;
133 int downMap = 0;
134}; 130};
135 131
136class MapPtrCtr : public wxTreeItemData { 132class MapPtrCtr : public wxTreeItemData {
diff --git a/tools/mapedit/src/widget.cpp b/tools/mapedit/src/widget.cpp index 7f90880..fa0af39 100644 --- a/tools/mapedit/src/widget.cpp +++ b/tools/mapedit/src/widget.cpp
@@ -75,30 +75,30 @@ void MapeditWidget::OnPaint(wxPaintEvent&)
75 75
76 RenderMap(map, dc, tiles_dc); 76 RenderMap(map, dc, tiles_dc);
77 77
78 if (map->getLeftMoveType() == Map::MoveType::Warp) 78 if (map->getAdjacent(Map::MoveDir::Left).type == Map::MoveType::Warp)
79 { 79 {
80 auto tomap = map->getWorld()->getMap(map->getLeftMoveMapID()); 80 auto tomap = map->getWorld()->getMap(map->getAdjacent(Map::MoveDir::Left).map);
81 81
82 RenderMap(tomap.get(), dc, tiles_dc, -EDITOR_SPACING_X, EDITOR_SPACING_Y, false); 82 RenderMap(tomap.get(), dc, tiles_dc, -EDITOR_SPACING_X, EDITOR_SPACING_Y, false);
83 } 83 }
84 84
85 if (map->getRightMoveType() == Map::MoveType::Warp) 85 if (map->getAdjacent(Map::MoveDir::Right).type == Map::MoveType::Warp)
86 { 86 {
87 auto tomap = map->getWorld()->getMap(map->getRightMoveMapID()); 87 auto tomap = map->getWorld()->getMap(map->getAdjacent(Map::MoveDir::Right).map);
88 88
89 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_WIDTH-EDITOR_SPACING_X, EDITOR_SPACING_Y, false); 89 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_WIDTH-EDITOR_SPACING_X, EDITOR_SPACING_Y, false);
90 } 90 }
91 91
92 if (map->getUpMoveType() == Map::MoveType::Warp) 92 if (map->getAdjacent(Map::MoveDir::Up).type == Map::MoveType::Warp)
93 { 93 {
94 auto tomap = map->getWorld()->getMap(map->getUpMoveMapID()); 94 auto tomap = map->getWorld()->getMap(map->getAdjacent(Map::MoveDir::Up).map);
95 95
96 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_SPACING_X, -EDITOR_SPACING_Y, false); 96 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_SPACING_X, -EDITOR_SPACING_Y, false);
97 } 97 }
98 98
99 if (map->getDownMoveType() == Map::MoveType::Warp) 99 if (map->getAdjacent(Map::MoveDir::Down).type == Map::MoveType::Warp)
100 { 100 {
101 auto tomap = map->getWorld()->getMap(map->getDownMoveMapID()); 101 auto tomap = map->getWorld()->getMap(map->getAdjacent(Map::MoveDir::Down).map);
102 102
103 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_SPACING_X, EDITOR_HEIGHT-EDITOR_SPACING_Y, false); 103 RenderMap(tomap.get(), dc, tiles_dc, EDITOR_SPACING_X, EDITOR_HEIGHT-EDITOR_SPACING_Y, false);
104 } 104 }
diff --git a/tools/mapedit/src/world.cpp b/tools/mapedit/src/world.cpp index 043cf8a..01225cf 100644 --- a/tools/mapedit/src/world.cpp +++ b/tools/mapedit/src/world.cpp
@@ -36,43 +36,43 @@ World::World(std::string filename)
36 throw MapLoadException(filename); 36 throw MapLoadException(filename);
37 } 37 }
38 38
39 xmlChar* nextmapKey = xmlGetProp(top, (xmlChar*) "nextmap");
40 if (nextmapKey != 0)
41 {
42 nextMapID = atoi((char*) nextmapKey);
43 }
44 xmlFree(nextmapKey);
45
46 xmlChar* lastmapKey = xmlGetProp(top, (xmlChar*) "lastmap");
47 if (lastmapKey != 0)
48 {
49 lastmap = atoi((char*) lastmapKey);
50 }
51 xmlFree(lastmapKey);
52
53 xmlChar* startxKey = xmlGetProp(top, (xmlChar*) "startx");
54 if (startxKey == 0) throw MapLoadException(filename);
55 startingPosition.first = atoi((char*) startxKey);
56 xmlFree(startxKey);
57
58 xmlChar* startyKey = xmlGetProp(top, (xmlChar*) "starty");
59 if (startyKey == 0) throw MapLoadException(filename);
60 startingPosition.second = atoi((char*) startyKey);
61 xmlFree(startyKey);
62
63 xmlChar* startmapKey = xmlGetProp(top, (xmlChar*) "startmap");
64 if (startxKey == 0) throw MapLoadException(filename);
65 startingMap = atoi((char*) startmapKey);
66 xmlFree(startmapKey);
67
39 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) 68 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
40 { 69 {
41 if (!xmlStrcmp(node->name, (const xmlChar*) "nextmapid")) 70 if (!xmlStrcmp(node->name, (const xmlChar*) "root"))
42 {
43 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
44 if (key != 0)
45 {
46 nextMapID = atoi((char*) key);
47 }
48 xmlFree(key);
49 } else if (!xmlStrcmp(node->name, (const xmlChar*) "lastmap"))
50 { 71 {
51 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); 72 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
52 if (key != 0) 73 if (key == 0) throw MapLoadException(filename);
53 { 74 rootChildren.push_back(atoi((char*) key));
54 lastmap = atoi((char*) key);
55 }
56 xmlFree(key); 75 xmlFree(key);
57 } else if (!xmlStrcmp(node->name, (const xmlChar*) "root"))
58 {
59 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
60 if (key != 0)
61 {
62 rootChildren.push_back(atoi((char*) key));
63 }
64 xmlFree(key);
65 } else if (!xmlStrcmp(node->name, (const xmlChar*) "startpos"))
66 {
67 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
68 if (idKey == 0) throw MapLoadException(filename);
69 startingMap = atoi((char*) idKey);
70 xmlFree(idKey);
71
72 xmlChar* posKey = xmlGetProp(node, (xmlChar*) "pos");
73 if (posKey == 0) throw MapLoadException(filename);
74 sscanf((char*) posKey, "%d,%d", &startingPosition.first, &startingPosition.second);
75 xmlFree(posKey);
76 } else if (!xmlStrcmp(node->name, (const xmlChar*) "map")) 76 } else if (!xmlStrcmp(node->name, (const xmlChar*) "map"))
77 { 77 {
78 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id"); 78 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
@@ -82,18 +82,21 @@ World::World(std::string filename)
82 82
83 auto map = std::make_shared<Map>(id, this); 83 auto map = std::make_shared<Map>(id, this);
84 84
85 xmlChar* expandKey = xmlGetProp(node, (xmlChar*) "expanded");
86 if ((expandKey != 0) && (!xmlStrcmp(expandKey, (const xmlChar*) "true")))
87 {
88 map->setExpanded(true);
89 }
90 xmlFree(expandKey);
91
92 xmlChar* titleKey = xmlGetProp(node, (xmlChar*) "title");
93 if (titleKey == 0) throw MapLoadException(filename);
94 map->setTitle((char*) titleKey, false);
95 xmlFree(titleKey);
96
85 for (xmlNodePtr mapNode = node->xmlChildrenNode; mapNode != NULL; mapNode = mapNode->next) 97 for (xmlNodePtr mapNode = node->xmlChildrenNode; mapNode != NULL; mapNode = mapNode->next)
86 { 98 {
87 if (!xmlStrcmp(mapNode->name, (const xmlChar*) "name")) 99 if (!xmlStrcmp(mapNode->name, (const xmlChar*) "environment"))
88 {
89 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
90 if (key != 0)
91 {
92 map->setTitle((char*) key, false);
93 }
94
95 xmlFree(key);
96 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "environment"))
97 { 100 {
98 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1); 101 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
99 int* mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int)); 102 int* mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
@@ -104,88 +107,50 @@ World::World(std::string filename)
104 } 107 }
105 map->setMapdata(mapdata, false); 108 map->setMapdata(mapdata, false);
106 xmlFree(key); 109 xmlFree(key);
107 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "leftmap")) 110 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "entity"))
108 { 111 {
109 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type"); 112 auto data = std::make_shared<MapObjectEntry>();
110 if (typeKey == 0) throw MapLoadException(filename);
111 map->setLeftMoveType(Map::moveTypeForShort((char*) typeKey), false);
112 xmlFree(typeKey);
113 113
114 if (Map::moveTypeTakesMap(map->getLeftMoveType())) 114 xmlChar* typeKey = xmlGetProp(mapNode, (const xmlChar*) "type");
115 {
116 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
117 if (idKey == 0) throw MapLoadException(filename);
118 map->setLeftMoveMapID(atoi((char*) idKey), false);
119 xmlFree(idKey);
120 }
121 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "rightmap"))
122 {
123 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
124 if (typeKey == 0) throw MapLoadException(filename); 115 if (typeKey == 0) throw MapLoadException(filename);
125 map->setRightMoveType(Map::moveTypeForShort((char*) typeKey), false); 116 data->object = MapObject::getAllObjects().at((char*) typeKey).get();
126 xmlFree(typeKey); 117 xmlFree(typeKey);
127 118
128 if (Map::moveTypeTakesMap(map->getRightMoveType())) 119 xmlChar* xKey = xmlGetProp(mapNode, (const xmlChar*) "x");
129 { 120 if (xKey == 0) throw MapLoadException(filename);
130 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map"); 121 data->position.first = atoi((char*) xKey);
131 if (idKey == 0) throw MapLoadException(filename); 122 xmlFree(xKey);
132 map->setRightMoveMapID(atoi((char*) idKey), false);
133 xmlFree(idKey);
134 }
135 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "upmap"))
136 {
137 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
138 if (typeKey == 0) throw MapLoadException(filename);
139 map->setUpMoveType(Map::moveTypeForShort((char*) typeKey), false);
140 xmlFree(typeKey);
141 123
142 if (Map::moveTypeTakesMap(map->getUpMoveType())) 124 xmlChar* yKey = xmlGetProp(mapNode, (const xmlChar*) "y");
143 { 125 if (yKey == 0) throw MapLoadException(filename);
144 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map"); 126 data->position.second = atoi((char*) yKey);
145 if (idKey == 0) throw MapLoadException(filename); 127 xmlFree(yKey);
146 map->setUpMoveMapID(atoi((char*) idKey), false); 128
147 xmlFree(idKey); 129 map->addObject(data, false);
148 } 130 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "adjacent"))
149 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "downmap"))
150 { 131 {
151 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type"); 132 Map::MoveDir direction;
133 Map::MoveType moveType;
134 int mapId = 0;
135
136 xmlChar* dirKey = xmlGetProp(mapNode, (const xmlChar*) "dir");
137 if (dirKey == 0) throw MapLoadException(filename);
138 direction = Map::moveDirForShort((char*) dirKey);
139 xmlFree(dirKey);
140
141 xmlChar* typeKey = xmlGetProp(mapNode, (const xmlChar*) "type");
152 if (typeKey == 0) throw MapLoadException(filename); 142 if (typeKey == 0) throw MapLoadException(filename);
153 map->setDownMoveType(Map::moveTypeForShort((char*) typeKey), false); 143 moveType = Map::moveTypeForShort((char*) typeKey);
154 xmlFree(typeKey); 144 xmlFree(typeKey);
155 145
156 if (Map::moveTypeTakesMap(map->getDownMoveType())) 146 xmlChar* mapIdKey = xmlGetProp(mapNode, (const xmlChar*) "map");
147 if (mapIdKey != 0)
157 { 148 {
158 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map"); 149 mapId = atoi((char*) mapIdKey);
159 if (idKey == 0) throw MapLoadException(filename);
160 map->setDownMoveMapID(atoi((char*) idKey), false);
161 xmlFree(idKey);
162 } 150 }
163 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "entities")) 151 xmlFree(mapIdKey);
164 {
165 for (xmlNodePtr entityNode = mapNode->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next)
166 {
167 if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity"))
168 {
169 auto data = std::make_shared<MapObjectEntry>();
170 152
171 for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next) 153 map->setAdjacent(direction, moveType, mapId, false);
172 {
173 if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type"))
174 {
175 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
176 data->object = MapObject::getAllObjects().at((char*) key).get();
177 xmlFree(key);
178 } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position"))
179 {
180 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
181 sscanf((char*) key, "%d,%d", &data->position.first, &data->position.second);
182 xmlFree(key);
183 }
184 }
185
186 map->addObject(data, false);
187 }
188 }
189 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "child")) 154 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "child"))
190 { 155 {
191 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1); 156 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
@@ -194,13 +159,6 @@ World::World(std::string filename)
194 map->addChild(atoi((char*) key)); 159 map->addChild(atoi((char*) key));
195 } 160 }
196 xmlFree(key); 161 xmlFree(key);
197 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "expanded"))
198 {
199 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
200 if ((key != 0) && ((char) key[0] == '1'))
201 {
202 map->setExpanded(true);
203 }
204 } 162 }
205 } 163 }
206 164
@@ -266,16 +224,24 @@ void World::save(std::string name, wxTreeCtrl* mapTree)
266 rc = xmlTextWriterStartElement(writer, (xmlChar*) "world"); 224 rc = xmlTextWriterStartElement(writer, (xmlChar*) "world");
267 if (rc < 0) throw MapWriteException(name); 225 if (rc < 0) throw MapWriteException(name);
268 226
269 // <nextmapid/> 227 // nextmap=
270 std::ostringstream nextMap_out; 228 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "nextmap", "%d", nextMapID);
271 nextMap_out << nextMapID; 229 if (rc < 0) throw MapWriteException(name);
272 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "nextmapid", (xmlChar*) nextMap_out.str().c_str()); 230
231 // lastmap=
232 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "lastmap", "%d", lastmap);
233 if (rc < 0) throw MapWriteException(name);
234
235 // startx=
236 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "startx", "%d", startingPosition.first);
273 if (rc < 0) throw MapWriteException(name); 237 if (rc < 0) throw MapWriteException(name);
274 238
275 // <lastmap/> 239 // starty=
276 std::ostringstream lastMap_out; 240 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "starty", "%d", startingPosition.second);
277 lastMap_out << lastmap; 241 if (rc < 0) throw MapWriteException(name);
278 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "lastmap", (xmlChar*) lastMap_out.str().c_str()); 242
243 // startmap=
244 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "startmap", "%d", startingMap);
279 if (rc < 0) throw MapWriteException(name); 245 if (rc < 0) throw MapWriteException(name);
280 246
281 // ASSUMPTION: There will always be at least one child of the invisible root element. i.e. you cannot delete to zero maps. 247 // ASSUMPTION: There will always be at least one child of the invisible root element. i.e. you cannot delete to zero maps.
@@ -285,28 +251,10 @@ void World::save(std::string name, wxTreeCtrl* mapTree)
285 { 251 {
286 // <root> 252 // <root>
287 MapPtrCtr* ctl = (MapPtrCtr*) mapTree->GetItemData(it); 253 MapPtrCtr* ctl = (MapPtrCtr*) mapTree->GetItemData(it);
288 std::ostringstream rootid_out; 254 rc = xmlTextWriterWriteFormatElement(writer, (xmlChar*) "root", "%d", ctl->map->getID());
289 rootid_out << ctl->map->getID();
290 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "root", (xmlChar*) rootid_out.str().c_str());
291 if (rc < 0) throw MapWriteException(name); 255 if (rc < 0) throw MapWriteException(name);
292 } 256 }
293 257
294 // <startpos/>
295 rc = xmlTextWriterStartElement(writer, (xmlChar*) "startpos");
296 if (rc < 0) throw MapWriteException(name);
297
298 // id=
299 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "id", "%d", startingMap);
300 if (rc < 0) throw MapWriteException(name);
301
302 // pos=
303 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "pos", "%d,%d", startingPosition.first, startingPosition.second);
304 if (rc < 0) throw MapWriteException(name);
305
306 // </startpos>
307 rc = xmlTextWriterEndElement(writer);
308 if (rc < 0) throw MapWriteException(name);
309
310 for (auto mapPair : maps) 258 for (auto mapPair : maps)
311 { 259 {
312 Map& map = *mapPair.second; 260 Map& map = *mapPair.second;
@@ -318,16 +266,33 @@ void World::save(std::string name, wxTreeCtrl* mapTree)
318 if (rc < 0) throw MapWriteException(name); 266 if (rc < 0) throw MapWriteException(name);
319 267
320 // id= 268 // id=
321 std::ostringstream id_out; 269 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "id", "%d", map.getID());
322 id_out << map.getID();
323 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "id", (xmlChar*) id_out.str().c_str());
324 if (rc < 0) throw MapWriteException(name); 270 if (rc < 0) throw MapWriteException(name);
325 271
326 // <name/> 272 // expanded=
327 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "name", (xmlChar*) map.getTitle().c_str()); 273 wxTreeItemId node = map.getTreeItemId();
274 if (mapTree->IsExpanded(node))
275 {
276 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "expanded", (xmlChar*) "true");
277 if (rc < 0) throw MapWriteException(name);
278 } else {
279 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "expanded", (xmlChar*) "false");
280 if (rc < 0) throw MapWriteException(name);
281 }
282
283 // title=
284 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "name", (xmlChar*) map.getTitle().c_str());
328 if (rc < 0) throw MapWriteException(name); 285 if (rc < 0) throw MapWriteException(name);
329 286
330 // <environment/> 287 // <environment
288 rc = xmlTextWriterStartElement(writer, (xmlChar*) "environment");
289 if (rc < 0) throw MapWriteException(name);
290
291 // type=
292 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "type", (xmlChar*) "0");
293 if (rc < 0) throw MapWriteException(name);
294
295 // >
331 std::ostringstream mapdata_out; 296 std::ostringstream mapdata_out;
332 for (int y=0; y<MAP_HEIGHT; y++) 297 for (int y=0; y<MAP_HEIGHT; y++)
333 { 298 {
@@ -341,113 +306,60 @@ void World::save(std::string name, wxTreeCtrl* mapTree)
341 306
342 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "environment", (xmlChar*) mapdata_out.str().c_str()); 307 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "environment", (xmlChar*) mapdata_out.str().c_str());
343 if (rc < 0) throw MapWriteException(name); 308 if (rc < 0) throw MapWriteException(name);
344
345 // <leftmap/>
346 rc = xmlTextWriterStartElement(writer, (xmlChar*) "leftmap");
347 if (rc < 0) throw MapWriteException(name);
348 309
349 // type= 310 // </environment>
350 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "type", "%s", Map::shortForMoveType(map.getLeftMoveType()).c_str());
351 if (rc < 0) throw MapWriteException(name);
352
353 if (Map::moveTypeTakesMap(map.getLeftMoveType()))
354 {
355 // map=
356 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "map", "%d", map.getLeftMoveMapID());
357 if (rc < 0) throw MapWriteException(name);
358 }
359
360 // </leftmap>
361 rc = xmlTextWriterEndElement(writer); 311 rc = xmlTextWriterEndElement(writer);
362 if (rc < 0) throw MapWriteException(name); 312 if (rc < 0) throw MapWriteException(name);
363 313
364 // <rightmap/> 314 for (auto object : map.getObjects())
365 rc = xmlTextWriterStartElement(writer, (xmlChar*) "rightmap");
366 if (rc < 0) throw MapWriteException(name);
367
368 // type=
369 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "type", "%s", Map::shortForMoveType(map.getRightMoveType()).c_str());
370 if (rc < 0) throw MapWriteException(name);
371
372 if (Map::moveTypeTakesMap(map.getRightMoveType()))
373 { 315 {
374 // map= 316 // <entity>
375 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "map", "%d", map.getRightMoveMapID()); 317 rc = xmlTextWriterStartElement(writer, (xmlChar*) "entity");
376 if (rc < 0) throw MapWriteException(name); 318 if (rc < 0) throw MapWriteException(name);
377 }
378
379 // </rightmap>
380 rc = xmlTextWriterEndElement(writer);
381 if (rc < 0) throw MapWriteException(name);
382 319
383 // <upmap/> 320 // type=
384 rc = xmlTextWriterStartElement(writer, (xmlChar*) "upmap"); 321 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "type", (xmlChar*) object->object->getType().c_str());
385 if (rc < 0) throw MapWriteException(name);
386
387 // type=
388 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "type", "%s", Map::shortForMoveType(map.getUpMoveType()).c_str());
389 if (rc < 0) throw MapWriteException(name);
390
391 if (Map::moveTypeTakesMap(map.getUpMoveType()))
392 {
393 // map=
394 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "map", "%d", map.getUpMoveMapID());
395 if (rc < 0) throw MapWriteException(name); 322 if (rc < 0) throw MapWriteException(name);
396 }
397
398 // </upmap>
399 rc = xmlTextWriterEndElement(writer);
400 if (rc < 0) throw MapWriteException(name);
401 323
402 // <downmap/> 324 // x=
403 rc = xmlTextWriterStartElement(writer, (xmlChar*) "downmap"); 325 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "x", "%d", object->position.first);
404 if (rc < 0) throw MapWriteException(name); 326 if (rc < 0) throw MapWriteException(name);
405 327
406 // type= 328 // y=
407 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "type", "%s", Map::shortForMoveType(map.getDownMoveType()).c_str()); 329 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "y", "%d", object->position.second);
408 if (rc < 0) throw MapWriteException(name); 330 if (rc < 0) throw MapWriteException(name);
409 331
410 if (Map::moveTypeTakesMap(map.getDownMoveType())) 332 // </entity>
411 { 333 rc = xmlTextWriterEndElement(writer);
412 // map=
413 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "map", "%d", map.getDownMoveMapID());
414 if (rc < 0) throw MapWriteException(name); 334 if (rc < 0) throw MapWriteException(name);
415 } 335 }
416 336
417 // </downmap> 337 for (auto adjacent : map.getAdjacents())
418 rc = xmlTextWriterEndElement(writer);
419 if (rc < 0) throw MapWriteException(name);
420
421 // <entities>
422 rc = xmlTextWriterStartElement(writer, (xmlChar*) "entities");
423 if (rc < 0) throw MapWriteException(name);
424
425 for (auto object : map.getObjects())
426 { 338 {
427 // <entity> 339 // <adjacent>
428 rc = xmlTextWriterStartElement(writer, (xmlChar*) "entity"); 340 rc = xmlTextWriterStartElement(writer, (xmlChar*) "adjacent");
429 if (rc < 0) throw MapWriteException(name); 341 if (rc < 0) throw MapWriteException(name);
430 342
431 // <entity-type/> 343 // dir=
432 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-type", (xmlChar*) object->object->getType().c_str()); 344 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "dir", (xmlChar*) Map::shortForMoveDir(adjacent.first).c_str());
433 if (rc < 0) throw MapWriteException(name); 345 if (rc < 0) throw MapWriteException(name);
434 346
435 // <entity-position/> 347 // type=
436 std::ostringstream entpos_out; 348 rc = xmlTextWriterWriteAttribute(writer, (xmlChar*) "type", (xmlChar*) Map::shortForMoveType(adjacent.second.type).c_str());
437 entpos_out << object->position.first << "," << object->position.second;
438 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-position", (xmlChar*) entpos_out.str().c_str());
439 if (rc < 0) throw MapWriteException(name); 349 if (rc < 0) throw MapWriteException(name);
440 350
441 // </entity> 351 // map=
352 if (Map::moveTypeTakesMap(adjacent.second.type))
353 {
354 rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*) "map", "%d", adjacent.second.map);
355 if (rc < 0) throw MapWriteException(name);
356 }
357
358 // </adjacent>
442 rc = xmlTextWriterEndElement(writer); 359 rc = xmlTextWriterEndElement(writer);
443 if (rc < 0) throw MapWriteException(name); 360 if (rc < 0) throw MapWriteException(name);
444 } 361 }
445
446 // </entities>
447 rc = xmlTextWriterEndElement(writer);
448 if (rc < 0) throw MapWriteException(name);
449 362
450 wxTreeItemId node = map.getTreeItemId();
451 if (mapTree->ItemHasChildren(node)) 363 if (mapTree->ItemHasChildren(node))
452 { 364 {
453 wxTreeItemIdValue cookie2; 365 wxTreeItemIdValue cookie2;
@@ -455,16 +367,7 @@ void World::save(std::string name, wxTreeCtrl* mapTree)
455 { 367 {
456 // <child/> 368 // <child/>
457 MapPtrCtr* ctl = (MapPtrCtr*) mapTree->GetItemData(it); 369 MapPtrCtr* ctl = (MapPtrCtr*) mapTree->GetItemData(it);
458 std::ostringstream childid_out; 370 rc = xmlTextWriterWriteFormatElement(writer, (xmlChar*) "child", "%d", ctl->map->getID());
459 childid_out << ctl->map->getID();
460 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "child", (xmlChar*) childid_out.str().c_str());
461 if (rc < 0) throw MapWriteException(name);
462 }
463
464 if (mapTree->IsExpanded(node))
465 {
466 // <expanded/>
467 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "expanded", (xmlChar*) "1");
468 if (rc < 0) throw MapWriteException(name); 371 if (rc < 0) throw MapWriteException(name);
469 } 372 }
470 } 373 }