handle separately water and ground

The forbidden zones must be set in the primitives, in the fauna name = "Ybers:Ground|NoGo"
This commit is contained in:
depyraken 2016-03-30 02:56:09 +02:00
parent 7517200cc7
commit 42aeac0243
8 changed files with 154 additions and 76 deletions

View file

@ -501,7 +501,7 @@ void CSpawnBotFauna::getBestTarget()
if ( canMove() if ( canMove()
&& !player->isAggressive() && !player->isAggressive()
&& entity->wpos().isValid() && entity->wpos().isValid()
&& (entity->wpos().getFlags()&entity->getAStarFlag())==0) && isPlaceAllowed(entity->getAStarFlag(), entity->wpos().getFlags()))
{ {
// Suppose we can go to him // Suppose we can go to him
bool canChange = true; bool canChange = true;
@ -706,7 +706,7 @@ void CSpawnBotFauna::getBestTarget()
if ( profile if ( profile
&& profile->getAIProfileType()==ACTIVITY_CORPSE && profile->getAIProfileType()==ACTIVITY_CORPSE
&& botCreat->wpos().isValid() && botCreat->wpos().isValid()
&& !(botCreat->wpos().getFlags()&botCreat->getAStarFlag()) && isPlaceAllowed(botCreat->getAStarFlag(), botCreat->wpos().getFlags())
) )
{ {
CCorpseFaunaProfile *corpseProfile=NLMISC::safe_cast<CCorpseFaunaProfile*>(profile); CCorpseFaunaProfile *corpseProfile=NLMISC::safe_cast<CCorpseFaunaProfile*>(profile);
@ -951,7 +951,7 @@ void CMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& a
continue; continue;
if ( !faunaBot->wpos().isValid() if ( !faunaBot->wpos().isValid()
|| (faunaBot->wpos().getFlags()&denyFlag)!=0) || !isPlaceAllowed(denyFlag, faunaBot->wpos().getFlags()))
continue; continue;
// can be optimize by in avoid inversion. // can be optimize by in avoid inversion.
@ -990,7 +990,7 @@ void CMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& a
// check if its a nogo and water proof position. // check if its a nogo and water proof position.
if ( !wRndPos.isValid() if ( !wRndPos.isValid()
|| (wRndPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)!=0 ) || !isPlaceAllowed(denyFlag, wRndPos.getTopologyRef().getCstTopologyNode().getFlags()))
continue; continue;
#if !FINAL_VERSION #if !FINAL_VERSION
@ -1126,7 +1126,7 @@ CReturnMovementMagnet::CReturnMovementMagnet(RYAI_MAP_CRUNCH::CWorldPosition con
void CReturnMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag) void CReturnMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag)
{ {
if (_ForcedDest.isValid() && (_ForcedDest.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)==0) if (_ForcedDest.isValid() && isPlaceAllowed(denyFlag, _ForcedDest.getTopologyRef().getCstTopologyNode().getFlags()))
_PathCont.setDestination(_ForcedDest); _PathCont.setDestination(_ForcedDest);
else else
CMovementMagnet::getNewDestination(alternativePos, denyFlag); CMovementMagnet::getNewDestination(alternativePos, denyFlag);

View file

@ -309,7 +309,7 @@ void CBotProfileFlee::updateProfile(uint ticksSinceLastUpdate)
{ {
RYAI_MAP_CRUNCH::CWorldPosition wpos=rootCell->getWorldPosition(_Bot->getPersistent().getChildIndex()&3); RYAI_MAP_CRUNCH::CWorldPosition wpos=rootCell->getWorldPosition(_Bot->getPersistent().getChildIndex()&3);
if ( wpos.isValid() if ( wpos.isValid()
&& (wpos.getFlags()&_DenyFlags)==0 ) // verify that we got some compatible flags .. && isPlaceAllowed(_DenyFlags, wpos.getFlags())) // verify that we got some compatible flags ..
{ {
_LastDir=startDir; _LastDir=startDir;
_LastStartPos=_Bot->wpos(); _LastStartPos=_Bot->wpos();

View file

@ -374,7 +374,7 @@ bool s_move(
0.5f); 0.5f);
// If we can't follow the path or the computed pos is invalid // If we can't follow the path or the computed pos is invalid
if ( status==CFollowPath::FOLLOW_NO_PATH if ( status==CFollowPath::FOLLOW_NO_PATH
|| (_Bot->wpos().isValid() && (_Bot->wpos().getFlags()&_Bot->getAStarFlag())!=0)) || (_Bot->wpos().isValid() && !isPlaceAllowed(_Bot->getAStarFlag(), _Bot->wpos().getFlags())))
{ {
// Restore position // Restore position
_Bot->setPos(lastPos); _Bot->setPos(lastPos);
@ -605,7 +605,7 @@ static void s_updateProfile(
_AtAttackDist = norm < _RangeMax; _AtAttackDist = norm < _RangeMax;
// Check if target can be attacked // Check if target can be attacked
bool const targetInForbiddenZone = ((!target->wpos().isValid())||(target->wpos().getFlags()&_Bot->getAStarFlag())!=0); bool const targetInForbiddenZone = ((!target->wpos().isValid())||!isPlaceAllowed(_Bot->getAStarFlag(), target->wpos().getFlags()));
/****************************************************************************/ /****************************************************************************/
/* Profile main processing */ /* Profile main processing */

View file

@ -836,7 +836,7 @@ bool CGrpFauna::spawnPop(uint popVersion)
if (!places()[i]->worldValidPos().isValid()) if (!places()[i]->worldValidPos().isValid())
return false; return false;
const RYAI_MAP_CRUNCH::TAStarFlag flags=places()[i]->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); const RYAI_MAP_CRUNCH::TAStarFlag flags=places()[i]->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags();
if ((flags&getAStarFlag())!=0) if(!isPlaceAllowed(getAStarFlag(), flags)) // if place is not allowed - we now deal with creatures that can't go on the ground
return false; return false;
} }

View file

@ -97,12 +97,37 @@ IAliasCont* CMgrFauna::getAliasCont(TAIType type)
CAliasTreeOwner* CMgrFauna::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) CAliasTreeOwner* CMgrFauna::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree)
{ {
RYAI_MAP_CRUNCH::TAStarFlag flags = RYAI_MAP_CRUNCH::Nothing;
// this hack is to retrieve the AStar flags from the fauna group. We expect the groupname to be as follows : groupname:AStarFlag[|AStarFlag]
std::string key, tail;
std::string p = NLMISC::toLower(this->getAliasFullName()); // force lowercase
AI_SHARE::stringToKeywordAndTail(p, key, tail);
int bAstarFlags = 0;
if (!tail.empty()){ //AStarFlags were provided
bAstarFlags = 1;
vector<string> sFlags;
NLMISC::splitString(tail, "|", sFlags);
FOREACHC(it, vector<string>, sFlags){
TAStarFlag tmpflag = RYAI_MAP_CRUNCH::toAStarFlag(*it);
if( (tmpflag == TAStarFlag::Nothing) &&
it->compare("nothing")){ // this is not a valid AStarFlags => Let's preserve the default way the fauna is handled
bAstarFlags = 0;
break;
}
flags = RYAI_MAP_CRUNCH::TAStarFlag( flags | tmpflag);
}
}
if(!bAstarFlags){
flags = WaterAndNogo;
}
CAliasTreeOwner* child = NULL; CAliasTreeOwner* child = NULL;
switch (aliasTree->getType()) switch (aliasTree->getType())
{ {
case AITypeGrp: case AITypeGrp:
child = new CGrpFauna(this, aliasTree, WaterAndNogo); child = new CGrpFauna(this, aliasTree, flags);
break; break;
case AITypeEvent: case AITypeEvent:
child = new CAIEventReaction(getStateMachine(), aliasTree); child = new CAIEventReaction(getStateMachine(), aliasTree);

View file

@ -1530,7 +1530,10 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro
CPropertySet activities[CCellChoice::MAX_ZONE_SCORE]; CPropertySet activities[CCellChoice::MAX_ZONE_SCORE];
activities[CCellChoice::FOOD_ZONE_SCORE].merge(foodActivity); activities[CCellChoice::FOOD_ZONE_SCORE].merge(foodActivity);
activities[CCellChoice::REST_ZONE_SCORE].merge(restActivity); activities[CCellChoice::REST_ZONE_SCORE].merge(restActivity);
CPossibleTAStarFlags PossibleTAStarFlags; // possible TAStarFlags
const int nFlags = PossibleTAStarFlags.buildTAStarFlagsList(denyflags); // we build the list according to the deny flags
// Look for a conveninent zone in a convenient cell. // Look for a conveninent zone in a convenient cell.
if (extensiveDebug) nldebug("ED0001.02: cells.size()=%d", cells.size()); if (extensiveDebug) nldebug("ED0001.02: cells.size()=%d", cells.size());
// For each cell // For each cell
@ -1586,22 +1589,15 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro
continue; continue;
} }
TAStarFlag const flags = (TAStarFlag)(wpos.getFlags()&GroundFlags); // Erase unused flags.
float const score = faunaZone->getFreeAreaScore(); float const score = faunaZone->getFreeAreaScore();
for (TAStarFlag possibleFlag=Nothing;possibleFlag<=GroundFlags;possibleFlag=(TAStarFlag)(possibleFlag+2)) // tricky !! -> to replace with a defined list of flags to checks. for(int i = 0;i < nFlags;i++){
{ TAStarFlag possibleFlag = PossibleTAStarFlags.get(i);
const uint32 incompatibilityFlags=possibleFlag&denyflags&GroundFlags; // Erase unused flags.
if (incompatibilityFlags)
{
if (extensiveDebug) nldebug("ED0001.06: incompatibilityFlags");
continue;
}
const uint32 masterTopo=wpos.getTopologyRef().getCstTopologyNode().getMasterTopo(possibleFlag); const uint32 masterTopo=wpos.getTopologyRef().getCstTopologyNode().getMasterTopo(possibleFlag);
if (masterTopo==~0) if(masterTopo==CTopology::TTopologyId::UNDEFINED_TOPOLOGY)
{ {
if (extensiveDebug) nldebug("ED0001.07: masterTopo==~0"); if (extensiveDebug) nldebug("ED0001.07: CTopology::TTopologyId::UNDEFINED_TOPOLOGY");
continue; continue;
} }
@ -1611,7 +1607,7 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro
continue; continue;
} }
CCellChoice::CZoneScore &zoneScore=searchMap[possibleFlag][masterTopo].zones[typeZone]; CCellChoice::CZoneScore &zoneScore=searchMap[possibleFlag & WaterAndNogo][masterTopo].zones[typeZone];
if (score<zoneScore.score) if (score<zoneScore.score)
{ {
@ -1662,8 +1658,8 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro
#if !FINAL_VERSION #if !FINAL_VERSION
const RYAI_MAP_CRUNCH::TAStarFlag restFlags=rest->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); const RYAI_MAP_CRUNCH::TAStarFlag restFlags=rest->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags();
const RYAI_MAP_CRUNCH::TAStarFlag foodFlags=food->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); const RYAI_MAP_CRUNCH::TAStarFlag foodFlags=food->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags();
nlassert((restFlags&denyflags)==0); nlassert(isPlaceAllowed(denyflags, restFlags));
nlassert((foodFlags&denyflags)==0); nlassert(isPlaceAllowed(denyflags, foodFlags));
#endif #endif
return true; return true;
} }
@ -1740,7 +1736,7 @@ const CFaunaZone *CCellZone::lookupFaunaZone(const CPropertySet &activity, TASta
} }
const RYAI_MAP_CRUNCH::TAStarFlag flags=faunaZone->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); const RYAI_MAP_CRUNCH::TAStarFlag flags=faunaZone->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags();
if (flags&denyflags) if (!isPlaceAllowed(denyflags, flags))
continue; continue;
const float score=faunaZone->getFreeAreaScore(); const float score=faunaZone->getFreeAreaScore();

View file

@ -34,6 +34,9 @@ NL_BEGIN_STRING_CONVERSION_TABLE (TAStarFlag)
NL_STRING_CONVERSION_TABLE_ENTRY(NoGo) NL_STRING_CONVERSION_TABLE_ENTRY(NoGo)
NL_STRING_CONVERSION_TABLE_ENTRY(WaterAndNogo) NL_STRING_CONVERSION_TABLE_ENTRY(WaterAndNogo)
NL_STRING_CONVERSION_TABLE_ENTRY(GroundFlags) NL_STRING_CONVERSION_TABLE_ENTRY(GroundFlags)
NL_STRING_CONVERSION_TABLE_ENTRY(Ground)
NL_STRING_CONVERSION_TABLE_ENTRY(GroundAndNogo)
NL_STRING_CONVERSION_TABLE_ENTRY(GroundAndWaterAndNogo)
NL_END_STRING_CONVERSION_TABLE(TAStarFlag, AStarFlagConversion, Nothing) NL_END_STRING_CONVERSION_TABLE(TAStarFlag, AStarFlagConversion, Nothing)
const std::string& toString(TAStarFlag flag) const std::string& toString(TAStarFlag flag)
@ -781,14 +784,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosS(); tmpPos=tmpPos.getPosS();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isESlotValid()) if (!tmpPos.getCellLinkage().isESlotValid())
return false; return false;
tmpPos=tmpPos.getPosE(); tmpPos=tmpPos.getPosE();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
} }
@ -798,7 +801,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosE(); tmpPos=tmpPos.getPosE();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isSSlotValid()) if (!tmpPos.getCellLinkage().isSSlotValid())
@ -819,14 +822,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosN(); tmpPos=tmpPos.getPosN();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isESlotValid()) if (!tmpPos.getCellLinkage().isESlotValid())
return false; return false;
tmpPos=tmpPos.getPosE(); tmpPos=tmpPos.getPosE();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
} }
@ -836,7 +839,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosE(); tmpPos=tmpPos.getPosE();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isNSlotValid()) if (!tmpPos.getCellLinkage().isNSlotValid())
@ -856,14 +859,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosN(); tmpPos=tmpPos.getPosN();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isWSlotValid()) if (!tmpPos.getCellLinkage().isWSlotValid())
return false; return false;
tmpPos=tmpPos.getPosW(); tmpPos=tmpPos.getPosW();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
} }
@ -873,7 +876,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosW(); tmpPos=tmpPos.getPosW();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isNSlotValid()) if (!tmpPos.getCellLinkage().isNSlotValid())
@ -893,14 +896,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosS(); tmpPos=tmpPos.getPosS();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isWSlotValid()) if (!tmpPos.getCellLinkage().isWSlotValid())
return false; return false;
tmpPos=tmpPos.getPosW(); tmpPos=tmpPos.getPosW();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
} }
@ -910,7 +913,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
return false; return false;
tmpPos=tmpPos.getPosW(); tmpPos=tmpPos.getPosW();
if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags()))
return false; return false;
if (!tmpPos.getCellLinkage().isSSlotValid()) if (!tmpPos.getCellLinkage().isSSlotValid())
@ -1348,29 +1351,21 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi
const CTopology &startTopoNode=startPos.getTopologyRef().getCstTopologyNode(); const CTopology &startTopoNode=startPos.getTopologyRef().getCstTopologyNode();
const CTopology &endTopoNode=endPos.getTopologyRef().getCstTopologyNode(); const CTopology &endTopoNode=endPos.getTopologyRef().getCstTopologyNode();
TAStarFlag startFlag=(TAStarFlag)(startTopoNode.getFlags()&WaterAndNogo);
// if (!allowStartRestriction)
startFlag=Nothing;
CPossibleTAStarFlags PossibleTAStarFlags; // build a list of possible flags given the denyflags
const int nFlags = PossibleTAStarFlags.buildTAStarFlagsList(denyflags);
for (TAStarFlag possibleFlag=Nothing;possibleFlag<=WaterAndNogo;possibleFlag=(TAStarFlag)(possibleFlag+2)) // tricky !! -> to replace with a defined list of flags to checks. for(int i = 0;i < nFlags;i++){ // for each possible flag
{ TAStarFlag possibleFlag = PossibleTAStarFlags.get(i);
const uint32 incompatibilityFlags=(possibleFlag&(denyflags&~startFlag))&WaterAndNogo; uint32 startMasterTopo=startTopoNode.getMasterTopo(possibleFlag);
uint32 endMasterTopo=endTopoNode.getMasterTopo(possibleFlag);
if (incompatibilityFlags) if( (startMasterTopo^endMasterTopo)!=0 ||
continue; (startMasterTopo == CTopology::TTopologyId::UNDEFINED_TOPOLOGY)){ // if not same masterTopo or invalid masterTopo then continue
continue;
const uint32 startMasterTopo=startTopoNode.getMasterTopo(possibleFlag); }
const uint32 endMasterTopo=endTopoNode.getMasterTopo(possibleFlag); res.set(possibleFlag, startMasterTopo);
if ( (startMasterTopo^endMasterTopo)!=0 res.setValid();
|| startMasterTopo == std::numeric_limits<uint32>::max()) // if not same masterTopo or invalid masterTopo then bypass .. break;
continue;
res.set(possibleFlag, startMasterTopo);
res.setValid();
if (((possibleFlag&denyflags)&WaterAndNogo)==0) // it was the optimal case ?
break;
} }
} }
@ -1665,7 +1660,7 @@ bool CWorldMap::findAStarPath(const CTopology::TTopologyId &start, const CTopolo
const CTopology &ntp = next.getCstTopologyNode(); const CTopology &ntp = next.getCstTopologyNode();
// don't examine not accessible nodes // don't examine not accessible nodes
if ((ntp.Flags & denyflags) != 0) if (!isPlaceAllowed(denyflags,(RYAI_MAP_CRUNCH::TAStarFlag) ntp.Flags))
continue; continue;
// compute actual node distance // compute actual node distance
@ -1821,7 +1816,7 @@ bool CWorldMap::findInsideAStarPath(CWorldPosition const& start, CWorldPosition
continue; continue;
// If that point's flags are not compatible skip it // If that point's flags are not compatible skip it
if ((denyflags & mv.getTopologyRef().getCstTopologyNode().getFlags()) != 0) if (!isPlaceAllowed(denyflags, mv.getTopologyRef().getCstTopologyNode().getFlags()))
continue; continue;
// Build an A* node // Build an A* node
@ -1927,7 +1922,7 @@ bool CWorldMap::move(CWorldPosition &pos, CAStarPath &path, uint &currentstep) c
bool CWorldMap::move(CWorldPosition& pos, CMapPosition const& end, TAStarFlag const denyFlags) const bool CWorldMap::move(CWorldPosition& pos, CMapPosition const& end, TAStarFlag const denyFlags) const
{ {
CWorldPosition tempPos(pos); CWorldPosition tempPos(pos);
BOMB_IF((tempPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0, "Error in CWorldMap::mode, invalid flag "<<RYAI_MAP_CRUNCH::toString(tempPos.getTopologyRef().getCstTopologyNode().getFlags()) BOMB_IF(!isPlaceAllowed(denyFlags, tempPos.getTopologyRef().getCstTopologyNode().getFlags()), "Error in CWorldMap::mode, invalid flag "<<RYAI_MAP_CRUNCH::toString(tempPos.getTopologyRef().getCstTopologyNode().getFlags())
<<"on world pos "<<pos.toString()<<" while going to map pos "<<end.toString()<<" with denyflags "<<RYAI_MAP_CRUNCH::toString(denyFlags), return false); <<"on world pos "<<pos.toString()<<" while going to map pos "<<end.toString()<<" with denyflags "<<RYAI_MAP_CRUNCH::toString(denyFlags), return false);
// not optimum but it will be rewrite for each specialized rootcell type. // not optimum but it will be rewrite for each specialized rootcell type.
const sint32 x0 = pos.x(); const sint32 x0 = pos.x();
@ -1945,7 +1940,7 @@ bool CWorldMap::move(CWorldPosition& pos, CMapPosition const& end, TAStarFlag co
if ( !move(tempPos, CDirection(dx,dy)) if ( !move(tempPos, CDirection(dx,dy))
|| (tempPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) // Arghh !! || !isPlaceAllowed(denyFlags, tempPos.getTopologyRef().getCstTopologyNode().getFlags())) // Arghh !!
return false; return false;
pos=tempPos; pos=tempPos;
} }

View file

@ -52,18 +52,74 @@ enum TAStarFlag
Water = 2, Water = 2,
NoGo = 4, NoGo = 4,
WaterAndNogo = 6, WaterAndNogo = 6,
GroundFlags = WaterAndNogo GroundFlags = WaterAndNogo,
Ground = 8,
GroundAndNogo = 12,
GroundAndWaterAndNogo = 14
}; };
const std::string& toString(TAStarFlag flag); const std::string& toString(TAStarFlag flag);
TAStarFlag toAStarFlag(const std::string& str); TAStarFlag toAStarFlag(const std::string& str);
inline int isPlaceAllowed(TAStarFlag denyFlags, TAStarFlag flags){ // check if the place is allowed given the denyFlags and flags
if(denyFlags & Ground){ // in case of ground is denied
return ((flags & denyFlags) == 0) && // denied flags against the current flags
(flags & Water); // check the current flag is in the water
} else {
return (flags & denyFlags) == 0; // denied flags against the current flags
}
}
uint const WorldMapGridSize = 256; uint const WorldMapGridSize = 256;
double const WorldGridResolution = 1.; double const WorldGridResolution = 1.;
NLMISC::CVectorD const WorldStartOffset = NLMISC::CVectorD(0., 0., 0.); NLMISC::CVectorD const WorldStartOffset = NLMISC::CVectorD(0., 0., 0.);
typedef sint TLevel; typedef sint TLevel;
class CPossibleTAStarFlags { // class to create a list of possible TAStarFlags
private:
uint8 nFlags;
uint8 aFlags[3];
public:
CPossibleTAStarFlags() : nFlags(0){ // default constructor
}
int buildTAStarFlagsList(const TAStarFlag denyflags){
nFlags = 0;
if(denyflags & Ground){ // ground forbidden
if(!(denyflags & Water)){ // Water possible
aFlags[nFlags++] = (uint8)(Water | Ground);
if(!(denyflags & NoGo)){ // Water and NoGo possible
aFlags[nFlags++] = (uint8)(Water | NoGo | Ground);
}
}
} else { // ground possible
aFlags[nFlags++] = (uint8)(Nothing);
if(!(denyflags & Water)){ // Ground and Water possible
aFlags[nFlags++] = (uint8)(Water);
if(!(denyflags & NoGo)){ // Ground, Water and NoGo possible
aFlags[nFlags++] = (uint8)(Water | NoGo);
}
} else {
if(!(denyflags & NoGo)){ // Ground and NoGo possible
aFlags[nFlags++] = (uint8)(NoGo);
}
}
}
return nFlags;
}
int size(){ // returns the size of the list of possible TAStarFlags
return nFlags;
}
TAStarFlag get(int nIndex){ // returns a possible TAStarFlag
return (TAStarFlag)aFlags[nIndex];
}
CPossibleTAStarFlags(const TAStarFlag denyflags){ //constructor, build a possible TAStarFlag list
buildTAStarFlagsList(denyflags);
}
};
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -1573,17 +1629,23 @@ void CTopology::updateTopologyRef(CWorldMap* worldMapPtr)
inline inline
uint32 CTopology::getMasterTopo(TAStarFlag const& flags) const uint32 CTopology::getMasterTopo(TAStarFlag const& flags) const
{ {
switch (flags&WaterAndNogo) switch (flags&(WaterAndNogo | Ground))
{ {
case Nothing: case Nothing:
default: default:
return MasterTopL; return MasterTopL;
case Water: case Water:
return MasterTopLW; return MasterTopLW;
case NoGo: case NoGo:
return MasterTopLN; return MasterTopLN;
case WaterAndNogo: case WaterAndNogo:
return MasterTopLNW; return MasterTopLNW;
case Water|Ground:
return (MasterTopL == TTopologyId::UNDEFINED_TOPOLOGY) ? MasterTopLW : TTopologyId::UNDEFINED_TOPOLOGY;
case Water|Ground|NoGo:
return (MasterTopL == TTopologyId::UNDEFINED_TOPOLOGY) ? MasterTopLNW : TTopologyId::UNDEFINED_TOPOLOGY;
case NoGo|Ground:
return TTopologyId::UNDEFINED_TOPOLOGY;
} }
} }