CMapPlayGalaxy.cpp 18.4 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * CMapPlayGalaxy.cpp
 *
 *  Created on: 25.03.2011
 *      Author: gerstrong
 */

#include "CMapPlayGalaxy.h"
9 10
#include "common/ai/platform/CPlatform.h"
#include "common/ai/CPlayerBase.h"
Gerhard Stein's avatar
Gerhard Stein committed
11
#include "engine/core/CBehaviorEngine.h"
Gerhard Stein's avatar
Gerhard Stein committed
12 13
#include "ep4/CMapLoaderGalaxyEp4.h"
#include "ep5/CMapLoaderGalaxyEp5.h"
14
#include "ep6/CMapLoaderGalaxyEp6.h"
15 16 17
#include "ep4/ai/CInchWorm.h"
#include "ep4/ai/CFoot.h"
#include "ep4/ai/CSmokePuff.h"
18
#include "engine/core/VGamepads/vgamepadsimple.h"
Gerhard Stein's avatar
Gerhard Stein committed
19 20
#include <base/GsLogging.h>
#include <base/video/CVideoDriver.h>
21

22
#include <boost/property_tree/ptree.hpp>
23
#include <base/utils/Base64.h>
24

Gerhard Stein's avatar
Gerhard Stein committed
25 26
#include "GalaxyEngine.h"

27
CMapPlayGalaxy::CMapPlayGalaxy(std::vector<CInventory> &inventoryVec) :
Gerhard Stein's avatar
Gerhard Stein committed
28
mActive(false),
29
mInventoryVec(inventoryVec),
30
mpOption(gpBehaviorEngine->m_option),
31
mMsgBoxOpen(false)
32 33
{}

34

35
bool CMapPlayGalaxy::isActive()
Gerhard Stein's avatar
Gerhard Stein committed
36
{	return mActive;	}
37

38 39 40



41 42
void CMapPlayGalaxy::setActive(bool value)
{
Gerhard Stein's avatar
Gerhard Stein committed
43
	mActive = value;
44

Gerhard Stein's avatar
Gerhard Stein committed
45
	if(mActive)
46
	{
47 48
        mMap.drawAll();
        gVideoDriver.updateScrollBuffer(mMap.m_scrollx, mMap.m_scrolly);
49
        gVideoDriver.setRefreshSignal(true);
50 51 52
	}
}

53 54 55



56 57 58 59 60
/**
 * return the name of the opened level
 */
std::string CMapPlayGalaxy::getLevelName()
{
Gerhard Stein's avatar
Gerhard Stein committed
61
	return mMap.getLevelName();
62 63
}

64

65

Gerhard Stein's avatar
Gerhard Stein committed
66 67
void CMapPlayGalaxy::pumpEvent(const CEvent *evPtr)
{
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    if( const EventSpawnObject *ev = dynamic_cast<const EventSpawnObject*>(evPtr) )
    {
        std::shared_ptr<CGalaxySpriteObject> obj( static_cast<CGalaxySpriteObject*>(
                            const_cast<CSpriteObject*>(ev->pObject) ) );
        mObjectPtr.push_back( move(obj) );
    }
    else if( const EventSpawnFoot *ev = dynamic_cast<const EventSpawnFoot*>(evPtr) ) // Special Case where the Foot is created
    {                                                                                // Episode 4 Secret level
        // kill all the InchWorms in that case, so they can't do any spawning
        for( auto obj=mObjectPtr.rbegin() ; obj!=mObjectPtr.rend() ; obj++ )
        {
            galaxy::CInchWorm *inchworm = dynamic_cast<galaxy::CInchWorm*>(obj->get());
            if( inchworm != NULL )
            {
                inchworm->exists = false;
            }
        }


        // Create the foot with Smoke Puff
        int posX = ev->x;
        int posY = ev->y-(4<<CSF);
        for( int x=-1 ; x<2 ; x++ )
        {
            for( int y=-1 ; y<2 ; y++ )
            {
            std::shared_ptr<CGalaxySpriteObject> smoke(new galaxy::CSmokePuff( &mMap, posX+(x<<CSF), posY+(y<<CSF), 0 ));
            mObjectPtr.push_back( smoke );
            }
        }

        std::shared_ptr<CGalaxySpriteObject> foot(new galaxy::CFoot( &mMap, ev->foeID, 0x2EF4, posX, posY));
        mObjectPtr.push_back( foot );
    }


Gerhard Stein's avatar
Gerhard Stein committed
104
    for( auto obj = mObjectPtr.begin(); obj != mObjectPtr.end() ; obj++)
Gerhard Stein's avatar
Gerhard Stein committed
105 106 107
    {
        auto &objRef = *(obj->get());
        objRef.pumpEvent(evPtr);
Gerhard Stein's avatar
Gerhard Stein committed
108
    }
Gerhard Stein's avatar
Gerhard Stein committed
109
}
110 111 112



