Merge branch 'new_features'

feature/prepare-cross-merge
Nuno 4 years ago committed by kaetemi
parent 1c57ac7b8f
commit 796582e235
No known key found for this signature in database
GPG Key ID: 9873C4D40BB479BC

@ -63,6 +63,7 @@ public:
void aggroGain(TDataSetRow const& aggroBot) const { }
virtual void spawnBots() = 0;
virtual void spawnBots(const std::string &name) = 0;
virtual void despawnBots(bool immediately) = 0;
virtual void update() = 0;

@ -546,6 +546,11 @@ void CSpawnGroupFauna::spawnBots()
_Timer.set(getPersistent().timer(CGrpFauna::SPAWN_TIME));
}
void CSpawnGroupFauna::spawnBots(const std::string &name)
{
}
void CSpawnGroupFauna::despawnBots(bool immediately)
{
setDespawnImmediately(immediately);

@ -28,7 +28,7 @@
#include "ai_generic_fight.h"
class CGrpFauna;
class CGrpFauna;
class CSpawnGroupFauna;
#define GROUP_VISION_UPDATE_RADIUS (80)
@ -53,14 +53,14 @@ public:
StateWandering,
StateResting
};
public:
CSpawnGroupFauna(CPersistent<CSpawnGroup>& owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlag);
bool isSpawning();
void update();
/// @name CFightOrganizer implementation
//@{
virtual void setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy);
@ -69,84 +69,85 @@ public:
virtual void setFlee(CSpawnBot* bot, CAIVector& fleeVect);
virtual void setReturnAfterFight(CSpawnBot* bot);
//@}
virtual void spawnBots();
virtual void spawnBots(const std::string &name);
virtual void despawnBots(bool immediately);
// overrides the init to avoid automatic bot spawn ..
void spawnBotOfGroup() { }
virtual void despawnGrp(); // critical code (despawn 'this' object).
uint32 getLastUpdate() const { return _LastUpdate; }
// Update Rate feature.
int getUpdatePriority() const { return IsRingShard? (_UpdatePriority&7): _UpdatePriority; }
// overloading to recalc the priority update rate.
void recalcUpdatePriorityDeltaAndGroupPos();
CAIPos const& magnetPos() const;
float magnetRadiusNear() const;
float magnetRadiusFar() const;
void resetTimer() { _Timer.set(0); }
CGrpFauna& getPersistent();
// std::string buildDebugString(uint idx) const;
void setPlace(int placeIndex);
void incCurrentCycle();
void setCurrentCycle(uint32 cycle);
uint32 getCurrentCycleTime();
CAIPlace* targetPlace() const { return _TargetPlace; }
CPathCont& getPathCont() { return _PathCont; }
CBotFauna* leader() const { return _Leader; }
void setDespawnImmediately(bool immediately) { _DespawnImmediately = immediately; }
bool despawnImmediately() { return _DespawnImmediately; }
void setMustDespawnBots(bool toDespawnBots = true) { _MustDespawnBots=toDespawnBots; }
bool mustDespawnBots() { return _MustDespawnBots; }
private:
uint32 getDt() const { return _DeltaTime; }
CBotFauna* findLeader();
CBotFauna* findLeader();
// Behavior update method.
void generalUpdate(TState state = StateUndefined);
// Update method for different states.
void updateSpawning();
void updateActivity(AITYPES::TProfiles activity);
void checkTimers(); // called at each update to see if the last timer delay has expired (if true calls updateCycles)
private:
CPathCont _PathCont;
NLMISC::CDbgPtr<CAIPlace> _TargetPlace; // a dynamic pointer to one of the above places
bool _ArrivedInZone; // indicates that we have not reach the new zone
NLMISC::CDbgPtr<CBotFauna> _Leader; // the individual in the group who is treated as the leader
CAITimer _Timer;
uint32 _CurrentCycle;
int _UpdatePriority;
uint32 _LastUpdate; // gamecycle at which update() last called
uint32 _DeltaTime; // Dt, simply
bool _MustDespawnBots; // if its a day group and its night for instance.
bool _DespawnImmediately; // when MustdespawnBots, indicate if we must done it immedialtely or at best when no player can see it
};
@ -189,7 +190,7 @@ public:
TPlaces _Place;
uint32 _NextCycle;
};
class Cycle
{
public:
@ -201,104 +202,104 @@ public:
}
std::vector<uint16> _PopList;
};
public:
CGrpFauna(CMgrFauna* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MAP_CRUNCH::TAStarFlag denyFlags);
virtual ~CGrpFauna();
RYZOMID::TTypeId getRyzomType() { return RYZOMID::creature; }
CDynGrpBase* getGrpDynBase() { return this; }
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// PersistentStateInstance
CAliasTreeOwner* aliasTreeOwner() { return this; }
CAIS::CCounter& getSpawnCounter();
bool timeAllowSpawn(uint32 popVersion = 12345) const;
void stateChange(CAIState const* oldState, CAIState const* newState);
CGroup* getGroup() { return this; }
//////////////////////////////////////////////////////////////////////////
virtual void lastBotDespawned();
virtual void firstBotSpawned();
// debugging stuff
CDebugHistory* getDebugHistory() { return this; }
CPersistentStateInstance* getPersistentStateInstance() { return this; }
virtual void setEvent(uint eventId);
virtual void serviceEvent (const CServiceEvent &info);
virtual std::string getFullName() const { return CGroup::getFullName(); }
virtual std::string getIndexString() const { return CGroup::getIndexString(); }
IAliasCont* getAliasCont(AITYPES::TAIType type);
CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree);
NLMISC::CSmartPtr<CSpawnGroup> createSpawnGroup();
CSpawnGroupFauna* getSpawnObj() const { return NLMISC::type_cast<CSpawnGroupFauna*>(CGroup::getSpawnObj()); }
void allocateBots();
// This struct is used to manage dead creatures and their corresponding respawned creature.
// inheritted virtual interface ------------------------------------
virtual bool spawn();
bool spawnPop(uint popVersion);
virtual void despawnGrp();
// Methods for setting up static data ------------------------------
void setType(AITYPES::TFaunaType type);
void setCyles(std::string const& cycles);
// Methods for manageing population descriptions
void setPopulation(CPopulation *pop);
// Methods for managing places
void setPlace(CAIPlace*& variable, CAIPlace* place);
void setupWanderPlace();
// Miscelaneous accessors ------------------------------------------
CMgrFauna& mgr() const;
// reference timer value
static uint32 refTimer(TTime time);
uint32 timer(TTime time) const { return _Timer[time]; }
void setTimer(TTime timer, uint32 time) { _Timer[timer] = time*10; } ///< we set time in seconds.
AITYPES::TFaunaType getType() const { return _Type; }
void setSpawnType(AITYPES::TSpawnType sp_type) { _SpawnType = sp_type; }
void displayPlaces(CStringWriter& stringWriter) const;
CAliasCont<CAIPlace>& places() { return _Places; }
CAliasCont<CPopulation>& populations() { return _Populations; }
AITYPES::CPropertySet& faction() { return _Faction; }
static const CCycleDef cycles[];
static const uint32 nbCycle;
void setAutoSpawn(bool autoSpawn) { CGroup::setAutoSpawn(autoSpawn); if (!isAutoSpawn()) _CurrentCycle=std::numeric_limits<uint32>::max(); }
/// @name CChild implementation
//@{
virtual std::string getOneLineInfoString() const;
virtual std::vector<std::string> getMultiLineInfoString() const;
//@}
/** Find next valid place with the wanted flags.
* If several places are valid, then one is picked randomly
* If several places are valid, then one is picked randomly
* \return INVALID_PLACE if no such place exist
*/
sint getNextPlace(const CFaunaGenericPlace *startPlace, CAIPlaceXYRFauna::TFlag wantedFlag) const;
@ -309,35 +310,35 @@ public:
public:
// Dynamic data modified during normal activity --------------------
uint32 _CurPopulation; // which alternative bot population is active
protected:
// Static data initilised at init time -----------------------------
// basic data (name, id, pointer to manager, etc)
AITYPES::TFaunaType _Type; // FaunaTypeHerbivore, FaunaTypePredator, ... etc
// Definition of a vector of vectors of classes for populations ----
CAliasCont<CPopulation> _Populations;
CAliasCont<CAIPlace> _Places;
AITYPES::TSpawnType _SpawnType;
CAITimer _priorityRecalcTimer; // timer used to determine time of next recalc of _updateMask
uint32 _Timer[LAST_TIME];
float _Aggro;
/// Animat Addon
double _MotivationGroupProtection; // A value between 0 an 1 giving the importance of the group protection.
double _MotivationHarvestSap; // Motivation for the sap harvest.
std::vector<Cycle> _Cycles; // Cycles List.
uint32 _CurrentCycle; // current Cycle.
sint32 _CurrentCycleIndex; // the pop index in the cycle
AITYPES::CPropertySet _Faction;
};

