#ifdef _WIN32 #pragma warning (disable : 4786) #endif #include #include using namespace std; #include "levelcond.h" #include "level.h" #include "board.h" #include "levelfct.h" #include "gamemanager.h" LvlCond::LvlCond() { level = NULL; cond = NULL; keep_yes = false; keep_no = false; keeped = false; } LvlCond::LvlCond(QDomElement pcond, Level *l) { node_cond = pcond; level = l; QDomElement child = node_cond.firstChild().toElement(); QString str_yes, str_no; str_yes = node_cond.attribute("switch_yes", "no"); str_no = node_cond.attribute("switch_no", "no"); keep_yes = (str_yes == "yes") ? true : false; keep_no = (str_no == "yes") ? true : false; name = node_cond.attribute("name"); named = (name.isNull()) ? false : true; keeped = false; if(child.isNull()) { cout << "Error, cond element must have a child" << endl; exit(100); } QString cname = child.tagName(); if(cname == "and") { cond = new LvlCondAnd(child,level); } else if(cname == "or") { cond = new LvlCondOr(child,level); } else if(cname == "not") { cond = new LvlCondNot(child,level); } else if(cname == "true") { cond = new LvlCondTrue(child,level); } else if(cname == "false") { cond = new LvlCondFalse(child,level); } else if(cname == "onboard") { cond = new LvlTestOnboard(child,level); } else if(cname == "state") { cond = new LvlTestState(child,level); } else if(cname == "position") { cond = new LvlTestPosition(child,level); } else if(cname == "turntype") { cond = new LvlTestTurnType(child,level); } else if(cname == "inf") { cond = new LvlTestInf(child, level); } else if(cname == "sup") { cond = new LvlTestSup(child,level); } else if(cname == "equal") { cond = new LvlTestEqual(child,level); } else if(cname == "condref") { cond = new LvlCondRef(child, level); } else { cout << "Error, cond element must have a child named \"or\", " << "\"and\", \"not\" or \"test\"" << endl; exit(100); } } bool LvlCond::Eval() { if(!keeped) { value = cond->Eval(); if(keep_yes && value) { keeped = true; QDomElement current = level->xml.createElement("true"); node_cond.removeChild(node_cond.firstChild()); node_cond.appendChild(current); } else if(keep_no && !value) { keeped = true; QDomElement current = level->xml.createElement("false"); node_cond.removeChild(node_cond.firstChild()); node_cond.appendChild(current); } if(named) { level->getCond(name) = value; } } return value; } LvlCond::~LvlCond() { if(cond != NULL) { delete cond; } } LvlCondRef::LvlCondRef() { } LvlCondRef::LvlCondRef(QDomElement pcond, Level *l) { node_cond = pcond; level = l; name = node_cond.attribute("name"); } bool LvlCondRef::Eval() { return level->getCond(name); } LvlCondEval::LvlCondEval() { } LvlCondEval::LvlCondEval(QDomElement cond, Level *l) { node_cond = cond; level = l; name = node_cond.attribute("name"); QDomElement node_fct = cond.firstChild().toElement(); fct = LvlFct::Build(node_fct, l); } bool LvlCondEval::Eval() { int value = fct->Eval(); level->getValue(name) = value; return true; } LvlCondAnd::LvlCondAnd(QDomElement pcond, Level *l) { node_cond = pcond; level = l; QDomElement child = node_cond.firstChild().toElement(); QString str_all = node_cond.attribute("test_all", "no"); test_all = (str_all == "yes") ? true : false; if(!child.isNull()) { cond = new LvlCond(child, l); child = child.nextSibling().toElement(); } while(!child.isNull()) { conds.push_back(new LvlCond(child, l)); child = child.nextSibling().toElement(); } } LvlCondAnd::~LvlCondAnd() { list::iterator it; for(it = conds.begin() ; it != conds.end() ; it++) { delete *it; } } bool LvlCondAnd::Eval() { bool result = true; if(!cond->Eval()) { if(!test_all) { return false; } else { result = false; } } list::iterator it; for(it = conds.begin() ; it != conds.end() ; it++) { if(!(*it)->Eval()) { if(!test_all) { return false; } else { result = false; } } } return result; } LvlCondOr::LvlCondOr(QDomElement pcond, Level *l) { node_cond = pcond; level = l; QDomElement child = node_cond.firstChild().toElement(); QString str_all = node_cond.attribute("test_all", "no"); test_all = (str_all == "yes") ? true : false; if(!child.isNull()) { cond = new LvlCond(child, l); child = child.nextSibling().toElement(); } while(!child.isNull()) { conds.push_back(new LvlCond(child, l)); child = child.nextSibling().toElement(); } } LvlCondOr::~LvlCondOr() { list::iterator it; for(it = conds.begin() ; it != conds.end() ; it++) { delete *it; } } bool LvlCondOr::Eval() { bool result = false; if(cond->Eval()) { if(!test_all) { return true; } else { result = true; } } list::iterator it; for(it = conds.begin() ; it != conds.end() ; it++) { if((*it)->Eval()) { if(!test_all) { return true; } else { result = true; } } } return result; } LvlCondNot::LvlCondNot(QDomElement pcond, Level *l) { node_cond = pcond; level = l; QDomElement child = node_cond.firstChild().toElement(); if(!child.isNull()) { cond = new LvlCond(child, l); } } bool LvlCondNot::Eval() { return !cond->Eval(); } LvlCondTrue::LvlCondTrue(QDomElement pcond, Level *l) { node_cond = pcond; level = l; } bool LvlCondTrue::Eval() { return true; } LvlCondFalse::LvlCondFalse(QDomElement pcond, Level *l) { node_cond = pcond; level = l; } bool LvlCondFalse::Eval() { return false; } LvlTest::LvlTest() { } LvlTest::LvlTest(QDomElement pcond, Level *l) : LvlCond(pcond,l) { } bool LvlTest::Eval() { return cond->Eval(); } LvlTestOnboard::LvlTestOnboard(QDomElement pcond, Level *l) { node_cond = pcond; level = l; } bool LvlTestOnboard::Eval() { int number = 0; LevelRef *ref = NULL; QString str_min, str_max, name, str_type; str_min = node_cond.attribute("min", "1"); str_max = node_cond.attribute("max", "inf"); name = node_cond.attribute("name"); bool named = !name.isNull(); str_type = node_cond.attribute("type"); LvlObjectType wanted, type; int min, max; min = str_min.toInt(); if(str_max == "inf") { max = INT_MAX; } else { max = str_max.toInt(); } wanted = LevelObject::Name2LvlType(str_type.latin1()); Level::CreatureIterator it; if(named) { level->clearRef(name); ref = new LevelRef(wanted, name); } for(it = level->beginCreature() ; it != level->endCreature() ; it++) { type = LevelObject::Type2LvlType((*it).second->Type()); if(type & wanted) { number++; if(named) { LvlUnit *unit = LvlUnit::ConvertUnit((*it).second, level); switch(type&wanted) { case OT_FLAMER: ref->AddObject(dynamic_cast(unit)); break; case OT_TERMINATOR: ref->AddObject(dynamic_cast(unit)); break; case OT_SERGEANT: ref->AddObject(dynamic_cast(unit)); break; case OT_GENESTEALER: ref->AddObject(dynamic_cast(unit)); break; case OT_BLIP: ref->AddObject(dynamic_cast(unit)); break; default: break; } } } } if((number >= min) && (number <= max)) { if(named) { level->setRef(ref); } return true; } return false; } LvlTestState::LvlTestState(QDomElement pcond, Level *l) { node_cond = pcond; level = l; } bool LvlTestState::Eval() { QDomElement child = node_cond.firstChild().toElement(); LvlZone *zone = LvlZone::Build(child, level); set *cases = zone->getCases(); set::iterator it; QString str_state = node_cond.attribute("state"), str_entire; TestState state = TS_ONFIRE; bool entire, result, local; if (str_state == "onfire") { state = TS_ONFIRE; } else if (str_state == "blocked") { state = TS_BLOCKED; } else if (str_state == "free") { state = TS_FREE; } else if (str_state == "occupied") { state = TS_OCCUPIED; } str_entire = node_cond.attribute("entire"); entire = (str_entire == "yes") ? true : false; if(entire) { result = true; } else { result = false; } for(it = cases->begin() ; it != cases->end() ; it++) { switch(state) { case TS_ONFIRE: local = level->IsOnFire(*it); break; default: cout << "Not implemented yet" << endl; return false; } if(entire && !local) { result = false; break; } else if(!entire && local) { result = true; break; } } delete cases; if(!zone->is_ref) { delete zone; } return result; } // bool LvlTestDead::Eval() // { // int min, max, filter, number = 0, cur; // LvlObjectType wanted; // ObjectType type; // QString str_min, str_max, str_type; // str_min = node_cond.attribute("min", "1"); // str_max = node_cond.attribute("max", "inf"); // min = str_min.toInt(); // if(str_max == "inf") // { // max = INT_MAX; // } // else // { // max = str_max.toInt(); // } // str_type = node_cond.attribute("type"); // wanted = LevelObject::Name2LvlType(str_type.latin1()); // for(filter = 1 ; filter < (1 << NbLvlObjectType) ; filter <<= 1) // { // cur = wanted & filter; // type = LevelObject::LvlType2Type((LvlObjectType)cur); // if(type != NB_OBJECT_TYPE) // { // number += level->getNbKilled(type); // } // } // if((number >= min) && (number <= max)) // { // return true; // } // return false; // } LvlTestPosition::LvlTestPosition(QDomElement pcond, Level *l) { node_cond = pcond; level = l; QDomElement child = node_cond.firstChild().toElement(); if(child.isNull()) { cout << "Error, position element must have a child named \"zone\"" << endl; exit(100); } zone = LvlZone::Build(child, level); QString str_type = node_cond.attribute("type"); lvl_type = LevelObject::Name2LvlType(str_type.latin1()); QString str_dir = node_cond.attribute("dir1","none"); dir1 = string2dir(str_dir); str_dir = node_cond.attribute("dir2","none"); dir2 = string2dir(str_dir); str_dir = node_cond.attribute("dir3","none"); dir3 = string2dir(str_dir); name = node_cond.attribute("name"); named = (name.isNull()) ? false : true; } bool LvlTestPosition::Eval() { bool result = false; LevelRef *ref = NULL; set *poss = zone->getCases(); set::iterator it; set::iterator it_obj; LvlObjectType cur; if(named) { ref = new LevelRef(lvl_type, name); } for(it = poss->begin() ; it != poss->end() ; it++) { set *obj=board->getObject(*it); for(it_obj = obj->begin() ; it_obj != obj->end() ; it_obj++) { cur = LevelObject::Type2LvlType((*it_obj)->Type()); if(cur & lvl_type) { Direction dir = (*it_obj)->getOrientation(); if (dir==dir1 || dir==dir2 || dir==dir3 || (dir1==NODIRECTION && dir2==NODIRECTION && dir3==NODIRECTION)) { result = true; if(named) { LvlUnit *unit = LvlUnit::ConvertUnit(*it_obj, level); switch(cur) { case OT_FLAMER: ref->AddObject(dynamic_cast(unit)); break; case OT_TERMINATOR: ref->AddObject(dynamic_cast(unit)); break; case OT_SERGEANT: ref->AddObject(dynamic_cast(unit)); break; case OT_GENESTEALER: ref->AddObject(dynamic_cast(unit)); break; case OT_BLIP: ref->AddObject(dynamic_cast(unit)); break; case OT_DOOR: { LvlDoor *door; door = LvlDoor::Build(dynamic_cast(*it_obj), level); ref->AddObject(door); } break; case OT_BULKHEAD: default: break; } } else { delete poss; return true; } } } } } if(named) { level->setRef(ref); } delete poss; return result; } // LvlTestAP::LvlTestAP(QDomElement pcond, Level *l) // { // node_cond = pcond; // level = l; // QDomElement child = node_cond.firstChild().toElement(); // if(child.isNull()) // { // cout << "Error, position element must have a child named \"zone\"" << endl; // exit(100); // } // ref_name = child.attribute("name"); // QString str_min, str_max, str_need_all; // str_min = node_cond.attribute("min","0"); // str_max = node_cond.attribute("max","inf"); // str_need_all = node_cond.attribute("need_all", "no"); // min = str_min.toInt(); // if(str_max == "inf") // { // max = INT_MAX; // } // else // { // max = str_max.toInt(); // } // need_all = (str_need_all == "yes") ? true : false; // } // bool LvlTestAP::Eval() // { // int AP; // bool result = false; // LevelRef* ref = level->getRef(ref_name); // LevelRef::iterator it; // cout << "TestAP : min = " << min << " max = " << max << " name = " << ref_name << endl; // if(ref != NULL) // { // cout << "\tref not NULL" << endl; // cout << "\tref size : " << ref->size() << endl; // for(it = ref->begin() ; it != ref->end() ; it++) // { // cout << "\ttesting object adress : " << *it << endl; // LvlUnit *unit = dynamic_cast(*it); // if(unit != NULL) // { // AP = unit->getActPts(); // cout << "\tFound unit with AP : " << AP << endl; // if((AP >= min) && (AP <= max)) // { // result = true; // if(!need_all) // { // break; // } // } // else if(need_all) // { // result = false; // break; // } // } // } // } // cout << "\tresult = " << ((result)?"true":"false") << endl; // return result; // } // bool LvlTestLeaved::Eval() // { // int number=0; // for(int filter = 1 ; filter < (1 << NbLvlObjectType) ; filter <<= 1) // { // int cur = lvltype & filter; // type = LevelObject::LvlType2Type((LvlObjectType)cur); // if(type != NB_OBJECT_TYPE) // { // const list* lst = man->getExitedUnits(type); // if (lst != NULL) // number += lst->size(); // } // } // if((number >= min) && (number <= max)) // return true; // return false; // } LvlTestInf::LvlTestInf(QDomElement cond, Level *l) { level = l; node_cond = cond; QDomElement f,s; f = cond.firstChild().toElement(); s = f.nextSibling().toElement(); first = LvlFct::Build(f,l); second = LvlFct::Build(s,l); } bool LvlTestInf::Eval() { int f,s; f = first->Eval(); s = second->Eval(); return f <= s; } LvlTestSup::LvlTestSup(QDomElement cond, Level *l) { level = l; node_cond = cond; QDomElement f,s; f = cond.firstChild().toElement(); s = f.nextSibling().toElement(); first = LvlFct::Build(f,l); second = LvlFct::Build(s,l); } bool LvlTestSup::Eval() { int f,s; f = first->Eval(); s = second->Eval(); return f >= s; } LvlTestEqual::LvlTestEqual(QDomElement cond, Level *l) { level = l; node_cond = cond; QDomElement f,s; f = cond.firstChild().toElement(); s = f.nextSibling().toElement(); first = LvlFct::Build(f,l); second = LvlFct::Build(s,l); } bool LvlTestEqual::Eval() { int f,s; f = first->Eval(); s = second->Eval(); return f == s; } LvlTestTurnType::LvlTestTurnType(QDomElement cond, Level *l) { level = l; node_cond = cond; QString typestring = cond.attribute("type"); if (typestring=="marine") type=MARINE_TURN; else if (typestring=="genestealer") type=GENESTEALER_TURN; else if (typestring=="cat") type=CAT_TURN; else { cout << "Error during level loading. Found an unknow attribute \" " << typestring.latin1() << "\"."; exit(0); } } bool LvlTestTurnType::Eval() { return (man->getTurn()==type); }