113
void CMapPlayGalaxy::ponderBase(const float deltaT)
114
{
115 116
    const bool msgboxactive = mMsgBoxOpen;

117 118
    bool pause = msgboxactive;

Gerhard Stein's avatar
Gerhard Stein committed
119
    // Check if the engine need to be paused
120 121
    for( auto &inv : mInventoryVec)
        pause |= inv.showStatus();
122

Gerhard Stein's avatar
Gerhard Stein committed
123 124 125
    // Animate the tiles of the map
    mMap.m_animation_enabled = !pause;
    mMap.animateAllTiles();
126

Gerhard Stein's avatar
Gerhard Stein committed
127 128 129 130
    if(!pause)
    {
        for( auto obj = mObjectPtr.begin(); obj != mObjectPtr.end() ; obj++)
        {
131 132
            auto &objRef = *(obj->get());
            bool visibility = false;
133

134 135 136
            if( objRef.exists )
            {
                visibility = objRef.calcVisibility();
gerstrong's avatar
gerstrong committed
137

138
                if( visibility )
139
                {
140 141
                    // Process the AI of the object as it's given
                    objRef.process();
gerstrong's avatar
gerstrong committed
142

143 144 145
                    // Check collision between objects using NlogN order
                    auto theOther = obj; theOther++;
                    for( ; theOther != mObjectPtr.end() ; theOther++)
146
                    {
147 148 149 150 151 152 153 154 155 156 157 158
                        auto &theOtherRef = *(theOther->get());
                        if( !theOtherRef.exists )
                            continue;

                        objRef.isNearby(theOtherRef);
                        theOtherRef.isNearby(objRef);

                        if( objRef.hitdetect(theOtherRef) )
                        {
                            objRef.getTouchedBy(theOtherRef);
                            theOtherRef.getTouchedBy(objRef);
                        }
159 160
                    }
                }
161
            }
gerstrong's avatar
gerstrong committed
162

163
            // If the Player is not only dying, but also lost it's existence, meaning he got out of the screen
Gerhard Stein's avatar
Gerhard Stein committed
164
            // show the death-message or go gameover.
165
            if( galaxy::CPlayerBase *player = dynamic_cast<galaxy::CPlayerBase*>(obj->get()) )
Gerhard Stein's avatar
Gerhard Stein committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179
            {
                // Special cases, when Keen is god, but still has to die,
                // kill him anyways.
                if( player->touchedBottomOfMap() )
                {
                    player->kill(true);
                }

                // Is he really dead?
                if( player->dead || (!visibility && player->m_dying) )
                {
                    player->processDead();
                }
            }
gerstrong's avatar
gerstrong committed
180

Gerhard Stein's avatar
Gerhard Stein committed
181
            objRef.processEvents();
Gerhard Stein's avatar
Gerhard Stein committed
182
        }
183 184 185 186 187
	}


}