@ -341,6 +341,57 @@ void CSpawnGroupNpc::stateChange(CAIState const* oldState, CAIState const* newSt
}
}
void CSpawnGroupNpc::spawnBots(const std::string &name)
{
ucstring ucName;
ucName.fromUtf8(name);
FOREACH(itBot, CCont<CBot>, bots())
{
CBot* bot = *itBot;
if (!bot->isSpawned()) {
bot->spawn();
if (!ucName.empty())
{
CSpawnBot *spawnBot = bot->getSpawnObj();
if (spawnBot)
{
TDataSetRow row = spawnBot->dataSetRow();
NLNET::CMessage msgout("CHARACTER_NAME");
msgout.serial(row);
msgout.serial(ucName);
sendMessageViaMirror("IOS", msgout);
spawnBot->getPersistent().setCustomName(ucName);
}
}
if (_Cell < 0) {
CEntityId id = bot->getSpawnObj()->getEntityId();
sint32 x = bot->getSpawnObj()->pos().x();
sint32 y = bot->getSpawnObj()->pos().y();
sint32 z = bot->getSpawnObj()->pos().h();
float t = bot->getSpawnObj()->pos().theta().asRadians();
uint8 cont = 0;
uint8 slide = 1;
NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle() + 1;
CMessage msgout2("ENTITY_TELEPORTATION");
msgout2.serial( id );
msgout2.serial( x );
msgout2.serial( y );
msgout2.serial( z );
msgout2.serial( t );
msgout2.serial( tick );
msgout2.serial( cont );
msgout2.serial( _Cell );
msgout2.serial( slide );
sendMessageViaMirror("GPMS", msgout2);
}
}
}
}
void CSpawnGroupNpc::spawnBots()
{
FOREACH(itBot, CCont<CBot>, bots())
@ -348,6 +399,7 @@ void CSpawnGroupNpc::spawnBots()
CBot* bot = *itBot;
if (!bot->isSpawned()) {
bot->spawn();
if (_Cell < 0) {
CEntityId id = bot->getSpawnObj()->getEntityId();
sint32 x = bot->getSpawnObj()->pos().x();

@ -45,6 +45,7 @@ public:
CGroupNpc& getPersistent() const;
virtual void spawnBots();
virtual void spawnBots(const std::string &name);
virtual void despawnBots(bool immediately);
void update();

@ -33,7 +33,7 @@ class CPetOwner;
class CSpawnGroupPet
: public CSpawnGroup
{
public:
public:
CSpawnGroupPet(CPersistent<CSpawnGroup>& owner)
: CSpawnGroup(owner)
, _PathCont(NLMISC::safe_cast<CGroup*>(&owner)->getAStarFlag())
@ -41,18 +41,19 @@ public:
_LastUpdate = CTimeInterface::gameCycle();
_IsPlayerSpawned = true;
}
CGrpPet& getPersistent() const;
void spawnBots() { }
void spawnBots(const std::string &name) { }
void despawnBots (bool immediately) { }
void update();
CPathCont& getPathCont() { return _PathCont; }
CAIVector const& getPos() const { return _PathCont.getDestination(); }
private:
CPathCont _PathCont; // this path container is share by all player pets .. (thats accelerate our computing).
uint32 _LastUpdate;
@ -68,37 +69,37 @@ class CGrpPet
{
public:
CGrpPet(CMgrPet* mgr, NLMISC::CEntityId const& owner, CAIAliasDescriptionNode* aliasTree = NULL);
CDynGrpBase* getGrpDynBase() { return NULL; }
RYZOMID::TTypeId getRyzomType() { return RYZOMID::pack_animal; }
CAIS::CCounter& getSpawnCounter();
/// @name Service events
//@{
void serviceUp(uint32 serviceId, std::string const& serviceName);
void serviceDown(uint32 serviceId, std::string const& serviceName);
//@}
void init() { }
void release() { }
void setEvent(uint eventId);
NLMISC::CSmartPtr<CSpawnGroup> createSpawnGroup();
CPersistentStateInstance* getPersistentStateInstance();
NLMISC::CEntityId const& getPetOwner() const { return _PetOwner; }
CMgrPet& getPetManager() { return *(NLMISC::safe_cast<CMgrPet*>(getOwner())); }
CCont<CBot>& bots() { return _Bots; }
virtual std::string getOneLineInfoString() const { return std::string("Pet group '") + getName() + "'"; }
private:
NLMISC::CEntityId const _PetOwner;
};

@ -705,61 +705,7 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
grp->clrBotsAreNamedFlag();
//addGroupInfo(grp, name, grp->getAlias());
{
// build unnamed bot
for (uint i=0; i<nbBots; ++i)
{
_LastSpawnAlias++;
nlinfo("Spawn with alias : %d (%s)", _LastSpawnAlias, _LigoConfig.aliasToString(_LastSpawnAlias).c_str());
grp->bots().addChild(new CBotNpc(grp, _LastSpawnAlias, name), i); // Doub: 0 instead of getAlias()+i otherwise aliases are wrong
CBotNpc* const bot = NLMISC::safe_cast<CBotNpc*>(grp->bots()[i]);
bot->setSheet(sheet);
bot->setPrimAlias(900+_InstanceNumber);
if (!look.empty())
bot->setClientSheet(look);
bot->equipmentInit();
bot->initEnergy(/*groupEnergyCoef()*/0);
CAIVector rpos(pos);
if (dispersionRadius == 0)
{
nlinfo("Stucked !");
bot->setStuck(true);
}
float angle = 0.f;
if (orientation < (NLMISC::Pi * 2.0) && orientation > (-NLMISC::Pi * 2.0))
angle = (float)orientation;
else
angle = randomAngle();
// Spawn all randomly except if only 1 bot
if (nbBots > 1 || dispersionRadius > 1)
{
bot->saveFirstPosition(pos, dispersionRadius);
RYAI_MAP_CRUNCH::CWorldMap const& worldMap = CWorldContainer::getWorldMap();
RYAI_MAP_CRUNCH::CWorldPosition wp;
uint32 maxTries = 100;
do
{
rpos = pos;
rpos += randomPos(dispersionRadius);
--maxTries;
}
while (!worldMap.setWorldPosition(AITYPES::vp_auto, wp, rpos) && maxTries>0);
if (maxTries<=0)
rpos = pos;
bot->setStartPos(pos.x().asDouble(), pos.y().asDouble(), angle, AITYPES::vp_auto);
}
else
bot->setStartPos(rpos.x().asDouble(),rpos.y().asDouble(), angle, AITYPES::vp_auto);
}
}
eventCreateNpcBot(grp, nbBots, false, sheetId, pos, "", orientation, dispersionRadius, look);
grp->spawn();
CSpawnGroupNpc* spawnGroup = grp->getSpawnObj();
@ -802,6 +748,71 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
return grp;
}
bool CAIInstance::eventCreateNpcBot(CGroupNpc* grp, uint nbBots, bool spawnBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, const std::string &name, double orientation, double dispersionRadius, const std::string &look)
{
uint32 offset = grp->bots().size();
for (uint i=0; i<nbBots; ++i)
{
_LastSpawnAlias++;
grp->bots().addChild(new CBotNpc(grp, _LastSpawnAlias, grp->getName()), offset+i);
CBotNpc* const bot = NLMISC::safe_cast<CBotNpc*>(grp->bots()[offset+i]);
AISHEETS::ICreatureCPtr sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId);
if (!sheet)
{
nlwarning("invalid sheet while creating event npc group");
return false;
}
bot->setSheet(sheet);
bot->setPrimAlias(900+_InstanceNumber);
if (!look.empty())
bot->setClientSheet(look);
bot->equipmentInit();
bot->initEnergy(/*groupEnergyCoef()*/0);
CAIVector rpos(pos);
if (dispersionRadius == 0)
bot->setStuck(true);
float angle = 0.f;
if (orientation < (NLMISC::Pi * 2.0) && orientation > (-NLMISC::Pi * 2.0))
angle = (float)orientation;
else
angle = randomAngle();
// Spawn all randomly except if only 1 bot
if (nbBots > 1 || dispersionRadius > 1)
{
bot->saveFirstPosition(pos, dispersionRadius);
RYAI_MAP_CRUNCH::CWorldMap const& worldMap = CWorldContainer::getWorldMap();
RYAI_MAP_CRUNCH::CWorldPosition wp;
uint32 maxTries = 100;
do
{
rpos = pos;
rpos += randomPos(dispersionRadius);
--maxTries;
}
while (!worldMap.setWorldPosition(AITYPES::vp_auto, wp, rpos) && maxTries>0);
if (maxTries<=0)
rpos = pos;
bot->setStartPos(pos.x().asDouble(), pos.y().asDouble(), angle, AITYPES::vp_auto);
}
else
bot->setStartPos(rpos.x().asDouble(),rpos.y().asDouble(), angle, AITYPES::vp_auto);
}
if (spawnBots)
grp->getSpawnObj()->spawnBots(name);
return true;
}
CBotEasterEgg* CAIInstance::createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look)
{
if (_EasterEggManager == NULL)

@ -209,6 +209,7 @@ public:
}
CGroupNpc* eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName, const std::string &look, sint32 cell=0);
bool eventCreateNpcBot(CGroupNpc* grp, uint nbBots, bool spawnBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, const std::string &name, double orientation, double dispersionRadius, const std::string &look);
/// create a new easter egg
CBotEasterEgg* createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look);

