mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2025-01-20 14:42:03 +00:00
4689 lines
143 KiB
C++
4689 lines
143 KiB
C++
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|||
|
//
|
|||
|
// This program is free software: you can redistribute it and/or modify
|
|||
|
// it under the terms of the GNU Affero General Public License as
|
|||
|
// published by the Free Software Foundation, either version 3 of the
|
|||
|
// License, or (at your option) any later version.
|
|||
|
//
|
|||
|
// This program is distributed in the hope that it will be useful,
|
|||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
// GNU Affero General Public License for more details.
|
|||
|
//
|
|||
|
// You should have received a copy of the GNU Affero General Public License
|
|||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|
|||
|
#include "stdpch.h"
|
|||
|
|
|||
|
#include "script_compiler.h"
|
|||
|
|
|||
|
#include "ai_grp_npc.h"
|
|||
|
#include "group_profile.h"
|
|||
|
#include "ai_generic_fight.h"
|
|||
|
#include "server_share/msg_brick_service.h"
|
|||
|
|
|||
|
#include "continent_inline.h"
|
|||
|
#include "dyn_grp_inline.h"
|
|||
|
|
|||
|
#include "ai_script_data_manager.h"
|
|||
|
|
|||
|
#include "nf_helpers.h"
|
|||
|
#include "ai_aggro.h"
|
|||
|
#include "game_share/send_chat.h"
|
|||
|
#include "game_share/string_manager_sender.h"
|
|||
|
#include <time.h>
|
|||
|
|
|||
|
|
|||
|
using std::string;
|
|||
|
using std::vector;
|
|||
|
using namespace NLMISC;
|
|||
|
using namespace AIVM;
|
|||
|
using namespace AICOMP;
|
|||
|
using namespace AITYPES;
|
|||
|
using namespace RYAI_MAP_CRUNCH;
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection spawn__
|
|||
|
Spawns the current group.
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void spawn__(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
if (!entity)
|
|||
|
{
|
|||
|
nlwarning("spawnInstance failed");
|
|||
|
return;
|
|||
|
}
|
|||
|
CGroup const* const grp = entity->getGroup();
|
|||
|
if (grp)
|
|||
|
{
|
|||
|
if (grp->isSpawned())
|
|||
|
grp->getSpawnObj()->spawnBots();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection despawn_f_
|
|||
|
Depawns the current group.
|
|||
|
|
|||
|
Arguments: f(Immediatly) ->
|
|||
|
@param Immediatly is whether the groups spawns immediatly (1) or not (0)
|
|||
|
|
|||
|
@code
|
|||
|
()despawn(0); // despawn
|
|||
|
()despawn(1); // despawn immediatement
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void despawn_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float const immediatly = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
if (!entity)
|
|||
|
{
|
|||
|
nlwarning("despawnInstance failed");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CGroup* const grp = entity->getGroup();
|
|||
|
if (!grp)
|
|||
|
{
|
|||
|
nlwarning("despawn : entity '%s'%s is not a group ? ",
|
|||
|
entity->aliasTreeOwner()->getAliasFullName().c_str(),
|
|||
|
entity->aliasTreeOwner()->getAliasString().c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
grp->despawnBots(immediatly!=0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isAlived__f
|
|||
|
Test if the group is alived
|
|||
|
|
|||
|
Arguments: -> f(Immediatly)
|
|||
|
@return 1 if group is spawned
|
|||
|
|
|||
|
@code
|
|||
|
(alive)isAlived();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void isAlived__f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
if (!entity)
|
|||
|
{
|
|||
|
stack.push(0.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CGroup* const grp = entity->getGroup();
|
|||
|
if (!grp)
|
|||
|
{
|
|||
|
nlwarning("isAlived__f : entity '%s'%s is not a group ? ",
|
|||
|
entity->aliasTreeOwner()->getAliasFullName().c_str(),
|
|||
|
entity->aliasTreeOwner()->getAliasString().c_str());
|
|||
|
stack.push(0.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!grp->isSpawned())
|
|||
|
{
|
|||
|
stack.push(0.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
for (uint i=0; i<grp->bots().size(); ++i)
|
|||
|
{
|
|||
|
const CBot *const bot = grp->getBot(i);
|
|||
|
if ( !bot
|
|||
|
|| !bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
|
|||
|
CAIEntityPhysical *const ep=bot->getSpawnObj();
|
|||
|
if (ep->isAlive())
|
|||
|
{
|
|||
|
stack.push(1.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
stack.push(0.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPos_ssfff_c
|
|||
|
Used to create a dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(Dispersion) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupPos("class_forager", "state_machine_1", x, y, 30);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPos_ssfff_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
if (dispersionRadius<0.)
|
|||
|
dispersionRadius = 0.;
|
|||
|
stack.push(spawnNewGroup(entity, stack, aiInstance, CAIVector(x, y), -1, dispersionRadius));
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPos_ssfff_
|
|||
|
Used to create a dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(Dispersion) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupPos("class_forager", "state_machine_1", x, y, 30);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPos_ssfff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
if (dispersionRadius<0.)
|
|||
|
dispersionRadius = 0.;
|
|||
|
spawnNewGroup(entity, stack, aiInstance, CAIVector(x, y), -1, dispersionRadius);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPos_ssff_c
|
|||
|
Used to create a dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupPos("class_forager", "state_machine_1", x, y);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPos_ssff_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupPos_ssfff_c(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPos_ssff_
|
|||
|
Used to create a dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupPos("class_forager", "state_machine_1", x, y);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPos_ssff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupPos_ssfff_(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPosMl_ssffff_c
|
|||
|
Used to create a multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(BaseLevel), f(Dispersion) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupPosMl("class_forager", "state_machine_1", x, y, 13, 7.5);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPosMl_ssffff_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
if (dispersionRadius<0.)
|
|||
|
dispersionRadius = 0.;
|
|||
|
stack.push(spawnNewGroup(entity, stack, aiInstance, CAIVector(x,y), -1, dispersionRadius));
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPosMl_ssffff_
|
|||
|
Used to create a multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(BaseLevel), f(Dispersion) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupPosMl("class_forager", "state_machine_1", x, y, 13, 7.5);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPosMl_ssffff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
if (dispersionRadius<0.)
|
|||
|
dispersionRadius = 0.;
|
|||
|
spawnNewGroup(entity, stack, aiInstance, CAIVector(x,y), -1, dispersionRadius);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPosMl_ssfff_c
|
|||
|
Used to create a multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(BaseLevel) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupPosMl("class_forager", "state_machine_1", x, y, 13);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPosMl_ssfff_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupPosMl_ssffff_c(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupPosMl_ssfff_
|
|||
|
Used to create a multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), f(x), f(y), f(BaseLevel) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] x position of the spawned group on x axis
|
|||
|
@param[in] y position of the spawned group on y axis
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupPosMl("class_forager", "state_machine_1", x, y, 13);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupPosMl_ssfff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupPosMl_ssffff_(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getMidPos__ff
|
|||
|
Returns the position (x, y) of the current group.
|
|||
|
|
|||
|
Arguments: -> f(x), f(y)
|
|||
|
@param[out] x position of the group on x axis
|
|||
|
@param[out] y position of the group on y axis
|
|||
|
|
|||
|
@code
|
|||
|
(x, y)getMidPos();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void getMidPos__ff(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
CGroup* const group = entity->getGroup();
|
|||
|
|
|||
|
CAIVector vect;
|
|||
|
if (group->isSpawned())
|
|||
|
{
|
|||
|
if (!group->getSpawnObj()->calcCenterPos(vect))
|
|||
|
group->getSpawnObj()->calcCenterPos(vect, true);
|
|||
|
}
|
|||
|
|
|||
|
float x((float)vect.x().asDouble());
|
|||
|
float y((float)vect.y().asDouble());
|
|||
|
|
|||
|
stack.push(y);
|
|||
|
stack.push(x);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroup_sssf_c
|
|||
|
Used to create dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(Dispersion) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroup("class_forager", "state_machine_1", $zone, 10);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroup_sssf_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId const zoneName = CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
CNpcZone const* spawnZone = aiInstance->getZone(zoneName);
|
|||
|
if (!spawnZone)
|
|||
|
{
|
|||
|
string StateMachine = stack.top();
|
|||
|
stack.pop();
|
|||
|
stack.pop();
|
|||
|
nlwarning("newNpcChildGroup failed : spawnZone Not Found ! for StateMachine : %s", StateMachine.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
if (dispersionRadius<0.)
|
|||
|
{
|
|||
|
dispersionRadius = 0.;
|
|||
|
CNpcZonePlace const* spawnZonePlace = dynamic_cast<CNpcZonePlace const*>(spawnZone);
|
|||
|
if (spawnZonePlace!=NULL)
|
|||
|
dispersionRadius = spawnZonePlace->getRadius();
|
|||
|
}
|
|||
|
stack.push(spawnNewGroup(entity, stack, aiInstance, spawnZone->midPos(), -1, dispersionRadius));
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroup_sssf_
|
|||
|
Used to create dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(Dispersion) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroup("class_forager", "state_machine_1", $zone, 10);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroup_sssf_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId const zoneName = CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
CNpcZone const* spawnZone = aiInstance->getZone(zoneName);
|
|||
|
if (!spawnZone)
|
|||
|
{
|
|||
|
string StateMachine = stack.top();
|
|||
|
stack.pop();
|
|||
|
stack.pop();
|
|||
|
nlwarning("newNpcChildGroup failed : spawnZone Not Found ! for StateMachine : %s", StateMachine.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
if (dispersionRadius<0.)
|
|||
|
{
|
|||
|
dispersionRadius = 0.;
|
|||
|
CNpcZonePlace const* spawnZonePlace = dynamic_cast<CNpcZonePlace const*>(spawnZone);
|
|||
|
if (spawnZonePlace!=NULL)
|
|||
|
dispersionRadius = spawnZonePlace->getRadius();
|
|||
|
}
|
|||
|
spawnNewGroup(entity, stack, aiInstance, spawnZone->midPos(), -1, dispersionRadius);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroup_sss_c
|
|||
|
Used to create dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(Dispersion) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroup("class_forager", "state_machine_1", $zone);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroup_sss_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroup_sssf_c(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroup_sss_
|
|||
|
Used to create dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(Dispersion) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroup("class_forager", "state_machine_1", $zone);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroup_sss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroup_sssf_(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupMl_sssff_c
|
|||
|
Used to create multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(BaseLevel), f(Dispersion) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupMl("class_forager", "state_machine_1", $zone, 2, 50);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupMl_sssff_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
int baseLevel = (int)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId const zoneName = CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
CNpcZone const* spawnZone = aiInstance->getZone(zoneName);
|
|||
|
if (!spawnZone)
|
|||
|
{
|
|||
|
string StateMachine = stack.top();
|
|||
|
stack.pop();
|
|||
|
stack.pop();
|
|||
|
nlwarning("newNpcChildGroup failed : spawnZone Not Found ! for StateMachine : %s", StateMachine.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
if (dispersionRadius<0.)
|
|||
|
{
|
|||
|
dispersionRadius = 0.;
|
|||
|
CNpcZonePlace const* spawnZonePlace = dynamic_cast<CNpcZonePlace const*>(spawnZone);
|
|||
|
if (spawnZonePlace!=NULL)
|
|||
|
dispersionRadius = spawnZonePlace->getRadius();
|
|||
|
}
|
|||
|
stack.push(spawnNewGroup(entity, stack, aiInstance, spawnZone->midPos(), baseLevel, dispersionRadius));
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupMl_sssff_
|
|||
|
Used to create multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(BaseLevel), f(Dispersion) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[in] Dispersion is the dispersion radius in meters when spawning a group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupMl("class_forager", "state_machine_1", $zone, 2, 50);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupMl_sssff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
double dispersionRadius = (double)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
int baseLevel = (int)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId const zoneName = CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
return;
|
|||
|
|
|||
|
CNpcZone const* spawnZone = aiInstance->getZone(zoneName);
|
|||
|
if (!spawnZone)
|
|||
|
{
|
|||
|
string StateMachine = stack.top();
|
|||
|
stack.pop();
|
|||
|
stack.pop();
|
|||
|
nlwarning("newNpcChildGroup failed : spawnZone Not Found ! for StateMachine : %s", StateMachine.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
if (dispersionRadius<0.)
|
|||
|
{
|
|||
|
dispersionRadius = 0.;
|
|||
|
CNpcZonePlace const* spawnZonePlace = dynamic_cast<CNpcZonePlace const*>(spawnZone);
|
|||
|
if (spawnZonePlace!=NULL)
|
|||
|
dispersionRadius = spawnZonePlace->getRadius();
|
|||
|
}
|
|||
|
spawnNewGroup (entity, stack, aiInstance, spawnZone->midPos(), baseLevel, dispersionRadius);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupMl_sssf_c
|
|||
|
Used to create multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(BaseLevel) -> c(Group)
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
@param[out] Group is the newly created group
|
|||
|
|
|||
|
@code
|
|||
|
(@grp)newNpcChildGroupMl("class_forager", "state_machine_1", $zone, 12);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupMl_sssf_c(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupMl_sssff_c(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection newNpcChildGroupMl_sssf_
|
|||
|
Used to create multilevel dynamic npc group (a parent/children relation is defined).
|
|||
|
|
|||
|
Arguments: s(GroupTemplate), s(StateMachine), s(Zone), f(BaseLevel) ->
|
|||
|
@param[in] GroupTemplate is the name of a template npc group defined in the same AIInstance
|
|||
|
@param[in] StateMachine is the name of a state machine defined in the same AIInstance
|
|||
|
@param[in] Zone is returned by the getZoneWithFlags methods
|
|||
|
@param[in] BaseLevel is the base level of the spawned group
|
|||
|
|
|||
|
@code
|
|||
|
()newNpcChildGroupMl("class_forager", "state_machine_1", $zone, 12);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void newNpcChildGroupMl_sssf_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)-1.0f);
|
|||
|
newNpcChildGroupMl_sssff_(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection spawnManager_s_
|
|||
|
Spawns a manager.
|
|||
|
|
|||
|
Arguments: s(ManagerName) ->
|
|||
|
@param[in] ManagerName is the name of the manager to spawn
|
|||
|
|
|||
|
@code
|
|||
|
()spawnManager("NPC Manager"); // Spawns all the NPCs in the NPC manager called "NPC Manager"
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void spawnManager_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string ManagerName = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
breakable
|
|||
|
{
|
|||
|
if (!entity)
|
|||
|
{
|
|||
|
nlwarning("SpawnManager error entity not spawned");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
nlwarning("SpawnManager error AIInstance not Found");
|
|||
|
break;
|
|||
|
}
|
|||
|
/** :TODO: If CStringFilter is available use it here and test the whole */
|
|||
|
string/*CStringFilter*/ managerFilter(ManagerName);
|
|||
|
FOREACH(itManager, CAliasCont<CManager>, aiInstance->managers())
|
|||
|
{
|
|||
|
CManager* manager = *itManager;
|
|||
|
if (manager && managerFilter==manager->getName())
|
|||
|
{
|
|||
|
manager->spawn();
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
nlwarning("SpawnManager error");
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection despawnManager_s_
|
|||
|
Despawns a manager.
|
|||
|
|
|||
|
Arguments: s(ManagerName) ->
|
|||
|
@param[in] ManagerName is the name of the manager to despawn
|
|||
|
|
|||
|
@code
|
|||
|
()despawnManager("NPC Manager"); // Despawns all the NPCs in the NPC manager called "NPC Manager"
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void despawnManager_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string ManagerName = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
breakable
|
|||
|
{
|
|||
|
if (!entity)
|
|||
|
{
|
|||
|
nlwarning("DespawnManager error entity not spawned");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
nlwarning("DespawnManager error AIInstance not Found");
|
|||
|
break;
|
|||
|
}
|
|||
|
// :TODO: If CStringFilter is available use it here and test the whole
|
|||
|
string/*CStringFilter*/ managerFilter(ManagerName);
|
|||
|
FOREACH(itManager, CAliasCont<CManager>, aiInstance->managers())
|
|||
|
{
|
|||
|
CManager *manager=*itManager;
|
|||
|
if (manager && managerFilter==manager->getName())
|
|||
|
{
|
|||
|
manager->despawnMgr();
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getGroupTemplateWithFlags_sss_s
|
|||
|
Returns the name of a randomly chosen group template corresponding to specified flags.
|
|||
|
|
|||
|
Arguments: s(OneOf), s(Mandatory), s(ExceptFlags) -> s(GroupTemplate)
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptFlags is a '|' separated list of flags
|
|||
|
@param[out] GroupTemplate is a group template matching at least one of OneOf flags, all Manadatory flags and none of ExceptFlags
|
|||
|
|
|||
|
@code
|
|||
|
($group)getGroupTemplateWithFlags("food|rest", "invasion|outpost"); // Get a group which matches 'invasion', 'outpost' and either 'food' or 'rest' flags.
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getGroupTemplateWithFlags_sss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string exceptProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string mandatoryProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string oneOfProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
// If no AI instance return
|
|||
|
IManagerParent* managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Fill the property sets.
|
|||
|
AITYPES::CPropertySet oneOfSet = readSet(oneOfProperties);
|
|||
|
AITYPES::CPropertySet mandatorySet = readSet(mandatoryProperties);
|
|||
|
AITYPES::CPropertySet exceptSet = readSet(exceptProperties);
|
|||
|
|
|||
|
vector<CGroupDesc<CGroupFamily> const*> groupDescs;
|
|||
|
FOREACH (itCont, CCont<CContinent>, aiInstance->continents())
|
|||
|
{
|
|||
|
FOREACH (itRegion, CCont<CRegion>, itCont->regions())
|
|||
|
{
|
|||
|
FOREACH (itFamily, CCont<CGroupFamily>, itRegion->groupFamilies())
|
|||
|
{
|
|||
|
FOREACH (itGroupDesc, CCont<CGroupDesc<CGroupFamily> >, itFamily->groupDescs())
|
|||
|
{
|
|||
|
// Skip groups not meeting the criteria
|
|||
|
if (!itGroupDesc->properties().containsPartOfNotStrict(oneOfSet))
|
|||
|
continue;
|
|||
|
if (!itGroupDesc->properties().containsAllOf(mandatorySet))
|
|||
|
continue;
|
|||
|
if (itGroupDesc->properties().containsPartOfStrict(exceptSet))
|
|||
|
continue;
|
|||
|
groupDescs.push_back(*itGroupDesc);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (groupDescs.size()==0)
|
|||
|
{
|
|||
|
nlwarning("getGroupTemplateWithFlags failed: no group template found that contains all of '%s' and a part of'%s' ", mandatoryProperties.c_str(), oneOfProperties.c_str());
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CGroupDesc<CGroupFamily> const* groupDesc = groupDescs[CAIS::rand16((uint32)groupDescs.size())];
|
|||
|
stack.push(groupDesc->getFullName());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getGroupTemplateWithFlags_ss_s
|
|||
|
Returns the name of a randomly chosen group template corresponding to specified flags.
|
|||
|
|
|||
|
Arguments: s(OneOf), s(Mandatory) -> s(GroupTemplate)
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[out] GroupTemplate is a group template matching at least one of OneOf flags and all Manadatory flags
|
|||
|
|
|||
|
@code
|
|||
|
($group)getGroupTemplateWithFlags("food|rest", "invasion|outpost"); // Get a group which matches 'invasion', 'outpost' and either 'food' or 'rest' flags.
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getGroupTemplateWithFlags_ss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
getGroupTemplateWithFlags_sss_s(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getZoneWithFlags_ssss_s
|
|||
|
The first parameter is a list of 'one match enough' zone flags. The zones must
|
|||
|
have at least one of these flags to be selected. The second parameter is a
|
|||
|
list of 'all required' zone flag. The zones must have all these flags to be
|
|||
|
selected. The fourth parameter is a list of 'all forbidden' zone flag. The
|
|||
|
zones must not have any of these flags to be selected. Additionnaly the
|
|||
|
returned zone cannot be ExceptZone. Last argument specifies a list of flags
|
|||
|
that the selected zone cannot have.
|
|||
|
|
|||
|
With the list of selectable zone, the system then select a zone based on
|
|||
|
entity density in each selected zone. The system will select the least
|
|||
|
populated zone. It then returns the zone name.
|
|||
|
|
|||
|
Priority is given to current Cell, and after that to all cells.
|
|||
|
|
|||
|
Arguments: s(OneOf), s(Mandatory), s(ExceptZone), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptZone is a zone name
|
|||
|
@param[in] ExceptProperties is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getZoneWithFlags("food|rest", "invasion|outpost", $oldzone); // Get a zone which matches invasion, outpost and either food or rest flags with the best score except $oldzone.
|
|||
|
($zone)getZoneWithFlags("boss", "", $oldzone); // Get a zone which matches boss flag with the best score except the $oldzone
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getZoneWithFlags_ssss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string exceptProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId curZoneId= CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
string mandatoryProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string oneOfProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
// If no AI instance return
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Fill the property sets.
|
|||
|
AITYPES::CPropertySet oneOfSet = readSet(oneOfProperties);
|
|||
|
AITYPES::CPropertySet mandatorySet = readSet(mandatoryProperties);
|
|||
|
AITYPES::CPropertySet exceptSet = readSet(exceptProperties);
|
|||
|
// Get current zone
|
|||
|
CNpcZone const* const curZone = aiInstance->getZone(curZoneId);
|
|||
|
// Create the scorer
|
|||
|
CZoneScorerMandatoryAndOneOfPlusExcept const scorer(oneOfSet, mandatorySet, exceptSet, curZone);
|
|||
|
|
|||
|
getZoneWithFlags_helper(entity, stack, aiInstance, scorer);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getZoneWithFlags_sss_s
|
|||
|
@sa @ref getZoneWithFlags_ssss_s
|
|||
|
|
|||
|
Arguments: s(OneOf), s(Mandatory), s(ExceptZone) -> s(Zone)
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptZone is a zone name
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getZoneWithFlags("food|rest", "invasion|outpost", $oldzone); // Get a zone which matches invasion, outpost and either food or rest flags with the best score except $oldzone.
|
|||
|
($zone)getZoneWithFlags("boss", "", $oldzone); // Get a zone which matches boss flag with the best score except the $oldzone
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getZoneWithFlags_sss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
getZoneWithFlags_ssss_s(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNearestZoneWithFlags_ffsss_s
|
|||
|
@sa @ref getZoneWithFlags_ssss_s
|
|||
|
|
|||
|
The zone returned by this function is the nearest from the specified point and taking into account the zone free space.
|
|||
|
|
|||
|
Arguments: f(X), f(Y), s(OneOf), s(Mandatory), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] X is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] Y is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptProperties is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getNearestZoneWithFlags(x, y, "food|rest", "invasion|outpost", "stayaway");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNearestZoneWithFlags_ffsss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string exceptProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string mandatoryProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string oneOfProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
// If no AI instance return
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Fill the property sets.
|
|||
|
AITYPES::CPropertySet oneOfSet = readSet(oneOfProperties);
|
|||
|
AITYPES::CPropertySet mandatorySet = readSet(mandatoryProperties);
|
|||
|
AITYPES::CPropertySet exceptSet = readSet(exceptProperties);
|
|||
|
// Create the scorer
|
|||
|
CZoneScorerMandatoryAndOneOfAndDistAndSpace const scorer(oneOfSet, mandatorySet, exceptSet, CAIVector(x, y));
|
|||
|
|
|||
|
getZoneWithFlags_helper(entity, stack, aiInstance, scorer);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNearestZoneWithFlags_ffss_s
|
|||
|
@sa @ref getZoneWithFlags_sss_s
|
|||
|
|
|||
|
The zone returned by this function is the nearest from the specified point and taking into account the zone free space.
|
|||
|
|
|||
|
Arguments: f(X), f(Y), s(OneOf), s(Mandatory), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] X is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] Y is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getNearestZoneWithFlags(x, y, "food|rest", "invasion|outpost");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNearestZoneWithFlags_ffss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
getNearestZoneWithFlags_ffsss_s(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNearestZoneWithFlagsStrict_ffsss_s
|
|||
|
@sa @ref getZoneWithFlags_ssss_s
|
|||
|
|
|||
|
The zone returned by this function is the nearest from the specified point without taking into account the zone free space.
|
|||
|
|
|||
|
Arguments: f(X), f(Y), s(OneOf), s(Mandatory), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] X is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] Y is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptProperties is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getNearestZoneWithFlagsStrict(x, y, "food|rest", "invasion|outpost", "stayaway");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNearestZoneWithFlagsStrict_ffsss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string exceptProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string mandatoryProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string oneOfProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const y = stack.top();
|
|||
|
stack.pop();
|
|||
|
float const x = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
// If no AI instance return
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Fill the property sets.
|
|||
|
AITYPES::CPropertySet oneOfSet = readSet(oneOfProperties);
|
|||
|
AITYPES::CPropertySet mandatorySet = readSet(mandatoryProperties);
|
|||
|
AITYPES::CPropertySet exceptSet = readSet(exceptProperties);
|
|||
|
// Create the scorer
|
|||
|
const CZoneScorerMandatoryAndOneOfAndDist scorer(oneOfSet, mandatorySet, exceptSet, CAIVector(x, y));
|
|||
|
|
|||
|
getZoneWithFlags_helper(entity, stack, aiInstance, scorer);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNearestZoneWithFlagsStrict_ffss_s
|
|||
|
@sa @ref getZoneWithFlags_sss_s
|
|||
|
|
|||
|
The zone returned by this function is the nearest from the specified point without taking into account the zone free space.
|
|||
|
|
|||
|
Arguments: f(X), f(Y), s(OneOf), s(Mandatory), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] X is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] Y is the position of the zone we are looking for on the X axis
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching at least one of OneOf flags, all Manadatory flags and can't be ExceptZone
|
|||
|
|
|||
|
@code
|
|||
|
($zone)getNearestZoneWithFlagsStrict(x, y, "food|rest", "invasion|outpost");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNearestZoneWithFlagsStrict_ffss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
getNearestZoneWithFlagsStrict_ffsss_s(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNeighbourZoneWithFlags_ssss_s
|
|||
|
@sa @ref getZoneWithFlags_ssss_s
|
|||
|
|
|||
|
Here priority is given to current Cell, after that to neighbour Cells, and
|
|||
|
finally to all cells. CurrentZone cannot be returned.
|
|||
|
|
|||
|
Arguments: s(CurrentZone), s(OneOf), s(Mandatory), s(ExceptProperties) -> s(Zone)
|
|||
|
@param[in] CurrentZone is a zone name
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[in] ExceptProperties is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching the specified flags
|
|||
|
|
|||
|
@code
|
|||
|
($zone1)getNeighbourZoneWithFlags($zone, "boss", "", $exceptflag); // Get the zone in the neighbour cells of the one containing $zone which matches specified flags
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNeighbourZoneWithFlags_ssss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string exceptProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string mandatoryProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
string oneOfProperties = stack.top();
|
|||
|
stack.pop();
|
|||
|
TStringId curZoneId = CStringMapper::map(stack.top());
|
|||
|
stack.pop();
|
|||
|
|
|||
|
// If no AI instance return
|
|||
|
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (!aiInstance)
|
|||
|
{
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// If curzone is invalid return
|
|||
|
CNpcZone const* const curZone = aiInstance->getZone(curZoneId);
|
|||
|
if (!curZone)
|
|||
|
{
|
|||
|
nlwarning("getNeighbourZoneWithFlags failed: current zone is invalid!");
|
|||
|
nlwarning(" - current zone: %s", CStringMapper::unmap(curZoneId).c_str());
|
|||
|
nlwarning(" - oneOfProperties: %s", oneOfProperties.c_str());
|
|||
|
nlwarning(" - mandatoryProperties: %s", mandatoryProperties.c_str());
|
|||
|
nlwarning(" - exceptProperties: %s", exceptProperties.c_str());
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Fill the property sets.
|
|||
|
AITYPES::CPropertySet oneOfSet = readSet(oneOfProperties);
|
|||
|
AITYPES::CPropertySet mandatorySet = readSet(mandatoryProperties);
|
|||
|
AITYPES::CPropertySet exceptSet = readSet(exceptProperties);
|
|||
|
// Create the scorer
|
|||
|
CZoneScorerMandatoryAndOneOfPlusExcept const scorer(oneOfSet, mandatorySet, exceptSet, curZone);
|
|||
|
|
|||
|
vector<CCell*> cells;
|
|||
|
curZone->getOwner()->getNeighBourgCellList(cells);
|
|||
|
cells.push_back(curZone->getOwner());
|
|||
|
std::random_shuffle(cells.begin(), cells.end());
|
|||
|
|
|||
|
CNpcZone const* const newZone = CCellZone::lookupNpcZoneScorer(cells, scorer);
|
|||
|
|
|||
|
if (newZone)
|
|||
|
{
|
|||
|
stack.push(newZone->getAliasTreeOwner().getAliasFullName());
|
|||
|
return;
|
|||
|
}
|
|||
|
nlwarning("getNeighbourgZoneWithFlags failed: no zone found");
|
|||
|
nlwarning(" - current zone: %s", CStringMapper::unmap(curZoneId).c_str());
|
|||
|
nlwarning(" - oneOfProperties: %s", oneOfProperties.c_str());
|
|||
|
nlwarning(" - mandatoryProperties: %s", mandatoryProperties.c_str());
|
|||
|
nlwarning(" - exceptProperties: %s", exceptProperties.c_str());
|
|||
|
|
|||
|
stack.push(string());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getNeighbourZoneWithFlags_sss_s
|
|||
|
@sa @ref getZoneWithFlags_sss_s
|
|||
|
|
|||
|
Here priority is given to current Cell, after that to neighbour Cells, and
|
|||
|
finally to all cells. CurrentZone cannot be returned.
|
|||
|
|
|||
|
Arguments: s(CurrentZone), s(OneOf), s(Mandatory) -> s(Zone)
|
|||
|
@param[in] CurrentZone is a zone name
|
|||
|
@param[in] OneOf is a '|' separated list of flags
|
|||
|
@param[in] Mandatory is a '|' separated list of flags
|
|||
|
@param[out] Zone is a zone matching the specified flags
|
|||
|
|
|||
|
@code
|
|||
|
($zone1)getNeighbourZoneWithFlags($zone, "boss", ""); // Get the zone in the neighbour cells of the one containing $zone which matches specified flags
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup not in a family behaviour
|
|||
|
void getNeighbourZoneWithFlags_sss_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
getNeighbourZoneWithFlags_ssss_s(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setAggro_ff_
|
|||
|
Sets aggro parameters of current group.
|
|||
|
|
|||
|
Arguments: f(Range), f(NbTicks) ->
|
|||
|
@param[in] Range is a aggro range in meters
|
|||
|
@param[in] NbTicks is a aggro update period in ticks
|
|||
|
|
|||
|
@code
|
|||
|
()setAggro(Range, NbTicks); // Sets the aggro range of the group to Range, updated every NbTicks ticks
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setAggro_ff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
sint32 updateNbTicks = (sint32)(float)stack.top();
|
|||
|
stack.pop();
|
|||
|
float aggroRange = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* const grp = entity->getGroup();
|
|||
|
if (grp)
|
|||
|
{
|
|||
|
grp->_AggroRange = aggroRange;
|
|||
|
if (updateNbTicks>0)
|
|||
|
grp->_UpdateNbTicks = updateNbTicks;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setCanAggro_f_
|
|||
|
Let a bot aggro or prevent it from aggroing.
|
|||
|
|
|||
|
Arguments: f(CanAggro) ->
|
|||
|
@param[in] CanAggro tells whether the bot can aggro (!=0) or not (==0)
|
|||
|
|
|||
|
@code
|
|||
|
()setCanAggro(0);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setCanAggro_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
bool canAggro = ((float)stack.top())!=0.f;
|
|||
|
stack.pop();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
CSpawnBot* spBot = bot->getSpawnObj();
|
|||
|
if (spBot)
|
|||
|
spBot->setCanAggro(canAggro);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection clearAggroList_f_
|
|||
|
Reset the aggrolist of a bot.
|
|||
|
|
|||
|
Arguments: f(bool don't send lost aggro message to EGS) ->
|
|||
|
|
|||
|
@code
|
|||
|
()clearAggroList(0/1);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void clearAggroList_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
bool sendAggroLostMessage = ((float)stack.top())==0.f;
|
|||
|
stack.pop();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
CSpawnBot* spBot = bot->getSpawnObj();
|
|||
|
if (spBot)
|
|||
|
spBot->clearAggroList(sendAggroLostMessage);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection clearAggroList__
|
|||
|
Reset the aggrolist of a bot.
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
@code
|
|||
|
()clearAggroList();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void clearAggroList__(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
stack.push((float)0.f);
|
|||
|
clearAggroList_f_(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setMode_s_
|
|||
|
Sets the mode of every bot of the group. Valid modes are:
|
|||
|
- Normal
|
|||
|
- Sit
|
|||
|
- Eat
|
|||
|
- Rest
|
|||
|
- Alert
|
|||
|
- Hungry
|
|||
|
- Death
|
|||
|
|
|||
|
Arguments: s(Mode) ->
|
|||
|
@param[in] Mode is the mode name to set
|
|||
|
|
|||
|
@code
|
|||
|
()setMode("Alert");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setMode_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string NewMode = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
MBEHAV::EMode mode = MBEHAV::stringToMode(NewMode);
|
|||
|
if (mode==MBEHAV::UNKNOWN_MODE)
|
|||
|
return;
|
|||
|
|
|||
|
FOREACH(botIt, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (botIt->getSpawnObj())
|
|||
|
botIt->getSpawnObj()->setMode(mode);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setAutoSpawn_f_
|
|||
|
Determine if the current group should respawn automatically after despawn.
|
|||
|
|
|||
|
Arguments: f(AutoSpawn) ->
|
|||
|
@param[in] AutoSpawn is whether the group automatically rewpawns (1) or not (0)
|
|||
|
|
|||
|
@code
|
|||
|
()setAutoSpawn(1);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setAutoSpawn_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float const autoSpawn = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
group->setAutoSpawn(autoSpawn!=0.f);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
// HP related methods
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setHPLevel_f_
|
|||
|
Sets the current HP level of each bot of the group.
|
|||
|
|
|||
|
Arguments: f(Coef) ->
|
|||
|
@param[in] Coef is the percentage of its max HP each creature will have
|
|||
|
|
|||
|
@code
|
|||
|
()setHPLevel(0.8);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setHPLevel_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float coef = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)(sbot->maxHitPoints()*coef));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
// HP related methods
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setHPScale_f__f_
|
|||
|
Sets the current HP level of level of each bot of the group. its maxHitPoints
|
|||
|
eg:
|
|||
|
for a bot HP = 850 and MaxHP = 1000
|
|||
|
()setHPScale_f_(0); HP will be 0 so DeltaHp = 850
|
|||
|
()setHPScale_f_(1); HP will be 100 so DeltaHp = 150
|
|||
|
()setHPScale_f_(0.5); HP will be 500 so DeltaHp = 350
|
|||
|
if bot HP = 840 and Max abd setHpRatio(0) HP will be 0
|
|||
|
|
|||
|
|
|||
|
Arguments: f(Coef) ->
|
|||
|
@param[in] Coef is the percentage of its max HP each creature will *BE*
|
|||
|
|
|||
|
@code
|
|||
|
()setHPLevel(0.8);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setHPScale_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float coef = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)( sbot->maxHitPoints() *coef - sbot->currentHitPoints()) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection scaleHP_f_
|
|||
|
Scales the bots HP.
|
|||
|
|
|||
|
Arguments: f(Coef) ->
|
|||
|
@param[in] Coef is the percentage of its current HP each creature will have
|
|||
|
|
|||
|
@code
|
|||
|
()scaleHP(2);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void scaleHP_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float coef = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)(sbot->currentHitPoints()*coef));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setBotHPScaleByAlias_fs_
|
|||
|
Same as setHpSacale but only on a specific bot of a groupe from the current group by its bot alias
|
|||
|
|
|||
|
Arguments: f(alias),f(Coef), ->
|
|||
|
@param[in] alias is the alias of the bot
|
|||
|
@param[in] Coef is the percentage of its current HP each creature will have
|
|||
|
|
|||
|
|
|||
|
@code
|
|||
|
()scaleHpByAlias(2, '(A:1000:10560)');
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void setBotHPScaleByAlias_fs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
uint32 alias = LigoConfig.aliasFromString((string)stack.top()) ; stack.pop();
|
|||
|
|
|||
|
float coef = stack.top(); stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
|
|||
|
if (bot->getAlias() != alias) { continue; }
|
|||
|
if (!bot->isSpawned()) return;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)( sbot->maxHitPoints() *coef - sbot->currentHitPoints()) );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection downScaleHP_f_
|
|||
|
Scales the bots HP down.
|
|||
|
|
|||
|
Arguments: f(Coef) ->
|
|||
|
@param[in] Coef is a value
|
|||
|
|
|||
|
@code
|
|||
|
()downScaleHP(2);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void downScaleHP_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float coef = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
clamp(coef, 0.f, 1.f);
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)(sbot->currentHitPoints()*(coef-1)));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection upScaleHP_f_
|
|||
|
Scales the bots HP up.
|
|||
|
|
|||
|
Arguments: f(Coef) ->
|
|||
|
@param[in] Coef is a value
|
|||
|
|
|||
|
@code
|
|||
|
()upScaleHP(2);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void upScaleHP_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float coef = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
clamp(coef, 0.f, 1.f);
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
CSpawnBot* spBot = bot->getSpawnObj();
|
|||
|
if (spBot)
|
|||
|
{
|
|||
|
msgList.Entities.push_back(spBot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)((spBot->maxHitPoints()-spBot->currentHitPoints())*coef));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addHP_f_
|
|||
|
Add HP to the bots.
|
|||
|
|
|||
|
Arguments: f(HP) ->
|
|||
|
@param[in] HP is the amount of hit points to add to each bot
|
|||
|
|
|||
|
@code
|
|||
|
()addHP(500);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addHP_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float addHP = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CChangeCreatureHPMsg& msgList = CAIS::instance().getCreatureChangeHP();
|
|||
|
|
|||
|
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
if (!bot->isSpawned())
|
|||
|
continue;
|
|||
|
|
|||
|
CSpawnBot* const sbot = bot->getSpawnObj();
|
|||
|
|
|||
|
msgList.Entities.push_back(sbot->dataSetRow());
|
|||
|
msgList.DeltaHp.push_back((sint32)(sbot->currentHitPoints()+addHP));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection aiAction_s_
|
|||
|
Triggers an AI action, defined by its sheet name, on the current target.
|
|||
|
|
|||
|
Arguments: s(actionSheetId) ->
|
|||
|
@param[in] actionSheetId is a the sheet name of the action
|
|||
|
|
|||
|
@code
|
|||
|
()aiAction("kick_his_ass.aiaction");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void aiAction_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string actionName = stack.top();
|
|||
|
stack.pop();
|
|||
|
NLMISC::CSheetId sheetId(actionName);
|
|||
|
if (sheetId==NLMISC::CSheetId::Unknown)
|
|||
|
{
|
|||
|
nlwarning("Action SheetId Unknown %s", actionName.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
|
|||
|
if (action.isNull())
|
|||
|
{
|
|||
|
nlwarning("Action SheetId Unknown %s", actionName.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
FOREACH(botIt, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
CSpawnBot* pbot = botIt->getSpawnObj();
|
|||
|
if (pbot!=NULL)
|
|||
|
{
|
|||
|
CSpawnBot& bot = *pbot;
|
|||
|
if (!bot.getAIProfile())
|
|||
|
continue; // OK
|
|||
|
|
|||
|
CBotProfileFight* profile = dynamic_cast<CBotProfileFight*>(bot.getAIProfile());
|
|||
|
if (!profile)
|
|||
|
continue; // OK
|
|||
|
|
|||
|
if (!profile->atAttackDist())
|
|||
|
continue; // NOT OK
|
|||
|
|
|||
|
TDataSetRow dataSetRow;
|
|||
|
if ((CAIEntityPhysical*)bot.getTarget())
|
|||
|
dataSetRow = bot.getTarget()->dataSetRow();
|
|||
|
|
|||
|
CEGSExecuteAiActionMsg msg(bot.dataSetRow(), dataSetRow, action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
|
|||
|
msg.send(egsString);
|
|||
|
bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
|
|||
|
// OK
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection aiActionSelf_s_
|
|||
|
Triggers an AI action, defined by its sheet name, on the bot itself.
|
|||
|
|
|||
|
Arguments: s(actionSheetId) ->
|
|||
|
@param[in] actionSheetId is a the sheet name of the action
|
|||
|
|
|||
|
@code
|
|||
|
()aiActionSelf("defensive_aura.aiaction");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void aiActionSelf_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string actionName = stack.top();
|
|||
|
stack.pop();
|
|||
|
NLMISC::CSheetId sheetId(actionName);
|
|||
|
if (sheetId==NLMISC::CSheetId::Unknown)
|
|||
|
{
|
|||
|
nlwarning("Action SheetId Unknown %s", actionName.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
AISHEETS::IAIActionCPtr action = AISHEETS::CSheets::getInstance()->lookupAction(sheetId);
|
|||
|
if (action.isNull())
|
|||
|
{
|
|||
|
nlwarning("Action SheetId Unknown %s", actionName.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
FOREACH(botIt, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
CSpawnBot* pbot = botIt->getSpawnObj();
|
|||
|
if (pbot!=NULL)
|
|||
|
{
|
|||
|
CSpawnBot& bot = *pbot;
|
|||
|
CEGSExecuteAiActionMsg msg(bot.dataSetRow(), bot.dataSetRow(), action->SheetId(), bot._DamageCoef, bot._DamageSpeedCoef);
|
|||
|
msg.send(egsString);
|
|||
|
bot.setActionFlags(RYZOMACTIONFLAGS::Attacks);
|
|||
|
// OK
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addProfileParameter_s_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
|
|||
|
@code
|
|||
|
()addProfileParameter("running"); // <20>quivalent <20> un parameter "running" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addProfileParameter_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, "", 0.f);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addProfileParameter_ss_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName),s(parameterContent) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
@param[in] parameterContent is the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
()addProfileParameter("foo", "bar"); // <20>quivalent <20> un parameter "foo:bar" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addProfileParameter_ss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string value = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, value, 0.f);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addProfileParameter_sf_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName),f(parameterContent) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
@param[in] parameterContent is the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
()addProfileParameter("foo", 0.5); // <20>quivalent <20> un parameter "foo:0.5" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addProfileParameter_sf_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float value = (float)stack.top();
|
|||
|
stack.pop();
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, "", value);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection removeProfileParameter_s_
|
|||
|
removes a profile parameter from the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to remove
|
|||
|
|
|||
|
@code
|
|||
|
()removeProfileParameter("running"); // retire le param<61>tre "running" ou "running:<*>" du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void removeProfileParameter_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->removeProfileParameter(name);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addPersistentProfileParameter_s_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
|
|||
|
@code
|
|||
|
()addProfileParameter("running"); // <20>quivalent <20> un parameter "running" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addPersistentProfileParameter_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, "", 0.f);
|
|||
|
|
|||
|
group->addProfileParameter(name, "", 0.f);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addPersistentProfileParameter_ss_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName),s(parameterContent) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
@param[in] parameterContent is the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
()addPersistentProfileParameter("foo", "bar"); // <20>quivalent <20> un parameter "foo:bar" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addPersistentProfileParameter_ss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string value = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, value, 0.f);
|
|||
|
|
|||
|
group->addProfileParameter(name, value, 0.f);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection addPersistentProfileParameter_sf_
|
|||
|
Adds a profile parameter to the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName),f(parameterContent) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to add
|
|||
|
@param[in] parameterContent is the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
()addPersistentProfileParameter("foo", 0.5); // <20>quivalent <20> un parameter "foo:0.5" dans la primitive du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void addPersistentProfileParameter_sf_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float value = (float)stack.top();
|
|||
|
stack.pop();
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->addProfileParameter(name, "", value);
|
|||
|
|
|||
|
group->addProfileParameter(name, "", value);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection removePersistentProfileParameter_s_
|
|||
|
removes a profile parameter from the current group.
|
|||
|
|
|||
|
Arguments: s(parameterName) ->
|
|||
|
@param[in] parameterName is a the id of the parameter to remove
|
|||
|
|
|||
|
@code
|
|||
|
()removeProfileParameter("running"); // retire le param<61>tre "running" ou "running:<*>" du groupe
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void removePersistentProfileParameter_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string name = (std::string)stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (group->isSpawned())
|
|||
|
group->getSpawnObj()->removeProfileParameter(name);
|
|||
|
|
|||
|
group->removeProfileParameter(name);
|
|||
|
}
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getOutpostState__s
|
|||
|
Returns the name of the current outpost state (group must be in an outpost).
|
|||
|
|
|||
|
Arguments: -> s(StateName)
|
|||
|
@param[out] StateName is the name of the current outpost state
|
|||
|
|
|||
|
@code
|
|||
|
($name)getOutpostState();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void getOutpostStateName__s(CStateInstance* si, CScriptStack& stack)
|
|||
|
{
|
|||
|
string str;
|
|||
|
|
|||
|
breakable
|
|||
|
{
|
|||
|
if (!si)
|
|||
|
break;
|
|||
|
|
|||
|
CGroup* group = si->getGroup();
|
|||
|
if (!group)
|
|||
|
break;
|
|||
|
|
|||
|
COutpostManager* manager = dynamic_cast<COutpostManager*>(group->getOwner());
|
|||
|
if (!manager)
|
|||
|
break;
|
|||
|
|
|||
|
str = static_cast<COutpost*>(manager->getOwner())->getStateName();
|
|||
|
}
|
|||
|
|
|||
|
stack.push(str);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isOutpostTribeOwner__f
|
|||
|
Returns whether the current outpost owner is a tribe (group must be in an outpost).
|
|||
|
|
|||
|
Arguments: -> f(TribeOwner)
|
|||
|
@param[out] TribeOwner is whether the current outpost owner is a tribe (1) or not (0)
|
|||
|
|
|||
|
@code
|
|||
|
(tribeOwner)isOutpostTribeOwner();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void isOutpostTribeOwner__f(CStateInstance* si, CScriptStack& stack)
|
|||
|
{
|
|||
|
float tribeOwner = 0.f;
|
|||
|
|
|||
|
breakable
|
|||
|
{
|
|||
|
if (!si)
|
|||
|
break;
|
|||
|
|
|||
|
CGroup* group = si->getGroup();
|
|||
|
if (!group)
|
|||
|
break;
|
|||
|
|
|||
|
COutpostManager* manager = dynamic_cast<COutpostManager*>(group->getOwner());
|
|||
|
if (!manager)
|
|||
|
break;
|
|||
|
|
|||
|
if (!static_cast<COutpost*>(manager->getOwner())->isBelongingToAGuild())
|
|||
|
tribeOwner = 1.f;
|
|||
|
}
|
|||
|
|
|||
|
stack.push(tribeOwner);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isOutpostGuildOwner__f
|
|||
|
Returns whether the current outpost owner is a guild (group must be in an outpost).
|
|||
|
|
|||
|
Arguments: -> f(TribeOwner)
|
|||
|
@param[out] TribeOwner is whether the current outpost owner is a guild (1) or not (0)
|
|||
|
|
|||
|
@code
|
|||
|
(guildOwner)isOutpostGuildOwner();
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void isOutpostGuildOwner__f(CStateInstance* si, CScriptStack& stack)
|
|||
|
{
|
|||
|
float guildOwner = 0.f;
|
|||
|
|
|||
|
breakable
|
|||
|
{
|
|||
|
if (!si)
|
|||
|
break;
|
|||
|
|
|||
|
CGroup* group = si->getGroup();
|
|||
|
if (!group)
|
|||
|
break;
|
|||
|
|
|||
|
COutpostManager* manager = dynamic_cast<COutpostManager*>(group->getOwner());
|
|||
|
if (!manager)
|
|||
|
break;
|
|||
|
|
|||
|
if (static_cast<COutpost*>(manager->getOwner())->isBelongingToAGuild())
|
|||
|
guildOwner = 1.f;
|
|||
|
}
|
|||
|
|
|||
|
stack.push(guildOwner);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getEventParam_f_f
|
|||
|
Returns the content of a param
|
|||
|
|
|||
|
Arguments: f(paramIndex) -> f(value)
|
|||
|
@param[in] paramIndex is the parameter index passed by EGS ai_event message
|
|||
|
@param[out] value is a the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
(val)getEventParam(2);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void getEventParam_f_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
uint32 varId = (uint32)((float)stack.top());
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
stack.top() = group->getEventParamFloat(varId);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getEventParam_f_s
|
|||
|
Returns the content of a param
|
|||
|
|
|||
|
Arguments: f(paramIndex) -> s(value)
|
|||
|
@param[in] paramIndex is the parameter index passed by EGS ai_event message
|
|||
|
@param[out] value is a the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
($val)getEventParam(2);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void getEventParam_f_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
uint32 varId = (uint32)((float)stack.top());
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
stack.top() = group->getEventParamString(varId);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// -- Boss functions
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getPlayerStat_ss_f
|
|||
|
Get some player stat.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. This EntityId is passed as string as argument. The EntityId can be obtains via getCurrentPlayerAggroListTarget or getRandomPlayerAggroListTarget.
|
|||
|
The player must be in the same AI Instance (same continent).
|
|||
|
If the player is not in the same Ai Instance or the input string is empty the function return zero and *display* a warning message on the log. You can think of using isPlayerAlived to be sure that the id is still a valid value.
|
|||
|
If param is not one of "HP", "MaxHp", "RatioHp" zero is return and a warning message is printed on the log.
|
|||
|
- The "Hp" stat is the property CURRENT_HIT_POINTS as seen in the mirror.
|
|||
|
- The "MaxHp" stat is the property MAX_HIT_POINTS as seen in the mirror.
|
|||
|
- The "RatioHp" stat is (Hp * 100) / MaxHp
|
|||
|
Be careful the argument is case sensitive.
|
|||
|
|
|||
|
Arguments: s(playerEidAsString), s(statName) -> s(result)
|
|||
|
@param[in] playerEidAsString is EntityId as string from the player we want infos
|
|||
|
@param[in] statName is the name of the property (can be "HP", "MaxHp", "RatioHp")
|
|||
|
@param[out] value is a the value of the parameter
|
|||
|
|
|||
|
@code
|
|||
|
($playerEid)getCurrentPlayerEid();
|
|||
|
print($playerEid); //log (0x00001fbd50:00:00:81)
|
|||
|
(maxHp)getPlayerStat($playerEid, "MaxHp");
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getPlayerStat_ss_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getPlayerStat_ss_f";
|
|||
|
// 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;
|
|||
|
}
|
|||
|
|
|||
|
if (statName == "Hp" )
|
|||
|
{
|
|||
|
// return DSPropertyCURRENT_HIT_POINTS Mirror value
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol( TheDataset, playerRow, DSPropertyCURRENT_HIT_POINTS );
|
|||
|
stack.push((float)mirrorSymbol.getValue());
|
|||
|
return;
|
|||
|
}
|
|||
|
else if (statName == "MaxHp")
|
|||
|
{
|
|||
|
// return DSPropertyMAX_HIT_POINTS Mirror value
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol( TheDataset, playerRow, DSPropertyMAX_HIT_POINTS );
|
|||
|
stack.push((float)mirrorSymbol.getValue());
|
|||
|
return;
|
|||
|
}
|
|||
|
else if (statName == "RatioHp")
|
|||
|
{
|
|||
|
// return percentage of live (read from mirror values)
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol( TheDataset, playerRow, DSPropertyCURRENT_HIT_POINTS );
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol2( TheDataset, playerRow, DSPropertyMAX_HIT_POINTS );
|
|||
|
|
|||
|
stack.push((float)(100.0*mirrorSymbol.getValue() / mirrorSymbol2.getValue()));
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
nlwarning("Try to call %s with wrong state %s", funName.c_str(), statName.c_str() );
|
|||
|
}
|
|||
|
stack.push((float)0);
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getPlayerDistance_fs_f
|
|||
|
Get the distance between a player and a bot in meters.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. This EntityId is passed as string as argument. The EntityId can be obtains via getCurrentPlayerAggroListTarget or getRandomPlayerAggroListTarget.
|
|||
|
The player must be in the same AI Instance (same continent).
|
|||
|
If the player is not in the same Ai Instance or the input string is empty the function return -1 and display a warning message on the log. You can think of using isPlayerAlived to be sure that the player id is still a valid value.
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index the function returns -1 and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
Arguments: s(playerEidAsString), f(botIndex) -> s(result)
|
|||
|
@param[in] playerEidAsString is EntityId as string from the player we want infos
|
|||
|
@param[in] botIndex is the index of an bot member of the current group
|
|||
|
@param[out] value is a the distance between the player on the bot (or -1 if error)
|
|||
|
|
|||
|
@code
|
|||
|
($playerEid)getCurrentPlayerEid();
|
|||
|
(index)getBotIndexByName("toto");
|
|||
|
(distance)getPlayerDistance(index, $playerEid);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getPlayerDistance_fs_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getPlayerDistance_is_f";
|
|||
|
|
|||
|
// read input params
|
|||
|
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
|
|||
|
sint32 botIndex = (sint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get the player Eid
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
|
|||
|
// get the Spawn bot by its index
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
stack.push((float) -1);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// get DataSetRow of player to read mirro values
|
|||
|
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 player is still alived.", funName.c_str(), playerEidStr.c_str() );
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// calculate the size between position of the player (from mirro) to position of the spawn bot.
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol( TheDataset, playerRow, DSPropertyPOSX );
|
|||
|
CMirrorPropValue<sint32> mirrorSymbol2( TheDataset, playerRow, DSPropertyPOSY );
|
|||
|
const double dx = double (mirrorSymbol.getValue()) - double(spBot->x().asInt());
|
|||
|
const double dy = double (mirrorSymbol2.getValue()) - double(spBot->y().asInt());
|
|||
|
const double dist2 = (dx*dx + dy*dy) / 1000000.0;
|
|||
|
const double dist = sqrt(dist2);
|
|||
|
|
|||
|
stack.push(float(dist));
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getCurrentPlayerAggroListTarget_f_s
|
|||
|
Get the player entity id (as string) that has the most aggro in the aggro list of a bot.
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. This EntityId is returned as result. If the aggro list is empty an empty string is returned (but *NO* warning messages)
|
|||
|
|
|||
|
|
|||
|
Arguments: f(botIndex) -> s(playerEidAsString)
|
|||
|
@param[in] botIndex is the index of an bot member of the current group
|
|||
|
@param[out] playerEidAsString is EntityId as string from the player we want infos
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getCurrentPlayerAggroListTarget(4);
|
|||
|
(distance)getPlayerDistance(4, $playerId);
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
void getCurrentPlayerAggroListTarget_f_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "getCurrentPlayerAggroListTarget_f_s";
|
|||
|
|
|||
|
// get input params
|
|||
|
sint32 botIndex = (sint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get spawn Bot
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// iteratre throug aggro list to have the eid with max aggro
|
|||
|
CBotAggroOwner::TBotAggroList const& aggroList = spBot->getBotAggroList();
|
|||
|
CBotAggroOwner::TBotAggroList::const_iterator aggroIt(aggroList.begin()), aggroEnd(aggroList.end());
|
|||
|
TDataSetRow foundRow = TDataSetRow();
|
|||
|
float foundAggro = 0;
|
|||
|
for (; aggroIt != aggroEnd; ++aggroIt)
|
|||
|
{
|
|||
|
float aggro = aggroIt->second->finalAggro();
|
|||
|
if (aggro > foundAggro)
|
|||
|
{
|
|||
|
if (CMirrors::getEntityId(aggroIt->first).getType() != RYZOMID::player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(aggroIt->first);
|
|||
|
if (!ep)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
CBotPlayer const* const player = NLMISC::safe_cast<CBotPlayer const*>(ep);
|
|||
|
if (!player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (!player->isAggroable())
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
foundAggro = aggro;
|
|||
|
foundRow = aggroIt->first;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( foundRow == TDataSetRow())
|
|||
|
{ // Empty aggro list so no warning displayed
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
const NLMISC::CEntityId& found = CMirrors::getEntityId(foundRow);
|
|||
|
stack.push(std::string(found.toString()));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getRandomPlayerAggroListTarget_f_s
|
|||
|
Get a player entity id (as string) from the aggro list of a bot.
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. This EntityId is returned as result. If the aggro list is empty an empty string is returned (but *NO* warning messages)
|
|||
|
|
|||
|
|
|||
|
Arguments: f(botIndex) -> s(playerEidAsString)
|
|||
|
@param[in] botIndex is the index of an bot member of the current group
|
|||
|
@param[out] playerEidAsString is EntityId as string from the player we want infos
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(4);
|
|||
|
()setAggroListTarget(4, $playerId);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
void getRandomPlayerAggroListTarget_f_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "getRandomPlayerAggroListTarget_f_s";
|
|||
|
|
|||
|
// test botIndex
|
|||
|
uint32 botIndex = (uint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get Spawn bot
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || !group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// make a vector of aggroable player
|
|||
|
CBotAggroOwner::TBotAggroList const& aggroList = spBot->getBotAggroList();
|
|||
|
//typedef std::map<TDataSetRow, TAggroEntryPtr> TBotAggroList;
|
|||
|
CBotAggroOwner::TBotAggroList::const_iterator aggroIt(aggroList.begin()), aggroEnd(aggroList.end());
|
|||
|
TDataSetRow foundRow = TDataSetRow();
|
|||
|
std::vector<TDataSetRow> playerAggroable;
|
|||
|
for (; aggroIt != aggroEnd; ++aggroIt)
|
|||
|
{
|
|||
|
if (CMirrors::getEntityId(aggroIt->first).getType() != RYZOMID::player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(aggroIt->first);
|
|||
|
if (!ep)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
CBotPlayer const* const player = NLMISC::safe_cast<CBotPlayer const*>(ep);
|
|||
|
if (!player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (!player->isAggroable())
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
playerAggroable.push_back(aggroIt->first);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( playerAggroable.empty())
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
// chose a randomly a player among the container
|
|||
|
uint32 index = static_cast<uint32>( static_cast<double>(playerAggroable.size())*rand()/(RAND_MAX+1.0) );
|
|||
|
|
|||
|
const NLMISC::CEntityId& found = CMirrors::getEntityId(playerAggroable[ index ]);
|
|||
|
stack.push(std::string(found.toString()));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getAggroListElement_ff_s
|
|||
|
Get a player entity id (as string) from the aggro list of a bot by it aggro list index.
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
A aggro list index is used to identified the player in the aggro list. The size of the aggro list is given by getAggroListSize_f_s
|
|||
|
)
|
|||
|
|
|||
|
|
|||
|
Arguments: f(botIndex), f(aggroListIndex) -> s(playerEidAsString)
|
|||
|
@param[in] botIndex is the index of an bot member of the current group
|
|||
|
@param[in] aggroListIndex is the index of a aggroable player in the aggro list of the bot identified by botIndex
|
|||
|
@param[out] playerEidAsString is EntityId as string from the player we want infos
|
|||
|
|
|||
|
@code
|
|||
|
(aggroSize)getAggorListSize(0);
|
|||
|
// to much player are attacking the boss
|
|||
|
if (aggoroSize > 10)
|
|||
|
{
|
|||
|
($player1)getAggroListElement(0);
|
|||
|
($player2)getAggroListElement(1);
|
|||
|
($player3)getAggroListElement(2);
|
|||
|
// so the boss teleport 3 person from its aggro list at the end of the world
|
|||
|
teleportPlayer($player1, 14233, 123123, 0, 0);
|
|||
|
teleportPlayer($player2, 14233, 123123, 0, 0);
|
|||
|
teleportPlayer($player2, 14233, 123123, 0, 0);
|
|||
|
clearAggroList();
|
|||
|
}
|
|||
|
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getAggroListElement_ff_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "getAggroListElement_ff_s";
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// get params
|
|||
|
uint32 elementIndex = (uint32)((float)stack.top()); stack.pop();
|
|||
|
sint32 botIndex = (uint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get spawn bot by its index
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || !group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// make a vector of aggroable player
|
|||
|
CBotAggroOwner::TBotAggroList const& aggroList = spBot->getBotAggroList();
|
|||
|
//typedef std::map<TDataSetRow, TAggroEntryPtr> TBotAggroList;
|
|||
|
CBotAggroOwner::TBotAggroList::const_iterator aggroIt(aggroList.begin()), aggroEnd(aggroList.end());
|
|||
|
TDataSetRow foundRow = TDataSetRow();
|
|||
|
|
|||
|
std::vector<TDataSetRow> playerAggroable;
|
|||
|
for (; aggroIt != aggroEnd; ++aggroIt)
|
|||
|
{
|
|||
|
if (CMirrors::getEntityId(aggroIt->first).getType() != RYZOMID::player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(aggroIt->first);
|
|||
|
if (!ep)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
CBotPlayer const* const player = NLMISC::safe_cast<CBotPlayer const*>(ep);
|
|||
|
if (!player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (!player->isAggroable())
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
playerAggroable.push_back(aggroIt->first);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( playerAggroable.empty())
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
// if index outside return "";
|
|||
|
if (0 > elementIndex && elementIndex >= playerAggroable.size())
|
|||
|
{
|
|||
|
stack.push(std::string(""));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
const NLMISC::CEntityId& found = CMirrors::getEntityId(playerAggroable[ uint32(elementIndex) ]);
|
|||
|
stack.push(std::string(found.toString()));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getAggroListSize_f_f
|
|||
|
Get a size of the aggro lsit of a bot (list of aggroable PLAYER)
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
A number is used to indicate the size of the aggro lsit
|
|||
|
|
|||
|
Arguments: f(aggroListIndex) -> f(sizeOfAggroList)
|
|||
|
@param[in] botIndex is the index of an bot member of the current group.
|
|||
|
@param[out] sizeOfAggroList The size of the aggro list index.
|
|||
|
|
|||
|
@code
|
|||
|
(aggroSize)getAggorListSize(0);
|
|||
|
// to much player are attacking the boss
|
|||
|
if (aggoroSize > 10)
|
|||
|
{
|
|||
|
($player1)getAggroListElement(0);
|
|||
|
($player2)getAggroListElement(1);
|
|||
|
($player3)getAggroListElement(2);
|
|||
|
// so the boss teleport 3 person from its aggro list at the end of the world
|
|||
|
teleportPlayer($player1, 14233, 123123, 0, 0);
|
|||
|
teleportPlayer($player2, 14233, 123123, 0, 0);
|
|||
|
teleportPlayer($player2, 14233, 123123, 0, 0);
|
|||
|
clearAggroList();
|
|||
|
}
|
|||
|
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getAggroListSize_f_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "getRandomPlayerAggroListTarget_f_s";
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// input params
|
|||
|
uint32 botIndex = (uint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get spawn bot by index of the bot
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || !group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(float(0) );
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
stack.push(float(0) );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// make a vector of aggroable player
|
|||
|
CBotAggroOwner::TBotAggroList const& aggroList = spBot->getBotAggroList();
|
|||
|
//typedef std::map<TDataSetRow, TAggroEntryPtr> TBotAggroList;
|
|||
|
CBotAggroOwner::TBotAggroList::const_iterator aggroIt(aggroList.begin()), aggroEnd(aggroList.end());
|
|||
|
TDataSetRow foundRow = TDataSetRow();
|
|||
|
|
|||
|
std::vector<TDataSetRow> playerAggroable;
|
|||
|
for (; aggroIt != aggroEnd; ++aggroIt)
|
|||
|
{
|
|||
|
if (CMirrors::getEntityId(aggroIt->first).getType() != RYZOMID::player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(aggroIt->first);
|
|||
|
if (!ep)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
CBotPlayer const* const player = NLMISC::safe_cast<CBotPlayer const*>(ep);
|
|||
|
if (!player)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (!player->isAggroable())
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
playerAggroable.push_back(aggroIt->first);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// return the size of the aggro list
|
|||
|
stack.push(float(playerAggroable.size()));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setAggroListTarget_fs_
|
|||
|
|
|||
|
Maximize the Aggro of a target from the Aggro list of one bot (this id can be given by getRandomPlayerAggroListTarget)..
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. If the entityId is not from the aggro list then a warning message is shown in the log. If the entityId is a empty string nothing no message are displayed.
|
|||
|
|
|||
|
Arguments: f(botIndex) >s(playerEidAsString) >
|
|||
|
@param[in] botIndex is the index of an bot member of the current group
|
|||
|
@param[in] playerEidAsString is EntityId of the player that will be attacked
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(4);
|
|||
|
()setAggroListTarget(4, $playerId);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void setAggroListTarget_fs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "setAggroListTarget_fs_";
|
|||
|
|
|||
|
|
|||
|
|
|||
|
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
|
|||
|
sint32 botIndex = (sint32)((float)stack.top());stack.pop();
|
|||
|
|
|||
|
// get the entity id
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
|
|||
|
// get the spawn bot by its indesx
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || !group->isSpawned() || botIndex <0 || group->bots().size() <= static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or group not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
return;
|
|||
|
}
|
|||
|
CBot* bot = group->getBot(botIndex);
|
|||
|
CSpawnBot* spBot = bot?bot->getSpawnObj():0;
|
|||
|
if (!spBot)
|
|||
|
{
|
|||
|
nlwarning("%s used bad index %d/%d (or bot not spawn)", funName.c_str(), botIndex, group->bots().size());
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// test if player eid is ok
|
|||
|
if (playerEidStr.empty()) { return; }
|
|||
|
TDataSetRow playerRow = TheDataset.getDataSetRow( playerEid );
|
|||
|
bool accessible = TheDataset.isAccessible( playerRow );
|
|||
|
bool pj = playerEid.getType() == RYZOMID::player;
|
|||
|
CAIEntityPhysical* ep = accessible && pj ? CAIS::instance().getEntityPhysical(playerRow):0;
|
|||
|
CBotPlayer const* const player = ep ? NLMISC::safe_cast<CBotPlayer const*>(ep):0;
|
|||
|
if (!ep || !player ||!player->isAggroable() )
|
|||
|
{
|
|||
|
nlwarning("Try to call %s with on a player '%s' that is not accessible (or not aggroable). The isPlayerAlived function must be called to be sure that the player is still alived.", funName.c_str(), playerEidStr.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// maximize aggro from the bot for the player
|
|||
|
spBot->maximizeAggroFor(playerRow);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setGroupAggroListTarget_s_
|
|||
|
|
|||
|
Maximize the Aggro of a target from the Aggro list of one bot to his group (this id can be given by getRandomPlayerAggroListTarget)..
|
|||
|
|
|||
|
A player EntityId is used to identify the player. If the entityId is not from the aggro list then a warning message is shown in the log. If the entityId is a empty string nothing no message are displayed.
|
|||
|
|
|||
|
Arguments: s(playerEidAsString) >
|
|||
|
@param[in] playerEidAsString is EntityId of the player that will be attacked by the group
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(4);
|
|||
|
()setGroupAggroListTarget($playerId);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void setGroupAggroListTarget_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "setGroupAggroListTarget_s_";
|
|||
|
|
|||
|
// read params
|
|||
|
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
|
|||
|
|
|||
|
// read eid of the player
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
|
|||
|
|
|||
|
// test if player eid is ok
|
|||
|
if (playerEidStr.empty()) { return; }
|
|||
|
TDataSetRow playerRow = TheDataset.getDataSetRow( playerEid );
|
|||
|
bool accessible = TheDataset.isAccessible( playerRow );
|
|||
|
bool pj = playerEid.getType() == RYZOMID::player;
|
|||
|
CAIEntityPhysical* ep = accessible && pj ? CAIS::instance().getEntityPhysical(playerRow):0;
|
|||
|
CBotPlayer const* const player = ep ? NLMISC::safe_cast<CBotPlayer const*>(ep):0;
|
|||
|
if (!ep || !player ||!player->isAggroable() )
|
|||
|
{
|
|||
|
nlwarning("Try to call %s with on a player '%s' that is not accessible (or not aggroable). The isPlayerAlived function must be called to be sure that the player is still alived.", funName.c_str(), playerEidStr.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// test if group is spawn
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || !group->isSpawned() || group->bots().isEmpty() )
|
|||
|
{
|
|||
|
nlwarning("Call %s on a empty/not spawned group", funName.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// apply maximizeAggroFor on all member of the group
|
|||
|
CCont<CBot>::iterator itBot = group->bots().begin();
|
|||
|
CCont<CBot>::iterator itEnd = group->bots().end();
|
|||
|
|
|||
|
for (; itBot != itEnd; ++itBot)
|
|||
|
{
|
|||
|
|
|||
|
CSpawnBot* spBot = itBot->getSpawnObj();
|
|||
|
if (!spBot) { continue; }
|
|||
|
spBot->maximizeAggroFor(playerRow);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection setManagerAggroListTarget_ss_
|
|||
|
|
|||
|
Maximize the Aggro of a target of one bot to some groups of his manage.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. If the entityId is not from the aggro list then a warning message is shown in the log. If the entityId is a empty string nothing no message are displayed.
|
|||
|
|
|||
|
A string is used to select groups of the manager (groups name must contains this string)
|
|||
|
|
|||
|
Arguments: f(botIndex), s(playerEidAsString) >
|
|||
|
@param[in] playerId is EntityId of the player
|
|||
|
@param[in] nameElement The element of the name of all group we are interest in.
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(0);
|
|||
|
()setManagerAggroListTarget($playerId, "group_bandit_"); // all group that have name like "group_bandit_*" will attack the player
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void setManagerAggroListTarget_ss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "setManagerAggroListTarget_ss_";
|
|||
|
|
|||
|
|
|||
|
// read params
|
|||
|
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
|
|||
|
std::string groupNameStr = ((std::string)stack.top()); stack.pop();
|
|||
|
|
|||
|
|
|||
|
// test if player eid is ok
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
|
|||
|
if (playerEidStr.empty()) { return; }
|
|||
|
TDataSetRow playerRow = TheDataset.getDataSetRow( playerEid );
|
|||
|
bool accessible = TheDataset.isAccessible( playerRow );
|
|||
|
bool pj = playerEid.getType() == RYZOMID::player;
|
|||
|
CAIEntityPhysical* ep = accessible && pj ? CAIS::instance().getEntityPhysical(playerRow):0;
|
|||
|
CBotPlayer const* const player = ep ? NLMISC::safe_cast<CBotPlayer const*>(ep):0;
|
|||
|
if (!ep || !player ||!player->isAggroable() )
|
|||
|
{
|
|||
|
nlwarning("Try to call %s with on a player '%s' that is not accessible (or not aggroable). The isPlayerAlived function must be called to be sure that the player is still alived.", funName.c_str(), playerEidStr.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group )
|
|||
|
{
|
|||
|
nlwarning("Call %s on a non exisiting group", funName.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
// get the manager of the group
|
|||
|
CManager* manager = group->getOwner();
|
|||
|
if (!manager)
|
|||
|
{
|
|||
|
nlwarning("Call %s on a non exisiting manager", funName.c_str() );
|
|||
|
return;
|
|||
|
}
|
|||
|
// for all group of the manager maximize aaggro *IF* the group name contains groupNameStr
|
|||
|
group=manager->getNextValidGroupChild();
|
|||
|
while (group!=NULL)
|
|||
|
{
|
|||
|
if ( ! (!group || !group->isSpawned() || group->bots().isEmpty() ) && group->getName().find(groupNameStr) != std::string::npos )
|
|||
|
{
|
|||
|
// apply maximizeAggroFor on all member of the group
|
|||
|
CCont<CBot>::iterator itBot = group->bots().begin();
|
|||
|
CCont<CBot>::iterator itEnd = group->bots().end();
|
|||
|
|
|||
|
for (; itBot != itEnd; ++itBot)
|
|||
|
{
|
|||
|
|
|||
|
CSpawnBot* spBot = itBot->getSpawnObj();
|
|||
|
if (!spBot) { continue; }
|
|||
|
spBot->maximizeAggroFor(playerRow);
|
|||
|
}
|
|||
|
}
|
|||
|
group = manager->getNextValidGroupChild(group);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getBotIndexByName_s_f
|
|||
|
|
|||
|
Get the index of a bot of a group by its name (or return -1). Mainly usefull for scripted boss.
|
|||
|
|
|||
|
botIndex begins at zero for the first member of the group, -1 if the bot is not found.
|
|||
|
|
|||
|
Arguments:, s(botName) > f(botIndex)
|
|||
|
|
|||
|
@param[in] name is the name of the bot
|
|||
|
@param[out] botIndex is the index of an bot member of the current group
|
|||
|
|
|||
|
@code
|
|||
|
(botIndex)getBotIndexByName("boss_random_aggro");
|
|||
|
($playerId)getRandomPlayerAggroListTarget(botIndex);
|
|||
|
()setAggroListTarget(botIndex, $playerId);
|
|||
|
}
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getBotIndexByName_s_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getBotIndexByName_s_f";
|
|||
|
|
|||
|
// read params
|
|||
|
std::string botName = (std::string)stack.top(); stack.pop();
|
|||
|
|
|||
|
// test if group is spawned
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group || group->bots().isEmpty() )
|
|||
|
{
|
|||
|
nlwarning("Call %s on a empty group", funName.c_str() );
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Search on all persistent bot of the groupe the bot that have the searched name
|
|||
|
CCont<CBot>::iterator itBot = group->bots().begin();
|
|||
|
CCont<CBot>::iterator itEnd = group->bots().end();
|
|||
|
|
|||
|
sint32 index = -1;
|
|||
|
for (; itBot != itEnd; ++itBot)
|
|||
|
{
|
|||
|
++index;
|
|||
|
const std::string& name = itBot->getName();
|
|||
|
if (name == botName)
|
|||
|
{
|
|||
|
stack.push((float)index);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Bot not found
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isGroupAlived__f
|
|||
|
|
|||
|
Test if a group is alived (at least one member is alived)
|
|||
|
|
|||
|
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid.
|
|||
|
If no bot are identified by the bot index (or bot not spawaned) the function display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.
|
|||
|
|
|||
|
|
|||
|
Arguments: s(playerid) > f(success)
|
|||
|
|
|||
|
@param[out] sucess is 1.0f if there is at least one member of the group alived (0.0f if not alived bot are found)
|
|||
|
|
|||
|
@code
|
|||
|
($alived)isGroupAlived();
|
|||
|
if ($alived == 1.0f) {
|
|||
|
}
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
void isGroupAlived__f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
isAlived__f(entity, stack);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isBotAlived_f_f
|
|||
|
|
|||
|
Test if a bot of the current group is alived. The bot is identified by its index.
|
|||
|
|
|||
|
Arguments: f(botIndex) > f(success)
|
|||
|
|
|||
|
@param[int] botIndex the index of the bot.
|
|||
|
@param[out] sucess is 1.0f if there is at least one member of the group alived (0.0f if not alived bot are found)
|
|||
|
|
|||
|
@code
|
|||
|
($botIndex)getBotIndexByName("boss_3");
|
|||
|
$alived)isBotAlived($botIndex);
|
|||
|
if (alived == 1.0f) {
|
|||
|
}
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
void isBotAlived_f_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "isBotAlived_f_f";
|
|||
|
// get input index
|
|||
|
sint32 botIndex = (sint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
// get Spawn Bot
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
stack.push((float)0);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!group->isSpawned() || group->bots().isEmpty() || botIndex < 0 || group->bots().size() < static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
stack.push(0.0f);return;
|
|||
|
}
|
|||
|
const CBot *const bot = group->getBot(botIndex);
|
|||
|
if ( !bot || !bot->isSpawned()) { stack.push(0.0f); return;};
|
|||
|
CAIEntityPhysical *const ep=bot->getSpawnObj();
|
|||
|
if ( !ep) { stack.push(0.0f); return;};
|
|||
|
|
|||
|
// test if spawn bot is alive
|
|||
|
if (ep->isAlive()) { stack.push(1.0f); return;}
|
|||
|
|
|||
|
stack.push(0.0f);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection isPlayerAlived_s_f
|
|||
|
|
|||
|
Test if a a player is is alived.
|
|||
|
|
|||
|
A player EntityId is used to identify the player. If the player is not connected, not in the same continent, or dead 0 is returned.
|
|||
|
|
|||
|
Arguments: s(playerId) > f(success)
|
|||
|
|
|||
|
@param[in] palyerId
|
|||
|
@param[out] success is 1.0f if the entity id of a player is alived.
|
|||
|
|
|||
|
@code
|
|||
|
($botIndex)getBotIndexByName("boss_3");
|
|||
|
($playerId)getCurrentPlayerAggroListTarget($botIndex):
|
|||
|
(alived)isPlayerlived($playerId);
|
|||
|
if (alived == 1.0f) {
|
|||
|
}
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void isPlayerAlived_s_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
// get input data
|
|||
|
std::string playerEidStr = (std::string)stack.top(); stack.pop();
|
|||
|
|
|||
|
//get CAIEntityPhysical of the player
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
TDataSetRow playeDataSetRow = TheDataset.getDataSetRow( playerEid) ;
|
|||
|
if (playerEidStr.empty() || !TheDataset.isAccessible( playeDataSetRow ) || playerEid.getType() != RYZOMID::player )
|
|||
|
{
|
|||
|
stack.push(0.0f); return;
|
|||
|
}
|
|||
|
CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(playeDataSetRow);
|
|||
|
if (!ep)
|
|||
|
{
|
|||
|
|
|||
|
stack.push(0.0f); return;
|
|||
|
}
|
|||
|
// test if the player is alived
|
|||
|
if (ep->isAlive())
|
|||
|
{
|
|||
|
stack.push(1.0f); return;
|
|||
|
}
|
|||
|
|
|||
|
stack.push(0.0f); return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
@subsection getServerTimeStr__s
|
|||
|
|
|||
|
Gets the server time as string "eg 21:17:14 the x"
|
|||
|
This function is usefull for stat purpose or debug (to know when a boss is down)
|
|||
|
|
|||
|
Arguments: > s(serverTime)
|
|||
|
|
|||
|
|
|||
|
@param[out] The server time as debug string
|
|||
|
|
|||
|
@code
|
|||
|
($serverTime)getServerTimeAsString();
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void getServerTimeStr__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
//get the server time (as debug string)
|
|||
|
time_t currentTime;
|
|||
|
time( ¤tTime );
|
|||
|
std::string str = NLMISC::toString("%s", asctime(localtime(¤tTime)));
|
|||
|
stack.push(str);
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
@subsection getServerTime__s
|
|||
|
|
|||
|
Gets the server time as number (it is the number of seconde since 1970). This value is useful for saving the server date on a file
|
|||
|
|
|||
|
Arguments: > s(serverTime)
|
|||
|
|
|||
|
@param[out] The server time as string (a float is not sharp enough
|
|||
|
|
|||
|
@code
|
|||
|
($serverTime)getServerTime();
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void getServerTime__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
//get the server time (as time stamp)
|
|||
|
time_t currentTime;
|
|||
|
time( ¤tTime );
|
|||
|
std::string ret = NLMISC::toString("%d", currentTime);
|
|||
|
// convert to string
|
|||
|
stack.push((std::string)ret);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
@subsection getRyzomDateStr__s
|
|||
|
|
|||
|
Gets the ryzom date as string
|
|||
|
Arguments: > s(ryzomDateStr)
|
|||
|
|
|||
|
@param[out] ryzomTimeAndDateAsString The time and date of the ryzom univers as debug string.
|
|||
|
|
|||
|
@code
|
|||
|
($ryzomDateStr)getRyzomDateStr);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getRyzomDateStr__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
// Display time using ryzom style
|
|||
|
std::string result;
|
|||
|
const CRyzomTime &rt = CTimeInterface::getRyzomTime();
|
|||
|
result = NLMISC::toString("%d:%d:00", (int) floorf(rt.getRyzomTime()) , (int) floorf(60.f * fmodf(rt.getRyzomTime(), 1.f)));
|
|||
|
|
|||
|
uint32 month = rt.getRyzomMonth();
|
|||
|
MONTH::EMonth monthInCycle = rt.getRyzomMonthInCurrentCycle();
|
|||
|
std::string monthName = MONTH::toString((MONTH::EMonth) monthInCycle);
|
|||
|
uint32 dayOfMonth = rt.getRyzomDayOfMonth();
|
|||
|
std::string dayName = WEEKDAY::toString((WEEKDAY::EWeekDay) rt.getRyzomDayOfWeek());
|
|||
|
result += NLMISC::toString(" / %s %d %s(%d) %d",
|
|||
|
dayName.c_str(),
|
|||
|
(int) (dayOfMonth + 1),
|
|||
|
monthName.c_str(),
|
|||
|
(int) (month + 1),
|
|||
|
(int) rt.getRyzomYear());
|
|||
|
|
|||
|
stack.push( result );
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
@subsection getRyzomDate__s
|
|||
|
|
|||
|
Gets the ryzom tick game cycle. Useful for computing difference of time.
|
|||
|
The return value is a string and not a float because float is not sharp enought?
|
|||
|
Arguments: > s(tickGameCycle)
|
|||
|
|
|||
|
@param[out] TickGameCycle The time of the ryzom univers (stops when server stops). 10 tick is 1 second.
|
|||
|
|
|||
|
@code
|
|||
|
($tickGameCycle)getRyzomDate();
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getRyzomDate__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
//get GameTickCycle
|
|||
|
const NLMISC::TGameCycle ryzomTime= CTickEventHandler::getGameCycle();
|
|||
|
std::string ret = NLMISC::toString("%d", ryzomTime);
|
|||
|
// convert to string
|
|||
|
stack.push((std::string)ret);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
class CPhraseParameters
|
|||
|
{
|
|||
|
public:
|
|||
|
enum TMode {NpcMsg, SystemMsg, EmoteMsg};
|
|||
|
TVectorParamCheck Values;
|
|||
|
};
|
|||
|
|
|||
|
CPhraseParameters PhraseParameters;
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phraseBegin__
|
|||
|
Clear the parameters stack.
|
|||
|
|
|||
|
Used when creating a customized msg via phraseEndSystemMsg_fss_, phraseEndNpcMsg_fss_, phraseEndSystemMsg_fss_.
|
|||
|
It Must be called at start of phrase if we are not sure that the parameter stack is clean.
|
|||
|
|
|||
|
Parameter stack is unclean when someone has called a phrasePush* function but *not* a phraseEnd function before (which is *very* bad).
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
@code
|
|||
|
()phraseBegin();
|
|||
|
()phrasePushValue("money", 15);
|
|||
|
()phrasePushValue("integer", 15);
|
|||
|
()phrasePushValue("time", 15);
|
|||
|
()phraseEndSystemMsg(0, "say", "PHRASE_FROM_PHRASE_WITH_3_PARAMETERS");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void phraseBegin__(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phrasePushValue_sf_
|
|||
|
This function push a value as number on the parameter stack. This stack is used by phraseEndSystemMsg_fss_, phraseEndNpcMsg_fss_, phraseEndSystemMsg_fss_ functions.
|
|||
|
@see phraseBegin__
|
|||
|
@see phrasePushString_ss_
|
|||
|
@see phraseEndSystemMsg_fss_
|
|||
|
@see phraseEndNpcMsg_fss_
|
|||
|
@see phraseEndSystemMsg_fss_
|
|||
|
|
|||
|
|
|||
|
The value *Must* be an number and only few type are handled.
|
|||
|
- money
|
|||
|
- integer
|
|||
|
- time
|
|||
|
|
|||
|
Some value other can be handled *BUT* the value *MUST* be the C++ code enum value. So LD must ask to coder to do a scripting fonction that have as input a string that contains enum value as string eg "matis" and that return the C++ enum value as int (eg 4).
|
|||
|
- skill
|
|||
|
- faction
|
|||
|
- power_type
|
|||
|
- race
|
|||
|
- damage_type
|
|||
|
- characteristic
|
|||
|
- score
|
|||
|
- body_part
|
|||
|
|
|||
|
Arguments: s(paramType), f(value) ->
|
|||
|
@param[in] paramType the type of the parameter
|
|||
|
@param[in] value the value of the parameter
|
|||
|
|
|||
|
|
|||
|
@code
|
|||
|
()phraseBegin();
|
|||
|
()phrasePushValue("money", 15);
|
|||
|
()phrasePushValue("integer", 15);
|
|||
|
()phrasePushValue("time", 15);
|
|||
|
()phraseEndSystemMsg(0, "say", "PHRASE_WITH_3_PARAMETERS");
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CGroup
|
|||
|
void phrasePushValue_sf_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
float f = (float)stack.top();stack.pop(); // get the value as float
|
|||
|
std::string typeStr = (std::string)stack.top(); stack.pop(); // get the param type
|
|||
|
// create the good STRING_MANAGER::TParam in fonction of its type and is value
|
|||
|
STRING_MANAGER::TParamType type = STRING_MANAGER::stringToParamType(typeStr);
|
|||
|
STRING_MANAGER::TParam param;
|
|||
|
param.Type = type;
|
|||
|
switch( type )
|
|||
|
{
|
|||
|
|
|||
|
case STRING_MANAGER::money:
|
|||
|
{
|
|||
|
param.Money = static_cast<uint64>(f);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
case STRING_MANAGER::integer:
|
|||
|
{
|
|||
|
param.Int = static_cast<sint32>(f);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::time:
|
|||
|
{
|
|||
|
param.Time = static_cast<uint32>(f);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::skill:
|
|||
|
case STRING_MANAGER::faction:
|
|||
|
case STRING_MANAGER::power_type:
|
|||
|
case STRING_MANAGER::race:
|
|||
|
case STRING_MANAGER::damage_type:
|
|||
|
case STRING_MANAGER::characteristic:
|
|||
|
case STRING_MANAGER::score:
|
|||
|
case STRING_MANAGER::body_part:
|
|||
|
{
|
|||
|
param.Enum = static_cast<uint32>( f );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
param.Type = STRING_MANAGER::invalid_value;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
PhraseParameters.Values.push_back(param);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phrasePushString_ss_
|
|||
|
This function push a value as string on the parameter stack. This stack is used by phraseEndSystemMsg_fss_, phraseEndNpcMsg_fss_, phraseEndSystemMsg_fss_ functions.
|
|||
|
@see phraseBegin__
|
|||
|
@see phrasePushValue_sf_
|
|||
|
@see phraseEndSystemMsg_fss_
|
|||
|
@see phraseEndNpcMsg_fss_
|
|||
|
@see phraseEndSystemMsg_fss_
|
|||
|
|
|||
|
|
|||
|
The value *Must* be a string.
|
|||
|
The string is internal converted to number, sheetId, entityId when needed.
|
|||
|
|
|||
|
Input as a number:
|
|||
|
- money
|
|||
|
- integer
|
|||
|
- time
|
|||
|
|
|||
|
Input as string literal
|
|||
|
- literal
|
|||
|
|
|||
|
Input as an entityId (obtains via getCurrentPlayerAggroListTarget_f_s, getRandomPlayerAggroListTarget_f_s, getBotEid_f_s, getCurrentSpeakerEid__s, getAggroListElement_ff_s)
|
|||
|
- player
|
|||
|
- bot
|
|||
|
- entity
|
|||
|
|
|||
|
Input as sheetId name (example: "toto.sbrick", "toto.sitem", "toto.creature")
|
|||
|
- item
|
|||
|
- outpost
|
|||
|
- creature_model
|
|||
|
- creature
|
|||
|
- sphrase
|
|||
|
- sbrick
|
|||
|
|
|||
|
Input as string identifier
|
|||
|
- place
|
|||
|
- event_faction
|
|||
|
- title
|
|||
|
- bot_name
|
|||
|
|
|||
|
Input as stringId (number): *WARNING* LD must as coder to do function that return string_id if they want to use that type
|
|||
|
- dyn_string_id
|
|||
|
- string_id
|
|||
|
|
|||
|
|
|||
|
Input must be a enum value:
|
|||
|
Some value other can be handled *BUT* the value *MUST* be the C++ code enum value. So LD must ask to coder to do a scripting fonction that have as input a string that contains enum value as string eg "matis" and that return the C++ enum value as int (eg 4).
|
|||
|
- skill
|
|||
|
- faction
|
|||
|
- power_type
|
|||
|
- race
|
|||
|
- damage_type
|
|||
|
- characteristic
|
|||
|
- score
|
|||
|
- body_part
|
|||
|
|
|||
|
Arguments: s(paramType), f(value) ->
|
|||
|
@param[in] paramType the type of the parameter
|
|||
|
@param[in] value the value of the parameter
|
|||
|
|
|||
|
|
|||
|
@code
|
|||
|
($playerEid)getCurrentPlayerEid();
|
|||
|
($botEid)group3.getBotEid(4);
|
|||
|
()phraseBegin();
|
|||
|
()phrasePushValue("integer", 15);
|
|||
|
()phrasePushString("integer", "15");
|
|||
|
()phrasePushString("literal", "Test 123");
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()phrasePushString("bot", $botEid);
|
|||
|
()phrasePushString("item", "abc.sitem");
|
|||
|
()phrasePushString("sbrick", "toto.sbrick");
|
|||
|
()phrasePushString("creature_model", "toto.creature");
|
|||
|
()phraseEndSystemMsg(0, "say", "PHRASE_WITH_SOME_PARAMETERS");
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void phrasePushString_ss_(CStateInstance* entity, CScriptStack& stack )
|
|||
|
{
|
|||
|
std::string s = (std::string)stack.top(); stack.pop(); // get the param value
|
|||
|
std::string typeStr = (std::string)stack.top(); stack.pop(); // get the param type
|
|||
|
|
|||
|
// construct a STRING_MANAGER::TParam in fonction of its type and its value
|
|||
|
STRING_MANAGER::TParamType type = STRING_MANAGER::stringToParamType(typeStr);
|
|||
|
STRING_MANAGER::TParam param;
|
|||
|
param.Type = type;
|
|||
|
switch( type )
|
|||
|
{
|
|||
|
|
|||
|
case STRING_MANAGER::money:
|
|||
|
{
|
|||
|
param.Money = static_cast<uint64>(atoi( s.c_str() ));
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::player:
|
|||
|
case STRING_MANAGER::bot:
|
|||
|
case STRING_MANAGER::entity:
|
|||
|
{
|
|||
|
|
|||
|
NLMISC::CEntityId id;
|
|||
|
uint32 alias = 0;
|
|||
|
id.fromString(s.c_str());
|
|||
|
CAIEntityPhysical* entityPhysical=CAIS::instance().getEntityPhysical(TheDataset.getDataSetRow(id));
|
|||
|
if (entityPhysical)
|
|||
|
{
|
|||
|
switch( entityPhysical->getRyzomType())
|
|||
|
{
|
|||
|
case RYZOMID::creature:
|
|||
|
case RYZOMID::npc:
|
|||
|
{
|
|||
|
|
|||
|
CSpawnBot* sb = NLMISC::safe_cast<CSpawnBot*>(entityPhysical);
|
|||
|
alias = sb->getPersistent().getAlias();
|
|||
|
break;
|
|||
|
}
|
|||
|
default:
|
|||
|
;
|
|||
|
// player or other have no alias
|
|||
|
}
|
|||
|
}
|
|||
|
param.setEIdAIAlias( id, alias );
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case STRING_MANAGER::integer:
|
|||
|
{
|
|||
|
param.Int = atoi( s.c_str());
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::time:
|
|||
|
{
|
|||
|
param.Time = atoi( s.c_str());
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
case STRING_MANAGER::item:
|
|||
|
case STRING_MANAGER::outpost:
|
|||
|
case STRING_MANAGER::creature_model:
|
|||
|
case STRING_MANAGER::creature:
|
|||
|
case STRING_MANAGER::sphrase:
|
|||
|
case STRING_MANAGER::sbrick:
|
|||
|
{
|
|||
|
if (s.empty())
|
|||
|
{
|
|||
|
nlwarning("Sheet name expected but not found in script");
|
|||
|
param.SheetId= CSheetId();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
param.SheetId = CSheetId(s);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
case STRING_MANAGER::place:
|
|||
|
case STRING_MANAGER::event_faction:
|
|||
|
case STRING_MANAGER::title:
|
|||
|
case STRING_MANAGER::bot_name:
|
|||
|
{
|
|||
|
param.Identifier = s;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::skill:
|
|||
|
case STRING_MANAGER::faction:
|
|||
|
case STRING_MANAGER::power_type:
|
|||
|
case STRING_MANAGER::race:
|
|||
|
case STRING_MANAGER::damage_type:
|
|||
|
case STRING_MANAGER::characteristic:
|
|||
|
case STRING_MANAGER::score:
|
|||
|
case STRING_MANAGER::body_part:
|
|||
|
{
|
|||
|
param.Enum = static_cast<uint32>( atoi( s.c_str()) );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
case STRING_MANAGER::literal:
|
|||
|
param.Literal.fromUtf8(s);
|
|||
|
break;
|
|||
|
|
|||
|
case STRING_MANAGER::dyn_string_id:
|
|||
|
case STRING_MANAGER::string_id:
|
|||
|
param.StringId = static_cast<uint32>( atoi( s.c_str()) );
|
|||
|
break;
|
|||
|
|
|||
|
case STRING_MANAGER::self:
|
|||
|
case STRING_MANAGER::role:
|
|||
|
case STRING_MANAGER::compass:
|
|||
|
case STRING_MANAGER::guild:
|
|||
|
case STRING_MANAGER::ecosystem:
|
|||
|
case STRING_MANAGER::classification_type:
|
|||
|
default:
|
|||
|
param.Type = STRING_MANAGER::invalid_value;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
PhraseParameters.Values.push_back(param);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void phraseEnd(CStateInstance* entity, CScriptStack& stack, CPhraseParameters::TMode mode)
|
|||
|
{
|
|||
|
std::string funName = "phraseEnd";
|
|||
|
|
|||
|
// get Function parameters
|
|||
|
|
|||
|
std::string phraseId = (std::string)stack.top();stack.pop();
|
|||
|
std::string sayMode;
|
|||
|
if (mode != CPhraseParameters::EmoteMsg)
|
|||
|
{
|
|||
|
sayMode = (std::string)stack.top();stack.pop();
|
|||
|
}
|
|||
|
sint32 botIndex = (sint32)((float)stack.top());stack.pop();
|
|||
|
|
|||
|
|
|||
|
// Verify is bot is alived
|
|||
|
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!group->isSpawned() || group->bots().isEmpty() || botIndex < 0 || group->bots().size() < static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
const CBot *const bot = group->getBot(botIndex);
|
|||
|
if ( !bot || !bot->isSpawned())
|
|||
|
{
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
CSpawnBot *const sp= bot->getSpawnObj();
|
|||
|
if ( !sp || !sp->isAlive() )
|
|||
|
{
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// parse type of chat
|
|||
|
CChatGroup::TGroupType groupType;
|
|||
|
if (mode != CPhraseParameters::EmoteMsg)
|
|||
|
{
|
|||
|
groupType = CChatGroup::stringToGroupType(sayMode);
|
|||
|
}
|
|||
|
|
|||
|
// verify phraseId validity
|
|||
|
if (phraseId.empty())
|
|||
|
{
|
|||
|
nlwarning("%s %d: Phrase identifier is empty", funName.c_str(),static_cast<uint32>(mode));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// send chat to client
|
|||
|
switch (mode)
|
|||
|
{
|
|||
|
case CPhraseParameters::NpcMsg:
|
|||
|
npcChatParamToChannel(sp->dataSetRow(), groupType, phraseId.c_str(), PhraseParameters.Values);
|
|||
|
break;
|
|||
|
case CPhraseParameters::SystemMsg:
|
|||
|
STRING_MANAGER::sendSystemStringToClientAudience(sp->dataSetRow(),std::vector<NLMISC::CEntityId>(), groupType, phraseId.c_str(), PhraseParameters.Values);
|
|||
|
break;
|
|||
|
|
|||
|
case CPhraseParameters::EmoteMsg:
|
|||
|
STRING_MANAGER::sendCustomEmoteTextToClientAudience(sp->dataSetRow(),std::vector<NLMISC::CEntityId>(), phraseId.c_str(), PhraseParameters.Values);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
PhraseParameters.Values.clear();
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phraseEndNpcMsg_fss_
|
|||
|
Send a message with parameter through a bot says.
|
|||
|
Parameters are taken from the parameters stack.
|
|||
|
@see phrasePushValue_sf_
|
|||
|
@see phrasePushString_ss_
|
|||
|
|
|||
|
Arguments: s(botIndex), s(sayType), s(phraseIdentifier) ->
|
|||
|
@param[in] botIndex the Position of the bot in the group ( see getBotIndexByName_s_f)
|
|||
|
@param[in] sayType Is the type of the say dialog ("say", "shout", "civilization", "territory", "universe", "arround", "system", "region")
|
|||
|
@param[in] phraseIdentifier Is the identifier phrase as seen in phrase_wk.uxt
|
|||
|
|
|||
|
@code
|
|||
|
()phrasePushString("literal", "text non traduit");
|
|||
|
()groupOf5Bot.phraseEndNpcMsg(4, "say", "PHRASE_TOTO");
|
|||
|
@endcode
|
|||
|
|
|||
|
WARNING
|
|||
|
In this case in the phrase_wk.txt PHRASE_TOTO must be defined as
|
|||
|
@code
|
|||
|
PHRASE_TOTO(bot b, literal l)
|
|||
|
{
|
|||
|
[I am $b$, on this text is not translated $l$ ]
|
|||
|
}
|
|||
|
@endcode
|
|||
|
|
|||
|
The first parameter is ALWAYS the bot that says the text (value is automaticaly set)
|
|||
|
*/
|
|||
|
void phraseEndNpcMsg_fss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
phraseEnd(entity, stack, CPhraseParameters::NpcMsg);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phraseEndSystemMsg_fss_
|
|||
|
Send a message with parameter through system braodcast msg.
|
|||
|
Parameters are taken from the parameters stack.
|
|||
|
@see phrasePushValue_sf_
|
|||
|
@see phrasePushString_ss_
|
|||
|
|
|||
|
Arguments: s(botIndex), s(sayType), s(phraseIdentifier) ->
|
|||
|
@param[in] botIndex the Position of the bot in the group ( see getBotIndexByName_s_f)
|
|||
|
@param[in] sayType Is the type of the say dialog ("say", "shout", "civilization", "territory", "universe", "arround", "system", "region")
|
|||
|
@param[in] phraseIdentifier Is the identifier phrase as seen in phrase_wk.uxt
|
|||
|
|
|||
|
@code
|
|||
|
()phrasePushString("literal", "Test des levels designer");
|
|||
|
()groupOf5Bot.phraseEndSystemMsg(4, "say", "PHRASE_TOTO");
|
|||
|
@endcode
|
|||
|
|
|||
|
*WARNING*
|
|||
|
In this case in the phrase_wk.txt PHRASE_TOTO must be defined as
|
|||
|
@code
|
|||
|
PHRASE_TOTO(literal l)
|
|||
|
{
|
|||
|
[$l$]
|
|||
|
}
|
|||
|
@endcode
|
|||
|
The first parameter is *NOT* automaticaly set to the bot that send the system msg as phraseEndNpcMsg_fss_.
|
|||
|
|
|||
|
Because the msg can be send as "around". The broadcas msg must be send by a bot (that have a valid position)
|
|||
|
*/
|
|||
|
void phraseEndSystemMsg_fss_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
phraseEnd(entity, stack, CPhraseParameters::SystemMsg);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection phraseEndEmoteMsg_fs_
|
|||
|
Send a custom emote message with parameter through system braodcast msg.
|
|||
|
Parameters are taken from the parameters stack.
|
|||
|
@see phrasePushValue_sf_
|
|||
|
@see phrasePushString_ss_
|
|||
|
|
|||
|
Arguments: s(botIndex), s(phraseIdentifier) ->
|
|||
|
@param[in] botIndex the Position of the bot in the group ( see getBotIndexByName_s_f)
|
|||
|
@param[in] phraseIdentifier Is the identifier phrase as seen in phrase_wk.uxt
|
|||
|
|
|||
|
@code
|
|||
|
($playerEid)getCurrentPlayerEid();
|
|||
|
($botEid)getCurrentSpeakerEid();
|
|||
|
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()groupOf5Bot.phraseEndEmoteMsg(,"PHRASE_TOTO1");
|
|||
|
|
|||
|
()phrasePushString("bot", $botEid);
|
|||
|
()groupOf5Bot.phraseEndEmoteMsg(,"PHRASE_TOTO2");
|
|||
|
@endcode
|
|||
|
|
|||
|
*WARNING*
|
|||
|
In this case in the phrase_wk.txt PHRASE_TOTO must be defined as
|
|||
|
@code
|
|||
|
PHRASE_TOTO1(player p)
|
|||
|
{
|
|||
|
[$p$ is laughing ]
|
|||
|
}
|
|||
|
PHRASE_TOTO2(bot b)
|
|||
|
{
|
|||
|
[$b$ is sad ]
|
|||
|
}
|
|||
|
@endcode
|
|||
|
The first parameter is NOT automaticaly the bot that says the text as phraseEndNpcMsg_fss_ because a bot can make a player doing a emote text.
|
|||
|
|
|||
|
The emote msg must be send by a bot (that have a valid position).
|
|||
|
*/
|
|||
|
void phraseEndEmoteMsg_fs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
phraseEnd(entity, stack, CPhraseParameters::EmoteMsg);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection queryEgs_sscfs_
|
|||
|
Send a query msg to egs to know infos on a player.
|
|||
|
Answer is asynchronous so we have to indicates a group and a user event that will be triggered when answer will come back to AIS
|
|||
|
|
|||
|
Possible info to know are
|
|||
|
- Name
|
|||
|
- Hp
|
|||
|
- MaxHp
|
|||
|
- RatioHp
|
|||
|
- Sap
|
|||
|
- MaxSap
|
|||
|
- RatioSap
|
|||
|
- Focus
|
|||
|
- MaxFocus
|
|||
|
- RatioFocus
|
|||
|
- Stamina
|
|||
|
- MaxStamina
|
|||
|
- RatioStamina
|
|||
|
|
|||
|
|
|||
|
Arguments: s(botIndex), s(query), c(groupThatWillBeTriggered), f(idOfTheUserEvent), s(msgId)
|
|||
|
@param[in] botIndex the Position of the bot in the group ( see getBotIndexByName_s_f)
|
|||
|
@param[in] query The query we want to send
|
|||
|
@param[in] groupThatWillBeTriggered The group that will receive a user_event when the answer will come
|
|||
|
@param[in] idOfTheUserEvent The number of the user event that will be triggered
|
|||
|
@param[in] msgId The id of the msg
|
|||
|
|
|||
|
Answer will be given by the getParam
|
|||
|
|
|||
|
@code
|
|||
|
//Sening msg to EGS
|
|||
|
(@groupToNotify)boss_group.context();
|
|||
|
()queryEgs("Name", $playerEid, @groupToNotify, 4, "MSG_NAME");
|
|||
|
()queryEgs("Hp", $playerEid, @groupToNotify, 4, "msg1");
|
|||
|
()queryEgs("MaxHp", $playerEid, @groupToNotify, 4, "msg2");
|
|||
|
()queryEgs("RatioHp", $playerEid, @groupToNotify, 4, "msg3");
|
|||
|
()queryEgs("Sap", $playerEid, @groupToNotify, 4, "msg4");
|
|||
|
()queryEgs("MaxSap", $playerEid, @groupToNotify, 4, "msg5");
|
|||
|
()queryEgs("RatioSap", $playerEid, @groupToNotify, 4, "msg6");
|
|||
|
()queryEgs("Focus", $playerEid, @groupToNotify, 4, "msg7");
|
|||
|
()queryEgs("MaxFocus", $playerEid, @groupToNotify, 4, "msg8");
|
|||
|
()queryEgs("RatioFocus", $playerEid, @groupToNotify, 4, "msg9");
|
|||
|
()queryEgs("Stamina", $playerEid, @groupToNotify, 4, "msg10");
|
|||
|
()queryEgs("MaxStamina", $playerEid, @groupToNotify, 4, "msg11");
|
|||
|
()queryEgs("RatioStamina", $playerEid, @groupToNotify, 4, "msg12");
|
|||
|
()queryEgs("BestSkillLevel", $playerEid, @groupToNotify, 4, "msg13");
|
|||
|
@endcode
|
|||
|
Answer of the EGS
|
|||
|
@code
|
|||
|
// the user_event 4 of groupToNotify will be trigered
|
|||
|
($msgName)getEventParam(0); // the msg name
|
|||
|
($ret)getEventParam(1); // the return
|
|||
|
($funName)getEventParam(2); // the name of the function
|
|||
|
($playerEid)getEventParam(3); // the id of the player
|
|||
|
($param1)getEventParam(4); // empty ot item, or sbrick or botEid
|
|||
|
|
|||
|
if ($msgName == "MSG_NAME") {
|
|||
|
()phrasePushString("literal", $ret);
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_MSG");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()phrasePushString("literal", $funName);
|
|||
|
()phrasePushString("literal", $msgName);
|
|||
|
()phrasePushString("integer", $ret);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_EGS_QUERY");
|
|||
|
|
|||
|
}
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
void queryEgs_sscfs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "queryEgs_sscfs_";
|
|||
|
// read input params
|
|||
|
string literal = (string)stack.top(); stack.pop();
|
|||
|
float useEventId = (float)stack.top(); stack.pop();
|
|||
|
CGroupNpc* const groupToNotify = dynamic_cast<CGroupNpc*>( (IScriptContext*)stack.top() ); stack.pop();
|
|||
|
string param1 = (string)stack.top(); stack.pop();
|
|||
|
string func = (string)stack.top(); stack.pop();
|
|||
|
|
|||
|
// create a CUserEventMsg to send to EGS
|
|||
|
CGroup* const group = entity ? entity->getGroup() : 0;
|
|||
|
IManagerParent* const managerParent = (group&& group->getOwner()) ? group->getOwner()->getOwner():0;
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (aiInstance == NULL)
|
|||
|
{
|
|||
|
nlwarning("%s failed: the AI instance of the entity is NULL", funName.c_str());
|
|||
|
DEBUG_STOP;
|
|||
|
return;
|
|||
|
}
|
|||
|
CQueryEgs msg;
|
|||
|
msg.InstanceId = aiInstance->getInstanceNumber();
|
|||
|
msg.GroupAlias = groupToNotify->getAlias();
|
|||
|
msg.EventId = (int)useEventId;
|
|||
|
msg.Params.push_back(literal);
|
|||
|
msg.Params.push_back(func);
|
|||
|
msg.Params.push_back(param1);
|
|||
|
msg.send("EGS");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
@subsection queryEgs_ssscfs_
|
|||
|
Send a query msg to egs to know infos on a player.
|
|||
|
Answer is asynchronous so we have to indicates a group and a user event that will be triggered when answer will come back to AIS
|
|||
|
|
|||
|
Possible info to know are:
|
|||
|
- KnowBrick (to knwo if the player know a specific brick); return value is 0 or 1 (if the player know the brick)
|
|||
|
- IsInInventory (to knwo has an item in inventory of in equipement); return value is 0, 1(item in equipment), 2(item in bag)
|
|||
|
- Target (to know if a player target a bot; return value is 0, 1(player target the bot)
|
|||
|
|
|||
|
Arguments: s(botIndex), s(query), s(queryParam), c(groupThatWillBeTriggered), f(idOfTheUserEvent), s(msgId)
|
|||
|
@param[in] botIndex the Position of the bot in the group ( see getBotIndexByName_s_f)
|
|||
|
@param[in] query The query we want to send
|
|||
|
@param[in] queryParam Is the paramter of the query (a .creature of IsInInventory, a .sbrick for KnowBrick, a Bot EntityId for Target
|
|||
|
@param[in] groupThatWillBeTriggered The group that will receive a user_event when the answer will come
|
|||
|
@param[in] idOfTheUserEvent The number of the user event that will be triggered
|
|||
|
@param[in] msgId The id of the msg
|
|||
|
|
|||
|
Answer will be given by the getParam
|
|||
|
@code
|
|||
|
//Sening msg to EGS
|
|||
|
//($playerEid)getCurrentPlayerEid();
|
|||
|
(@groupToNotify)boss_group.context();
|
|||
|
()queryEgs("KnowBrick", $playerEid, "bfma01.sbrick", @groupToNotify, 4, "MSG_BRICK");
|
|||
|
()queryEgs("IsInInventory", $playerEid, "iccm1bm.sitem", @groupToNotify, 4, "MSG_ITEM");
|
|||
|
()queryEgs("Target", $playerEid, $botEid, @groupToNotify, 4, "msg14");
|
|||
|
@endcode
|
|||
|
|
|||
|
Answer of the EGS
|
|||
|
@code
|
|||
|
($msgName)getEventParam(0); // the msg name
|
|||
|
($ret)getEventParam(1); // the return
|
|||
|
($funName)getEventParam(2); // the name of the function
|
|||
|
($playerEid)getEventParam(3); // the id of the player
|
|||
|
($param1)getEventParam(4); // empty ot item, or sbrick or botEid
|
|||
|
|
|||
|
if ($msgName == "MSG_ITEM")
|
|||
|
{
|
|||
|
()phrasePushString("item", $param1);
|
|||
|
()phrasePushString("integer", $ret);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_EGS_QUERY_ITEM");
|
|||
|
} else if ($msgName == "MSG_BRICK") {
|
|||
|
()phrasePushString("sbrick", $param1);
|
|||
|
()phrasePushString("integer", $ret);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_EGS_QUERY_BRICK");
|
|||
|
|
|||
|
} else if ($msgName == "MSG_NAME") {
|
|||
|
()phrasePushString("literal", $ret);
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_MSG");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
()phrasePushString("player", $playerEid);
|
|||
|
()phrasePushString("literal", $funName);
|
|||
|
()phrasePushString("literal", $msgName);
|
|||
|
()phrasePushString("integer", $ret);
|
|||
|
()boss_group.phraseEndNpcMsg(0, "say", "TEST_BOSS_TEST_EGS_QUERY");
|
|||
|
|
|||
|
}
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void queryEgs_ssscfs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "queryEgs_ssscfs_";
|
|||
|
// get input params
|
|||
|
string literal = (string)stack.top(); stack.pop();
|
|||
|
float useEventId = (float)stack.top(); stack.pop();
|
|||
|
CGroupNpc* const groupToNotify = dynamic_cast<CGroupNpc*>( (IScriptContext*)stack.top() ); stack.pop();
|
|||
|
string param2 = (string)stack.top(); stack.pop();
|
|||
|
string param1 = (string)stack.top(); stack.pop();
|
|||
|
string func = (string)stack.top(); stack.pop();
|
|||
|
|
|||
|
// create CQueryEgs to send to egs
|
|||
|
CGroup* const group = entity ? entity->getGroup() : 0;
|
|||
|
IManagerParent* const managerParent = (group&& group->getOwner()) ? group->getOwner()->getOwner():0;
|
|||
|
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
|
|||
|
if (aiInstance == NULL)
|
|||
|
{
|
|||
|
nlwarning("%s failed: the AI instance of the entity is NULL", funName.c_str());
|
|||
|
DEBUG_STOP;
|
|||
|
return;
|
|||
|
}
|
|||
|
CQueryEgs msg;
|
|||
|
msg.InstanceId = aiInstance->getInstanceNumber();
|
|||
|
msg.GroupAlias = groupToNotify->getAlias();
|
|||
|
msg.EventId = (int)useEventId;
|
|||
|
msg.Params.push_back(literal);
|
|||
|
msg.Params.push_back(func);
|
|||
|
msg.Params.push_back(param1);
|
|||
|
msg.Params.push_back(param2);
|
|||
|
msg.send("EGS");
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection summonPlayer_fs_
|
|||
|
|
|||
|
Summon a player to a bot.
|
|||
|
|
|||
|
Can be used by a boss to teleport a player. Or the create a teleporter.
|
|||
|
|
|||
|
A player EntityId is used to identify the player.
|
|||
|
A index is used to identified the bot (index for the current group)
|
|||
|
|
|||
|
|
|||
|
Arguments: f(botIndex), s(playerEid) >
|
|||
|
@param[in] botIndex is the index of the bot in the current group(static group)
|
|||
|
@param[in] playerEid The entityId of the player
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(0);
|
|||
|
()teleportPlayer(0, $playerEid); // teleport player to the boss.
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void summonPlayer_fs_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
std::string funName = "summonPlayer_fffs_";
|
|||
|
std::string playerEidStr = ((std::string)stack.top()); stack.pop();
|
|||
|
sint32 botIndex = (sint32)((float)stack.top()); stack.pop();
|
|||
|
|
|||
|
|
|||
|
// Verify is bot is alived
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!group->isSpawned() || group->bots().isEmpty() || botIndex < 0 || group->bots().size() < static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
const CBot *const bot = group->getBot(botIndex);
|
|||
|
if ( !bot || !bot->isSpawned())
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
CSpawnBot *const sp= bot->getSpawnObj();
|
|||
|
if ( !sp || !sp->isAlive() )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Read position for mirror
|
|||
|
TDataSetRow row = sp->dataSetRow();
|
|||
|
if (! TheDataset.isAccessible( row ) )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CMirrorPropValue<sint32> mirrorSymbolX( TheDataset, row, DSPropertyPOSX );
|
|||
|
CMirrorPropValue<sint32> mirrorSymbolY( TheDataset, row, DSPropertyPOSY );
|
|||
|
|
|||
|
// retrieve the CBotPlayer
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
CAIEntityPhysical *charEntity=CAIS::instance().getEntityPhysical(TheDataset.getDataSetRow(playerEid));
|
|||
|
if (!charEntity)
|
|||
|
return;
|
|||
|
|
|||
|
// do nothing if one of them is dead
|
|||
|
if (!charEntity->isAlive() )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// send teleport MSG
|
|||
|
TDataSetRow CharacterRowId = charEntity->dataSetRow();
|
|||
|
|
|||
|
NLMISC::CEntityId player = CMirrors::getEntityId(CharacterRowId);
|
|||
|
|
|||
|
if (player != NLMISC::CEntityId::Unknown)
|
|||
|
{
|
|||
|
sint32 x2 = mirrorSymbolX.getValue();
|
|||
|
sint32 y2 = mirrorSymbolY.getValue();
|
|||
|
sint32 z2 = 0;
|
|||
|
float t = 0; // TODO direction to mob?
|
|||
|
|
|||
|
NLNET::CMessage msgout( "TELEPORT_PLAYER" );
|
|||
|
nlWrite(msgout, serial, player );
|
|||
|
msgout.serial( const_cast<sint32 &>(x2) );
|
|||
|
msgout.serial( const_cast<sint32 &>(y2) );
|
|||
|
msgout.serial( const_cast<sint32 &>(z2) );
|
|||
|
msgout.serial( const_cast<float &>(t) );
|
|||
|
sendMessageViaMirror( "EGS", msgout );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection teleportPlayer_sffff_
|
|||
|
|
|||
|
Teleport a player to a position
|
|||
|
|
|||
|
A player EntityId is used to identify the player.
|
|||
|
The position is identified by the value x,y,z and the heading
|
|||
|
|
|||
|
|
|||
|
Arguments: s(playerId), f(x), f(y), f(z), f(heading) >
|
|||
|
@param[in] playerId is EntityId of the player
|
|||
|
@param[in] x,y,z,heading is the new position of the player
|
|||
|
|
|||
|
@code
|
|||
|
($playerId)getRandomPlayerAggroListTarget(0);
|
|||
|
()teleportPlayer($playerEid, 1000, 1000, 100, 0);
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void teleportPlayer_sffff_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
// get player and position parameters
|
|||
|
float t = (float)stack.top(); stack.pop(); // heading
|
|||
|
float z = (float)stack.top(); stack.pop();
|
|||
|
float y = (float)stack.top(); stack.pop();
|
|||
|
float x = (float)stack.top(); stack.pop();
|
|||
|
std::string playerEidStr = (std::string)stack.top(); stack.pop();
|
|||
|
NLMISC::CEntityId playerEid;
|
|||
|
playerEid.fromString(playerEidStr.c_str());
|
|||
|
|
|||
|
// retrieve the CBotPlayer
|
|||
|
CAIEntityPhysical *charEntity=CAIS::instance().getEntityPhysical(TheDataset.getDataSetRow(playerEid));
|
|||
|
if (!charEntity)
|
|||
|
return;
|
|||
|
|
|||
|
// do nothing if one of them is dead
|
|||
|
if (!charEntity->isAlive() )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// teleport player to position
|
|||
|
if (playerEid != NLMISC::CEntityId::Unknown)
|
|||
|
{
|
|||
|
sint32 x2 = static_cast<sint32>(x*1000);
|
|||
|
sint32 y2 = static_cast<sint32>(y*1000);
|
|||
|
sint32 z2 = static_cast<sint32>(z*1000);
|
|||
|
|
|||
|
NLNET::CMessage msgout( "TELEPORT_PLAYER" );
|
|||
|
msgout.serial( const_cast<CEntityId &>(playerEid) );
|
|||
|
msgout.serial( const_cast<sint32 &>(x2) );
|
|||
|
msgout.serial( const_cast<sint32 &>(y2) );
|
|||
|
msgout.serial( const_cast<sint32 &>(z2) );
|
|||
|
msgout.serial( const_cast<float &>(t) );
|
|||
|
sendMessageViaMirror( "EGS", msgout );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getBotEid_f_s
|
|||
|
Get the bot EntityId by its Index.
|
|||
|
Arguments: f(botIndex) -> s(botEid)
|
|||
|
|
|||
|
@param[in] botIndex the Position of the bot in the group
|
|||
|
@param[out] botEid The entity Id given by the bot (or empty) if the indexed bot is not from the group
|
|||
|
|
|||
|
@code
|
|||
|
(index)getBotIndexByName("bot_toto");
|
|||
|
($botEid)getBotEid(index);
|
|||
|
if (index != -1)
|
|||
|
{
|
|||
|
()phrasePushValue("entity", $botEid);
|
|||
|
()phraseEndEmoteMsg(index, "PHRASE_YOUR_ARE_CLICKING_ON_ME");
|
|||
|
}
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
|
|||
|
void getBotEid_f_s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getBotEid_f_s";
|
|||
|
// get spawn Bot by its index
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
stack.push(std::string(CEntityId::Unknown.toString()));
|
|||
|
return;
|
|||
|
}
|
|||
|
sint32 botIndex = (sint32)((float)stack.top());stack.pop();
|
|||
|
if (!group->isSpawned() || group->bots().isEmpty() || botIndex < 0 || group->bots().size() < static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
stack.push(std::string(CEntityId::Unknown.toString()));
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
const CBot *const bot = group->getBot(botIndex);
|
|||
|
if ( !bot || !bot->isSpawned()) { stack.push(std::string(CEntityId::Unknown.toString())); return;}
|
|||
|
|
|||
|
|
|||
|
CSpawnBot *const sb= bot->getSpawnObj();
|
|||
|
if ( !sb ||!sb->isAlive()) {stack.push(std::string(CEntityId::Unknown.toString())); return;};
|
|||
|
|
|||
|
// return the entity id of the spawn bot
|
|||
|
CEntityId id= sb->getEntityId();
|
|||
|
stack.push(std::string(id.toString()));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getBotIndex_s_f
|
|||
|
Get the bot Index by its entityId.
|
|||
|
Entity Id of a bot can be given via getCurrentSpeackerEid().
|
|||
|
It can be usefull to Known the index of the bot in the group with the EntityId.
|
|||
|
|
|||
|
Arguments: s(botEid) -> f(botIndex),
|
|||
|
|
|||
|
@param[in] botEid The entity Id given by the bot
|
|||
|
@param[out] botIndex the Position of the bot in the group (or -1 if the entity_id is not from a bot of the group)
|
|||
|
|
|||
|
@code
|
|||
|
($botEid)getCurrentSpeakerEid();
|
|||
|
(index)getBotIndex($botEid);
|
|||
|
if (index != -1)
|
|||
|
{
|
|||
|
()phrasePushValue("entity", $botEid);
|
|||
|
()phraseEndNpcg(index, "PHRASE_YOUR_ARE_CLICKING_ON_ME");
|
|||
|
}
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getBotIndex_s_f(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getBotEid_f_s";
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("%s on a non Npc Group, doesn't work", funName.c_str());
|
|||
|
stack.push(std::string(CEntityId::Unknown.toString()));
|
|||
|
return;
|
|||
|
}
|
|||
|
std::string botEid = (std::string)stack.top(); stack.pop();
|
|||
|
|
|||
|
// look in the group if the bot is alived
|
|||
|
uint32 botIndex = 0, last = group->bots().size();
|
|||
|
for ( ;botIndex != last; ++botIndex)
|
|||
|
{
|
|||
|
if (!group->isSpawned() || group->bots().isEmpty() || group->bots().size() < static_cast<uint32>(botIndex))
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
const CBot *const bot = group->getBot(botIndex);
|
|||
|
if ( !bot || !bot->isSpawned()) { continue; }
|
|||
|
|
|||
|
|
|||
|
CSpawnBot *const sb= bot->getSpawnObj();
|
|||
|
if ( !sb ||!sb->isAlive()) {continue;};
|
|||
|
CEntityId id= sb->getEntityId();
|
|||
|
// if bot is alived return its index
|
|||
|
if (botEid == id.toString())
|
|||
|
{
|
|||
|
stack.push((float)botIndex);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
stack.push((float)-1);
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getCurrentPlayerEid__s
|
|||
|
Get the entity id of the player that is clicking on a bot.
|
|||
|
|
|||
|
WARNING the function is only valid when called from an player_target_npc event.
|
|||
|
|
|||
|
|
|||
|
Arguments: -> s(playerEidAsString),
|
|||
|
@param[out] playerEidAsString is EntityId as string from the player.
|
|||
|
|
|||
|
@code
|
|||
|
($playerEid)getCurrentPlayerEid();
|
|||
|
(index)getBotIndexByName("toto");
|
|||
|
(distance)getPlayerDistance(index, $playerEid);
|
|||
|
phrasePushString("player", $playerEid);
|
|||
|
phrasePushValue("interger", distance);
|
|||
|
phraseEndNpcMsg(index, "say", "MSG_BOT_B_SAYS_THE_PLAYER_P_IS_AT_DISTANCE_D");
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getCurrentPlayerEid__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getCurrentPlayerEid__s";
|
|||
|
CEntityId id = CEntityId::Unknown;
|
|||
|
// if we are in player_target_npc event TempPlayer is valid
|
|||
|
if (!TempPlayer)
|
|||
|
{
|
|||
|
//TempPlayer is invalid so return Unkwn eid
|
|||
|
std::string s = id.toString();
|
|||
|
stack.push(s);
|
|||
|
return;
|
|||
|
}
|
|||
|
// TempPlayer is valid so return eid
|
|||
|
id = TempPlayer->getEntityId();
|
|||
|
std::string s = id.toString();
|
|||
|
stack.push(s);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection getCurrentSpeakerEid__s
|
|||
|
Get the entity id of the bot at which the player as that is clicking at.
|
|||
|
|
|||
|
WARNING the function is only valid when called from an player_target_npc event.
|
|||
|
|
|||
|
|
|||
|
Arguments: -> s(botEidAsString),
|
|||
|
@param[out] botEidAsString is EntityId as string from the bot.
|
|||
|
|
|||
|
@code
|
|||
|
($botEid)getCurrentSpeakerEid();
|
|||
|
($playerEid)getCurrentSpeakerEid();
|
|||
|
|
|||
|
phrasePushString("player", $playerEid);
|
|||
|
phrasePushValue("bot", $botEid);
|
|||
|
phraseEndEmotMsg(index, "EMOT_PLAYER_INSULT_BOT");
|
|||
|
@endcode
|
|||
|
*/
|
|||
|
void getCurrentSpeakerEid__s(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
std::string funName = "getCurrentSpeakerEid__s";
|
|||
|
CEntityId id = CEntityId::Unknown;
|
|||
|
// if we are in player_target_npc event TempSpeaker is valid
|
|||
|
if (!TempSpeaker)
|
|||
|
{
|
|||
|
//TempSpeaker is invalid so return Unkwn eid
|
|||
|
std::string s = id.toString();
|
|||
|
stack.push(s);
|
|||
|
return;
|
|||
|
}
|
|||
|
//TempSpeaker is valid so return correct eid
|
|||
|
id = TempSpeaker->getEntityId();
|
|||
|
std::string s = id.toString();
|
|||
|
stack.push(s);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////////
|
|||
|
// Undocumented methods //
|
|||
|
//////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
// CGroup
|
|||
|
void setSheet_s_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
string sheetname = stack.top();
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CSheetId sheetId(sheetname+".creature");
|
|||
|
if (sheetId==CSheetId::Unknown)
|
|||
|
return;
|
|||
|
|
|||
|
FOREACH(itBot, CCont<CBot>, entity->getGroup()->bots())
|
|||
|
{
|
|||
|
CBot* bot = *itBot;
|
|||
|
if (bot)
|
|||
|
{
|
|||
|
AISHEETS::ICreatureCPtr const sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId);
|
|||
|
if (!sheet.isNull())
|
|||
|
bot->triggerSetSheet(sheet);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
// CGroup
|
|||
|
void setHealer_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
bool value = ((float)stack.top())!=0.f;
|
|||
|
stack.pop();
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (group->isSpawned())
|
|||
|
{
|
|||
|
FOREACH(itBot, CCont<CBot>, group->bots())
|
|||
|
{
|
|||
|
CBot* bot = *itBot;
|
|||
|
if (bot)
|
|||
|
{
|
|||
|
bot->setHealer(value);
|
|||
|
// break; // :NOTE: Only set first bot as a healer
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/****************************************************************************/
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection sitDown__
|
|||
|
Make the group sit Down
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
@code
|
|||
|
()sitDown();
|
|||
|
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CStateInstance
|
|||
|
void sitDown__(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("sitDown__ failed");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CAILogicActionSitDownHelper::sitDown(group);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection standUp
|
|||
|
Make the group stand up (if was previously stand down)
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
@code
|
|||
|
()standUp();
|
|||
|
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CStateInstance
|
|||
|
void standUp__(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("standUp__ failed");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CAILogicActionSitDownHelper::standUp(group);
|
|||
|
}
|
|||
|
|
|||
|
//----------------------------------------------------------------------------
|
|||
|
/** @page code
|
|||
|
|
|||
|
@subsection standUp
|
|||
|
Use to implement setConditionRet
|
|||
|
|
|||
|
Arguments: ->
|
|||
|
|
|||
|
@code
|
|||
|
()setConditionRet(1);
|
|||
|
|
|||
|
@endcode
|
|||
|
|
|||
|
*/
|
|||
|
// CStateInstance
|
|||
|
void setConditionSuccess_f_(CStateInstance* entity, CScriptStack& stack)
|
|||
|
{
|
|||
|
bool conditionState = (uint32)((float)stack.top()) != 0;
|
|||
|
CGroup* group = entity->getGroup();
|
|||
|
if (!group)
|
|||
|
{
|
|||
|
nlwarning("setConditionSuccess_f_ failed");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
CAILogicDynamicIfHelper::setConditionSuccess(conditionState);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
|
|||
|
{
|
|||
|
std::map<std::string, FScrptNativeFunc> functions;
|
|||
|
|
|||
|
#define REGISTER_NATIVE_FUNC(cont, func) cont.insert(std::make_pair(std::string(#func), &func))
|
|||
|
|
|||
|
REGISTER_NATIVE_FUNC(functions, spawn__);
|
|||
|
REGISTER_NATIVE_FUNC(functions, despawn_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, isAlived__f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssfff_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssfff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssff_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPos_ssff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPosMl_ssffff_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPosMl_ssffff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPosMl_ssfff_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupPosMl_ssfff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroup_sssf_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroup_sssf_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroup_sss_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroup_sss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupMl_sssff_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupMl_sssff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupMl_sssf_c);
|
|||
|
REGISTER_NATIVE_FUNC(functions, newNpcChildGroupMl_sssf_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, spawnManager_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, sitDown__);
|
|||
|
REGISTER_NATIVE_FUNC(functions, standUp__);
|
|||
|
REGISTER_NATIVE_FUNC(functions, despawnManager_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getMidPos__ff);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getGroupTemplateWithFlags_sss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getGroupTemplateWithFlags_ss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getZoneWithFlags_ssss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getZoneWithFlags_sss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNearestZoneWithFlags_ffsss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNearestZoneWithFlags_ffss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNearestZoneWithFlagsStrict_ffsss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNearestZoneWithFlagsStrict_ffss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNeighbourZoneWithFlags_ssss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getNeighbourZoneWithFlags_sss_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setAggro_ff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setCanAggro_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, clearAggroList_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, clearAggroList__);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setMode_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setAutoSpawn_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setHPLevel_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setHPScale_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, scaleHP_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setBotHPScaleByAlias_fs_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, downScaleHP_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, upScaleHP_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addHP_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, aiAction_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, aiActionSelf_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addProfileParameter_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addProfileParameter_ss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addProfileParameter_sf_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, removeProfileParameter_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addPersistentProfileParameter_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addPersistentProfileParameter_ss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, addPersistentProfileParameter_sf_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, removePersistentProfileParameter_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getOutpostStateName__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, isOutpostTribeOwner__f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, isOutpostGuildOwner__f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getEventParam_f_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getEventParam_f_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setSheet_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setHealer_f_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setConditionSuccess_f_);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Boss functions (custom text)
|
|||
|
REGISTER_NATIVE_FUNC(functions, phraseBegin__);
|
|||
|
REGISTER_NATIVE_FUNC(functions, phrasePushValue_sf_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, phrasePushString_ss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, phraseEndNpcMsg_fss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, phraseEndSystemMsg_fss_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, phraseEndEmoteMsg_fs_);
|
|||
|
|
|||
|
// Boss functions (Bot infos)
|
|||
|
REGISTER_NATIVE_FUNC(functions, getBotIndex_s_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getBotEid_f_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getCurrentSpeakerEid__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getBotIndexByName_s_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, isGroupAlived__f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, isBotAlived_f_f);
|
|||
|
|
|||
|
// Boss functions (Player infos)
|
|||
|
REGISTER_NATIVE_FUNC(functions, isPlayerAlived_s_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getPlayerStat_ss_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getPlayerDistance_fs_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getCurrentPlayerEid__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, queryEgs_sscfs_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, queryEgs_ssscfs_);
|
|||
|
|
|||
|
// Boss functions (Aggro list)
|
|||
|
REGISTER_NATIVE_FUNC(functions, getCurrentPlayerAggroListTarget_f_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getRandomPlayerAggroListTarget_f_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getAggroListElement_ff_s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getAggroListSize_f_f);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setAggroListTarget_fs_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setGroupAggroListTarget_s_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, setManagerAggroListTarget_ss_);
|
|||
|
|
|||
|
// Boss functions (Time infos)
|
|||
|
REGISTER_NATIVE_FUNC(functions, getServerTimeStr__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getServerTime__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getRyzomDateStr__s);
|
|||
|
REGISTER_NATIVE_FUNC(functions, getRyzomDate__s);
|
|||
|
|
|||
|
// Boss function (teleport actions)
|
|||
|
REGISTER_NATIVE_FUNC(functions, teleportPlayer_sffff_);
|
|||
|
REGISTER_NATIVE_FUNC(functions, summonPlayer_fs_);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#undef REGISTER_NATIVE_FUNC
|
|||
|
|
|||
|
return functions;
|
|||
|
}
|