2010-05-06 00:08:41 +00:00
// 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_player.h"
# include "ai_script_data_manager.h"
# include "ais_control.h"
using std : : string ;
using std : : vector ;
using namespace NLMISC ;
using namespace AIVM ;
using namespace AICOMP ;
using namespace AITYPES ;
using namespace RYAI_MAP_CRUNCH ;
// a big bad global var !
extern CAIEntityPhysical * TempSpeaker ;
extern CBotPlayer * TempPlayer ;
/****************************************************************************/
/* CGroupNpc methods */
/****************************************************************************/
//----------------------------------------------------------------------------
// setfactionProp
/** @page code
@ subsection setFactionProp_ss_
Set a property of the faction profile . Valid values for Property are :
- faction
- ennemyFaction
- friendFaction
There are special faction that are automatically attributed to entities .
Special factions are :
- Player
- Predator
- Famous < faction > where faction is the name of a Ryzom faction with uppercase
initials and without underscores ( ie : tribe_beachcombers - >
FamousTribeBeachcombers ) , it represents players with a positive fame with the
specified faction
- outpost : < id > : < side > where id is the outpost alias as an int , and side is
either attacker ou defender ( these faction may see their format change soon
and shouldn ' t be used without prior discussion with the responsible coder ) , it
represents players and squads fighting in an outpost conflict
Arguments : s ( Property ) , s ( Content ) - >
@ param Property is the property to modify
@ param Content is a ' | ' seperated list of faction names
@ code
( ) setFactionProp ( " ennemyFaction " , " Player " ) ;
@ endcode
*/
// CGroupNpc
void setFactionProp_ss_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string params = stack . top ( ) ; // ToChange
stack . pop ( ) ;
TStringId const factionType = CStringMapper : : map ( stack . top ( ) ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " setFactionProp on a non Npc Group, doesnt work " ) ;
return ;
}
static TStringId factionStrId = CStringMapper : : map ( " faction " ) ;
static TStringId ennemyFactionStrId = CStringMapper : : map ( " ennemyFaction " ) ;
static TStringId friendFactionStrId = CStringMapper : : map ( " friendFaction " ) ;
breakable
{
CPropertySetWithExtraList < TAllianceId > tmpSet ;
CStringSeparator const sep ( params , " | " ) ;
while ( sep . hasNext ( ) )
tmpSet . addProperty ( AITYPES : : CPropertyId : : create ( sep . get ( ) ) ) ;
if ( factionType = = factionStrId )
{
grpNpc - > faction ( ) = tmpSet ;
break ;
}
if ( factionType = = ennemyFactionStrId )
{
grpNpc - > ennemyFaction ( ) = tmpSet ;
break ;
}
if ( factionType = = friendFactionStrId )
{
grpNpc - > friendFaction ( ) = tmpSet ;
break ;
}
nlwarning ( " '%s' is not a correct faction name " , CStringMapper : : unmap ( factionType ) . c_str ( ) ) ;
return ;
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection moveToZone_ss_
Moves the current group from one zone to another .
Arguments : s ( From ) , s ( To ) - >
@ param [ in ] From is a zone name
@ param [ in ] To is a zone name
@ code
( ) moveToZone ( $ zone1 , $ zone2 ) ; // Move the current group from $zone1 to $zone2
@ endcode
*/
// Spawned CGroupNpc not in a family behaviour
void moveToZone_ss_ ( CStateInstance * entity , CScriptStack & stack )
{
TStringId const zoneDest = CStringMapper : : map ( stack . top ( ) ) ;
stack . pop ( ) ;
TStringId const zoneSrc = CStringMapper : : map ( stack . top ( ) ) ;
stack . pop ( ) ;
IManagerParent * const managerParent = entity - > getGroup ( ) - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance )
return ;
if ( ! entity )
{
nlwarning ( " moveToZone failed: no state instance! " ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
return ;
}
CGroupNpc * group = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! group )
{
nlwarning ( " moveToZone failed: no NPC group! " ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
return ;
}
CSpawnGroupNpc * spawnGroup = group - > getSpawnObj ( ) ;
if ( ! spawnGroup )
{
nlwarning ( " moveToZone failed: no spawned group! " ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
return ;
}
CNpcZone const * const destZone = aiInstance - > getZone ( zoneDest ) ;
CNpcZone const * const srcZone = aiInstance - > getZone ( zoneSrc ) ;
if ( ! destZone )
{
nlwarning ( " moveToZone: getZone destination failed! " ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
}
if ( ! srcZone )
{
nlwarning ( " moveToZone: getZone source failed! " ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
}
if ( ! destZone | | ! srcZone )
return ;
if ( destZone = = srcZone )
{
nlwarning ( " Trying to find a path between two same zones in %s, aborting moveToZone " , entity - > getActiveState ( ) - > getAliasFullName ( ) . c_str ( ) ) ;
nlwarning ( " - from %s " , CStringMapper : : unmap ( zoneSrc ) . c_str ( ) ) ;
nlwarning ( " - to %s " , CStringMapper : : unmap ( zoneDest ) . c_str ( ) ) ;
return ;
}
spawnGroup - > movingProfile ( ) . setAIProfile ( new CGrpProfileDynFollowPath ( spawnGroup , srcZone , destZone , AITYPES : : CPropertySet ( ) ) ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setActivity_s_
Changes the activity of the group . Valid activities are :
- " no_change "
- " escorted "
- " guard "
- " guard_escorted "
- " normal "
- " faction "
- " faction_no_assist "
- " bandit "
Arguments : s ( Activity ) - >
@ param [ in ] Activity is an activity name the group will take
@ code
( ) setActivity ( " bandit " ) ; // Gives a bandit activity to the group
@ endcode
*/
// Spawned CGroupNpc not in a family behaviour
void setActivity_s_ ( CStateInstance * entity , CScriptStack & stack )
{
string activity = stack . top ( ) ;
stack . pop ( ) ;
IManagerParent * const managerParent = entity - > getGroup ( ) - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance )
return ;
if ( ! entity ) { nlwarning ( " setActivity failed! " ) ; return ; }
CGroupNpc * group = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! group )
{ nlwarning ( " setActivity failed: no NPC group " ) ;
return ;
}
CSpawnGroupNpc * spawnGroup = group - > getSpawnObj ( ) ;
if ( ! spawnGroup )
{ nlwarning ( " setActivity failed: no spawned group " ) ;
return ;
}
breakable
{
if ( activity = = " no_change " )
break ;
if ( activity = = " escorted " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileEscorted ( spawnGroup ) ) ;
break ;
}
if ( activity = = " guard " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileGuard ( spawnGroup ) ) ;
break ;
}
if ( activity = = " guard_escorted " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileGuardEscorted ( spawnGroup ) ) ;
break ;
}
if ( activity = = " normal " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileNormal ( spawnGroup ) ) ;
break ;
}
if ( activity = = " faction " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileFaction ( spawnGroup ) ) ;
break ;
}
if ( activity = = " faction_no_assist " )
{
CGrpProfileFaction * grpPro = new CGrpProfileFaction ( spawnGroup ) ;
grpPro - > noAssist ( ) ;
spawnGroup - > activityProfile ( ) . setAIProfile ( grpPro ) ;
break ;
}
if ( activity = = " bandit " )
{
spawnGroup - > activityProfile ( ) . setAIProfile ( new CGrpProfileBandit ( spawnGroup ) ) ;
break ;
}
nlwarning ( " trying to set activity profile to an unknown profile name " ) ;
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection waitInZone_s_
Makes the group wander in the specified zone . It ' s useful to prevent the group
from looping previous movement profile ) .
Arguments : s ( Zone ) - >
@ param [ in ] Zone is a zone name
@ code
( ) waitInZone ( $ zone ) ; // Makes the group wander in $zone
@ endcode
*/
// Spawned CGroupNpc not in a family behaviour
void waitInZone_s_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string zoneName = stack . top ( ) ;
TStringId const zoneDest = CStringMapper : : map ( zoneName ) ;
stack . pop ( ) ;
if ( ! entity )
{
nlwarning ( " waitInZone failed! " ) ;
return ;
}
IManagerParent * const managerParent = entity - > getGroup ( ) - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance )
{
// :TODO: Check is that warning was a flood
//nlwarning("waitInZone failed!");
return ;
}
CGroupNpc * group = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! group )
{
nlwarning ( " waitInZone failed: no NPC group " ) ;
return ;
}
CSpawnGroupNpc * spawnGroup = group - > getSpawnObj ( ) ;
if ( ! spawnGroup )
{
nlwarning ( " waitInZone failed: no spawned group " ) ;
return ;
}
CNpcZone const * const destZone = aiInstance - > getZone ( zoneDest ) ;
if ( ! destZone )
{
nlwarning ( " waitInZone: getZone destination failed! (%s) " , zoneName . c_str ( ) ) ;
return ;
}
spawnGroup - > movingProfile ( ) . setAIProfile ( new CGrpProfileWander ( spawnGroup , destZone ) ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection stopMoving__
Makes the group stop moving and stand at its current position .
Arguments : - >
@ code
( ) stopMoving ( ) ; // Makes the group stop moving
@ endcode
*/
// Spawned CGroupNpc not in a family behaviour
void stopMoving__ ( CStateInstance * entity , CScriptStack & stack )
{
if ( ! entity )
{
nlwarning ( " stopMoving failed! " ) ;
return ;
}
IManagerParent * const managerParent = entity - > getGroup ( ) - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance )
return ;
CGroupNpc * group = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! group )
{
nlwarning ( " stopMoving failed: no NPC group " ) ;
return ;
}
CSpawnGroupNpc * spawnGroup = group - > getSpawnObj ( ) ;
if ( ! spawnGroup )
{
nlwarning ( " stopMoving failed: no spawned group " ) ;
return ;
}
spawnGroup - > movingProfile ( ) . setAIProfile ( new CGrpProfileIdle ( spawnGroup ) ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection wander__
Makes the group wander in the current npc state zone .
Arguments : - >
@ code
( ) wander ( ) ; // Makes the group wander
@ endcode
*/
// Spawned CGroupNpc not in a family behaviour
void wander__ ( CStateInstance * entity , CScriptStack & stack )
{
if ( ! entity )
{
nlwarning ( " wander failed! " ) ;
return ;
}
IManagerParent * const managerParent = entity - > getGroup ( ) - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance )
return ;
CGroupNpc * group = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! group )
{
nlwarning ( " wander failed: no NPC group " ) ;
return ;
}
CSpawnGroupNpc * spawnGroup = group - > getSpawnObj ( ) ;
if ( ! spawnGroup )
{
nlwarning ( " wander failed: no spawned group " ) ;
return ;
}
spawnGroup - > movingProfile ( ) . setAIProfile ( new CGrpProfileWander ( spawnGroup ) ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setAttackable_f_
Sets the group as being attackable ( or not ) by bots and players . 0 means not
attackable , 1 means attackable .
Arguments : f ( Attackable ) - >
@ param [ in ] Attackable tells whether the group is attackable
@ code
( ) setAttackable ( 1 ) ; // Make the group attackable by players and bots
@ endcode
*/
// CGroupNpc
void setAttackable_f_ ( CStateInstance * entity , CScriptStack & stack )
{
bool const attackable = ( float & ) stack . top ( ) ! = 0.0f ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
npcGroup - > setPlayerAttackable ( attackable ) ;
npcGroup - > setBotAttackable ( attackable ) ;
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setPlayerAttackable_f_
Sets the group as being attackable ( or not ) by players . 0 means not
attackable , 1 means attackable .
Arguments : f ( Attackable ) - >
@ param [ in ] Attackable tells whether the group is attackable
@ code
( ) setPlayerAttackable ( 1 ) ; // Make the group attackable by players
@ endcode
*/
// CGroupNpc
void setPlayerAttackable_f_ ( CStateInstance * entity , CScriptStack & stack )
{
bool attackable = ( float & ) stack . top ( ) ! = 0.0f ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
npcGroup - > setPlayerAttackable ( attackable ) ;
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
// setBotAttackable_f_
// Arguments: f(Attackable) ->
/** @page code
@ subsection setBotAttackable_f_
Sets the group as being attackable ( or not ) by bots . 0 means not attackable , 1
means attackable .
Arguments : f ( Attackable ) - >
@ param [ in ] Attackable tells whether the group is attackable
@ code
( ) setBotAttackable ( 0 ) ; // Make the group not attackable by bots
@ endcode
*/
// CGroupNpc
void setBotAttackable_f_ ( CStateInstance * entity , CScriptStack & stack )
{
bool attackable = ( float & ) stack . top ( ) ! = 0.0f ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
npcGroup - > setBotAttackable ( attackable ) ;
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
// setFactionAttackableAbove_sff_
// Arguments: s(Faction),f(Threshold),f(Attackable) ->
/** @page code
@ subsection setFactionAttackableAbove_sff_
Sets the group as being attackable ( or not ) by players having their fame
matching the specified condition . If player fame for Faction is above
specified Threshold the bot will be attackable by that player or not depending
on Attackable parameter , 0 meaning not attackable , 1 meaning attackable .
Note : Bots must not be player attackable for the faction to be taken into
account .
Arguments : s ( Faction ) , f ( Threshold ) , f ( Attackable ) - >
@ param [ in ] Faction tells the faction against which player fame will be tested
@ param [ in ] Threshold is the test threshold above which player will be able to attack
@ param [ in ] Attackable tells whether the group is attackable or not
@ code
( ) setFactionAttackableAbove ( " TribeNightTurners " , 0 , 1 ) ; // Make the group attackable by players with positive tribe_night_turners fame
@ endcode
*/
// CGroupNpc
void setFactionAttackableAbove_sff_ ( CStateInstance * entity , CScriptStack & stack )
{
bool attackable = ( float & ) stack . top ( ) ! = 0.0f ;
stack . pop ( ) ;
sint32 threshold = ( sint32 ) ( float & ) stack . top ( ) ;
stack . pop ( ) ;
std : : string faction = ( std : : string & ) stack . top ( ) ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
npcGroup - > setFactionAttackableAbove ( faction , threshold , attackable ) ;
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
// setFactionAttackableBelow_sff_
// Arguments: s(Faction),f(Threshold),f(Attackable) ->
/** @page code
@ subsection setFactionAttackableBelow_sff_
Sets the group as being attackable ( or not ) by players having their fame
matching the specified condition . If player fame for Faction is below
specified Threshold the bot will be attackable by that player or not depending
on Attackable parameter , 0 meaning not attackable , 1 meaning attackable .
Note : Bots must not be player attackable for the faction to be taken into
account .
Arguments : s ( Faction ) , f ( Threshold ) , f ( Attackable ) - >
@ param [ in ] Faction tells the faction against which player fame will be tested
@ param [ in ] Threshold is the test threshold below which player will be able to attack
@ param [ in ] Attackable tells whether the group is attackable or not
@ code
( ) setFactionAttackableBelow ( " TribeMatisianBorderGuards " , 0 , 1 ) ; // Make the group attackable by players with negative tribe_matisian_border_guards fame
@ endcode
*/
// CGroupNpc
void setFactionAttackableBelow_sff_ ( CStateInstance * entity , CScriptStack & stack )
{
bool attackable = ( float & ) stack . top ( ) ! = 0.0f ;
stack . pop ( ) ;
sint32 threshold = ( sint32 ) ( float & ) stack . top ( ) ;
stack . pop ( ) ;
std : : string faction = ( std : : string & ) stack . top ( ) ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
npcGroup - > setFactionAttackableBelow ( faction , threshold , attackable ) ;
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addBotChat_s_
Add an entry in the botchat menu of every bot of the group . Specified text ID
can be created dynamically with setSimplePhrase ( @ ref setSimplePhrase_ss_ ) .
Arguments : s ( BotChat ) - >
@ param [ in ] BotChat is a text ID
@ code
( ) addBotChat ( " menu:QUESTION:REPONSE " ) ;
@ endcode
*/
// CGroupNpc
void addBotChat_s_ ( CStateInstance * entity , CScriptStack & stack )
{
string const botChat = ( string ) stack . top ( ) ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
FOREACH ( botIt , CCont < CBot > , group - > bots ( ) )
{
CBot * bot = * botIt ;
CBotNpc * botNpc = NLMISC : : safe_cast < CBotNpc * > ( bot ) ;
if ( botNpc )
{
if ( ! botNpc - > getChat ( ) )
botNpc - > newChat ( ) ;
botNpc - > getChat ( ) - > add ( botNpc - > getAIInstance ( ) , botChat ) ;
CSpawnBotNpc * spawnBotNpc = botNpc - > getSpawn ( ) ;
if ( spawnBotNpc )
{
spawnBotNpc - > setCurrentChatProfile ( botNpc - > getChat ( ) ) ;
}
}
}
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection clearBotChat__
Removes all entries from the botchat menu of every bot of the group .
Arguments : - >
@ code
( ) clearBotChat ( ) ;
@ endcode
*/
// CGroupNpc
void clearBotChat__ ( CStateInstance * entity , CScriptStack & stack )
{
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
FOREACH ( botIt , CCont < CBot > , group - > bots ( ) )
{
CBot * bot = * botIt ;
CBotNpc * botNpc = NLMISC : : safe_cast < CBotNpc * > ( bot ) ;
if ( botNpc )
{
if ( ! botNpc - > getChat ( ) )
botNpc - > newChat ( ) ;
botNpc - > getChat ( ) - > clear ( ) ;
CSpawnBotNpc * spawnBotNpc = botNpc - > getSpawn ( ) ;
if ( spawnBotNpc )
{
spawnBotNpc - > setCurrentChatProfile ( botNpc - > getChat ( ) ) ;
}
}
}
if ( npcGroup - > isSpawned ( ) )
npcGroup - > getSpawnObj ( ) - > sendInfoToEGS ( ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection ignoreOffensiveActions_f_
Make the bots of the group ignore offensive actions issued on them .
Arguments : f ( IgnoreOffensiveActions ) - >
@ param [ in ] IgnoreOffensiveActions is tells whethere to ignore offensive actions ( 1 ) or not ( 0 )
@ code
( ) ignoreOffensiveActions ( 1 ) ;
@ endcode
*/
// CGroup
void ignoreOffensiveActions_f_ ( CStateInstance * entity , CScriptStack & stack )
{
bool const ignoreOffensiveActions = ( ( float ) stack . top ( ) ) ! = 0.f ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
FOREACH ( botIt , CCont < CBot > , group - > bots ( ) )
{
CBot * bot = * botIt ;
if ( bot )
bot - > setIgnoreOffensiveActions ( ignoreOffensiveActions ) ;
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setDespawnTime_f_
Sets the time before current group being despawned .
Arguments : f ( DespawnTime ) - >
@ param [ in ] DespawnTime is the despawn time in ticks ( - 1 will set " pseudo-infinite " )
@ code
( ) setDespawnTime ( 80 ) ;
( ) setDespawnTime ( - 1 ) ;
@ endcode
*/
// CGroupNpc
void setDespawnTime_f_ ( CStateInstance * entity , CScriptStack & stack )
{
float time = stack . top ( ) ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
uint32 despawntime = ( uint32 ) ( sint32 ) time ; // -1 => ~0
// TODO:kxu: fix CAITimer!
if ( despawntime > 0x7fffffff )
despawntime = 0x7fffffff ; // AI timers do not treat properly delta times greater than the max signed int
npcGroup - > despawnTime ( ) = despawntime ;
}
/** @page code
@ subsection despawnBotByAlias_s_
Despawn a specific Bot by its alias
Arguments : f ( alias ) , - >
@ param [ in ] alias is the alias of the bot
@ code
( ) despawnBotByAlias ( ' ( A : 1000 : 10560 ) ' ) ;
@ endcode
*/
// CGroup
void despawnBotByAlias_s_ ( CStateInstance * entity , CScriptStack & stack )
{
uint32 alias = LigoConfig . aliasFromString ( ( string ) stack . top ( ) ) ; stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
FOREACH ( botIt , CCont < CBot > , group - > bots ( ) )
{
CBot * bot = * botIt ;
if ( bot - > getAlias ( ) ! = alias ) { continue ; }
if ( ! bot - > isSpawned ( ) ) return ;
if ( bot - > getRyzomType ( ) = = RYZOMID : : npc )
{
CBotNpc * botNpc = NLMISC : : safe_cast < CBotNpc * > ( bot ) ;
CSpawnBotNpc * spawnBotNpc = botNpc - > getSpawn ( ) ;
spawnBotNpc - > spawnGrp ( ) . addBotToDespawnAndRespawnTime ( & spawnBotNpc - > getPersistent ( ) , 1 , spawnBotNpc - > spawnGrp ( ) . getPersistent ( ) . respawnTime ( ) ) ;
}
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setRespawnTime_f_
Sets the time in game cycles before current group being respawned .
Arguments : f ( RespawnTime ) - >
@ param [ in ] RespawnTime is the respawn time in ticks ( - 1 will set " pseudo-infinite " )
@ code
( ) setRespawnTime ( 80 ) ;
( ) setRespawnTime ( - 1 ) ;
@ endcode
*/
// CGroupNpc
void setRespawnTime_f_ ( CStateInstance * entity , CScriptStack & stack )
{
float const time = stack . top ( ) ;
stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
uint32 respawntime = ( uint32 ) ( sint32 ) time ; // -1 => ~0
// TODO:kxu: fix CAITimer!
if ( respawntime > 0x7fffffff )
respawntime = 0x7fffffff ; // AI timers do not treat properly delta times greater than the max signed int
npcGroup - > respawnTime ( ) = respawntime ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addHpUpTrigger_ff_
Registers a trigger on HP increases . Whenever the HP level of a bot upcross
the threshold it triggers the specified user event . Several triggers can be
registered on the same group , even with the same threshold and event .
Arguments : f ( threshold ) , f ( user_event_n ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] user_event_n is the user event to trigger
@ code
( ) addHpUpTrigger ( 0.5 , 4 ) ;
@ endcode
*/
// CGroupNpc
void addHpUpTrigger_ff_ ( CStateInstance * entity , CScriptStack & stack )
{
int eventId = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to add a hp up trigger (%f) listener (user event %d) in a group which is not an NPC group. " , threshold , eventId ) ;
return ;
}
grpNpc - > addHpUpTrigger ( threshold , eventId ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delHpUpTrigger_ff_
Unregisters a trigger on HP increases . The same values used when registering
the trigger must be passed . If several triggers were defined with the same
parameters only one is removed .
Arguments : f ( threshold ) , f ( user_event_n ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] user_event_n is the user event to trigger
@ code
( ) delHpUpTrigger ( 0.5 , 4 ) ;
@ endcode
*/
// CGroupNpc
void delHpUpTrigger_ff_ ( CStateInstance * entity , CScriptStack & stack )
{
int eventId = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a hp up trigger (%f) listener (user event %d) in a group which is not an NPC group. " , threshold , eventId ) ;
return ;
}
grpNpc - > delHpUpTrigger ( threshold , eventId ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addHpDownTrigger_ff_
Registers a trigger on HP decreases . Whenever the HP level of a bot downcross
the threshold it triggers the specified user event . Several triggers can be
registered on the same group , even with the same threshold and event .
Arguments : f ( threshold ) , f ( user_event_n ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] user_event_n is the user event to trigger
@ code
( ) addHpDownTrigger ( 0.5 , 5 ) ;
@ endcode
*/
// CGroupNpc
void addHpDownTrigger_ff_ ( CStateInstance * entity , CScriptStack & stack )
{
int eventId = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to add a hp down trigger (%f) listener (user event %d) in a group which is not an NPC group. " , threshold , eventId ) ;
return ;
}
grpNpc - > addHpDownTrigger ( threshold , eventId ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delHpDownTrigger_ff_
Unregisters a trigger on HP decreases . The same values used when registering
the trigger must be passed . If several triggers were defined with the same
parameters only one is removed .
Arguments : f ( threshold ) , f ( user_event_n ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] user_event_n is the user event to trigger
@ code
( ) delHpDownTrigger ( 0.5 , 5 ) ;
@ endcode
*/
// CGroupNpc
void delHpDownTrigger_ff_ ( CStateInstance * entity , CScriptStack & stack )
{
int eventId = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a hp down trigger (%f) listener (user event %d) in a group which is not an NPC group. " , threshold , eventId ) ;
return ;
}
grpNpc - > delHpDownTrigger ( threshold , eventId ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addHpUpTrigger_fs_
@ sa @ ref addHpUpTrigger_ff_
These triggers call a script function instead of trigger a user event .
Arguments : f ( threshold ) , s ( callback ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] callback is the script callback to trigger
@ code
( ) addHpUpTrigger ( 0.5 , " onHPIncrease " ) ;
@ endcode
*/
// CGroupNpc
void addHpUpTrigger_fs_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to add a hp up trigger (%f) listener (%s) in a group which is not an NPC group. " , threshold , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > addHpUpTrigger ( threshold , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delHpUpTrigger_fs_
@ sa @ ref delHpUpTrigger_ff_
This function is used to remove script function triggers .
Arguments : f ( threshold ) , s ( callback ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] callback is the script callback to trigger
@ code
( ) delHpUpTrigger ( 0.5 , " onHPIncrease " ) ;
@ endcode
*/
// CGroupNpc
void delHpUpTrigger_fs_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a hp up trigger (%f) listener (%s) in a group which is not an NPC group. " , threshold , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > delHpUpTrigger ( threshold , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addHpDownTrigger_fs_
@ sa @ ref addHpDownTrigger_ff_
These triggers call a script function instead of trigger a user event .
Arguments : f ( threshold ) , s ( callback ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] callback is the script callback to trigger
@ code
( ) addHpDownTrigger ( 0.5 , " onHPDecrease " ) ;
@ endcode
*/
// CGroupNpc
void addHpDownTrigger_fs_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to add a hp down trigger (%f) listener (%s) in a group which is not an NPC group. " , threshold , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > addHpDownTrigger ( threshold , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delHpDownTrigger_fs_
@ sa @ ref delHpDownTrigger_ff_
This function is used to remove script function triggers .
Arguments : f ( threshold ) , s ( callback ) - >
@ param [ in ] threshold is a HP threshold
@ param [ in ] callback is the script callback to trigger
@ code
( ) delHpDownTrigger ( 0.5 , " onHPDecrease " ) ;
@ endcode
*/
// CGroupNpc
void delHpDownTrigger_fs_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
float threshold = ( float ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a hp down trigger (%f) listener (%s) in a group which is not an NPC group. " , threshold , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > delHpDownTrigger ( threshold , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addNamedEntityListener_ssf_
Associates a listeners with a named entity property . Whenever that field
changes the specified user event is triggered . Valid property names are :
- state
- param1
- param2
Name of the entity cannot be listened , because it cannot change . Several
listeners ( even with the same parameters ) can be associated to each property .
Arguments : s ( name ) , s ( prop ) , f ( event ) - >
@ param [ in ] name is a the name of the named entity to listen
@ param [ in ] prop is a the property of the named entity to listen
@ param [ in ] event is a the user event to trigger
@ code
( ) addNamedEntityListener ( " Invasion " , " state " , 6 ) ;
@ endcode
*/
// CGroupNpc
void addNamedEntityListener_ssf_ ( CStateInstance * entity , CScriptStack & stack )
{
int event = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
std : : string prop = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string name = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to create a named entity (%s:%s) listener (user event %d) in a group which is not an NPC group. " , name . c_str ( ) , prop . c_str ( ) , event ) ;
return ;
}
grpNpc - > addNamedEntityListener ( name , prop , event ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delNamedEntityListener_ssf_
Removes a listener from a named entity property . If several listeners with the
same parameters are registered , only one is removed .
Arguments : s ( name ) , s ( prop ) , f ( event ) - >
@ param [ in ] name is a the name of the named entity to listen
@ param [ in ] prop is a the property of the named entity to listen
@ param [ in ] event is a the user event to trigger
@ code
( ) delNamedEntityListener ( " Invasion " , " state " , 6 ) ;
@ endcode
*/
// CGroupNpc
void delNamedEntityListener_ssf_ ( CStateInstance * entity , CScriptStack & stack )
{
int event = ( int ) ( float ) stack . top ( ) ;
stack . pop ( ) ;
std : : string prop = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string name = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a named entity (%s:%s) listener (user event %d) in a group which is not an NPC group. " , name . c_str ( ) , prop . c_str ( ) , event ) ;
return ;
}
grpNpc - > delNamedEntityListener ( name , prop , event ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection addNamedEntityListener_sss_
@ sa @ ref addNamedEntityListener_ssf_
These listeners call a script function instead of triggering a user event .
Arguments : s ( name ) , s ( prop ) , s ( cbFunc ) - >
@ param [ in ] name is a the name of the named entity to listen
@ param [ in ] prop is a the property of the named entity to listen
@ param [ in ] cbFunc is a the callback to trigger
@ code
( ) addNamedEntityListener ( " Invasion " , " state " , " onStateChange " ) ;
@ endcode
*/
// CGroupNpc
void addNamedEntityListener_sss_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string prop = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string name = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to create a named entity (%s:%s) listener (%s) in a group which is not an NPC group. " , name . c_str ( ) , prop . c_str ( ) , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > addNamedEntityListener ( name , prop , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection delNamedEntityListener_sss_
@ sa @ ref delNamedEntityListener_ssf_
This function removes script function listeners .
Arguments : s ( name ) , s ( prop ) , s ( cbFunc ) - >
@ param [ in ] name is a the name of the named entity to listen
@ param [ in ] prop is a the property of the named entity to listen
@ param [ in ] cbFunc is a the callback to trigger
@ code
( ) delNamedEntityListener ( " Invasion " , " state " , " onStateChange " ) ;
@ endcode
*/
// CGroupNpc
void delNamedEntityListener_sss_ ( CStateInstance * entity , CScriptStack & stack )
{
std : : string cbFunc = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string prop = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
std : : string name = ( std : : string ) stack . top ( ) ;
stack . pop ( ) ;
CGroupNpc * const grpNpc = dynamic_cast < CGroupNpc * > ( entity - > getGroup ( ) ) ;
if ( ! grpNpc )
{
nlwarning ( " Trying to delete a named entity (%s:%s) listener (%s) in a group which is not an NPC group. " , name . c_str ( ) , prop . c_str ( ) , cbFunc . c_str ( ) ) ;
return ;
}
grpNpc - > delNamedEntityListener ( name , prop , cbFunc ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setPlayerController_ss_
Make a player control a npc .
Arguments : s ( botId ) , s ( playerId ) - >
@ param [ in ] botId is the entity id of the bot the player will control
@ param [ in ] playerId is the entity id of the player that will control the bot
@ code
( ) setPlayerController ( " (0x0002015bb4:01:88:88) " , " (0x0000004880:00:00:00) " ) ;
@ endcode
*/
// CSpawnBotNpc
void setPlayerController_ss_ ( CStateInstance * entity , CScriptStack & stack )
{
NLMISC : : CEntityId playerId = NLMISC : : CEntityId ( ( std : : string ) stack . top ( ) ) ;
stack . pop ( ) ;
NLMISC : : CEntityId botId = NLMISC : : CEntityId ( ( std : : string ) stack . top ( ) ) ;
stack . pop ( ) ;
if ( botId ! = NLMISC : : CEntityId : : Unknown )
{
CGroup * grp = NULL ;
CSpawnBotNpc * bot = NULL ;
if ( ( bot = dynamic_cast < CSpawnBotNpc * > ( CAIEntityPhysicalLocator : : getInstance ( ) - > getEntity ( botId ) ) )
& & ( & bot - > getPersistent ( ) . getGroup ( ) ) = = entity - > getGroup ( ) )
{
CBotPlayer * player = NULL ;
if ( playerId ! = NLMISC : : CEntityId : : Unknown
& & ( player = dynamic_cast < CBotPlayer * > ( CAIEntityPhysicalLocator : : getInstance ( ) - > getEntity ( playerId ) ) ) )
{
bot - > setPlayerController ( player ) ;
}
else
bot - > setPlayerController ( NULL ) ;
}
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection clearPlayerController_s_
Stop the control of a npc by a player .
Arguments : s ( botId ) - >
@ param [ in ] botId is the entity id of the bot
@ code
( ) clearPlayerController ( " (0x0002015bb4:01:88:88) " ) ;
@ endcode
*/
// CSpawnBotNpc
void clearPlayerController_s_ ( CStateInstance * entity , CScriptStack & stack )
{
NLMISC : : CEntityId botId = NLMISC : : CEntityId ( ( std : : string ) stack . top ( ) ) ;
stack . pop ( ) ;
if ( botId ! = NLMISC : : CEntityId : : Unknown )
{
CGroup * grp = NULL ;
CSpawnBotNpc * bot = NULL ;
if ( ( bot = dynamic_cast < CSpawnBotNpc * > ( CAIEntityPhysicalLocator : : getInstance ( ) - > getEntity ( botId ) ) )
& & ( & bot - > getPersistent ( ) . getGroup ( ) ) = = entity - > getGroup ( ) )
{
bot - > setPlayerController ( NULL ) ;
}
}
}
//----------------------------------------------------------------------------
/** @page code
@ subsection activateEasterEgg_fffsffffsss_
Call the EGS function CCharacterControl : : activateEasterEgg
Arguments : f ( easterEggId ) , f ( scenarioId ) , f ( actId ) , s ( items ) , f ( x ) , f ( y ) , f ( z ) , f ( heading ) , f ( groupname ) , f ( name ) , f ( clientSheet ) - >
@ param [ in ] items is the sheet / quantity vector ( a string of format " item1:qty1;item2:qty2;... " )
@ code
( ) activateEasterEgg ( 2 , 1601 , 4 , " toto.sitem:2;tata.sitem:1;titi.sitem:3 " , 1247 , 4627 , 0 , 0 ) ;
@ endcode
*/
void activateEasterEgg_fffsffffsss_ ( CStateInstance * si , CScriptStack & stack )
{
std : : string clientSheet = ( std : : string ) stack . top ( ) ; stack . pop ( ) ;
std : : string name = ( std : : string ) stack . top ( ) ; stack . pop ( ) ;
std : : string grpCtrl = ( std : : string ) stack . top ( ) ; stack . pop ( ) ;
float heading = ( float ) stack . top ( ) ; stack . pop ( ) ;
float z = ( float ) stack . top ( ) ; stack . pop ( ) ;
float y = ( float ) stack . top ( ) ; stack . pop ( ) ;
float x = ( float ) stack . top ( ) ; stack . pop ( ) ;
string items = ( string ) stack . top ( ) ; stack . pop ( ) ;
uint32 actId = static_cast < uint32 > ( ( float ) stack . top ( ) ) ; stack . pop ( ) ;
TSessionId scenarioId ( static_cast < uint32 > ( ( float ) stack . top ( ) ) ) ; stack . pop ( ) ;
uint32 easterEgg = static_cast < uint32 > ( ( float ) stack . top ( ) ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > activateEasterEgg ( easterEgg , scenarioId , actId , items , x , y , z , heading , grpCtrl , name , clientSheet ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection deactivateEasterEgg_fff_
Call the EGS function CCharacterControl : : deactivateEasterEgg
Arguments : f ( easterEggId ) , f ( scenarioId ) , f ( actId ) - >
@ code
( ) deactivateEasterEgg ( 0 , 4 ) ;
@ endcode
*/
void deactivateEasterEgg_fff_ ( CStateInstance * si , CScriptStack & stack )
{
uint32 actId = static_cast < uint32 > ( ( float ) stack . top ( ) ) ; stack . pop ( ) ;
TSessionId scenarioId ( static_cast < uint32 > ( ( float ) stack . top ( ) ) ) ; stack . pop ( ) ;
uint32 easterEgg = static_cast < uint32 > ( ( float ) stack . top ( ) ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > deactivateEasterEgg ( easterEgg , scenarioId , actId ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection receiveMissionItems_ssc_
The npc will ask mission items to the targeter player .
A new entry of the npc contextual menu will propose to the targeter player
to give mission items to the npc if he has the requested items .
Then user events are triggered on the group to inform it about what happens :
- user_event_1 : triggered if the player has the requested mission items .
- user_event_2 : triggered if the player hasn ' t the requested mission items .
- user_event_3 : triggered after the player has given the mission items to the npc .
Warning : this function can only be called after the event " player_target_npc " .
Arguments : s ( missionItems ) , s ( missionText ) , c ( groupToNotify ) - >
@ param [ in ] missionItems is the list of mission items , the string format is " item1:qty1;item2:qty2;... " .
@ param [ in ] missionText is the text which will appear in the npc contextual menu .
@ param [ in ] groupToNotify is the npc group which will receive the user events .
@ code
( @ groupToNotify ) group_name . context ( ) ;
( ) receiveMissionItems ( " toto.sitem:2;tata.sitem:1;titi.sitem:3 " , " Mission text " , @ groupToNotify ) ;
@ endcode
*/
// CSpawnBotNpc
void receiveMissionItems_ssc_ ( CStateInstance * entity , CScriptStack & stack )
{
CGroupNpc * const groupToNotify = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ;
stack . pop ( ) ;
string missionText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
string missionItems = ( string ) stack . top ( ) ;
stack . pop ( ) ;
if ( groupToNotify = = NULL )
{
nlwarning ( " receiveMissionItems failed: groupToNotify is NULL " ) ;
DEBUG_STOP ;
return ;
}
if ( missionItems . empty ( ) )
{
nlwarning ( " receiveMissionItems failed: missionItems is empty " ) ;
DEBUG_STOP ;
return ;
}
nlassert ( entity ! = NULL ) ;
CGroup * const group = entity - > getGroup ( ) ;
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( aiInstance = = NULL )
{
nlwarning ( " receiveMissionItems failed: the AI instance of the entity is NULL " ) ;
DEBUG_STOP ;
return ;
}
CBotPlayer * const talkingPlayer = TempPlayer ;
CSpawnBotNpc * const talkingNpc = dynamic_cast < CSpawnBotNpc * > ( TempSpeaker ) ;
if ( talkingPlayer = = NULL
| | talkingNpc = = NULL
| | talkingNpc - > getPersistent ( ) . getOwner ( ) ! = group ) // check if the talking npc is in this group
{
nlwarning ( " receiveMissionItems failed: invalid interlocutors " ) ;
DEBUG_STOP ;
return ;
}
// do nothing if one of them is dead
if ( ! talkingPlayer - > isAlive ( ) | | ! talkingNpc - > isAlive ( ) )
{
return ;
}
// turn the npc to face the player
talkingNpc - > setTheta ( talkingNpc - > pos ( ) . angleTo ( talkingPlayer - > pos ( ) ) ) ;
// send the request to the EGS
CGiveItemRequestMsg msg ;
msg . InstanceId = aiInstance - > getInstanceNumber ( ) ;
msg . GroupAlias = groupToNotify - > getAlias ( ) ;
msg . CharacterRowId = talkingPlayer - > dataSetRow ( ) ;
msg . CreatureRowId = talkingNpc - > dataSetRow ( ) ;
msg . MissionText = missionText ;
// extract items and quantities from the missionItems string
std : : vector < std : : string > itemAndQtyList ;
NLMISC : : splitString ( missionItems , " ; " , itemAndQtyList ) ;
if ( itemAndQtyList . empty ( ) )
{
nlwarning ( " receiveMissionItems failed: the provided mission items string is invalid " ) ;
DEBUG_STOP ;
return ;
}
FOREACHC ( it , std : : vector < std : : string > , itemAndQtyList )
{
std : : vector < std : : string > itemAndQty ;
NLMISC : : splitString ( * it , " : " , itemAndQty ) ;
if ( itemAndQty . size ( ) ! = 2 )
{
nlwarning ( " receiveMissionItems failed: the provided mission items string is invalid " ) ;
DEBUG_STOP ;
return ;
}
const CSheetId sheetId ( itemAndQty [ 0 ] ) ;
if ( sheetId = = CSheetId : : Unknown )
{
nlwarning ( " receiveMissionItems failed: invalid mission item sheet '%s' " , itemAndQty [ 0 ] . c_str ( ) ) ;
DEBUG_STOP ;
return ;
}
// if LD use this the function outside a ring shard
if ( IsRingShard )
{
// Here we destroy the item: so we do not want that a user create a scenario where we destroy
// other players precious items
static std : : set < CSheetId > r2PlotItemSheetId ; // :TODO: use R2Share::CRingAccess
// lazy intialisation
if ( r2PlotItemSheetId . empty ( ) )
{
for ( uint32 i = 0 ; i < = 184 ; + + i )
{
r2PlotItemSheetId . insert ( CSheetId ( NLMISC : : toString ( " r2_plot_item_%d.sitem " , i ) ) ) ;
}
}
// A npc give a mission to take an item given by an other npc
// but the item instead of being a r2_plot_item is a normal item like system_mp or big armor
if ( r2PlotItemSheetId . find ( sheetId ) = = r2PlotItemSheetId . end ( ) )
{
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " !!!!!!!!!!!! Someone is trying to hack us " ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " ERROR/HACK : an npc is trying to give to a player a item that is not a plot item SheetId='%s' sheetIdAsInt=%u " , sheetId . toString ( ) . c_str ( ) , sheetId . asInt ( ) ) ;
nlwarning ( " His ai instanceId is %u, use log to know the sessionId and the user " , msg . InstanceId ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
return ;
}
}
const uint32 quantity = ( uint32 ) atoi ( itemAndQty [ 1 ] . c_str ( ) ) ;
if ( quantity = = 0 )
{
nlwarning ( " receiveMissionItems failed: invalid quantity '%s' " , itemAndQty [ 1 ] . c_str ( ) ) ;
DEBUG_STOP ;
return ;
}
msg . Items . push_back ( sheetId ) ;
msg . Quantities . push_back ( quantity ) ;
}
nlassert ( ! msg . Items . empty ( ) ) ;
nlassert ( msg . Items . size ( ) = = msg . Quantities . size ( ) ) ;
msg . send ( " EGS " ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection giveMissionItems_ssc_
The npc will give mission items to the targeter player .
A new entry of the npc contextual menu will propose to the targeter player
to receive mission items from the npc .
Then user events are triggered on the group to inform it about what happens :
- user_event_1 : triggered after the player has received the mission items from the npc .
Warning : this function can only be called after the event " player_target_npc " .
Arguments : s ( missionItems ) , s ( missionText ) , c ( groupToNotify ) - >
@ param [ in ] missionItems is the list of mission items , the string format is " item1:qty1;item2:qty2;... " .
@ param [ in ] missionText is the text which will appear in the npc contextual menu .
@ param [ in ] groupToNotify is the npc group which will receive the user events .
@ code
( @ groupToNotify ) group_name . context ( ) ;
( ) giveMissionItems ( " toto.sitem:2;tata.sitem:1;titi.sitem:3 " , " Mission text " , @ groupToNotify ) ;
@ endcode
*/
// CSpawnBotNpc
void giveMissionItems_ssc_ ( CStateInstance * entity , CScriptStack & stack )
{
CGroupNpc * const groupToNotify = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ;
stack . pop ( ) ;
string missionText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
string missionItems = ( string ) stack . top ( ) ;
stack . pop ( ) ;
if ( groupToNotify = = NULL )
{
nlwarning ( " giveMissionItems failed: groupToNotify is NULL " ) ;
DEBUG_STOP ;
return ;
}
if ( missionItems . empty ( ) )
{
nlwarning ( " giveMissionItems failed: missionItems is empty " ) ;
DEBUG_STOP ;
return ;
}
nlassert ( entity ! = NULL ) ;
CGroup * const group = entity - > getGroup ( ) ;
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( aiInstance = = NULL )
{
nlwarning ( " giveMissionItems failed: the AI instance of the entity is NULL " ) ;
DEBUG_STOP ;
return ;
}
CBotPlayer * const talkingPlayer = TempPlayer ;
CSpawnBotNpc * const talkingNpc = dynamic_cast < CSpawnBotNpc * > ( TempSpeaker ) ;
if ( talkingPlayer = = NULL
| | talkingNpc = = NULL
| | talkingNpc - > getPersistent ( ) . getOwner ( ) ! = group ) // check if the talking npc is in this group
{
nlwarning ( " giveMissionItems failed: invalid interlocutors " ) ;
DEBUG_STOP ;
return ;
}
// do nothing if one of them is dead
if ( ! talkingPlayer - > isAlive ( ) | | ! talkingNpc - > isAlive ( ) )
{
return ;
}
// turn the npc to face the player
talkingNpc - > setTheta ( talkingNpc - > pos ( ) . angleTo ( talkingPlayer - > pos ( ) ) ) ;
// send the request to the EGS
CReceiveItemRequestMsg msg ;
msg . InstanceId = aiInstance - > getInstanceNumber ( ) ;
msg . GroupAlias = groupToNotify - > getAlias ( ) ;
msg . CharacterRowId = talkingPlayer - > dataSetRow ( ) ;
msg . CreatureRowId = talkingNpc - > dataSetRow ( ) ;
msg . MissionText = missionText ;
// extract items and quantities from the missionItems string
std : : vector < std : : string > itemAndQtyList ;
NLMISC : : splitString ( missionItems , " ; " , itemAndQtyList ) ;
if ( itemAndQtyList . empty ( ) )
{
nlwarning ( " giveMissionItems failed: the provided mission items string is invalid " ) ;
DEBUG_STOP ;
return ;
}
FOREACHC ( it , std : : vector < std : : string > , itemAndQtyList )
{
std : : vector < std : : string > itemAndQty ;
NLMISC : : splitString ( * it , " : " , itemAndQty ) ;
if ( itemAndQty . size ( ) ! = 2 )
{
nlwarning ( " giveMissionItems failed: the provided mission items string is invalid " ) ;
DEBUG_STOP ;
return ;
}
const CSheetId sheetId ( itemAndQty [ 0 ] ) ;
if ( sheetId = = CSheetId : : Unknown )
{
nlwarning ( " giveMissionItems failed: invalid mission item sheet '%s' " , itemAndQty [ 0 ] . c_str ( ) ) ;
DEBUG_STOP ;
return ;
}
// if LD use this the function outside a ring shard
if ( IsRingShard )
{
static std : : set < CSheetId > r2PlotItemSheetId ; // :TODO: use R2Share::CRingAccess
// lazy intialisation
if ( r2PlotItemSheetId . empty ( ) )
{
for ( uint32 i = 0 ; i < = 184 ; + + i )
{
r2PlotItemSheetId . insert ( CSheetId ( NLMISC : : toString ( " r2_plot_item_%d.sitem " , i ) ) ) ;
}
}
// A npc give a mission to give a item to an other npc
// but the item instead of being a r2_plot_item is a normal item like system_mp or big armor
if ( r2PlotItemSheetId . find ( sheetId ) = = r2PlotItemSheetId . end ( ) )
{
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " !!!!!!!!!!!! Someone is trying to hack us " ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " ERROR/HACK : an npc is trying to give to a player a item that is not a plot item SheetId='%s' sheetIdAsInt=%u " , sheetId . toString ( ) . c_str ( ) , sheetId . asInt ( ) ) ;
nlwarning ( " His ai instanceId is %u, use log to know the sessionId and the user " , msg . InstanceId ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
nlwarning ( " !!!!!!!!!!!! " ) ;
return ;
}
}
const uint32 quantity = ( uint32 ) atoi ( itemAndQty [ 1 ] . c_str ( ) ) ;
if ( quantity = = 0 )
{
nlwarning ( " giveMissionItems failed: invalid quantity '%s' " , itemAndQty [ 1 ] . c_str ( ) ) ;
DEBUG_STOP ;
return ;
}
msg . Items . push_back ( sheetId ) ;
msg . Quantities . push_back ( quantity ) ;
}
nlassert ( ! msg . Items . empty ( ) ) ;
nlassert ( msg . Items . size ( ) = = msg . Quantities . size ( ) ) ;
msg . send ( " EGS " ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection talkTo_sc_
A new entry of the npc contextual menu will propose to the targeter player to talk to the npc .
Then user events are triggered on the group to inform it about what happens :
- user_event_1 : triggered each time ( because of the TRICK ) .
- user_event_3 : triggered after the player has talked to the npc .
Warning : this function can only be called after the event " player_target_npc " .
Arguments : s ( missionText ) , c ( groupToNotify ) - >
@ param [ in ] missionText is the text which will appear in the npc contextual menu .
@ param [ in ] groupToNotify is the npc group which will receive the user events .
@ code
( @ groupToNotify ) group_name . context ( ) ;
( ) talkTo ( " Mission text " , @ groupToNotify ) ;
@ endcode
*/
// CSpawnBotNpc
void talkTo_sc_ ( CStateInstance * entity , CScriptStack & stack )
{
CGroupNpc * const groupToNotify = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ;
stack . pop ( ) ;
string missionText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
if ( groupToNotify = = NULL )
{
nlwarning ( " talkTo failed: groupToNotify is NULL " ) ;
DEBUG_STOP ;
return ;
}
nlassert ( entity ! = NULL ) ;
CGroup * const group = entity - > getGroup ( ) ;
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( aiInstance = = NULL )
{
nlwarning ( " talkTo failed: the AI instance of the entity is NULL " ) ;
DEBUG_STOP ;
return ;
}
CBotPlayer * const talkingPlayer = TempPlayer ;
CSpawnBotNpc * const talkingNpc = dynamic_cast < CSpawnBotNpc * > ( TempSpeaker ) ;
if ( talkingPlayer = = NULL
| | talkingNpc = = NULL
| | talkingNpc - > getPersistent ( ) . getOwner ( ) ! = group ) // check if the talking npc is in this group
{
nlwarning ( " talkTo failed: invalid interlocutors " ) ;
DEBUG_STOP ;
return ;
}
// do nothing if one of them is dead
if ( ! talkingPlayer - > isAlive ( ) | | ! talkingNpc - > isAlive ( ) )
{
return ;
}
// turn the npc to face the player
talkingNpc - > setTheta ( talkingNpc - > pos ( ) . angleTo ( talkingPlayer - > pos ( ) ) ) ;
// send the request to the EGS
// TRICK: here we use an empty give item request
CGiveItemRequestMsg msg ;
msg . InstanceId = aiInstance - > getInstanceNumber ( ) ;
msg . GroupAlias = groupToNotify - > getAlias ( ) ;
msg . CharacterRowId = talkingPlayer - > dataSetRow ( ) ;
msg . CreatureRowId = talkingNpc - > dataSetRow ( ) ;
msg . MissionText = missionText ;
nlassert ( msg . Items . empty ( ) ) ;
nlassert ( msg . Quantities . empty ( ) ) ;
msg . send ( " EGS " ) ;
}
//give_reward
void giveReward_ssssc_ ( CStateInstance * entity , CScriptStack & stack )
{
CGroupNpc * const groupToNotify = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ;
stack . pop ( ) ;
string notEnoughPointsText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
string inventoryFullText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
string rareRewardText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
string rewardText = ( string ) stack . top ( ) ;
stack . pop ( ) ;
if ( groupToNotify = = NULL )
{
nlwarning ( " giveReward failed: groupToNotify is NULL " ) ;
DEBUG_STOP ;
return ;
}
nlassert ( entity ! = NULL ) ;
CGroup * const group = entity - > getGroup ( ) ;
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( aiInstance = = NULL )
{
nlwarning ( " giveReward failed: the AI instance of the entity is NULL " ) ;
DEBUG_STOP ;
return ;
}
CEntityId charEid ( group - > getEventParamString ( 0 ) ) ; // must be player char EID
CEntityId npcEid ( group - > getEventParamString ( 1 ) ) ; // must be NPC EID
if ( charEid = = CEntityId : : Unknown | | npcEid = = CEntityId : : Unknown )
{
nlwarning ( " giveReward failed: the chareter or npc can't be retrreived from the event parameter " ) ;
DEBUG_STOP ;
return ;
}
// retrieve the CBotPlayer
CAIEntityPhysical * charEntity = CAIS : : instance ( ) . getEntityPhysical ( TheDataset . getDataSetRow ( charEid ) ) ;
if ( ! charEntity )
return ;
CBotPlayer * talkingPlayer = NLMISC : : safe_cast < CBotPlayer * > ( charEntity ) ;
if ( ! talkingPlayer )
return ;
// retrieve the CSpawnBotNpcBotPlayer
CAIEntityPhysical * npcEntity = CAIS : : instance ( ) . getEntityPhysical ( TheDataset . getDataSetRow ( npcEid ) ) ;
if ( ! npcEntity )
return ;
CSpawnBotNpc * talkingNpc = NLMISC : : safe_cast < CSpawnBotNpc * > ( npcEntity ) ;
if ( ! talkingNpc )
return ;
// CBotPlayer* const talkingPlayer = TempPlayer;
// CSpawnBotNpc* const talkingNpc = dynamic_cast<CSpawnBotNpc*>(TempSpeaker);
if ( talkingPlayer = = NULL
| | talkingNpc = = NULL )
{
nlwarning ( " giveReward failed: invalid interlocutors " ) ;
DEBUG_STOP ;
return ;
}
// do nothing if one of them is dead
if ( ! talkingPlayer - > isAlive ( ) | | ! talkingNpc - > isAlive ( ) )
{
return ;
}
// turn the npc to face the player
talkingNpc - > setTheta ( talkingNpc - > pos ( ) . angleTo ( talkingPlayer - > pos ( ) ) ) ;
TDataSetRow CharacterRowId = talkingPlayer - > dataSetRow ( ) ;
TDataSetRow CreatureRowId = talkingNpc - > dataSetRow ( ) ;
IAisControl : : getInstance ( ) - > giveRewardMessage ( CharacterRowId , CreatureRowId ,
rewardText , rareRewardText , inventoryFullText , notEnoughPointsText ) ;
}
//give_reward
void teleportNear_fffc_ ( CStateInstance * entity , CScriptStack & stack )
{
CGroupNpc * const groupToNotify = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ;
stack . pop ( ) ;
float z = ( float ) stack . top ( ) ; stack . pop ( ) ;
float y = ( float ) stack . top ( ) ; stack . pop ( ) ;
float x = ( float ) stack . top ( ) ; stack . pop ( ) ;
if ( groupToNotify = = NULL )
{
nlwarning ( " teleportNear failed: groupToNotify is NULL " ) ;
DEBUG_STOP ;
return ;
}
nlassert ( entity ! = NULL ) ;
CGroup * const group = entity - > getGroup ( ) ;
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( aiInstance = = NULL )
{
nlwarning ( " giveReward failed: the AI instance of the entity is NULL " ) ;
DEBUG_STOP ;
return ;
}
CEntityId charEid ( group - > getEventParamString ( 0 ) ) ; // must be player char EID
CEntityId npcEid ( group - > getEventParamString ( 1 ) ) ; // must be NPC EID
if ( charEid = = CEntityId : : Unknown | | npcEid = = CEntityId : : Unknown )
{
nlwarning ( " giveReward failed: the character or npc can't be retreived from the event parameter " ) ;
DEBUG_STOP ;
return ;
}
// retrieve the CBotPlayer
CAIEntityPhysical * charEntity = CAIS : : instance ( ) . getEntityPhysical ( TheDataset . getDataSetRow ( charEid ) ) ;
if ( ! charEntity )
return ;
CBotPlayer * talkingPlayer = NLMISC : : safe_cast < CBotPlayer * > ( charEntity ) ;
if ( ! talkingPlayer )
return ;
// retrieve the CSpawnBotNpcBotPlayer
CAIEntityPhysical * npcEntity = CAIS : : instance ( ) . getEntityPhysical ( TheDataset . getDataSetRow ( npcEid ) ) ;
if ( ! npcEntity )
return ;
CSpawnBotNpc * talkingNpc = NLMISC : : safe_cast < CSpawnBotNpc * > ( npcEntity ) ;
if ( ! talkingNpc )
return ;
// CBotPlayer* const talkingPlayer = TempPlayer;
// CSpawnBotNpc* const talkingNpc = dynamic_cast<CSpawnBotNpc*>(TempSpeaker);
if ( talkingPlayer = = NULL
| | talkingNpc = = NULL )
{
nlwarning ( " giveReward failed: invalid interlocutors " ) ;
DEBUG_STOP ;
return ;
}
// do nothing if one of them is dead
if ( ! talkingPlayer - > isAlive ( ) | | ! talkingNpc - > isAlive ( ) )
{
return ;
}
// turn the npc to face the player
/// talkingNpc->setTheta(talkingNpc->pos().angleTo(talkingPlayer->pos()));
TDataSetRow CharacterRowId = talkingPlayer - > dataSetRow ( ) ;
TDataSetRow CreatureRowId = talkingNpc - > dataSetRow ( ) ;
NLMISC : : CEntityId player = CMirrors : : getEntityId ( CharacterRowId ) ;
if ( player ! = NLMISC : : CEntityId : : Unknown )
{
IAisControl : : getInstance ( ) - > teleportNearMessage ( player , x , y , z ) ;
}
}
// Return an "alive" bot from a group by the bot name
static CSpawnBot * getSpawnBotFromGroupByName ( CGroupNpc * const group , const std : : string & botname )
{
// Group exist
if ( ! group ) { return 0 ; }
// Group is in a valid AIInstance
{
if ( ! group - > getOwner ( ) ) { return 0 ; }
IManagerParent * const managerParent = group - > getOwner ( ) - > getOwner ( ) ;
CAIInstance * const aiInstance = dynamic_cast < CAIInstance * > ( managerParent ) ;
if ( ! aiInstance ) { return 0 ; }
}
// Bot is spawn and alive
{
CSpawnBot * spawnBot = 0 ;
CAliasCont < CBot > const & bots = group - > bots ( ) ;
CBot * child = bots . getChildByName ( botname ) ;
if ( ! child ) { return 0 ; }
spawnBot = child - > getSpawnObj ( ) ;
if ( ! spawnBot | | ! spawnBot - > isAlive ( ) ) { return 0 ; }
return spawnBot ;
}
nlassert ( 0 ) ; //this path is never used
return 0 ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection facing_cscs_
The npc1 will turn to npc2
Arguments : c ( group1 ) , s ( botname1 ) , c ( group2 ) , s ( botname2 ) , - >
@ param [ in ] group1 is the npc group of the boot that turn to the other bot
@ param [ in ] botname1 is the name of the bot
@ param [ in ] group2 is the npc group of the boot that is the target
@ param [ in ] botname2 is the name of the bot that is targeted
@ code
( @ group1 ) group_name1 . context ( ) ;
( @ group1 ) group_name2 . context ( ) ;
( ) facing ( @ group1 , " bob " , @ group2 , " bobette " ) ;
@ endcode
*/
// CSpawnBotNpc
void facing_cscs_ ( CStateInstance * entity , CScriptStack & stack )
{
string botname2 = ( string ) stack . top ( ) ; stack . pop ( ) ;
CGroupNpc * const group2 = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ; stack . pop ( ) ;
string botname1 = ( string ) stack . top ( ) ; stack . pop ( ) ;
CGroupNpc * const group1 = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ; stack . pop ( ) ;
CSpawnBot * bot1 = getSpawnBotFromGroupByName ( group1 , botname1 ) ;
CSpawnBot * bot2 = getSpawnBotFromGroupByName ( group2 , botname2 ) ;
if ( ! bot1 | | ! bot2 ) { return ; }
CSpawnBotNpc * bot = dynamic_cast < CSpawnBotNpc * > ( bot1 ) ;
if ( ! bot ) { return ; }
// Same than setTheta but initial theta is restored few secondes later
bot - > setFacing ( bot1 - > pos ( ) . angleTo ( bot2 - > pos ( ) ) ) ;
// bot1->setTheta(bot1->pos().angleTo(bot2->pos()));
}
//----------------------------------------------------------------------------
/** @page code
@ subsection npcSay_css_
A new entry of the npc contextual menu will propose to the targeter player to talk to the npc .
Make a npc say a text
There are 3 type of text
- Classic StringId ( IOS does traduction )
- RING " complete text (no traduction)
- RING StringId ( DSS does traduction )
Arguments : c ( group ) , s ( botname ) , s ( text ) , - >
@ param [ in ] group is the npc group of the boot that does the emote
@ param [ in ] botname is the name of the bot
@ param [ in ] text is the name of the emote
@ code
( @ group ) group_name . context ( ) ;
( ) emote ( @ group , " bob " , " DSS_1601 RtEntryText_6 " ) ; // Send To dss
( ) emote ( @ group , " bob " , " RAW Ca farte? " ) ; // phrase direcly send to IOS as raw (for debug)
( ) emote ( @ group , " bob " , " answer_group_no_m " ) ; //phrase id
@ endcode
*/
// CSpawnBotNpc
# include "game_share/chat_group.h"
# include "game_share/send_chat.h"
void npcSay_css_ ( CStateInstance * entity , CScriptStack & stack )
{
string text = ( string ) stack . top ( ) ; stack . pop ( ) ;
string botname = ( string ) stack . top ( ) ; stack . pop ( ) ;
CGroupNpc * const group = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ; stack . pop ( ) ;
CSpawnBot * spawnBot = getSpawnBotFromGroupByName ( group , botname ) ;
if ( ! spawnBot ) { return ; }
std : : string prefix = NLMISC : : CSString ( text ) . left ( 4 ) ;
if ( prefix = = " DSS_ " )
{
2010-05-18 14:53:47 +00:00
NLMISC : : CSString phrase = NLMISC : : CSString ( text ) . right ( ( unsigned int ) text . length ( ) - 4 ) ;
2010-05-06 00:08:41 +00:00
NLMISC : : CSString idStr = phrase . strtok ( " " , false , false , false , false ) ;
uint32 scenarioId = atoi ( idStr . c_str ( ) ) ;
forwardToDss ( spawnBot - > dataSetRow ( ) , CChatGroup : : say , phrase , scenarioId ) ;
return ;
}
if ( prefix = = " RAW " )
{
2010-05-18 14:53:47 +00:00
NLMISC : : CSString phrase = NLMISC : : CSString ( text ) . right ( ( unsigned int ) text . length ( ) - 4 ) ;
2010-05-06 00:08:41 +00:00
npcChatToChannelSentence ( spawnBot - > dataSetRow ( ) , CChatGroup : : say , phrase ) ;
return ;
}
//Classic phrase ID
npcChatToChannel ( spawnBot - > dataSetRow ( ) , CChatGroup : : say , text ) ;
return ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection deactivateEasterEgg_fff_
Call the DSS function CAnimationModule : : dssMessage
Arguments : f ( easterEggId ) , f ( scenarioId ) , f ( actId ) - >
@ code
( ) dssMessage ( 114 , " BC " , " Bob " , " Life is harde " ) ;
@ endcode
*/
void dssMessage_fsss_ ( CStateInstance * entity , CScriptStack & stack )
{
string msg = ( string ) stack . top ( ) ; stack . pop ( ) ;
string who = ( string ) stack . top ( ) ; stack . pop ( ) ;
string mode = ( string ) stack . top ( ) ; stack . pop ( ) ;
float instance = ( float ) stack . top ( ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > dssMessage ( TSessionId ( uint32 ( instance ) ) , mode , who , msg ) ;
return ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection setScenarioPoints
Call the DSS function CAnimationModule : : setScenarioPoints
Arguments : f ( scenarioInstance ) , f ( scenarioPoints ) - >
@ code
( ) setScenarioPoints ( 114 , 42 ) ;
@ endcode
*/
void setScenarioPoints_ff_ ( CStateInstance * entity , CScriptStack & stack )
{
float scenarioPoints = ( float ) stack . top ( ) ; stack . pop ( ) ;
float instance = ( float ) stack . top ( ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > setScenarioPoints ( TSessionId ( uint32 ( instance ) ) , scenarioPoints ) ;
return ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection startScenarioTiming
Call the DSS function CAnimationModule : : startScenarioTiming
Arguments : f ( scenarioInstance ) ,
@ code
( ) startScenarioTiming ( 114 , 42 ) ;
@ endcode
*/
void startScenarioTiming_f_ ( CStateInstance * entity , CScriptStack & stack )
{
float instance = ( float ) stack . top ( ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > startScenarioTiming ( TSessionId ( uint32 ( instance ) ) ) ;
return ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection endScenarioTiming
Call the DSS function CAnimationModule : : endScenarioTiming
Arguments : f ( scenarioInstance ) ,
@ code
( ) endScenarioTiming ( 114 , 42 ) ;
@ endcode
*/
void endScenarioTiming_f_ ( CStateInstance * entity , CScriptStack & stack )
{
float instance = ( float ) stack . top ( ) ; stack . pop ( ) ;
IAisControl : : getInstance ( ) - > endScenarioTiming ( TSessionId ( uint32 ( instance ) ) ) ;
return ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection emote_css_
Make a npc launch a emote
Arguments : c ( group1 ) , s ( botname1 ) , c ( group2 ) , s ( botname2 ) , - >
@ param [ in ] group1 is the npc group of the boot that does the emote
@ param [ in ] botname1 is the name of the bot
@ param [ in ] emote is the name of the emote
@ code
( @ group1 ) group_name . context ( ) ;
( ) emote ( @ group1 , " bob " , " sad " )
@ endcode
*/
// CSpawnBotNpc
/****************************************************************************/
void emote_css_ ( CStateInstance * entity , CScriptStack & stack )
{
string emoteName = ( string ) stack . top ( ) ; stack . pop ( ) ;
string botname = ( string ) stack . top ( ) ; stack . pop ( ) ;
CGroupNpc * const group = dynamic_cast < CGroupNpc * > ( ( IScriptContext * ) stack . top ( ) ) ; stack . pop ( ) ;
CSpawnBot * spawnBot = getSpawnBotFromGroupByName ( group , botname ) ;
if ( ! spawnBot ) { return ; }
//CBot& bot = spawnBot->getPersistent();
// The entity Id must be valid (whe know that the bot is alive so its entity Id must be ok)
NLMISC : : CEntityId entityId = spawnBot - > getEntityId ( ) ;
if ( entityId = = NLMISC : : CEntityId : : Unknown )
{
return ;
}
// Is the emote valid
uint32 emoteId = CAIS : : instance ( ) . getEmotNumber ( emoteName ) ;
if ( emoteId = = ~ 0 )
{
return ;
}
// Get the behaviour Id
MBEHAV : : EBehaviour behaviourId = ( MBEHAV : : EBehaviour ) ( emoteId + MBEHAV : : EMOTE_BEGIN ) ;
// Change the behaviour
NLNET : : CMessage msgout ( " SET_BEHAVIOUR " ) ;
msgout . serial ( entityId ) ;
MBEHAV : : CBehaviour bh ( behaviourId ) ;
bh . Data = ( uint16 ) ( CTimeInterface : : gameCycle ( ) ) ;
msgout . serial ( bh ) ;
NLNET : : CUnifiedNetwork : : getInstance ( ) - > send ( " EGS " , msgout ) ;
}
//----------------------------------------------------------------------------
/** @page code
@ subsection maxHitRange_f_
Sets the max hit range possible for player , in meters
Arguments : f ( MaxHitRange ) - >
@ param [ in ] MaxHitRange set the max range for player can hit this npc group
@ code
( ) maxHitRange ( 50 ) ; // Set the max hit range in 50 meters all npc in group
@ endcode
*/
// CBotNpc
void maxHitRange_f_ ( CStateInstance * entity , CScriptStack & stack )
{
float maxHitRange = ( float & ) stack . top ( ) ; stack . pop ( ) ;
CGroup * group = entity - > getGroup ( ) ;
CGroupNpc * npcGroup = NLMISC : : safe_cast < CGroupNpc * > ( group ) ;
FOREACH ( botIt , CCont < CBot > , group - > bots ( ) )
{
CBot * bot = * botIt ;
if ( ! bot - > isSpawned ( ) ) return ;
if ( bot - > getRyzomType ( ) = = RYZOMID : : npc )
{
CBotNpc * botNpc = NLMISC : : safe_cast < CBotNpc * > ( bot ) ;
botNpc - > setMaxHitRangeForPlayer ( maxHitRange ) ;
}
}
}
////----------------------------------------------------------------------------
///** @page code
//
//@subsection hideMissionStepIcon_b_
//Allows to hide icons for current missions steps having interactions with this NPC (default: shown)
//
//Arguments: b(hide) ->
//@param[in] hide true to hide the icon for all mission steps relating to this NPC (default: false)
//
//*/
//// CBotNpc
//void hideMissionStepIcon_b_(CStateInstance* entity, CScriptStack& stack)
//{
// bool b = (bool&)stack.top(); stack.pop();
// CGroup* group = entity->getGroup();
// CGroupNpc* npcGroup = NLMISC::safe_cast<CGroupNpc*>(group);
//
// FOREACH(botIt, CCont<CBot>, group->bots())
// {
// CBot* bot = *botIt;
//
// if (!bot->isSpawned()) return;
// if (bot->getRyzomType() == RYZOMID::npc)
// {
// CBotNpc* botNpc = NLMISC::safe_cast<CBotNpc*>(bot);
// botNpc->setMissionStepIconHidden(b);
// }
// }
//}
//
////----------------------------------------------------------------------------
///** @page code
//
//@subsection hideMissionGiverIcon_b_
//Allows to hide icons for missions proposed by this NPC (default: shown)
//
//Arguments: b(hide) ->
//@param[in] hide true to hide the icon for all missions propsed by this NPC (default: false)
//
//*/
//// CBotNpc
//void hideMissionGiverIcon_b_(CStateInstance* entity, CScriptStack& stack)
//{
// bool b = (bool&)stack.top(); stack.pop();
// CGroup* group = entity->getGroup();
// CGroupNpc* npcGroup = NLMISC::safe_cast<CGroupNpc*>(group);
//
// FOREACH(botIt, CCont<CBot>, group->bots())
// {
// CBot* bot = *botIt;
//
// if (!bot->isSpawned()) return;
// if (bot->getRyzomType() == RYZOMID::npc)
// {
// CBotNpc* botNpc = NLMISC::safe_cast<CBotNpc*>(bot);
// botNpc->setMissionGiverIconHidden(b);
// }
// }
//}
std : : map < std : : string , FScrptNativeFunc > nfGetNpcGroupNativeFunctions ( )
{
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 , setFactionProp_ss_ ) ;
REGISTER_NATIVE_FUNC ( functions , moveToZone_ss_ ) ;
REGISTER_NATIVE_FUNC ( functions , setActivity_s_ ) ;
REGISTER_NATIVE_FUNC ( functions , waitInZone_s_ ) ;
REGISTER_NATIVE_FUNC ( functions , stopMoving__ ) ;
REGISTER_NATIVE_FUNC ( functions , wander__ ) ;
REGISTER_NATIVE_FUNC ( functions , setAttackable_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , setPlayerAttackable_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , setBotAttackable_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , setFactionAttackableAbove_sff_ ) ;
REGISTER_NATIVE_FUNC ( functions , setFactionAttackableBelow_sff_ ) ;
REGISTER_NATIVE_FUNC ( functions , addBotChat_s_ ) ;
REGISTER_NATIVE_FUNC ( functions , clearBotChat__ ) ;
REGISTER_NATIVE_FUNC ( functions , ignoreOffensiveActions_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , setDespawnTime_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , setRespawnTime_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , addHpUpTrigger_ff_ ) ;
REGISTER_NATIVE_FUNC ( functions , delHpUpTrigger_ff_ ) ;
REGISTER_NATIVE_FUNC ( functions , addHpDownTrigger_ff_ ) ;
REGISTER_NATIVE_FUNC ( functions , delHpDownTrigger_ff_ ) ;
REGISTER_NATIVE_FUNC ( functions , addHpUpTrigger_fs_ ) ;
REGISTER_NATIVE_FUNC ( functions , delHpUpTrigger_fs_ ) ;
REGISTER_NATIVE_FUNC ( functions , addHpDownTrigger_fs_ ) ;
REGISTER_NATIVE_FUNC ( functions , delHpDownTrigger_fs_ ) ;
REGISTER_NATIVE_FUNC ( functions , addNamedEntityListener_ssf_ ) ;
REGISTER_NATIVE_FUNC ( functions , delNamedEntityListener_ssf_ ) ;
REGISTER_NATIVE_FUNC ( functions , addNamedEntityListener_sss_ ) ;
REGISTER_NATIVE_FUNC ( functions , delNamedEntityListener_sss_ ) ;
REGISTER_NATIVE_FUNC ( functions , setPlayerController_ss_ ) ;
REGISTER_NATIVE_FUNC ( functions , clearPlayerController_s_ ) ;
REGISTER_NATIVE_FUNC ( functions , activateEasterEgg_fffsffffsss_ ) ;
REGISTER_NATIVE_FUNC ( functions , deactivateEasterEgg_fff_ ) ;
REGISTER_NATIVE_FUNC ( functions , receiveMissionItems_ssc_ ) ;
REGISTER_NATIVE_FUNC ( functions , giveMissionItems_ssc_ ) ;
REGISTER_NATIVE_FUNC ( functions , talkTo_sc_ ) ;
REGISTER_NATIVE_FUNC ( functions , facing_cscs_ ) ;
REGISTER_NATIVE_FUNC ( functions , emote_css_ ) ;
REGISTER_NATIVE_FUNC ( functions , npcSay_css_ ) ;
REGISTER_NATIVE_FUNC ( functions , dssMessage_fsss_ ) ;
REGISTER_NATIVE_FUNC ( functions , despawnBotByAlias_s_ ) ;
REGISTER_NATIVE_FUNC ( functions , giveReward_ssssc_ ) ;
REGISTER_NATIVE_FUNC ( functions , teleportNear_fffc_ ) ;
REGISTER_NATIVE_FUNC ( functions , setScenarioPoints_ff_ ) ;
REGISTER_NATIVE_FUNC ( functions , startScenarioTiming_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , endScenarioTiming_f_ ) ;
REGISTER_NATIVE_FUNC ( functions , maxHitRange_f_ ) ;
// REGISTER_NATIVE_FUNC(functions, hideMissionStepIcon_b_);
// REGISTER_NATIVE_FUNC(functions, hideMissionGiverIcon_b_);
# undef REGISTER_NATIVE_FUNC
return functions ;
}