@ -4229,7 +4229,7 @@ void CBotProfileMoveTo::updateProfile(uint ticksSinceLastUpdate)
{
// get a base pointer to allow virtual call to work
nlwarning("Follow No Path : %s", _Bot->getPersistent().getOneLineInfoString().c_str());
//nlwarning("Follow No Path : %s", _Bot->getPersistent().getOneLineInfoString().c_str());
}
}
}

File diff suppressed because it is too large Load Diff

@ -32,10 +32,10 @@ public:
{
}
virtual ~CStringFilter() { }
bool operator !=(std::string const& other) const { return !operator ==(other); }
bool operator ==(std::string const& other) const { return NLMISC::testWildCard(other, _Filter); }
private:
std::string _Filter;
};
@ -183,6 +183,25 @@ void buildOutpostList(TContainer& container)
}
}
template <class TContainer>
void buildNpcManagerList(TContainer& container)
{
std::deque<CAIInstance*> aiinstances;
buildInstanceList(aiinstances);
FOREACH(itAIInstance, std::deque<CAIInstance*>, aiinstances)
{
CAIInstance* aiinstance = *itAIInstance;
if (aiinstance == NULL)
continue;
CManager* ManagerPtr = CAIS::instance().tryToGetManager("i0:m1");
if (ManagerPtr)
container.push_back(ManagerPtr);
}
}
template <class TContainer>
void buildManagerList(TContainer& container)
{
@ -329,9 +348,9 @@ void buildFaunaPlaceList(TContainer& container)
{
CGrpFauna *grpFauna = dynamic_cast<CGrpFauna *>(*itGroup);
if (!grpFauna)
continue;
continue;
FOREACH(itPlaces, CAliasCont<CAIPlace>, grpFauna->places())
{
{
container.push_back(*itPlaces);
}
}
@ -535,7 +554,7 @@ void despawn(CAIPlace &value)
else
{
nlwarning("Places %s is not time driven, cannot deactivate it", value.getIndexString().c_str());
}
}
}
}

