Map.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003-2006 The Pentagram team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include "pent_include.h"
00020 
00021 #include <stack>
00022 
00023 #include "Map.h"
00024 #include "IDataSource.h"
00025 #include "ODataSource.h"
00026 #include "ItemFactory.h"
00027 #include "Item.h"
00028 #include "Container.h"
00029 #include "ObjectManager.h"
00030 #include "CoreApp.h"
00031 #include "GameInfo.h"
00032 
00033 #include "ShapeInfo.h" // debugging only
00034 #include "GameData.h" // ""
00035 #include "MainShapeArchive.h" // ""
00036 
00037 //#define DUMP_ITEMS
00038 
00039 Map::Map(uint32 mapnum_)
00040         : mapnum(mapnum_)
00041 {
00042 
00043 }
00044 
00045 
00046 Map::~Map()
00047 {
00048         clear();
00049 }
00050 
00051 void Map::clear()
00052 {
00053         std::list<Item*>::iterator iter;
00054 
00055         for (iter = fixeditems.begin(); iter != fixeditems.end(); ++iter) {
00056                 delete *iter;
00057         }
00058         fixeditems.clear();
00059 
00060         for (iter = dynamicitems.begin(); iter != dynamicitems.end(); ++iter) {
00061                 delete *iter;
00062         }
00063         dynamicitems.clear();
00064 }
00065 
00066 void Map::loadNonFixed(IDataSource* ds)
00067 {
00068         loadFixedFormatObjects(dynamicitems, ds, 0);
00069 }
00070 
00071 void Map::loadFixed(IDataSource* ds)
00072 {
00073         loadFixedFormatObjects(fixeditems, ds, Item::EXT_FIXED);
00074 
00075 
00076         // U8 hack for missing ground tiles on map 25. See docs/u8bugs.txt
00077         if (GAME_IS_U8 && mapnum == 25)
00078         {
00079                 // TODO
00080         }
00081 
00082         // U8 hack for missing ground/wall tiles on map 62. See docs/u8bugs.txt
00083         if (GAME_IS_U8 && mapnum == 62)
00084         {
00085                 Item* item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00086                                                                                         Item::EXT_FIXED, false);
00087                 item->setLocation(16255, 6143, 48);
00088                 fixeditems.push_back(item);
00089 
00090                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00091                                                                            Item::EXT_FIXED, false);
00092                 item->setLocation(16639, 6143, 48);
00093                 fixeditems.push_back(item);
00094 
00095                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00096                                                                            Item::EXT_FIXED, false);
00097                 item->setLocation(16511, 6143, 48);
00098                 fixeditems.push_back(item);
00099 
00100 
00101                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00102                                                                            Item::EXT_FIXED, false);
00103                 item->setLocation(15999, 6143, 48);
00104                 fixeditems.push_back(item);
00105 
00106                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00107                                                                            Item::EXT_FIXED, false);
00108                 item->setLocation(15871, 6143, 48);
00109                 fixeditems.push_back(item);
00110 
00111                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00112                                                                            Item::EXT_FIXED, false);
00113                 item->setLocation(15743, 6143, 48);
00114                 fixeditems.push_back(item);
00115 
00116                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00117                                                                            Item::EXT_FIXED, false);
00118                 item->setLocation(15615, 6143, 48);
00119                 fixeditems.push_back(item);
00120 
00121 
00122 
00123                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00124                                                                            Item::EXT_FIXED, false);
00125                 item->setLocation(15999, 6015, 48);
00126                 fixeditems.push_back(item);
00127 
00128                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00129                                                                            Item::EXT_FIXED, false);
00130                 item->setLocation(15871, 6015, 48);
00131                 fixeditems.push_back(item);
00132 
00133                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00134                                                                            Item::EXT_FIXED, false);
00135                 item->setLocation(15743, 6015, 48);
00136                 fixeditems.push_back(item);
00137 
00138                 item = ItemFactory::createItem(301, 1, 0, 0, 0, 0,
00139                                                                            Item::EXT_FIXED, false);
00140                 item->setLocation(15615, 6015, 48);
00141                 fixeditems.push_back(item);
00142 
00143 
00144 
00145                 item = ItemFactory::createItem(497, 0, 0, 0, 0, 0,
00146                                                                            Item::EXT_FIXED, false);
00147                 item->setLocation(15487, 6271, 48);
00148                 fixeditems.push_back(item);
00149 
00150                 item = ItemFactory::createItem(497, 0, 0, 0, 0, 0,
00151                                                                            Item::EXT_FIXED, false);
00152                 item->setLocation(15359, 6271, 48);
00153                 fixeditems.push_back(item);
00154 
00155                 item = ItemFactory::createItem(409, 32, 0, 0, 0, 0,
00156                                                                            Item::EXT_FIXED, false);
00157                 item->setLocation(14975, 6399, 0);
00158                 fixeditems.push_back(item);
00159 
00160                 item = ItemFactory::createItem(409, 32, 0, 0, 0, 0,
00161                                                                            Item::EXT_FIXED, false);
00162                 item->setLocation(14975, 6015, 0);
00163                 fixeditems.push_back(item);
00164 
00165                 item = ItemFactory::createItem(409, 32, 0, 0, 0, 0,
00166                                                                            Item::EXT_FIXED, false);
00167                 item->setLocation(15103, 6015, 0);
00168                 fixeditems.push_back(item);
00169         }
00170 }
00171 
00172 void Map::unloadFixed()
00173 {
00174         std::list<Item*>::iterator iter;
00175 
00176         for (iter = fixeditems.begin(); iter != fixeditems.end(); ++iter) {
00177                 delete *iter;
00178         }
00179         fixeditems.clear();
00180 }
00181 
00182 void Map::loadFixedFormatObjects(std::list<Item*>& itemlist, IDataSource* ds,
00183                                                                  uint32 extendedflags)
00184 {
00185         if (!ds) return;
00186         uint32 size = ds->getSize();
00187         if (size == 0) return;
00188 
00189         uint32 itemcount = size / 16;
00190 
00191         std::stack<Container*> cont;
00192         int contdepth = 0;
00193 
00194         for (uint32 i = 0; i < itemcount; ++i)
00195         {
00196                 // These are ALL unsigned on disk
00197                 sint32 x = static_cast<sint32>(ds->readX(2));
00198                 sint32 y = static_cast<sint32>(ds->readX(2));
00199                 sint32 z = static_cast<sint32>(ds->readX(1));
00200 
00201                 if (GAME_IS_CRUSADER) {
00202                         x *= 2;
00203                         y *= 2;
00204                 }
00205 
00206                 uint32 shape = ds->read2();
00207                 uint32 frame = ds->read1();
00208                 uint16 flags = ds->read2();
00209                 uint16 quality = ds->read2();
00210                 uint16 npcnum = static_cast<uint16>(ds->read1());
00211                 uint16 mapnum = static_cast<uint16>(ds->read1());
00212                 uint16 next = ds->read2(); // do we need next for anything?
00213 
00214                 // find container this item belongs to, if any.
00215                 // the x coordinate stores the container-depth of this item,
00216                 // so pop items from the container stack until we reach x,
00217                 // or, if x is too large, the item is added to the top-level list
00218                 while (contdepth != x && contdepth > 0) {
00219                         cont.pop();
00220                         contdepth--;
00221 #ifdef DUMP_ITEMS
00222                         pout << "---- Ending container ----" << std::endl;
00223 #endif
00224                 }
00225 
00226 #ifdef DUMP_ITEMS
00227                 pout << shape << "," << frame << ":\t(" << x << "," << y << "," << z << "),\t" << std::hex << flags << std::dec << ", " << quality << ", " << npcnum << ", " << mapnum << ", " << next << std::endl;
00228 #endif
00229 
00230                 Item *item = ItemFactory::createItem(shape,frame,quality,flags,npcnum,
00231                                                                                          mapnum,extendedflags,false);
00232                 if (!item) {
00233                         pout << shape << "," << frame << ":\t(" << x << "," << y << "," << z << "),\t" << std::hex << flags << std::dec << ", " << quality << ", " << npcnum << ", " << mapnum << ", " << next;
00234 
00235                         ShapeInfo *info = GameData::get_instance()->getMainShapes()->
00236                                 getShapeInfo(shape);
00237                         if (info) pout << ", family = " << info->family;
00238                         pout << std::endl;
00239 
00240                         pout << "Couldn't create item" << std::endl;
00241                         continue;
00242                 }
00243                 item->setLocation(x,y,z);
00244 
00245                 if (contdepth > 0) {
00246                         cont.top()->addItem(item);
00247                 } else {
00248                         itemlist.push_back(item);
00249                 }
00250 
00251                 Container *c = p_dynamic_cast<Container*>(item);
00252                 if (c) {
00253                         // container, so prepare to read contents
00254                         contdepth++;
00255                         cont.push(c);
00256 #ifdef DUMP_ITEMS
00257                         pout << "---- Starting container ----" << std::endl;
00258 #endif
00259                 }
00260         }
00261 }
00262 
00263 
00264 void Map::save(ODataSource* ods)
00265 {
00266         ods->write4(dynamicitems.size());
00267 
00268         std::list<Item*>::iterator iter;
00269         for (iter = dynamicitems.begin(); iter != dynamicitems.end(); ++iter) {
00270                 (*iter)->save(ods);
00271         }
00272 }
00273 
00274 
00275 bool Map::load(IDataSource* ids, uint32 version)
00276 {
00277         uint32 itemcount = ids->read4();
00278 
00279         for (unsigned int i = 0; i < itemcount; ++i) {
00280                 Object* obj = ObjectManager::get_instance()->loadObject(ids, version);
00281                 Item* item = p_dynamic_cast<Item*>(obj);
00282                 if (!item) return false;
00283                 dynamicitems.push_back(item);
00284         }
00285 
00286         return true;
00287 }

Generated on Fri Jul 27 22:27:25 2007 for pentagram by  doxygen 1.4.7