Gerhard Stein's avatar
Gerhard Stein committed
188
void CMapPlayGalaxy::render()
189
{
Gerhard Stein's avatar
Gerhard Stein committed
190
    gVideoDriver.blitScrollSurface();
Gerhard Stein's avatar
Gerhard Stein committed
191 192 193 194

    auto obj = mObjectPtr.rbegin();

    // Draw all the sprites without player
195
    // The player sprites are drawn at the end
Gerhard Stein's avatar
Gerhard Stein committed
196
    galaxy::CPlayerBase* player[] = {nullptr, nullptr, nullptr, nullptr};
gerstrong's avatar
gerstrong committed
197

198
    int pIt = 0;
Gerhard Stein's avatar
Gerhard Stein committed
199 200 201 202
    for( ; obj!=mObjectPtr.rend() ; obj++ )
    {
        if( galaxy::CPlayerBase* curplayer = dynamic_cast<galaxy::CPlayerBase*>(obj->get()) )
        {
203 204
            player[pIt] = curplayer;
            pIt++;
Gerhard Stein's avatar
Gerhard Stein committed
205 206 207 208 209 210 211
            continue;
        }

        if((*obj)->honorPriority )
            (*obj)->draw();
    }

212
    for(int i=0 ; i<pIt ; i++)
Gerhard Stein's avatar
Gerhard Stein committed
213
    {
214
        player[i]->draw();
Gerhard Stein's avatar
Gerhard Stein committed
215 216
    }

Gerhard Stein's avatar
Gerhard Stein committed
217 218 219
    // RenderShake Effect
    mMap.renderShaking();

220
    // Draw foregroundtiles here!
Gerhard Stein's avatar
Gerhard Stein committed
221
    mMap._drawForegroundTiles();
Gerhard Stein's avatar
Gerhard Stein committed
222 223 224 225 226 227 228 229 230

    for( obj=mObjectPtr.rbegin() ;
            obj!=mObjectPtr.rend() ; obj++ )
    {
        if(!(*obj)->honorPriority)
            (*obj)->draw();
    }

    if(mpOption[OPT_HUD].value )
231 232 233
    {
        for( int pId = mInventoryVec.size()-1 ; pId>=0 ; pId-- )
        {
Gerhard Stein's avatar
Gerhard Stein committed
234
            mInventoryVec[pId].drawHUD();
235 236
        }
    }
237 238 239 240 241 242

}


// Saved GameState stuff for that individual map

243 244
void CMapPlayGalaxy::operator>>(CSaveGameController &savedGame)
{
245 246 247
	const Uint16 level = mMap.getLevel();
	savedGame.encodeData( level );

gerstrong's avatar
gerstrong committed
248
	std::vector< std::shared_ptr<CGalaxySpriteObject> > filteredObjects;
Gerhard Stein's avatar
Gerhard Stein committed
249

gerstrong's avatar
gerstrong committed
250
	// let's filter the Foe out that won't do any good!
Gerhard Stein's avatar
Gerhard Stein committed
251
	for( auto &it : mObjectPtr )
252
	{
Gerhard Stein's avatar
Gerhard Stein committed
253
	    if( it->mFoeID != 0 )
254
	    {
Gerhard Stein's avatar
Gerhard Stein committed
255
		filteredObjects.push_back( it );
256 257
	    }
	}
gerstrong's avatar
gerstrong committed
258

259
	const size_t size = filteredObjects.size();
gerstrong's avatar
gerstrong committed
260

261 262 263
	// save the number of objects on screen
	savedGame.encodeData(size);

Gerhard Stein's avatar
Gerhard Stein committed
264
	for( auto &it : filteredObjects )
Gerhard Stein's avatar
Gerhard Stein committed
265 266
	{
		// save all the objects states
Gerhard Stein's avatar
Gerhard Stein committed
267
		unsigned int newYpos = it->getYPosition();
gerstrong's avatar
gerstrong committed
268 269
		unsigned int newXpos = it->getXPosition();

Gerhard Stein's avatar
Gerhard Stein committed
270
		savedGame.encodeData( it->mFoeID );
271
		savedGame.encodeData( newXpos );
272
		savedGame.encodeData( newYpos );
Gerhard Stein's avatar
Gerhard Stein committed
273 274 275 276 277 278 279
		savedGame.encodeData( it->dead );
		savedGame.encodeData( it->onscreen );
		savedGame.encodeData( it->hasbeenonscreen );
		savedGame.encodeData( it->exists );
		savedGame.encodeData( it->blockedd );
		savedGame.encodeData( it->blockedu );
		savedGame.encodeData( it->blockedl );
gerstrong's avatar
gerstrong committed
280
		savedGame.encodeData( it->blockedr );
281
		savedGame.encodeData( it->xDirection );
gerstrong's avatar
gerstrong committed
282
		savedGame.encodeData( it->yDirection );
Gerhard Stein's avatar
Gerhard Stein committed
283 284 285 286 287 288 289
		savedGame.encodeData( it->mHealthPoints );
		savedGame.encodeData( it->canbezapped );
		savedGame.encodeData( it->cansupportplayer );
		savedGame.encodeData( it->inhibitfall );
		savedGame.encodeData( it->honorPriority );
		savedGame.encodeData( it->sprite );
		savedGame.encodeData( it->m_ActionNumber );
290
		it->serialize(savedGame);
Gerhard Stein's avatar
Gerhard Stein committed
291 292 293 294 295
	}

	// Save the map_data as it is left
	savedGame.encodeData(mMap.m_width);
	savedGame.encodeData(mMap.m_height);
296 297 298 299 300

	const Uint32 mapSize = mMap.m_width*mMap.m_height*sizeof(word);

	savedGame.addData( reinterpret_cast<byte*>(mMap.getBackgroundData()), mapSize );
	savedGame.addData( reinterpret_cast<byte*>(mMap.getForegroundData()), mapSize );
301
	savedGame.addData( reinterpret_cast<byte*>(mMap.getInfoData()), mapSize );
302 303
}

