Merge branch 'fixes'

feature/prepare-cross-merge
Ulukyn 4 years ago committed by kaetemi
parent 578ae687df
commit 72d29ef8f6
No known key found for this signature in database
GPG Key ID: 9873C4D40BB479BC

@ -42,6 +42,8 @@ using namespace RYAI_MAP_CRUNCH;
static bool VerboseLog = false;
#define LOG if (!VerboseLog) { } else nlinfo
extern CAIVector randomPos(double dispersionRadius);
//////////////////////////////////////////////////////////////////////////////
// CSpawnBotNpc //
//////////////////////////////////////////////////////////////////////////////
@ -64,14 +66,14 @@ void CSpawnBotNpc::sendInfoToEGS() const
{
if (!EGSHasMirrorReady)
return;
CSpawnBot::sendInfoToEGS();
TGenNpcDescMsgImp msg;
msg.setEntityIndex(dataSetRow());
getPersistent().fillDescriptionMsg(msg);
msg.setChat(_CurrentChatProfile);
msg.send("EGS");
}
@ -86,7 +88,7 @@ void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event)
// no self aggro.
if (event._targetRow==event._originatorRow)
return;
if ((event._nature==ACTNATURE::FIGHT || event._nature==ACTNATURE::OFFENSIVE_MAGIC) && !getPersistent().ignoreOffensiveActions())
{
float aggro = event._weight;
@ -116,7 +118,7 @@ void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event)
{
++AISStat::BotTotalUpdCtr;
++AISStat::BotNpcUpdCtr;
{
H_AUTO(AIHpTrig);
// Fix for HP triggers
@ -136,7 +138,7 @@ void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event)
_OldHpPercentage = getPhysical().hpPercentage();
}
}
// Bot chat and dyn chat override AI profile unless fighting
// The directing adjustment is done client-slide (each player sees the NPC facing him)
if (!getActiveChats().empty())
@ -156,10 +158,10 @@ void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event)
if (sp)
{
sp->getPersistent().notifyStopNpcControl();
}
}
_PlayerController = NULL;
_PlayerController = NULL;
}
if (_PlayerController == NULL)
@ -186,16 +188,16 @@ void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event)
// If sit and move then stand up
if (IsRingShard)
{
{
if (getMode() == MBEHAV::SIT
&& (x().asInt() != startPos.x().asInt() || y().asInt() != startPos.y().asInt()) )
{
setMode(MBEHAV::NORMAL);
}
if (_FacingTick != 0)
{
{
uint32 tick = CTimeInterface::gameCycle();
if ( (tick - _FacingTick) > 40)
{
@ -213,7 +215,7 @@ void CSpawnBotNpc::setFacing(CAngle theta)
{
_FacingTheta = pos().theta();
}
setTheta(theta);
_FacingTick = CTimeInterface::gameCycle();
}
@ -260,8 +262,8 @@ std::vector<std::string> CSpawnBotNpc::getMultiLineInfoString() const
{
std::vector<std::string> container;
std::vector<std::string> strings;
pushTitle(container, "CSpawnBotNpc");
strings.clear();
strings = CSpawnBot::getMultiLineInfoString();
@ -287,8 +289,8 @@ std::vector<std::string> CSpawnBotNpc::getMultiLineInfoString() const
}
}
pushFooter(container);
return container;
}
@ -301,7 +303,7 @@ void CSpawnBotNpc::beginBotChat(CBotPlayer* plr)
nlwarning("Chat pair added more than once!!!");
}
#endif
// add an entry to the bot chat vector
_ActiveChats.push_back(plr);
}
@ -313,11 +315,11 @@ void CSpawnBotNpc::endBotChat(CBotPlayer* plr)
{
if (_ActiveChats[i]!=plr)
continue;
// we've found a match for the player so remove the entry from the _aciveChats vector and return
_ActiveChats[i] = _ActiveChats[_ActiveChats.size()-1];
_ActiveChats.pop_back();
#ifdef NL_DEBUG
for (size_t j=i;j<_ActiveChats.size();++j)
{
@ -342,14 +344,14 @@ void CSpawnBotNpc::propagateAggro() const
CDynGrpBase* myDgb = pGroup->getGrpDynBase();
nlassert(myDgb);
CFamilyBehavior* myfb = myDgb->getFamilyBehavior();
CAIVision<CPersistentOfPhysical> vision;
// look for bots around
vision.updateBotsAndPlayers(pGroup->getAIInstance(), CAIVector(pos()), 0, (uint32)getAggroPropagationRadius());
typedef map<CSpawnBot*, float> TCandidatesCont;
TCandidatesCont candidates;
if (myfb!=NULL)
{
FOREACH(it, CAIVision<CPersistentOfPhysical>, vision)
@ -358,32 +360,32 @@ void CSpawnBotNpc::propagateAggro() const
CSpawnBot* otherSpBot = otherPBot.getSpawnObj();
CGroup* otherPGroup = otherPBot.getOwner();
CSpawnGroup* otherSpGroup = otherPGroup->getSpawnObj();
// If bot is in our group skip it
if (otherSpGroup==spGroup)
continue;
// If bot is not in a dynamic system skip it
CDynGrpBase* otherDGB = otherPGroup->getGrpDynBase();
if (!otherDGB)
continue;
// If bot is not in our family skip it
CFamilyBehavior* otherFB = otherDGB->getFamilyBehavior();
if (otherFB!=myfb)
continue;
// ok, this group should help us !
// TODO : take only groups with the 'activity_figth' property
// filter out if the group is already in combat mode
// If group is not spawned skip it (???) (:TODO: See why this test)
if (!otherPGroup->isSpawned())
continue;
CProfilePtr& otherFightProfile = otherSpGroup->fightProfile();
if (!otherFightProfile.getAIProfile() || otherFightProfile.getAIProfileType()!=AITYPES::FIGHT_NORMAL || !(static_cast<CGrpProfileFight*>(otherFightProfile.getAIProfile())->stillHaveEnnemy()))
{
float dist = (float)CAIVector(otherSpBot->pos()).quickDistTo(pos());
@ -392,10 +394,10 @@ void CSpawnBotNpc::propagateAggro() const
}
}
}
if (!candidates.empty())
nldebug("Tick %u, prop aggro from %p to %u bots", CTickEventHandler::getGameCycle(), this, candidates.size());
FOREACH (it, TCandidatesCont, candidates)
{
float propFactor = 1.0f - (it->second / getAggroPropagationRadius());
@ -435,7 +437,7 @@ void CSpawnBotNpc::setCurrentChatProfile(CNpcChatProfileImp* chatProfile)
{
if (chatProfile)
_CurrentChatProfile = *chatProfile;
else
else
_CurrentChatProfile.clear(); // clear the chat profile
}
@ -466,7 +468,7 @@ CBotNpc::CBotNpc(CGroup* owner, uint32 alias, std::string const& name)
init();
}
CBotNpc::~CBotNpc()
CBotNpc::~CBotNpc()
{
if (isSpawned())
{
@ -479,12 +481,12 @@ void CBotNpc::calcSpawnPos(RYAI_MAP_CRUNCH::CWorldMap const& worldMap)
CAIStatePositional const* const state = static_cast<CAIStatePositional*>(grp().getStartState());
RYAI_MAP_CRUNCH::CWorldPosition wp;
uint32 maxTries = 100;
breakable
{
if (!state)
break;
if (state->shape().hasPatat() && state->shape().getRandomPosCount())
{
do
@ -497,11 +499,11 @@ void CBotNpc::calcSpawnPos(RYAI_MAP_CRUNCH::CWorldMap const& worldMap)
_StartPos.setTheta(0); // to initialise among vertices deltas (no?).
break;
}
if (!state->shape().hasPoints())
break;
std::vector<CShape::TPosition> const& posList = state->shape().getGeometry();
std::vector<CShape::TPosition> const& posList = state->shape().getGeometry();
do
{
const uint32 a=CAIS::rand16((uint32)posList.size());
@ -560,15 +562,15 @@ std::string CBotNpc::getCustomLootTableId()
return _CustomLootTableId;
}
void CBotNpc::setPrimAlias(uint32 alias)
{
void CBotNpc::setPrimAlias(uint32 alias)
{
_PrimAlias = alias;
}
uint32 CBotNpc::getPrimAlias() const
{
return _PrimAlias;
uint32 CBotNpc::getPrimAlias() const
{
return _PrimAlias;
}
@ -578,18 +580,18 @@ void CBotNpc::fillDescriptionMsg(RYMSG::TGenNpcDescMsg& msg) const
msg.setBotAttackable(grp().getBotAttackable());
msg.setAlias(getAlias());
msg.setGrpAlias(grp().getAlias());
msg.setSheet(getSheet()->SheetId());
msg.setRightHandItem(getSheet()->RightItem());
msg.setRightHandItemQuality(1);
msg.setLeftHandItem(getSheet()->LeftItem());
msg.setLeftHandItemQuality(1);
msg.setDontFollow(isStuck());
msg.setBuildingBot(isBuildingBot());
for (size_t i=0; i<_LootList.size(); ++i)
{
NLMISC::CSheetId const& sheetRef = _LootList[i];
@ -629,12 +631,12 @@ bool CBotNpc::finalizeSpawnNpc()
getSpawn()->setOutpostAlias(ownerOutpost->getAlias());
getSpawn()->setOutpostSide(_OutpostSide);
}
CMirrors::initSheetServer(getSpawn()->dataSetRow(), getSheet()->SheetId());
getSpawn()->setCurrentChatProfile(_ChatProfile);
getSpawn()->sendInfoToEGS();
if (_useVisualProperties) // use VisualPropertyA, B, C
{
sendVisualProperties();
@ -643,9 +645,9 @@ bool CBotNpc::finalizeSpawnNpc()
{
sendVPA ();
}
getSpawn()->spawnGrp().botHaveSpawn(this);
return true;
}
@ -671,10 +673,10 @@ bool CBotNpc::spawn()
nlwarning("spawn() Aborted for bot '%s' due to bad sheet", getFullName().c_str());
return false;
}
if (!CBot::spawn())
return false;
// :KLUDGE: Last part calls a tricky method also called by sheetChanged
// :TODO: Clean that mess
return finalizeSpawnNpc();
@ -688,12 +690,12 @@ void CBotNpc::sendVPA() // alternate VPA
CVisualSlotManager* visualSlotManager = CVisualSlotManager::getInstance();
NLMISC::CSheetId rightSheet = getSheet()->RightItem();
NLMISC::CSheetId leftSheet = getSheet()->LeftItem();
visProp.Element.WeaponRightHand = visualSlotManager->rightItem2Index(rightSheet);
visProp.Element.WeaponLeftHand = visualSlotManager->leftItem2Index(leftSheet);
}
// setting up the visual property A mirror record
// setting up the visual property A mirror record
visProp.Element.ColorTop = getSheet()->ColorBody();
visProp.Element.ColorBot = getSheet()->ColorLegs();
visProp.Element.ColorHair = getSheet()->ColorHead();
@ -714,7 +716,7 @@ void CBotNpc::sendVPA() // alternate VPA
visProp.Element.ColorBoot,
visProp.Element.ColorArm,
visProp.Element.Seed);
CMirrors::setVPA(getSpawn()->dataSetRow(), visProp);
}
@ -732,7 +734,7 @@ bool CBotNpc::reSpawn(bool sendMessage)
{
if (!spawn())
return false;
getSpawn()->updateChat(grp().getCAIState());
return true;
}
@ -746,7 +748,7 @@ void CBotNpc::despawnBot()
}
}
void CBotNpc::equipmentInit()
void CBotNpc::equipmentInit()
{
_Sheet->reset();
_Hat = false;
@ -762,7 +764,7 @@ void CBotNpc::equipmentAdd(std::string const& input)
// if string is empty just return without making a fuss
if (input.empty())
return;
// split string into keyword and tail
std::string keyword, tail;
if (!AI_SHARE::stringToKeywordAndTail(input,keyword,tail))
@ -773,7 +775,7 @@ void CBotNpc::equipmentAdd(std::string const& input)
input.c_str());
return;
}
// do something depending on keyword
if (NLMISC::nlstricmp(keyword,"ri")==0)
{
@ -836,7 +838,7 @@ void CBotNpc::equipmentAdd(std::string const& input)
else if ( NLMISC::nlstricmp(keyword,"CLIENT_SHEET")==0 )
{
setClientSheet(tail + ".creature");
}
}
else if (NLMISC::nlstricmp(keyword,"loot")==0)
{
if (tail.empty())
@ -854,14 +856,14 @@ void CBotNpc::equipmentAdd(std::string const& input)
}
else if (NLMISC::nlstricmp(keyword, "USER_MODEL") == 0)
{
uint32 primAlias = getAlias() >> LigoConfig.getDynamicAliasSize();
nldebug("Parsing userModelId '%s' with primAlias: '%u'", tail.c_str(), primAlias);
setPrimAlias(primAlias);
setUserModelId(tail);
}
else if (NLMISC::nlstricmp(keyword, "CUSTOM_LOOT_TABLE") == 0)
{
{
uint32 primAlias = getAlias() >> LigoConfig.getDynamicAliasSize();
nldebug("Parsing customLootTableId '%s' with primAlias: '%u'", tail.c_str(), primAlias);
setPrimAlias(primAlias);
@ -878,14 +880,14 @@ void CBotNpc::equipmentAdd(std::string const& input)
/*
Colors are something like that:
3D INTERFACE MP
0: ROUGE ROUGE RED
1: BEIGE ORANGE BEIGE
2: VERT CITRON VERT CITRON GREEN
3: VERT VERT TURQUOISE
4: BLEU BLEU BLUE
5: ROUGE dark ROUGE (normal) CRIMSON
6: BLANC JAUNE WHITE
3D INTERFACE MP
0: ROUGE ROUGE RED
1: BEIGE ORANGE BEIGE
2: VERT CITRON VERT CITRON GREEN
3: VERT VERT TURQUOISE
4: BLEU BLEU BLUE
5: ROUGE dark ROUGE (normal) CRIMSON
6: BLANC JAUNE WHITE
7: NOIR BLEU very dark BLACK
3D column is (probably) used for equipment
@ -894,7 +896,7 @@ void CBotNpc::setColour(uint8 colour)
{
_Sheet->setColorHead(colour);
_Sheet->setColorArms(colour);
_Sheet->setColorHands(colour);
_Sheet->setColorHands(colour);
_Sheet->setColorBody(colour);
_Sheet->setColorLegs(colour);
_Sheet->setColorFeets(colour);
@ -906,11 +908,11 @@ void CBotNpc::setColours(std::string input)
int const numColours = 8;
static std::vector <std::string> colourNames[numColours];
static bool init = false;
// if string is empty just return without making a fuss
if (input.empty())
return;
if (!init)
{
// lookup 'ColourNames' in config file (should be a multi-line field)
@ -920,7 +922,7 @@ void CBotNpc::setColours(std::string input)
// for each line in config file var try to add an alternative name for one of the colour slots
for (uint i=0; i<varPtr->size(); ++i)
{
// split line into name and idx (line example: 'red: 5')
// split line into name and idx (line example: 'red: 5')
std::string name, idxStr;
if (AI_SHARE::stringToKeywordAndTail(varPtr->asString(i),name,idxStr))
{
@ -994,12 +996,12 @@ void CBotNpc::setColours(std::string input)
}
}
}
if (i==numColours)
nlwarning("Failed to identify colour: '%s' in line: '%s'",colour.c_str(),input.c_str());
}
}
// assuming that we found more than 0 results pick one at random
if (results.empty())
{
@ -1151,9 +1153,10 @@ void CBotNpc::init()
{
_ChatProfile = NULL;
_MaxHitRangeForPC = -1.0f;
_DispersionRadius = 0;
// _MissionIconFlags.IsMissionStepIconDisplayable = true;
// _MissionIconFlags.IsMissionGiverIconDisplayable = true;
equipmentInit();
}
@ -1169,21 +1172,38 @@ CSpawnBotNpc const* CBotNpc::getSpawn() const
void CBotNpc::getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta)
{
if (_StartPos.isNull())
if (_DispersionRadius > 0)
{
RYAI_MAP_CRUNCH::CWorldPosition wp;
CAIVector rpos = _FirstPosition;
uint32 maxTries = 100;
do
{
rpos = _FirstPosition;
rpos += randomPos(_DispersionRadius);
--maxTries;
}
while (!worldMap.setWorldPosition(AITYPES::vp_auto, wp, rpos) && maxTries>0);
if (maxTries > 0 ) {
nlinfo("set pos %f,%f", rpos.x().asDouble(), rpos.x().asDouble());
_StartPos.setXY(rpos);
}
}
else if (_StartPos.isNull())
calcSpawnPos(worldMap);
if (isStuck() || IsRingShard)
worldMap.setWorldPosition(_VerticalPos, pos, _StartPos);
else
CWorldContainer::calcNearestWPosFromPosAnRadius(_VerticalPos, worldMap, pos, _StartPos, 10, 200, CWorldContainer::CPosValidatorDefault());
#ifdef NL_DEBUG
if (!pos.isValid() && !isStuck())
{
nlwarning("Npc Spawn Pos Error %s", pos.toString().c_str());
}
#endif
spawnTheta = _StartPos.theta();
triedPos = _StartPos;
}
@ -1220,20 +1240,20 @@ void CBotNpc::sheetChanged()
CAngle spawnTheta = getSpawnObj()->theta();
float botMeterSize = getSheet()->Scale()*getSheet()->Radius();
// :TODO: Save profile info
// If stuck bot position may be outside collision and must be recomputed
if (isStuck() || IsRingShard)
getSpawnPos(lastTriedPos, botWPos, CWorldContainer::getWorldMap(), spawnTheta);
// Delete old bot
CMirrors::removeEntity(getSpawnObj()->getEntityId());
setSpawn(NULL); // automatic smart pointer deletion
notifyBotDespawn();
// Finalize spawn object creation
if (!finalizeSpawn(botWPos, spawnTheta, botMeterSize))
return;
// :KLUDGE: Both finalizeSpawn and finalizeSpawnNpc are called,
// sheetChanged has a strange herited meaning and may confuse future
// coders
@ -1252,16 +1272,16 @@ NLMISC_COMMAND(verboseNPCBotProfiles, "Turn on or off or check the state of verb
{
if (args.size()>1)
return false;
if (args.size()==1)
NLMISC::fromString(args[0], VerboseLog);
nlinfo("VerboseLogging is %s",VerboseLog?"ON":"OFF");
return true;
}
// virtual function so do not need to be inlined
bool CBotNpc::getFaunaBotUseBotName() const
{
return _FaunaBotUseBotName;
{
return _FaunaBotUseBotName;
}

@ -41,47 +41,47 @@ class CSpawnBotNpc
{
public:
CSpawnBotNpc(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags);
void update(uint32 ticks);
CSpawnGroupNpc& spawnGrp() const;
// Accessors for NPC dynamic parameters -----------------------------
void setCurrentChatProfile(CNpcChatProfileImp* chatProfile);
void updateChat(CAIState const* state);
virtual void processEvent(CCombatInterface::CEvent const& event);
CAIEntityPhysical& getPhysical() { return *this; }
/// @name Chat parameter management
/// @name Chat parameter management
//@{
void beginBotChat(CBotPlayer* plr);
void endBotChat(CBotPlayer* plr);
void beginDynChat() { ++_NbCurrentDynChats; }
void endDynChat() { --_NbCurrentDynChats; }
//@}
// Return the active bot chats
std::vector<CBotPlayer*>& getActiveChats() { return _ActiveChats; }
// Return the number of dyn chats (these chats are not managed by the AIS)
uint getNbActiveDynChats() { return _NbCurrentDynChats; }
/// Dispatching message to EGS to describe chat possibilities
void sendInfoToEGS() const;
virtual std::vector<std::string> getMultiLineInfoString() const;
CBotNpc& getPersistent() const;
virtual RYZOMID::TTypeId getRyzomType() const { return RYZOMID::npc; }
virtual bool isBotAttackable() const;
virtual void propagateAggro() const;
float getReturnDistCheck() const;
void setPlayerController(CBotPlayer* player);
@ -102,7 +102,7 @@ public:
private:
std::vector<CBotPlayer*> _ActiveChats; // vector of ptrs to players currently chatting with bot
float _OldHpPercentage; // Fix for HP triggers
CNpcChatProfileImp _CurrentChatProfile;
sint32 _NbCurrentDynChats;
NLMISC::CSmartPtr<CPlayerControlNpc> _PlayerController;
@ -135,7 +135,7 @@ public:
{
reset();
}
///@name ICreature overloads
//@{
virtual uint8 ColorHead() const { return _ColorHead; }
@ -144,7 +144,7 @@ public:
virtual uint8 ColorBody() const { return _ColorBody; }
virtual uint8 ColorLegs() const { return _ColorLegs; }
virtual uint8 ColorFeets() const { return _ColorFeets; }
virtual NLMISC::CSheetId const& LeftItem() const
{
if (_LeftItem!=NLMISC::CSheetId::Unknown)
@ -160,7 +160,7 @@ public:
return this->CCreatureProxy::RightItem();
}
//@}
///@name Setters
//@{
void setColorHead(uint8 val) { _ColorHead = val; }
@ -169,7 +169,7 @@ public:
void setColorBody(uint8 val) { _ColorBody = val; }
void setColorLegs(uint8 val) { _ColorLegs = val; }
void setColorFeets(uint8 val) { _ColorFeets = val; }
void setLeftItem(NLMISC::CSheetId const& val) { _LeftItem = val; }
void setRightItem(NLMISC::CSheetId const& val) { _RightItem = val; }
//@}
@ -188,13 +188,13 @@ public:
_ColorFeets = _Sheet->ColorFeets();
}
}
private:
private:
NLMISC::CSheetId _LeftItem;
NLMISC::CSheetId _RightItem;
uint8 _ColorHead;
uint8 _ColorArms;
uint8 _ColorHands;
uint8 _ColorHands;
uint8 _ColorBody;
uint8 _ColorLegs;
uint8 _ColorFeets;
@ -212,72 +212,74 @@ class CBotNpc
{
public:
friend class CSpawnBotNpc; // allows CSpawnBotNpc to acceed his definition.
public:
CBotNpc(CGroup* owner, CAIAliasDescriptionNode* alias = NULL);
CBotNpc(CGroup* owner, uint32 alias, std::string const& name);
virtual ~CBotNpc();
void init();
RYZOMID::TTypeId getRyzomType() const { return RYZOMID::npc; }
CSpawnBotNpc* getSpawn();
CSpawnBotNpc const* getSpawn() const;
CAIS::CCounter& getSpawnCounter();
void calcSpawnPos(RYAI_MAP_CRUNCH::CWorldMap const& worldMap);
void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta);
CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius);
// spawn & despawn --------------------------------------------------
virtual bool spawn();
virtual void despawnBot();
bool reSpawn(bool sendMessage = true);
//------------------------------------------------------------
// accessing the parent mgr, group, etc
// accessing the parent mgr, group, etc
CGroupNpc& grp() const;
// Carried equipment management -------------------------------------
void equipmentInit();
void equipmentAdd(std::string const& kit);
// Write accessors for NPC base parameters --------------------------
void setStartPos(double x, double y, float theta, AITYPES::TVerticalPos verticalPos);
void setColour(uint8 colour);
void setColours(std::string colours);
void setVisualProperties(std::string input);
inline void saveFirstPosition(CAIVector pos, uint8 value) { _FirstPosition = pos, _DispersionRadius = value; }
inline void setMaxHitRangeForPlayer(float maxHitRange) { _MaxHitRangeForPC = maxHitRange; }
// void setMissionStepIconHidden(bool hide) { _MissionIconFlags.IsMissionStepIconDisplayable = !hide; }
// void setMissionGiverIconHidden(bool hide) { _MissionIconFlags.IsMissionGiverIconDisplayable = !hide; }
// Read accessors for NPC base parameters ---------------------------
NLMISC::CSheetId getStats() const { return getSheet()->SheetId(); }
CAIPos const& getStartPos() const { return _StartPos; }
AITYPES::TVerticalPos getStartVerticalPos() const { return _VerticalPos; }
// Callback called on state change of parent group (including changes to/from punctual states)
// the update routine (delegates control to the _aiProfile object) --
// void update(uint32 ticks);
// do nothing for 'ticks' ticks
// return number of ticks of movement time left after destination reached (or 0)
void sendVPA();
void sendVisualProperties();
void newChat();
NLMISC::CSmartPtr<CNpcChatProfileImp> const& getChat() const { return _ChatProfile; }
void setUserModelId(const std::string &userModelId);
std::string getUserModelId();
@ -287,13 +289,13 @@ public:
void setPrimAlias(uint32 alias);
uint32 getPrimAlias() const;
// void fillDescriptionMsg(CNpcBotDescriptionImp& msg) const;
void fillDescriptionMsg(RYMSG::TGenNpcDescMsg& msg) const;
virtual std::string getOneLineInfoString() const { return std::string("NPC bot '") + getName() + "'"; }
virtual AISHEETS::ICreatureCPtr getSheet() const { return _Sheet.getPtr(); }
virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet);
@ -302,22 +304,22 @@ public:
{
return _Sheet!=NULL && _Sheet->isValid();
}
void setOutpostSide(OUTPOSTENUMS::TPVPSide side) { _OutpostSide = side; }
virtual bool getFaunaBotUseBotName() const;
protected:
virtual void sheetChanged();
bool finalizeSpawnNpc();
virtual void initAdditionalMirrorValues();
protected:
// stuff supplied by CAIBot ------------------
// sheet (.creature) for game parameters
// position & orientation
// mode and behaviour
// A static bot object with a fauna sheet must not display SheetName but botobject name
bool _FaunaBotUseBotName;
@ -332,23 +334,25 @@ protected:
// look parameters ---------------------------
bool _Hat;
bool _useVisualProperties; // true => use VisualPropertyA, B, C instead of alternate VPA
uint64 _VisualPropertyA;
uint64 _VisualPropertyB;
uint64 _VisualPropertyC;
CBotNpcSheetPtr _Sheet;
// spawn place -------------------------------
CAIPos _StartPos;
CAIVector _FirstPosition;
uint8 _DispersionRadius;
std::vector<NLMISC::CSheetId> _LootList;
// static chat parameters --------------------
NLMISC::CSmartPtr<CNpcChatProfileImp> _ChatProfile;
// Outpost side
OUTPOSTENUMS::TPVPSide _OutpostSide;

@ -216,8 +216,9 @@ void CAIInstance::initInstance(string const& continentName, uint32 instanceNumbe
_ContinentName = continentName;
_InstanceNumber = instanceNumber;
_LastSpawnAlias = (900 + _InstanceNumber) << LigoConfig.getDynamicAliasSize();
_LastSpawnAlias = (900 + _InstanceNumber) << LigoConfig.getDynamicAliasSize();
_LastStateAlias = 0;
_LastGroupAlias = (900 + _InstanceNumber) << LigoConfig.getDynamicAliasSize();
sendInstanceInfoToEGS();
@ -344,8 +345,9 @@ CGroup* CAIInstance::findGroup(uint32 alias)
void CAIInstance::findGroup(std::vector<CGroup*>& result, std::string const& name)
{
std::map<std::string, std::vector<NLMISC::CDbgPtr<CGroup> > >::iterator it(_GroupFromNames.find(name));
if (it != _GroupFromNames.end())
if (it != _GroupFromNames.end()) {
result.insert(result.end(), it->second.begin(), it->second.end());
}
}
void CAIInstance::addMissionInfo(std::string const& missionName, uint32 alias)
@ -647,8 +649,9 @@ std::vector<std::string> CAIInstance::getMultiLineInfoString() const
#include "ai_bot_npc.h"
#include "ai_profile_npc.h"
inline
static CAIVector randomPos(double dispersionRadius)
extern CAIVector randomPos(double dispersionRadius);
CAIVector randomPos(double dispersionRadius)
{
if (dispersionRadius<=0.)
{
@ -684,14 +687,15 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
return NULL;
}
_LastGroupAlias++;
string name = botsName.empty() ? NLMISC::toString("event_group_%u", _LastGroupAlias):botsName;
// Create a group
CGroupNpc* grp = new CGroupNpc(_EventNpcManager, NULL, RYAI_MAP_CRUNCH::Nothing);
CGroupNpc* grp = new CGroupNpc(_EventNpcManager, _LastGroupAlias, name, RYAI_MAP_CRUNCH::Nothing);
// Register it in the manager
_EventNpcManager->groups().addAliasChild(grp);
// Set the group parameters
grp->setAutoSpawn(false);
string name = botsName.empty() ? NLMISC::toString("event_group_%u", grp->getChildIndex()):botsName;
grp->setName(name);
grp->clearParameters();
@ -707,7 +711,7 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
{
// build unnamed bot
for (uint i=0; i<nbBots; ++i)
for (uint i=0; i<nbBots; ++i)
{
_LastSpawnAlias++;
nlinfo("Spawn with alias : %d (%s)", _LastSpawnAlias, _LigoConfig.aliasToString(_LastSpawnAlias).c_str());
@ -727,9 +731,17 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
nlinfo("Stucked !");
bot->setStuck(true);
}
float angle = 0.f;
if (orientation < (NLMISC::Pi * 2.0) && orientation > (-NLMISC::Pi * 2.0))
angle = (float)orientation;
else
angle = randomAngle();
// Spawn all randomly except if only 1 bot
if (nbBots > 1)
if (nbBots > 1 || dispersionRadius > 1)
{
bot->saveFirstPosition(pos, dispersionRadius);
RYAI_MAP_CRUNCH::CWorldMap const& worldMap = CWorldContainer::getWorldMap();
RYAI_MAP_CRUNCH::CWorldPosition wp;
uint32 maxTries = 100;
@ -742,15 +754,11 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
while (!worldMap.setWorldPosition(AITYPES::vp_auto, wp, rpos) && maxTries>0);
if (maxTries<=0)
rpos = pos;
}
float angle = 0.f;
if (orientation < (NLMISC::Pi * 2.0) && orientation > (-NLMISC::Pi * 2.0))
angle = (float)orientation;
bot->setStartPos(pos.x().asDouble(), pos.y().asDouble(), angle, AITYPES::vp_auto);
}
else
angle = randomAngle();
bot->setStartPos(rpos.x().asDouble(),rpos.y().asDouble(), angle, AITYPES::vp_auto);
bot->setStartPos(rpos.x().asDouble(),rpos.y().asDouble(), angle, AITYPES::vp_auto);
}
}
@ -786,7 +794,7 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
}
grp->setNextState(statePositional);
}
if (spawnBots)
grp->getSpawnObj()->spawnBots();
@ -999,7 +1007,7 @@ void cbEventNpcGroupScript( NLNET::CMessage& msgin, const std::string &serviceNa
CEntityId playerId;
if (!eid.empty())
playerId = CEntityId(eid);
strings.resize(nbString-1);
CSString groupname = CSString(firstCommand);
if (firstCommand[0] == '#' && firstCommand[1] == '(')

@ -65,7 +65,7 @@ class CAIInstance
public:
CAIInstance(CAIS* owner);
virtual ~CAIInstance();
typedef CHashMap<NLMISC::TStringId, NLMISC::CDbgPtr<CNpcZone>, NLMISC::CStringIdHashMapTraits> TZoneList;
TZoneList zoneList;
void addZone(std::string const& zoneName, CNpcZone* zone);
@ -73,50 +73,50 @@ public:
CNpcZone* getZone(NLMISC::TStringId zoneName);
// Trig Event if player in zone
void updateZoneTrigger(CBotPlayer* player);
// overloads for IManagerParent virtuals
CAIInstance* getAIInstance() const { return const_cast<CAIInstance*>(this); }
CCellZone* getCellZone() { return NULL; }
virtual std::string getIndexString() const;
virtual std::string getOneLineInfoString() const;
virtual std::vector<std::string> getMultiLineInfoString() const;
std::string getManagerIndexString(CManager const* manager) const;
void groupDead(CGroup* grp) { }
void serviceEvent(CServiceEvent const& info);
//-------------------------------------------------------------------
// classic init(), update() and release()
// the update routine called once per tick
// this is the routine that calls the managers' updates
void update();
//-------------------------------------------------------------------
// managing the set of managers
// factory for creating new managers and for adding them to the _managers map
CManager* newMgr(AITYPES::TMgrType type, uint32 alias, std::string const& name, std::string const& mapName, std::string const& filename);
// a method that parse a supposed know type of manager:group:bot hierarchy and return the element as CAIEntity.
CManager* tryToGetManager(char const* str);
CGroup* tryToGetGroup(char const* str);
CAIEntity* tryToGetEntity(char const* str, CAIS::TSearchType searchType);
// erase a manager (free resources, free id, etc, etc
// asserts if the id is invalid (<0 or >1023)
// displays a warning and returns cleanly if the id is unused
void deleteMgr(sint mgrId);
//-------------------------------------------------------------------
// the previous interfaces for searching the data structures for named objects are transfered in CAIEntityId
// the previous interfaces for searching the data structures for named objects are transfered in CAIEntityId
// as its one of their object behavior. a solution to build id directly was added.
CMgrPet* getPetMgr() { return _PetManager; }
CManagerPlayer* getPlayerMgr() { return _PlayerManager; }
//-------------------------------------------------------------------
// Interface to kami management
void registerKamiDeposit(uint32 alias, CGroupNpc* grp);
@ -124,23 +124,23 @@ public:
//-------------------------------------------------------------------
// Interface to the vision management matrices
// read accessors for getting hold of the vision matrices and their associated iterator tables
CAIEntityMatrix<CPersistentOfPhysical>& playerMatrix() { return _PlayerMatrix; }
CAIEntityMatrix<CPersistentOfPhysical>& botMatrix() { return _BotMatrix; }
CAliasCont<CManager>& managers() { return _Managers; }
CCont<CContinent>& continents() { return _Continents; }
CCont<CContinent> const& continents() const { return _Continents; }
// Methods to retreive location in the dynamic system.
CContinent* locateContinentForPos(CAIVector const& pos);
CRegion* locateRegionForPos(CAIVector const& pos);
CCellZone* locateCellZoneForPos(CAIVector const& pos);
CCell* locateCellForPos(CAIVector const& pos);
//-------------------------------------------------------------------
// Mission name/alias retreiver
/** Add a mission name and alias info. If alias is already mapped to a mission name, replace the mapping.
@ -161,7 +161,7 @@ public:
* This search is not optimized, linar time search !
*/
std::string const& findMissionName(uint32 alias);
//-------------------------------------------------------------------
// group name/alias retreiver
void addGroupInfo(CGroup* grp);
@ -169,19 +169,19 @@ public:
void removeGroupInfo(CGroup* grp, CAliasTreeOwner* grpAliasTreeOwner);
CGroup* findGroup(uint32 alias);
void findGroup(std::vector<CGroup*>& result, std::string const& name);
/// Time warp management. This method is called when time as warped more than 600ms
bool advanceUserTimer(uint32 nbTicks);
bool spawn();
bool despawn();
uint32 getInstanceNumber() const { return _InstanceNumber; }
std::string const& getContinentName() const { return _ContinentName; }
std::string& getContinentName() { return _ContinentName; }
void initInstance(std::string const& continentName, uint32 instanceNumber);
/// Main squad family accessor
COutpostSquadFamily *getSquadFamily() { return _SquadFamily; }
@ -219,7 +219,7 @@ public:
private:
void sendInstanceInfoToEGS();
private:
/// @name AI service hierarchy
//@{
@ -228,16 +228,16 @@ private:
/// the set of managers and the service's root alias description tree node
CAliasCont<CManager> _Managers;
//@}
static NLLIGO::CLigoConfig _LigoConfig;
/// The ai instance continent name (multi ai system)
std::string _ContinentName;
/// The ai instance number (multi ai system)
uint32 _InstanceNumber;
CAIEntity* tryToGetEntity(char const* str);
// we must share pets and players .. later :)
/// pet manager
CMgrPet* _PetManager;
@ -246,9 +246,10 @@ private:
/// event npc Manager.
CMgrNpc* _EventNpcManager;
uint32 _LastGroupAlias;
uint32 _LastSpawnAlias;
uint32 _LastStateAlias;
/// easter egg manager
NLMISC::CRefPtr<CMgrNpc> _EasterEggManager;
@ -257,14 +258,14 @@ private:
/// map of kami groups by alias (for kami groups associated with deposits)
std::map<uint, CGroupNpc*> _KamiDeposits;
/// matrices used for vision generation and their associated iterator tables
CAIEntityMatrix<CPersistentOfPhysical> _PlayerMatrix;
CAIEntityMatrix<CPersistentOfPhysical> _BotMatrix;
// Mission name to alias container.
std::map<std::string, std::vector<uint32> > _MissionToAlias;
/// Group name and alias container.
std::map<std::string, std::vector<NLMISC::CDbgPtr<CGroup> > > _GroupFromNames;
std::map<uint32, NLMISC::CDbgPtr<CGroup> > _GroupFromAlias;

@ -3926,7 +3926,21 @@ void CGrpProfileFaction::checkTargetsAround()
const uint32 playerRadius=assistPlayers||attackPlayers?thisGrpNpc._AggroRange:0;
const uint32 botRadius=assistBots||attackBots?thisGrpNpc._AggroRange:0;
Vision.updateBotsAndPlayers(thisGrpNpc.getAIInstance(), centerPos, playerRadius, botRadius);
CCont<CBot >::iterator itBot=_Grp->bots().begin();
uint32 cellValue = 0;
CBot* bot = *itBot;
if (bot)
{
CSpawnBot* spawnBot = bot->getSpawnObj();
if (spawnBot)
{
CMirrorPropValueRO<uint32> cell( TheDataset, spawnBot->dataSetRow(), DSPropertyCELL );
cellValue = cell();
} else
nlinfo("BOT NOT SPAWN TO GET CELL");
}
Vision.updateBotsAndPlayers(thisGrpNpc.getAIInstance(), centerPos, playerRadius, botRadius, cellValue);
}
// Assist players
@ -4046,7 +4060,7 @@ void CGrpProfileFaction::checkTargetsAround()
void CGrpProfileFaction::updateProfile(uint ticksSinceLastUpdate)
{
checkTargetsAround ();
checkTargetsAround();
CGrpProfileNormal::updateProfile(ticksSinceLastUpdate);
}

@ -53,12 +53,12 @@ public:
{}
virtual ~CAIVision() {}
template <class VectorClass>
void updateBotsAndPlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters,uint32 botRadiusInMeters)
template <class VectorClass>
void updateBotsAndPlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters,uint32 botRadiusInMeters, uint32 cell=0)
{
// _lastUpdate=CTimeInterface::gameCycle();
updatePlayers(aii, xy, playerRadiusInMeters);
updateBots(aii, xy, botRadiusInMeters);
updatePlayers(aii, xy, playerRadiusInMeters, cell);
updateBots(aii, xy, botRadiusInMeters, cell);
}
void clear ()
@ -85,7 +85,7 @@ public:
{
public:
iterator(): _vect(NULL), _vision(NULL) {}
iterator(const CAIVision *vision): _vision(vision)
iterator(const CAIVision *vision): _vision(vision)
{
if (!vision->players().empty())
{
@ -116,7 +116,7 @@ public:
#endif
const NLMISC::CDbgPtr<T> &dbgRef=*_it;
T* objPtr=(T*)dbgRef;
return objPtr;
}
iterator operator++()
@ -156,17 +156,17 @@ public:
private:
const CAIVision *_vision;
const std::vector<NLMISC::CDbgPtr<T> > *_vect;
const std::vector<NLMISC::CDbgPtr<T> > *_vect;
typename std::vector<NLMISC::CDbgPtr<T> >::const_iterator _it;
};
//----------------------------------------------------------------------
// stl-like begin() and end()
iterator begin()
iterator begin()
{
return iterator(this);
}
iterator end()
iterator end()
{
return iterator();
}
@ -190,17 +190,17 @@ private:
template <class VectorClass>
void updateBots(CAIInstance *aii, const VectorClass &xy,uint32 botRadiusInMeters)
template <class VectorClass>
void updateBots(CAIInstance *aii, const VectorClass &xy, uint32 botRadiusInMeters, uint32 cell)
{
H_AUTO(VisionUpdateBots);
_botsVisionCenter = xy;
_botsVisionRadius = botRadiusInMeters;
const CAIEntityMatrixIteratorTblLinear *tbl;
typename CAIEntityMatrix<T>::CEntityIteratorLinear it;
_bots.clear();
if (botRadiusInMeters==0)
return;
@ -211,24 +211,26 @@ private:
for (it = aii->botMatrix().beginEntities(tbl,xy); !it.end(); ++it)
{
CAIEntityPhysical const* phys = const_cast<T*>(&*it)->getSpawnObj();
if (phys && phys->aipos().quickDistTo(aiVectorXy) < botRadiusInMeters)
CMirrorPropValueRO<uint32> botCell( TheDataset, phys->dataSetRow(), DSPropertyCELL );
if ((cell >= 0 || botCell() == cell) && phys && phys->aipos().quickDistTo(aiVectorXy) < botRadiusInMeters)
{
_bots.push_back(const_cast<T*>(&*it));
}
}
}
template <class VectorClass>
void updatePlayers(CAIInstance *aii, const VectorClass &xy,uint32 playerRadiusInMeters)
template <class VectorClass>
void updatePlayers(CAIInstance *aii, const VectorClass &xy, uint32 playerRadiusInMeters, uint32 cell = 0)
{
H_AUTO(VisionUpdatePlayers);
_playersVisionCenter = xy;
_playersVisionRadius = playerRadiusInMeters;
const CAIEntityMatrixIteratorTblLinear *tbl;
typename CAIEntityMatrix<T>::CEntityIteratorLinear it;
_players.clear();
if (playerRadiusInMeters==0)
return;
@ -238,16 +240,14 @@ private:
for (it = aii->playerMatrix().beginEntities(tbl,xy); !it.end(); ++it)
{
CAIEntityPhysical const* phys = const_cast<T*>(&*it)->getSpawnObj();
CMirrorPropValueRO<uint32> cell( TheDataset, phys->dataSetRow(), DSPropertyCELL );
if (phys && phys->aipos().quickDistTo(aiVectorXy) < playerRadiusInMeters)
CMirrorPropValueRO<uint32> botCell( TheDataset, phys->dataSetRow(), DSPropertyCELL );
if ((cell >= 0 || botCell() == cell) && phys && phys->aipos().quickDistTo(aiVectorXy) < playerRadiusInMeters)
{
_players.push_back(const_cast<T*>(&*it));
}
}
}
//----------------------------------------------------------------------
// private data

@ -88,7 +88,7 @@ class CCharacterBotChatBeginEndReceiver: public CCharacterBotChatBeginEnd
for (uint i=0;i<BotChatStart.size();i+=2)
CAIS::instance().beginBotChat(BotChatStart[i+1],BotChatStart[i]);
}
// terminate ended bot chats
{
for (uint i=0;i<BotChatEnd.size();i+=2)
@ -155,7 +155,7 @@ extern void cbSpawnEasterEgg( NLNET::CMessage& msgin, const std::string &service
extern void cbDespawnEasterEgg( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId );
TUnifiedCallbackItem CbArray[] =
TUnifiedCallbackItem CbArray[] =
{
{ "ADDED_ENTITIES", cbAddEntities, },
{ "SRC_SPWN_VLD", cbValidateSourceSpawn },
@ -273,7 +273,7 @@ public:
virtual void doOperation()
{
nldebug("Tick %u, CTaskRingGoLive2 (Spawn) session %u instance %u %u", getTime(), _SessionId.asInt(), _AiInstance, _IsBase);
CAIActions::IExecutor* executer;
executer = CAIActions::getExecuter();
@ -284,11 +284,11 @@ public:
dataRec.init(&Pdr);
dataRec.applyToExecutor(*executer);
{
{
std::string cmd = toString("spawnManagers r2.%04d.%s", _SessionId.asInt(), _IsBase?"base":"act");
ICommand::execute(cmd, *InfoLog);
}
{
{
std::string cmd = toString("spawnManagers r2.%04d.%s", _SessionId.asInt(), _IsBase?"base.zone_trigger":"act.zone_trigger");
ICommand::execute(cmd, *InfoLog);
}
@ -300,7 +300,7 @@ public:
private:
uint32 _AiInstance;
TSessionId _SessionId;
bool _IsBase;
bool _IsBase;
};
@ -309,12 +309,12 @@ private:
static void cbR2GoLive( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
{
TSessionId sessionId;
uint32 aiInstance;
bool isBase;
uint32 size;
msgin.serial(sessionId);
msgin.serial(aiInstance);
msgin.serial(isBase);
@ -322,7 +322,7 @@ static void cbR2GoLive( NLNET::CMessage& msgin, const std::string &serviceName,
if (size != 0)
{
// case where we want to start an instance but (at start of an edition session) but animation not started
uint32 tick = CTimeInterface::gameCycle();
CTaskRingGoLive1* task1 = new CTaskRingGoLive1( aiInstance, isBase);
CTaskRingGoLive2* task2 = new CTaskRingGoLive2( sessionId, aiInstance, isBase);
@ -330,15 +330,15 @@ static void cbR2GoLive( NLNET::CMessage& msgin, const std::string &serviceName,
uint8* buffer = new uint8[size];
msgin.serialBuffer(buffer, size);
msgin.serialBuffer(buffer, size);
task2->Pdr.fromBuffer((const char*)buffer, size);
delete [] buffer;
CAIS::instance().addTickedTask(tick + 1,task1);
CAIS::instance().addTickedTask(tick + 2, task2);
}
if( isBase )
@ -349,7 +349,7 @@ static void cbR2GoLive( NLNET::CMessage& msgin, const std::string &serviceName,
CUnifiedNetwork::getInstance()->send("DSS",msgout);
nlinfo( "R2An: ack sent to DSS for anim session %u", aiInstance );
}
return;
}
@ -367,7 +367,7 @@ public:
{
ICommand::execute(toString("createDynamicAIInstance %d", _AiInstance), *InfoLog);
// load a primitiv.binprim from DSS
//ICommand::execute(toString("despawnManagers %s", isBase?"base":"act"), *InfoLog);
ICommand::execute(toString("unloadPrimitiveFile \"r2.%04d.act.primitive\"", _AiInstance), *InfoLog);
@ -385,7 +385,7 @@ public:
private:
uint32 _AiInstance;
bool _IsBase;
bool _IsBase;
};
static void cbR2StopLive( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
@ -397,7 +397,7 @@ static void cbR2StopLive( NLNET::CMessage& msgin, const std::string &serviceName
msgin.serial(isBase);
uint32 tick = CTimeInterface::gameCycle();
CTask<uint32>* task1 = new CTaskR2StopLive( aiInstance, isBase);
CTask<uint32>* task1 = new CTaskR2StopLive( aiInstance, isBase);
CAIS::instance().addTickedTask(tick ,task1);
}
@ -425,15 +425,15 @@ private:
};
static void cbR2StartInstance( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
{
{
uint32 aiInstance;
msgin.serial(aiInstance);
msgin.serial(aiInstance);
uint32 tick = CTimeInterface::gameCycle();
CTask<uint32>* task1 = new CTaskR2StartInstance( aiInstance);
CTask<uint32>* task1 = new CTaskR2StartInstance( aiInstance);
CAIS::instance().addTickedTask(tick ,task1);
}
//--------------------------------------------------------------------------
@ -492,7 +492,7 @@ void cbValidateSourceSpawn( NLNET::CMessage& msgin, const std::string &serviceNa
if ( canSpawnHere && (wPos.getFlags() & (RYAI_MAP_CRUNCH::Water | RYAI_MAP_CRUNCH::Interior)) )
canSpawnHere = false;
//continue;
msgout.fastWrite( canSpawnHere );
// TODO: Browse the possible surfaces for the position (x,y), then keep only the one(s)
@ -569,7 +569,7 @@ void CMsgAIOpenMgrs::callback (const std::string &serviceName, uint8 sid)
// failed to identify type so give up
nlwarning("Failed to translate '%s' into a known type - request to open manager %04d (%s) ignored",
Type[i].c_str(),MgrId[i],Name[i].c_str());
std::string msgStr("Failed to open "+Name[i]+" due to bad type: '"+Type[i]+"'");
std::string msgStr("Failed to open "+Name[i]+" due to bad type: '"+Type[i]+"'");
CMsgAIFeedback(msgStr).send("AIDS");
}
}
@ -657,17 +657,17 @@ void CMessages::init()
TRANSPORT_CLASS_REGISTER( CHandledAIGroupDespawnedMsg );
TRANSPORT_CLASS_REGISTER( CGiveItemRequestMsg );
TRANSPORT_CLASS_REGISTER( CReceiveItemRequestMsg );
// Classes used for comms between AI and EGS
TRANSPORT_CLASS_REGISTER (CPetSpawnMsgImp);
TRANSPORT_CLASS_REGISTER (CPetSpawnConfirmationMsg);
TRANSPORT_CLASS_REGISTER (CPetCommandMsgImp);
TRANSPORT_CLASS_REGISTER (CPetCommandConfirmationMsg);
TRANSPORT_CLASS_REGISTER (CBSAIDeathReport);
TRANSPORT_CLASS_REGISTER (CCAisActionMsg);
TRANSPORT_CLASS_REGISTER (CEGSExecutePhraseMsg);
TRANSPORT_CLASS_REGISTER (CEGSExecuteAiActionMsg);
@ -708,7 +708,7 @@ void CMessages::init()
TRANSPORT_CLASS_REGISTER (CChangeCreatureHPMsg);
TRANSPORT_CLASS_REGISTER (CChangeCreatureModeMsgImp);
TRANSPORT_CLASS_REGISTER (CQueryEgs);
// setup the callback array
CUnifiedNetwork::getInstance()->addCallbackArray( CbArray, sizeof(CbArray)/sizeof(CbArray[0]) );
@ -732,7 +732,7 @@ void CEnableAggroOnPlayerImp::callback (const std::string &name, NLNET::TService
{
nlwarning("CEnableAggroOnPlayerImp::callback: unknow entity %s on this AIS !", EntityRowId.toString().c_str());
}
return;
}
@ -794,7 +794,7 @@ void CChangeActionFlagMsgImp::callback (const std::string &name, NLNET::TService
{
const uint32 size = (uint32)Entities.size();
nlassert( size == ActionFlags.size() && size == Values.size());
for (uint32 i = 0 ; i < size ; ++i)
{
CAIEntityPhysical *const phys=CAIS::instance().getEntityPhysical(Entities[i]);
@ -825,7 +825,7 @@ void CChangeCreatureModeMsgImp::callback (const std::string &name, NLNET::TServi
//{
//public:
// TDataSetRow EntityRowId;
//
//
// virtual void description ()
// {
// className ("CAIAskForInfosOnEntityMsg");
@ -842,7 +842,7 @@ void CChangeCreatureModeMsgImp::callback (const std::string &name, NLNET::TServi
//public:
// TDataSetRow EntityRowId;
// std::vector<std::string> Infos;
//
//
// virtual void description ()
// {
// className ("CAIInfosOnEntityMsg");
@ -972,7 +972,7 @@ void CBSAIDeathReport::callback(const std::string &name, NLNET::TServiceId id)
}
}
switch(phys->getRyzomType())
{
case RYZOMID::npc:
@ -982,10 +982,10 @@ void CBSAIDeathReport::callback(const std::string &name, NLNET::TServiceId id)
const CMgrNpc &mgr = spawnGrp.getPersistent().mgr();
spawnGrp.addBotToDespawnAndRespawnTime (&(sb->getPersistent()), spawnGrp.getPersistent().despawnTime(), spawnGrp.getPersistent().respawnTime());
if (spawnGrp.getPersistent().getSquadLeader(false)==&sb->getPersistent())
spawnGrp.getPersistent().processStateEvent(mgr.EventSquadLeaderKilled);
CBotNpc* bot = NLMISC::safe_cast<CBotNpc*>(&(sb->getPersistent()));
spawnGrp.botHaveDied (bot);
@ -996,7 +996,7 @@ void CBSAIDeathReport::callback(const std::string &name, NLNET::TServiceId id)
{
nlinfo("NPC: TRIGGER EVENT BOT KILLED");
}
spawnGrp.getPersistent().processStateEvent(mgr.EventBotKilled);
std::string eventGroupKilled;
@ -1020,7 +1020,7 @@ void CBSAIDeathReport::callback(const std::string &name, NLNET::TServiceId id)
std::vector<TDataSetRow> playerAggroable;
for (; aggroIt != aggroEnd; ++aggroIt)
{
{
if (CMirrors::getEntityId(aggroIt->first).getType() != RYZOMID::player)
continue;
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(aggroIt->first);
@ -1033,7 +1033,7 @@ void CBSAIDeathReport::callback(const std::string &name, NLNET::TServiceId id)
continue;
playerAggroable.push_back(aggroIt->first);
}
NLNET::CMessage msgout("TRIGGER_WEBIG");
if (!eventBotKilled.empty())
msgout.serial(eventBotKilled);
@ -1107,7 +1107,7 @@ void CAITauntImp::callback (const std::string &name, NLNET::TServiceId id)
if (!aggroOwner)
return;
aggroOwner->maximizeAggroFor(PlayerRowId);
}
@ -1145,7 +1145,7 @@ void sAggroLost(TDataSetRow playerBot, TDataSetRow targetBot)
void sAggroGain(TDataSetRow playerBot, TDataSetRow targetBot)
{
CAIEntityPhysical *entity=CAIS::instance().getEntityPhysical(playerBot); // necessary ?
CAIEntityPhysical *entity=CAIS::instance().getEntityPhysical(playerBot);
if ( !entity
|| CMirrors::getEntityId(playerBot).getType()!=RYZOMID::player)
return;
@ -1153,6 +1153,9 @@ void sAggroGain(TDataSetRow playerBot, TDataSetRow targetBot)
CAIGainAggroMsg msg(targetBot, playerBot, false);
msg.send("EGS");
if (entity->getActionFlags() & RYZOMACTIONFLAGS::InWater)
return;
CAIEntityPhysical *botEntity = CAIEntityPhysicalLocator::getInstance()->getEntity(targetBot);
CSpawnBotNpc* bot = dynamic_cast<CSpawnBotNpc*>(botEntity);
if (bot && bot->getPersistent().getOwner()) {
@ -1170,7 +1173,7 @@ void sAggroGain(TDataSetRow playerBot, TDataSetRow targetBot)
CBot* bot = *itBot;
CSpawnBot *const sp = bot->getSpawnObj();
if (sp && sp->isAlive())
{
{
CAIGainAggroMsg msg(sp->dataSetRow(), playerBot, true);
msg.send("EGS");
}

@ -41,13 +41,13 @@ CAIState const* CStateInstance::getActiveState() const
if (!this)
return NULL; // ugly! -> to remove date = 19/05/2004.
#endif
if (_PunctualState) // the puntual state is active !
return _PunctualState;
if (_state) // the normal state is active !
return _state;
// no state is active !
return NULL;
}
@ -110,7 +110,7 @@ void CStateInstance::callScriptCallBack(IScriptContext* caller, TStringId const&
AIVM::CByteCodeEntry const* const codeScript = getScriptCallBackPtr(funcName);
if (!codeScript || !codeScript->isValid())
return;
interpretCode(caller, *codeScript); // effectively calls the call back.
}
@ -153,15 +153,15 @@ void CStateInstance::dumpVarsAndFunctions(CStringWriter& sw) const
sw.append("float variables:");
FOREACHC(varIt, TLogicVarList, _LogicVar)
sw.append(" "+CStringMapper::unmap(varIt->first)+" = "+NLMISC::toString(varIt->second));
sw.append("string variables:");
FOREACHC(varIt, TStrLogicVarList, _StrLogicVar)
sw.append(" "+CStringMapper::unmap(varIt->first)+" = "+varIt->second);
sw.append("context variables:");
FOREACHC(varIt, TCtxLogicVarList, _CtxLogicVar)
sw.append(" "+CStringMapper::unmap(varIt->first)+" = "+NLMISC::toStringPtr(varIt->second));
sw.append("callBacks:");
FOREACHC(varIt, TCallBackList, _CallBacks)
sw.append(" "+CStringMapper::unmap(varIt->first));
@ -183,7 +183,7 @@ void CStateInstance::interpretCodeOnChildren(CByteCodeEntry const& codeScriptEnt
vector<CSmartPtr<CGroup> > tmpList;
FOREACH(childIt, CPersistentStateInstance::TChildList, getPersistentStateInstance()->childs())
tmpList.push_back((*childIt)->getGroup());
FOREACH(childIt, vector<CSmartPtr<CGroup> >, tmpList)
(*childIt)->getPersistentStateInstance()->interpretCode(this, codeScriptEntry);
}
@ -195,7 +195,7 @@ IScriptContext* CStateInstance::findContext(NLMISC::TStringId const strId)
#endif
std::vector<CGroup*> grps;
this->getGroup()->getAIInstance()->findGroup(grps, CStringMapper::unmap(strId));
if (grps.size()==1)
if (grps.size() >= 1)
return grps.back()->getPersistentStateInstance();
else
return NULL;
@ -213,7 +213,7 @@ void CStateInstance::init(CAIState* startState)
_state=
_PunctualState=
_NextPunctualState=NULL;
_CancelPunctualState = false;
_NextState = startState;
_LogicVarChanged = false;
@ -244,12 +244,12 @@ void CStateInstance::setGlobalNelVar(std::string const& varId, std::string value
void CStateInstance::blockUserEvent(uint32 eventId)
{
_UserEventBlocked |= (1 << eventId);
_UserEventBlocked |= (1 << eventId);
}
void CStateInstance::unblockUserEvent(uint32 eventId)
{
_UserEventBlocked &= ~(1 << eventId);
_UserEventBlocked &= ~(1 << eventId);
}
bool CStateInstance::isUserEventBlocked(uint32 eventId) const
@ -264,15 +264,15 @@ bool CStateInstance::isUserEventBlocked(uint32 eventId) const
void CPersistentStateInstance::updateStateInstance()
{
// deal with timer events -----------------------------------------
// Event: State Timeout
if (_StateTimeout.testOnce())
processStateEvent(getEventContainer().EventPositionalStateTimeout);
// Event: Punctual State Timeout
if (_PunctualStateTimeout.testOnce())
processStateEvent(getEventContainer().EventPunctualStateTimeout);
// Event: User Timer n Triggered
for (uint i=0;i<4;++i)
{
@ -280,7 +280,7 @@ void CPersistentStateInstance::updateStateInstance()
continue;
processStateEvent(getEventContainer().EventUserTimer[i]);
}
// Event logic var changed
@ -297,9 +297,9 @@ void CPersistentStateInstance::updateStateInstance()
}
_LogicVarChanged = false;
}
// deal with positional state change ------------------------------
// if state change requested (and not in punctual state) then setup new state
if (_NextState)
{
@ -310,27 +310,27 @@ void CPersistentStateInstance::updateStateInstance()
oldState = _state;
processStateEvent(getEventContainer().EventEndOfState);
}
// switch state & initalise state status flags
_state = _NextState;
_NextState = NULL;
_StateTimeout.disable();
if (_PunctualState || _NextPunctualState)
return;
removeExceptForState(_state);
processStateEvent(getEventContainer().EventStartOfState);
stateChange(oldState, _state);
}
// deal with start of punctual state ------------------------------
// if state change requested then setup new state
if (_NextPunctualState)
{
CAIState const* oldState = NULL;
breakable
{
if (_PunctualState)
@ -344,21 +344,21 @@ void CPersistentStateInstance::updateStateInstance()
break;
}
}
// switch state & initalize state status flags
_PunctualState = _NextPunctualState;
_NextPunctualState = NULL;
_CancelPunctualState = false;
_PunctualStateTimeout.disable();
// initalize new state
CAIState const* const newState = _PunctualState;
removeExceptForState(newState);
processStateEvent(getEventContainer().EventStartOfState, newState);
stateChange(oldState, newState);
}
// must be done after start of state
if (_FirstBotSpawned)
{
@ -366,29 +366,29 @@ void CPersistentStateInstance::updateStateInstance()
processStateEvent(getEventContainer().EventFirstBotSpawned);
}
// deal with end of punctual state --------------------------------
if (!_CancelPunctualState)
return;
_CancelPunctualState = false;
// if there was an active punctual state then cancel it
if (!_PunctualState)
return;
// switch state & initalise state status flags
_PunctualStateTimeout.disable();
_StateTimeout.resume(); // this line just in case timeout suspended during punctual state
// close down current state
CAIState const* const punctualState = _PunctualState;
processStateEvent(getEventContainer().EventEndOfState, punctualState);
_PunctualState = NULL;
// this removes obj that depends on state affectation existence.
removeExceptForState(_state);
// specialized virtual state change call.
stateChange(punctualState, _state);
}

@ -770,7 +770,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr )
string usedlang = senderLang;
if (EnableDeepL && !senderClient.dontSendTranslation(senderLang))
if (EnableDeepL)
{
chatType = "dynamic";
if (ucstr[0] == '>') // Sent directly when prefixed by '>', it's the anti-translation code
@ -790,7 +790,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr )
source_lang = mongoText.substr(6, 2);
string sourceText = mongoText.substr(9, endOfOriginal-9);
strFindReplace(sourceText, ")", "}");
mongoText = "["+source_lang+"](http://chat.ryzom.com/channel/pub-universe-"+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4);
mongoText = "["+source_lang+"](http://chat.ryzom.com/channel/pub-uni-"+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4);
}
else
{
@ -813,6 +813,11 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr )
chatInGroup( grpId, ucstr.substr(1), sender );
}
else if (senderClient.dontSendTranslation(senderLang))
{
sendToAllUni = true;
chatInGroup( grpId, ucstr, sender );
}
else
{
_Log.displayNL("%s|%s|*|%s-*|%s", "universe", fullName.c_str(), senderLang.c_str(), ucstr.toUtf8().c_str());
@ -1034,7 +1039,7 @@ void CChatManager::chat( const TDataSetRow& sender, const ucstring& ucstr )
if (haveOriginMessage) // Only send untranslated message
canSendChat = false;
}
else if (!translatedLang.empty() && translatedLang != SM->getLanguageCodeString(co->Language))
else if (!translatedLang.empty() && co && translatedLang != SM->getLanguageCodeString(co->Language))
canSendChat = false;
}
@ -1157,7 +1162,7 @@ void CChatManager::chatInGroup( TGroupId& grpId, const ucstring& ucstr, const TD
if (!areOriginal)
continue;
}
else if (usedlang != SM->getLanguageCodeString(co->Language))
else if (co == NULL || usedlang != SM->getLanguageCodeString(co->Language))
continue;
}
@ -1921,6 +1926,7 @@ void CChatManager::sendFarChat(const string &name, const ucstring& ucstr, const
{
string usedlang = "";
string source_lang = "";
string mongoText = ucstr.toUtf8();
string::size_type endOfOriginal = mongoText.find("}@{");
@ -1940,15 +1946,17 @@ void CChatManager::sendFarChat(const string &name, const ucstring& ucstr, const
else if (chan == "universe")
{
chatId = "FACTION_"+toUpper(usedlang);
rc_channel = "pub-universe-";
rc_channel = "pub-uni-";
}
string source_lang = usedlang;
if (endOfOriginal != string::npos)
{
if (mongoText.size() > 9)
source_lang = mongoText.substr(6, 2);
else
source_lang = usedlang;
string sourceText = mongoText.substr(9, endOfOriginal-9);
strFindReplace(sourceText, ")", "}");
mongoText = "["+source_lang+"](http://chat.ryzom.com/channel/"+rc_channel+source_lang+"? "+sourceText+") "+mongoText.substr(endOfOriginal+4, mongoText.size()-endOfOriginal-4);
@ -1985,7 +1993,7 @@ void CChatManager::sendFarChat(const string &name, const ucstring& ucstr, const
NLMISC::CEntityId receiverId = TheDataset.getEntityId(dcc->getClient()->getID());
CCharacterInfos* co = IOS->getCharInfos(receiverId);
if (!EnableDeepL || usedlang.empty() || usedlang == SM->getLanguageCodeString(co->Language))
if (!EnableDeepL || usedlang.empty() || (co != NULL && usedlang == SM->getLanguageCodeString(co->Language)))
sendFarChat((CChatGroup::TGroupType)12, dcc->getClient()->getID(), ucstr.substr(startPos), ucstring("~")+ucstring(name), *chanId);
dcc = dcc->getNextChannelSession(); // next session in this channel
}

Loading…
Cancel
Save