From 46ad8bcf5d01dce162c9f506718c79324289b7af Mon Sep 17 00:00:00 2001 From: Nuno Date: Mon, 12 Apr 2021 10:33:33 +0200 Subject: [PATCH] Merge branch 'new_features' --- .../src/ai_service/ai_generic_fight.cpp | 78 +++++++----- ryzom/server/src/ai_service/ai_grp_npc.h | 5 + ryzom/server/src/ai_service/nf_grp_npc.cpp | 112 +++++++++++++++++- 3 files changed, 160 insertions(+), 35 deletions(-) diff --git a/ryzom/server/src/ai_service/ai_generic_fight.cpp b/ryzom/server/src/ai_service/ai_generic_fight.cpp index c88a93b8f..eeec81ffc 100644 --- a/ryzom/server/src/ai_service/ai_generic_fight.cpp +++ b/ryzom/server/src/ai_service/ai_generic_fight.cpp @@ -290,20 +290,20 @@ void CBotProfileFlee::updateProfile(uint ticksSinceLastUpdate) if (fleeVector.isNull()) fleeVector.setX(1+fleeVector.x()); // hum .. RYAI_MAP_CRUNCH::CDirection startDir(fleeVector.x(), fleeVector.y(), true); - + // if we need to change our destination. if ( startDir!=_LastDir || !_LastStartPos.hasSameFullCellId(_Bot->wpos())) { const RYAI_MAP_CRUNCH::CWorldMap &worldMap=CWorldContainer::getWorldMap(); calcDone=false; - + for (sint nbStep=0;nbStep<8;nbStep++) { // try to find a direction around startDir. RYAI_MAP_CRUNCH::CDirection dir(startDir); dir.addStep((RYAI_MAP_CRUNCH::CDirection::TDeltaDirection) ((nbStep&1)?(nbStep>>1):(-(nbStep>>1)))); - + const RYAI_MAP_CRUNCH::CRootCell *rootCell=worldMap.getRootCellCst(_Bot->wpos().stepCell(dir.dx(),dir.dy())); if (rootCell) { @@ -318,13 +318,13 @@ void CBotProfileFlee::updateProfile(uint ticksSinceLastUpdate) _fightFleePathContainer.setDestination(/*AITYPES::vp_auto, */wpos); break; } - + } - + } - + } - + // if we found somewhere to go, then go there .. if (calcDone) { @@ -368,7 +368,7 @@ NLMISC_COMMAND(fleeGiveUpDistanceUnreachable, "Generic flee give up distance whe CFightOrganizer::CFightOrganizer() : _HaveEnnemy(true) { -} +} bool CFightOrganizer::healIteration(CBot* bot, CBot* otherBot) { @@ -407,7 +407,7 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) IAIProfile *profile=spawnBot->getAIProfile(); AITYPES::TProfiles profileType=profile?profile->getAIProfileType():AITYPES::BAD_TYPE; - + // special comp if feared bypass every other comp .. (panic mode !) if (spawnBot->isFeared()) { @@ -420,9 +420,9 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) fleeVect += delta; aggroer = aggroer->nextTargeter(); } - + CAIS& inst = CAIS::instance(); - + FOREACHC(itEntry, CBotAggroOwner::TBotAggroList, spawnBot->getBotAggroList()) { CAIEntityPhysical* const phys = inst.getEntityPhysical(itEntry->second->getBot()); @@ -432,7 +432,7 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) delta -= phys->aipos(); fleeVect += delta; } - + fleeVect.normalize(1000); CAIVector toGroup = spawnBot->spawnGrp().getCenterPos(); toGroup -= spawnBot->aipos(); @@ -473,19 +473,33 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) if (healIteration(bot, *itBot)) return true; } - } + // Heal others - if (spawnBot->canHeal()) - { FOREACH(itBot, CCont, group->bots()) { if (*itBot && bot!=*itBot) if (healIteration(bot, *itBot)) return true; } + + // Heal others groups + CGroupNpc* npcGroup = NLMISC::safe_cast(group); + if (npcGroup) { + std::vector grps = npcGroup->getHealGroups(); + for (uint i=0; i, grps[i]->bots()) + { + if (*itBot && bot!=*itBot) + if (healIteration(bot, *itBot)) { + return true; + } + } + } + } } } - + if (profileType==AITYPES::BOT_FIGHT) { CBotProfileFight *fightProfile=NLMISC::safe_cast(profile); @@ -496,21 +510,21 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) } } - + std::vector botList; AISHEETS::ICreatureCPtr botSheet = bot->getSheet(); - + float grpAggroCoef = 0.5f*botSheet->GroupCohesionModulator(); - + spawnBot->updateListAndMarkBot(botList, 1.f-grpAggroCoef); - + // unmarkBot list and choose target. double BestChooseScore=0; //botSheet.ScoreModulator; - + CAIEntityPhysical * ennemy = NULL; CAIEntityPhysical const * fleeEnnemy = NULL; double BestFleeScore=0; //botSheet.FearModulator; - + CAIVector movingVector; double fear=1.0f; @@ -519,7 +533,7 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) FOREACH(it, std::vector, botList) { CAIEntityPhysical *const entity=(*it); - + if (!entity->isAlive()) { if (ai_profile_npc_VerboseLog) @@ -540,18 +554,18 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) spawnBot->forgetAggroFor(entity->dataSetRow()); continue; } - + // is there a problem. if (entity->_AggroScore>0) { CAIVector targetToPos(spawnBot->aipos()); targetToPos -= entity->aipos(); - + double slotCoef; { // 1 near - 0 far. slotCoef = 1.f/(1.f+targetToPos.quickNorm()*botSheet->DistModulator()); // melee consideration. (don't know correct dist for caster or range may be in munition sheet !?). - + if (((CAIEntityPhysical*)entity->getTarget())!=spawnBot) { int nbOtherTargeter = entity->targeterCount(); @@ -562,11 +576,11 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) } slotCoef *= entity->getFreeFightSpaceRatio(); } - + ////////////////////////////////////////////////////////////////////////////// - + float score = (float)(entity->_AggroScore*slotCoef); - + if (target && target->getRyzomType() == RYZOMID::player) { if (entity != target) @@ -596,12 +610,12 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) } entity->_ChooseLastTime = std::numeric_limits::max(); } - + if (fleeEnnemy==NULL && !spawnBot->getUnreachableTarget().isNULL()) { fleeEnnemy = spawnBot->getUnreachableTarget(); } - + if (ennemy) { _HaveEnnemy=true; @@ -610,7 +624,7 @@ bool CFightOrganizer::reorganizeIteration(CBot* bot) { return true; } - + // set the correct profile, if its not the case, otherwise, just change the target. if (profileType!=AITYPES::BOT_FIGHT) { diff --git a/ryzom/server/src/ai_service/ai_grp_npc.h b/ryzom/server/src/ai_service/ai_grp_npc.h index a2cdf6509..a90f4f5d8 100644 --- a/ryzom/server/src/ai_service/ai_grp_npc.h +++ b/ryzom/server/src/ai_service/ai_grp_npc.h @@ -237,6 +237,10 @@ public: void addHandle(TDataSetRow playerRowId, uint32 missionAlias, uint32 DespawnTimeInTick); void delHandle(TDataSetRow playerRowId, uint32 missionAlias); + void addHealGroup(CGroupNpc *healGroups) { _HealGroups.push_back(healGroups); } + std::vector getHealGroups() { return _HealGroups; } + void resetHealGroups() { _HealGroups.clear(); } + uint32 getTimerWhenNoMoreHandle(); void setSpawnZone(const CNpcZone *zone) { _SpawnZone = zone; } @@ -310,6 +314,7 @@ private: bool _AutoSpawnWhenNoMoreHandle; NLMISC::CVirtualRefPtr _SpawnZone; bool _RingGrp;//Ring rulez: like a override bandit profile + std::vector _HealGroups; }; diff --git a/ryzom/server/src/ai_service/nf_grp_npc.cpp b/ryzom/server/src/ai_service/nf_grp_npc.cpp index 01525043d..da962df04 100644 --- a/ryzom/server/src/ai_service/nf_grp_npc.cpp +++ b/ryzom/server/src/ai_service/nf_grp_npc.cpp @@ -2853,12 +2853,12 @@ void setUserModel_s_(CStateInstance* entity, CScriptStack& stack) { CBot* bot = *botIt; - //if (!bot->isSpawned()) return; - if (bot->getRyzomType() == RYZOMID::npc) { CBotNpc* botNpc = NLMISC::safe_cast(bot); botNpc->setUserModelId("ARK_"+userModel); + if (bot->isSpawned()) + bot->getSpawnObj()->sendInfoToEGS(); } } } @@ -2895,6 +2895,8 @@ void setCustomLoot_s_(CStateInstance* entity, CScriptStack& stack) { CBotNpc* botNpc = NLMISC::safe_cast(bot); botNpc->setCustomLootTableId(customTable); + if (bot->isSpawned()) + bot->getSpawnObj()->sendInfoToEGS(); } } } @@ -3037,13 +3039,17 @@ void setEventCode_sss_(CStateInstance* entity, CScriptStack& stack) code = scriptHex_decode(code); vector lines_of_code; NLMISC::splitString(code, "\n", lines_of_code); + uint32 line = 0; if (!lines_of_code.empty()) { + nlinfo("=== Code ==="); FOREACHC(it, vector, lines_of_code) { - nlinfo("Code: %s", (*it).c_str()); + nlinfo("#%d %s", line, (*it).c_str()); eventAction->Args.push_back(*it); + line++; } + nlinfo("=== * ==="); } // Register event action @@ -3091,6 +3097,104 @@ void setEventCode_sss_(CStateInstance* entity, CScriptStack& stack) } +//---------------------------------------------------------------------------- +/** @page code + +@subsection setParent_s_ + +A a link child -> parent from child + + +Arguments: parent(direction) +@param[in] the name of group who will be the parent of this group + +@code +()setParent("group_name"); +@endcode + +*/ + +void setParent_s_(CStateInstance* entity, CScriptStack& stack) +{ + + string parent = stack.top(); + + std::vector grps; + entity->getGroup()->getAIInstance()->findGroup(grps, parent); + if (grps.size() > 0) + { + CGroup* parentGroup = grps.back(); + CGroupNpc* parentNpcGroup = NLMISC::safe_cast(parentGroup); + + CGroup* group = entity->getGroup(); + CGroupNpc* npcGroup = NLMISC::safe_cast(group); + if (npcGroup && parentNpcGroup) + npcGroup->getPersistentStateInstance()->setParentStateInstance(parentNpcGroup->getPersistentStateInstance()); + } +} + + + +//---------------------------------------------------------------------------- +/** @page code + +@subsection addHealGroup_s_ + +Add a link to be able to heal a group + + +Arguments: group(direction) +@param[in] the name of group who will able to heal + +@code +()addHealGroup("group_name"); +@endcode + +*/ + +void addHealGroup_s_(CStateInstance* entity, CScriptStack& stack) +{ + + string healGroup = stack.top(); + + std::vector healGrps; + entity->getGroup()->getAIInstance()->findGroup(healGrps, healGroup); + + CGroup* group = entity->getGroup(); + CGroupNpc* npcGroup = NLMISC::safe_cast(group); + + for (uint i=0; i(healGrps[i]); + if (healNpcGroup) + npcGroup->addHealGroup(healNpcGroup); + } +} + +//---------------------------------------------------------------------------- +/** @page code + +@subsection resetHealGroups_ + +Add a link to be able to heal a group + +@code +()resetHealGroups(); +@endcode + +*/ + +void resetHealGroups_(CStateInstance* entity, CScriptStack& stack) +{ + CGroup* group = entity->getGroup(); + CGroupNpc* npcGroup = NLMISC::safe_cast(group); + npcGroup->resetHealGroups(); +} + + + + + std::map nfGetNpcGroupNativeFunctions() { std::map functions; @@ -3156,6 +3260,8 @@ std::map nfGetNpcGroupNativeFunctions() REGISTER_NATIVE_FUNC(functions, maxHitRange_f_); REGISTER_NATIVE_FUNC(functions, setEventCode_sss_); + REGISTER_NATIVE_FUNC(functions, setParent_s_); + REGISTER_NATIVE_FUNC(functions, addHealGroup_s_); REGISTER_NATIVE_FUNC(functions, addUserModel_sss_); REGISTER_NATIVE_FUNC(functions, addCustomLoot_ss_);