1
// $Id: xml_plf.cxx,v 1.37 2003/04/05 23:24:32 grumbel Exp $
3
// Pingus - A free Lemmings clone
4
// Copyright (C) 2000 Ingo Ruhnke <grumbel@gmx.de>
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include "xml_helper.hxx"
22
#include "xml_file_reader.hxx"
23
#include "xml_plf.hxx"
24
#include "globals.hxx"
26
#include "pingus_error.hxx"
27
#include "worldobj_data_factory.hxx"
28
#include "worldobjsdata/entrance_data.hxx"
29
#include "worldobjsdata/exit_data.hxx"
30
#include "worldobjsdata/hotspot_data.hxx"
31
#include "worldobjsdata/liquid_data.hxx"
33
using Actions::action_from_string;
35
XMLPLF::XMLPLF (const std::string& arg_filename)
37
filename = arg_filename;
38
std::string str = System::checksum (filename);
40
doc = xmlParseFile(filename.c_str());
43
PingusError::raise("XMLPLF: Couldn't open \"" + filename + "\"");
45
resname = System::basename(System::dirname(filename))
46
+ "/" + System::basename(filename.substr(0, filename.length()-4));
55
// Free all the allocated memory
56
for(vector<BackgroundData*>::iterator i = backgrounds.begin ();
57
i != backgrounds.end ();
61
for(vector<WorldObjData*>::iterator i = worldobjs_data.begin ();
62
i != worldobjs_data.end ();
71
//std::cout << "parsing file" << std::endl;
72
xmlNodePtr cur = doc->ROOT;
74
cur = XMLhelper::skip_blank(cur);
76
if (cur && XMLhelper::equal_str(cur->name, "pingus-level"))
78
//std::cout << "parse_file...." << std::endl;
80
cur = XMLhelper::skip_blank(cur);
83
std::cout << "XMLPLF: node: " << cur->name << std::endl;
86
cur = XMLhelper::skip_blank(cur);
90
if (xmlIsBlankNode(cur))
96
if (XMLhelper::equal_str(cur->name, "version"))
98
// FIXME: ignoring version at the moment
100
// FIXME: This can mostly be unified with the
101
// WorldObjDataFactory, exit, backgrounds, etc. are all
103
else if (XMLhelper::equal_str(cur->name, "global"))
107
else if (XMLhelper::equal_str(cur->name, "action-list"))
111
else if (XMLhelper::equal_str(cur->name, "background"))
113
parse_background(cur);
115
else if (XMLhelper::equal_str(cur->name, "groundpiece"))
117
#ifndef OLD_GROUNDPIECES
118
// FIXME: This is *not* backward compatible and wreck the levels
119
// worldobjs_data.push_back(WorldObjDataFactory::instance()->create (doc, cur));
121
// This probally is backward compatible
122
//groundpieces.push_back(WorldObjsData::GroundpieceData (doc, cur));
123
worldobjs_data.push_back(new WorldObjsData::GroundpieceData (doc, cur));
125
parse_groundpiece(cur);
128
else if (XMLhelper::equal_str(cur->name, "exit"))
130
worldobjs_data.push_back (new WorldObjsData::ExitData(doc, cur));
132
else if (XMLhelper::equal_str(cur->name, "entrance"))
134
worldobjs_data.push_back (new WorldObjsData::EntranceData(doc, cur));
136
else if (XMLhelper::equal_str(cur->name, "trap"))
140
else if (XMLhelper::equal_str(cur->name, "hotspot"))
142
worldobjs_data.push_back(new WorldObjsData::HotspotData(doc, cur));
144
else if (XMLhelper::equal_str(cur->name, "liquid"))
146
worldobjs_data.push_back(new WorldObjsData::LiquidData(doc, cur));
148
else if (XMLhelper::equal_str(cur->name, "worldobj"))
150
worldobjs_data.push_back(WorldObjDataFactory::instance()->create(doc, cur));
152
else if (XMLhelper::equal_str(cur->name, "prefab"))
154
worldobjs_data.push_back(WorldObjDataFactory::instance()->create(doc, cur));
156
else if (XMLhelper::equal_str(cur->name, "group"))
158
worldobjs_data.push_back(WorldObjDataFactory::instance()->create(doc, cur));
159
//worldobjs_data.push_back (new WorldObjsData::WorldObjGroupData (doc, cur));
162
else if (XMLhelper::equal_str(cur->name, "start-position"))
164
parse_start_pos(cur);
166
else if (XMLhelper::equal_str(cur->name, "weather"))
168
worldobjs_data.push_back(WorldObjDataFactory::instance()->create (doc, cur));
172
printf("XMLPLF: Unhandled: %s\n", reinterpret_cast<const char*>(cur->name));
176
//puts("global done");
178
PingusError::raise("XMLPLF: This is no valid Pingus level");
183
XMLPLF::parse_group (xmlNodePtr cur)
189
if (XMLhelper::equal_str(cur->name, "background"))
191
parse_background(cur);
193
else if (XMLhelper::equal_str(cur->name, "groundpiece"))
195
parse_groundpiece(cur);
197
else if (XMLhelper::equal_str(cur->name, "exit"))
199
worldobjs_data.push_back(new WorldObjsData::ExitData(doc, cur));
201
else if (XMLhelper::equal_str(cur->name, "entrance"))
203
worldobjs_data.push_back(new WorldObjsData::EntranceData(doc, cur));
205
else if (XMLhelper::equal_str(cur->name, "trap"))
209
else if (XMLhelper::equal_str(cur->name, "hotspot"))
211
worldobjs_data.push_back(new WorldObjsData::HotspotData (doc, cur));
213
else if (XMLhelper::equal_str(cur->name, "liquid"))
215
worldobjs_data.push_back(new WorldObjsData::LiquidData (doc, cur));
217
else if (XMLhelper::equal_str(cur->name, "worldobj"))
219
worldobjs_data.push_back(WorldObjDataFactory::instance()->create (doc, cur));
221
else if (XMLhelper::equal_str(cur->name, "group"))
223
//worldobjs_data.push_back (new WorldObjsData::WorldObjGroupData (doc, cur));
226
else if (XMLhelper::equal_str(cur->name, "start-position"))
228
parse_start_pos(cur);
230
else if (XMLhelper::equal_str(cur->name, "weather"))
232
worldobjs_data.push_back(WorldObjDataFactory::instance()->create (doc, cur));
236
printf("XMLPLF: Unhandled parse_group: %s\n", reinterpret_cast<const char*>(cur->name));
243
XMLPLF::parse_start_pos (xmlNodePtr cur)
249
if (xmlIsBlankNode(cur))
255
if (XMLhelper::equal_str(cur->name, "position"))
257
Vector pos = XMLhelper::parse_vector(doc, cur);
258
start_x_pos = static_cast<int>(pos.x);
259
start_y_pos = static_cast<int>(pos.y);
263
std::cout << "XMLPLF::parse_start_pos: " << cur->name << std::endl;
270
XMLPLF::parse_background (xmlNodePtr cur)
272
// The allocated objects are delete'd in the destructor
273
//FIXME: Repair me backgrounds.push_back(BackgroundData::create (doc, cur));
276
if (XMLhelper::get_prop(cur, "type", type))
278
worldobjs_data.push_back(WorldObjDataFactory::instance()
279
->create (type + "-background", doc, cur));
283
worldobjs_data.push_back(WorldObjDataFactory::instance()
284
->create ("surface-background", doc, cur));
289
XMLPLF::parse_actions (xmlNodePtr cur)
295
if (xmlIsBlankNode(cur))
302
button.name = action_from_string(reinterpret_cast<const char*>(cur->name));
304
if (!XMLhelper::get_prop(cur, "count", button.number_of))
306
//std::cout << "XMLPLF::parse_actions (): No 'count' given, fallback to the old format" << std::endl;
307
if (!XMLhelper::node_list_get_string(doc, cur->children, 1, button.number_of))
308
std::cout << "XMLPLF:parse_actions: no action number given" << std::endl;
311
actions.push_back(button);
318
XMLPLF::parse_global (xmlNodePtr cur)
320
XMLFileReader reader(doc, cur);
322
reader.read_string("author", author);
323
reader.read_int("number-of-pingus", number_of_pingus);
324
reader.read_int("number-to-save", number_to_save);
325
reader.read_int("time", max_time);
326
reader.read_int("difficulty", difficulty);
327
reader.read_bool("playable", playable);
328
reader.read_string("comment", comment);
329
reader.read_string("music", music);
330
reader.read_int("width", width);
331
reader.read_int("height", height);
336
if (xmlIsBlankNode(cur))
342
if (XMLhelper::equal_str(cur->name, "levelname"))
347
if (XMLhelper::node_list_get_string(doc, cur->children, 1, name)) {
348
if (XMLhelper::get_prop(cur, "lang", lang))
349
levelname[lang] = name;
351
levelname[default_language] = name;
354
else if (XMLhelper::equal_str(cur->name, "description"))
359
if (XMLhelper::node_list_get_string(doc, cur->children, 1, desc)) {
360
if (XMLhelper::get_prop(cur, "lang", lang))
361
description[lang] = desc;
363
description[default_language] = desc;
371
XMLPLF::parse_groundpiece (xmlNodePtr cur)
373
groundpieces.push_back(WorldObjsData::GroundpieceData (doc, cur));
377
XMLPLF::parse_traps (xmlNodePtr cur)
379
xmlNodePtr child_cur = XMLhelper::skip_blank(cur->children);
381
if (XMLhelper::equal_str(child_cur->name, "type"))
384
if (XMLhelper::node_list_get_string(doc, child_cur->children, 1, name))
386
worldobjs_data.push_back(WorldObjDataFactory::instance()->create(name, doc, cur));
391
std::cout << "XMLPLF::parse_traps: Invalid data structure" << std::endl;