304 305


306
// This is for loading the game
Gerhard Stein's avatar
Gerhard Stein committed
307
bool CMapPlayGalaxy::operator<<(CSaveGameController &savedGame)
308
{
309 310 311
	Uint16 level;
	savedGame.decodeData( level );

Gerhard Stein's avatar
Gerhard Stein committed
312
	std::unique_ptr<galaxy::CMapLoaderGalaxy> mapLoader;
313
	const unsigned int episode = gpBehaviorEngine->getEpisode();
314

Gerhard Stein's avatar
Gerhard Stein committed
315
	if(episode == 4)
316
	{
317
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp4( mObjectPtr, mInventoryVec) );
318
	}
Gerhard Stein's avatar
Gerhard Stein committed
319
	else if(episode == 5)
320
	{
321
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp5( mObjectPtr, mInventoryVec) );
322
	}
323
	else if(episode == 6)
324
	{
325
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp6( mObjectPtr, mInventoryVec) );
326
	}
Gerhard Stein's avatar
Gerhard Stein committed
327 328
	else
	{
329
		gLogging.textOut("Error loading the file. This game is not supported!");
Gerhard Stein's avatar
Gerhard Stein committed
330 331 332 333 334
		return false;
	}

	// Load the World map level.
	mapLoader->loadMap( mMap, level );
335 336 337 338

    // Load the Background Music
	g_pMusicPlayer->stop();

Gerhard Stein's avatar
Gerhard Stein committed
339 340

    if( !galaxy::loadLevelMusic(level) )
341
    	gLogging.textOut("Warning: The music cannot be played. Check that all the files have been correctly copied!");
342 343 344 345
    else
    	g_pMusicPlayer->play();


346 347 348
	// load the number of objects on screen
	Uint32 size;
	Uint32 x, y;
349 350
	Uint16 foeID;
	uint16_t actionNumber;
351
	savedGame.decodeData(size);
352

353 354 355 356
	// Now load the previously created objects

	if(!mObjectPtr.empty())
		mObjectPtr.clear();
gerstrong's avatar
gerstrong committed
357

Gerhard Stein's avatar
Gerhard Stein committed
358
	mMap.mNumFuses = 0;
359
	mMap.mFuseInLevel = false;
360 361

	for( Uint32 i=0 ; i<size ; i++ )
