1 /** @file episode.cpp  Episode definition accessor.
2  *
3  * @authors Copyright © 2014 Daniel Swanson <danij@dengine.net>
4  *
5  * @par License
6  * GPL: http://www.gnu.org/licenses/gpl.html
7  *
8  * <small>This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version. This program is distributed in the hope that it
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details. You should have received a copy of the GNU
15  * General Public License along with this program; if not, see:
16  * http://www.gnu.org/licenses</small>
17  */
18 
19 #include "doomsday/defs/episode.h"
20 #include "doomsday/defs/ded.h"
21 
22 #include <de/Record>
23 #include <de/RecordValue>
24 
25 using namespace de;
26 
27 namespace defn {
28 
resetToDefaults()29 void Episode::resetToDefaults()
30 {
31     Definition::resetToDefaults();
32 
33     // Add all expected fields with their default values.
34     def().addText(VAR_ID, "");
35     def().addText("startMap", "Maps:"); // URI. Unknown.
36     def().addText("title", "Untitled");
37     def().addText("menuHelpInfo", "");  // None.
38     def().addText("menuImage", "");     // URI. None.
39     def().addText("menuShortcut", "");  // Key name. None.
40     def().addArray("hub", new ArrayValue);
41     def().addArray("map", new ArrayValue);
42 }
43 
addHub()44 Record &Episode::addHub()
45 {
46     Record *hub = new Record;
47 
48     hub->addBoolean("custom", false);
49 
50     hub->addText (VAR_ID, "");
51     hub->addArray("map", new ArrayValue);
52 
53     def()["hub"].array().add(new RecordValue(hub, RecordValue::OwnsRecord));
54 
55     return *hub;
56 }
57 
hubCount() const58 int Episode::hubCount() const
59 {
60     return int(geta("hub").size());
61 }
62 
hasHub(int index) const63 bool Episode::hasHub(int index) const
64 {
65     return index >= 0 && index < hubCount();
66 }
67 
hub(int index)68 Record &Episode::hub(int index)
69 {
70     return *def().geta("hub")[index].as<RecordValue>().record();
71 }
72 
hub(int index) const73 Record const &Episode::hub(int index) const
74 {
75     return *geta("hub")[index].as<RecordValue>().record();
76 }
77 
tryFindHubByMapId(String const & mapId)78 Record *Episode::tryFindHubByMapId(String const &mapId)
79 {
80     de::Uri const mapUri(mapId, RC_NULL);
81     if (!mapUri.path().isEmpty())
82     {
83         for (int i = 0; i < hubCount(); ++i)
84         {
85             Record &hubRec = hub(i);
86             foreach (Value *mapIt, hubRec.geta("map").elements())
87             {
88                 Record &mgNodeDef = mapIt->as<RecordValue>().dereference();
89                 if (mapUri == de::makeUri(mgNodeDef.gets(VAR_ID)))
90                 {
91                     return &hubRec;
92                 }
93             }
94         }
95     }
96     return 0; // Not found.
97 }
98 
tryFindMapGraphNode(String const & mapId)99 Record *Episode::tryFindMapGraphNode(String const &mapId)
100 {
101     de::Uri const mapUri(mapId, RC_NULL);
102     if (!mapUri.path().isEmpty())
103     {
104         // First, try the hub maps.
105         for (int i = 0; i < hubCount(); ++i)
106         {
107             Record const &hubRec = hub(i);
108             foreach (Value *mapIt, hubRec.geta("map").elements())
109             {
110                 Record &mgNodeDef = mapIt->as<RecordValue>().dereference();
111                 if (mapUri == de::makeUri(mgNodeDef.gets(VAR_ID)))
112                 {
113                     return &mgNodeDef;
114                 }
115             }
116         }
117         // Try the non-hub maps.
118         foreach (Value *mapIt, geta("map").elements())
119         {
120             Record &mgNodeDef = mapIt->as<RecordValue>().dereference();
121             if (mapUri == de::makeUri(mgNodeDef.gets(VAR_ID)))
122             {
123                 return &mgNodeDef;
124             }
125         }
126     }
127     return 0; // Not found.
128 }
129 
tryFindMapGraphNodeByWarpNumber(int warpNumber)130 de::Record *Episode::tryFindMapGraphNodeByWarpNumber(int warpNumber)
131 {
132     if (warpNumber > 0)
133     {
134         // First, try the hub maps.
135         for (int i = 0; i < hubCount(); ++i)
136         {
137             Record const &hubRec = hub(i);
138             foreach (Value *mapIt, hubRec.geta("map").elements())
139             {
140                 Record &mgNodeDef = mapIt->as<RecordValue>().dereference();
141                 if (mgNodeDef.geti("warpNumber") == warpNumber)
142                 {
143                     return &mgNodeDef;
144                 }
145             }
146         }
147         // Try the non-hub maps.
148         foreach (Value *mapIt, geta("map").elements())
149         {
150             Record &mgNodeDef = mapIt->as<RecordValue>().dereference();
151             if (mgNodeDef.geti("warpNumber") == warpNumber)
152             {
153                 return &mgNodeDef;
154             }
155         }
156     }
157     return 0; // Not found.
158 }
159 
160 } // namespace defn
161