00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "World.h"
00022 #include "Map.h"
00023 #include "CurrentMap.h"
00024 #include "IDataSource.h"
00025 #include "ODataSource.h"
00026 #include "FlexFile.h"
00027 #include "RawArchive.h"
00028 #include "ItemFactory.h"
00029 #include "Actor.h"
00030 #include "MainActor.h"
00031 #include "idMan.h"
00032 #include "GameData.h"
00033 #include "Kernel.h"
00034 #include "ObjectManager.h"
00035 #include "GUIApp.h"
00036 #include "CameraProcess.h"
00037 #include "Gump.h"
00038 #include "Animation.h"
00039 #include "getObject.h"
00040 #include "MemoryManager.h"
00041 #include "AudioProcess.h"
00042
00043
00044
00045 World* World::world = 0;
00046
00047 World::World()
00048 : currentmap(0)
00049 {
00050 con.Print(MM_INFO, "Creating World...\n");
00051 assert(world == 0);
00052
00053 world = this;
00054 }
00055
00056
00057 World::~World()
00058 {
00059 con.Print(MM_INFO, "Destroying World...\n");
00060 clear();
00061
00062 world = 0;
00063 }
00064
00065
00066 void World::clear()
00067 {
00068 unsigned int i;
00069
00070 for (i = 0; i < maps.size(); ++i) {
00071 delete maps[i];
00072 }
00073 maps.clear();
00074
00075 while (!ethereal.empty())
00076 ethereal.pop_front();
00077
00078 if (currentmap)
00079 delete currentmap;
00080 currentmap = 0;
00081 }
00082
00083 void World::reset()
00084 {
00085 con.Print(MM_INFO, "Resetting World...\n");
00086
00087 clear();
00088
00089 initMaps();
00090 }
00091
00092 void World::initMaps()
00093 {
00094
00095
00096
00097 maps.resize(256);
00098 for (unsigned int i = 0; i < 256; ++i) {
00099 maps[i] = new Map(i);
00100 }
00101
00102 currentmap = new CurrentMap();
00103 }
00104
00105 bool World::switchMap(uint32 newmap)
00106 {
00107 assert(currentmap);
00108
00109 if (currentmap->getNum() == newmap)
00110 return true;
00111
00112 if (newmap >= maps.size() || maps[newmap] == 0)
00113 return false;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 CameraProcess::ResetCameraProcess();
00138
00139 AudioProcess *ap = AudioProcess::get_instance();
00140 if (ap) ap->stopAllExceptSpeech();
00141
00142
00143 GUIApp *gui = GUIApp::get_instance();
00144 if (gui)
00145 {
00146 Gump *desktop = gui->getDesktopGump();
00147 if (desktop) desktop->CloseItemDependents();
00148 }
00149
00150
00151 while (!ethereal.empty()) {
00152 uint16 eth = ethereal.front();
00153 ethereal.pop_front();
00154 Item* i = getItem(eth);
00155 if(i) i->destroy();
00156 }
00157
00158 uint32 oldmap = currentmap->getNum();
00159 if (oldmap != 0) {
00160 perr << "Unloading map " << oldmap << std::endl;
00161
00162 assert(oldmap < maps.size() && maps[oldmap] != 0);
00163
00164 currentmap->writeback();
00165
00166 perr << "Unloading Fixed items from map " << oldmap << std::endl;
00167
00168 maps[oldmap]->unloadFixed();
00169 }
00170
00171
00172 Kernel::get_instance()->killProcessesNotOfType(0, 1, true);
00173
00174 pout << "Loading Fixed items in map " << newmap << std::endl;
00175 IDataSource *items = GameData::get_instance()->getFixed()
00176 ->get_datasource(newmap);
00177 maps[newmap]->loadFixed(items);
00178 delete items;
00179
00180 currentmap->loadMap(maps[newmap]);
00181
00182
00183 CameraProcess::SetCameraProcess(new CameraProcess(1));
00184 CameraProcess::SetEarthquake(0);
00185
00186 MemoryManager::get_instance()->freeResources();
00187
00188 return true;
00189 }
00190
00191 void World::loadNonFixed(IDataSource* ds)
00192 {
00193 FlexFile* f = new FlexFile(ds);
00194
00195 pout << "Loading NonFixed items" << std::endl;
00196
00197 for (unsigned int i = 0; i < f->getCount(); ++i) {
00198
00199
00200 if (f->getSize(i) > 0) {
00201 assert(maps.size() > i);
00202 assert(maps[i] != 0);
00203
00204 IDataSource *items = f->getDataSource(i);
00205
00206 maps[i]->loadNonFixed(items);
00207
00208 delete items;
00209
00210 }
00211 }
00212
00213 delete f;
00214 }
00215
00216 void World::loadItemCachNPCData(IDataSource* itemcach, IDataSource* npcdata)
00217 {
00218 FlexFile* itemcachflex = new FlexFile(itemcach);
00219 FlexFile* npcdataflex = new FlexFile(npcdata);
00220
00221 IDataSource* itemds = itemcachflex->getDataSource(0);
00222 IDataSource* npcds = npcdataflex->getDataSource(0);
00223
00224 delete itemcachflex;
00225 delete npcdataflex;
00226
00227 pout << "Loading NPCs" << std::endl;
00228
00229 for (uint32 i = 1; i < 256; ++i)
00230 {
00231
00232 itemds->seek(0x00000+i*2);
00233 sint32 x = static_cast<sint32>(itemds->readX(2));
00234 itemds->seek(0x04800+i*2);
00235 sint32 y = static_cast<sint32>(itemds->readX(2));
00236 itemds->seek(0x09000+i*1);
00237 sint32 z = static_cast<sint32>(itemds->readX(1));
00238
00239 itemds->seek(0x0B400+i*2);
00240 uint32 shape = itemds->read2();
00241 itemds->seek(0x0FC00+i*1);
00242 uint32 frame = itemds->read1();
00243 itemds->seek(0x12000+i*2);
00244 uint16 flags = itemds->read2();
00245 itemds->seek(0x16800+i*2);
00246 uint16 quality = itemds->read2();
00247 itemds->seek(0x1B000+i*1);
00248 uint16 npcnum = static_cast<uint8>(itemds->read1());
00249 itemds->seek(0x1D400+i*1);
00250 uint16 mapnum = static_cast<uint8>(itemds->read1());
00251 itemds->seek(0x1F800+i*2);
00252 uint16 next;
00253 next = itemds->read2();
00254
00255
00256 npcds->seek(7 + i * 0x31);
00257 frame += npcds->read1() << 8;
00258
00259 if (shape == 0) {
00260
00261
00262 continue;
00263 }
00264
00265 #ifdef DUMP_ITEMS
00266 pout << shape << "," << frame << ":\t(" << x << "," << y << "," << z << "),\t" << std::hex << flags << std::dec << ", " << quality << ", " << npcnum << ", " << mapnum << ", " << next << std::endl;
00267 #endif
00268
00269 Actor *actor = ItemFactory::createActor(shape,frame,quality,
00270 flags|Item::FLG_IN_NPC_LIST,
00271 npcnum,mapnum,
00272 Item::EXT_PERMANENT_NPC,false);
00273 if (!actor) {
00274 #ifdef DUMP_ITEMS
00275 pout << "Couldn't create actor" << std::endl;
00276 #endif
00277 continue;
00278 }
00279 ObjectManager::get_instance()->assignActorObjId(actor, i);
00280
00281 actor->setLocation(x,y,z);
00282
00283
00284 npcds->seek(i * 0x31);
00285 actor->setStr(npcds->read1());
00286 actor->setDex(npcds->read1());
00287 actor->setInt(npcds->read1());
00288 actor->setHP(npcds->read1());
00289 actor->setDir(npcds->read1());
00290 uint16 la = npcds->read2();
00291 actor->setLastAnim(static_cast<Animation::Sequence>(la));
00292 npcds->skip(1);
00293 npcds->skip(1);
00294 npcds->skip(1);
00295 npcds->skip(1);
00296 uint8 align = npcds->read1();
00297 actor->setAlignment(align & 0x0F);
00298 actor->setEnemyAlignment(align & 0xF0);
00299 actor->setUnk0C(npcds->read1());
00300
00301
00302
00303 npcds->skip(14);
00304 actor->clearActorFlag(0xFF);
00305 actor->setActorFlag(npcds->read1());
00306 npcds->skip(1);
00307 npcds->skip(16);
00308 sint16 mana = static_cast<sint16>(npcds->read2());
00309 actor->setMana(mana);
00310 actor->clearActorFlag(0xFFFF00);
00311 uint32 flags2F = npcds->read1();
00312 actor->setActorFlag(flags2F << 8);
00313 uint32 flags30 = npcds->read1();
00314 actor->setActorFlag(flags30 << 16);
00315 }
00316
00317 delete itemds;
00318 delete npcds;
00319 }
00320
00321
00322 void World::worldStats()
00323 {
00324 unsigned int i, mapcount = 0;
00325
00326 for (i = 0; i < maps.size(); i++) {
00327 if (maps[i] != 0 && !maps[i]->isEmpty())
00328 mapcount++;
00329 }
00330
00331 pout << "World memory stats:" << std::endl;
00332 pout << "Maps : " << mapcount << "/256" << std::endl;
00333 Actor* av = getMainActor();
00334 pout << "Avatar pos.: ";
00335 if (av) {
00336 pout << "map " << av->getMapNum() << ", (";
00337 sint32 x,y,z;
00338 av->getLocation(x,y,z);
00339 pout << x << "," << y << "," << z << ")" << std::endl;
00340 } else {
00341 pout << "missing (null)" << std::endl;
00342 }
00343 }
00344
00345 void World::save(ODataSource* ods)
00346 {
00347 ods->write4(currentmap->getNum());
00348
00349 ods->write2(currentmap->egghatcher);
00350
00351 uint16 es = ethereal.size();
00352 ods->write4(es);
00353
00354
00355 uint16* e = new uint16[es];
00356 std::list<ObjId>::iterator it = ethereal.begin();
00357 unsigned int i;
00358 for (i = 0; i < es; ++i) {
00359 e[es-i] = *it;
00360 ++it;
00361 }
00362
00363 for (i = 0; i < es; ++i) {
00364 ods->write2(e[i]);
00365 }
00366 delete[] e;
00367 }
00368
00369
00370 bool World::load(IDataSource* ids, uint32 version)
00371 {
00372 uint16 curmapnum = ids->read4();
00373 currentmap->setMap(maps[curmapnum]);
00374
00375 currentmap->egghatcher = ids->read2();
00376
00377 uint32 etherealcount = ids->read4();
00378 for (unsigned int i = 0; i < etherealcount; ++i) {
00379 ethereal.push_front(ids->read2());
00380 }
00381
00382 return true;
00383 }
00384
00385 void World::saveMaps(ODataSource* ods)
00386 {
00387 ods->write4(maps.size());
00388 for (unsigned int i = 0; i < maps.size(); ++i) {
00389 maps[i]->save(ods);
00390 }
00391 }
00392
00393
00394 bool World::loadMaps(IDataSource* ids, uint32 version)
00395 {
00396 uint32 mapcount = ids->read4();
00397
00398
00399 for (unsigned int i = 0; i < mapcount; ++i) {
00400 bool res = maps[i]->load(ids, version);
00401 if (!res) return false;
00402 }
00403
00404 return true;
00405 }