morph with blocking places works now. I still want to cleanup this after some discussion with softcoder ( some things marked with TT )

This commit is contained in:
Titus Tscharntke 2012-09-13 21:50:07 +00:00
parent 5373c9cf6b
commit ed91a7c59b
3 changed files with 83 additions and 49 deletions

View File

@ -2702,8 +2702,9 @@ bool Unit::morph(const MorphCommandType *mct){
Field morphUnitField=fLand; Field morphUnitField=fLand;
if(morphUnitType->getField(fAir)) morphUnitField=fAir; if(morphUnitType->getField(fAir)) morphUnitField=fAir;
if(morphUnitType->getField(fLand)) morphUnitField=fLand; if(morphUnitType->getField(fLand)) morphUnitField=fLand;
map->clearUnitCells(this, pos, false);
if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this,morphUnitType)) { if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this,morphUnitType)) {
map->clearUnitCells(this, pos); map->clearUnitCells(this, pos, true);
faction->deApplyStaticCosts(type,mct); faction->deApplyStaticCosts(type,mct);
checkItemInVault(&this->hp,this->hp); checkItemInVault(&this->hp,this->hp);

View File

@ -837,32 +837,11 @@ bool Map::isFreeCell(const Vec2i &pos, Field field) const {
(field!=fLand || getDeepSubmerged(getCell(pos)) == false); (field!=fLand || getDeepSubmerged(getCell(pos)) == false);
} }
bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const {
if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const{
if(unit->getCurrField() != field) { if(isInside(pos)){
return isFreeCell(pos, field);
}
Cell *c= getCell(pos); Cell *c= getCell(pos);
if(c->getUnit(unit->getCurrField()) == unit) { if(c->getUnit(field)==unit){
if(unit->getCurrField() == fAir) {
if(field == fAir) {
return true;
}
const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos));
if(sc != NULL) {
if(getDeepSubmerged(sc) == true) {
return false;
}
else if(field == fLand) {
if(sc->isFree() == false) {
return false;
}
else if(c->getUnit(field) != NULL) {
return false;
}
}
}
}
return true; return true;
} }
else{ else{
@ -872,6 +851,42 @@ bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) c
return false; return false;
} }
//TT: this is much more complicated compared with the old one above. I think its no more needed
//bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const {
// if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) {
// if(unit->getCurrField() != field) {
// return isFreeCell(pos, field);
// }
// Cell *c= getCell(pos);
// if(c->getUnit(unit->getCurrField()) == unit) {
// if(unit->getCurrField() == fAir) {
// if(field == fAir) {
// return true;
// }
// const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos));
// if(sc != NULL) {
// if(getDeepSubmerged(sc) == true) {
// return false;
// }
// else if(field == fLand) {
// if(sc->isFree() == false) {
// return false;
// }
// else if(c->getUnit(field) != NULL) {
// return false;
// }
// }
// }
// }
// return true;
// }
// else{
// return isFreeCell(pos, field);
// }
// }
// return false;
//}
bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const { bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const {
if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) {
const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos));
@ -1382,7 +1397,7 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
} }
} }
} }
Field field=ut->getField();
for(int i = 0; i < ut->getSize(); ++i) { for(int i = 0; i < ut->getSize(); ++i) {
for(int j = 0; j < ut->getSize(); ++j) { for(int j = 0; j < ut->getSize(); ++j) {
Vec2i currPos= pos + Vec2i(i, j); Vec2i currPos= pos + Vec2i(i, j);
@ -1392,9 +1407,10 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
} }
if( ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) { if( ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) {
if(getCell(currPos)->getUnit(unit->getCurrField()) != NULL && if(getCell(currPos)->getUnit(field) != NULL &&
getCell(currPos)->getUnit(unit->getCurrField()) != unit) { getCell(currPos)->getUnit(field) != unit) {
// TT: is this ok ?
// If unit tries to move into a cell where another unit resides // If unit tries to move into a cell where another unit resides
// cancel the move command // cancel the move command
if(unit->getCurrSkill() != NULL && if(unit->getCurrSkill() != NULL &&
@ -1409,22 +1425,36 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
// unit->toString().c_str(), // unit->toString().c_str(),
// getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); // getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str());
} }
// If the unit trying to move into the cell is not in the moving state //TT: Nonsens?
// it is likely being created or morphed so we will will log the error // else {
else { // // If the unit trying to move into the cell is not in the moving state
canPutInCell = false; // // it is likely being created or morphed so we will will log the error
// throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != NULL"); // canPutInCell = false;
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n", // // throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != NULL");
__FILE__,__FUNCTION__,__LINE__, // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n",
currPos.getString().c_str(), // __FILE__,__FUNCTION__,__LINE__,
unit->toString().c_str(), // currPos.getString().c_str(),
getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); // unit->toString().c_str(),
} // getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str());
// }
}
if(getCell(currPos)->getUnit(field) == NULL ||
getCell(currPos)->getUnit(field) == unit) {
if(unit->getCurrSkill() != NULL &&
unit->getCurrSkill()->getClass() == scMorph &&
unit->getType()->getName(false)!=ut->getName(false)){
// unit is beeing morphed to another unit with maybe other field.
getCell(currPos)->setUnit(field, unit);
canPutInCell = false;
}
if(canPutInCell == true) {
getCell(currPos)->setUnit(unit->getCurrField(), unit);
}
}
else {
throw megaglest_runtime_error("trying to move into occupied cell and field");
} }
if(canPutInCell == true) {
getCell(currPos)->setUnit(unit->getCurrField(), unit);
}
} }
else if(ut->hasCellMap() == true && else if(ut->hasCellMap() == true &&
ut->getAllowEmptyCellMap() == true && ut->getAllowEmptyCellMap() == true &&
@ -1444,20 +1474,23 @@ void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
} }
//removes a unit from cells //removes a unit from cells
void Map::clearUnitCells(Unit *unit, const Vec2i &pos) { void Map::clearUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) {
assert(unit != NULL); assert(unit != NULL);
if(unit == NULL) { if(unit == NULL) {
throw megaglest_runtime_error("unit == NULL"); throw megaglest_runtime_error("unit == NULL");
} }
const UnitType *ut= unit->getType(); const UnitType *ut= unit->getType();
bool currentField=unit->getCurrField();
if(unit->getCurrSkill() != NULL && if(ignoreSkill==false &&
unit->getCurrSkill() != NULL &&
unit->getCurrSkill()->getClass() == scMorph) { unit->getCurrSkill()->getClass() == scMorph) {
Command *command= unit->getCurrCommand(); Command *command= unit->getCurrCommand();
const MorphCommandType *mct= static_cast<const MorphCommandType*>(command->getCommandType()); const MorphCommandType *mct= static_cast<const MorphCommandType*>(command->getCommandType());
if(unit->getType()->getSize()<=mct->getMorphUnit()->getSize()){ if(unit->getType()->getSize()<=mct->getMorphUnit()->getSize()){
ut=mct->getMorphUnit(); ut=mct->getMorphUnit();
currentField=ut->getField();
} }
} }
@ -1485,14 +1518,14 @@ void Map::clearUnitCells(Unit *unit, const Vec2i &pos) {
//} //}
// Only clear the cell if its the unit we expect to clear out of it // Only clear the cell if its the unit we expect to clear out of it
if(getCell(currPos)->getUnit(unit->getCurrField()) == unit) { if(getCell(currPos)->getUnit(currentField) == unit) {
getCell(currPos)->setUnit(unit->getCurrField(), NULL); getCell(currPos)->setUnit(currentField, NULL);
} }
} }
else if(ut->hasCellMap() == true && else if(ut->hasCellMap() == true &&
ut->getAllowEmptyCellMap() == true && ut->getAllowEmptyCellMap() == true &&
ut->hasEmptyCellMap() == true) { ut->hasEmptyCellMap() == true) {
getCell(currPos)->setUnitWithEmptyCellMap(unit->getCurrField(), NULL); getCell(currPos)->setUnitWithEmptyCellMap(currentField, NULL);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n", //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n",
// __FILE__,__FUNCTION__,__LINE__, // __FILE__,__FUNCTION__,__LINE__,

View File

@ -397,7 +397,7 @@ public:
bool aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<int, std::map<Field,bool> > > > > *lookupCache=NULL) const; bool aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<int, std::map<Field,bool> > > > > *lookupCache=NULL) const;
bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2,std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<Field,bool> > > > *lookupCache=NULL) const; bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2,std::map<Vec2i, std::map<Vec2i, std::map<int, std::map<Field,bool> > > > *lookupCache=NULL) const;
void putUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false); void putUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false);
void clearUnitCells(Unit *unit, const Vec2i &pos); void clearUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false);
Vec2i computeRefPos(const Selection *selection) const; Vec2i computeRefPos(const Selection *selection) const;
Vec2i computeDestPos( const Vec2i &refUnitPos, const Vec2i &unitPos, Vec2i computeDestPos( const Vec2i &refUnitPos, const Vec2i &unitPos,