Gerhard Stein's avatar
Gerhard Stein committed
362
	{
363
		savedGame.decodeData(foeID);
364 365
		savedGame.decodeData(x);
		savedGame.decodeData(y);
366

Gerhard Stein's avatar
Gerhard Stein committed
367
		CGalaxySpriteObject *pNewfoe = mapLoader->addFoe(mMap, foeID, x, y);
368 369 370

		// TODO: Be careful here is a bad Null Pointer inside that structure
		if(pNewfoe == NULL)
371
		{
Gerhard Stein's avatar
Gerhard Stein committed
372
            pNewfoe = new CGalaxySpriteObject(&mMap, foeID, x, y, 0);
373
		}
374 375 376 377 378 379 380 381 382

		savedGame.decodeData( pNewfoe->dead );
		savedGame.decodeData( pNewfoe->onscreen );
		savedGame.decodeData( pNewfoe->hasbeenonscreen );
		savedGame.decodeData( pNewfoe->exists );
		savedGame.decodeData( pNewfoe->blockedd );
		savedGame.decodeData( pNewfoe->blockedu );
		savedGame.decodeData( pNewfoe->blockedl );
		savedGame.decodeData( pNewfoe->blockedr );
383
		savedGame.decodeData( pNewfoe->xDirection );
384
		savedGame.decodeData( pNewfoe->yDirection );
385 386 387 388 389 390
		savedGame.decodeData( pNewfoe->mHealthPoints );
		savedGame.decodeData( pNewfoe->canbezapped );
		savedGame.decodeData( pNewfoe->cansupportplayer );
		savedGame.decodeData( pNewfoe->inhibitfall );
		savedGame.decodeData( pNewfoe->honorPriority );
		savedGame.decodeData( pNewfoe->sprite );
391
		savedGame.decodeData( actionNumber );
392
		pNewfoe->deserialize(savedGame);
Gerhard Stein's avatar
Gerhard Stein committed
393

394
		if(pNewfoe->exists)
395 396
		{
		    pNewfoe->setActionForce(actionNumber);
gerstrong's avatar
gerstrong committed
397
		    std::shared_ptr<CGalaxySpriteObject> newFoe(pNewfoe);
Gerhard Stein's avatar
Gerhard Stein committed
398
		    mObjectPtr.push_back(newFoe);
399
		}
400
	}
Gerhard Stein's avatar
Gerhard Stein committed
401

402 403 404
	// Save the map_data as it is left
	savedGame.decodeData(mMap.m_width);
	savedGame.decodeData(mMap.m_height);
Gerhard Stein's avatar
Gerhard Stein committed
405

406 407
	savedGame.readDataBlock( reinterpret_cast<byte*>(mMap.getBackgroundData()) );
	savedGame.readDataBlock( reinterpret_cast<byte*>(mMap.getForegroundData()) );
408
	savedGame.readDataBlock( reinterpret_cast<byte*>(mMap.getInfoData()) );
Gerhard Stein's avatar
Gerhard Stein committed
409

410
	if( mMap.m_width * mMap.m_height > 0 )
411
	{
412
		mMap.drawAll();
413
	}
414

415
	return true;
416
}
Gerhard Stein's avatar
Gerhard Stein committed
417 418 419 420 421


