CFuse.cpp 5.88 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * CAmpton.cpp
 *
 *  Created on: 29 Dez 2012
 *      Author: Gerstrong
 */


#include "CFuse.h"
Gerhard Stein's avatar
Gerhard Stein committed
10
#include "../../common/ai/CPlayerLevel.h"
11
#include "../../common/dialog/CMessageBoxBitmapGalaxy.h"
12
#include <base/utils/misc.h>
13
#include <sdl/audio/music/CMusic.h>
14
#include "../../common/ai/CEnemyShot.h"
15 16

/*
17
$3186W #QED?
18 19 20 21 22 23
 */


namespace galaxy {  
  
  
24 25
CFuse::CFuse(CMap *pmap, const Uint16 foeID, const Uint32 x, const Uint32 y, const int sprVar) :
CGalaxySpriteObject(pmap, foeID, x, y, sprVar),
26 27 28
mTimer(0)
{  
	// Adapt this AI
Gerhard Stein's avatar
Gerhard Stein committed
29 30
	m_ActionBaseOffset = 0x3186;
	setActionForce(0);
Gerhard Stein's avatar
Gerhard Stein committed
31
	//setupGalaxyObjectOnMap(0x3186, 0);
32 33
	
	xDirection = LEFT;
34
	
35 36
	mpMap->mNumFuses++;
	mpMap->mFuseInLevel = true;
37 38 39 40 41 42 43 44

    loadPythonScripts("qed");
}



bool CFuse::loadPythonScripts(const std::string &scriptBaseName)
{
45
    #if USE_PYTHON3
Gerhard Stein's avatar
Gerhard Stein committed
46
    auto pModule = gPython.loadModule( scriptBaseName, JoinPaths(gKeenFiles.gameDir ,"ai") );
47

48
    const int level = mpMap->getLevel();
49

50 51 52
    if (pModule != nullptr)
    {

53 54 55 56 57 58
        // Change the bounding box, so object are easier to touch
        m_BBox.x1 = -(1<<CSF);
        m_BBox.y1 = -(1<<CSF);
        m_BBox.x2 = (2<<CSF);
        m_BBox.y2 = (2<<CSF);

59 60
        // Level Text
        {            
61 62 63 64 65
            // pFunc is a new reference
            PyObject *pFunc = PyObject_GetAttrString(pModule, "getLevelText");

            if (pFunc && PyCallable_Check(pFunc))
            {
66 67 68 69 70
                PyObject *arglist = Py_BuildValue("(i)", level);


                PyObject *pValue = PyObject_CallObject(pFunc, arglist);

71 72

                if (pValue != nullptr)
73 74 75
                {                    
                    PyObject *objectsRepresentation = PyObject_Repr(pValue);

Gerhard Stein's avatar
Gerhard Stein committed
76
                    auto *str = PyUnicode_AsUTF8(objectsRepresentation) ;
77 78

                    if(str)
79
                    {
80
                        std::string message = str;
81 82 83 84

                        // Because line breaks are not formatted correctly
                        fixNewLine(message);

85 86 87 88
                        if(!message.empty())
                        {
                            std::string levelText = "LEVEL_TEXT";
                            levelText += itoa(level);
89
                            gBehaviorEngine.setMessage(levelText, message);
90
                        }
91
                    }
92

93
                    Py_DECREF(pValue);
94
                    Py_DECREF(objectsRepresentation);
95 96 97
                }
                else
                {
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

                    PyErr_Print();
                    gLogging.ftextOut("Call failed\n");
                    return false;
                }

                Py_DECREF(pFunc);
                Py_DECREF(arglist);
            }
            else
            {
                if (PyErr_Occurred())
                {
                    PyErr_Print();
                }

                gLogging.ftextOut("Cannot find function \"pyMethodStr\"\n");
                return false;
            }

            Py_XDECREF(pFunc);


        }

        // The bitmap of the hint message
        {
            // pFunc is a new reference
            PyObject *pFunc = PyObject_GetAttrString(pModule, "getLevelTextBmp");

            if (pFunc && PyCallable_Check(pFunc))
            {
                PyObject *arglist = Py_BuildValue("(i)", level);


                PyObject *pValue = PyObject_CallObject(pFunc, arglist);


                if (pValue != nullptr)
                {
                    mLevelTestBmp = PyLong_AsLong(pValue);
                    Py_DECREF(pValue);
                }
                else
                {
143 144 145 146
                    PyErr_Print();
                    gLogging.ftextOut("Call failed\n");
                    return false;
                }
147

148
                Py_DECREF(pFunc);
149
                Py_DECREF(arglist);
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
            }
            else
            {
                if (PyErr_Occurred())
                {
                    PyErr_Print();
                }

                gLogging.ftextOut("Cannot find function \"pyMethodStr\"\n");
                return false;
            }

            Py_XDECREF(pFunc);


165
        }
166 167 168 169 170 171 172 173 174

        Py_DECREF(pModule);
    }
    else
    {
        return false;
    }

    Py_Finalize();
175
#endif
176 177

    return true;
178 179 180
}


181 182


183 184
void CFuse::getTouchedBy(CSpriteObject &theObject)
{
185
	if(mIsDead || theObject.mIsDead)
186
		return;
187

188

189 190
    if( auto *thePlayer = dynamic_cast<CPlayerLevel*>(&theObject) )
    {
191
        const auto level = mpMap->getLevel();
192 193
        std::string levelText = "LEVEL_TEXT";
        levelText += itoa(level);
194

195
        const auto msg = gBehaviorEngine.getString(levelText);
196

197 198 199 200
        if(!msg.empty())
        {
            thePlayer->m_Inventory.Item.m_gem.clear();
            thePlayer->m_Inventory.Item.fuse_levels_completed++;
201
            mpMap->mFuseInLevel = false;
202

203
            std::vector<CMessageBoxGalaxy*> msgs;
204

205
            const int sprVar = thePlayer->getSpriteVariantIdx();
206 207

            msgs.push_back( new CMessageBoxBitmapGalaxy(sprVar,
208
                                msg,
209
                                gGraphics.getBitmapFromId(sprVar, mLevelTestBmp),
210
                                RIGHT,
211
                                true, nullptr) );
212

213
            showMsgVec( msgs );
214
            mIsDead = true;
215
        }
216
    }
217 218 219 220 221 222 223 224 225 226
    else if( auto *theEnemyShot = dynamic_cast<CEnemyShot*>(&theObject) ) // happens when Keen 9 - Fight against Mortimer
    {
        // Now replace those tiles
        for(int x=m_BBox.x1 ; x<m_BBox.x2 ; x+=(1<<CSF))
        {
            for(int y=m_BBox.y1 ; y<m_BBox.y2 ; y+=(1<<CSF))
            {
                const Uint16 where_x = (getXPosition()+x)>>CSF;
                const Uint16 where_y = (getYPosition()+y)>>CSF;

227
                mpMap->setTile(where_x, where_y, 0, true, 1);
228 229 230
            }
        }

231 232
        mIsDead = true;
        theEnemyShot->mIsDead = true;
233
    }
234

235 236 237 238 239
}


void CFuse::process()
{
240
    // TODO: We might need a scattermLevelTestBmp effect here
Gerhard Stein's avatar
Gerhard Stein committed
241 242
	//if(!processActionRoutine())
	  //  exists = false;
243 244 245
}

}