diff --git a/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp b/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp index 84bc47bf1..a6573d4bb 100644 --- a/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp +++ b/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp @@ -501,7 +501,7 @@ void CSpawnBotFauna::getBestTarget() if ( canMove() && !player->isAggressive() && entity->wpos().isValid() - && (entity->wpos().getFlags()&entity->getAStarFlag())==0) + && isPlaceAllowed(entity->getAStarFlag(), entity->wpos().getFlags())) { // Suppose we can go to him bool canChange = true; @@ -706,7 +706,7 @@ void CSpawnBotFauna::getBestTarget() if ( profile && profile->getAIProfileType()==ACTIVITY_CORPSE && botCreat->wpos().isValid() - && !(botCreat->wpos().getFlags()&botCreat->getAStarFlag()) + && isPlaceAllowed(botCreat->getAStarFlag(), botCreat->wpos().getFlags()) ) { CCorpseFaunaProfile *corpseProfile=NLMISC::safe_cast(profile); @@ -951,7 +951,7 @@ void CMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& a continue; if ( !faunaBot->wpos().isValid() - || (faunaBot->wpos().getFlags()&denyFlag)!=0) + || !isPlaceAllowed(denyFlag, faunaBot->wpos().getFlags())) continue; // 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. if ( !wRndPos.isValid() - || (wRndPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)!=0 ) + || !isPlaceAllowed(denyFlag, wRndPos.getTopologyRef().getCstTopologyNode().getFlags())) continue; #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) { - if (_ForcedDest.isValid() && (_ForcedDest.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)==0) + if (_ForcedDest.isValid() && isPlaceAllowed(denyFlag, _ForcedDest.getTopologyRef().getCstTopologyNode().getFlags())) _PathCont.setDestination(_ForcedDest); else CMovementMagnet::getNewDestination(alternativePos, denyFlag); diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp b/code/ryzom/server/src/ai_service/ai_generic_fight.cpp index fb8235063..cec456267 100644 --- a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp +++ b/code/ryzom/server/src/ai_service/ai_generic_fight.cpp @@ -309,7 +309,7 @@ void CBotProfileFlee::updateProfile(uint ticksSinceLastUpdate) { RYAI_MAP_CRUNCH::CWorldPosition wpos=rootCell->getWorldPosition(_Bot->getPersistent().getChildIndex()&3); 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; _LastStartPos=_Bot->wpos(); diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp b/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp index 4b655422c..f6d0af29d 100644 --- a/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp +++ b/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp @@ -374,7 +374,7 @@ bool s_move( 0.5f); // If we can't follow the path or the computed pos is invalid 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 _Bot->setPos(lastPos); @@ -605,7 +605,7 @@ static void s_updateProfile( _AtAttackDist = norm < _RangeMax; // 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 */ diff --git a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp b/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp index 5738af614..daa9de3c6 100644 --- a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp +++ b/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp @@ -836,7 +836,7 @@ bool CGrpFauna::spawnPop(uint popVersion) if (!places()[i]->worldValidPos().isValid()) return false; 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; } diff --git a/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp b/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp index b178cccff..68312d6ca 100644 --- a/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp +++ b/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp @@ -97,12 +97,37 @@ IAliasCont* CMgrFauna::getAliasCont(TAIType type) 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 sFlags; + NLMISC::splitString(tail, "|", sFlags); + FOREACHC(it, vector, 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; switch (aliasTree->getType()) { case AITypeGrp: - child = new CGrpFauna(this, aliasTree, WaterAndNogo); + child = new CGrpFauna(this, aliasTree, flags); break; case AITypeEvent: child = new CAIEventReaction(getStateMachine(), aliasTree); diff --git a/code/ryzom/server/src/ai_service/continent.cpp b/code/ryzom/server/src/ai_service/continent.cpp index 4745a19e4..96c172c72 100644 --- a/code/ryzom/server/src/ai_service/continent.cpp +++ b/code/ryzom/server/src/ai_service/continent.cpp @@ -1530,7 +1530,10 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro CPropertySet activities[CCellChoice::MAX_ZONE_SCORE]; activities[CCellChoice::FOOD_ZONE_SCORE].merge(foodActivity); 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. if (extensiveDebug) nldebug("ED0001.02: cells.size()=%d", cells.size()); // For each cell @@ -1586,22 +1589,15 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro continue; } - TAStarFlag const flags = (TAStarFlag)(wpos.getFlags()&GroundFlags); // Erase unused flags. + 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. - { - const uint32 incompatibilityFlags=possibleFlag&denyflags&GroundFlags; // Erase unused flags. - if (incompatibilityFlags) - { - if (extensiveDebug) nldebug("ED0001.06: incompatibilityFlags"); - continue; - } - + for(int i = 0;i < nFlags;i++){ + TAStarFlag possibleFlag = PossibleTAStarFlags.get(i); 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; } @@ -1611,7 +1607,7 @@ bool CCellZone::findRestAndFoodFaunaZoneInCellList(CFaunaZone const*& rest, CPro continue; } - CCellChoice::CZoneScore &zoneScore=searchMap[possibleFlag][masterTopo].zones[typeZone]; + CCellChoice::CZoneScore &zoneScore=searchMap[possibleFlag & WaterAndNogo][masterTopo].zones[typeZone]; if (scoreworldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); const RYAI_MAP_CRUNCH::TAStarFlag foodFlags=food->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); - nlassert((restFlags&denyflags)==0); - nlassert((foodFlags&denyflags)==0); + nlassert(isPlaceAllowed(denyflags, restFlags)); + nlassert(isPlaceAllowed(denyflags, foodFlags)); #endif 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(); - if (flags&denyflags) + if (!isPlaceAllowed(denyflags, flags)) continue; const float score=faunaZone->getFreeAreaScore(); diff --git a/code/ryzom/server/src/ai_share/world_map.cpp b/code/ryzom/server/src/ai_share/world_map.cpp index 677e8cb97..cbba47d49 100644 --- a/code/ryzom/server/src/ai_share/world_map.cpp +++ b/code/ryzom/server/src/ai_share/world_map.cpp @@ -34,6 +34,9 @@ NL_BEGIN_STRING_CONVERSION_TABLE (TAStarFlag) NL_STRING_CONVERSION_TABLE_ENTRY(NoGo) NL_STRING_CONVERSION_TABLE_ENTRY(WaterAndNogo) 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) const std::string& toString(TAStarFlag flag) @@ -781,14 +784,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosS(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isESlotValid()) return false; tmpPos=tmpPos.getPosE(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; } @@ -798,7 +801,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosE(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isSSlotValid()) @@ -819,14 +822,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosN(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isESlotValid()) return false; tmpPos=tmpPos.getPosE(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; } @@ -836,7 +839,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosE(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isNSlotValid()) @@ -856,14 +859,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosN(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isWSlotValid()) return false; tmpPos=tmpPos.getPosW(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; } @@ -873,7 +876,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosW(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isNSlotValid()) @@ -893,14 +896,14 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosS(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; if (!tmpPos.getCellLinkage().isWSlotValid()) return false; tmpPos=tmpPos.getPosW(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; } @@ -910,7 +913,7 @@ void CWorldMap::countCells(uint &compute, uint &white, uint &simple, uint &multi return false; tmpPos=tmpPos.getPosW(); - if ((tmpPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0) + if (!isPlaceAllowed(denyFlags, tmpPos.getTopologyRef().getCstTopologyNode().getFlags())) return false; 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 &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. - { - const uint32 incompatibilityFlags=(possibleFlag&(denyflags&~startFlag))&WaterAndNogo; - - if (incompatibilityFlags) - continue; - - const uint32 startMasterTopo=startTopoNode.getMasterTopo(possibleFlag); - const uint32 endMasterTopo=endTopoNode.getMasterTopo(possibleFlag); - if ( (startMasterTopo^endMasterTopo)!=0 - || startMasterTopo == std::numeric_limits::max()) // if not same masterTopo or invalid masterTopo then bypass .. - continue; - - res.set(possibleFlag, startMasterTopo); - res.setValid(); - - if (((possibleFlag&denyflags)&WaterAndNogo)==0) // it was the optimal case ? - break; + for(int i = 0;i < nFlags;i++){ // for each possible flag + TAStarFlag possibleFlag = PossibleTAStarFlags.get(i); + uint32 startMasterTopo=startTopoNode.getMasterTopo(possibleFlag); + uint32 endMasterTopo=endTopoNode.getMasterTopo(possibleFlag); + if( (startMasterTopo^endMasterTopo)!=0 || + (startMasterTopo == CTopology::TTopologyId::UNDEFINED_TOPOLOGY)){ // if not same masterTopo or invalid masterTopo then continue + continue; + } + res.set(possibleFlag, startMasterTopo); + res.setValid(); + break; } } @@ -1665,7 +1660,7 @@ bool CWorldMap::findAStarPath(const CTopology::TTopologyId &start, const CTopolo const CTopology &ntp = next.getCstTopologyNode(); // don't examine not accessible nodes - if ((ntp.Flags & denyflags) != 0) + if (!isPlaceAllowed(denyflags,(RYAI_MAP_CRUNCH::TAStarFlag) ntp.Flags)) continue; // compute actual node distance @@ -1821,7 +1816,7 @@ bool CWorldMap::findInsideAStarPath(CWorldPosition const& start, CWorldPosition continue; // 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; // Build an A* node @@ -1927,7 +1922,7 @@ bool CWorldMap::move(CWorldPosition &pos, CAStarPath &path, uint ¤tstep) c bool CWorldMap::move(CWorldPosition& pos, CMapPosition const& end, TAStarFlag const denyFlags) const { CWorldPosition tempPos(pos); - BOMB_IF((tempPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlags)!=0, "Error in CWorldMap::mode, invalid flag "<