GameMapGump.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2003-2007  The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (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 "GameMapGump.h"
00022 #include "RenderSurface.h"
00023 
00024 #include "Kernel.h"
00025 
00026 #include "World.h"
00027 #include "Map.h"
00028 #include "CurrentMap.h"
00029 #include "Item.h"
00030 #include "Actor.h"
00031 #include "MainActor.h"
00032 #include "ItemSorter.h"
00033 #include "CameraProcess.h"
00034 #include "GUIApp.h"
00035 #include "ShapeInfo.h"
00036 #include "IDataSource.h"
00037 #include "ODataSource.h"
00038 #include "Mouse.h"
00039 #include "getObject.h"
00040 #include "AvatarMoverProcess.h"
00041 #include "MissileTracker.h"
00042 #include "Direction.h"
00043 
00044 
00045 #include "GravityProcess.h" // hack...
00046 #include "PathfinderProcess.h"
00047 #include "UCList.h"
00048 #include "LoopScript.h"
00049 
00050 // map dumping
00051 #include "Texture.h"
00052 #include "FileSystem.h"
00053 #include "PNGWriter.h"
00054 
00055 
00056 DEFINE_RUNTIME_CLASSTYPE_CODE(GameMapGump,Gump);
00057 
00058 bool GameMapGump::highlightItems = false;
00059 
00060 GameMapGump::GameMapGump() :
00061         Gump(), display_dragging(false)
00062 {
00063         display_list = new ItemSorter();
00064 }
00065 
00066 GameMapGump::GameMapGump(int X, int Y, int Width, int Height) :
00067         Gump(X,Y,Width,Height, 0, FLAG_DONT_SAVE | FLAG_CORE_GUMP, LAYER_GAMEMAP),
00068         display_list(0), display_dragging(false)
00069 {
00070         // Offset the gump. We want 0,0 to be the centre
00071         dims.x -= dims.w/2;
00072         dims.y -= dims.h/2;
00073 
00074         pout << "Create display_list ItemSorter object" << std::endl;
00075         display_list = new ItemSorter();
00076 }
00077 
00078 GameMapGump::~GameMapGump()
00079 {
00080         delete display_list;
00081 }
00082 
00083 bool GameMapGump::Run(const uint32 framenum)
00084 {
00085         Gump::Run(framenum);
00086 
00087         return true; // Always repaint, even though we really could just
00088                      // try to detect it
00089 }
00090 
00091 void GameMapGump::GetCameraLocation(sint32& lx, sint32& ly, sint32& lz,
00092                                                                         int lerp_factor)
00093 {
00094         CameraProcess *camera = CameraProcess::GetCameraProcess();
00095         if (!camera) 
00096         {
00097                 CameraProcess::GetCameraLocation(lx,ly,lz);
00098         }
00099         else
00100         {
00101                 camera->GetLerped(lx, ly, lz, lerp_factor);
00102         }
00103 }
00104 
00105 
00106 void GameMapGump::PaintThis(RenderSurface *surf, sint32 lerp_factor, bool scaled)
00107 {
00108         World *world = World::get_instance();
00109         if (!world) return;     // Is it possible the world doesn't exist?
00110 
00111         CurrentMap *map = world->getCurrentMap();
00112         if (!map) return;       // Is it possible the map doesn't exist?
00113 
00114 
00115         // Get the camera location
00116         int lx, ly, lz;
00117         GetCameraLocation(lx, ly, lz, lerp_factor);
00118 
00119         CameraProcess *camera = CameraProcess::GetCameraProcess();
00120 
00121         uint16 roofid = 0;
00122         int zlimit = 1 << 16; // should be high enough
00123 
00124         if (!camera)
00125         {
00126                 // Check roof
00128                 sint32 ax, ay, az, axd, ayd, azd;
00129                 Actor* av = getMainActor();
00130                 av->getLocation(ax, ay, az);
00131                 av->getFootpadWorld(axd, ayd, azd);
00132                 map->isValidPosition(ax, ay, az, 32, 32, 8, 0, 1, 0, &roofid);
00133         }
00134         else
00135                 roofid = camera->FindRoof(lerp_factor);
00136 
00137         Item* roof = getItem(roofid);
00138         if (roof) {
00139                 zlimit = roof->getZ();
00140         }
00141 
00142         display_list->BeginDisplayList(surf, lx, ly, lz);
00143 
00144         uint32 gametick = Kernel::get_instance()->getFrameNum();
00145 
00146         bool paintEditorItems = GUIApp::get_instance()->isPaintEditorItems();
00147 
00148         // Get all the required items
00149         for (int cy = 0; cy < MAP_NUM_CHUNKS; cy++)
00150         {
00151                 for (int cx = 0; cx < MAP_NUM_CHUNKS; cx++)
00152                 {
00153                         // Not fast, ignore
00154                         if (!map->isChunkFast(cx,cy)) continue;
00155 
00156                         const std::list<Item*>* items = map->getItemList(cx,cy);
00157 
00158                         if (!items) continue;
00159 
00160                         std::list<Item*>::const_iterator it = items->begin();
00161                         std::list<Item*>::const_iterator end = items->end();
00162                         for (; it != end; ++it)
00163                         {
00164                                 Item *item = *it;
00165                                 if (!item) continue;
00166 
00167                                 item->setupLerp(gametick);
00168                                 item->doLerp(lerp_factor);
00169 
00170                                 if (item->getZ() >= zlimit && !item->getShapeInfo()->is_draw())
00171                                         continue;
00172                                 if (!paintEditorItems && item->getShapeInfo()->is_editor())
00173                                         continue;
00174                                 if (item->getFlags() & Item::FLG_INVISIBLE)
00175                                         continue;
00176                                 display_list->AddItem(item);
00177                         }
00178                 }
00179         }
00180 
00181         // Dragging:
00182 
00183         if (display_dragging) {
00184                 display_list->AddItem(dragging_pos[0],dragging_pos[1],dragging_pos[2],
00185                                                           dragging_shape, dragging_frame,
00186                                                           dragging_flags, Item::EXT_TRANSPARENT);
00187         }
00188 
00189 
00190         display_list->PaintDisplayList(highlightItems);
00191 }
00192 
00193 // Trace a click, and return ObjId
00194 uint16 GameMapGump::TraceObjId(int mx, int my)
00195 {
00196         uint16 objid = Gump::TraceObjId(mx,my);
00197         if (objid && objid != 65535) return objid;
00198 
00199         ParentToGump(mx,my);
00200         return display_list->Trace(mx,my,0,highlightItems);
00201 }
00202 
00203 uint16 GameMapGump::TraceCoordinates(int mx, int my, sint32 coords[3],
00204                                                                          int offsetx, int offsety, Item* item)
00205 {
00206         sint32 dxd = 0,dyd = 0,dzd = 0;
00207         if (item)
00208                 item->getFootpadWorld(dxd,dyd,dzd);
00209 
00210         sint32 cx, cy, cz;
00211         GetCameraLocation(cx, cy, cz);
00212 
00213         ItemSorter::HitFace face;
00214         ObjId trace = display_list->Trace(mx,my,&face);
00215         
00216         Item* hit = getItem(trace);
00217         if (!hit) // strange...
00218                 return 0;
00219 
00220         sint32 hx,hy,hz;
00221         sint32 hxd,hyd,hzd;
00222         hit->getLocation(hx,hy,hz);
00223         hit->getFootpadWorld(hxd,hyd,hzd);
00224 
00225         // adjust mx (if dragged item wasn't 'picked up' at its origin)
00226         mx -= offsetx;
00227         my -= offsety;
00228 
00229         // mx = (coords[0]-cx-coords[1]+cy)/4
00230         // my = (coords[0]-cx+coords[1]-cy)/8 - coords[2] + cz
00231 
00232         // the below expressions solve these two equations to two of the coords,
00233         // while fixing the other coord
00234 
00235         switch (face) {
00236         case ItemSorter::Z_FACE:
00237                 coords[0] = 2*mx + 4*(my+hz+hzd) + cx - 4*cz;
00238                 coords[1] = -2*mx + 4*(my+hz+hzd) + cy - 4*cz;
00239                 coords[2] = hz+hzd;
00240                 break;
00241         case ItemSorter::X_FACE:
00242                 coords[0] = hx+dxd;
00243                 coords[1] = -4*mx + hx+dxd - cx + cy;
00244                 coords[2] = -my + (hx+dxd)/4 - mx/2 - cx/4 + cz;
00245                 break;
00246         case ItemSorter::Y_FACE:
00247                 coords[0] = 4*mx + hy+dyd + cx - cy;
00248                 coords[1] = hy+dyd;
00249                 coords[2] = -my + mx/2 + (hy+dyd)/4 - cy/4 + cz;
00250                 break;
00251         }
00252 
00253         return trace;
00254 }
00255 
00256 bool GameMapGump::GetLocationOfItem(uint16 itemid, int &gx, int &gy,
00257                                                                         sint32 lerp_factor)
00258 {
00259         Item *item = getItem(itemid);
00260 
00261         if (!item) return false;
00262 
00263         while (item->getParentAsContainer()) item = item->getParentAsContainer();
00264 
00265         sint32 ix, iy, iz;
00266 
00267         // Hacks be us. Force the item into the fast area
00268         item->setupLerp(Kernel::get_instance()->getFrameNum());
00269         item->doLerp(lerp_factor);
00270         item->getLerped(ix,iy,iz);
00271 
00272         // Get the camera's location
00273         sint32 cx, cy, cz;
00274                 CameraProcess *cam = CameraProcess::GetCameraProcess();
00275         if (!cam) CameraProcess::GetCameraLocation(cx,cy,cz);
00276         else cam->GetLerped(cx,cy,cz,lerp_factor);
00277 
00278         // Screenspace bounding box bottom x coord (RNB x coord)
00279         gx = (ix - iy)/4;
00280         // Screenspace bounding box bottom extent  (RNB y coord)
00281         gy = (ix + iy)/8 - iz;
00282 
00283         // Screenspace bounding box bottom x coord (RNB x coord)
00284         gx -= (cx - cy)/4;
00285         // Screenspace bounding box bottom extent  (RNB y coord)
00286         gy -= (cx + cy)/8 - cz;
00287 
00288         return true;
00289 }
00290 
00291 Gump* GameMapGump::OnMouseDown(int button, int mx, int my)
00292 {
00293         int sx = mx, sy = my;
00294         ParentToGump(sx, sy);
00295         GumpToScreenSpace(sx, sy);
00296 
00297         AvatarMoverProcess* amp = GUIApp::get_instance()->getAvatarMoverProcess();
00298         if (button == BUTTON_RIGHT || button == BUTTON_LEFT) {
00299                 amp->OnMouseDown(button, sx, sy);
00300         }
00301 
00302         if (button == BUTTON_LEFT || button == BUTTON_RIGHT ||
00303                 button == BUTTON_MIDDLE)
00304         {
00305                 // we take all clicks
00306                 return this;
00307         }
00308 
00309         return 0;
00310 }
00311 
00312 void GameMapGump::OnMouseUp(int button, int mx, int my)
00313 {
00314         AvatarMoverProcess* amp = GUIApp::get_instance()->getAvatarMoverProcess();
00315         if (button == BUTTON_RIGHT || button == BUTTON_LEFT) {
00316                 amp->OnMouseUp(button);
00317         }
00318 }
00319 
00320 void GameMapGump::OnMouseClick(int button, int mx, int my)
00321 {
00322         MainActor* avatar = getMainActor();
00323         switch (button) {
00324         case BUTTON_LEFT:
00325         {
00326                 if (avatar->isInCombat()) break;
00327 
00328                 if (GUIApp::get_instance()->isMouseDown(BUTTON_RIGHT)) break;
00329 
00330                 if (GUIApp::get_instance()->isAvatarInStasis()) {
00331                         pout << "Can't: avatarInStasis" << std::endl;
00332                         break;
00333                 }
00334 
00335                 uint16 objID = TraceObjId(mx, my);
00336                 Item *item = getItem(objID);
00337                 if (item) {
00338                         sint32 x,y,z;
00339                         item->getLocation(x,y,z);
00340                         item->dumpInfo();
00341                         
00342                         // call the 'look' event
00343                         item->callUsecodeEvent_look();
00344                 }
00345                 break;
00346         }
00347         case BUTTON_MIDDLE:
00348         {
00349                 uint16 objID = TraceObjId(mx, my);
00350                 Item *item = getItem(objID);
00351                 if (item) {
00352                         sint32 x,y,z;
00353                         item->getLocation(x,y,z);
00354                         item->dumpInfo();
00355 
00356 #if 1
00357                         Actor* devon = getActor(1);
00358                         PathfinderProcess* pfp = new PathfinderProcess(devon, x, y, z);
00359 //                      PathfinderProcess* pfp = new PathfinderProcess(devon, objID, false);
00360                         Kernel::get_instance()->addProcess(pfp);
00361 #elif 0
00362                         if (p_dynamic_cast<Actor*>(item)) {
00363                                 p_dynamic_cast<Actor*>(item)->die(0);
00364                         } else {
00365                                 item->destroy();
00366                         }
00367 #elif 0
00368                         UCList uclist(2);
00369                         LOOPSCRIPT(script, LS_TOKEN_TRUE); // we want all items
00370                         World* world= World::get_instance();
00371                         world->getCurrentMap()->surfaceSearch(&uclist, script,
00372                                                                                                   sizeof(script),
00373                                                                                                   item, true, false, true);
00374                         for (uint32 i = 0; i < uclist.getSize(); i++)
00375                         {
00376                                 Item *item2 = getItem(uclist.getuint16(i));
00377                                 if (!item2) continue;
00378                                 item2->setExtFlag(Item::EXT_HIGHLIGHT);
00379                         }
00380 #elif 0
00381                         item->receiveHit(1, 0, 1024, 0);
00382 #elif 0
00383                         item->clearFlag(Item::FLG_HANGING);
00384 #endif
00385                 }
00386         }
00387         default:
00388                 break;
00389         }
00390 }
00391 
00392 void GameMapGump::OnMouseDouble(int button, int mx, int my)
00393 {
00394         MainActor* avatar = getMainActor();
00395         switch (button) {
00396         case BUTTON_LEFT:
00397         {
00398                 if (avatar->isInCombat()) break;
00399 
00400                 if (GUIApp::get_instance()->isMouseDown(BUTTON_RIGHT)) break;
00401 
00402                 if (GUIApp::get_instance()->isAvatarInStasis()) {
00403                         pout << "Can't: avatarInStasis" << std::endl; 
00404                         break;
00405                 }
00406 
00407                 uint16 objID = TraceObjId(mx, my);
00408                 Item *item = getItem(objID);
00409                 if (item) {
00410                         sint32 x,y,z;
00411                         item->getLocation(x,y,z);
00412                         item->dumpInfo();
00413 
00414                         if (p_dynamic_cast<Actor*>(item) ||
00415                                 avatar->canReach(item, 128)) // CONSTANT!
00416                         {
00417                                 // call the 'use' event
00418                                 item->use();
00419                         } else {
00420                                 GUIApp::get_instance()->flashCrossCursor();
00421                         }
00422                 }
00423                 break;
00424         }
00425         default:
00426                 break;
00427         }
00428 }
00429 
00430 void GameMapGump::IncSortOrder(int count)
00431 {
00432         if (count>0) display_list->IncSortLimit();
00433         else display_list->DecSortLimit();
00434 }
00435 
00436 bool GameMapGump::StartDraggingItem(Item* item, int mx, int my)
00437 {
00438 //      ParentToGump(mx, my);
00439 
00440         if (!item->canDrag()) return false;
00441 
00442         MainActor* avatar = getMainActor();
00443         if (!avatar->canReach(item, 128)) return false;  // CONSTANT!
00444         
00445         // get item offset
00446         int itemx, itemy;
00447         GetLocationOfItem(item->getObjId(), itemx, itemy);
00448         GUIApp::get_instance()->setDraggingOffset(mx - itemx, my - itemy);
00449 
00450         return true;
00451 }
00452 
00453 bool GameMapGump::DraggingItem(Item* item, int mx, int my)
00454 {
00455         // determine target location and set dragging_x/y/z
00456         int dox, doy;
00457         GUIApp::get_instance()->getDraggingOffset(dox, doy);
00458 
00459         dragging_shape = item->getShape();
00460         dragging_frame = item->getFrame();
00461         dragging_flags = item->getFlags();
00462         display_dragging = true;
00463 
00464         // determine if item can be dropped here
00465 
00466         ObjId trace = TraceCoordinates(mx, my, dragging_pos, dox, doy, item);
00467         if (!trace)
00468                 return false;
00469 
00470         MainActor* avatar = getMainActor();
00471         if (trace == 1) { // dropping on self
00472                 ObjId bp = avatar->getEquip(7); // !! constant
00473                 Container* backpack = getContainer(bp);
00474                 return  backpack->CanAddItem(item, true);
00475         }
00476 
00477         bool throwing = false;
00478         if (!avatar->canReach(item, 128, // CONSTANT!
00479                                                   dragging_pos[0], dragging_pos[1], dragging_pos[2]))
00480         {
00481                 // can't reach, so see if we can throw
00482                 int throwrange = item->getThrowRange();
00483                 if (throwrange && avatar->canReach(item, throwrange, dragging_pos[0],
00484                                                                                    dragging_pos[1], dragging_pos[2]))
00485                 {
00486                         int speed = 64 - item->getTotalWeight() + avatar->getStr();
00487                         if (speed < 1) speed = 1;
00488                         sint32 ax,ay,az;
00489                         avatar->getLocation(ax,ay,az);
00490                         MissileTracker t(item, ax, ay, az,
00491                                                          dragging_pos[0], dragging_pos[1], dragging_pos[2],
00492                                                          speed, 4);
00493                         if (t.isPathClear())
00494                                 throwing = true;
00495                         else
00496                                 return false;
00497                 } else {
00498                         return false;
00499                 }
00500         }
00501 
00502         if (!item->canExistAt(dragging_pos[0], dragging_pos[1], dragging_pos[2]))
00503                 return false;
00504 
00505         if (throwing)
00506                 GUIApp::get_instance()->setMouseCursor(GUIApp::MOUSE_TARGET);
00507 
00508         return true;
00509 }
00510 
00511 void GameMapGump::DraggingItemLeftGump(Item* item)
00512 {
00513         display_dragging = false;
00514 }
00515 
00516 
00517 void GameMapGump::StopDraggingItem(Item* item, bool moved)
00518 {
00519         display_dragging = false;
00520 
00521         if (!moved) return; // nothing to do
00522 
00523         // make items on top of item fall and call release on supporting items
00524         item->grab();
00525 }
00526 
00527 void GameMapGump::DropItem(Item* item, int mx, int my)
00528 {
00529         int dox, doy;
00530         GUIApp::get_instance()->getDraggingOffset(dox, doy);
00531 
00532         display_dragging = false;
00533         Actor* avatar = getMainActor();
00534 
00535         ObjId trace = TraceCoordinates(mx, my, dragging_pos, dox, doy, item);
00536         if (trace == 1) { // dropping on self
00537                 ObjId bp = avatar->getEquip(7); // !! constant
00538                 Container* backpack = getContainer(bp);
00539                 if (backpack && item->moveToContainer(backpack)) {
00540                         pout << "Dropped item in backpack" << std::endl;
00541                         item->randomGumpLocation();
00542                         return;
00543                 }
00544         }
00545 
00546         if (!avatar->canReach(item, 128, // CONSTANT!
00547                                                   dragging_pos[0], dragging_pos[1], dragging_pos[2]))
00548         {
00549                 // can't reach, so throw
00550                 pout << "Throwing item to (" << dragging_pos[0] << ","
00551                          << dragging_pos[1] << "," << dragging_pos[2] << ")" << std::endl;
00552                 int speed = 64 - item->getTotalWeight() + avatar->getStr();
00553                 if (speed < 1) speed = 1;
00554                 sint32 ax,ay,az;
00555                 avatar->getLocation(ax,ay,az);
00556                 // CHECKME: correct position to throw from?
00557                 // CHECKME: correct events triggered when doing this move?
00558                 item->move(ax, ay, az+24);
00559                 sint32 tx, ty;
00560                 tx = dragging_pos[0];
00561                 ty = dragging_pos[1];
00562                 int inaccuracy = 4 * (30 - avatar->getDex());
00563                 if (inaccuracy < 20) inaccuracy = 20; // just in case dex > 25
00564                 tx += (std::rand()%inaccuracy) - (std::rand()%inaccuracy);
00565                 ty += (std::rand()%inaccuracy) - (std::rand()%inaccuracy);
00566                 MissileTracker t(item, tx, ty, dragging_pos[2],
00567                                                  speed, 4);
00568                 t.launchItem();
00569 
00570                 // FIXME: When doing this animation, sometimes items will
00571                 //        get stuck on the avatar. Why?
00572 #if 0
00573                 avatar->doAnim(Animation::stand,
00574                                            Get_WorldDirection(dragging_pos[1]-ay,
00575                                                                                   dragging_pos[0]-ax));
00576 #endif
00577         } else {
00578                 pout << "Dropping item at (" << dragging_pos[0] << ","
00579                          << dragging_pos[1] << "," << dragging_pos[2] << ")" << std::endl;
00580 
00581                 // CHECKME: collideMove and grab (in StopDraggingItem)
00582                 // both call release on supporting items.
00583 
00584                 item->collideMove(dragging_pos[0], dragging_pos[1], dragging_pos[2],
00585                                                   true, true); // teleport item
00586                 item->fall();
00587         }
00588 }
00589 
00590 void GameMapGump::ConCmd_toggleHighlightItems(const Console::ArgvType &argv)
00591 {
00592         GameMapGump::SetHighlightItems(!GameMapGump::isHighlightItems());
00593 }
00594 
00595 void GameMapGump::ConCmd_dumpMap(const Console::ArgvType &)
00596 {
00597         // We only support 32 bits per pixel for now
00598         if (RenderSurface::format.s_bpp != 32) return;
00599 
00600         // Actual size 
00601         sint32 awidth = 8192;
00602         sint32 aheight = 8192;
00603 
00604         sint32 xpos = 0;
00605         sint32 ypos = 0;
00606 
00607         sint32 left = 16384;
00608         sint32 right = -16384;
00609         sint32 top = 16384;
00610         sint32 bot = -16384;
00611 
00612         sint32 camheight = 256;
00613 
00614         // Work out the map limit we do this very coarsly
00615         // Now render the map
00616         for (sint32 y = 0; y < 64; y++)
00617         {
00618                 for (sint32 x = 0; x < 64; x++)
00619                 {
00620                         const std::list<Item *> *list =
00621                                 World::get_instance()->getCurrentMap()->getItemList(x,y);
00622 
00623                         // Should iterate the items!
00624                         // (items could extend outside of this chunk and they have height)
00625                         if (list && list->size() != 0) 
00626                         {
00627                                 sint32 l = (x*512 - y*512)/4 - 128;
00628                                 sint32 r = (x*512 - y*512)/4 + 128;
00629                                 sint32 t = (x*512 + y*512)/8 - 256;
00630                                 sint32 b = (x*512 + y*512)/8;
00631 
00632                                 t -= 256; // approx. adjustment for height of items in chunk
00633 
00634                                 if (l < left) left = l;
00635                                 if (r > right) right = r;
00636                                 if (t < top) top = t;
00637                                 if (b > bot) bot = b;
00638                         }
00639                 }
00640         }
00641 
00642         if (right == -16384) return;
00643 
00644         // camera height
00645         bot += camheight;
00646         top += camheight;
00647 
00648         awidth = right-left;
00649         aheight = bot-top;
00650 
00651         ypos = top;
00652         xpos = left;
00653 
00654         // Buffer Size
00655         sint32 bwidth = awidth;
00656         sint32 bheight = 256;
00657 
00658         // Tile size
00659         sint32 twidth = bwidth/8;
00660         sint32 theight = bheight;
00661 
00662 
00663         GameMapGump* g = new GameMapGump(0, 0, twidth, theight);
00664         bool isInvisible = (getMainActor()->getFlags() & Item::FLG_INVISIBLE) != 0;
00665         getMainActor()->setFlag(Item::FLG_INVISIBLE);
00666         World::get_instance()->getCurrentMap()->setWholeMapFast();
00667 
00668         RenderSurface* s = RenderSurface::CreateSecondaryRenderSurface(bwidth,
00669                                                                                                                                    bheight);
00670         Texture* t = s->GetSurfaceAsTexture();
00671         // clear buffer
00672         std::memset(t->buffer, 0, 4*bwidth*bheight);
00673 
00674 
00675         // Write tga header
00676         std::string filename = "@home/mapdump";
00677         char buf[32];
00678         sprintf(buf, "%02d",  World::get_instance()->getCurrentMap()->getNum());
00679         filename += buf;
00680         filename += ".png";
00681         ODataSource *ds = FileSystem::get_instance()->WriteFile(filename);
00682         std::string pngcomment = "Map ";
00683         pngcomment += buf;
00684         pngcomment += ", dumped by Pentagram.";
00685 
00686         PNGWriter* pngw = new PNGWriter(ds);
00687         pngw->init(awidth, aheight, pngcomment);
00688 
00689         // Now render the map
00690         for (sint32 y = 0; y < aheight; y+=theight)
00691         {
00692                 for (sint32 x = 0; x < awidth; x+=twidth)
00693                 {
00694                         // Work out 'effective' and world coords
00695                         sint32 ex = xpos+x+twidth/2;
00696                         sint32 ey = ypos+y+theight/2;
00697                         sint32 wx = ex*2 + ey*4;
00698                         sint32 wy = ey*4 - ex*2;
00699 
00700                         s->SetOrigin(x,y%bheight);
00701                         CameraProcess::SetCameraProcess(
00702                                 new CameraProcess(wx+4*camheight, wy+4*camheight, camheight));
00703                         g->Paint(s, 256, false);
00704 
00705                 }
00706 
00707                 // Write out the current buffer
00708                 if (((y+theight)%bheight) == 0) {
00709                         for (int i = 0; i < bwidth*bheight; ++i) {
00710                                 // Convert to correct pixel format
00711                                 uint8 r, g, b;
00712                                 UNPACK_RGB8(t->buffer[i],r,g,b);
00713                                 uint8 *buf = reinterpret_cast<uint8*>(&t->buffer[i]);
00714                                 buf[0] = b; buf[1] = g; buf[2] = r; buf[3] = 0xFF;
00715                         }
00716 
00717                         pngw->writeRows(bheight, t);
00718 
00719                         // clear buffer for next set
00720                         std::memset(t->buffer, 0, 4*bwidth*bheight);
00721                 }
00722         }
00723 
00724         pngw->finish();
00725         delete pngw;
00726 
00727         delete ds;
00728 
00729         delete g;
00730         delete s;
00731 
00732         if (!isInvisible)
00733                 getMainActor()->clearFlag(Item::FLG_INVISIBLE);
00734 
00735         CameraProcess::SetCameraProcess(new CameraProcess(1));
00736 
00737         pout << "Map stored in " << filename << "." << std::endl;
00738 }
00739 
00740 void GameMapGump::RenderSurfaceChanged()
00741 {
00742         dims.x += dims.w/2;
00743         dims.y += dims.h/2;
00744 
00745         // Resize the desktop gump to match the parent
00746         Pentagram::Rect new_dims;
00747         parent->GetDims(new_dims);
00748         dims.w = new_dims.w;
00749         dims.h = new_dims.h;
00750 
00751         dims.x -= dims.w/2;
00752         dims.y -= dims.h/2;
00753 
00754         Gump::RenderSurfaceChanged();
00755 }
00756 
00757 void GameMapGump::saveData(ODataSource* ods)
00758 {
00759         CANT_HAPPEN_MSG("Trying to save GameMapGump");
00760 }
00761 
00762 bool GameMapGump::loadData(IDataSource* ids, uint32 version)
00763 {
00764         CANT_HAPPEN_MSG("Trying to load GameMapGump");
00765 
00766         return false;
00767 }
00768 
00769 
00770 // Colourless Protection

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