// Saves the level using the Savegamecontroller in XML.
void CMapPlayGalaxy::operator>>(boost::property_tree::ptree &levelNode)
{
422
    // Coding here
Gerhard Stein's avatar
Gerhard Stein committed
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
    const Uint16 level = mMap.getLevel();
    levelNode.put("level", level);

    std::vector< std::shared_ptr<CGalaxySpriteObject> > filteredObjects;

    // let's filter the Foe out that won't do any good, by having an invalid foe id
    for( auto &it : mObjectPtr )
    {
        if( it->mFoeID != 0 )
        {
            filteredObjects.push_back( it );
        }
    }

    const size_t size = filteredObjects.size();

    // save the number of objects on screen
    levelNode.put("NumSprites", size);

    for( auto &it : filteredObjects )
    {
        auto &spriteNode = levelNode.add("Sprite", "");

        // save all the objects states
        unsigned int newYpos = it->getYPosition();
        unsigned int newXpos = it->getXPosition();

        spriteNode.put("<xmlattr>.id", it->mFoeID);
451
        spriteNode.put("<xmlattr>.variant", it->getSpriteVariantId());
Gerhard Stein's avatar
Gerhard Stein committed
452 453 454 455 456 457 458 459 460 461 462 463 464
        spriteNode.put("<xmlattr>.x", newXpos);
        spriteNode.put("<xmlattr>.y", newYpos);

        spriteNode.put("dead", it->dead);
        spriteNode.put("onscreen", it->onscreen);
        spriteNode.put("hasbeenonscreen", it->hasbeenonscreen);
        spriteNode.put("exists", it->exists);
        spriteNode.put("blockedd", it->blockedd);
        spriteNode.put("blockedu", it->blockedu);
        spriteNode.put("blockedl", it->blockedl);
        spriteNode.put("blockedr", it->blockedr);
        spriteNode.put("xDirection", it->xDirection);
        spriteNode.put("yDirection", it->yDirection);
465
        spriteNode.put("health", (int)it->mHealthPoints);
Gerhard Stein's avatar
Gerhard Stein committed
466 467 468 469 470 471
        spriteNode.put("canbezapped", it->canbezapped);
        spriteNode.put("cansupportplayer", it->cansupportplayer);
        spriteNode.put("inhibitfall", it->inhibitfall);
        spriteNode.put("honorPriority", it->honorPriority);
        spriteNode.put("spritePic", it->sprite);
        spriteNode.put("Actionumber", it->m_ActionNumber);
Gerhard Stein's avatar
Gerhard Stein committed
472
        it->serialize(spriteNode);
Gerhard Stein's avatar
Gerhard Stein committed
473 474
    }

475 476
    // Save the map_data as it is left
    {
477
        auto &mapNode = levelNode.put("Map", "");
478 479 480 481
        mapNode.put("width", mMap.m_width);
        mapNode.put("height", mMap.m_height);

        const Uint32 mapSize = mMap.m_width*mMap.m_height*sizeof(word);
Gerhard Stein's avatar
Gerhard Stein committed
482

483 484 485
        const std::string b64textBG   = base64Encode( reinterpret_cast<byte*>(mMap.getBackgroundData()), mapSize);
        const std::string b64textFG   = base64Encode( reinterpret_cast<byte*>(mMap.getForegroundData()), mapSize);
        const std::string b64textInfo = base64Encode( reinterpret_cast<byte*>(mMap.getInfoData()), mapSize);
Gerhard Stein's avatar
Gerhard Stein committed
486

487 488 489 490
        mapNode.put("bgdata", b64textBG);
        mapNode.put("fgdata", b64textFG);
        mapNode.put("infodata", b64textInfo);
    }
Gerhard Stein's avatar
Gerhard Stein committed
491 492 493 494 495
}

// This is for loading the game
void CMapPlayGalaxy::operator<<(boost::property_tree::ptree &levelNode)
{
gerstrong's avatar
gerstrong committed
496
    int level = levelNode.get<int>("level", 0);
497 498

    std::unique_ptr<galaxy::CMapLoaderGalaxy> mapLoader;
499
    const unsigned int episode = gpBehaviorEngine->getEpisode();
500 501 502

    if(episode == 4)
    {
503
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp4( mObjectPtr, mInventoryVec) );
504 505 506
    }
    else if(episode == 5)
    {
507
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp5( mObjectPtr, mInventoryVec) );
508 509 510
    }
    else if(episode == 6)
    {
511
        mapLoader.reset( new galaxy::CMapLoaderGalaxyEp6( mObjectPtr, mInventoryVec) );
512 513 514
    }
    else
    {
515
        gLogging.textOut("Error loading the file. This game is not supported!");
516
        return;
gerstrong's avatar
gerstrong committed
517
    }
518 519 520 521 522 523 524

    // Load the World map level.
    mapLoader->loadMap( mMap, level );

    // Load the Background Music
    g_pMusicPlayer->stop();

Gerhard Stein's avatar
Gerhard Stein committed
525
    if( !galaxy::loadLevelMusic(level) )
526
        gLogging.textOut("Warning: The music cannot be played. Check that all the files have been correctly copied!");
527 528 529 530 531 532 533 534 535 536
    else
        g_pMusicPlayer->play();


    // load the number of objects on screen
    Uint32 x, y;
    Uint16 foeID;

    // Now load the previously created objects

