1 /***************************************************************************
2 mapeditor.cpp - The (not yet supported) map editor
3 -------------------
4 begin : Tue Jun 18 2005
5 copyright : (C) 2005 by Gabor Torok
6 email : cctorok@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "common/constants.h"
19 #include "mapeditor.h"
20 #include "render/renderlib.h"
21 #include "rpg/rpglib.h"
22 #include "mapwidget.h"
23 #include "sdlhandler.h"
24 #include "scourge.h"
25 #include "partyeditor.h"
26 #include "item.h"
27 #include "creature.h"
28 #include "shapepalette.h"
29 #include "outdoorgenerator.h"
30 #include "dungeongenerator.h"
31
32 using namespace std;
33
34 #define OUTDOOR_TEXTURE_WIDTH 4
35 #define OUTDOOR_TEXTURE_DEPTH 4
36
37 char *floorTypeName[2][80] = {
38 { "FLOOR_TILE", N_( "Tile: Passage" ) },
39 { "ROOM_FLOOR_TILE", N_( "Tile: Room" ) }
40 };
41
42 /**
43 *@author Gabor Torok
44 */
45
46
47 /*
48 TODO:
49 - ability to "name" item, shape, creature. Then text file can reference name.
50 - need to call ShapePalette::decrementSkinRefCount() when closing map?
51 */
52
contains(vector<Shape * > * seen,Shape * shape)53 bool contains( vector<Shape*> *seen, Shape *shape ) {
54 for ( int i = 0; i < static_cast<int>( seen->size() ); i++ ) {
55 if ( ( *seen )[i] == shape ) return true;
56 }
57 return false;
58 }
59
MapEditor(Scourge * scourge)60 MapEditor::MapEditor( Scourge *scourge ) {
61 this->scourge = scourge;
62
63 // default map settings
64 level = 1;
65 depth = 0;
66
67 outdoorTextureAngle = 0;
68 outdoorTextureHorizFlip = outdoorTextureVertFlip = false;
69
70 mapSettings = new EditorMapSettings();
71
72 scourge->getMap()->setMapRenderHelper( MapRenderHelper::helpers[ MapRenderHelper::ROOM_HELPER ] );
73
74 createNewMapDialog();
75
76 scourge->getShapePalette()->loadAllShapes();
77
78 int w = 200;
79 mainWin = new Window( scourge->getSDLHandler(),
80 scourge->getScreenWidth() - w, 0,
81 w, scourge->getScreenHeight(),
82 _( "Map Editor" ), false, Window::BASIC_WINDOW,
83 GuiTheme::DEFAULT_THEME );
84 mainWin->setVisible( false );
85 mainWin->setLocked( true );
86
87 int startx = 8;
88 w -= 2;
89
90 int yy = 8;
91 int ystep = 24;
92
93 mainWin->createLabel( 5, yy + 10, _( "Name:" ) );
94 nameText = mainWin->createTextField( 60, yy, 10 );
95 yy += ystep;
96
97 loadButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Load" ) );
98 saveButton = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 5, yy + 20, _( "Save" ) );
99 yy += ystep;
100
101 wallButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Wall" ), true );
102 toggleButtonList.push_back( wallButton );
103 wallButton->setSelected( true );
104 doorButton = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 10, yy + 20, _( "Door" ), true );
105 toggleButtonList.push_back( doorButton );
106 yy += ystep;
107
108
109
110 newButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "New Map" ) );
111 floorType = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 10, yy + 20, _( floorTypeName[ 1 ][ 1 ] ), true );
112 yy += ystep;
113
114 startPosButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Start Pos" ), true );
115 toggleButtonList.push_back( startPosButton );
116 yy += ystep;
117
118 rugButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Rug" ), true );
119 toggleButtonList.push_back( rugButton );
120 secretButton = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 10, yy + 20, _( "Secret" ), true );
121 toggleButtonList.push_back( secretButton );
122 yy += ystep;
123 trapButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Trap" ), true );
124 toggleButtonList.push_back( trapButton );
125 roofButton = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 10, yy + 20, _( "Show Roofs" ), true );
126 roofButton->setSelected( true );
127 //toggleButtonList.push_back( roofButton );
128 yy += ystep;
129
130 lowerButton = mainWin->createButton( startx, yy, ( w - 10 ) / 2, yy + 20, _( "Lower" ), true );
131 toggleButtonList.push_back( lowerButton );
132 lowerButton->setSelected( false );
133 lowerButton->setEnabled( false );
134 raiseButton = mainWin->createButton( ( w - 10 ) / 2 + 5, yy, w - 10, yy + 20, _( "Raise" ), true );
135 toggleButtonList.push_back( raiseButton );
136 raiseButton->setSelected( false );
137 raiseButton->setEnabled( false );
138 yy += ystep;
139
140
141 // Lists
142 vector<Shape*> seen;
143
144 // items
145 itemButton = mainWin->createButton( startx, yy, w - 10, yy + 20, _( "Item" ), true );
146 toggleButtonList.push_back( itemButton );
147 yy += ystep;
148 itemList = new ScrollingList( startx, yy, w - 16, 75,
149 scourge->getShapePalette()->getHighlightTexture() );
150 mainWin->addWidget( itemList );
151 yy += 79;
152
153
154 furnitureButton = mainWin->createButton( startx, yy, w - 10, yy + 20, _( "Furniture" ), true );
155 toggleButtonList.push_back( furnitureButton );
156 yy += ystep;
157 furnitureList = new ScrollingList( startx, yy, w - 16, 75,
158 scourge->getShapePalette()->getHighlightTexture() );
159 mainWin->addWidget( furnitureList );
160 yy += 79;
161
162 // separate items from furniture
163 map<string, const RpgItem *> *itemMap = RpgItem::getItemMap();
164 vector<RpgItem*> itemVector;
165 vector<RpgItem*> furnitureVector;
166 for ( map<string, const RpgItem*>::iterator i = itemMap->begin();
167 i != itemMap->end(); ++i ) {
168 string name = i->first;
169 RpgItem *item = ( RpgItem* )( i->second );
170 Shape *shape = scourge->getShapePalette()->getShape( item->getShapeIndex() );
171 seen.push_back( shape );
172 if ( item->isContainer() || item->isOther() ) {
173 furnitureVector.push_back( item );
174 } else {
175 itemVector.push_back( item );
176 }
177 }
178
179 itemNames = new string[ itemVector.size() ];
180 for ( unsigned int i = 0; i < itemVector.size(); i++ ) {
181 itemNames[ i ] = itemVector[ i ]->getDisplayName();
182 }
183 itemList->setLines( itemVector.size(), itemNames );
184
185 furnitureNames = new string[ furnitureVector.size() ];
186 for ( unsigned int i = 0; i < furnitureVector.size(); i++ ) {
187 furnitureNames[ i ] = furnitureVector[ i ]->getDisplayName();
188 }
189 furnitureList->setLines( furnitureVector.size(), furnitureNames );
190
191 // creatures
192 creatureButton = mainWin->createButton( startx, yy, w - 10, yy + 20, _( "Creature" ), true );
193 toggleButtonList.push_back( creatureButton );
194 yy += ystep;
195 creatureList = new ScrollingList( startx, yy, w - 16, 75,
196 scourge->getShapePalette()->getHighlightTexture() );
197 mainWin->addWidget( creatureList );
198 yy += 79;
199 map<string, Monster*> *creatureMap = &( Monster::monstersByName );
200 creatureNames = new string[ creatureMap->size() ];
201 int count = 0;
202 for ( map<string, Monster*>::iterator i = creatureMap->begin()
203 ; i != creatureMap->end(); ++i ) {
204 string name = i->first;
205 Monster *monster = i->second;
206
207 // find its place by level
208 int index = count;
209 for ( int t = 0; t < count; t++ ) {
210 Monster *m = creatures[ creatureNames[ t ] ];
211 if ( m->getLevel() > monster->getLevel() ) {
212 index = t;
213 break;
214 }
215 }
216
217 // make room
218 for ( int t = count - 1; t >= index; t-- ) {
219 creatureNames[ t + 1 ] = creatureNames[ t ];
220 }
221 count++;
222
223 // add new creature
224 creatureNames[ index ] = monster->isNpc() ? "NPC " : "";
225 char levelStr[ 20 ];
226 snprintf( levelStr, 20, "%d - ", monster->getLevel() );
227 creatureNames[ index ] += levelStr + name;
228 creatures[ creatureNames[ index ] ] = monster;
229 }
230 creatureList->setLines( creatureMap->size(), creatureNames );
231
232 // shapes
233 shapeButton = mainWin->createButton( startx, yy, w - 10, yy + 20, _( "Shape" ), true );
234 toggleButtonList.push_back( shapeButton );
235 yy += ystep;
236 shapeList = new ScrollingList( startx, yy, w - 16, 75,
237 scourge->getShapePalette()->getHighlightTexture() );
238 mainWin->addWidget( shapeList );
239 yy += 79;
240
241 map< string, GLShape* > *shapeMap = scourge->getShapePalette()->getShapeMap();
242 shapeNames = new std::string[shapeMap->size()];
243 count = 0;
244 for ( map<string, GLShape*>::iterator i = shapeMap->begin(); i != shapeMap->end(); ++i ) {
245 GLShape *shape = i->second;
246 if ( !contains( &seen, shape ) && shape->isShownInMapEditor() ) {
247 shapeNames[ count ] = i->first;
248 count++;
249 }
250 }
251 shapeList->setLines( count, shapeNames );
252
253 // outdoor textures
254 outdoorTexturesButton = mainWin->createButton( startx, yy, w - 10, yy + 20, _( "Outdoor Textures" ), true );
255 outdoorTexturesButton->setEnabled( false );
256 toggleButtonList.push_back( outdoorTexturesButton );
257 yy += ystep;
258 outdoorTexturesList = new ScrollingList( startx, yy, w - 16, 75, scourge->getShapePalette()->getHighlightTexture() );
259 mainWin->addWidget( outdoorTexturesList );
260 yy += 79;
261
262 count = 0;
263 outdoorTextureNames = new string[ WallTheme::OUTDOOR_THEME_REF_COUNT ];
264 for ( int i = 0; i < WallTheme::OUTDOOR_THEME_REF_COUNT; i++ ) {
265 outdoorTextureNames[ count++ ] = WallTheme::outdoorThemeRefName[ i ];
266 }
267 outdoorTexturesList->setLines( count, outdoorTextureNames );
268
269 miniMap = new MiniMap( scourge );
270 }
271
createNewMapDialog()272 void MapEditor::createNewMapDialog() {
273 // new map ui
274 int nw = 450;
275 int nh = 430;
276 newMapWin = new Window( scourge->getSDLHandler(),
277 40, 40, nw, nh,
278 _( "Map Properties" ),
279 false,
280 Window::BASIC_WINDOW,
281 GuiTheme::DEFAULT_THEME );
282 newMapWin->setVisible( false );
283 newMapWin->setModal( true );
284 int startx = 8;
285 enum { TMP_SIZE = 300 };
286 char tmp[ TMP_SIZE ];
287 snprintf( tmp, TMP_SIZE, "%s (0-50):", _( "Map level" ) );
288 newMapWin->createLabel( startx, 20, tmp );
289 levelText = newMapWin->createTextField( 150, 10, 20 );
290 snprintf( tmp, TMP_SIZE, "%s (0-10):", _( "Map depth" ) );
291 newMapWin->createLabel( startx, 40, tmp );
292 depthText = newMapWin->createTextField( 150, 30, 20 );
293 newMapWin->createLabel( startx, 60, _( "Map theme:" ) );
294 nw -= 12;
295
296
297 themeList = new ScrollingList( 150, 50, 220, 60,
298 scourge->getShapePalette()->getHighlightTexture() );
299 newMapWin->addWidget( themeList );
300 themeNames = new string[ scourge->getShapePalette()->getAllThemeCount() ];
301
302 for ( int i = 0; i < scourge->getShapePalette()->getAllThemeCount(); i++ ) {
303 themeNames[ i ] = scourge->getShapePalette()->getAllThemeName( i );
304 if ( scourge->getShapePalette()->isThemeSpecial( i ) )
305 themeNames[i] += "(S)";
306 }
307 themeList->setLines( scourge->getShapePalette()->getAllThemeCount(), themeNames );
308
309 newMapWin->createLabel( startx, 135, _( "Outdoor Map:" ) );
310 outdoorMapButton = newMapWin->createButton( startx + 100, 120, startx + 200, 140, "Outdoors", true );
311
312 newMapWin->createLabel( startx + 210, 135, _( "Dungeon Map:" ) );
313 dungeonMapButton = newMapWin->createButton( startx + 310, 120, startx + 410, 140, "Dungeon", true );
314
315 newMapWin->createLabel( startx, 160, _( "Select map location: (click on map, drag to move)" ) );
316 mapWidget = new MapWidget( scourge, newMapWin, startx, 170, nw - startx, 335 );
317 newMapWin->addWidget( mapWidget->getCanvas() );
318
319 int bw = nw / 6;
320 okButton = newMapWin->createButton( nw - bw * 3 - 10, 375, nw - bw * 2 - 5, 395, _( "New Map" ) );
321 applyButton = newMapWin->createButton( nw - bw * 2 + 5, 375, nw - bw - 5, 395, _( "Apply" ) );
322 cancelButton = newMapWin->createButton( nw - bw, 375, nw - 5, 395, _( "Cancel" ) );
323 }
324
~MapEditor()325 MapEditor::~MapEditor() {
326 // map< string, GLShape* > *shapeMap = scourge->getShapePalette()->getShapeMap();
327 delete[] shapeNames;
328 delete[] itemNames;
329 delete mainWin;
330 delete miniMap;
331 }
332
drawView()333 void MapEditor::drawView() {
334
335 scourge->getMap()->preDraw();
336 scourge->getMap()->draw();
337 scourge->getMap()->postDraw();
338
339 miniMap->drawMap();
340
341 glDisable( GL_CULL_FACE );
342 glDisable( GL_SCISSOR_TEST );
343
344 glDisable( GL_CULL_FACE );
345 glDisable( GL_DEPTH_TEST );
346 glDisable( GL_TEXTURE_2D );
347 glPushMatrix();
348 glColor3f( 1, 0, 0 );
349
350 glLoadIdentity();
351
352 if ( scourge->getMap()->getCursorFlatMapX() < MAP_WIDTH &&
353 scourge->getMap()->getCursorFlatMapY() < MAP_DEPTH ) {
354 Location *pos = scourge->getMap()->getLocation( scourge->getMap()->getCursorFlatMapX(),
355 scourge->getMap()->getCursorFlatMapY(),
356 0 );
357 scourge->getSDLHandler()->texPrint( 50, 120, "F:%d,%d,%d C:%d,%d %s=%s %s=%s %s=%s",
358 scourge->getMap()->getCursorFlatMapX(),
359 scourge->getMap()->getCursorFlatMapY(),
360 scourge->getMap()->cursorZ,
361 scourge->getMap()->getCursorChunkX(),
362 scourge->getMap()->getCursorChunkY(),
363 _( "Shape" ),
364 ( pos && pos->shape ? pos->shape->getName() : "NULL" ),
365 _( "Item" ),
366 ( pos && pos->item ? ( ( Item* )( pos->item ) )->getRpgItem()->getDisplayName() : "NULL" ),
367 _( "Creature" ),
368 ( pos && pos->creature ? pos->creature->getName() : "NULL" ) );
369 }
370 if ( outdoorTexturesButton->isSelected() ) {
371 glColor3f( 1, 1, 0 );
372 scourge->getSDLHandler()->texPrint( 50, 130, "Keys: z,x - rotate, q,w - mirror" );
373 glColor3f( 1, 0, 0 );
374 }
375 glTranslatef( 50, 50, 0 );
376 glRotatef( scourge->getMap()->getZRot(), 0, 0, 1 );
377
378 int n = 30;
379 glBegin( GL_LINES );
380 glVertex2f( 0, 0 );
381 glVertex2f( 0, n );
382
383 glVertex2f( 0, 0 );
384 glVertex2f( -n / 2, n / 2 );
385
386 glVertex2f( 0, 0 );
387 glVertex2f( n / 2, n / 2 );
388 glEnd();
389
390 glPopMatrix();
391
392
393 }
394
drawAfter()395 void MapEditor::drawAfter() {
396 }
397
handleEvent(SDL_Event * event)398 bool MapEditor::handleEvent( SDL_Event *event ) {
399 scourge->getMap()->cursorWidth = scourge->getMap()->cursorDepth = 1;
400 scourge->getMap()->cursorHeight = MAP_WALL_HEIGHT;
401 if ( outdoorTexturesButton->isSelected() ) {
402 int ref = outdoorTexturesList->getSelectedLine();
403 scourge->getMap()->cursorWidth = scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureWidth( ref );
404 scourge->getMap()->cursorDepth = scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureHeight( ref );
405 scourge->getMap()->cursorHeight = 1;
406 } else {
407 GLShape *shape;
408 if ( getShape( &shape ) ) {
409 scourge->getMap()->cursorWidth = shape->getWidth();
410 scourge->getMap()->cursorDepth = shape->getDepth();
411 scourge->getMap()->cursorHeight = shape->getHeight();
412 }
413 }
414
415 // find the highest point under the cursor
416 int maxz = 0;
417 for ( int gx = 0; gx < scourge->getMap()->cursorWidth; gx++ ) {
418 for ( int gy = 0; gy < scourge->getMap()->cursorDepth; gy++ ) {
419 for ( int i = MAP_VIEW_HEIGHT - 1; i >= 0; i-- ) {
420 Location *pos = scourge->getMap()->getLocation( scourge->getMap()->getCursorFlatMapX() + gx,
421 scourge->getMap()->getCursorFlatMapY() - gy,
422 i );
423 if ( pos && pos->shape && !( ( GLShape* )pos->shape )->hasVirtualShapes() && !pos->shape->isRoof() && maxz < i + 1 ) {
424 maxz = i + 1;
425 }
426 }
427 }
428 }
429 //scourge->getMap()->cursorZ = ( maxz >= MAP_VIEW_HEIGHT - 1 ? 0 : maxz + 1 );
430 //int editorZ = scourge->getMap()->cursorZ;
431 //if( !maxz ) editorZ = 0;
432
433 int editorZ = scourge->getMap()->cursorZ = maxz;
434
435
436 scourge->getMap()->handleEvent( event );
437
438 switch ( event->type ) {
439 //case SDL_MOUSEMOTION:
440 /*
441 if( event->motion.state == SDL_BUTTON_LEFT &&
442 newMapWin->isVisible() ) {
443 mapWidget->setPosition( scourge->getMouseX() - newMapWin->getX() - mapWidget->getCanvas()->getX(),
444 scourge->getMouseY() - newMapWin->getY() - mapWidget->getCanvas()->getY() - Window::TOP_HEIGHT );
445 }
446 */
447 case SDL_MOUSEBUTTONUP:
448 processMouseMotion( event->button.button, editorZ );
449 break;
450 case SDL_KEYUP:
451 if ( event->key.keysym.sym == SDLK_ESCAPE ) {
452 hide();
453 return true;
454 } else if ( event->key.keysym.sym == SDLK_KP_PLUS ||
455 event->key.keysym.sym == SDLK_KP_MINUS ) {
456 miniMap->setShowMiniMap( miniMap->isMiniMapShown() ? false : true );
457 return false;
458 } else if ( event->key.keysym.sym == SDLK_x ) {
459 outdoorTextureAngle += 90;
460 if ( outdoorTextureAngle >= 360 ) outdoorTextureAngle -= 360;
461 } else if ( event->key.keysym.sym == SDLK_z ) {
462 outdoorTextureAngle -= 90;
463 if ( outdoorTextureAngle < 360 ) outdoorTextureAngle += 360;
464 } else if ( event->key.keysym.sym == SDLK_q ) {
465 outdoorTextureHorizFlip = !( outdoorTextureHorizFlip );
466 } else if ( event->key.keysym.sym == SDLK_w ) {
467 outdoorTextureVertFlip = !( outdoorTextureVertFlip );
468 } else if ( event->key.keysym.sym == SDLK_s ) {
469 scourge->getSquirrelConsole()->setVisible( scourge->getSquirrelConsole()->isVisible() ? false : true );
470 } else if ( event->key.keysym.sym == SDLK_g ) {
471 scourge->getMap()->setGridEnabled( scourge->getMap()->isGridEnabled() ? false : true );
472 }
473 break;
474 default: break;
475 }
476 return false;
477 }
478
handleEvent(Widget * widget,SDL_Event * event)479 bool MapEditor::handleEvent( Widget *widget, SDL_Event *event ) {
480
481 int found = -1;
482 for ( int i = 0; i < static_cast<int>( toggleButtonList.size() ); i++ ) {
483 if ( toggleButtonList[ i ] == widget ) {
484 found = i;
485 break;
486 }
487 }
488 if ( found > -1 ) {
489 for ( int i = 0; i < static_cast<int>( toggleButtonList.size() ); i++ ) {
490 toggleButtonList[ i ]->setSelected( i == found );
491 }
492 }
493
494 string result;
495 if ( widget == roofButton ) {
496 scourge->getMap()->setRoofShowing( roofButton->isSelected() );
497 } else if ( widget == saveButton ) {
498 string tmp( nameText->getText() );
499 scourge->getMap()->saveMap( tmp, result );
500 scourge->showMessageDialog( result.c_str() );
501 // scourge->getParty()->toggleRound( false );
502 } else if ( widget == loadButton ) {
503 string tmp( nameText->getText() );
504 scourge->getMap()->loadMap( tmp, result );
505 if ( scourge->getMap()->isHeightMapEnabled() ) {
506 lowerButton->setEnabled( true );
507 raiseButton->setEnabled( true );
508 outdoorTexturesButton->setEnabled( true );
509 }
510 scourge->showMessageDialog( result.c_str() );
511 // scourge->getParty()->toggleRound( false );
512 } else if ( widget == newButton ) {
513 newMapWin->setVisible( true );
514 stringstream tmp;
515 tmp << this->level;
516 levelText->setText( tmp.str().c_str() );
517 tmp.clear();
518 tmp << this->depth;
519 depthText->setText( tmp.str().c_str() );
520 // FIXME: select theme!
521 cerr << "FIXME: select theme!" << endl;
522 mapWidget->setSelection( scourge->getMap()->mapGridX, scourge->getMap()->mapGridY );
523 } else if ( widget == okButton || widget == applyButton ) {
524 newMapWin->setVisible( false );
525
526 this->level = atoi( levelText->getText() );
527 this->depth = atoi( depthText->getText() );
528 if ( widget == okButton ) {
529 scourge->getMap()->reset();
530 int line = themeList->getSelectedLine();
531 if ( line > -1 ) {
532 string str = themeNames[ line ];
533 int pos = str.rfind( "(S)" );
534 if ( pos == str.size() - 3 ) str.erase( pos );
535 scourge->getShapePalette()->loadTheme( str.c_str() );
536 }
537
538 if ( outdoorMapButton->isSelected() ) {
539 scourge->getMap()->setMapRenderHelper( MapRenderHelper::helpers[ MapRenderHelper::OUTDOOR_HELPER ] );
540 OutdoorGenerator *og = new OutdoorGenerator( scourge, level, depth, 1, false, false, NULL );
541 og->toMap( scourge->getMap(), scourge->getShapePalette(), false, false );
542 delete og;
543 raiseButton->setEnabled( true );
544 lowerButton->setEnabled( true );
545 outdoorTexturesButton->setEnabled( true );
546 } else if ( dungeonMapButton->isSelected() ) {
547 scourge->getMap()->setMapRenderHelper( MapRenderHelper::helpers[ MapRenderHelper::ROOM_HELPER ] );
548 DungeonGenerator *og = new DungeonGenerator( scourge, level, depth, 1, false, false, NULL );
549 og->toMap( scourge->getMap(), scourge->getShapePalette(), false, false );
550 delete og;
551 } else {
552 scourge->getMap()->setMapRenderHelper( MapRenderHelper::helpers[ MapRenderHelper::ROOM_HELPER ] );
553 lowerButton->setEnabled( false );
554 raiseButton->setEnabled( false );
555 outdoorTexturesButton->setEnabled( false );
556 }
557 }
558 mapWidget->getSelection( &( scourge->getMap()->mapGridX ), &( scourge->getMap()->mapGridY ) );
559
560 } else if ( widget == cancelButton ) {
561 newMapWin->setVisible( false );
562 } else if ( widget == floorType ) {
563 floorType->setLabel( _( floorTypeName[ floorType->isSelected() ? 0 : 1 ][ 1 ] ) );
564 } else if ( widget == mapWidget->getCanvas() ) {
565 // mapWidget->setPosition( scourge->getMouseX() - newMapWin->getX() - mapWidget->getCanvas()->getX(),
566 // scourge->getMouseY() - newMapWin->getY() - mapWidget->getCanvas()->getY() - Window::TOP_HEIGHT );
567 } else if ( widget == scourge->getSquirrelRun() ||
568 widget == scourge->getSquirrelText() ) {
569 scourge->runSquirrelConsole();
570 } else if ( widget == scourge->getSquirrelClear() ) {
571 scourge->clearSquirrelConsole();
572 } else if ( widget == scourge->getSquirrelReload() ) {
573 scourge->runSquirrelConsole( "scourgeGame.reloadNuts();" );
574 }
575 return false;
576 }
577
show()578 void MapEditor::show() {
579 scourge->getMap()->setMapSettings( mapSettings );
580 scourge->getMap()->reset();
581 scourge->getMap()->center( MAP_WIDTH / 2, MAP_DEPTH / 2, true );
582 scourge->getMap()->setViewArea( 0, 0,
583 mainWin->getX(),
584 mainWin->getY() + mainWin->getHeight() );
585 scourge->getShapePalette()->loadTheme( "egypt" );
586 mainWin->setVisible( true );
587 }
588
hide()589 void MapEditor::hide() {
590 mainWin->setVisible( false );
591 scourge->getMap()->setMapSettings( scourge->getMapSettings() );
592 }
593
getShape(GLShape ** shape,Item ** item,Creature ** creature)594 bool MapEditor::getShape( GLShape **shape,
595 Item **item,
596 Creature **creature ) {
597 *shape = NULL;
598 if ( item ) *item = NULL;
599 if ( creature ) *creature = NULL;
600 if ( creatureButton->isSelected() &&
601 creatureList->getSelectedLine() > -1 ) {
602 string s = creatureNames[ creatureList->getSelectedLine() ];
603 Monster *monster = creatures[ s ];
604 //Monster *monster = Monster::getMonsterByName( creatureNames[ creatureList->getSelectedLine() ] );
605 // cache creature shapes
606 if ( creatureOutlines.find( monster ) == creatureOutlines.end() ) {
607 creatureOutlines[ monster ] = scourge->getSession()->getShapePalette()->
608 getCreatureShape( monster->getModelName(),
609 monster->getSkinName(),
610 monster->getScale(),
611 monster );
612 }
613 *shape = creatureOutlines[ monster ];
614 if ( creature ) {
615 cerr << "new creature" << endl;
616 *creature = scourge->getSession()->newCreature( monster, *shape );
617 }
618 return true;
619 } else if ( itemButton->isSelected() &&
620 itemList->getSelectedLine() > -1 ) {
621 addNewItem( itemNames[ itemList->getSelectedLine() ].c_str(), shape, item, creature );
622 return true;
623 } else if ( furnitureButton->isSelected() &&
624 furnitureList->getSelectedLine() > -1 ) {
625 addNewItem( furnitureNames[ furnitureList->getSelectedLine() ].c_str(), shape, item, creature );
626 return true;
627 } else if ( shapeButton->isSelected() &&
628 shapeList->getSelectedLine() > -1 ) {
629 *shape = scourge->getShapePalette()->
630 findShapeByName( shapeNames[ shapeList->getSelectedLine() ].c_str() );
631 return true;
632 } else {
633 return false;
634 }
635 }
636
addNewItem(char const * name,GLShape ** shape,Item ** item,Creature ** creature)637 void MapEditor::addNewItem( char const* name,
638 GLShape **shape,
639 Item **item,
640 Creature **creature ) {
641 RpgItem *rpgItem = RpgItem::getItemByName( name );
642 *shape = scourge->getShapePalette()->getShape( rpgItem->getShapeIndex() );
643 if ( item ) {
644 cerr << "new item" << endl;
645 *item = scourge->getSession()->newItem( rpgItem, level );
646 // fill the container with random items
647 if ( rpgItem->isContainer() ) {
648 // some items
649 int n = Util::dice( 3 );
650 for ( int i = 0; i < n; i++ ) {
651 RpgItem *containedItem = RpgItem::getRandomItem( depth );
652 if ( containedItem )
653 ( *item )->addContainedItem( scourge->getSession()->
654 newItem( containedItem, level ),
655 true );
656 }
657 // some spells
658 if ( 0 == Util::dice( 25 ) ) {
659 int n = Util::pickOne( 1, 2 );
660 int spellLevel = level / 5;
661 for ( int i = 0; i < n; i++ ) {
662 Spell *spell = MagicSchool::getRandomSpell( spellLevel );
663 if ( spell ) {
664 Item *scroll = scourge->getSession()->
665 newItem( RpgItem::getItemByName( "Scroll" ), level, spell );
666 ( *item )->addContainedItem( scroll, true );
667 }
668 }
669 }
670
671 // print summary
672 cerr << "Container contents:" << endl;
673 for ( int i = 0; i < ( *item )->getContainedItemCount(); i++ ) {
674 cerr << "\t" << ( *item )->getContainedItem( i )->getRpgItem()->getDisplayName() << endl;
675 }
676 }
677 }
678 }
679
processMouseMotion(Uint8 button,int editorZ)680 void MapEditor::processMouseMotion( Uint8 button, int editorZ ) {
681 if ( scourge->getSDLHandler()->mouseX < mainWin->getX() &&
682 ( button == SDL_BUTTON_LEFT ||
683 button == SDL_BUTTON_RIGHT &&
684 ( SDL_GetModState() & KMOD_SHIFT ) ) ) {
685
686 // draw the correct walls in this chunk
687 int xx = scourge->getMap()->getCursorFlatMapX();
688 int yy = scourge->getMap()->getCursorFlatMapY() - 1;
689
690 if ( startPosButton->isSelected() ) {
691 scourge->getMap()->startx = xx;
692 scourge->getMap()->starty = yy;
693 return;
694 }
695
696 int mapx = ( ( xx - MAP_OFFSET ) / MAP_UNIT ) * MAP_UNIT + MAP_OFFSET;
697 int mapy = ( ( yy - MAP_OFFSET ) / MAP_UNIT ) * MAP_UNIT + MAP_OFFSET;
698
699 //int mapx = scourge->getMap()->getCursorChunkX() * MAP_UNIT + MAP_OFFSET;
700 //int mapy = scourge->getMap()->getCursorChunkY() * MAP_UNIT + MAP_OFFSET;
701
702 GLShape *shape;
703 if ( button == SDL_BUTTON_LEFT ) {
704 if ( outdoorTexturesButton->isSelected() ) {
705 if ( outdoorTexturesList->getSelectedLine() > -1 ) {
706 //string s = outdoorTextureNames[ outdoorTexturesList->getSelectedLine() ];
707 //NamedOutdoorTexture *ot = scourge->getShapePalette()->getOutdoorNamedTexture( s );
708 int ref = outdoorTexturesList->getSelectedLine();
709 int faceCount = scourge->getShapePalette()->getCurrentTheme()->getOutdoorFaceCount( ref );
710 if ( faceCount == 0 ) {
711 cerr << "Map Editor Error: no textures for outdoor theme! ref=" << WallTheme::outdoorThemeRefName[ref] << endl;
712 return;
713 }
714 // int w = scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureWidth( ref );
715 // int h = scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureHeight( ref );
716 scourge->getMap()->setOutdoorTexture( xx, yy + 1,
717 0, 0,
718 ref,
719 outdoorTextureAngle,
720 outdoorTextureHorizFlip,
721 outdoorTextureVertFlip,
722 ROAD_LAYER );
723 }
724 return;
725 } else {
726 Item *item;
727 Creature *creature;
728 if ( getShape( &shape, &item, &creature ) ) {
729 if ( item ) {
730 scourge->getMap()->setItem( xx, yy + 1, editorZ, item );
731 } else if ( creature ) {
732 scourge->getMap()->setCreature( xx, yy + 1, editorZ, creature );
733 creature->moveTo( xx, yy + 1, editorZ );
734 } else if ( shape ) {
735 if ( shape->getIgnoreHeightMap() && !shape->isRoof() ) {
736 for ( int sx = mapx; sx < mapx + shape->getWidth(); sx++ ) {
737 for ( int sy = mapy - shape->getDepth(); sy <= mapy; sy++ ) {
738 flattenChunk( sx, sy );
739 }
740 }
741 }
742 scourge->getMap()->setPosition( xx, yy + 1, editorZ, shape );
743 }
744 return;
745 }
746 }
747 } else if ( button == SDL_BUTTON_RIGHT ) {
748 if ( outdoorTexturesButton->isSelected() ) {
749 int ref = outdoorTexturesList->getSelectedLine();
750 scourge->getMap()->removeOutdoorTexture( xx, yy + 1, scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureWidth( ref ), scourge->getShapePalette()->getCurrentTheme()->getOutdoorTextureHeight( ref ), ROAD_LAYER );
751 } else if ( getShape( &shape ) ) {
752 for ( int sx = 0; sx < shape->getWidth(); sx++ ) {
753 for ( int sy = 0; sy < shape->getDepth(); sy++ ) {
754 for ( int sz = MAP_VIEW_HEIGHT - 1; sz >= 0; sz-- ) {
755 scourge->getMap()->removeLocation( xx + sx, yy - sy + 1, sz );
756 }
757 }
758 }
759 return;
760 }
761 }
762
763 int innerX = xx - mapx;
764 int innerY = yy - mapy;
765
766 // cerr << "pos: " << mapx << "," << mapy <<
767 // " map:" << scourge->getMap()->getCursorFlatMapX() << "," <<
768 // scourge->getMap()->getCursorFlatMapX() << endl;
769
770
771 // find the region in the chunk
772 int mx = -1;
773 int my = -1;
774 int dir = -1;
775 if ( innerX < MAP_UNIT_OFFSET ) {
776 mx = mapx;
777 my = mapy;
778 dir = Constants::WEST;
779 } else if ( innerY < MAP_UNIT_OFFSET ) {
780 mx = mapx;
781 my = mapy;
782 dir = Constants::NORTH;
783 } else if ( innerX >= MAP_UNIT - MAP_UNIT_OFFSET ) {
784 mx = mapx + MAP_UNIT - MAP_UNIT_OFFSET;
785 my = mapy;
786 dir = Constants::EAST;
787 } else if ( innerY >= MAP_UNIT - MAP_UNIT_OFFSET ) {
788 mx = mapx;
789 my = mapy + MAP_UNIT - MAP_UNIT_OFFSET;
790 dir = Constants::SOUTH;
791 }
792
793 if ( dir != -1 ) {
794 if ( secretButton->isSelected() ) {
795 if ( button == SDL_BUTTON_RIGHT ) {
796 removeSecret( xx, yy + 1 );
797 } else {
798 addSecret( xx, yy + 1 );
799 }
800 } else if ( button == SDL_BUTTON_RIGHT ) {
801 removeWall( mx, my, dir );
802 } else if ( wallButton->isSelected() ) {
803 addWall( mx, my, dir );
804 } else if ( doorButton->isSelected() ) {
805 addDoor( mx, my, dir );
806 }
807
808 // blend the corners
809 for ( int x = -1; x <= 1; x++ ) {
810 for ( int y = -1; y <= 1; y++ ) {
811 blendCorners( mapx + ( x * MAP_UNIT ),
812 mapy + ( y * MAP_UNIT ) );
813 }
814 }
815 } else {
816 int chunkX = ( mapx - MAP_OFFSET ) / MAP_UNIT;
817 int chunkY = ( mapy - MAP_OFFSET ) / MAP_UNIT;
818 if ( rugButton->isSelected() ) {
819 if ( button == SDL_BUTTON_RIGHT ) {
820 scourge->getMap()->removeRugPosition( chunkX, chunkY );
821 } else {
822 addRug( chunkX, chunkY );
823 }
824 } else if ( trapButton->isSelected() ) {
825 if ( button == SDL_BUTTON_RIGHT ) {
826 removeTrap( xx, yy );
827 } else {
828 addTrap( xx, yy );
829 }
830 } else {
831 if ( button == SDL_BUTTON_RIGHT ) {
832 removeFloor( mapx, mapy );
833 } else if ( lowerButton->isSelected() ) {
834 lowerGroundHeight( xx, yy );
835 } else if ( raiseButton->isSelected() ) {
836 raiseGroundHeight( xx, yy );
837 } else {
838 addFloor( mapx, mapy );
839 }
840 }
841 }
842 }
843 }
844
addRug(Sint16 mapx,Sint16 mapy)845 void MapEditor::addRug( Sint16 mapx, Sint16 mapy ) {
846 // pick an orientation
847 bool isHorizontal = ( Util::dice( 2 ) == 0 ? true : false );
848
849 // save it
850 Rug rug;
851 rug.isHorizontal = isHorizontal;
852 rug.texture = scourge->getSession()->getShapePalette()->getRandomRug();
853 rug.angle = Util::roll( -15.0f, 15.0f );
854
855 scourge->getMap()->setRugPosition( mapx, mapy, &rug );
856 }
857
addSecret(Sint16 mapx,Sint16 mapy)858 void MapEditor::addSecret( Sint16 mapx, Sint16 mapy ) {
859 Location *pos = scourge->getMap()->getLocation( mapx, mapy, 0 );
860 if ( pos ) {
861 scourge->getMap()->addSecretDoor( pos->x, pos->y );
862 }
863 }
864
removeSecret(Sint16 mapx,Sint16 mapy)865 void MapEditor::removeSecret( Sint16 mapx, Sint16 mapy ) {
866 Location *pos = scourge->getMap()->getLocation( mapx, mapy, 0 );
867 if ( pos ) {
868 scourge->getMap()->removeSecretDoor( pos->x, pos->y );
869 }
870 }
871
addTrap(Sint16 mapx,Sint16 mapy)872 void MapEditor::addTrap( Sint16 mapx, Sint16 mapy ) {
873 int w = Util::pickOne( 4, 9 );
874 int h = Util::pickOne( 4, 9 );
875 scourge->getMap()->addTrap( mapx, mapy, w, h );
876 }
877
removeTrap(Sint16 mapx,Sint16 mapy)878 void MapEditor::removeTrap( Sint16 mapx, Sint16 mapy ) {
879 int trapIndex = scourge->getMap()->getTrapAtLoc( mapx, mapy );
880 if ( trapIndex > -1 ) scourge->getMap()->removeTrap( trapIndex );
881 }
882
flattenChunk(Sint16 mapX,Sint16 mapY)883 void MapEditor::flattenChunk( Sint16 mapX, Sint16 mapY ) {
884 int chunkX = ( mapX - MAP_OFFSET ) / MAP_UNIT;
885 int chunkY = ( mapY - MAP_OFFSET ) / MAP_UNIT;
886 for ( int x = -OUTDOORS_STEP; x <= MAP_UNIT + OUTDOORS_STEP; x++ ) {
887 for ( int y = -OUTDOORS_STEP; y <= MAP_UNIT + OUTDOORS_STEP; y++ ) {
888 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
889 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
890 scourge->getMap()->setGroundHeight( xx, yy, 0 );
891 }
892 }
893 }
894
addWall(Sint16 mapx,Sint16 mapy,int dir)895 void MapEditor::addWall( Sint16 mapx, Sint16 mapy, int dir ) {
896 flattenChunk( mapx, mapy );
897 switch ( dir ) {
898 case Constants::NORTH: addNSWall( mapx, mapy, 1 ); break;
899 case Constants::SOUTH: addNSWall( mapx, mapy, -1 ); break;
900 case Constants::WEST: addEWWall( mapx, mapy, 1 ); break;
901 case Constants::EAST: addEWWall( mapx, mapy, -1 ); break;
902 default: cerr << "*** addWall, Unknown dir=" << dir << endl;
903 }
904 }
905
addDoor(Sint16 mapx,Sint16 mapy,int dir)906 void MapEditor::addDoor( Sint16 mapx, Sint16 mapy, int dir ) {
907 flattenChunk( mapx, mapy );
908 switch ( dir ) {
909 case Constants::NORTH: addNSDoor( mapx, mapy, 1 ); break;
910 case Constants::SOUTH: addNSDoor( mapx, mapy, -1 ); break;
911 case Constants::WEST: addEWDoor( mapx, mapy, 1 ); break;
912 case Constants::EAST: addEWDoor( mapx, mapy, -1 ); break;
913 default: cerr << "*** addDoor, Unknown dir=" << dir << endl;
914 }
915 }
916
removeWall(Sint16 mapx,Sint16 mapy,int dir)917 void MapEditor::removeWall( Sint16 mapx, Sint16 mapy, int dir ) {
918 switch ( dir ) {
919 case Constants::NORTH: removeNSWall( mapx, mapy, 1 ); break;
920 case Constants::SOUTH: removeNSWall( mapx, mapy, -1 ); break;
921 case Constants::WEST: removeEWWall( mapx, mapy, 1 ); break;
922 case Constants::EAST: removeEWWall( mapx, mapy, -1 ); break;
923 default: cerr << "*** removeWall, Unknown dir=" << dir << endl;
924 }
925 }
926
addEWDoor(Sint16 mapx,Sint16 mapy,int dir)927 void MapEditor::addEWDoor( Sint16 mapx, Sint16 mapy, int dir ) {
928 ShapePalette *shapePal = scourge->getShapePalette();
929 if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT / 2, 0 ) ) {
930 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT - MAP_UNIT_OFFSET,
931 MAP_WALL_HEIGHT - 2, shapePal->findShapeByName( "EW_DOOR_TOP" ) );
932 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET + 2,
933 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
934 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET * 2 + 2,
935 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
936 scourge->getMap()->setPosition( mapx + 1, mapy + MAP_UNIT - MAP_UNIT_OFFSET - 2,
937 0, shapePal->findShapeByName( "EW_DOOR" ) );
938 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT - MAP_UNIT_OFFSET,
939 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
940
941 // corners
942 if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 ) ) {
943 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
944 shapePal->findShapeByName( "CORNER" ) );
945 }
946 if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT, 0 ) ) {
947 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT, 0,
948 shapePal->findShapeByName( "CORNER" ) );
949 }
950 }
951 }
952
addNSDoor(Sint16 mapx,Sint16 mapy,int dir)953 void MapEditor::addNSDoor( Sint16 mapx, Sint16 mapy, int dir ) {
954 ShapePalette *shapePal = scourge->getShapePalette();
955 if ( !scourge->getMap()->getLocation( mapx + MAP_UNIT / 2,
956 mapy + MAP_UNIT_OFFSET,
957 0 ) ) {
958 scourge->getMap()->setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET,
959 MAP_WALL_HEIGHT - 2, shapePal->findShapeByName( "NS_DOOR_TOP" ) );
960 scourge->getMap()->setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET,
961 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
962 scourge->getMap()->setPosition( mapx + MAP_UNIT_OFFSET * 2, mapy + MAP_UNIT_OFFSET - 1,
963 0, shapePal->findShapeByName( "NS_DOOR" ) );
964 scourge->getMap()->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET * 2, mapy + MAP_UNIT_OFFSET,
965 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
966 scourge->getMap()->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET * 3, mapy + MAP_UNIT_OFFSET,
967 0, shapePal->findShapeByName( "DOOR_SIDE" ) );
968
969 // corners
970 if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 ) ) {
971 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
972 shapePal->findShapeByName( "CORNER" ) );
973 }
974 if ( !scourge->getMap()->getLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 ) ) {
975 scourge->getMap()->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
976 shapePal->findShapeByName( "CORNER" ) );
977 }
978 }
979 }
980
addEWWall(Sint16 mapx,Sint16 mapy,int dir)981 void MapEditor::addEWWall( Sint16 mapx, Sint16 mapy, int dir ) {
982 // short wall
983 bool north = false;
984 bool south = false;
985 if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT / 2, 0 ) ) {
986
987 // see if EW_WALL to the north and south
988 north = ( mapy - 1 >= 0 &&
989 scourge->getMap()->getLocation( mapx, mapy - 1, 0 ) &&
990 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy + 1, 0 ) );
991 south = ( mapy + MAP_UNIT + 1 < MAP_DEPTH &&
992 scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT + 1, 0 ) &&
993 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy + MAP_UNIT - 1, 0 ) );
994
995 // corner
996 if ( south ) {
997 scourge->getMap()->
998 removeLocation( mapx, mapy + MAP_UNIT, 0 );
999 } else if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT, 0 ) ) {
1000 scourge->getMap()->
1001 setPosition( mapx, mapy + MAP_UNIT, 0,
1002 scourge->getShapePalette()->
1003 findShapeByName( "CORNER" ) );
1004 }
1005
1006 // corner
1007 if ( north ) {
1008 scourge->getMap()->
1009 removeLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 );
1010 } else if ( !scourge->getMap()->getLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 ) ) {
1011 scourge->getMap()->
1012 setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
1013 scourge->getShapePalette()->
1014 findShapeByName( "CORNER" ) );
1015 }
1016
1017 if ( north && south ) {
1018 scourge->getMap()->
1019 setPosition( mapx, mapy + MAP_UNIT, 0,
1020 scourge->getShapePalette()->
1021 findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1022 } else if ( south ) {
1023 scourge->getMap()->
1024 setPosition( mapx, mapy + MAP_UNIT, 0,
1025 scourge->getShapePalette()->
1026 findShapeByName( "EW_WALL_EXTRA" ) );
1027 } else if ( north ) {
1028 scourge->getMap()->
1029 setPosition( mapx, mapy + MAP_UNIT - MAP_UNIT_OFFSET, 0,
1030 scourge->getShapePalette()->
1031 findShapeByName( "EW_WALL_EXTRA" ) );
1032 } else {
1033 scourge->getMap()->
1034 setPosition( mapx, mapy + MAP_UNIT - MAP_UNIT_OFFSET, 0,
1035 scourge->getShapePalette()->
1036 findShapeByName( "EW_WALL" ) );
1037 }
1038
1039 // add a light
1040 if ( Util::dice( 100 ) <= 25 ) {
1041 if ( dir == 1 ) {
1042 scourge->getMap()->
1043 setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT - 4,
1044 6, scourge->getShapePalette()->findShapeByName( "LAMP_WEST" ) );
1045 scourge->getMap()->
1046 setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT - 4,
1047 4, scourge->getShapePalette()->findShapeByName( "LAMP_BASE" ) );
1048 } else {
1049 scourge->getMap()->
1050 setPosition( mapx - 1, mapy + MAP_UNIT - 4,
1051 6, scourge->getShapePalette()->findShapeByName( "LAMP_EAST" ) );
1052 scourge->getMap()->
1053 setPosition( mapx - 1, mapy + MAP_UNIT - 4,
1054 4, scourge->getShapePalette()->findShapeByName( "LAMP_BASE" ) );
1055 }
1056 }
1057
1058
1059 // change north chunk
1060 //cerr << "Looking north of EW_WALL map=" << mapx << "," << mapy << endl;
1061 if ( isShape( mapx, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL" ) &&
1062 isShape( mapx, mapy, 0, "CORNER" ) &&
1063 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy - 1, 0 ) ) {
1064 //cerr << "Success!" << endl;
1065 scourge->getMap()->removeLocation( mapx, mapy - MAP_UNIT_OFFSET, 0 );
1066 scourge->getMap()->removeLocation( mapx, mapy, 0 );
1067 scourge->getMap()->
1068 setPosition( mapx, mapy, 0, scourge->getShapePalette()->
1069 findShapeByName( "EW_WALL_EXTRA" ) );
1070 }
1071
1072 //cerr << "Looking north of EW_WALL_EXTRA map=" << mapx << "," << mapy << endl;
1073 if ( isShape( mapx, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL_EXTRA" ) &&
1074 isShape( mapx, mapy, 0, "CORNER" ) &&
1075 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy - 1, 0 ) ) {
1076 //cerr << "Success!" << endl;
1077 scourge->getMap()->removeLocation( mapx, mapy - MAP_UNIT_OFFSET, 0 );
1078 scourge->getMap()->removeLocation( mapx, mapy, 0 );
1079 scourge->getMap()->
1080 setPosition( mapx, mapy, 0, scourge->getShapePalette()->
1081 findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1082 }
1083
1084 // change the south chunk
1085 //cerr << "Looking south of EW_WALL map=" << mapx << "," << mapy << endl;
1086 if ( isShape( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0, "EW_WALL" ) &&
1087 isShape( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1088 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy + MAP_UNIT + 1, 0 ) ) {
1089 //cerr << "Success!" << endl;
1090 scourge->getMap()->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0 );
1091 scourge->getMap()->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0 );
1092 scourge->getMap()->
1093 setPosition( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0,
1094 scourge->getShapePalette()->
1095 findShapeByName( "EW_WALL_EXTRA" ) );
1096 }
1097 //cerr << "Looking south of EW_WALL_EXTRA map=" << mapx << "," << mapy << endl;
1098 if ( isShape( mapx, mapy + MAP_UNIT + MAP_UNIT, 0, "EW_WALL_EXTRA" ) &&
1099 isShape( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1100 !scourge->getMap()->getLocation( mapx + dir * ( MAP_UNIT / 2 ), mapy + MAP_UNIT + 1, 0 ) ) {
1101 //cerr << "Success!" << endl;
1102 scourge->getMap()->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT, 0 );
1103 scourge->getMap()->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0 );
1104 scourge->getMap()->
1105 setPosition( mapx, mapy + MAP_UNIT + MAP_UNIT, 0,
1106 scourge->getShapePalette()->
1107 findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1108 }
1109 //cerr << "----------------------------------------------------" << endl;
1110 }
1111 }
1112
addNSWall(Sint16 mapx,Sint16 mapy,int dir)1113 void MapEditor::addNSWall( Sint16 mapx, Sint16 mapy, int dir ) {
1114
1115 bool east = false;
1116 bool west = false;
1117
1118 // short wall
1119 if ( !scourge->getMap()->getLocation( mapx + MAP_UNIT / 2,
1120 mapy + MAP_UNIT_OFFSET,
1121 0 ) ) {
1122
1123 // see if NS_WALL to the east and west
1124 east = ( mapx + MAP_UNIT < MAP_WIDTH &&
1125 scourge->getMap()->getLocation( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 ) &&
1126 !scourge->getMap()->getLocation( mapx + MAP_UNIT - 1, mapy + dir * ( MAP_UNIT / 2 ), 0 ) );
1127 west = ( mapx - 1 >= 0 &&
1128 scourge->getMap()->getLocation( mapx - 1, mapy + MAP_UNIT_OFFSET, 0 ) &&
1129 !scourge->getMap()->getLocation( mapx, mapy + dir * ( MAP_UNIT / 2 ), 0 ) );
1130
1131 // corner
1132 if ( west ) {
1133 scourge->getMap()->
1134 removeLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 );
1135 } else if ( !scourge->getMap()->getLocation( mapx,
1136 mapy + MAP_UNIT_OFFSET,
1137 0 ) ) {
1138 scourge->getMap()->
1139 setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
1140 scourge->getShapePalette()->
1141 findShapeByName( "CORNER" ) );
1142 }
1143
1144 // corner
1145 if ( east ) {
1146 scourge->getMap()->
1147 removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1148 } else if ( !scourge->getMap()->getLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET,
1149 mapy + MAP_UNIT_OFFSET,
1150 0 ) ) {
1151 scourge->getMap()->
1152 setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1153 scourge->getShapePalette()->
1154 findShapeByName( "CORNER" ) );
1155 }
1156
1157
1158 if ( east && west ) {
1159 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
1160 scourge->getShapePalette()->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1161 } else if ( west ) {
1162 scourge->getMap()->setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
1163 scourge->getShapePalette()->findShapeByName( "NS_WALL_EXTRA" ) );
1164 } else if ( east ) {
1165 scourge->getMap()->setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1166 scourge->getShapePalette()->findShapeByName( "NS_WALL_EXTRA" ) );
1167 } else {
1168 scourge->getMap()->setPosition( mapx + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1169 scourge->getShapePalette()->findShapeByName( "NS_WALL" ) );
1170 }
1171
1172 // Add a light
1173 if ( Util::dice( 100 ) <= 25 ) {
1174 if ( dir == 1 ) {
1175 scourge->getMap()->
1176 setPosition( mapx + 4, mapy + MAP_UNIT_OFFSET + 1, 6,
1177 scourge->getShapePalette()->findShapeByName( "LAMP_NORTH" ) );
1178 scourge->getMap()->
1179 setPosition( mapx + 4, mapy + MAP_UNIT_OFFSET + 1, 4,
1180 scourge->getShapePalette()->findShapeByName( "LAMP_BASE" ) );
1181 } else {
1182 /*
1183 See gltorch.cpp on why there aren't southern torches... <sigh>
1184 cerr << "adding South light" << endl;
1185 scourge->getMap()->
1186 setPosition(mapx + 4, mapy, 6,
1187 scourge->getShapePalette()->findShapeByName("LAMP_SOUTH", true));
1188 scourge->getMap()->
1189 setPosition(mapx + 4, mapy, 4,
1190 scourge->getShapePalette()->findShapeByName("LAMP_BASE", true));
1191
1192 */
1193 }
1194 }
1195
1196 // change west chunk
1197 if ( isShape( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL" ) &&
1198 isShape( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1199 !scourge->getMap()->getLocation( mapx - MAP_UNIT_OFFSET, mapy + dir * ( MAP_UNIT / 2 ), 0 ) ) {
1200 scourge->getMap()->removeLocation( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1201 scourge->getMap()->removeLocation( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1202 scourge->getMap()->
1203 setPosition( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1204 scourge->getShapePalette()->findShapeByName( "NS_WALL_EXTRA" ) );
1205 }
1206 if ( isShape( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL_EXTRA" ) &&
1207 isShape( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1208 !scourge->getMap()->getLocation( mapx - MAP_UNIT_OFFSET, mapy + dir * ( MAP_UNIT / 2 ), 0 ) ) {
1209 scourge->getMap()->removeLocation( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1210 scourge->getMap()->removeLocation( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 );
1211 scourge->getMap()->
1212 setPosition( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1213 scourge->getShapePalette()->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1214 }
1215
1216 // change the east chunk
1217 if ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL" ) &&
1218 isShape( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1219 !scourge->getMap()->getLocation( mapx + MAP_UNIT, mapy + dir * ( MAP_UNIT / 2 ), 0 ) ) {
1220 scourge->getMap()->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1221 scourge->getMap()->removeLocation( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 );
1222 scourge->getMap()->
1223 setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1224 scourge->getShapePalette()->
1225 findShapeByName( "NS_WALL_EXTRA" ) );
1226 }
1227 if ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL_EXTRA" ) &&
1228 isShape( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1229 !scourge->getMap()->getLocation( mapx + MAP_UNIT, mapy + dir * ( MAP_UNIT / 2 ), 0 ) ) {
1230 scourge->getMap()->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1231 scourge->getMap()->removeLocation( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 );
1232 scourge->getMap()->
1233 setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1234 scourge->getShapePalette()->
1235 findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1236 }
1237 }
1238 }
1239
addFloor(Sint16 mapx,Sint16 mapy,bool doFlattenChunk)1240 void MapEditor::addFloor( Sint16 mapx, Sint16 mapy, bool doFlattenChunk ) {
1241 if ( scourge->getMap()->getFloorPosition( mapx, mapy + MAP_UNIT ) ) return;
1242 if ( doFlattenChunk ) flattenChunk( mapx, mapy );
1243 scourge->getMap()->
1244 setFloorPosition( mapx, mapy + MAP_UNIT,
1245 scourge->getShapePalette()->
1246 findShapeByName( floorTypeName[ floorType->isSelected() ? 0 : 1 ][ 0 ] ) );
1247 }
1248
lowerGroundHeight(Sint16 mapx,Sint16 mapy)1249 void MapEditor::lowerGroundHeight( Sint16 mapx, Sint16 mapy ) {
1250 scourge->getMap()->setGroundHeight( mapx / OUTDOORS_STEP, mapy / OUTDOORS_STEP, Util::roll( 0, 2 ) );
1251 }
1252
raiseGroundHeight(Sint16 mapx,Sint16 mapy)1253 void MapEditor::raiseGroundHeight( Sint16 mapx, Sint16 mapy ) {
1254 scourge->getMap()->setGroundHeight( mapx / OUTDOORS_STEP, mapy / OUTDOORS_STEP, Util::roll( 14.0f, 20.0f ) );
1255 }
1256
changePathChunk(Sint16 mapx,Sint16 mapy,bool lower)1257 void MapEditor::changePathChunk( Sint16 mapx, Sint16 mapy, bool lower ) {
1258 //if( !scourge->getMap()->getFloorPosition( mapx, mapy + MAP_UNIT ) ) return;
1259 int chunkX = ( mapx - MAP_OFFSET ) / MAP_UNIT;
1260 int chunkY = ( mapy - MAP_OFFSET ) / MAP_UNIT;
1261 for ( int x = OUTDOORS_STEP; x <= MAP_UNIT - OUTDOORS_STEP; x++ ) {
1262 for ( int y = OUTDOORS_STEP; y <= MAP_UNIT - OUTDOORS_STEP; y++ ) {
1263 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
1264 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
1265 scourge->getMap()->setGroundHeight( xx, yy, ( lower ? 0 : Util::roll( 7, 10 ) ) );
1266 }
1267 }
1268 for ( int x = OUTDOORS_STEP; x <= MAP_UNIT - OUTDOORS_STEP; x++ ) {
1269 if ( scourge->getMap()->getFloorPosition( mapx, mapy ) ) {
1270 int y = 0;
1271 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
1272 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
1273 scourge->getMap()->setGroundHeight( xx, yy, ( lower ? 0 : Util::roll( 7, 10 ) ) );
1274 }
1275 if ( scourge->getMap()->getFloorPosition( mapx, mapy + MAP_UNIT + MAP_UNIT ) ) {
1276 int y = MAP_UNIT - 1;
1277 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
1278 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
1279 scourge->getMap()->setGroundHeight( xx, yy, ( lower ? 0 : Util::roll( 7, 10 ) ) );
1280 }
1281 }
1282 for ( int y = OUTDOORS_STEP; y <= MAP_UNIT - OUTDOORS_STEP; y++ ) {
1283 if ( scourge->getMap()->getFloorPosition( mapx - MAP_UNIT, mapy + MAP_UNIT ) ) {
1284 int x = 0;
1285 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
1286 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
1287 scourge->getMap()->setGroundHeight( xx, yy, ( lower ? 0 : Util::roll( 7, 10 ) ) );
1288 }
1289 if ( scourge->getMap()->getFloorPosition( mapx + MAP_UNIT, mapy + MAP_UNIT ) ) {
1290 int x = MAP_UNIT - 1;
1291 int xx = ( MAP_OFFSET + ( chunkX * MAP_UNIT ) + x ) / OUTDOORS_STEP;
1292 int yy = ( MAP_OFFSET + ( chunkY * MAP_UNIT ) + y ) / OUTDOORS_STEP;
1293 scourge->getMap()->setGroundHeight( xx, yy, ( lower ? 0 : Util::roll( 7, 10 ) ) );
1294 }
1295 }
1296 }
1297
removeFloor(Sint16 mapx,Sint16 mapy)1298 void MapEditor::removeFloor( Sint16 mapx, Sint16 mapy ) {
1299 scourge->getMap()->removeFloorPosition( mapx, mapy + MAP_UNIT );
1300 }
1301
removeEWWall(Sint16 mapx,Sint16 mapy,int dir)1302 void MapEditor::removeEWWall( Sint16 mapx, Sint16 mapy, int dir ) {
1303 for ( int y = 1; y <= MAP_UNIT; y++ ) {
1304 for ( int z = 0; z < MAP_VIEW_HEIGHT; z++ ) {
1305 scourge->getMap()->removeLocation( mapx + 1, mapy + y, z );
1306 }
1307 }
1308 }
1309
removeNSWall(Sint16 mapx,Sint16 mapy,int dir)1310 void MapEditor::removeNSWall( Sint16 mapx, Sint16 mapy, int dir ) {
1311 for ( int x = 0; x < MAP_UNIT; x++ ) {
1312 for ( int z = 0; z < MAP_VIEW_HEIGHT; z++ ) {
1313 scourge->getMap()->removeLocation( mapx + x, mapy + MAP_UNIT_OFFSET - 1, z );
1314 }
1315 }
1316 }
1317
blendCorners(Sint16 mapx,Sint16 mapy)1318 void MapEditor::blendCorners( Sint16 mapx, Sint16 mapy ) {
1319
1320 if ( !( mapx >= 0 && mapx < MAP_WIDTH &&
1321 mapy >= 0 && mapy < MAP_DEPTH ) )
1322 return;
1323
1324
1325 Map *levelMap = scourge->getMap();
1326 ShapePalette *pal = scourge->getShapePalette();
1327
1328 // check NW corner
1329 if ( isShape( mapx - 1, mapy + 1, 0, "CORNER" ) &&
1330 isShape( mapx, mapy - 1, 0, "CORNER" ) &&
1331 !levelMap->getLocation( mapx, mapy + MAP_UNIT_OFFSET, 0 ) ) {
1332
1333 bool nsWall = ( isShape( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL" ) ? true : false );
1334 bool nsWallExtra = ( isShape( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL_EXTRA" ) ? true : false );
1335 bool ewWall = ( isShape( mapx, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL" ) ? true : false );
1336 bool ewWallExtra = ( isShape( mapx, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL_EXTRA" ) ? true : false );
1337
1338 if ( ( nsWall || nsWallExtra ) && ( ewWall || ewWallExtra ) ) {
1339
1340 levelMap->setPosition( mapx, mapy + MAP_UNIT_OFFSET, 0,
1341 pal->findShapeByName( "CORNER" ) );
1342 levelMap->removeLocation( mapx - 1, mapy + 1, 0 );
1343 levelMap->removeLocation( mapx, mapy - 1, 0 );
1344
1345 // change west chunk
1346 if ( nsWall ) {
1347 levelMap->removeLocation( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1348 levelMap->setPosition( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1349 pal->findShapeByName( "NS_WALL_EXTRA" ) );
1350 } else if ( nsWallExtra ) {
1351 levelMap->removeLocation( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 );
1352 levelMap->setPosition( mapx - MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1353 pal->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1354 }
1355
1356 // change north chunk
1357 if ( ewWall ) {
1358 levelMap->removeLocation( mapx, mapy - MAP_UNIT_OFFSET, 0 );
1359 levelMap->setPosition( mapx, mapy, 0,
1360 pal->findShapeByName( "EW_WALL_EXTRA" ) );
1361 } else if ( ewWallExtra ) {
1362 levelMap->removeLocation( mapx, mapy - MAP_UNIT_OFFSET, 0 );
1363 levelMap->setPosition( mapx, mapy, 0,
1364 pal->findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1365 }
1366 }
1367 }
1368
1369 // check NE corner
1370 if ( isShape( mapx + MAP_UNIT, mapy + 1, 0, "CORNER" ) &&
1371 isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - 1, 0, "CORNER" ) &&
1372 !levelMap->getLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 ) ) {
1373
1374 bool nsWall = ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL" ) ? true : false );
1375 bool nsWallExtra = ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0, "NS_WALL_EXTRA" ) ? true : false );
1376 bool ewWall = ( isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL" ) ? true : false );
1377 bool ewWallExtra = ( isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - MAP_UNIT_OFFSET, 0, "EW_WALL_EXTRA" ) ? true : false );
1378
1379 if ( ( nsWall || nsWallExtra ) && ( ewWall || ewWallExtra ) ) {
1380
1381 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0,
1382 pal->findShapeByName( "CORNER" ) );
1383 levelMap->removeLocation( mapx + MAP_UNIT, mapy + 1, 0 );
1384 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - 1, 0 );
1385
1386 // change west chunk
1387 if ( nsWall ) {
1388 levelMap->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1389 levelMap->setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1390 pal->findShapeByName( "NS_WALL_EXTRA" ) );
1391 } else if ( nsWallExtra ) {
1392 levelMap->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT_OFFSET, 0 );
1393 levelMap->setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0,
1394 pal->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1395 }
1396
1397 // change north chunk
1398 if ( ewWall ) {
1399 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - MAP_UNIT_OFFSET, 0 );
1400 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy, 0,
1401 pal->findShapeByName( "EW_WALL_EXTRA" ) );
1402 } else if ( ewWallExtra ) {
1403 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy - MAP_UNIT_OFFSET, 0 );
1404 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy, 0,
1405 pal->findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1406 }
1407 }
1408 }
1409
1410 // check SE corner
1411 if ( isShape( mapx + MAP_UNIT, mapy + MAP_UNIT, 0, "CORNER" ) &&
1412 isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1413 !levelMap->getLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0 ) ) {
1414
1415 bool nsWall = ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0, "NS_WALL" ) ? true : false );
1416 bool nsWallExtra = ( isShape( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0, "NS_WALL_EXTRA" ) ? true : false );
1417 bool ewWall = ( isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0, "EW_WALL" ) ? true : false );
1418 bool ewWallExtra = ( isShape( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT, 0, "EW_WALL_EXTRA" ) ? true : false );
1419
1420 if ( ( nsWall || nsWallExtra ) && ( ewWall || ewWallExtra ) ) {
1421
1422 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0,
1423 pal->findShapeByName( "CORNER" ) );
1424 levelMap->removeLocation( mapx + MAP_UNIT, mapy + MAP_UNIT_OFFSET, 0 );
1425 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0 );
1426
1427 // change west chunk
1428 if ( nsWall ) {
1429 levelMap->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0 );
1430 levelMap->setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT, 0,
1431 pal->findShapeByName( "NS_WALL_EXTRA" ) );
1432 } else if ( nsWallExtra ) {
1433 levelMap->removeLocation( mapx + MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0 );
1434 levelMap->setPosition( mapx + MAP_UNIT, mapy + MAP_UNIT, 0,
1435 pal->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1436 }
1437
1438 // change north chunk
1439 if ( ewWall ) {
1440 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0 );
1441 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0,
1442 pal->findShapeByName( "EW_WALL_EXTRA" ) );
1443 } else if ( ewWallExtra ) {
1444 levelMap->removeLocation( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT, 0 );
1445 levelMap->setPosition( mapx + MAP_UNIT - MAP_UNIT_OFFSET, mapy + MAP_UNIT + MAP_UNIT, 0,
1446 pal->findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1447 }
1448 }
1449 }
1450
1451 // check SW corner
1452 if ( isShape( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0, "CORNER" ) &&
1453 isShape( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0, "CORNER" ) &&
1454 !levelMap->getLocation( mapx, mapy + MAP_UNIT, 0 ) ) {
1455
1456 bool nsWall = ( isShape( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0, "NS_WALL" ) ? true : false );
1457 bool nsWallExtra = ( isShape( mapx - MAP_UNIT, mapy + MAP_UNIT, 0, "NS_WALL_EXTRA" ) ? true : false );
1458 bool ewWall = ( isShape( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0, "EW_WALL" ) ? true : false );
1459 bool ewWallExtra = ( isShape( mapx, mapy + MAP_UNIT + MAP_UNIT, 0, "EW_WALL_EXTRA" ) ? true : false );
1460
1461 if ( ( nsWall || nsWallExtra ) && ( ewWall || ewWallExtra ) ) {
1462
1463 levelMap->setPosition( mapx, mapy + MAP_UNIT, 0,
1464 pal->findShapeByName( "CORNER" ) );
1465 levelMap->removeLocation( mapx - MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0 );
1466 levelMap->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT_OFFSET, 0 );
1467
1468 // change west chunk
1469 if ( nsWall ) {
1470 levelMap->removeLocation( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0 );
1471 levelMap->setPosition( mapx - MAP_UNIT + MAP_UNIT_OFFSET, mapy + MAP_UNIT, 0,
1472 pal->findShapeByName( "NS_WALL_EXTRA" ) );
1473 } else if ( nsWallExtra ) {
1474 levelMap->removeLocation( mapx - MAP_UNIT, mapy + MAP_UNIT, 0 );
1475 levelMap->setPosition( mapx - MAP_UNIT, mapy + MAP_UNIT, 0,
1476 pal->findShapeByName( "NS_WALL_TWO_EXTRAS" ) );
1477 }
1478
1479 // change north chunk
1480 if ( ewWall ) {
1481 levelMap->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0 );
1482 levelMap->setPosition( mapx, mapy + MAP_UNIT + MAP_UNIT - MAP_UNIT_OFFSET, 0,
1483 pal->findShapeByName( "EW_WALL_EXTRA" ) );
1484 } else if ( ewWallExtra ) {
1485 levelMap->removeLocation( mapx, mapy + MAP_UNIT + MAP_UNIT, 0 );
1486 levelMap->setPosition( mapx, mapy + MAP_UNIT + MAP_UNIT, 0,
1487 pal->findShapeByName( "EW_WALL_TWO_EXTRAS" ) );
1488 }
1489 }
1490 }
1491 }
1492
isShape(Sint16 mapx,Sint16 mapy,Sint16 mapz,const char * name)1493 bool MapEditor::isShape( Sint16 mapx, Sint16 mapy, Sint16 mapz, const char *name ) {
1494 // cerr << "\ttesting map=" << mapx << "," << mapy << " looking for " << name;
1495 if ( mapx >= 0 && mapx < MAP_WIDTH &&
1496 mapy >= 0 && mapy < MAP_DEPTH &&
1497 mapz >= 0 && mapz < MAP_VIEW_HEIGHT ) {
1498 Location *pos = scourge->getMap()->getLocation( mapx, mapy, mapz );
1499 // cerr << " found=" << ( !pos ? "NULL" : pos->shape->getName() ) << endl;
1500 return( pos && pos->shape && !strcmp( pos->shape->getName(), name ) );
1501 } else {
1502 // cerr << " found nothing." << endl;
1503 return false;
1504 }
1505 }
1506
1507