@ -107,6 +107,52 @@ void despawn_f_(CStateInstance* entity, CScriptStack& stack)
grp->despawnBots(immediatly!=0);
}
//----------------------------------------------------------------------------
/** @page code
@subsection spawnBot_fsssffff_
Spawn new bots in the current group.
Arguments: f(NbrBots), s(Sheet), s(Name), s(Look), f(x), f(y), f(orientation), f(dispersion) ->
@code
@endcode
*/
// CGroup
void spawnBot_fsssffff_(CStateInstance* entity, CScriptStack& stack)
{
double dispersionRadius = (double)(float)stack.top();
stack.pop();
double orientation = (double)(float)stack.top();
stack.pop();
double y = (double)(float)stack.top();
stack.pop();
double x = (double)(float)stack.top();
stack.pop();
string look = (string)stack.top();
stack.pop();
string name = (string)stack.top();
stack.pop();
CSheetId sheetId((string)stack.top());
stack.pop();
uint nbBots = (uint)(float)stack.top();
stack.pop();
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
if (!aiInstance)
return;
CGroupNpc* grp = dynamic_cast<CGroupNpc*>(entity->getGroup());
if (grp)
aiInstance->eventCreateNpcBot(grp, nbBots, true, sheetId, CAIVector(x, y), name, orientation, dispersionRadius, look);
return;
}
//----------------------------------------------------------------------------
/** @page code
@ -2426,6 +2472,49 @@ void getPlayerStat_ss_f(CStateInstance* entity, CScriptStack& stack)
}
//----------------------------------------------------------------------------
/** @page code
@subsection getPlayerPosition_ss_ff
Get player position (x or y).
Arguments: s(playerEidAsString), s(statName) -> s(result)
@param[in] playerEidAsString is EntityId as string from the player we want infos
@param[in] axis ("X" or "Y")
@param[out] value is a the value of the parameter
@code
($playerEid)getCurrentPlayerEid();
(x, y)getPlayerPosition($playerEid);
@endcode
*/
void getPlayerPosition_s_ff(CStateInstance* entity, CScriptStack& stack)
{
std::string funName = "getPlayerPosition_s_ff";
// reaed input
std::string statName = ((std::string)stack.top()); stack.pop();
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
// get Dataset of the player to have access to mirror values
NLMISC::CEntityId playerEid;
playerEid.fromString(playerEidStr.c_str());
TDataSetRow playerRow = TheDataset.getDataSetRow( playerEid );
if (! TheDataset.isAccessible( playerRow ) )
{
nlwarning("Try to call %s with on a player '%s' that is not accessible. The isPlayerAlived function must be called to be sure that the palyer is still alived.", funName.c_str(), playerEidStr.c_str() );
stack.push((float)0);
return;
}
CMirrorPropValue<sint32> mirrorSymbol( TheDataset, playerRow, DSPropertyPOSY );
stack.push((float)mirrorSymbol.getValue());
CMirrorPropValue<sint32> mirrorSymbol2( TheDataset, playerRow, DSPropertyPOSX );
stack.push((float)mirrorSymbol2.getValue());
return;
}
/** @page code
@subsection getPlayerDistance_fs_f
@ -4771,6 +4860,7 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, spawn__);
REGISTER_NATIVE_FUNC(functions, despawn_f_);
REGISTER_NATIVE_FUNC(functions, isAlived__f);
REGISTER_NATIVE_FUNC(functions, spawnBot_fsssffff_);
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssfff_c);
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssfff_);
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssff_c);
@ -4858,6 +4948,7 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
// Boss functions (Player infos)
REGISTER_NATIVE_FUNC(functions, isPlayerAlived_s_f);
REGISTER_NATIVE_FUNC(functions, getPlayerStat_ss_f);
REGISTER_NATIVE_FUNC(functions, getPlayerPosition_s_ff);
REGISTER_NATIVE_FUNC(functions, getPlayerDistance_fs_f);
REGISTER_NATIVE_FUNC(functions, getCurrentPlayerEid__s);
REGISTER_NATIVE_FUNC(functions, queryEgs_sscfs_);

@ -2246,7 +2246,7 @@ Arguments: c(group1), s(botname1), c(group2), s(botname2), ->
@code
(@group1)group_name1.context();
(@group1)group_name2.context();
(@group2)group_name2.context();
()facing(@group1, "bob", @group2, "bobette");
@endcode
@ -2642,7 +2642,8 @@ void rename_s_(CStateInstance* entity, CScriptStack& stack)
{
string newName = (string)stack.top(); stack.pop();
ucstring name;
name.fromUtf8(newName); CGroup* group = entity->getGroup();
name.fromUtf8(newName);
CGroup* group = entity->getGroup();
if (group->isSpawned())
{

@ -1047,6 +1047,74 @@ string getJewelEnchantAttr(CSheetId sbrick)
//enchantEquipedItem 530162 WristR jmod_focus_tryker_1.sbrick
//enchantEquipedItem 530162 Neck tag_fyros_3.sbrick
//enchantEquipedItem 530162 Neck jrez_fulllife_tryker.sbrick,jboost2.sbrick
//----------------------------------------------------------------------------
NLMISC_COMMAND(checkInventoryItems, "Check items from a characters inventory", "<uid> <inventory> <sheetnames> <quality> <quantity>")
{
if (args.size () < 5)
{
log.displayNL("ERR: Invalid number of parameters. Parameters: <inventory> <sheetnames> <quality> <quantity>");
return false;
}
GET_ACTIVE_CHARACTER
std::map<string, uint32> need_items;
string selected_inv = args[1];
std::vector<string> sheet_names;
NLMISC::splitString(args[2], ",", sheet_names);
std::vector<string> qualities;
NLMISC::splitString(args[3], ",", qualities);
std::vector<string> quantities;
NLMISC::splitString(args[4], ",", quantities);
for (uint32 i=0; i < std::min(quantities.size(), std::min(qualities.size(), sheet_names.size())); i++)
{
uint32 quantity = 0;
fromString(quantities[i], quantity);
need_items.insert(make_pair(sheet_names[i]+":"+qualities[i], quantity));
}
std::map<uint32, uint32> slots;
std::map<string, uint32>::iterator itNeedItems;
// Save list of slots and quantities to delete
CInventoryPtr inventory = getInventory(c, selected_inv);
if (inventory != NULL)
{
for (uint32 j = 0; j < inventory->getSlotCount(); j++)
{
CGameItemPtr itemPtr = inventory->getItem(j);
if (itemPtr != NULL)
{
string sheet = itemPtr->getSheetId().toString();
uint32 item_quality = itemPtr->quality();
itNeedItems = need_items.find(sheet+":"+NLMISC::toString("%d", item_quality));
if (itNeedItems != need_items.end() && (*itNeedItems).second > 0)
{
uint32 quantity = std::min((*itNeedItems).second, itemPtr->getStackSize());
slots.insert(make_pair(j, quantity));
(*itNeedItems).second -= quantity;
}
}
}
// Check if all items has been found
for (itNeedItems = need_items.begin(); itNeedItems != need_items.end(); ++itNeedItems)
{
if ((*itNeedItems).second != 0) {
log.displayNL("ERR: Not enough items.");
return false;
}
}
}
log.displayNL("OK");
return true;
}
//----------------------------------------------------------------------------
NLMISC_COMMAND(enchantEquipedItem, "enchantEquipedItem", "<uid> <slotname> <sheet1>,[<sheet2> ...] [<maxSpaLoad>]")
{

Loading…
Cancel
Save