537
    //const size_t size = levelNode.get<int>("NumSprites", 0);
538 539 540 541 542

    // Now load the previously created objects
    if(!mObjectPtr.empty())
        mObjectPtr.clear();

543 544
    mapLoader->resetNumLoadedPlayers();

545 546 547
    mMap.mNumFuses = 0;
    mMap.mFuseInLevel = false;

548
    for( auto &levelItem : levelNode )
gerstrong's avatar
gerstrong committed
549
    {
550
        if(levelItem.first == "Sprite")
551
        {
552 553 554
            auto &spriteNode = levelItem.second;

            foeID = spriteNode.get<int>("<xmlattr>.id");
555
            int sprVarID = spriteNode.get<int>("<xmlattr>.variant", 0);
556 557 558 559 560 561 562 563
            x = spriteNode.get<int>("<xmlattr>.x");;
            y = spriteNode.get<int>("<xmlattr>.y");;

            CGalaxySpriteObject *pNewfoe = mapLoader->addFoe(mMap, foeID, x, y);

            // TODO: Be careful here is a bad Null Pointer inside that structure
            if(pNewfoe == nullptr)
            {
Gerhard Stein's avatar
Gerhard Stein committed
564
                pNewfoe = new CGalaxySpriteObject(&mMap, foeID, x, y, sprVarID);
565 566 567 568 569 570 571 572 573 574
            }

            pNewfoe->dead = spriteNode.get<bool>("dead", false);
            pNewfoe->onscreen = spriteNode.get<bool>("onscreen", false);
            pNewfoe->hasbeenonscreen = spriteNode.get<bool>("hasbeenonscreen", false);
            pNewfoe->exists = spriteNode.get<bool>("exists", false);
            pNewfoe->blockedd = spriteNode.get<bool>("blockedd", false);
            pNewfoe->blockedu = spriteNode.get<bool>("blockedu", false);
            pNewfoe->blockedl = spriteNode.get<bool>("blockedl", false);
            pNewfoe->blockedr = spriteNode.get<bool>("blockedr", false);
575 576 577
            pNewfoe->xDirection = spriteNode.get<int>("xDirection", 0);
            pNewfoe->yDirection = spriteNode.get<int>("yDirection", 0);
            pNewfoe->mHealthPoints = spriteNode.get<int>("health", 1);
578 579 580 581
            pNewfoe->canbezapped = spriteNode.get<bool>("canbezapped", false);
            pNewfoe->cansupportplayer = spriteNode.get<bool>("cansupportplayer", false);
            pNewfoe->inhibitfall = spriteNode.get<bool>("inhibitfall", false);
            pNewfoe->honorPriority = spriteNode.get<bool>("honorPriority", false);
582 583
            pNewfoe->sprite = spriteNode.get<int>("spritePic", 1);
            const Uint16 actionNumber = spriteNode.get<int>("Actionumber", 1);
584 585 586 587 588 589 590 591
            pNewfoe->deserialize(spriteNode);

            if(pNewfoe->exists)
            {
                pNewfoe->setActionForce(actionNumber);
                std::shared_ptr<CGalaxySpriteObject> newFoe(pNewfoe);
                mObjectPtr.push_back(newFoe);
            }
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
        }
    }


    // Save the map_data as it is left
    {
        auto &mapNode = levelNode.get_child("Map");
        mMap.m_width = mapNode.get<int>("width");
        mMap.m_height = mapNode.get<int>("height");

        const std::string b64textBG   = mapNode.get<std::string>("bgdata");
        const std::string b64textFG   = mapNode.get<std::string>("fgdata");
        const std::string b64textInfo = mapNode.get<std::string>("infodata");

        base64Decode(reinterpret_cast<byte*>(mMap.getBackgroundData()), b64textBG);
        base64Decode(reinterpret_cast<byte*>(mMap.getForegroundData()), b64textFG);
        base64Decode(reinterpret_cast<byte*>(mMap.getInfoData()), b64textInfo);
    }

    if( mMap.m_width * mMap.m_height > 0 )
    {
        mMap.drawAll();
    }
Gerhard Stein's avatar
Gerhard Stein committed
615 616 617
}