//-------------------------------------------------------------- void ofApp::setup(){ ofSetFrameRate(60.0f); ofHideCursor(); // 读取字体文件 bool bLoad = Font.loadFont("fonts/vag.ttf",24); // 加载音效资源 ofSoundPlayer P0; bool bP0 = P0.loadSound("sounds/tap1.mp3"); P0.setMultiPlay(true); P0.setLoop(false); Sounds["ChangeSize"] = P0; ofSoundPlayer P1; bool bP1 = P1.loadSound("sounds/mario_mainTheme.mp3"); P1.setLoop(true); P1.setVolume(0.3f); Sounds["Background"] = P1; P1.play(); ofSoundPlayer P2; bool bP2 = P2.loadSound("sounds/mario_jump.mp3"); P2.setLoop(false); P2.setVolume(1.0f); P2.setSpeed(1.25f); Sounds["Jump"] = P2; ofSoundPlayer P3; bool bP3 = P3.loadSound("sounds/mario_fail.mp3"); P3.setLoop(false); P3.setVolume(1.0f); P3.setSpeed(1.0f); Sounds["Fail"] = P3; ofSoundPlayer P4; bool bP4 = P4.loadSound("sounds/mario_stepOnEnemy.mp3"); P4.setLoop(false); P4.setVolume(1.0f); P4.setSpeed(1.0f); P4.setMultiPlay(true); Sounds["Eat"] = P4; ofSoundPlayer P5; bool bP5 = P5.loadSound("sounds/mario_coin.mp3"); P5.setLoop(false); P5.setVolume(1.0f); P5.setSpeed(1.0f); P5.setMultiPlay(true); Sounds["Coin"] = P5; ofSoundPlayer P6; bool bP6 = P6.loadSound("sounds/error.wav"); P6.setLoop(false); P6.setVolume(1.0f); P6.setSpeed(1.0f); P6.setMultiPlay(true); Sounds["Error"] = P6; ofSoundPlayer P7; bool bP7 = P7.loadSound("sounds/shrink.mp3"); P7.setLoop(false); P7.setVolume(1.0f); P7.setSpeed(1.0f); P7.setMultiPlay(true); Sounds["Beat"] = P7; ofSoundPlayer P8; bool bP8 = P8.loadSound("sounds/whip.mp3"); P8.setLoop(false); P8.setVolume(1.0f); P8.setSpeed(1.0f); P8.setMultiPlay(true); Sounds["Beat2"] = P8; // 初始化键鼠状态 for(int i=0;i<3;i++) { MouseKeyState[i] = false; } MousePos = ofVec2f(0,0); bShowDebug.set("ShowDebugInfo",true);//默认显示调试信息 FPS.set("FPS",0,0,100); //记录默认窗口尺寸 windowSizeX = ofGetWidth(); windowSizeY = ofGetHeight(); // 构造玩家 pPlayer.reset(new DrawGame::CircleSprite(&Font)); // 初始化敌人参数 EnemyBirthrate.set("EnemyBirthRate",1.0f,0.2f,5.0f); EnemyGrowthrate.set("EnemyGrowthRate",10.0f,0.0f,50.0f); WhiteEnemyRatio.set("WhiteEnemyRatio",0.3f,0.0f,1.0f); // 游戏状态 bGameRunning = true; HP.set("HP",2000.0f,0.0f,10000.0f); HPMax.set("HPMax",3500.0f,50.0f,10000.0f); // 画布 Canvas.allocate(windowSizeX,windowSizeY,GL_RGBA); Canvas.begin(); ofClear(ofColor::white); Canvas.end(); // 游戏规则参数 CoinValue.set("CoinValue",20.0f,0.0f,100.0f); HPIncSpd.set("HPIncreaseSpeed",3.0f,0.0f,30.0f); HPDecSpd.set("HPDecreaseSpeed",1.0f,0.0f,10.0f); HPDecJumpA.set("HPDecJumpA",5.0f,0.0f,50.0f); HPDecJumpB.set("HPDecJumpB",2.0f,0.0f,20.0f); HPEatAmt.set("HPEatAmount",7.0f,0.0f,200.0f); HPBeatAmt.set("HPBeatAmount",15.0f,0.0f,500.0f); HPBeatAmt2.set("HPBeatAmount",50.0f,0.0f,500.0f); // 初始化调试界面 Params.setName("Settings"); Params.add(EnemyBirthrate); Params.add(EnemyGrowthrate); Params.add(WhiteEnemyRatio); Params.add(HP); Params.add(HPMax); Params.add(CoinValue); Params.add(HPIncSpd); Params.add(HPDecSpd); Params.add(HPDecJumpA); Params.add(HPDecJumpB); Params.add(HPEatAmt); Params.add(HPBeatAmt); Params.add(HPBeatAmt2); loadSettings(); BtnReset.setup("Reset Game"); BtnReset.addListener(this,&ofApp::startGame); BtnSaveDrawing.setup("Save Drawing"); BtnSaveDrawing.addListener(this,&ofApp::saveCanvasImage); BtnSaveSettings.setup("Save Settings"); BtnSaveSettings.addListener(this,&ofApp::saveSettings); BtnLoadSettings.setup("Load Settings"); BtnLoadSettings.addListener(this,&ofApp::loadSettings); GUI_Debug.setup("Params"); GUI_Debug.add(&BtnReset); GUI_Debug.add(&BtnSaveDrawing); GUI_Debug.add(&BtnSaveSettings); GUI_Debug.add(&BtnLoadSettings); GUI_Debug.add(bShowDebug); GUI_Debug.add(FPS); GUI_Debug.add(Params); GUI_Debug.setPosition( ofGetWidth()-GUI_Debug.getWidth(),0); // 游戏界面初始化 ofVec2f Ctr(ofGetWidth()/2,ofGetHeight()/2); Ctr += ofVec2f(0,ofGetWidth()/6); ofPtr<DrawGame::GUITextButton> pBtn; pBtn.reset(new DrawGame::GUITextButton( "GUI_Retry","Retry",120,40,&Font,Ctr)); pRetryBtn = pBtn; ofAddListener(pRetryBtn->GUIEvent,this,&ofApp::GUICallback); pRetryBtn->setScale(1.5f); pRetryBtn->setVisible(false); pRetryBtn->setActive(false); ofPtr<DrawGame::GUIDataSlot> pHB; ofRectangle R(5,5,ofGetWidth()-10,30); string Tag2("GUI_HP"),Title2("HP"); ofParameter<float>* ptrHp= &HP; //pHB.reset(new ofPtr<DrawGame::GUIDataBar>( //ptrHp,Tag2,Title2,R,800.0f,&Font,2.0f)); ofTrueTypeFont* ft = &Font; pHB.reset(new DrawGame::GUIDataSlot( HP,HPMax,Tag2,Title2,R,0.1f,&Font,1000.0f,2.0f)); pHpBar = pHB; }
BOOL CbelaviewDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; FILE *fp; int i, j, k, t; char s[1024], q[1024]; char *v; double b; BOOL flag = FALSE; CPointProp PProp; CBoundaryProp BProp; CMaterialProp MProp; CCircuit CProp; CNode node; CSegment segm; CArcSegment asegm; CElement elm; CBlockLabel blk; CMeshNode mnode; CPoint mline; // make sure old document is cleared out... if (NumList != NULL) { for (i = 0; i < meshnode.GetSize(); i++) { if (ConList[i] != NULL) free(ConList[i]); } free(ConList); ConList = NULL; free(NumList); NumList = NULL; } nodelist.RemoveAll(); linelist.RemoveAll(); blocklist.RemoveAll(); arclist.RemoveAll(); nodeproplist.RemoveAll(); lineproplist.RemoveAll(); blockproplist.RemoveAll(); circproplist.RemoveAll(); meshnode.RemoveAll(); meshelem.RemoveAll(); contour.RemoveAll(); if ((fp = fopen(lpszPathName, "rt")) == NULL) { MsgBox("Couldn't read from specified .poly file"); return FALSE; } // define some defaults ProblemType = 0; Coords = 0; ProblemNote = ""; bHasMask = FALSE; Depth = -1; // parse the file while (flag == FALSE) { fgets(s, 1024, fp); sscanf(s, "%s", q); // Deal with flag for file format version if (_strnicmp(q, "[format]", 8) == 0) { double vers; v = StripKey(s); sscanf(v, "%lf", &vers); if (((int)vers) != 1) MsgBox("File is from a different version of Bela\nTrying to read anyhow..."); q[0] = NULL; } // Depth in the into-the-page direction if (_strnicmp(q, "[depth]", 7) == 0) { v = StripKey(s); sscanf(v, "%lf", &Depth); q[0] = NULL; } // Units of length used by the problem if (_strnicmp(q, "[lengthunits]", 13) == 0) { v = StripKey(s); sscanf(v, "%s", q); if (_strnicmp(q, "inches", 6) == 0) LengthUnits = 0; else if (_strnicmp(q, "millimeters", 11) == 0) LengthUnits = 1; else if (_strnicmp(q, "centimeters", 1) == 0) LengthUnits = 2; else if (_strnicmp(q, "mils", 4) == 0) LengthUnits = 4; else if (_strnicmp(q, "microns", 6) == 0) LengthUnits = 5; else if (_strnicmp(q, "meters", 6) == 0) LengthUnits = 3; q[0] = NULL; } // Problem Type (planar or axisymmetric) if (_strnicmp(q, "[problemtype]", 13) == 0) { v = StripKey(s); sscanf(v, "%s", q); if (_strnicmp(q, "planar", 6) == 0) ProblemType = 0; if (_strnicmp(q, "axisymmetric", 3) == 0) ProblemType = 1; q[0] = NULL; } // Coordinates (cartesian or polar) if (_strnicmp(q, "[coordinates]", 13) == 0) { v = StripKey(s); sscanf(v, "%s", q); if (_strnicmp(q, "cartesian", 4) == 0) Coords = 0; if (_strnicmp(q, "polar", 5) == 0) Coords = 1; q[0] = NULL; } // Comments if (_strnicmp(q, "[comment]", 9) == 0) { v = StripKey(s); // put in carriage returns; k = (int)strlen(v); for (i = 0; i < k; i++) { if ((v[i] == '\\') && (v[i + 1] == 'n')) { v[i] = 13; v[i + 1] = 10; } } for (i = 0; i < k; i++) { if (v[i] == '\"') { v = v + i + 1; i = k; } } k = (int)strlen(v); if (k > 0) { for (i = k - 1; i >= 0; i--) { if (v[i] == '\"') { v[i] = 0; i = -1; } } } ProblemNote = v; q[0] = NULL; } // properties for axisymmetric external region if (_strnicmp(q, "[extzo]", 7) == 0) { v = StripKey(s); sscanf(v, "%lf", &extZo); q[0] = NULL; } if (_strnicmp(q, "[extro]", 7) == 0) { v = StripKey(s); sscanf(v, "%lf", &extRo); q[0] = NULL; } if (_strnicmp(q, "[extri]", 7) == 0) { v = StripKey(s); sscanf(v, "%lf", &extRi); q[0] = NULL; } // Point Properties if (_strnicmp(q, "<beginpoint>", 11) == 0) { PProp.PointName = "New Point Property"; PProp.V = PProp.qp = 0; q[0] = NULL; } if (_strnicmp(q, "<pointname>", 11) == 0) { v = StripKey(s); k = (int)strlen(v); for (i = 0; i < k; i++) { if (v[i] == '\"') { v = v + i + 1; i = k; } } k = (int)strlen(v); if (k > 0) { for (i = k - 1; i >= 0; i--) { if (v[i] == '\"') { v[i] = 0; i = -1; } } } PProp.PointName = v; q[0] = NULL; } if (_strnicmp(q, "<vp>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &PProp.V); q[0] = NULL; } if (_strnicmp(q, "<qp>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &PProp.qp); q[0] = NULL; } if (_strnicmp(q, "<endpoint>", 9) == 0) { nodeproplist.Add(PProp); q[0] = NULL; } // Boundary Properties; if (_strnicmp(q, "<beginbdry>", 11) == 0) { BProp.BdryName = "New Boundary"; BProp.BdryFormat = 0; BProp.V = BProp.qs = 0; BProp.c0 = BProp.c1 = 0; q[0] = NULL; } if (_strnicmp(q, "<bdryname>", 10) == 0) { v = StripKey(s); k = (int)strlen(v); for (i = 0; i < k; i++) { if (v[i] == '\"') { v = v + i + 1; i = k; } } k = (int)strlen(v); if (k > 0) { for (i = k - 1; i >= 0; i--) { if (v[i] == '\"') { v[i] = 0; i = -1; } } } BProp.BdryName = v; q[0] = NULL; } if (_strnicmp(q, "<bdrytype>", 10) == 0) { v = StripKey(s); sscanf(v, "%i", &BProp.BdryFormat); q[0] = NULL; } if (_strnicmp(q, "<vs>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &BProp.V); q[0] = NULL; } if (_strnicmp(q, "<qs>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &BProp.qs); q[0] = NULL; } if (_strnicmp(q, "<c0>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &BProp.c0); q[0] = NULL; } if (_strnicmp(q, "<c1>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &BProp.c1); q[0] = NULL; } if (_strnicmp(q, "<endbdry>", 9) == 0) { lineproplist.Add(BProp); q[0] = NULL; } // Block Properties; if (_strnicmp(q, "<beginblock>", 12) == 0) { MProp.BlockName = "New Material"; MProp.ex = 1.; MProp.ey = 1.; MProp.qv = 0.; q[0] = NULL; } if (_strnicmp(q, "<blockname>", 10) == 0) { v = StripKey(s); k = (int)strlen(v); for (i = 0; i < k; i++) { if (v[i] == '\"') { v = v + i + 1; i = k; } } k = (int)strlen(v); if (k > 0) { for (i = k - 1; i >= 0; i--) { if (v[i] == '\"') { v[i] = 0; i = -1; } } } MProp.BlockName = v; q[0] = NULL; } if (_strnicmp(q, "<ex>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &MProp.ex); q[0] = NULL; } if (_strnicmp(q, "<ey>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &MProp.ey); q[0] = NULL; } if (_strnicmp(q, "<qv>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &MProp.qv); q[0] = NULL; } if (_strnicmp(q, "<endblock>", 9) == 0) { blockproplist.Add(MProp); q[0] = NULL; } // Circuit Properties if (_strnicmp(q, "<beginconductor>", 16) == 0) { CProp.CircName = "New Circuit"; CProp.V = CProp.q = 0; CProp.CircType = 0; q[0] = NULL; } if (_strnicmp(q, "<conductorname>", 15) == 0) { v = StripKey(s); k = (int)strlen(v); for (i = 0; i < k; i++) { if (v[i] == '\"') { v = v + i + 1; i = k; } } k = (int)strlen(v); if (k > 0) { for (i = k - 1; i >= 0; i--) { if (v[i] == '\"') { v[i] = 0; i = -1; } } } CProp.CircName = v; q[0] = NULL; } if (_strnicmp(q, "<vc>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &CProp.V); q[0] = NULL; } if (_strnicmp(q, "<qc>", 4) == 0) { v = StripKey(s); sscanf(v, "%lf", &CProp.q); q[0] = NULL; } if (_strnicmp(q, "<conductortype>", 15) == 0) { v = StripKey(s); sscanf(v, "%i", &CProp.CircType); q[0] = NULL; } if (_strnicmp(q, "<endconductor>", 14) == 0) { circproplist.Add(CProp); q[0] = NULL; } // Points list; if (_strnicmp(q, "[numpoints]", 11) == 0) { v = StripKey(s); sscanf(v, "%i", &k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%lf %lf %i %i %i\n", &node.x, &node.y, &t, &node.InGroup, &node.InConductor); node.BoundaryMarker = t - 1; node.InConductor--; nodelist.Add(node); } q[0] = NULL; } // read in segment list if (_strnicmp(q, "[numsegments]", 13) == 0) { v = StripKey(s); sscanf(v, "%i", &k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%i %i %lf %i %i %i %i\n", &segm.n0, &segm.n1, &segm.MaxSideLength, &t, &segm.Hidden, &segm.InGroup, &segm.InConductor); segm.BoundaryMarker = t - 1; segm.InConductor--; linelist.Add(segm); } q[0] = NULL; } // read in arc segment list if (_strnicmp(q, "[numarcsegments]", 13) == 0) { v = StripKey(s); sscanf(v, "%i", &k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%i %i %lf %lf %i %i %i %i\n", &asegm.n0, &asegm.n1, &asegm.ArcLength, &asegm.MaxSideLength, &t, &asegm.Hidden, &asegm.InGroup, &asegm.InConductor); asegm.BoundaryMarker = t - 1; asegm.InConductor--; arclist.Add(asegm); } q[0] = NULL; } // read in list of holes; if (_strnicmp(q, "[numholes]", 13) == 0) { v = StripKey(s); sscanf(v, "%i", &k); if (k > 0) { blk.BlockType = -1; blk.MaxArea = 0; for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%lf %lf\n", &blk.x, &blk.y); // blocklist.Add(blk); // don't add holes to the list // of block labels because it messes up the // number of block labels. } } q[0] = NULL; } // read in regional attributes if (_strnicmp(q, "[numblocklabels]", 13) == 0) { v = StripKey(s); sscanf(v, "%i", &k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%lf %lf %i %lf %i %i\n", &blk.x, &blk.y, &blk.BlockType, &blk.MaxArea, &blk.InGroup, &blk.IsExternal); blk.IsDefault = blk.IsExternal & 2; blk.IsExternal = blk.IsExternal & 1; if (blk.MaxArea < 0) blk.MaxArea = 0; else blk.MaxArea = PI*blk.MaxArea*blk.MaxArea / 4.; blk.BlockType -= 1; blocklist.Add(blk); } q[0] = NULL; } if (_strnicmp(q, "[solution]", 10) == 0) { flag = TRUE; q[0] = NULL; } } // read in meshnodes; fscanf(fp, "%i\n", &k); meshnode.SetSize(k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%lf %lf %lf %i", &mnode.x, &mnode.y, &mnode.V, &mnode.Q); meshnode.SetAt(i, mnode); } // read in elements; fscanf(fp, "%i\n", &k); meshelem.SetSize(k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%i %i %i %i", &elm.p[0], &elm.p[1], &elm.p[2], &elm.lbl); elm.blk = blocklist[elm.lbl].BlockType; meshelem.SetAt(i, elm); } // read in circuit data; fscanf(fp, "%i\n", &k); for (i = 0; i < k; i++) { fgets(s, 1024, fp); sscanf(s, "%lf %lf", &circproplist[i].V, &circproplist[i].q); } fclose(fp); // scale depth to meters for internal computations; if (Depth == -1) Depth = 1; else Depth *= LengthConv[LengthUnits]; // element centroids and radii; for (i = 0; i < meshelem.GetSize(); i++) { meshelem[i].ctr = Ctr(i); for (j = 0, meshelem[i].rsqr = 0; j < 3; j++) { b = sqr(meshnode[meshelem[i].p[j]].x - meshelem[i].ctr.re) + sqr(meshnode[meshelem[i].p[j]].y - meshelem[i].ctr.im); if (b > meshelem[i].rsqr) meshelem[i].rsqr = b; } } // Find flux density in each element; for (i = 0; i < meshelem.GetSize(); i++) GetElementD(i); // Find extreme values of A; A_Low = meshnode[0].V; A_High = meshnode[0].V; for (i = 1; i<meshnode.GetSize(); i++) { if (meshnode[i].V>A_High) A_High = meshnode[i].V; if (meshnode[i].V < A_Low) A_Low = meshnode[i].V; } // save default values for extremes of A A_lb = A_Low; A_ub = A_High; // build list of elements connected to each node; // allocate connections list; NumList = (int *)calloc(meshnode.GetSize(), sizeof(int)); ConList = (int **)calloc(meshnode.GetSize(), sizeof(int *)); // find out number of connections to each node; for (i = 0; i < meshelem.GetSize(); i++) { for (j = 0; j < 3; j++) NumList[meshelem[i].p[j]]++; } // allocate space for connections lists; for (i = 0; i < meshnode.GetSize(); i++) ConList[i] = (int *)calloc(NumList[i], sizeof(int)); // build list; for (i = 0; i < meshnode.GetSize(); i++) NumList[i] = 0; for (i = 0; i < meshelem.GetSize(); i++) { for (j = 0; j < 3; j++) { k = meshelem[i].p[j]; ConList[k][NumList[k]] = i; NumList[k]++; } } // sort each connection list so that the elements are // arranged in a counter-clockwise order CComplex u0, u1; int swa; BOOL flg; for (i = 0; i < meshnode.GetSize(); i++) { for (j = 0; j < NumList[i]; j++) { for (k = 0, flg = FALSE; k < NumList[i] - j - 1; k++) { u0 = meshelem[ConList[i][k]].ctr - meshnode[i].CC(); u1 = meshelem[ConList[i][k + 1]].ctr - meshnode[i].CC(); if (arg(u0) > arg(u1)) { swa = ConList[i][k]; ConList[i][k] = ConList[i][k + 1]; ConList[i][k + 1] = swa; flg = TRUE; } } if (!flg) j = NumList[i]; } } // Find extreme values of potential d_PlotBounds[0][0] = A_Low; d_PlotBounds[0][1] = A_High; PlotBounds[0][0] = d_PlotBounds[0][0]; PlotBounds[0][1] = d_PlotBounds[0][1]; for (i = 0; i < meshelem.GetSize(); i++) GetNodalD(meshelem[i].d, i); // Find extreme values of D and E; i = 0; while (blocklist[meshelem[i].lbl].IsExternal) i++; d_PlotBounds[1][0] = abs(D(i)); d_PlotBounds[1][1] = d_PlotBounds[1][0]; d_PlotBounds[2][0] = abs(E(0)); d_PlotBounds[2][1] = d_PlotBounds[2][0]; for (i = 0; i < meshelem.GetSize(); i++) { if (!blocklist[meshelem[i].lbl].IsExternal) { b = abs(D(i)); if (b > d_PlotBounds[1][1]) d_PlotBounds[1][1] = b; if (b < d_PlotBounds[1][0]) d_PlotBounds[1][0] = b; b = abs(E(i)); if (b > d_PlotBounds[2][1]) d_PlotBounds[2][1] = b; if (b < d_PlotBounds[2][0]) d_PlotBounds[2][0] = b; } } PlotBounds[1][0] = d_PlotBounds[1][0]; PlotBounds[1][1] = d_PlotBounds[1][1]; PlotBounds[2][0] = d_PlotBounds[2][0]; PlotBounds[2][1] = d_PlotBounds[2][1]; // Choose bounds based on the type of contour plot // currently in play POSITION pos = GetFirstViewPosition(); CbelaviewView *theView = (CbelaviewView *)GetNextView(pos); // Build adjacency information for each element. FindBoundaryEdges(); // Check to see if any regions are multiply defined // (i.e. tagged by more than one block label). If so, // display an error message and mark the problem blocks. for (k = 0, bMultiplyDefinedLabels = FALSE; k < blocklist.GetSize(); k++) { if ((i = InTriangle(blocklist[k].x, blocklist[k].y)) >= 0) { if (meshelem[i].lbl != k) { blocklist[meshelem[i].lbl].IsSelected = TRUE; if (!bMultiplyDefinedLabels) { CString msg; msg = "Some regions in the problem have been defined\n"; msg += "by more than one block label. These potentially\n"; msg += "problematic regions will appear as selected in\n"; msg += "the initial view."; MsgBox(msg); bMultiplyDefinedLabels = TRUE; } } } } FirstDraw = TRUE; return TRUE; }