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

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

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

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

@ -3926,7 +3926,21 @@ void CGrpProfileFaction::checkTargetsAround()
const uint32 playerRadius=assistPlayers||attackPlayers?thisGrpNpc._AggroRange:0; const uint32 playerRadius=assistPlayers||attackPlayers?thisGrpNpc._AggroRange:0;
const uint32 botRadius=assistBots||attackBots?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 // Assist players
@ -4046,7 +4060,7 @@ void CGrpProfileFaction::checkTargetsAround()
void CGrpProfileFaction::updateProfile(uint ticksSinceLastUpdate) void CGrpProfileFaction::updateProfile(uint ticksSinceLastUpdate)
{ {
checkTargetsAround (); checkTargetsAround();
CGrpProfileNormal::updateProfile(ticksSinceLastUpdate); CGrpProfileNormal::updateProfile(ticksSinceLastUpdate);
} }

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

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

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

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

Loading…
Cancel
Save