diff --git a/code/ryzom/server/admin_executor_service.cfg b/code/ryzom/server/admin_executor_service.cfg deleted file mode 100644 index fdf3d6dca..000000000 --- a/code/ryzom/server/admin_executor_service.cfg +++ /dev/null @@ -1,149 +0,0 @@ -// Use with commandline: ryzom_admin_service -A. -C. -L. --nobreak --fulladminname=admin_executor_service --shortadminname=AES - -#include "admin_executor_service_default.cfg" - -// ---- config local variables - -// Address of the admin service (default port is 49996) -ASHost = "localhost"; -ASPort="46701"; - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "aes_open"; - -StartCommands= -{ - // Create a gateway module - "moduleManager.createModule StandardGateway gw", - // add a layer 5 transport - "gw.transportAdd L5Transport l5", - // open the transport - "gw.transportCmd l5(open)", - - /// Create default connection with admin executor service - // Create a gateway module - "moduleManager.createModule StandardGateway gw_aes", - // create the admin executor service module - "moduleManager.createModule AdminExecutorServiceClient aes_client", - "aes_client.plug gw_aes", - - // create a layer 3 client to connect to aes gateway - "gw_aes.transportAdd L3Client aes_l3c", - "gw_aes.transportCmd aes_l3c(connect addr="+AESHost+":"+AESPort+")", - - // create the admin executor service module - "moduleManager.createModule AdminExecutorService aes", - - // create a gateway to connect to as - "moduleManager.createModule StandardGateway asc_gw", - // create a layer 3 client - "asc_gw.transportAdd L3Client l3c", - "asc_gw.transportCmd l3c(connect addr="+ASHost+":"+ASPort+")", - - // create a gateway for services to connect - "moduleManager.createModule StandardGateway aes_gw", - // create a layer 3 server - "aes_gw.transportAdd L3Server l3s", - "aes_gw.transportOptions l3s(PeerInvisible)", - "aes_gw.transportCmd l3s(open port="+AESPort+")", - - // plug the as - "aes.plug asc_gw", - "aes.plug aes_gw", -}; - -StartCommands += -{ - "aes.addRegisteredService bms_master open", -// "aes.addRegisteredService bms_pd_master open", - "aes.addRegisteredService egs open", - "aes.addRegisteredService gpms open", - "aes.addRegisteredService ios open", - "aes.addRegisteredService rns open", - "aes.addRegisteredService rws open", - "aes.addRegisteredService ts open", - "aes.addRegisteredService ms open", - "aes.addRegisteredService ais_newbyland open", - "aes.addRegisteredService mfs open", - "aes.addRegisteredService su open", - "aes.addRegisteredService fes open", - "aes.addRegisteredService sbs open", - "aes.addRegisteredService lgs open", -// "aes.addRegisteredService mos open", -// "aes.addRegisteredService pdss open", - "aes.addRegisteredService ras open", -}; - - -bms_master = { "./", "/home/nevrax/dev/live/service_backup_service/backup_service", "-C. -L. --nobreak --writepid -P49990" }; -bms_pd_master = { "./", "/home/nevrax/dev/live/service_backup_service/backup_service", "-C. -L. --nobreak --writepid -P49992" }; -egs = { "./", "/home/nevrax/dev/live/service_entities_game_service/entities_game_service", "-C. -L. --nobreak --writepid" }; -gpms = { "/home/nevrax/dev/gpms", "/home/nevrax/dev/live/service_gpm_service/gpm_service", "-C. -L. --nobreak --writepid" }; -ios = { "/home/nevrax/dev/ios", "/home/nevrax/dev/live/service_input_output_service/input_output_service", "-C. -L. --nobreak --writepid" }; -rns = { "/home/nevrax/dev/rns", "/home/nevrax/dev/live/service_ryzom_naming_service/ryzom_naming_service", "-C. -L. --nobreak --writepid" }; -rws = { "/home/nevrax/dev/rws", "/home/nevrax/dev/live/service_ryzom_welcome_service/ryzom_welcome_service", "-C. -L. --nobreak --writepid" }; -ts = { "/home/nevrax/dev/ts", "/home/nevrax/dev/live/service_tick_service/tick_service", "-C. -L. --nobreak --writepid" }; -ms = { "/home/nevrax/dev/ms", "/home/nevrax/dev/live/service_mirror_service/mirror_service", "-C. -L. --nobreak --writepid" }; -ais_newbyland = { "/home/nevrax/dev/ais_newbyland", "/home/nevrax/dev/live/service_ai_service/ai_service", "-C. -L. --nobreak --writepid -mCommon:Newbieland:Post" }; -mfs = { "/home/nevrax/dev/mfs", "/home/nevrax/dev/live/service_mail_forum_service/mail_forum_service", "-C. -L. --nobreak --writepid" }; -su = { "/home/nevrax/dev/su", "/home/nevrax/dev/live/service_shard_unifier_service/shard_unifier_service", "-C. -L. --nobreak --writepid" }; -fes = { "/home/nevrax/dev/fes", "/home/nevrax/dev/live/service_frontend_service/frontend_service", "-C. -L. --nobreak --writepid" }; -sbs = { "/home/nevrax/dev/sbs", "/home/nevrax/dev/live/service_session_browser_server/session_browser_server", "-C. -L. --nobreak --writepid" }; -lgs = { "/home/nevrax/dev/lgs", "/home/nevrax/dev/live/service_logger_service/logger_service", "-C. -L. --nobreak --writepid" }; -mos = { "/home/nevrax/dev/mos", "/home/nevrax/dev/live/service_monitor_service/monitor_service", "-C. -L. --nobreak --writepid" }; -pdss = { "/home/nevrax/dev/pdss", "/home/nevrax/dev/live/service_pd_support_service/pd_support_service", "-C. -L. --nobreak --writepid" }; -ras = { "./", "src/ryzom_admin_service/ryzom_admin_service", "--fulladminname=admin_service --shortadminname=AS -C. -L. --nobreak --writepid" }; - -RegisteredServices= -{ - "bms_master", - "bms_pd_master", - "egs", - "gpms", - "ios", - "rns", - "rws", - "ts", - "ms", - "ais_newbyland", - "mfs", - "su", - "fes", - "sbs", - "lgs", - "mos", - "pdss", - "ras", -}; - -// -DontUseStdIn = 0; - -// ---- service NeL variables (used by CVariable class) - -// If the update loop is too slow, a thread will produce an assertion. -// By default, the value is set to 10 minutes. -// Set to 0 for no assertion. -UpdateAssertionThreadTimeout = 0; - -// ---- service custom variables (used by ConfigFile class) - - // ---- service custom variables (used by CVariable class) - -// in second, -1 for not restarting -RestartDelay = 60; - -// how many second before aborting the request if not finished -RequestTimeout = 5; - -// log path for advanced log report -LogPath = "/."; - -// setup for deployment environment with exeternal configuration system responsible for launching apps and -// for configuring AES services -DontLaunchServicesDirectly = 1; -UseExplicitAESRegistration = 1; -KillServicesOnDisconnect = 1; - -ShardName="dev"; diff --git a/code/ryzom/server/admin_executor_service_default.cfg b/code/ryzom/server/admin_executor_service_default.cfg deleted file mode 100644 index d975823de..000000000 --- a/code/ryzom/server/admin_executor_service_default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -#include "common.cfg" - -// I'm the AES, I'll not connect to myself! -DontUseAES = 1; - -// I don't need a connection to a naming service -DontUseNS = 1; diff --git a/code/ryzom/server/admin_service.cfg b/code/ryzom/server/admin_service.cfg deleted file mode 100644 index 59d4e3308..000000000 --- a/code/ryzom/server/admin_service.cfg +++ /dev/null @@ -1,22 +0,0 @@ -// Use with commandline: ryzom_admin_service --fulladminname=ryzom_admin_service --shortadminname=AS -C. -L. --nobreak --writepid - -// ---- config local variables - -ASWebPort="46700"; -ASPort="46701"; - -#include "admin_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "ras"; - -Paths = { - ".", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - - // ---- service custom variables (used by CVariable class) diff --git a/code/ryzom/server/admin_service_default.cfg b/code/ryzom/server/admin_service_default.cfg deleted file mode 100644 index 538b856b1..000000000 --- a/code/ryzom/server/admin_service_default.cfg +++ /dev/null @@ -1,27 +0,0 @@ -#include "common.cfg" - -DontUseNS = 1; - -RRDToolPath = "rrdtool"; -RRDVarPath = "save_shard/rrd_graphs"; - -// Variables required to be defined by other cfgs -//AESHost="localhost"; -//ASWebPort="46700"; -//ASPort="46701"; - -StartCommands += -{ - // create the admin service module and open the web interface - "moduleManager.createModule AdminService as webPort="+ASWebPort, - - // create a gateway for aes to connect - "moduleManager.createModule StandardGateway as_gw", - // create a layer 3 server - "as_gw.transportAdd L3Server l3s", - "as_gw.transportOptions l3s(PeerInvisible)", - "as_gw.transportCmd l3s(open port="+ASPort+")", - - // plug the as - "as.plug as_gw", -}; diff --git a/code/ryzom/server/ai_service.cfg b/code/ryzom/server/ai_service.cfg deleted file mode 100644 index 1a11d9507..000000000 --- a/code/ryzom/server/ai_service.cfg +++ /dev/null @@ -1,64 +0,0 @@ -// Use with commandline: ai_service -C. -L. --nobreak --writepid -mCommon:Newbieland:Post - -// ---- config local variables - -SUPort = 50505; -SUHost = "localhost"; -// SU - listen address of the SU service (for L5 connections) -SUAddress = SUHost+":"+SUPort; - -#include "ai_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "ais_newbyland"; - -GraphVars += { "TickSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; -GraphVars += { "MirrorCallbackCount", "60000" }; -GraphVars += { "MirrorCallbackTime", "60000" }; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -#include "used_continents.cfg" - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - -// define the primitives configuration used. (AIS, EGS) -UsedPrimitives = -{ - "newbieland_all", -}; - -// the following variable must be defined but should be empty - it's presence is used to change the behaviour -// of the packed sheet reader -GeorgePaths = { "" }; - -// ---- service custom variables (used by CVariable class) - -NbPlayersLimit = PlayerLimit; - -// Entity Limits (AIS) -NbPetLimit = NbPlayersLimit*4; -NbFaunaLimit = 50000; -NbNpcLimit = 20000; -NbFxLimit = 500; - -#include "backup_service_interface.cfg" - -// Set this shard as a ring (1) or mainland (0) shard (main behavior switch) -IsRingShard = 0; - -// Disable ryzom verbose logging -VerboseMIRROR = 0; diff --git a/code/ryzom/server/ai_service_default.cfg b/code/ryzom/server/ai_service_default.cfg deleted file mode 100644 index 3c9a6edcd..000000000 --- a/code/ryzom/server/ai_service_default.cfg +++ /dev/null @@ -1,198 +0,0 @@ -#include "common.cfg" - -// a list of system command that run at server startup. -SystemCmd = {}; - -////////////////////////////////////////////////////////////////////////////// -//- Basic (specific) heal profile parameters --------------------------------- -// Downtime for normal heal (on other bots of the group) -HealSpecificDowntime = 100; -// Downtime for self heal -HealSpecificDowntimeSelf = 100; -////////////////////////////////////////////////////////////////////////////// - -// Disable caching of ligo primitive in binary files -CachePrims = 0; -CachePrimsLog = 0; - -// do not log the corrected position. -LogAcceptablePos = 0; -// do not log group creation failure -LogGroupCreationFailure = 0; -// do not log aliad tree owner construstion. -LogAliasTreeOwner = 0; -// do not log outpost info -LogOutpostDebug = 0; -// Speed factor, for debug purpose only. Don't set to high speed factor ! -SpeedFactor = 1; -// Speep up the timer triggering. Set a value between 1 (normal) and INT_MAX. -TimerSpeedUp = 1; - -// Default timer for wander behavior -DefaultWanderMinTimer = 50; // 5s -DefaultWanderMaxTimer = 100; // 10s - -// Fame and guard behavior -// Fame value under witch the guard attack the player in sigth -FameForGuardAttack = -450000; -// The minimum of fame for guard to help the player -FameForGuardHelp = -200000; - -// The default aggro distance for NPC -DefaultNpcAggroDist = 15; -// The default escort range for escort behavior -DefaultEscortRange = 10; - -////////////////////////////////////////////////////////////////////////////// -// Aggro // -////////////////////////////////////////////////////////////////////////////// -AggroReturnDistCheck = 15.0; -AggroReturnDistCheckFauna = 15.0; -AggroReturnDistCheckNpc = 1.5; -AggroD1Radius = 250.0; -AggroD2Radius = 150.0; -AggroPrimaryGroupDist = 0.0; -AggroPrimaryGroupCoef = 0.0; -AggroSecondaryGroupDist = 0.0; -AggroSecondaryGroupCoef = 0.0; -AggroPropagationRadius = 60.0; - -BotRepopFx = ""; - -// GROUP KEYWORDS -// used mainly in event handlers to determine to which groups events apply -KeywordsGroupNpc = { - - "patrol", // a group of bots who guard a patrol route or point - "convoy", // a group with pack animals who follow roads from place to place - "with_players", // a group who may travel with players -}; - -// BOT KEYWORDS -// used mainly in npc_state_profile to determine which ai profiles to assign to which bots -KeywordsBotNpc = { - - "team_leader", // a bot who leads the way in front of their team (and acts as leader - // in discussion with players) - "animal_leader", // a bot who leads pack animals - "guard", // a bot who is a guard of some sort (eg karavan guard) - "emissary", // eg karavan emissary - "preacher", // eg kami preacher - "guardian", // typically kami guardians - "vip", // someone who has an escort of players or NPCs (assumed to be harmless) -}; - -// STATE KEYWORDS -// used mainly in event handlers to determine to which state events apply -// eg: when a player goes link dead if the team that this player is escorting -// is in a dangerous area the team may enter a 'protect ourselves and wait for -// players' punctual state -KeywordsStateNpc = { - - "safe", // eg the gathering point at town entrance - "dangerous", // eg a route through the wilds -}; - -ColourNames = -{ - "red : 0", - "beige : 1", - "green : 2", - "turquoise : 3", - "blue : 4", - "violet : 5", - "white : 6", - "black : 7", - - "redHair: 0", - "blackHair: 1", -}; - - -StartCommandsWhenMirrorReady = { -}; - -//--------------------------------------------------------- -// commands for multi IA configuration -// For multi IA config, use the -m command line switch folowed -// by a semicolon separated list of command block to run. -// ex : -// -mCommon:Matis:Post -// will execute the folowing command blocks in order : -// * StartCommandsWhenMirrorReadyCommon -// * StartCommandsWhenMirrorReadyMatis -// * StartCommandsWhenMirrorReadyPost -//--------------------------------------------------------- -// common commands before loading continents -StartCommandsWhenMirrorReadyCommon = -{ - "RandomPosMaxRetry 6400", - "fightRangeRange 4 60", - "LogOutpostDebug 1", - "grpHistoryRecordLog", - - "verboseAIProfiles", - "verboseAliasNodeTreeParserLog", - "verboseCombatLog", - "verboseFaunaMgrLog", - "verboseFaunaParseLog", - "verboseNPCBotProfiles", - "verboseNPCMgrLog", - "verboseNPCParserLog", - "verboseNpcDescriptionMsgLog", - "verbosePrimitiveParserLog", -// "verboseSwitchMultipleChangesOfAProperty", -}; - -// commands for Newbieland continent -StartCommandsWhenMirrorReadyNewbieland = -{ - "loadContinent newbieland", - "createStaticAIInstance newbieland", - "loadMapsFromCommon newbieland_all", -}; - -// commands for post continents loading -StartCommandsWhenMirrorReadyPost = -{ - "spawnInstances", - "updateAI", - "updateAI", -}; - - -// commands for Ring continents -StartCommandsWhenMirrorReadyRing = -{ - "loadContinent r2_desert", - "createDynamicAIInstance 10000", - "loadPrimitiveFile dummy.primitive", - - "loadContinent r2_forest", - "createDynamicAIInstance 10001", - "loadPrimitiveFile dummy.primitive", - - "loadContinent r2_lakes", - "createDynamicAIInstance 10003", - "loadPrimitiveFile dummy.primitive", - - "loadContinent r2_jungle", - "createDynamicAIInstance 10002", - "loadPrimitiveFile dummy.primitive", - - "loadContinent r2_roots", - "createDynamicAIInstance 10004", - "loadPrimitiveFile dummy.primitive", - -// "spawnInstances", - "updateAI", - "updateAI", - - // L5 connect to the shard unifier - "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", - - // Create a shard AIS Module - "moduleManager.createModule AisControl ais", - // Connect AIS - "ais.plug gw" -}; diff --git a/code/ryzom/server/backup_service.cfg b/code/ryzom/server/backup_service.cfg deleted file mode 100644 index 16d870748..000000000 --- a/code/ryzom/server/backup_service.cfg +++ /dev/null @@ -1,34 +0,0 @@ -// Use with commandline: backup_service -C. -L. --nobreak --writepid -P49990 - -#include "backup_service_default.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName = "bms_master"; - -Paths += { - ".", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// Where to save specific shard data (ie: player backup), relatively to SaveShardRoot -SaveFilesDirectory = ""; - -// where to save generic shard data (ie: packed_sheet) -WriteFilesDirectory = "data_shard"; - -// ---- service custom variables (used by ConfigFile class) - -WebPort = 49970; - -// ---- service custom variables (used by CVariable class) - -// BS - Root directory where data are backuped to -IncrementalBackupDirectory = "../incremental_backup"; - -// Root directory where data from shards are stored into -SaveShardRoot = "save_shard/"; diff --git a/code/ryzom/server/backup_service_default.cfg b/code/ryzom/server/backup_service_default.cfg deleted file mode 100644 index c74f48d28..000000000 --- a/code/ryzom/server/backup_service_default.cfg +++ /dev/null @@ -1,32 +0,0 @@ -#include "common.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -DontUseNS = 1; - -// ---- service NeL variables (used by CVariable class) - -ListeningPort = 49990; - -// ---- service custom variables (used by ConfigFile class) - -// Listening port for the Web server to connect in - -WebPort = 49898; - -BSReadState = 1; - - -// ---- service custom variables (used by CVariable class) - -// Port for the Layer 3 interface of the backup service -L3ListeningPort = 49950; - -// template path from SaveShardRoot to find character saves -SaveTemplatePath = "$shard/characters/account_$userid_$charid$ext"; - -// character saves possible extension list -SaveExtList = "_pdr.bin _pdr.xml .bin"; - -//BSFilePrefix = "R:/code/ryzom/r2_shard/"; -//BSFileSubst = "r2_shard/"; diff --git a/code/ryzom/server/backup_service_interface.cfg b/code/ryzom/server/backup_service_interface.cfg deleted file mode 100644 index 884eede99..000000000 --- a/code/ryzom/server/backup_service_interface.cfg +++ /dev/null @@ -1,5 +0,0 @@ -L3BSPort = "49950"; -BSHost = "localhost:49990"; -UseBS = 1; -// Root directory where data from shards are stored into -SaveShardRoot = "save_shard/"; diff --git a/code/ryzom/server/common.cfg b/code/ryzom/server/common.cfg deleted file mode 100644 index b61aba2c9..000000000 --- a/code/ryzom/server/common.cfg +++ /dev/null @@ -1,99 +0,0 @@ -// ---- config local variables - -// Used by ConfigFile in EGS and WS -ShardId = 302; - -// Used by CVariable in WS -PlayerLimit = 5000; - -// Used to connect to AES (this file) and to set up AES service (admin_executor_service.cfg) -AESPort="46702"; -AESHost="localhost"; - -// ---- service NeL variables (used by ConfigFile class) - -WindowStyle = "WIN"; - -// don't connect to the old NeLNS AES -DontUseAES = 1; - -// Configure module gateway for layer 5 module comm -StartCommands += -{ - // Create a gateway module - "moduleManager.createModule StandardGateway gw", - // add a layer 5 transport - "gw.transportAdd L5Transport l5", - // open the transport - "gw.transportCmd l5(open)", - - /// Create default connection with admin executor service - // Create a gateway module - "moduleManager.createModule StandardGateway gw_aes", - // create the admin executor service module - "moduleManager.createModule AdminExecutorServiceClient aes_client", - "aes_client.plug gw_aes", - - // create a layer 3 client to connect to aes gateway - "gw_aes.transportAdd L3Client aes_l3c", - "gw_aes.transportCmd aes_l3c(connect addr="+AESHost+":"+AESPort+")", -}; - -NSHost = "localhost"; - -// A list of vars to graph for any service -GraphVars += -{ - "ProcessUsedMemory", "60000", // every minute -}; - -IgnoredFiles = { "continent.cfg", "__read_me.txt", "bandit.html", "flora_primr.primitive" }; - -// Set a mainland SessionId. -// Live: Must be 0 for ring shards, non-zero (usually ShardId) for mainland shards -// Dev: Can be non-zero to initially connect a client to a ring shard -NoWSShardId = ShardId; - -// ---- service NeL variables (used by CVariable class) - -// Disable generation / display of nldebug messages -DisableNLDebug = 1; - -// Disable nel net verbose logging -VerboseNETTC = 0; -VerboseLNETL0 = 0; -VerboseLNETL1 = 0; -VerboseLNETL2 = 0; -VerboseLNETL3 = 0; -VerboseLNETL4 = 0; -VerboseLNETL5 = 0; -VerboseLNETL6 = 0; - -// If the update loop is too slow, a thread will produce an assertion. -// By default, the value is set to 10 minutes. -// Set to 0 for no assertion. -UpdateAssertionThreadTimeout = 6000000; - -// how to sleep between 2 network updates -// 0 = pipe -// 1 = usleep -// 2 = nanosleep -// 3 = sched_yield -// 4 = nothing -UseYieldMethod = 0; - -DefaultMaxExpectedBlockSize = 200000000; // 200 M ! -DefaultMaxSentBlockSize = 200000000; // 200 M ! - -// Will SaveFilesDirectory will be converted to a full path? -ConvertSaveFilesDirectoryToFullPath = 0; - -// Where to save specific shard data (ie: player backup), relatively to SaveShardRoot -SaveFilesDirectory = ""; - -// where to save generic shard data (ie: packed_sheet) -WriteFilesDirectory = "data_shard"; - -// ---- service custom variables (used by ConfigFile class) - -// ---- service custom variables (used by CVariable class) diff --git a/code/ryzom/server/dynamic_scenario_service.cfg b/code/ryzom/server/dynamic_scenario_service.cfg deleted file mode 100644 index d264d0f73..000000000 --- a/code/ryzom/server/dynamic_scenario_service.cfg +++ /dev/null @@ -1,320 +0,0 @@ -// Auto generated config file -// Use with commandline: dynamic_scenario_service -C. -L. --nobreak --writepid -AESAliasName= "dss"; - -ASWebPort="46700"; -ASPort="46701"; -AESPort="46702"; -SUPort = 50505; -SUGlobalPort = 50503; -L3BSPort = "49950"; -L3SlaveBSPort = "49951"; -L3MasterLGSPort = 49992; -LGSBSPort = 49994; -L3LGSBSPort = 49995; -SUHost = "localhost"; -MFSHost = "localhost"; -BSHost = "localhost:49990"; -SlaveBSHost = ""; -MasterLGSHost = "localhost"; -SlaveLGSHost = "localhost"; -LGSBSHost = "localhost"; -DBHost = "localhost"; -#define DONT_USE_LGS_SLAVE -// Configure module gateway for layer 5 module comm -StartCommands += -{ -// Create a gateway module -"moduleManager.createModule StandardGateway gw", -// add a layer 5 transport -"gw.transportAdd L5Transport l5", -// open the transport -"gw.transportCmd l5(open)", - -/// Create default connection with admin executor service -// Create a gateway module -"moduleManager.createModule StandardGateway gw_aes", -// create the admin executor service module -"moduleManager.createModule AdminExecutorServiceClient aes_client", -"aes_client.plug gw_aes", - -// create a layer 3 client to connect to aes gateway -"gw_aes.transportAdd L3Client aes_l3c", -"gw_aes.transportCmd aes_l3c(connect addr=localhost:"+AESPort+")", -}; - -/// A list of vars to graph for any service -GraphVars = -{ -"ProcessUsedMemory", "60000", // every minute -}; - - -/* Force default value for PDLib directory (e.g. SaveFilesDirectory...) -* PLEASE NOTICE THAT THIS LINE MUST BE LEFT TO "" -* Only log analyser must have the $shard parameter to find all shards root directory -*/ -PDRootDirectory = ""; - -// Log PD updates to log file (1 enabled, 0 disabled), see PDLogSaveDirectory to choose where to log -PDEnableLog = 1; - -// Log PD StringManager updates to log file (1 enabled, 0 disabled), see PDLogSaveDirectory to choose where to log -PDEnableStringLog = 0; - -// Number of seconds between 2 logs to file -PDLogUpdate = 10; - -// MySGL wrapper strict mode - controls use of asserts if SQL requests fail -MSWStrictMode=0; - -// This is the mapping for logical continent to physical one -ContinentNameTranslator = -{ -"matis_newbie", "matis", -"zorai_newbie", "zorai", -"terre", "terre_oubliee", -"sources", "sources_interdites" -}; - -NegFiltersDebug = { "ZZZZZZZZZZZ" }; -NegFiltersInfo = { "ZZZZZZZZZZZ" }; -NegFiltersWarning = { "ZZZZZZZZZZZ", "Missing log context for log" }; -//NegFiltersDebug = { "NET", "ADMIN", "MIRROR", "NC", "PATH" }; -//NegFiltersInfo = { "NET", "ADMIN", "MIRROR", "NC", "CF", "TimerManagerUpdate" }; -// NegFiltersWarning = { "CT_LRC", "AnimalSpawned" }; - -// Block the system in the tick service that provokes stalls when overloaded -WaitForBSThreshold=0; - -// Only produce log*.log files and not *.log -DontLog=1; - -IgnoredFiles = { "continent.cfg", "__read_me.txt", "bandit.html", "flora_primr.primitive" }; - -// If the update loop is too slow, a thread will produce an assertion. -// By default, the value is set to 10 minutes. -// Set to 0 for no assertion. -UpdateAssertionThreadTimeout = 6000000; - -DefaultMaxExpectedBlockSize = 200000000; // 200 M ! -DefaultMaxSentBlockSize = 200000000; // 200 M ! - -// MS Packet size limit in bytes, PER DATASET (warning: depending on the weights, limits per property may be very small) -MaxOutBandwidth = 100000000; - -// how to sleep between 2 network updates -// 0 = pipe -// 1 = usleep -// 2 = nanosleep -// 3 = sched_yield -// 4 = nothing -UseYieldMethod = 0; - -// The privileges needed to access any ring session -PrivilegeForSessionAccess = ":DEV:SGM:GM:SG:"; - -// The max number of ring points (aka ring access) for each ecosystem -MaxRingPoints = "A1:D7:F7:J8:L6:R13"; - -// Level limit for newb scenarios -FreeTrialSkillLimit=21; - -// Level limit for newb scenarios -DefaultInterShardExchangeLevelCap=0; - -// Configureation for DSS -MaxNpcs = 300; -MaxStaticObjects = 200; - -// the following variable must be defined but should be empty - it's presence is used to change the behaviour -// of the packed sheet reader -GeorgePaths = { "" }; - -// Dissable nel net verbose logging -VerboseNETTC = 0; -VerboseLNETL0 = 0; -VerboseLNETL1 = 0; -VerboseLNETL2 = 0; -VerboseLNETL3 = 0; -VerboseLNETL4 = 0; -VerboseLNETL5 = 0; -VerboseLNETL6 = 0; - -// Dissable ryzom verbose logging -VerboseMIRROR = 0; -VerboseRingRPLog = 0; -VerboseCDBGroup = 0; - -// What to do with characters coming from another mainland shard? -// 0: teleport to the stored session id -// 1: let the character play anyway, but leave the stored session id unchanged -// 2: assign the stored session id with FixedSessionId and let play -AllowCharsFromAllSessions = 0; - -// Use Shard Unifier or not -DontUseSU = 0; - -// the domain's set of useful addresses -LSHost = SUHost; -RSMHost = SUHost; - -// MFS config -WebSrvUsersDirectory = ""; -WebRootDirectory = "/home/nevrax/live/save_shard/www"; -HoFHDTDirectory = "/local/www/hof/hdt"; - -// BS Specifics -------------------------------------------------------------------------- -// BS - set to 1 if a BS is not part of a naming service group (then BS not disclosed -// to other services by the Layer 5, i.e. the services sending requests to BS have -// to know its/their address(es) by another mean) -BSDontUseNS = 1; -// BS - set the host of the naming service where the BS register -BSNSHost = "localhost"; -UseBS = 1; -XMLSave = 0; - -// Where to save specific shard data (ie: player backup), relatively to SaveShardRoot -SaveFilesDirectory = ""; - -// where to save generic shard data (ie: packed_sheet) -WriteFilesDirectory = "r2_shard/data_shard"; - -// Will SaveFilesDirectory will be converted to a full path? -ConvertSaveFilesDirectoryToFullPath = 0; - -// BS - Root directory where data are backuped to -IncrementalBackupDirectory = "../incremental_backup"; - -// IOS - Directory to store ios.string_cache file -StringManagerCacheDirectory = "../data_shard_local"; - -// IOS - Directory to log chat into -LogChatDirectory = "../data_shard_local"; - -// MFS - Directories -WebRootDirectory = "../www"; - -// Root directory where data from shards are stored into -SaveShardRoot = "../save_shard/"; - -// SU Specifics -------------------------------------------------------------------------- -// SU - set to 1 if SU didn't use a naming service -SUDontUseNS = 1; -// SU - host for the NS used by SU -SUNSHost = "localhost"; -// SU - listen address of the SU service (for L5 connections) -SUAddress = SUHost+":"+SUPort; -// SU - nel and ring database names -DBNelName = "nel"; -DBRingName = "ring_open"; -// Nel DB user -DBNelUser = "open"; -// Ring DB user -DBRingUser = "open"; -// SU - password to access to the nel database with DBNelUseruser (default is no password) -DBNelPass = ""; -// SU - password to access to the ring database with DBRingUser (default is no password) -DBRingPass = ""; - -// WS Specifics -------------------------------------------------------------------------- -// WS - use or not the legacy WelcomeService from nel ns (only for backward compatibility during transition to ring) -DontUseLSService = 1; - -// Global config -------------------------------------------------------------------------- -// set to 0 if you want to use the admin system -DontUseAES = 1; - -// Dissable generation / display of nldebug messages -DissableNLDebug = 1; -DisableNLDebug = 1; -ShardId = 201; -BasePort = 51400; -SaveFilesDirectory="open_ring01/"; -NSHost = "localhost"; -// Player limits (AIS, EGS, WS, FS) -NbPlayersLimit = 5000; -NbGuildLimit = 15000; -PlayerLimit = NbPlayersLimit; -ClientLimit = 1000; - -// Set this shard as a ring (1) or mainland (0) shard (main behavior switch) -IsRingShard = 1; - -// Set a mainland SessionId. -// Live: Must be 0 for ring shards, non-zero (usually ShardId) for mainland shards -// Dev: Can be non-zero to initially connect a client to a ring shard -NoWSShardId = ShardId; -FixedSessionId = 0; - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - -// FS Specifics -------------------------------------------------------------------------- -// Client bandwidth ratio, set to 1 for standard operation, more than one allocate more bandwidth -BandwidthRatio = 2; - -// EGS Specifics -------------------------------------------------------------------------- -// Entity Limits (EGS) -NbObjectsLimit = 2000; -NbNpcSpawnedByEGSLimit = 5000; -NbForageSourcesLimit = 10000; -NbToxicCloudsLimit = 5000; - -// AIS Specifics -------------------------------------------------------------------------- -// Entity Limits (AIS) -NbPetLimit = NbPlayersLimit*4; -NbFaunaLimit = 50000; -NbNpcLimit = 50000; -NbFxLimit = 500; - -// This is the list of continent to use with their unique instance number -UsedContinents = -{ -"r2_desert", "10000", -"r2_forest", "10001", -"r2_jungle", "10002", -"r2_lakes", "10003", -"r2_roots", "10004", -}; - -// define the primitives configuration used. -UsedPrimitives = -{ -}; -FSListenHost = "localhost"; -#include "dynamic_scenario_service_default.cfg" -WriteFilesDirectory="../live/service_dynamic_scenario_service/"; -DontLog = 1; -WebSrvHost = "http://localhost:50000/"; -Mainlands = { - "302", "Open", "(Open Developer Community)", "en", -}; -HomeMainlandNames = -{ - "302", "Open", "open", -}; -RRDVarPath = "../rrd_graphs"; -NegFiltersInfo+= {"FESTATS", "FETIME", "FERECV", "FESEND: sent SYNC message to client 1", "EIT: Register EId"}; -NegFiltersWarning+= {"PIPO_SESSION1", "casino_session_matis01", "invalid damage type 10", "_log_Item_Delete", -"_log_Item_Money", "_log_Item_Create", "_log_Item_Move", "botChatMissionAdvance> invalid index 0", -"_MaxRange(0) < _MinRange(1)", "Can't find craft plan sheet 'unknown.unknown'"}; -DontUseAES=1; -RingRPEnabled=0; -DomainName = "ryzom_open"; -EnableStlAllocatorChecker = 0; -// start commands for setting up the exchange level caps of different ryzom shards -StartCommands += { "setShardExchangeLimit 101 250" }; -StartCommands += { "setShardExchangeLimit 102 250" }; -StartCommands += { "setShardExchangeLimit 103 250" }; -StartCommands += { "setShardExchangeLimit 104 0" }; -StartCommands += { "setShardExchangeLimit 105 0" }; -StartCommands += { "displayShardExchangeLimits" }; -StartCommands += { "EnableStlAllocatorChecker 0" }; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; diff --git a/code/ryzom/server/dynamic_scenario_service_default.cfg b/code/ryzom/server/dynamic_scenario_service_default.cfg deleted file mode 100644 index 11eb80ce8..000000000 --- a/code/ryzom/server/dynamic_scenario_service_default.cfg +++ /dev/null @@ -1,9 +0,0 @@ - -DelayBeforeStartAct = 1; -MaxNpcs = 300; -MaxStaticObjects = 200; - -StartCommands += -{ - "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", -}; diff --git a/code/ryzom/server/entities_game_service.cfg b/code/ryzom/server/entities_game_service.cfg deleted file mode 100644 index 4ec5fc63d..000000000 --- a/code/ryzom/server/entities_game_service.cfg +++ /dev/null @@ -1,196 +0,0 @@ -// Use with commandline: entities_game_service -C. -L. --nobreak --writepid - -// ---- config local variables - -#define DONT_USE_LGS_SLAVE - -AESPort="46702"; -SUPort = 50505; -SUGlobalPort = 50503; -L3MasterLGSPort = 41292; -L3SlaveLGSPort = 49993; -SUHost = "localhost"; -MasterLGSHost = "localhost"; -SlaveLGSHost = "localhost"; -// SU - listen address of the SU service (for L5 connections) -SUAddress = SUHost+":"+SUPort; - -#include "entities_game_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "egs"; - -StartCommands += { -"moduleManager.createModule AnimSessionManager asm", -"asm.plug gw", -}; - -// start commands for setting up the exchange level caps of different ryzom shards -StartCommands += { "setShardExchangeLimit 302 250" }; - -StartCommands += { "displayShardExchangeLimits" }; -StartCommands += { "EnableStlAllocatorChecker 0" }; - -GraphVars += { "CharacterLoadPerTick", "60000" }; -GraphVars += { "CharacterSavePerTick", "60000" }; -GraphVars += { "TickSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; -GraphVars += { "MirrorCallbackCount", "60000" }; -GraphVars += { "MirrorCallbackTime", "60000" }; - -NSHost = "localhost"; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; -PathsNoRecurse= {"."}; - - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -WebSrvHost = "http://localhost:55555/"; - -NbPlayersLimit = PlayerLimit; -NbGuildLimit = 15000; - -// Entity Limits (EGS) -NbObjectsLimit = 2000; -NbNpcSpawnedByEGSLimit = 5000; -NbForageSourcesLimit = 10000; -NbToxicCloudsLimit = 5000; - -#include "used_continents.cfg" - -// define the primitives configuration used. -UsedPrimitives = -{ - "newbieland_all", -}; - -// the following variable must be defined but should be empty - it's presence is used to change the behaviour -// of the packed sheet reader -GeorgePaths = { "" }; - -HomeMainlandNames = -{ -"302", "Open", "open", -}; - -/* -UsedContinents += -{ -"bagne", "0", -"fyros", "1", -"fyros_island", "2", -"fyros_newbie", "3", -"indoors", "4", // NB : this is for uninstanciated indoors building. -"matis", "5", -"matis_newbie", "7", -"matis_island", "8", -"nexus", "9", -"route_gouffre","10", -"sources", "11", -"terre", "12", -// "testroom", "13", -"tryker", "14", -"tryker_island","15", -"tryker_newbie","16", -"zorai", "17", -"zorai_island", "18", -"zorai_newbie", "19", -"newbieland", "20", -"kitiniere", "21", -}; - -// define the primitives configuration used. -UsedPrimitives = -{ -"newbieland_all", -"matis_newbie_all", -"matis_all", -"matis_island_all", -"zorai_newbie_all", -"zorai_all", -"zorai_island_all", -"fyros_newbie_all", -"fyros_all", -"fyros_island_all", -"tryker_newbie_all", -"tryker_all", -"tryker_island_all", -"terre_all", -"sources_all", -"route_gouffre_all", -"nexus_all", -"bagne_all", -"kitiniere_all", -}; -*/ - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - - // ---- service custom variables (used by CVariable class) - -RingRPEnabled=0; -RingRPXPRequiredPerAction=700; -RingRPXPRequiredPerTimeSlice=700; - -MaxXPGainPerPlayer = 30.0; -DeathXPFactor = 0.1; - -MFSHost = "localhost"; - -// Use Shard Unifier or not -DontUseSU = 0; - -// Set this shard as a ring (1) or mainland (0) shard (main behavior switch) -IsRingShard = 0; - -// Set a mainland SessionId. -// Live: Must be 0 for ring shards, non-zero (usually ShardId) for mainland shards -// Dev: Can be non-zero to initially connect a client to a ring shard -FixedSessionId = ShardId; - -// Level limit for newb scenarios -FreeTrialSkillLimit=21; - -// Level limit for newb scenarios -DefaultInterShardExchangeLevelCap=0; - -// Disable ryzom verbose logging -VerboseMIRROR = 0; -VerboseRingRPLog = 0; -VerboseCDBGroup = 0; - -// What to do with characters coming from another mainland shard? -// 0: teleport to the stored session id -// 1: let the character play anyway, but leave the stored session id unchanged -// 2: assign the stored session id with FixedSessionId and let play -AllowCharsFromAllSessions = 0; - -/* Force default value for PDLib directory (e.g. SaveFilesDirectory...) - * PLEASE NOTICE THAT THIS LINE MUST BE LEFT TO "" - * Only log analyser must have the $shard parameter to find all shards root directory - */ -PDRootDirectory = ""; - -// Log PD updates to log file (1 enabled, 0 disabled), see PDLogSaveDirectory to choose where to log -PDEnableLog = 1; - -// Log PD StringManager updates to log file (1 enabled, 0 disabled), see PDLogSaveDirectory to choose where to log -PDEnableStringLog = 0; - -// Number of seconds between 2 logs to file -PDLogUpdate = 10; - -#include "backup_service_interface.cfg" - -XMLSave = 0; diff --git a/code/ryzom/server/entities_game_service_default.cfg b/code/ryzom/server/entities_game_service_default.cfg deleted file mode 100644 index 52d2f52bc..000000000 --- a/code/ryzom/server/entities_game_service_default.cfg +++ /dev/null @@ -1,1718 +0,0 @@ -#include "common.cfg" - -StartCommands += -{ - // L5 connect to the shard unifier - "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", - - // Create a gateway for global interconnection - // modules from different shard are visible to each other if they connect to - // this gateway. SU Local module have no interest to be plugged here. - "moduleManager.createModule StandardGateway glob_gw", - // add a layer 3 server transport - "glob_gw.transportAdd L3Client l3c", - // open the transport - "glob_gw.transportCmd l3c(connect addr="+SUHost+":"+SUGlobalPort+")", - - - // Create a gateway for logger service connection - "moduleManager.createModule StandardGateway lgs_gw", - - // add a layer 3 server transport for master logger service - "lgs_gw.transportAdd L3Client masterL3c", - // open the transport - "lgs_gw.transportCmd masterL3c(connect addr="+MasterLGSHost+":"+L3MasterLGSPort+")", -}; - -#ifndef DONT_USE_LGS_SLAVE - -StartCommands += -{ - // add a layer 3 server transport for slave logger service - "lgs_gw.transportAdd L3Client slaveL3c", - // open the transport - "lgs_gw.transportCmd slaveL3c(connect addr="+SlaveLGSHost+":"+L3SlaveLGSPort+")", -}; - -#endif - -StartCommands += -{ - // Create a shard unifier client module - "moduleManager.createModule ShardUnifierClient suc", - // Create a client commands forwader module - "moduleManager.createModule ClientCommandForwader ccf", - - // Create a characer control module - "moduleManager.createModule CharacterControl cc", - - // Create a guild unifier module - "moduleManager.createModule GuildUnifier gu", - - //Create a shard unifier name mapper - "moduleManager.createModule CharNameMapperClient cnmc", - - // Create the logger service client module - "moduleManager.createModule LoggerServiceClient lsc", - - "suc.plug gw", - "ccf.plug gw", - "cc.plug gw", - "gu.plug glob_gw", - "cnmc.plug gw", - "lsc.plug lgs_gw", -}; - -/// A list of vars to graph for EGS -GraphVars += -{ - "TotalNbItemForSale", "60000", // every minutes - "NbPlayers", "60000", // every minutes -}; - -//min fraction of the total damage done on a creature that a group/player must do to be attributed a kill -KillAttribMinFactor = 1.0; - -//max bulk the player can transport * 1000 (*1000 to avoid float operations) -MaxPlayerBulk = 100000; - -//max weight in grammes a player can have on him if his strength is 0 -BaseMaxCarriedWeight = 100000; - -// base bulk of player room -BasePlayerRoomBulk = 1000000; - -// if true, every player that was saved with an invalid position will be corrected the next time he logs in. -CorrectInvalidPlayerPositions = 1; - -// Create Character Start skills value -//CreateCharacterStartSkillsValue = "SCMM1BS:220:SMLOEFA:235:SFM1BMM:215:SKILL_POINTS:200:MONEY:1000"; -//CreateCharacterStartSkillsValue = "SM:20:SMA:50:SMAP:51:SMAE:51:SMT:50:SMTC:51:SMTM:51:SMTO:51:SKILL_POINTS:2550:MONEY:50000"; - - -// Enable caching of ligo primitive in binary files -CachePrims = 1; -// Log to see which primitives where loaded from cache -CachePrimsLog = 0; - -//************************************************************************************************************* -// variable for stop area effect of a gameplay system -//************************************************************************************************************* -FightAreaEffectOn = 1; -MagicAreaEffectOn = 1; -HarvestAreaEffectOn = 1; - -//************************************************************************************************************* -// save period time (ticks). -//************************************************************************************************************* -GuildSavePeriod = 100; -GuildChargeSavePeriod = 99; -GuildMaxMemberCount = 255; - -TickFrequencyPCSave = 4800; -// minimum period between 2 consecutive saves of the same character -MinPlayerSavePeriod = 600; - -StoreSavePeriod = 10; - -//************************************************************************************************************* -// Max duration of death panalty (when you death several times and only style one point in your characteristics due to death penalty -//************************************************************************************************************* -DeathPenaltyMaxDuration = 1000; // 10 ticks per second * 60 for minutes * 30 for 30 minutes // No more used. -DeathXPFactor = 1; -DeathXPResorptionTime = 60; - -//************************************************************************************************************* -// Duration of comma -//************************************************************************************************************* -CommaDelayBeforeDeath = 100; // 10 ticks per second * 60 for minutes * 5 for 5 minutes - -//************************************************************************************************************* -// Duration of dead mektoub stay spawned -//************************************************************************************************************* -SpawnedDeadMektoubDelay = 1000; // 10 ticks per second * 60 for minutes * 60 for hours * 24 for days - -//************************************************************************************************************* -// Progression -//************************************************************************************************************* -SkillProgressionFactor = 1.0; - -SkillFightValueLimiter = 250; //skill value temporary limited for beta -SkillMagicValueLimiter = 250; //skill value temporary limited for beta -SkillCraftValueLimiter = 250; //skill value temporary limited for beta -SkillHarvestValueLimiter = 250; //skill value temporary limited for beta - -NBMeanCraftRawMaterials = 1; //Mean of raw material used for craft an item, it's used for scale xp win when crafting an item with effective raw material used - -// when in a team value of each member above one for XP division among team members -XPTeamMemberDivisorValue = 0.5; -// distance max for an action to be taken into account when in a team -MaxDistanceForXpGain = 10; -// Max XP gain by any one player on any creature (each team member can gain up to this value) -MaxXPGainPerPlayer = 10.0; - - -//************************************************************************************************************* -// Characteristics parameters -//************************************************************************************************************* -//characteristic brick progression step -CharacteristicBrickStep = 1; -// Maximum value for characteristics (260 because characters begin with 10) -MaxCharacteristicValue = 250; - - -//************************************************************************************************************* -// Magic parameters -//************************************************************************************************************* -DefaultCastingTime = 1.0; -RechargeMoneyFactor = 1.0; -CristalMoneyFactor = 1.0; - -// int in ticks for following values -NoLinkSurvivalAddTime = 100; -NoLinkTimeFear = 100; -NoLinkTimeSleep = 100; -NoLinkTimeStun = 100; -NoLinkTimeRoot = 100; -NoLinkTimeSnare = 100; -NoLinkTimeSlow = 100; -NoLinkTimeBlind = 100; -NoLinkTimeMadness = 100; -NoLinkTimeDot = 100; -PostCastLatency = 100; // in ticks - -TickFrequencyCompassUpdate = 32; - -// update period of link spell in ticks -UpdatePeriodFear = 40; -UpdatePeriodSleep = 40; -UpdatePeriodStun = 40; -UpdatePeriodRoot = 40; -UpdatePeriodSnare = 40; -UpdatePeriodSlow = 40; -UpdatePeriodBlind = 40; -UpdatePeriodMadness = 40; -UpdatePeriodDot = 40; -DefaultUpdatePeriod = 40; - -// bonus on resist for each received spell -ResistIncreaseFear = 10; -ResistIncreaseSleep = 10; -ResistIncreaseStun = 10; -ResistIncreaseRoot = 10; -ResistIncreaseSnare = 10; -ResistIncreaseSlow = 10; -ResistIncreaseBlind = 10; -ResistIncreaseMadness = 10; - -ResistIncreaseAcid = 0; -ResistIncreaseCold = 0; -ResistIncreaseElectricity= 0; -ResistIncreaseFire = 0; -ResistIncreasePoison = 0; -ResistIncreaseRot = 0; -ResistIncreaseShockwave = 0; - -//************************************************************************************************************* -// Craft parameters -//************************************************************************************************************* -//////////////// -// DURABILITY // some kind of HP -// melee weapons -DaggerDurability = 100.0; -SwordDurability = 100.0; -MaceDurability = 100.0; -AxeDurability = 100.0; -SpearDurability = 100.0; -StaffDurability = 100.0; -MagicianStaffDurability = 100.0; -TwoHandSwordDurability = 100.0; -TwoHandAxeDurability = 100.0; -PikeDurability = 100.0; -TwoHandMaceDurability = 100.0; -// range weapon -AutolauchDurability = 100.0; -BowrifleDurability = 100.0; -LauncherDurability = 100.0; -PistolDurability = 100.0; -BowpistolDurability = 100.0; -RifleDurability = 100.0; -HarpoonDurability = 100.0; -// ammo -AutolaunchAmmoDurability = 100.0; -BowrifleAmmoDurability = 100.0; -GrenadeAmmoDurability = 100.0; -LauncherAmmoDurability = 100.0; -PistolAmmoDurability = 100.0; -BowpistolAmmoDurability = 100.0; -RifleAmmoDurability = 100.0; -HarpoonAmmoDurability = 100.0; -// armor and shield -ShieldDurability = 100.0; -BucklerDurability = 100.0; -LightBootsDurability = 100.0; -LightGlovesDurability = 100.0; -LightPantsDurability = 100.0; -LightSleevesDurability = 100.0; -LightVestDurability = 100.0; -MediumBootsDurability = 100.0; -MediumGlovesDurability = 100.0; -MediumPantsDurability = 100.0; -MediumSleevesDurability = 100.0; -MediumVestDurability = 100.0; -HeavyBootsDurability = 100.0; -HeavyGlovesDurability = 100.0; -HeavyPantsDurability = 100.0; -HeavySleevesDurability = 100.0; -HeavyVestDurability = 100.0; -HeavyHelmetDurability = 100.0; -// jewel -AnkletDurability = 100.0; -BraceletDurability = 100.0; -DiademDurability = 100.0; -EaringDurability = 100.0; -PendantDurability = 100.0; -RingDurability = 100.0; -// tool -ForageToolDurability = 100.0; -AmmoCraftingToolDurability = 100.0; -ArmorCraftingToolDurability = 100.0; -JewelryCraftingToolDurability = 100.0; -RangeWeaponCraftingToolDurability = 100.0; -MeleeWeaponCraftingToolDurability = 100.0; -ToolCraftingToolDurability = 100.0; - -//////////// -// WEIGHT // (Max is *2) -// melee weapons -DaggerWeight = 1.0; // Dg Type (Pierce) -SwordWeight = 1.0; // 1H Type -MaceWeight = 1.0; // 1H Type -AxeWeight = 1.0; // 1H Type -SpearWeight = 1.0; // 1H Type (pierce) -StaffWeight = 1.0; // 1H Type -MagicianStaffWeight = 1.0; // 2H type -TwoHandSwordWeight = 1.0; // 2H Type -TwoHandAxeWeight = 1.0; // 2H Type -PikeWeight = 1.0; // 2H Type (pierce) -TwoHandMaceWeight = 1.0; // 2H Type -// range weapon -PistolWeight = 1.0; -BowpistolWeight = 1.0; -RifleWeight = 1.0; -BowrifleWeight = 1.0; -AutolauchWeight = 1.0; -LauncherWeight = 1.0; -HarpoonWeight = 1.0; -// ammo -PistolAmmoWeight = 1.0; -BowpistolAmmoWeight = 1.0; -RifleAmmoWeight = 1.0; -BowrifleAmmoWeight = 1.0; -AutolaunchAmmoWeight = 1.0; -LauncherAmmoWeight = 1.0; -HarpoonAmmoWeight = 1.0; -GrenadeAmmoWeight = 1.0; -// armor and shield -ShieldWeight = 1.0; -BucklerWeight = 1.0; -// Light -LightBootsWeight = 1.0; -LightGlovesWeight = 1.0; -LightPantsWeight = 1.0; -LightSleevesWeight = 1.0; -LightVestWeight = 1.0; -// Medium -MediumBootsWeight = 1.0; -MediumGlovesWeight = 1.0; -MediumPantsWeight = 1.0; -MediumSleevesWeight = 1.0; -MediumVestWeight = 1.0; -// Heavy -HeavyBootsWeight = 1.0; -HeavyGlovesWeight = 1.0; -HeavyPantsWeight = 1.0; -HeavySleevesWeight = 1.0; -HeavyVestWeight = 1.0; -HeavyHelmetWeight = 1.0; -// jewel -AnkletWeight = 1.0; -BraceletWeight = 1.0; -DiademWeight = 1.0; -EaringWeight = 1.0; -PendantWeight = 1.0; -RingWeight = 1.0; -////////////// -// SAP LOAD // -// MIN -// melee weapons -DaggerSapLoad = 0.0; -SwordSapLoad = 0.0; -MaceSapLoad = 0.0; -AxeSapLoad = 0.0; -SpearSapLoad = 0.0; -StaffSapLoad = 0.0; -MagicianStaffSapLoad = 0.0; -TwoHandSwordSapLoad = 0.0; -TwoHandAxeSapLoad = 0.0; -PikeSapLoad = 0.0; -TwoHandMaceSapLoad = 0.0; -// range weapon -AutolauchSapLoad = 0.0; -BowrifleSapLoad = 0.0; -LauncherSapLoad = 0.0; -PistolSapLoad = 0.0; -BowpistolSapLoad = 0.0; -RifleSapLoad = 0.0; -HarpoonSapLoad = 0.0; -// ammo -AutolaunchAmmoSapLoad = 0.0; -BowrifleAmmoSapLoad = 0.0; -GrenadeAmmoSapLoad = 0.0; -LauncherAmmoSapLoad = 0.0; -PistolAmmoSapLoad = 0.0; -BowpistolAmmoSapLoad = 0.0; -RifleAmmoSapLoad = 0.0; -HarpoonAmmoSapLoad = 0.0; -// armor and shield -ShieldSapLoad = 0.0; -BucklerSapLoad = 0.0; -LightBootsSapLoad = 0.0; -LightGlovesSapLoad = 0.0; -LightPantsSapLoad = 0.0; -LightSleevesSapLoad = 0.0; -LightVestSapLoad = 0.0; -MediumBootsSapLoad = 0.0; -MediumGlovesSapLoad = 0.0; -MediumPantsSapLoad = 0.0; -MediumSleevesSapLoad = 0.0; -MediumVestSapLoad = 0.0; -HeavyBootsSapLoad = 0.0; -HeavyGlovesSapLoad = 0.0; -HeavyPantsSapLoad = 0.0; -HeavySleevesSapLoad = 0.0; -HeavyVestSapLoad = 0.0; -HeavyHelmetSapLoad = 0.0; -// jewel -AnkletSapLoad = 0.0; -BraceletSapLoad = 0.0; -DiademSapLoad = 0.0; -EaringSapLoad = 0.0; -PendantSapLoad = 0.0; -RingSapLoad = 0.0; -// MAX -// melee weapons -DaggerSapLoadMax = 1000.0; -SwordSapLoadMax = 1000.0; -MaceSapLoadMax = 1000.0; -AxeSapLoadMax = 1000.0; -SpearSapLoadMax = 1000.0; -StaffSapLoadMax = 1000.0; -MagicianStaffSapLoadMax = 1000.0; -TwoHandSwordSapLoadMax = 1000.0; -TwoHandAxeSapLoadMax = 1000.0; -PikeSapLoadMax = 1000.0; -TwoHandMaceSapLoadMax = 1000.0; -// range weapon -AutolauchSapLoadMax = 1000.0; -BowrifleSapLoadMax = 1000.0; -LauncherSapLoadMax = 1000.0; -PistolSapLoadMax = 1000.0; -BowpistolSapLoadMax = 1000.0; -RifleSapLoadMax = 1000.0; -HarpoonSapLoadMax = 1000.0; -// ammo -AutolaunchAmmoSapLoadMax = 1000.0; -BowrifleAmmoSapLoadMax = 1000.0; -GrenadeAmmoSapLoadMax = 1000.0; -LauncherAmmoSapLoadMax = 1000.0; -PistolAmmoSapLoadMax = 1000.0; -BowpistolAmmoSapLoadMax = 1000.0; -RifleAmmoSapLoadMax = 1000.0; -HarpoonAmmoSapLoadMax = 1000.0; -// armor and shield -ShieldSapLoadMax = 1000.0; -BucklerSapLoadMax = 1000.0; -LightBootsSapLoadMax = 1000.0; -LightGlovesSapLoadMax = 1000.0; -LightPantsSapLoadMax = 1000.0; -LightSleevesSapLoadMax = 1000.0; -LightVestSapLoadMax = 1000.0; -MediumBootsSapLoadMax = 1000.0; -MediumGlovesSapLoadMax = 1000.0; -MediumPantsSapLoadMax = 1000.0; -MediumSleevesSapLoadMax = 1000.0; -MediumVestSapLoadMax = 1000.0; -HeavyBootsSapLoadMax = 1000.0; -HeavyGlovesSapLoadMax = 1000.0; -HeavyPantsSapLoadMax = 1000.0; -HeavySleevesSapLoadMax = 1000.0; -HeavyVestSapLoadMax = 1000.0; -HeavyHelmetSapLoadMax = 1000.0; -// jewel -AnkletSapLoadMax = 1000.0; -BraceletSapLoadMax = 1000.0; -DiademSapLoadMax = 1000.0; -EaringSapLoadMax = 1000.0; -PendantSapLoadMax = 1000.0; -RingSapLoadMax = 1000.0; -//////////// -// DAMAGE Min -// melee weapons -DaggerDmg = 1.0; // Dg Type (Pierce) -StaffDmg = 1.0; // 1H Type -SwordDmg = 1.0; // 1H Type -MaceDmg = 1.0; // 1H Type -AxeDmg = 1.0; // 1H Type -SpearDmg = 1.0; // 1H Type (pierce) -TwoHandSwordDmg = 1.0; // 2H Type -TwoHandAxeDmg = 1.0; // 2H Type -PikeDmg = 1.0; // 2H Type (pierce) -TwoHandMaceDmg = 1.0; // 2H Type -MagicianStaffDmg = 1.0; // 2H Type -// range weapon (modifier) -PistolDmg = 0.0; -BowpistolDmg = 0.0; -RifleDmg = 0.0; -BowrifleDmg = 0.0; -AutolauchDmg = 0.0; -LauncherDmg = 0.0; -HarpoonDmg = 0.0; -// ammo -PistolAmmoDmg = 1.0; -BowpistolAmmoDmg = 1.0; -RifleAmmoDmg = 1.0; -BowrifleAmmoDmg = 1.0; -AutolaunchAmmoDmg = 1.0; -LauncherAmmoDmg = 1.0; -HarpoonAmmoDmg = 1.0; -GrenadeAmmoDmg = 1.0; -// DAMAGE Max -// melee weapons -DaggerDmgMax = 1.0; // Dg Type (Pierce) -StaffDmgMax = 1.0; // 1H Type -SwordDmgMax = 1.0; // 1H Type -MaceDmgMax = 1.0; // 1H Type -AxeDmgMax = 1.0; // 1H Type -SpearDmgMax = 1.0; // 1H Type (pierce) -TwoHandSwordDmgMax = 1.0; // 2H Type -TwoHandAxeDmgMax = 1.0; // 2H Type -PikeDmgMax = 1.0; // 2H Type (pierce) -TwoHandMaceDmgMax = 1.0; // 2H Type -MagicianStaffDmgMax = 1.0; -// range weapon (modifier) -AutolauchDmgMax = 0.0; -BowrifleDmgMax = 0.0; -LauncherDmgMax = 0.0; -PistolDmgMax = 0.0; -BowpistolDmgMax = 0.0; -RifleDmgMax = 0.0; -HarpoonDmgMax = 0.0; -// ammo -PistolAmmoDmgMax = 1.0; -BowpistolAmmoDmgMax = 1.0; -RifleAmmoDmgMax = 1.0; -BowrifleAmmoDmgMax = 1.0; -AutolaunchAmmoDmgMax = 1.0; -LauncherAmmoDmgMax = 1.0; -HarpoonAmmoDmgMax = 1.0; -GrenadeAmmoDmgMax = 1.0; - -////////////// -// HIT RATE // Hits for 10 sec -// melee weapons -DaggerHitRate = 1.0; // Dg Type (Pierce) -StaffHitRate = 1.0; // 1H Type (blunt) -SwordHitRate = 1.0; // 1H Type -MaceHitRate = 1.0; // 1H Type -AxeHitRate = 1.0; // 1H Type -SpearHitRate = 1.0; // 1H Type (pierce) -TwoHandSwordHitRate = 1.0; // 2H Type -TwoHandAxeHitRate = 1.0; // 2H Type -PikeHitRate = 1.0; // 2H Type (pierce) -TwoHandMaceHitRate = 1.0; // 2H Type -MagicianStaffHitRate = 1.0; // -// range weapon -PistolHitRate = 1.0; -BowpistolHitRate = 1.0; -RifleHitRate = 1.0; -BowrifleHitRate = 1.0; -AutolauchHitRate = 1.0; -LauncherHitRate = 1.0; -HarpoonHitRate = 1.0; -// ammo (modifier) -AutolaunchAmmoHitRate = 0.0; -BowrifleAmmoHitRate = 0.0; -GrenadeAmmoHitRate = 0.0; -LauncherAmmoHitRate = 0.0; -PistolAmmoHitRate = 0.0; -BowpistolAmmoHitRate = 0.0; -RifleAmmoHitRate = 0.0; -HarpoonAmmoHitRate = 0.0; - -////////////// -// Maximum hit rate ( after crafted item parameters applications ) -// melee weapons -DaggerHitRateMax = 10.0; -StaffHitRateMax = 10.0; // 1H Type (blunt) -SwordHitRateMax = 10.0; -MaceHitRateMax = 10.0; -AxeHitRateMax = 10.0; -SpearHitRateMax = 10.0; -TwoHandSwordHitRateMax = 10.0; -TwoHandAxeHitRateMax = 10.0; -PikeHitRateMax = 10.0; -TwoHandMaceHitRateMax = 10.0; -MagicianStaffHitRateMax = 10.0; -// range weapon -PistolHitRateMax = 1.0; -BowpistolHitRateMax = 1.0; -RifleHitRateMax = 1.0; -BowrifleHitRateMax = 1.0; -AutolauchHitRateMax = 1.0; -LauncherHitRateMax = 1.0; -HarpoonHitRateMax = 1.0; -// ammo -AutolaunchAmmoHitRateMax = 0.0; -BowrifleAmmoHitRateMax = 0.0; -GrenadeAmmoHitRateMax = 0.0; -LauncherAmmoHitRateMax = 0.0; -PistolAmmoHitRateMax = 0.0; -BowpistolAmmoHitRateMax = 0.0; -RifleAmmoHitRateMax = 0.0; -HarpoonAmmoHitRateMax = 0.0; - - -/////////// -// Range // for ammo, range weapon (modifier) (max = *2) -// range weapon -AutolauchRange = 10000.0; // Gat -BowrifleRange = 10000.0; -LauncherRange = 10000.0; // Rocket Launcher -PistolRange = 10000.0; -BowpistolRange = 10000.0; -RifleRange = 10000.0; -HarpoonRange = 10000.0; -// ammo -AutolaunchAmmoRange = 0.0; -BowrifleAmmoRange = 0.0; -GrenadeAmmoRange = 0.0; -LauncherAmmoRange = 0.0; -PistolAmmoRange = 0.0; -BowpistolAmmoRange = 0.0; -RifleAmmoRange = 0.0; -HarpoonAmmoRange = 0.0; -//////////////////// -// DODGE MODIFIER // not for ammo and jewel, but for armor too -// melee weapons & armor -DaggerDodgeMinModifier = 0.0; -DaggerDodgeMaxModifier = 0.0; -SwordDodgeMinModifier = 0.0; -SwordDodgeMaxModifier = 0.0; -MaceDodgeMinModifier = 0.0; -MaceDodgeMaxModifier = 0.0; -AxeDodgeMinModifier = 0.0; -AxeDodgeMaxModifier = 0.0; -SpearDodgeMinModifier = 0.0; -SpearDodgeMaxModifier = 0.0; -StaffDodgeMinModifier = 0.0; -StaffDodgeMaxModifier = 0.0; -TwoHandSwordDodgeMinModifier = 0.0; -TwoHandSwordDodgeMaxModifier = 0.0; -TwoHandAxeDodgeMinModifier = 0.0; -TwoHandAxeDodgeMaxModifier = 0.0; -PikeDodgeMinModifier = 0.0; -PikeDodgeMaxModifier = 0.0; -TwoHandMaceDodgeMinModifier = 0.0; -TwoHandMaceDodgeMaxModifier = 0.0; -MagicianStaffDodgeMinModifier = 0.0; -MagicianStaffDodgeMaxModifier = 0.0; -// range weapon -AutolauchDodgeMinModifier = 0.0; -AutolauchDodgeMaxModifier = 0.0; -BowrifleDodgeMinModifier = 0.0; -BowrifleDodgeMaxModifier = 0.0; -LauncherDodgeMinModifier = 0.0; -LauncherDodgeMaxModifier = 0.0; -PistolDodgeMinModifier = 0.0; -PistolDodgeMaxModifier = 0.0; -BowpistolDodgeMinModifier = 0.0; -BowpistolDodgeMaxModifier = 0.0; -RifleDodgeMinModifier = 0.0; -RifleDodgeMaxModifier = 0.0; -HarpoonDodgeMinModifier = 0.0; -HarpoonDodgeMaxModifier = 0.0; -// armor and shield -ShieldDodgeMinModifier = 0.0; -ShieldDodgeMaxModifier = 0.0; -BucklerDodgeMinModifier = 0.0; -BucklerDodgeMaxModifier = 0.0; -LightBootsDodgeMinModifier = 0.0; -LightBootsDodgeMaxModifier = 0.0; -LightGlovesDodgeMinModifier = 0.0; -LightGlovesDodgeMaxModifier = 0.0; -LightPantsDodgeMinModifier = 0.0; -LightPantsDodgeMaxModifier = 0.0; -LightSleevesDodgeMinModifier = 0.0; -LightSleevesDodgeMaxModifier = 0.0; -LightVestDodgeMinModifier = 0.0; -LightVestDodgeMaxModifier = 0.0; -MediumBootsDodgeMinModifier = 0.0; -MediumBootsDodgeMaxModifier = 0.0; -MediumGlovesDodgeMinModifier = 0.0; -MediumGlovesDodgeMaxModifier = 0.0; -MediumPantsDodgeMinModifier = 0.0; -MediumPantsDodgeMaxModifier = 0.0; -MediumSleevesDodgeMinModifier = 0.0; -MediumSleevesDodgeMaxModifier = 0.0; -MediumVestDodgeMinModifier = 0.0; -MediumVestDodgeMaxModifier = 0.0; -HeavyBootsDodgeMinModifier = 0.0; -HeavyBootsDodgeMaxModifier = 0.0; -HeavyGlovesDodgeMinModifier = 0.0; -HeavyGlovesDodgeMaxModifier = 0.0; -HeavyPantsDodgeMinModifier = 0.0; -HeavyPantsDodgeMaxModifier = 0.0; -HeavySleevesDodgeMinModifier = 0.0; -HeavySleevesDodgeMaxModifier = 0.0; -HeavyVestDodgeMinModifier = 0.0; -HeavyVestDodgeMaxModifier = 0.0; -HeavyHelmetDodgeMinModifier = 0.0; -HeavyHelmetDodgeMaxModifier = 0.0; -//////////////////// -// PARRY MODIFIER // not for ammo and jewel, but for armor too -// melee weapons -DaggerParryMinModifier = 0.0; -DaggerParryMaxModifier = 0.0; -SwordParryMinModifier = 0.0; -SwordParryMaxModifier = 0.0; -MaceParryMinModifier = 0.0; -MaceParryMaxModifier = 0.0; -AxeParryMinModifier = 0.0; -AxeParryMaxModifier = 0.0; -SpearParryMinModifier = 0.0; -SpearParryMaxModifier = 0.0; -StaffParryMinModifier = 0.0; -StaffParryMaxModifier = 0.0; -TwoHandSwordParryMinModifier = 0.0; -TwoHandSwordParryMaxModifier = 0.0; -TwoHandAxeParryMinModifier = 0.0; -TwoHandAxeParryMaxModifier = 0.0; -PikeParryMinModifier = 0.0; -PikeParryMaxModifier = 0.0; -TwoHandMaceParryMinModifier = 0.0; -TwoHandMaceParryMaxModifier = 0.0; -MagicianStaffParryMinModifier = 0.0; -MagicianStaffParryMaxModifier = 0.0; -// range weapon -AutolauchParryMinModifier = 0.0; -AutolauchParryMaxModifier = 0.0; -BowrifleParryMinModifier = 0.0; -BowrifleParryMaxModifier = 0.0; -LauncherParryMinModifier = 0.0; -LauncherParryMaxModifier = 0.0; -PistolParryMinModifier = 0.0; -PistolParryMaxModifier = 0.0; -BowpistolParryMinModifier = 0.0; -BowpistolParryMaxModifier = 0.0; -RifleParryMinModifier = 0.0; -RifleParryMaxModifier = 0.0; -HarpoonParryMinModifier = 0.0; -HarpoonParryMaxModifier = 0.0; -// armor and shield -ShieldParryMinModifier = 0.0; -ShieldParryMaxModifier = 0.0; -BucklerParryMinModifier = 0.0; -BucklerParryMaxModifier = 0.0; -LightBootsParryMinModifier = 0.0; -LightBootsParryMaxModifier = 0.0; -LightGlovesParryMinModifier = 0.0; -LightGlovesParryMaxModifier = 0.0; -LightPantsParryMinModifier = 0.0; -LightPantsParryMaxModifier = 0.0; -LightSleevesParryMinModifier = 0.0; -LightSleevesParryMaxModifier = 0.0; -LightVestParryMinModifier = 0.0; -LightVestParryMaxModifier = 0.0; -MediumBootsParryMinModifier = 0.0; -MediumBootsParryMaxModifier = 0.0; -MediumGlovesParryMinModifier = 0.0; -MediumGlovesParryMaxModifier = 0.0; -MediumPantsParryMinModifier = 0.0; -MediumPantsParryMaxModifier = 0.0; -MediumSleevesParryMinModifier = 0.0; -MediumSleevesParryMaxModifier = 0.0; -MediumVestParryMinModifier = 0.0; -MediumVestParryMaxModifier = 0.0; -HeavyBootsParryMinModifier = 0.0; -HeavyBootsParryMaxModifier = 0.0; -HeavyGlovesParryMinModifier = 0.0; -HeavyGlovesParryMaxModifier = 0.0; -HeavyPantsParryMinModifier = 0.0; -HeavyPantsParryMaxModifier = 0.0; -HeavySleevesParryMinModifier = 0.0; -HeavySleevesParryMaxModifier = 0.0; -HeavyVestParryMinModifier = 0.0; -HeavyVestParryMaxModifier = 0.0; -HeavyHelmetParryMinModifier = 0.0; -HeavyHelmetParryMaxModifier = 0.0; -////////////////////////////// -// ADVERSARY DODGE MODIFIER // not for ammo, jewel and armor -// melee weapons -DaggerAdversaryDodgeMinModifier = 0.0; -DaggerAdversaryDodgeMaxModifier = 0.0; -SwordAdversaryDodgeMinModifier = 0.0; -SwordAdversaryDodgeMaxModifier = 0.0; -MaceAdversaryDodgeMinModifier = 0.0; -MaceAdversaryDodgeMaxModifier = 0.0; -AxeAdversaryDodgeMinModifier = 0.0; -AxeAdversaryDodgeMaxModifier = 0.0; -SpearAdversaryDodgeMinModifier = 0.0; -SpearAdversaryDodgeMaxModifier = 0.0; -StaffAdversaryDodgeMinModifier = 0.0; -StaffAdversaryDodgeMaxModifier = 0.0; -TwoHandSwordAdversaryDodgeMinModifier = 0.0; -TwoHandSwordAdversaryDodgeMaxModifier = 0.0; -TwoHandAxeAdversaryDodgeMinModifier = 0.0; -TwoHandAxeAdversaryDodgeMaxModifier = 0.0; -PikeAdversaryDodgeMinModifier = 0.0; -PikeAdversaryDodgeMaxModifier = 0.0; -TwoHandMaceAdversaryDodgeMinModifier = 0.0; -TwoHandMaceAdversaryDodgeMaxModifier = 0.0; -MagicianStaffAdversaryDodgeMinModifier = 0.0; -MagicianStaffAdversaryDodgeMaxModifier = 0.0; -// range weapon -AutolauchAdversaryDodgeMinModifier = 0.0; -AutolauchAdversaryDodgeMaxModifier = 0.0; -BowrifleAdversaryDodgeMinModifier = 0.0; -BowrifleAdversaryDodgeMaxModifier = 0.0; -LauncherAdversaryDodgeMinModifier = 0.0; -LauncherAdversaryDodgeMaxModifier = 0.0; -PistolAdversaryDodgeMinModifier = 0.0; -PistolAdversaryDodgeMaxModifier = 0.0; -BowpistolAdversaryDodgeMinModifier = 0.0; -BowpistolAdversaryDodgeMaxModifier = 0.0; -RifleAdversaryDodgeMinModifier = 0.0; -RifleAdversaryDodgeMaxModifier = 0.0; -HarpoonAdversaryDodgeMinModifier = 0.0; -HarpoonAdversaryDodgeMaxModifier = 0.0; -////////////////////////////// -// ADVERSARY PARRY MODIFIER // not for ammo, jewel and armor -// melee weapons -DaggerAdversaryParryMinModifier = 0.0; -DaggerAdversaryParryMaxModifier = 0.0; -SwordAdversaryParryMinModifier = 0.0; -SwordAdversaryParryMaxModifier = 0.0; -MaceAdversaryParryMinModifier = 0.0; -MaceAdversaryParryMaxModifier = 0.0; -AxeAdversaryParryMinModifier = 0.0; -AxeAdversaryParryMaxModifier = 0.0; -SpearAdversaryParryMinModifier = 0.0; -SpearAdversaryParryMaxModifier = 0.0; -StaffAdversaryParryMinModifier = 0.0; -StaffAdversaryParryMaxModifier = 0.0; -TwoHandSwordAdversaryParryMinModifier = 0.0; -TwoHandSwordAdversaryParryMaxModifier = 0.0; -TwoHandAxeAdversaryParryMinModifier = 0.0; -TwoHandAxeAdversaryParryMaxModifier = 0.0; -PikeAdversaryParryMinModifier = 0.0; -PikeAdversaryParryMaxModifier = 0.0; -TwoHandMaceAdversaryParryMinModifier = 0.0; -TwoHandMaceAdversaryParryMaxModifier = 0.0; -MagicianStaffAdversaryParryMinModifier = 0.0; -MagicianStaffAdversaryParryMaxModifier = 0.0; -// range weapon -AutolauchAdversaryParryMinModifier = 0.0; -AutolauchAdversaryParryMaxModifier = 0.0; -BowrifleAdversaryParryMinModifier = 0.0; -BowrifleAdversaryParryMaxModifier = 0.0; -LauncherAdversaryParryMinModifier = 0.0; -LauncherAdversaryParryMaxModifier = 0.0; -PistolAdversaryParryMinModifier = 0.0; -PistolAdversaryParryMaxModifier = 0.0; -BowpistolAdversaryParryMinModifier = 0.0; -BowpistolAdversaryParryMaxModifier = 0.0; -RifleAdversaryParryMinModifier = 0.0; -RifleAdversaryParryMaxModifier = 0.0; -HarpoonAdversaryParryMinModifier = 0.0; -HarpoonAdversaryParryMaxModifier = 0.0; - -////////////////////////////// -// Cast Modifiers // for melee weapons -//Elemental casting time factor (melee weapon only) -// Min -DaggerElementalCastingTimeFactor = 0.0; -SwordElementalCastingTimeFactor = 0.0; -AxeElementalCastingTimeFactor = 0.0; -MaceElementalCastingTimeFactor = 0.0; -SpearElementalCastingTimeFactor = 0.0; -StaffElementalCastingTimeFactor = 0.0; -MagicianStaffElementalCastingTimeFactor = 0.0; -TwoHandAxeElementalCastingTimeFactor = 0.0; -TwoHandSwordElementalCastingTimeFactor = 0.0; -PikeElementalCastingTimeFactor = 0.0; -TwoHandMaceElementalCastingTimeFactor = 0.0; -// max -DaggerElementalCastingTimeFactorMax = 1.0; -SwordElementalCastingTimeFactorMax = 1.0; -AxeElementalCastingTimeFactorMax = 1.0; -MaceElementalCastingTimeFactorMax = 1.0; -SpearElementalCastingTimeFactorMax = 1.0; -StaffElementalCastingTimeFactorMax = 1.0; -MagicianStaffElementalCastingTimeFactorMax = 1.0; -TwoHandAxeElementalCastingTimeFactorMax = 1.0; -TwoHandSwordElementalCastingTimeFactorMax = 1.0; -PikeElementalCastingTimeFactorMax = 1.0; -TwoHandMaceElementalCastingTimeFactorMax = 1.0; - -//Elemental power factor (melee weapon only) -// Min -DaggerElementalPowerFactor = 0.0; -SwordElementalPowerFactor = 0.0; -AxeElementalPowerFactor = 0.0; -MaceElementalPowerFactor = 0.0; -SpearElementalPowerFactor = 0.0; -StaffElementalPowerFactor = 0.0; -MagicianStaffElementalPowerFactor = 0.2; -TwoHandAxeElementalPowerFactor = 0.0; -TwoHandSwordElementalPowerFactor = 0.0; -PikeElementalPowerFactor = 0.0; -TwoHandMaceElementalPowerFactor = 0.0; -// Max -DaggerElementalPowerFactorMax = 1.0; -SwordElementalPowerFactorMax = 1.0; -AxeElementalPowerFactorMax = 1.0; -MaceElementalPowerFactorMax = 1.0; -SpearElementalPowerFactorMax = 1.0; -StaffElementalPowerFactorMax = 1.0; -MagicianStaffElementalPowerFactorMax = 1.0; -TwoHandAxeElementalPowerFactorMax = 1.0; -TwoHandSwordElementalPowerFactorMax = 1.0; -PikeElementalPowerFactorMax = 1.0; -TwoHandMaceElementalPowerFactorMax = 1.0; - -//OffensiveAffliction casting time factor (melee weapon only) -// Min -DaggerOffensiveAfflictionCastingTimeFactor = 0.0; -SwordOffensiveAfflictionCastingTimeFactor = 0.0; -AxeOffensiveAfflictionCastingTimeFactor = 0.0; -MaceOffensiveAfflictionCastingTimeFactor = 0.0; -SpearOffensiveAfflictionCastingTimeFactor = 0.0; -StaffOffensiveAfflictionCastingTimeFactor = 0.0; -MagicianStaffOffensiveAfflictionCastingTimeFactor = 0.2; -TwoHandAxeOffensiveAfflictionCastingTimeFactor = 0.0; -TwoHandSwordOffensiveAfflictionCastingTimeFactor = 0.0; -PikeOffensiveAfflictionCastingTimeFactor = 0.0; -TwoHandMaceOffensiveAfflictionCastingTimeFactor = 0.0; -// Max -DaggerOffensiveAfflictionCastingTimeFactorMax = 1.0; -SwordOffensiveAfflictionCastingTimeFactorMax = 1.0; -AxeOffensiveAfflictionCastingTimeFactorMax = 1.0; -MaceOffensiveAfflictionCastingTimeFactorMax = 1.0; -SpearOffensiveAfflictionCastingTimeFactorMax = 1.0; -StaffOffensiveAfflictionCastingTimeFactorMax = 1.0; -MagicianStaffOffensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandAxeOffensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandSwordOffensiveAfflictionCastingTimeFactorMax = 1.0; -PikeOffensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandMaceOffensiveAfflictionCastingTimeFactorMax = 1.0; - -//OffensiveAffliction power factor (melee weapon only) -// Min -DaggerOffensiveAfflictionPowerFactor = 0.0; -SwordOffensiveAfflictionPowerFactor = 0.0; -AxeOffensiveAfflictionPowerFactor = 0.0; -MaceOffensiveAfflictionPowerFactor = 0.0; -SpearOffensiveAfflictionPowerFactor = 0.0; -StaffOffensiveAfflictionPowerFactor = 0.0; -MagicianStaffOffensiveAfflictionPowerFactor = 0.0; -TwoHandAxeOffensiveAfflictionPowerFactor = 0.0; -TwoHandSwordOffensiveAfflictionPowerFactor = 0.0; -PikeOffensiveAfflictionPowerFactor = 0.0; -TwoHandMaceOffensiveAfflictionPowerFactor = 0.0; -// Max -DaggerOffensiveAfflictionPowerFactorMax = 1.0; -SwordOffensiveAfflictionPowerFactorMax = 1.0; -AxeOffensiveAfflictionPowerFactorMax = 1.0; -MaceOffensiveAfflictionPowerFactorMax = 1.0; -SpearOffensiveAfflictionPowerFactorMax = 1.0; -StaffOffensiveAfflictionPowerFactorMax = 1.0; -MagicianStaffOffensiveAfflictionPowerFactorMax = 1.0; -TwoHandAxeOffensiveAfflictionPowerFactorMax = 1.0; -TwoHandSwordOffensiveAfflictionPowerFactorMax = 1.0; -PikeOffensiveAfflictionPowerFactorMax = 1.0; -TwoHandMaceOffensiveAfflictionPowerFactorMax = 1.0; - -//Heal casting time factor (melee weapon only) -// Min -DaggerHealCastingTimeFactor = 0.0; -SwordHealCastingTimeFactor = 0.0; -AxeHealCastingTimeFactor = 0.0; -MaceHealCastingTimeFactor = 0.0; -SpearHealCastingTimeFactor = 0.0; -StaffHealCastingTimeFactor = 0.0; -MagicianStaffHealCastingTimeFactor = 0.0; -TwoHandAxeHealCastingTimeFactor = 0.0; -TwoHandSwordHealCastingTimeFactor = 0.0; -PikeHealCastingTimeFactor = 0.0; -TwoHandMaceHealCastingTimeFactor = 0.0; -// Max -DaggerHealCastingTimeFactorMax = 1.0; -SwordHealCastingTimeFactorMax = 1.0; -AxeHealCastingTimeFactorMax = 1.0; -MaceHealCastingTimeFactorMax = 1.0; -SpearHealCastingTimeFactorMax = 1.0; -StaffHealCastingTimeFactorMax = 1.0; -MagicianStaffHealCastingTimeFactorMax = 1.0; -TwoHandAxeHealCastingTimeFactorMax = 1.0; -TwoHandSwordHealCastingTimeFactorMax = 1.0; -PikeHealCastingTimeFactorMax = 1.0; -TwoHandMaceHealCastingTimeFactorMax = 1.0; - -//Heal power factor (melee weapon only) -// Min -DaggerHealPowerFactor = 0.0; -SwordHealPowerFactor = 0.0; -AxeHealPowerFactor = 0.0; -MaceHealPowerFactor = 0.0; -SpearHealPowerFactor = 0.0; -StaffHealPowerFactor = 0.0; -MagicianStaffHealPowerFactor = 0.0; -TwoHandAxeHealPowerFactor = 0.0; -TwoHandSwordHealPowerFactor = 0.0; -PikeHealPowerFactor = 0.0; -TwoHandMaceHealPowerFactor = 0.0; -// Max -DaggerHealPowerFactorMax = 1.0; -SwordHealPowerFactorMax = 1.0; -AxeHealPowerFactorMax = 1.0; -MaceHealPowerFactorMax = 1.0; -SpearHealPowerFactorMax = 1.0; -StaffHealPowerFactorMax = 1.0; -MagicianStaffHealPowerFactorMax = 1.0; -TwoHandAxeHealPowerFactorMax = 1.0; -TwoHandSwordHealPowerFactorMax = 1.0; -PikeHealPowerFactorMax = 1.0; -TwoHandMaceHealPowerFactorMax = 1.0; - -//DefensiveAffliction casting time factor (melee weapon only) -// Min -DaggerDefensiveAfflictionCastingTimeFactor = 0.0; -SwordDefensiveAfflictionCastingTimeFactor = 0.0; -AxeDefensiveAfflictionCastingTimeFactor = 0.0; -MaceDefensiveAfflictionCastingTimeFactor = 0.0; -SpearDefensiveAfflictionCastingTimeFactor = 0.0; -StaffDefensiveAfflictionCastingTimeFactor = 0.0; -MagicianStaffDefensiveAfflictionCastingTimeFactor = 0.0; -TwoHandAxeDefensiveAfflictionCastingTimeFactor = 0.0; -TwoHandSwordDefensiveAfflictionCastingTimeFactor = 0.0; -PikeDefensiveAfflictionCastingTimeFactor = 0.0; -TwoHandMaceDefensiveAfflictionCastingTimeFactor = 0.0; -// Max -DaggerDefensiveAfflictionCastingTimeFactorMax = 1.0; -SwordDefensiveAfflictionCastingTimeFactorMax = 1.0; -AxeDefensiveAfflictionCastingTimeFactorMax = 1.0; -MaceDefensiveAfflictionCastingTimeFactorMax = 1.0; -SpearDefensiveAfflictionCastingTimeFactorMax = 1.0; -StaffDefensiveAfflictionCastingTimeFactorMax = 1.0; -MagicianStaffDefensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandAxeDefensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandSwordDefensiveAfflictionCastingTimeFactorMax = 1.0; -PikeDefensiveAfflictionCastingTimeFactorMax = 1.0; -TwoHandMaceDefensiveAfflictionCastingTimeFactorMax = 1.0; - -//DefensiveAffliction power factor (melee weapon only) -// Min -DaggerDefensiveAfflictionPowerFactor = 0.0; -SwordDefensiveAfflictionPowerFactor = 0.0; -AxeDefensiveAfflictionPowerFactor = 0.0; -MaceDefensiveAfflictionPowerFactor = 0.0; -SpearDefensiveAfflictionPowerFactor = 0.0; -StaffDefensiveAfflictionPowerFactor = 0.0; -MagicianStaffDefensiveAfflictionPowerFactor = 0.0; -TwoHandAxeDefensiveAfflictionPowerFactor = 0.0; -TwoHandSwordDefensiveAfflictionPowerFactor = 0.0; -PikeDefensiveAfflictionPowerFactor = 0.0; -TwoHandMaceDefensiveAfflictionPowerFactor = 0.0; -// Max -DaggerDefensiveAfflictionPowerFactorMax = 1.0; -SwordDefensiveAfflictionPowerFactorMax = 1.0; -AxeDefensiveAfflictionPowerFactorMax = 1.0; -MaceDefensiveAfflictionPowerFactorMax = 1.0; -SpearDefensiveAfflictionPowerFactorMax = 1.0; -StaffDefensiveAfflictionPowerFactorMax = 1.0; -MagicianStaffDefensiveAfflictionPowerFactorMax = 1.0; -TwoHandAxeDefensiveAfflictionPowerFactorMax = 1.0; -TwoHandSwordDefensiveAfflictionPowerFactorMax = 1.0; -PikeDefensiveAfflictionPowerFactorMax = 1.0; -TwoHandMaceDefensiveAfflictionPowerFactorMax = 1.0; - - - -/////////////////////// -// PROTECTION FACTOR // -// armor and shield -// Min -BucklerProtectionFactor = 0.10; -ShieldProtectionFactor = 0.10; -LightBootsProtectionFactor = 0.10; -LightGlovesProtectionFactor = 0.10; -LightPantsProtectionFactor = 0.10; -LightSleevesProtectionFactor = 0.10; -LightVestProtectionFactor = 0.10; -MediumBootsProtectionFactor = 0.10; -MediumGlovesProtectionFactor = 0.10; -MediumPantsProtectionFactor = 0.10; -MediumSleevesProtectionFactor = 0.10; -MediumVestProtectionFactor = 0.10; -HeavyBootsProtectionFactor = 0.10; -HeavyGlovesProtectionFactor = 0.10; -HeavyPantsProtectionFactor = 0.10; -HeavySleevesProtectionFactor = 0.10; -HeavyVestProtectionFactor = 0.10; -HeavyHelmetProtectionFactor = 0.10; -// Max -BucklerProtectionFactorMax = 0.10; -ShieldProtectionFactorMax = 0.10; -LightBootsProtectionFactorMax = 0.10; -LightGlovesProtectionFactorMax = 0.10; -LightPantsProtectionFactorMax = 0.10; -LightSleevesProtectionFactorMax = 0.10; -LightVestProtectionFactorMax = 0.10; -MediumBootsProtectionFactorMax = 0.10; -MediumGlovesProtectionFactorMax = 0.10; -MediumPantsProtectionFactorMax = 0.10; -MediumSleevesProtectionFactorMax = 0.10; -MediumVestProtectionFactorMax = 0.10; -HeavyBootsProtectionFactorMax = 0.10; -HeavyGlovesProtectionFactorMax = 0.10; -HeavyPantsProtectionFactorMax = 0.10; -HeavySleevesProtectionFactorMax = 0.10; -HeavyVestProtectionFactorMax = 0.10; -HeavyHelmetProtectionFactorMax = 0.10; -///////////////////////////// -// MAX SLASHING PROTECTION // value to multiply with the item level. -// armor and shield -BucklerMaxSlashingProtection = 0.10; -ShieldMaxSlashingProtection = 0.10; -LightBootsMaxSlashingProtection = 0.10; -LightGlovesMaxSlashingProtection = 0.10; -LightPantsMaxSlashingProtection = 0.10; -LightSleevesMaxSlashingProtection = 0.10; -LightVestMaxSlashingProtection = 0.10; -MediumBootsMaxSlashingProtection = 0.10; -MediumGlovesMaxSlashingProtection = 0.10; -MediumPantsMaxSlashingProtection = 0.10; -MediumSleevesMaxSlashingProtection = 0.10; -MediumVestMaxSlashingProtection = 0.10; -HeavyBootsMaxSlashingProtection = 0.10; -HeavyGlovesMaxSlashingProtection = 0.10; -HeavyPantsMaxSlashingProtection = 0.10; -HeavySleevesMaxSlashingProtection = 0.10; -HeavyVestMaxSlashingProtection = 0.33; -HeavyHelmetMaxSlashingProtection = 0.33; -////////////////////////// -// MAX BLUNT PROTECTION // -// armor and shield -BucklerMaxBluntProtection = 0.10; -ShieldMaxBluntProtection = 0.10; -LightBootsMaxBluntProtection = 0.10; -LightGlovesMaxBluntProtection = 0.10; -LightPantsMaxBluntProtection = 0.10; -LightSleevesMaxBluntProtection = 0.10; -LightVestMaxBluntProtection = 0.10; -MediumBootsMaxBluntProtection = 0.10; -MediumGlovesMaxBluntProtection = 0.10; -MediumPantsMaxBluntProtection = 0.10; -MediumSleevesMaxBluntProtection = 0.10; -MediumVestMaxBluntProtection = 0.10; -HeavyBootsMaxBluntProtection = 0.10; -HeavyGlovesMaxBluntProtection = 0.10; -HeavyPantsMaxBluntProtection = 0.10; -HeavySleevesMaxBluntProtection = 0.10; -HeavyVestMaxBluntProtection = 0.10; -HeavyHelmetMaxBluntProtection = 0.10; -///////////////////////////// -// MAX PIERCING PROTECTION // -// armor and shield -BucklerMaxPiercingProtection = 0.10; -ShieldMaxPiercingProtection = 0.10; -LightBootsMaxPiercingProtection = 0.10; -LightGlovesMaxPiercingProtection = 0.10; -LightPantsMaxPiercingProtection = 0.10; -LightSleevesMaxPiercingProtection = 0.10; -LightVestMaxPiercingProtection = 0.10; -MediumBootsMaxPiercingProtection = 0.10; -MediumGlovesMaxPiercingProtection = 0.10; -MediumPantsMaxPiercingProtection = 0.10; -MediumSleevesMaxPiercingProtection = 0.10; -MediumVestMaxPiercingProtection = 0.10; -HeavyBootsMaxPiercingProtection = 0.10; -HeavyGlovesMaxPiercingProtection = 0.10; -HeavyPantsMaxPiercingProtection = 0.10; -HeavySleevesMaxPiercingProtection = 0.10; -HeavyVestMaxPiercingProtection = 0.10; -HeavyHelmetMaxPiercingProtection = 0.10; -////////////////////////////// -// JEWEL PROTECTION -AcidJewelProtection = 0.01001; // de 0 à 1.0 (1.0 = 100% de protection) -ColdJewelProtection = 0.01001; -FireJewelProtection = 0.01001; -RotJewelProtection = 0.01001; -ShockWaveJewelProtection = 0.01001; -PoisonJewelProtection = 0.01001; -ElectricityJewelProtection = 0.01001; - -MaxMagicProtection = 10; // Maximum protection can be gived by jewelry (clamp value), de 0 à 100 (pourcentage) -HominBaseProtection = 10; // Homin base protection in generic magic damage type -HominRacialProtection = 10; // Homin base protection in racial magic damage type -MaxAbsorptionFactor = 10; // Factor used for compute maximum absorption gived by all jewel (100 = 1.0 factor (100%)) (Max absorbtion = sum(equipped jewels recommandeds) * factor) -////////////////////////////// -// JEWEL RESISTANCE -DesertResistance = 1; // In skill points bonus -ForestResistance = 1; -LacustreResistance = 1; -JungleResistance = 1; -PrimaryRootResistance = 1; - -HominRacialResistance = 10;// Homin racial magic resistance to magic racial spell type -MaxMagicResistanceBonus = 10;// clamp value of resistance bonus resistance after all bonus/malus applied -EcosystemResistancePenalty = 10;// ecosystem resistance penalty value -//************************************************************************************************************* -// regen speed parameters -//************************************************************************************************************* -RegenDivisor = 1.0; -RegenReposFactor = 1.0; -RegenOffset = 1.0; - -//************************************************************************************************************* -// weapon damage table config -//************************************************************************************************************* -MinDamage = 10; -DamageStep = 1; -ExponentialPower = 1; -SmoothingFactor = 0; - -//************************************************************************************************************* -// hand to hand combat config -//************************************************************************************************************* -HandToHandDamageFactor = 0.10; -HandToHandLatency = 25; // 25 ticks = 2.5s - -//************************************************************************************************************* -// combat config -//************************************************************************************************************* -BotDamageFactor = 1; // factor applied on npc and creature damage -// special effects when hit to localisation -HitChestStaLossFactor = 0.1; -HitHeadStunDuration = 1; -HitArmsSlowDuration = 1; -HitArmsSlowFactor = 10; -HitLegsSlowDuration = 1; -HitLegsSlowFactor = -10; -HitHandsDebuffDuration = 1; -HitHandsDebuffValue = -10; -HitFeetDebuffDuration = 1; -HitFeetDebuffValue = -10; -NbOpponentsBeforeMalus = 1; -ModPerSupernumeraryOpponent = -1; -MinTwoWeaponsLatency = 10; - -ShieldingRadius = 1; -CombatFlagLifetime = 10; // (in ticks) used for openings - -DodgeFactorForMagicSkills = 1.0; -DodgeFactorForForageSkills = 1.0; - -MagicResistFactorForCombatSkills = 1.0; -MagicResistFactorForMagicSkills = 1.0; -MagicResistFactorForForageSkills = 1.0; -MagicResistSkillDelta = -10; - -//************************************************************************************************************* -// Price parameters ( price formula is ItemPriceCoeff2 * x2 + ItemPriceCoeff1 * x + ItemPriceCoeff0 ) -//************************************************************************************************************* -// polynom coeff of degree 0 in the price formula -ItemPriceCoeff0 = 100.0; -// polynom coeff of degree 1 in the price formula -ItemPriceCoeff1 = 0.1; -// polynom coeff of degree 2 in the price formula -ItemPriceCoeff2 = 0.01; -// factor to apply on non raw maetrial items to compute their price -ItemPriceFactor = 1.0; -// factor to apply on animal price to get the price a user can buy them -AnimalSellFactor = 0.1; -// factor to apply on teleport price to get the price a user can buy them -TeleportSellFactor = 0.1; -// this factor is applied to all faction point prices -GlobalFactionPointPriceFactor = 1.0; - -// this factor is applied to all faction point prices -GlobalFactionPointPriceFactor = 1.0; - -//************************************************************************************************************* -// Max quality of Raw Material Npc item selled by NPC -//************************************************************************************************************* -MaxNPCRawMaterialQualityInSell = 100; - -//************************************************************************************************************* -// Sell store parameters -//************************************************************************************************************* -// an item can stay 7 days in a sale store (total cumulated time in game cycle) -MaxGameCycleSaleStore = 6048000; - -NBMaxItemPlayerSellDisplay = 128; //NB max item can be displayed for player item list selled -NBMaxItemNpcSellDisplay = 128; //NB max item can be displayed for npc item list selled -NBMaxItemYoursSellDisplay = 128; //NB max item can be displayed for your item list selled, it's also the max items player can put in sale store - -//************************************************************************************************************* -// Factor for apply malus wear equipment to craft ( Recommended max = Recommended - (Recommanded * malus wear * WearMalusCraftFactor ) -//************************************************************************************************************* -WearMalusCraftFactor = 0.1; - -//************************************************************************************************************* -// Item wear config -//************************************************************************************************************* -//MeleeWeaponWearPerAction = 0.01; -//RangeWeaponWearPerAction = 0.01; - -// now we base wear factor for weapons on the ration (WeaponLatency / ReferenceWeaponLatencyForWear) -// MUST be > 0 -ReferenceWeaponLatencyForWear = 10; - -CraftingToolWearPerAction = 0.01; -ForageToolWearPerAction = 0.01; -ArmorWearPerAction = 0.01; -ShieldWearPerAction = 0.01; -JewelryWearPerAction = 0.01; - -// melee weapons -DaggerWearPerAction = 0.01; -SwordWearPerAction = 0.01; -MaceWearPerAction = 0.01; -AxeWearPerAction = 0.01; -SpearWearPerAction = 0.01; -StaffWearPerAction = 0.01; -MagicianStaffWearPerAction = 0.01; -TwoHandSwordWearPerAction = 0.01; -TwoHandAxeWearPerAction = 0.01; -PikeWearPerAction = 0.01; -TwoHandMaceWearPerAction = 0.01; -// range weapon -AutolauchWearPerAction = 0.01; -BowrifleWearPerAction = 0.01; -LauncherWearPerAction = 0.01; -PistolWearPerAction = 0.01; -BowpistolWearPerAction = 0.01; -RifleWearPerAction = 0.01; - -//************************************************************************************************************* -// Fame Variables -//************************************************************************************************************* -// Fame memory interpolation periode -FameMemoryInterpolation = 1220000; -// Fame trend reset delay -FameTrendResetDelay = 10000; -// Point of fame lost with the faction of a killed bot -FameByKill = -1000; -// Minimum Fame To Buy a Guild Building -MinFameToBuyGuildBuilding = 0; -// Minimum Fame To Buy a Player Building -MinFameToBuyPlayerBuilding = 0; -// maximum price variation ( in absolute value ) that can be due to fame -MaxFamePriceVariation = 0.1; -// Maximum fame value taken in account in trade -MaxFameToTrade = 600000; -// Minimum fame value taken in account in trade, under this value, the merchant refuse to sell -MinFameToTrade = -600000; - -//************************************************************************************************************* -// Guild Variables -//************************************************************************************************************* -//fame to buy a guild building -MinFameToBuyGuildBuilding = 0; -// cost of the guild building in money -MoneyToBuyGuildBuilding = 10; -// base bulk of the guild building -BaseGuildBulk = 10000000; -// cost in money to create a guild -GuildCreationCost = 100000; -// max number of charges a guild can apply for -MaxAppliedChargeCount = 3; - -//************************************************************************************************************* -// Animals -//************************************************************************************************************* -AnimalHungerFactor = 0.01; -AnimalStopFollowingDistance = 100; -AllowAnimalInventoryAccessFromAnyStable = 0; - -//************************************************************************************************************* -// PVP -//************************************************************************************************************* -DuelQueryDuration = 600; -ChallengeSpawnZones = -{ - "pvp_challenge_fyros_spawn_1", - "pvp_challenge_fyros_spawn_2", -}; - -PVPMeleeCombatDamageFactor = 1.0; -PVPRangeCombatDamageFactor = 1.0; -PVPMagicDamageFactor = 1.0; - -TimeForSetPVPFlag = 1000; -TimeForResetPVPFlag = 1000; -TimeForPVPFlagOff = 1000; -PVPActionTimer = 1000; - -TotemBuildTime = 1000; -TotemRebuildWait = 1000; - -ResPawnPVPInSameRegionForbiden = 1; // 1 is player character can't respawn in same region of there death in faction PvP. - -BuildSpireActive = 1; - - -// max distance from PvP combat to gain PvP points (faction and HoF points) from team PvP kills (in meters) -MaxDistanceForPVPPointsGain = 5.0; -// minimum delta level used to compute the faction points gain -MinPVPDeltaLevel = -5; -// maximum delta level used to compute the faction points gain -MaxPVPDeltaLevel = 5; -// for team PvP progression add this value to the faction points divisor for each team member above one -PVPTeamMemberDivisorValue = 1.0; -// it is the base used in faction point gain formula -PVPFactionPointBase = 5.0; -// it is the base used in HoF point gain formula -PVPHoFPointBase = 5.0; -// in faction PvP the killed players loses the faction points gained per killer multiplied by this factor -PVPFactionPointLossFactor = 0.5; -// in faction PvP the killed players loses the HoF points gained per killer multiplied by this factor -PVPHoFPointLossFactor = 0.5; -// players will not get any point for the same PvP kill for this time in seconds -TimeWithoutPointForSamePVPKill = 100; - -VerboseFactionPoint = 0; - -//************************************************************************************************************* -// Outpost -//************************************************************************************************************* -// Global flag to activate outpost challenge system -LoadOutposts = 1; -// Outpost saving period in tick (1 outpost saved at a time) -OutpostSavingPeriod = 10; -// Period in ticks between 2 updates of the same outpost -OutpostUpdatePeriod = 10; -// Set if the outpost drillers generate mps or not -EnableOutpostDrillerMPGeneration = 1; -// Production time of mp in the driller (in seconds) -OutpostDrillerTimeUnit = 10*60*24; // per day -// Delay in ticks used to check if 2 actions for editing an outpost are concurrent -OutpostEditingConcurrencyCheckDelay = 10; -// Period in seconds between 2 updates of outpost timers on clients -OutpostClientTimersUpdatePeriod = 10; -// Number of rounds in an outpost fight -OutpostFightRoundCount = 10; -// Time of a round in an outpost fight, in seconds -OutpostFightRoundTime = 1*60; -// Time to decrement an outpost level in seconds (in peace time) -OutpostLevelDecrementTime = 60*60*24*1; -// Delay in ticks used to check if 2 actions for editing an outpost are concurrent -OutpostEditingConcurrencyCheckDelay = 10; -// Time of each outpost state (challenge, beforeAttack, afterAttack, beforeDefense, afterDefense), in seconds. If 0 default computed value is used. -OutpostStateTimeOverride = 0; -// Max time the player has to answer the JoinPvp Window, in seconds -OutpostJoinPvpTimer = 10; -// Time range before next attack period in which a service reboot will cancel the challenge, in seconds -OutpostRangeForCancelOnReset = 60*60*1; -// Max number of outposts per guild (DO NOT exceed outpost count in database.xml) -GuildMaxOutpostCount = 10; -//************************************************************************************************************* - -MonoMissionTimout = 144000; -VerboseMissions = 0; -MissionLogFile = "egs_missions.log"; -MissionPrerequisitsEnabled = 1; -CheckCharacterVisitPlacePeriodGC = 64; - -// This icon will be used for missions with an invalid mission icon. If -// default icon is invalid too mission will not be displayed at all on client. -DefaultMissionIcon = "generic_rite"; - -// Mission states is read from file mission_validation.cfg. The EGS will load -// only the files which state is in ValidMissionStates list. If that list -// contains the keyword "All" all missions will be loaded. -ValidMissionStates = { - "All", -// "Disabled", -// "Test", -// "Valid", -}; - -StoreBotNames = 1; - -Tocking = 1; - -// unlimited death pact for internal testing -UnlimitedDeathPact = 1; - -//ignore race prerequisits for missions -IgnoreMissionRacePrerequisits = 1; - -// Max distance allowed for bot chat & dyn chat -MaxBotChatDistanceM = 5; - -//zone types that must be set as triggers -TriggerZoneTypes = { "place","region" }; - -// PeopleAutorized 1:fyros 2:matis 4:tryker 8:zorai - - -StartCommandsWhenMirrorReady = -{ - "PeopleAutorized 255", -}; - -// set the world instance activity verbosity -VerboseWorldInstance = 0; - -// set the shop category parser verbosity -VerboseShopParsing = 0; - -// Checking coherency between saved players and CEntityIdTranslator map, may be slow, so put to 0 if you want -CheckEntityIdTranslatorCoherency = 0; - -// Filename that contains the list of invalid entity names -InvalidEntityNamesFilename = "invalid_entity_names.txt"; - -ForageKamiAngerThreshold1 = 10000; -ForageKamiAngerThreshold2 = 10000; -ForageKamiAngerDecreasePerHour = 900.0; -ForageKamiAngerPunishDamage = 5000; - -ForageValidateSourcesSpawnPos = 1; -AutoSpawnForageSourcePeriodOverride = 0; -ForageKamiAngerOverride = 0; -ForageSiteStock = 100; -ForageSiteNbUpdatesToLive = 10; -ForageSiteRadius = 10.0; -ForageExtractionTimeMinGC = 230.0; -ForageExtractionTimeSlopeGC = 2.0; -ForageQuantityBaseRate = 0; -ForageQuantityBrick1 = 0.5; -ForageQuantityBrick2 = 0.5; -ForageQuantityBrick3 = 0.5; -ForageQuantityBrick4 = 0.5; -ForageQuantityBrick5 = 0.5; -ForageQuantityBrick6 = 0.5; -ForageQuantityBrick7 = 0.5; -ForageQuantityBrick8 = 0.5; -ForageQuantityBrick9 = 0.5; -ForageQuantityBrick10 = 0.5; -ForageQuantityBrick11 = 0.5; -ForageQuantityBrick12 = 0.5; -ForageQuantitySlowFactor = 0.5; -ForageQualitySlowFactor = 1.50; -ForageQualitySlowFactorQualityLevelRatio = 0.1; -ForageQualitySlowFactorDeltaLevelRatio = 0.1; -ForageQualitySlowFactorMatSpecRatio = 0.1; -ForageQualityCeilingFactor = 1.0; -ForageQualityCeilingClamp = 1; -ForageQuantityImpactFactor = 20.0; -ForageQualityImpactFactor = 1.5; -ForageExtractionAbsorptionMatSpecFactor = 5.0; -ForageExtractionAbsorptionMatSpecMax = 1.0; -ForageExtractionCareMatSpecFactor = 1.0; -ForageExtractionAbsorptionEcoSpecFactor = 5.0; -ForageExtractionAbsorptionEcoSpecMax = 1.0; -ForageExtractionCareEcoSpecFactor = 1.0; -ForageExtractionNaturalDDeltaPerTick = 0.1; -ForageExtractionNaturalEDeltaPerTick = 0.1; -ForageCareFactor = 5.0; -ForageCareBeginZone = 5.0; -ForageHPRatioPerSourceLifeImpact = 0.005; -ForageExplosionDamage = 5000.0; -ToxicCloudDamage = 500.0; -ForageCareSpeed = 0.05; -ForageKamiOfferingSpeed = 0.01; -ForageDebug = 0; -ForageSourceSpawnDelay = 50; -ForageFocusRatioOfLocateDeposit = 10; -ForageFocusAutoRegenRatio = 1.0; -ForageReduceDamageTimeWindow = 50; -ForageExtractionXPFactor = 10.0; -ForageQuantityXPDeltaLevelBonusRate = 1.0; -ForageProspectionXPBonusRatio = 0.1; -ForageExtractionNbParticipantsXPBonusRatio = 0.1; -ForageExtractionNastyEventXPMalusRatio = 0.1; - -QuarteringQuantityAverageForCraftHerbivore = 2.0; -QuarteringQuantityAverageForCraftCarnivore = 5.0; -QuarteringQuantityAverageForMissions = 1.0; -QuarteringQuantityAverageForBoss5 = 10; -QuarteringQuantityAverageForBoss7 = 50; -QuarteringQuantityForInvasion5 = 50; -QuarteringQuantityForInvasion7 = 100; - -LootMoneyAmountPerXPLevel = 10.0; - -VerboseQuartering = 0; - -// Shutdown handling - -// Time to shutdown server in minutes -ShutdownCounter = 5; - -// Time between to shutdown messages in seconds -BroadcastShutdownMessageRate = 30; - -// Time to shutdown to close access to welcome service, in seconds -CloseShardAccessAt = 300; - -// Persistent Logging - -DatabaseId = 0; - -// delay during character stay in game after disconnection -TimeBeforeDisconnection = 300; - -// File that contains the privileges for client commands -ClientCommandsPrivilegesFile = "client_commands_privileges.txt"; - -// File that contains the info on the current event on the server -GameEventFile = "game_event.txt"; - -// Privilege needed for banner -BannerPriv = ":G:SG:GM:SGM:"; -// Privilege that never aggro the bots -NeverAggroPriv = ":OBSERVER:G:SG:GM:SGM:EM:"; -// Privilege always invisible -AlwaysInvisiblePriv = ":OBSERVER:EM:"; -// Privilege to teleport with a mektoub -TeleportWithMektoubPriv = ":GM:SGM:DEV:"; -// Privilege that forbid action execution -NoActionAllowedPriv = ":OBSERVER"; -// Privilege that bypass value and score checking -NoValueCheckingPriv = ":GM:SGM:DEV:EM:EG:"; -// Privilege that prevent being disconnected in case of shard closing for technical problem -NoForceDisconnectPriv = ":GM:SGM:DEV:"; - -// File used to save position flags -PositionFlagsFile = "position_flags.xml"; - -// load PVP zones from primitives? -LoadPVPFreeZones = 1; -LoadPVPVersusZones = 1; -LoadPVPGuildZones = 1; - -// buffer time in ticks used when entering/leaving a PVP zone -PVPZoneEnterBufferTime = 300; -PVPZoneLeaveBufferTime = 1200; -PVPZoneWarningRepeatTime = 50; -PVPZoneWarningRepeatTimeL = 3000; - -// If 1, use the Death Penalty factor from the PVPZone primitive, else no death penalty -PVPZoneWithDeathPenalty = 1; - -// if 1, pvp duel/challenge will be disabled -DisablePVPDuel = 0; -DisablePVPChallenge = 1; - -// Fame Variables -// All values are multiplied by 6000 compared to values displayed on the client. -FameMinToDeclare = 600000; -FameWarningLevel = 60000; -FameMinToRemain = 0; -FameMinToTrade = -600000; -FameMinToKOS = -600000; -FameMaxDefault = 600000; -FameAbsoluteMin = -600000; -FameAbsoluteMax = 600000; - -FameStartFyrosvFyros = 600000; -FameStartFyrosvMatis = -600000; -FameStartFyrosvTryker = -60000; -FameStartFyrosvZorai = 60000; -FameStartMatisvFyros = -600000; -FameStartMatisvMatis = 600000; -FameStartMatisvTryker = 60000; -FameStartMatisvZorai = -60000; -FameStartTrykervFyros = -60000; -FameStartTrykervMatis = 60000; -FameStartTrykervTryker = 600000; -FameStartTrykervZorai = -600000; -FameStartZoraivFyros = 60000; -FameStartZoraivMatis = -60000; -FameStartZoraivTryker = -600000; -FameStartZoraivZorai = 600000; -FameStartFyrosvKami = 60000; -FameStartFyrosvKaravan = -60000; -FameStartMatisvKami = -600000; -FameStartMatisvKaravan = 600000; -FameStartTrykervKami = -60000; -FameStartTrykervKaravan = 60000; -FameStartZoraivKami = 600000; -FameStartZoraivKaravan = -600000; - -FameMaxNeutralvFyros = 600000; -FameMaxNeutralvMatis = 600000; -FameMaxNeutralvTryker = 600000; -FameMaxNeutralvZorai = 600000; -FameMaxFyrosvFyros = 600000; -FameMaxFyrosvMatis = 0; -FameMaxFyrosvTryker = 600000; -FameMaxFyrosvZorai = 600000; -FameMaxMatisvFyros = 0; -FameMaxMatisvMatis = 600000; -FameMaxMatisvTryker = 600000; -FameMaxMatisvZorai = 600000; -FameMaxTrykervFyros = 600000; -FameMaxTrykervMatis = 600000; -FameMaxTrykervTryker = 600000; -FameMaxTrykervZorai = 0; -FameMaxZoraivFyros = 600000; -FameMaxZoraivMatis = 600000; -FameMaxZoraivTryker = 0000; -FameMaxZoraivZorai = 600000; -FameMaxNeutralvKami = 600000; -FameMaxNeutralvKaravan = 600000; -FameMaxKamivKami = 600000; -FameMaxKamivKaravan = -600000; -FameMaxKaravanvKami = -600000; -FameMaxKaravanvKaravan = 600000; - -// Log switches, turns nlinfo on/off -NameManagerLogEnabled = 1; -GameItemLogEnabled = 1; -EntityCallbacksLogEnabled = 1; -EntityManagerLogEnabled = 1; -GuildManagerLogEnabled = 1; -ForageExtractionLogEnabled = 0; -PhraseManagerLogEnabled = 1; -CharacterLogEnabled = 1; -PlayerLogEnabled = 1; -ShoppingLogEnabled = 0; -PVPLogEnabled = 1; -PersistentPlayerDataLogEnabled = 0; - -DailyShutdownSequenceTime = ""; -DailyShutdownBroadcastMessage = "The shard will be shut down in 1 minute"; -DailyShutdownCounterMinutes = 1; -CheckShutdownPeriodGC = 50; - -PlayerChannelHistoricSize = 50; - -FlushSendingQueuesOnExit = 1; -NamesOfOnlyServiceToFlushSending = "BS"; - -// stat database save period in ticks -StatDBSavePeriod = 20; - -// New Newbieland -UseNewNewbieLandStartingPoint= 1; - -// The domain mainlands configuration -Mainlands = { - "302", "Open", "(Open Developer Community)", "en", -}; diff --git a/code/ryzom/server/frontend_service.cfg b/code/ryzom/server/frontend_service.cfg deleted file mode 100644 index 2e3fb7601..000000000 --- a/code/ryzom/server/frontend_service.cfg +++ /dev/null @@ -1,47 +0,0 @@ -// Use with commandline: frontend_service -C. -L. --nobreak --writepid - -// ---- config local variables - -// Client bandwidth ratio, set to 1 for standard opration, more than one allocate more bandwidth -BandwidthRatio = 1; - -FSUDPPort = 47851; -FSListenHost = "shard.ryzomcore.org"; - -#include "frontend_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "fes"; - -GraphVars += { "TickSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; -GraphVars += { "MirrorCallbackCount", "60000" }; -GraphVars += { "MirrorCallbackTime", "60000" }; - -Paths = { - "../common/data_common", - ".", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -//AcceptInvalidCookie = 1; - -ClientLimit = 1000; - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - - // ---- service custom variables (used by CVariable class) - -// Disable ryzom verbose logging -VerboseMIRROR = 0; - -// Root directory where data from shards are stored into -SaveShardRoot = "save_shard/"; diff --git a/code/ryzom/server/frontend_service_default.cfg b/code/ryzom/server/frontend_service_default.cfg deleted file mode 100644 index b87682906..000000000 --- a/code/ryzom/server/frontend_service_default.cfg +++ /dev/null @@ -1,104 +0,0 @@ -#include "common.cfg" - -// Configure module gateway for front end operation -StartCommands += -{ - // Add a security plugin (will add player info on player module proxy) - "gw.securityCreate FESecurity", - // create a front end service transport - "gw.transportAdd FEServer fes", - // set the transport option (need PeerInvisible and Firewalled) - "gw.transportOptions fes(PeerInvisible Firewalled)", - // open the transport - "gw.transportCmd fes(open)", -}; - - -// UDP port for client communication -//FrontendPort = 47851; - -ListenAddress = FSListenHost+":"+FSUDPPort; - -// Maximum size that can be read from a client message -DatagramLength = 10000; - -// Time-out before removing a client when it does not send any more data -ClientTimeOut = 600000; // 10 min - -// Time-out before removing a limbo client when it does not send any more data -LimboTimeOut = 60000; // 1 min - -// Maximum bytes per game cycle sent to all clients (currently not used/implemented) -TotalBandwidth = 536870911; // <512 MB : max value for 32 bit bitsize ! - -// Maximum bytes per game cycle sent to a client, including all headers -ClientBandwidth = 332 * BandwidthRatio; // 332 <=> 13 kbit/s at 5 Hz; 202 <=> 16 kbit/s at 10 Hz - -// Maximum bytes for impulsion channels per datagram sent to a client -ImpulsionByteSize0 = 20 * BandwidthRatio; -ImpulsionByteSize1 = 200 * BandwidthRatio; -ImpulsionByteSize2 = 200 * BandwidthRatio; -NbMinimalVisualBytes = 50; - -// Distance/delta ratio that triggers the sending of a position -DistanceDeltaRatioForPos = 100; - -// Number of game cycles per front-end cycle -GameCycleRatio = 1; -// Execution period of distance calculation -CalcDistanceExecutionPeriod = 8; -// Execution period of position prioritization -PositionPrioExecutionPeriod = 2; -// Execution period of orientation prioritization -OrientationPrioExecutionPeriod = 8; -// Execution period of discreet properties prioritization -DiscreetPrioExecutionPeriod = 2; - -SortPrioExecutionPeriod = 1; - -// Display or not the "FE" nlinfos -DisplayInfo = 1; - -// Prioritizer mode (currently the only mode is 1 for DistanceDelta) -PriorityMode = 1; - -// Strategy for selecting pairs to prioritize (Power2WithCeiling=0, Scoring=1) -SelectionStrategy = 1; - -// Minimum number of pairs to select for prioritization -MinNbPairsToSelect = 2000; - -// Index of client to monitor, or 0 for no monitoring -ClientMonitor = 0; - -// Allow or not beeping -AllowBeep = 1; - -Lag = 0; // The lag on the simulated network (used by simlag) -PacketLoss = 0; // percentage of lost packet (used by simlag) -PacketDuplication = 0; // percentage of duplicated packet (used by simlag) -PacketDisordering = 0; // percentage of disordered packet (used by simlag) (Lag must be >100 to use disordering) - -// ---------------------------------------- -// Frontend/Patch mode settings - -// If 1, the frontend server is used in Patch/Frontend mode (0 = only frontend mode, old behaviour) -UseWebPatchServer = 1; - -// If 0, the frontend service is in Patch mode at startup, and it won't accept clients unless WS tells it to do so. -AcceptClientsAtStartup = 1; - -// Patch URL footer. PatchURL will look like 'http://223.254.124.23:43435/patch' -PatchingURLFooter = ":43435/patch"; - -// System command to be executed when FS tries to start Web Patch server (ideally at FS startup) -StartWebServerSysCommand = ""; - -// System command to be executed when FS tries to stop Web Patch server (ideally when FS turns to frontend mode) -StopWebServerSysCommand = ""; - -// Use Thread for sending -UseSendThread = 1; - -// Unidirectional Mirror mode (FS part) -ExpediteTOCK = 1; diff --git a/code/ryzom/server/gpm_service.cfg b/code/ryzom/server/gpm_service.cfg deleted file mode 100644 index 3d06bf73b..000000000 --- a/code/ryzom/server/gpm_service.cfg +++ /dev/null @@ -1,39 +0,0 @@ -// Use with commandline: gpm_service -C. -L. --nobreak --writepid - -#include "gpm_service_default.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "gpms"; - -GraphVars += { "TickSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; -GraphVars += { "MirrorCallbackCount", "60000" }; -GraphVars += { "MirrorCallbackTime", "60000" }; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -#include "used_continents.cfg" - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - - // ---- service custom variables (used by CVariable class) - -// Set this shard as a ring (1) or mainland (0) shard (main behavior switch) -IsRingShard = 0; - -// Disable ryzom verbose logging -VerboseMIRROR = 0; diff --git a/code/ryzom/server/gpm_service_default.cfg b/code/ryzom/server/gpm_service_default.cfg deleted file mode 100644 index ad6099f24..000000000 --- a/code/ryzom/server/gpm_service_default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -#include "common.cfg" - -CheckPlayerSpeed = 0; -SecuritySpeedFactor = 1.5; - -LoadPacsPrims = 0; -LoadPacsCol = 1; diff --git a/code/ryzom/server/input_output_service.cfg b/code/ryzom/server/input_output_service.cfg deleted file mode 100644 index dbc9f339b..000000000 --- a/code/ryzom/server/input_output_service.cfg +++ /dev/null @@ -1,81 +0,0 @@ -// Use with commandline: input_output_service -C. -L. --nobreak --writepid - -// ---- config local variables - -#define DONT_USE_LGS_SLAVE - -AESPort="46702"; -SUPort = 50505; -SUGlobalPort = 50503; -L3MasterLGSPort = 41292; -L3SlaveLGSPort = 49993; -SUHost = "localhost"; -MasterLGSHost = "localhost"; -SlaveLGSHost = "localhost"; -// SU - listen address of the SU service (for L5 connections) -SUAddress = SUHost+":"+SUPort; - -#include "input_output_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "ios"; - -// Create a char name mapper -StartCommands += -{ -"moduleManager.createModule CharNameMapper cnm", -"cnm.plug gw", -"moduleManager.createModule IOSRingModule iosrm", -"iosrm.plug gw", -}; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - -// the following variable must be defined but should be empty - it's presence is used to change the behaviour -// of the packed sheet reader -GeorgePaths = { "" }; - -// Use Shard Unifier or not -DontUseSU = 0; - -HomeMainlandNames = -{ -"302", "Open", "open", -}; - - // ---- service custom variables (used by CVariable class) - -// Set this shard as a ring (1) or mainland (0) shard (main behavior switch) -IsRingShard = 0; - -// Disable ryzom verbose logging -VerboseMIRROR = 0; - -#include "backup_service_interface.cfg" - -// IOS - Directory to store ios.string_cache file -StringManagerCacheDirectory = "data_shard_local"; - -// IOS - Directory to log chat into -LogChatDirectory = "data_shard_local"; - -ReadTranslationWork = 1; -TranslationWorkPath = ""; -VerboseStringManager = 0; -VerboseStringManagerParser = 0; -VerboseChat = 0; -VerboseChatManagement = 0; -VerboseNameTranslation = 0; diff --git a/code/ryzom/server/input_output_service_default.cfg b/code/ryzom/server/input_output_service_default.cfg deleted file mode 100644 index ee100d367..000000000 --- a/code/ryzom/server/input_output_service_default.cfg +++ /dev/null @@ -1,95 +0,0 @@ -#include "common.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -StartCommands += -{ - // L5 connect to the shard unifier - "unifiedNetwork.addService ShardUnifier ( address="+SUAddress+" sendId external autoRetry )", - - // Create a gateway for global interconnection - // modules from different shard are visible to each other if they connect to - // this gateway. SU Local module have no interest to be plugged here. - "moduleManager.createModule StandardGateway glob_gw", - // add a layer 3 server transport - "glob_gw.transportAdd L3Client l3c", - // open the transport - "glob_gw.transportCmd l3c(connect addr="+SUHost+":"+SUGlobalPort+")", - - // Create a gateway for logger service connection - "moduleManager.createModule StandardGateway lgs_gw", - - // add a layer 3 server transport for master logger service - "lgs_gw.transportAdd L3Client masterL3c", - // open the transport - "lgs_gw.transportCmd masterL3c(connect addr="+MasterLGSHost+":"+L3MasterLGSPort+")", -}; - -#ifndef DONT_USE_LGS_SLAVE - -StartCommands += -{ - // add a layer 3 server transport for slave logger service - "lgs_gw.transportAdd L3Client slaveL3c", - // open the transport - "lgs_gw.transportCmd slaveL3c(connect addr="+SlaveLGSHost+":"+L3SlaveLGSPort+")", -}; - -#endif - -StartCommands += -{ - // Create a chat unifier client - "moduleManager.createModule ChatUnifierClient cuc", - - // and plug it on the gateway to reach the SU ChatUnifierServer - "cuc.plug glob_gw", - "cuc.plug gw", - - // Create the logger service client module - "moduleManager.createModule LoggerServiceClient lsc", - "lsc.plug lgs_gw", -}; - -#endif - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// a list of system command that can be run with "sysCmd" service command. -SystemCmd = {}; - -// IOS don't use work directory by default -ReadTranslationWork = 0; -TranslationWorkPath = "translation/work"; - -// Global shard bot name translation file. You sould overide this -// in input_output_service.cfg to specialize the file -// depending on the shard main language. -BotNameTranslationFile = "bot_names.txt"; - -// Global shard event faction translation file. You sould override this -// in input_output_service.cfg to specialize the file -// depending on the shard main language. -EventFactionTranslationFile = "event_factions.txt"; - - -// ---- service custom variables (used by CVariable class) - -// Activate/deactivate debugging of missing paremeter replacement -DebugReplacementParameter = 1; - -// Default verbose debug flags: -//----------------------------- - -// Log bot name translation from 'BotNameTranslationFile' -VerboseNameTranslation = 1; -// Log chat management operation -VerboseChatManagement = 1; -// Log chat event -VerboseChat = 1; -// Log string manager message -VerboseStringManager = 1; -// Log the string manager parsing message -VerboseStringManagerParser = 0; diff --git a/code/ryzom/server/logger_service.cfg b/code/ryzom/server/logger_service.cfg deleted file mode 100644 index 4f6dd85c6..000000000 --- a/code/ryzom/server/logger_service.cfg +++ /dev/null @@ -1,50 +0,0 @@ -// Use with commandline: logger_service -C. -L. --nobreak --writepid - -#include "logger_service_default.cfg" - -// ---- config local variables - -LGSL3Port = 41292; - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "lgs"; - -StartCommands += -{ -"moduleManager.createModule LoggerService ls", -"moduleManager.createModule StandardGateway lgs_gw", -"ls.plug lgs_gw", -"lgs_gw.transportAdd L3Server l3s", -"lgs_gw.transportOptions l3s(PeerInvisible)", -"lgs_gw.transportCmd l3s(open port="+ LGSL3Port +")", -}; - -DontUseNS = 1; - -Paths = { - ".", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// Where to save specific shard data (ie: player backup), relatively to SaveShardRoot -SaveFilesDirectory = "save_shard/"; - -// where to save generic shard data (ie: packed_sheet) -WriteFilesDirectory = "r2_shard/data_shard"; - -// ---- service custom variables (used by ConfigFile class) - -// Use Shard Unifier or not -DontUseSU = 0; - -HomeMainlandNames = -{ -"302", "Open", "open", -}; - - // ---- service custom variables (used by CVariable class) - -#include "backup_service_interface.cfg" diff --git a/code/ryzom/server/logger_service_default.cfg b/code/ryzom/server/logger_service_default.cfg deleted file mode 100644 index 60d639fe1..000000000 --- a/code/ryzom/server/logger_service_default.cfg +++ /dev/null @@ -1 +0,0 @@ -#include "common.cfg" diff --git a/code/ryzom/server/mail_forum_service.cfg b/code/ryzom/server/mail_forum_service.cfg deleted file mode 100644 index d84cb466c..000000000 --- a/code/ryzom/server/mail_forum_service.cfg +++ /dev/null @@ -1,19 +0,0 @@ -// Use with commandline: mail_forum_service -C. -L. --nobreak --writepid - -#include "mail_forum_service_default.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "mfs"; - -Paths = { - ".", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - - // ---- service custom variables (used by CVariable class) diff --git a/code/ryzom/server/mail_forum_service_default.cfg b/code/ryzom/server/mail_forum_service_default.cfg deleted file mode 100644 index ec2556ec6..000000000 --- a/code/ryzom/server/mail_forum_service_default.cfg +++ /dev/null @@ -1,29 +0,0 @@ -#include "common.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -DontUseNS = 1; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - - -// ---- service custom variables (used by CVariable class) - -WebRootDirectory = "save_shard/www"; - -// Set if Hall of Fame generator is enabled -HoFEnableGenerator = 1; - -// Set if HoF generator is verbose -HoFVerbose = 0; - -// Directory where HDT files are -HoFHDTDirectory = "/local/www/hof/hdt"; - -// HoF generator maximum update period in milliseconds -HoFGeneratorUpdatePeriod = 200; - -// HoF generator directory update period in seconds -HoFGeneratorDirUpdatePeriod = 60; diff --git a/code/ryzom/server/mirror_service.cfg b/code/ryzom/server/mirror_service.cfg deleted file mode 100644 index 6bfaef14f..000000000 --- a/code/ryzom/server/mirror_service.cfg +++ /dev/null @@ -1,35 +0,0 @@ -// Use with commandline: mirror_service -C. -L. --nobreak --writepid - -#include "mirror_service_default.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "ms"; - -GraphVars += { "UserSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - -// MS Packet size limit in bytes, PER DATASET (warning: depending on the weights, limits per property may be very small) -MaxOutBandwidth = 100000000; - - // ---- service custom variables (used by CVariable class) - -// Disable ryzom verbose logging -VerboseMIRROR = 0; diff --git a/code/ryzom/server/mirror_service_default.cfg b/code/ryzom/server/mirror_service_default.cfg deleted file mode 100644 index fc517bbb9..000000000 --- a/code/ryzom/server/mirror_service_default.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#include "common.cfg" - -// ---- service custom variables (used by ConfigFile class) - -// Linux only -DestroyGhostSegments = 1; diff --git a/code/ryzom/server/monitor_service.cfg b/code/ryzom/server/monitor_service.cfg deleted file mode 100644 index 91119f9f5..000000000 --- a/code/ryzom/server/monitor_service.cfg +++ /dev/null @@ -1,38 +0,0 @@ -// Use with commandline: monitor_service -C. -L. --nobreak --writepid - -#include "monitor_service_default.cfg" - -#include "used_continents.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "mos"; - -GraphVars += { "UserSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; - -Paths = { - ".", - "../common/data_common", - "../common/data_leveldesign", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// Mirror limits -DatasetSizefe_temp = 600000; -DatasetSizefame = 26000; - -// MS Packet size limit in bytes, PER DATASET (warning: depending on the weights, limits per property may be very small) -MaxOutBandwidth = 100000000; - - -// ---- service custom variables (used by CVariable class) - -// Disable ryzom verbose logging -VerboseMIRROR = 0; diff --git a/code/ryzom/server/monitor_service_default.cfg b/code/ryzom/server/monitor_service_default.cfg deleted file mode 100644 index 60d639fe1..000000000 --- a/code/ryzom/server/monitor_service_default.cfg +++ /dev/null @@ -1 +0,0 @@ -#include "common.cfg" diff --git a/code/ryzom/server/naming_service.cfg b/code/ryzom/server/naming_service.cfg deleted file mode 100644 index 7acf8316e..000000000 --- a/code/ryzom/server/naming_service.cfg +++ /dev/null @@ -1,21 +0,0 @@ -// Use with commandline: ryzom_naming_service -C. -L. --nobreak --writepid - -#include "naming_service_default.cfg" - -// ---- config local variables - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "rns"; - -Paths = { - "data_www" -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -BasePort = 51000; - - // ---- service custom variables (used by CVariable class) diff --git a/code/ryzom/server/naming_service_default.cfg b/code/ryzom/server/naming_service_default.cfg deleted file mode 100644 index 354f2df3c..000000000 --- a/code/ryzom/server/naming_service_default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -#include "common.cfg" - -SId = 1; -DontUseNS = 1; - -UniqueOnShardServices = {}; // { "EGS", "GPMS", "IOS", "TICKS", "WS", "AIS", "DSS" }; -UniqueByMachineServices = {}; // { "MS" }; diff --git a/code/ryzom/server/save_shard/__read_me.txt b/code/ryzom/server/save_shard/__read_me.txt deleted file mode 100644 index 82a9280f0..000000000 --- a/code/ryzom/server/save_shard/__read_me.txt +++ /dev/null @@ -1,4 +0,0 @@ -Ce repertoire ne doit contenir *que* des fichiers qui sont differents s'il y a plusieurs instance de shard. -C'est le cas par exemple des sauvegardes des joueurs, des guiles, de la date etc... - -ATTENTION: *aucuns* fichiers (sauf le read me) ici ne doivent etre commité dans le cvs car ils sont sauvé dynamiquement et doivent savoir se creer lorsqu'ils n'existent pas. diff --git a/code/ryzom/server/save_shard/rrd_graphs/placeholder b/code/ryzom/server/save_shard/rrd_graphs/placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/code/ryzom/server/session_browser_server.cfg b/code/ryzom/server/session_browser_server.cfg deleted file mode 100644 index 05a05c6e2..000000000 --- a/code/ryzom/server/session_browser_server.cfg +++ /dev/null @@ -1,47 +0,0 @@ -// Use with commandline: session_browser_server -C. -L. --nobreak --writepid - -#include "session_browser_server_default.cfg" - -// ---- config local variables - -#include "sql.cfg" - -SBSPort = 48851; - -SUHost = "localhost"; - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "sbs"; - -StartCommands += -{ -"moduleManager.createModule SessionBrowserServerMod sbs suAddr="+SUHost+":49999 listenPort="+SBSPort+" ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+")", -"sbs.plug gw", -}; - -GraphVars += { "NetSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; - -Paths = { - ".", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// Use Shard Unifier or not -DontUseSU = 0; - -HomeMainlandNames = -{ - "302", "Open", "open", -}; - -// The max number of ring points (aka ring access) for each ecosystem -MaxRingPoints = "A1:D7:F7:J8:L6:R13"; - - -// ---- service custom variables (used by CVariable class) diff --git a/code/ryzom/server/session_browser_server_default.cfg b/code/ryzom/server/session_browser_server_default.cfg deleted file mode 100644 index 60d639fe1..000000000 --- a/code/ryzom/server/session_browser_server_default.cfg +++ /dev/null @@ -1 +0,0 @@ -#include "common.cfg" diff --git a/code/ryzom/server/shard.screen.rc b/code/ryzom/server/shard.screen.rc deleted file mode 100644 index f58dd1371..000000000 --- a/code/ryzom/server/shard.screen.rc +++ /dev/null @@ -1,77 +0,0 @@ -# ------------------------------------------------------------------------------ -# SCREEN KEYBINDINGS -# ------------------------------------------------------------------------------ - -# Remove some stupid / dangerous key bindings -bind ^k -#bind L -bind ^\ -# Make them better -bind \\ quit -bind K kill -bind I login on -bind O login off - -hardstatus alwayslastline "%w" - -chdir $RYZOM_PATH/server - -screen -t aes /bin/sh ../tools/scripts/linux/service_launcher.sh aes $RYZOM_PATH/../build/bin/ryzom_admin_service -A. -C. -L. --nobreak --fulladminname=admin_executor_service --shortadminname=AES - -# bms_master -screen -t bms_master /bin/sh ../tools/scripts/linux/service_launcher.sh bms_master $RYZOM_PATH/../build/bin/ryzom_backup_service -C. -L. --nobreak --writepid -P49990 - -# bms_pd_master -#screen -t bms_pd_master /bin/sh ../tools/scripts/linux/service_launcher.sh bms_pd_master $RYZOM_PATH/../build/bin/ryzom_backup_service -C. -L. --nobreak --writepid -P49992 - -# egs -screen -t egs /bin/sh ../tools/scripts/linux/service_launcher.sh egs $RYZOM_PATH/../build/bin/ryzom_entities_game_service -C. -L. --nobreak --writepid - -# gpms -screen -t gpms /bin/sh ../tools/scripts/linux/service_launcher.sh gpms $RYZOM_PATH/../build/bin/ryzom_gpm_service -C. -L. --nobreak --writepid - -# ios -screen -t ios /bin/sh ../tools/scripts/linux/service_launcher.sh ios $RYZOM_PATH/../build/bin/ryzom_ios_service -C. -L. --nobreak --writepid - -# rns -screen -t rns /bin/sh ../tools/scripts/linux/service_launcher.sh rns $RYZOM_PATH/../build/bin/ryzom_naming_service -C. -L. --nobreak --writepid - -# rws -screen -t rws /bin/sh ../tools/scripts/linux/service_launcher.sh rws $RYZOM_PATH/../build/bin/ryzom_welcome_service -C. -L. --nobreak --writepid - -# ts -screen -t ts /bin/sh ../tools/scripts/linux/service_launcher.sh ts $RYZOM_PATH/../build/bin/ryzom_tick_service -C. -L. --nobreak --writepid - -# ms -screen -t ms /bin/sh ../tools/scripts/linux/service_launcher.sh ms $RYZOM_PATH/../build/bin/ryzom_mirror_service -C. -L. --nobreak --writepid - -# ais_newbyland -screen -t ais_newbyland /bin/sh ../tools/scripts/linux/service_launcher.sh ais_newbyland $RYZOM_PATH/../build/bin/ryzom_ai_service -C. -L. --nobreak --writepid -mCommon:Newbieland:Post - -# mfs -screen -t mfs /bin/sh ../tools/scripts/linux/service_launcher.sh mfs $RYZOM_PATH/../build/bin/ryzom_mail_forum_service -C. -L. --nobreak --writepid - -# su -screen -t su /bin/sh ../tools/scripts/linux/service_launcher.sh su $RYZOM_PATH/../build/bin/ryzom_shard_unifier_service -C. -L. --nobreak --writepid - -# fes -screen -t fes /bin/sh ../tools/scripts/linux/service_launcher.sh fes $RYZOM_PATH/../build/bin/ryzom_frontend_service -C. -L. --nobreak --writepid - -# sbs -screen -t sbs /bin/sh ../tools/scripts/linux/service_launcher.sh sbs $RYZOM_PATH/../build/bin/ryzom_session_browser_service -C. -L. --nobreak --writepid - -# lgs -screen -t lgs /bin/sh ../tools/scripts/linux/service_launcher.sh lgs $RYZOM_PATH/../build/bin/ryzom_logger_service -C. -L. --nobreak --writepid - -# mos -#screen -t mos /bin/sh ../tools/scripts/linux/service_launcher.sh mos $RYZOM_PATH/../build/bin/ryzom_monitor_service -C. -L. --nobreak --writepid - -# pdss -#screen -t pdss /bin/sh ../tools/scripts/linux/service_launcher.sh pdss $RYZOM_PATH/../build/bin/ryzom_pd_support_service -C. -L. --nobreak --writepid - -# ras -screen -t ras /bin/sh ../tools/scripts/linux/service_launcher.sh ras $RYZOM_PATH/../build/bin/ryzom_admin_service --fulladminname=admin_service --shortadminname=AS -C. -L. --nobreak --writepid - -# switch back to AES screen -select 0 - diff --git a/code/ryzom/server/shard_unifier_service.cfg b/code/ryzom/server/shard_unifier_service.cfg deleted file mode 100644 index 9b37f063b..000000000 --- a/code/ryzom/server/shard_unifier_service.cfg +++ /dev/null @@ -1,50 +0,0 @@ -// Use with commandline: shard_unifier_service -C. -L. --nobreak --writepid - -// ---- config local variables - -SUGlobalPort = 50503; - -#include "sql.cfg" - -#include "shard_unifier_service_default.cfg" - -// ---- service NeL variables (used by ConfigFile class) - -AESAliasName= "su"; - -// Create a command executor -StartCommands += -{ -"moduleManager.createModule CommandExecutor ce", -"ce.plug gw", -}; - -GraphVars += { "TotalConcurentUser", "60000" }; -GraphVars += { "NetSpeedLoop", "60000" }; -GraphVars += { "L5CallbackCount", "60000" }; -GraphVars += { "L5CallbackTime", "60000" }; - -Paths = { - ".", -}; - -// ---- service NeL variables (used by CVariable class) - -// ---- service custom variables (used by ConfigFile class) - -// Use Shard Unifier or not -DontUseSU = 0; - -HomeMainlandNames = -{ -"302", "Open", "open", -}; - - // ---- service custom variables (used by CVariable class) - -DomainName = "ryzom_open"; - -// The privileges needed to access any ring session -PrivilegeForSessionAccess = ":DEV:SGM:GM:SG:"; - -#include "backup_service_interface.cfg" diff --git a/code/ryzom/server/shard_unifier_service_default.cfg b/code/ryzom/server/shard_unifier_service_default.cfg deleted file mode 100644 index a46bf0d95..000000000 --- a/code/ryzom/server/shard_unifier_service_default.cfg +++ /dev/null @@ -1,33 +0,0 @@ -#include "common.cfg" - -DontUseNS = 1; - -StartCommands += -{ - // Create a gateway for global interconnection - // modules from different shard are visible to each other if they connect to - // this gateway. SU Local module have no interest to be plugged here. - "moduleManager.createModule StandardGateway glob_gw", - // add a layer 3 server transport - "glob_gw.transportAdd L3Server l3s", - // open the transport - "glob_gw.transportCmd l3s(open port="+SUGlobalPort+")", - // Create a session manager module - "moduleManager.createModule RingSessionManager rsm web(port=49999) ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+") nel_db(host="+DBHost+" user="+DBNelUser+" password="+DBNelPass+" base="+DBNelName+")", - "rsm.plug gw", - // Create a login service module - "moduleManager.createModule LoginService ls ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+") web(port=49998) nel_db(host="+DBHost+" user="+DBNelUser+" password="+DBNelPass+" base="+DBNelName+")", - "ls.plug gw", - // Create a character synchronization module - "moduleManager.createModule CharacterSynchronisation cs fake_edit_char ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+")", - "cs.plug gw", - // Create entity locator module - "moduleManager.createModule EntityLocator el ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+") nel_db(host="+DBHost+" user="+DBNelUser+" password="+DBNelPass+" base="+DBNelName+")", - "el.plug gw", - // Create a mail forum notifier forwarder - "moduleManager.createModule MailForumNotifierFwd mfnfwd ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+") web(port=49897)", - "mfnfwd.plug gw", - // Create a chat unifier server module - "moduleManager.createModule ChatUnifierServer cus ring_db(host="+DBHost+" user="+DBRingUser+" password="+DBRingPass+" base="+DBRingName+")", - "cus.plug gw", -}; diff --git a/code/ryzom/server/sql.cfg b/code/ryzom/server/sql.cfg deleted file mode 100644 index e782d7618..000000000 --- a/code/ryzom/server/sql.cfg +++ /dev/null @@ -1,14 +0,0 @@ -DBHost = "localhost"; -DBNelName = "nel"; -DBRingName = "ring_open"; -// Nel DB user -DBNelUser = "shard"; -// Ring DB user -DBRingUser = "shard"; -// SU - password to access to the nel database with DBNelUseruser (default is no password) -DBNelPass = ""; -// SU - password to access to the ring database with DBRingUser (default is no password) -DBRingPass = ""; - -// MySQL wrapper strict mode - controls use of asserts if SQL requests fail -MSWStrictMode=0; diff --git a/code/ryzom/server/src/CMakeLists.txt b/code/ryzom/server/src/CMakeLists.txt deleted file mode 100644 index fc91decc4..000000000 --- a/code/ryzom/server/src/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -# Supporting modules and libraries. -# Need servershare for build packed collision tool -# Need aishare for build wmap tool -IF(WITH_RYZOM_TOOLS OR WITH_RYZOM_SERVER) - ADD_SUBDIRECTORY(server_share) - ADD_SUBDIRECTORY(ai_share) -ENDIF() - -IF(WITH_RYZOM_SERVER) - -# Supporting modules and libraries. -ADD_SUBDIRECTORY(admin_modules) -ADD_SUBDIRECTORY(gameplay_module_lib) -ADD_SUBDIRECTORY(pd_lib) - -# Ryzom Services -ADD_SUBDIRECTORY(ai_service) -ADD_SUBDIRECTORY(backup_service) -ADD_SUBDIRECTORY(dynamic_scenario_service) -ADD_SUBDIRECTORY(entities_game_service) -ADD_SUBDIRECTORY(frontend_service) -ADD_SUBDIRECTORY(gpm_service) -ADD_SUBDIRECTORY(input_output_service) -ADD_SUBDIRECTORY(ryzom_admin_service) -ADD_SUBDIRECTORY(ryzom_naming_service) -ADD_SUBDIRECTORY(ryzom_welcome_service) -ADD_SUBDIRECTORY(log_analyser_service) -ADD_SUBDIRECTORY(logger_service) -ADD_SUBDIRECTORY(mail_forum_service) -ADD_SUBDIRECTORY(mirror_service) -ADD_SUBDIRECTORY(monitor_service) -ADD_SUBDIRECTORY(pd_reference_builder) -ADD_SUBDIRECTORY(pd_support_service) -ADD_SUBDIRECTORY(persistant_data_service) -ADD_SUBDIRECTORY(session_browser_server) -ADD_SUBDIRECTORY(shard_unifier_service) -ADD_SUBDIRECTORY(tick_service) -ADD_SUBDIRECTORY(patchman_service) - - -# Deprecated, no longer used. -#ADD_SUBDIRECTORY(ags_test) -#ADD_SUBDIRECTORY(ai_data_service) -#ADD_SUBDIRECTORY(entity_view_service) -ADD_SUBDIRECTORY(general_utilities_service) - -# Not sure, no longer used maybe? -#sabrina -#simulation_service -#testing_tool_service - -ENDIF() diff --git a/code/ryzom/server/src/admin_modules/CMakeLists.txt b/code/ryzom/server/src/admin_modules/CMakeLists.txt deleted file mode 100644 index a47ec1037..000000000 --- a/code/ryzom/server/src/admin_modules/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -FILE(GLOB SRC *.cpp *.h) - -NL_TARGET_LIB(ryzom_adminmodules ${SRC}) - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -TARGET_LINK_LIBRARIES(ryzom_adminmodules nelmisc nelnet) -NL_DEFAULT_PROPS(ryzom_adminmodules "Ryzom, Library: Service Admin Modules") -NL_ADD_RUNTIME_FLAGS(ryzom_adminmodules) -NL_ADD_LIB_SUFFIX(ryzom_adminmodules) - -IF(WITH_PCH) - ADD_NATIVE_PRECOMPILED_HEADER(ryzom_adminmodules ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) -ENDIF() - -IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC) - INSTALL(TARGETS ryzom_adminmodules LIBRARY DESTINATION ${RYZOM_LIB_PREFIX} ARCHIVE DESTINATION ${RYZOM_LIB_PREFIX} COMPONENT libraries) -ENDIF() - diff --git a/code/ryzom/server/src/admin_modules/admin_modules.cpp b/code/ryzom/server/src/admin_modules/admin_modules.cpp deleted file mode 100644 index a3402c12e..000000000 --- a/code/ryzom/server/src/admin_modules/admin_modules.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -/** This file declare a pure nel module library */ - - -#include "nel/net/module_manager.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; - -extern void as_forceLink(); -extern void aes_forceLink(); -extern void aesclient_forceLink(); - -void admin_modules_forceLink() -{ - as_forceLink(); - aes_forceLink(); - aesclient_forceLink(); -} - -//NLMISC_DECL_PURE_LIB(CNelModuleLibrary); - diff --git a/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp b/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp deleted file mode 100644 index 39dfc6948..000000000 --- a/code/ryzom/server/src/admin_modules/admin_modules_itf.cpp +++ /dev/null @@ -1,731 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -///////////////////////////////////////////////////////////////// -// WARNING : this is a generated file, don't change it ! -///////////////////////////////////////////////////////////////// - -#include "stdpch.h" -#include "admin_modules_itf.h" - -namespace ADMIN -{ - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - - const CAdminServiceSkel::TMessageHandlerMap &CAdminServiceSkel::getMessageHandlers() const - { - static TMessageHandlerMap handlers; - static bool init = false; - - if (!init) - { - std::pair < TMessageHandlerMap::iterator, bool > res; - - res = handlers.insert(std::make_pair(std::string("USU"), &CAdminServiceSkel::upServiceUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("GU"), &CAdminServiceSkel::graphUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("HRGU"), &CAdminServiceSkel::highRezGraphUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("CR"), &CAdminServiceSkel::commandResult_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - init = true; - } - - return handlers; - } - bool CAdminServiceSkel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message) - { - const TMessageHandlerMap &mh = getMessageHandlers(); - - TMessageHandlerMap::const_iterator it(mh.find(message.getName())); - - if (it == mh.end()) - { - return false; - } - - TMessageHandler cmd = it->second; - (this->*cmd)(sender, message); - - return true; - } - - - void CAdminServiceSkel::upServiceUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminServiceSkel_upServiceUpdate_USU); - std::vector < TServiceStatus > serviceStatus; - nlRead(__message, serialCont, serviceStatus); - upServiceUpdate(sender, serviceStatus); - } - - void CAdminServiceSkel::graphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminServiceSkel_graphUpdate_GU); - TGraphDatas graphDatas; - nlRead(__message, serial, graphDatas); - graphUpdate(sender, graphDatas); - } - - void CAdminServiceSkel::highRezGraphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminServiceSkel_highRezGraphUpdate_HRGU); - THighRezDatas graphDatas; - nlRead(__message, serial, graphDatas); - highRezGraphUpdate(sender, graphDatas); - } - - void CAdminServiceSkel::commandResult_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminServiceSkel_commandResult_CR); - uint32 commandId; - nlRead(__message, serial, commandId); - std::string serviceAlias; - nlRead(__message, serial, serviceAlias); - std::string result; - nlRead(__message, serial, result); - commandResult(sender, commandId, serviceAlias, result); - } - // An AES send an update of the list of service up - void CAdminServiceProxy::upServiceUpdate(NLNET::IModule *sender, const std::vector < TServiceStatus > &serviceStatus) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->upServiceUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), serviceStatus); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_upServiceUpdate(__message, serviceStatus); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // An AES send graph data update - void CAdminServiceProxy::graphUpdate(NLNET::IModule *sender, const TGraphDatas &graphDatas) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->graphUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), graphDatas); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_graphUpdate(__message, graphDatas); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // An AES send high rez graph data update - void CAdminServiceProxy::highRezGraphUpdate(NLNET::IModule *sender, const THighRezDatas &graphDatas) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->highRezGraphUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), graphDatas); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_highRezGraphUpdate(__message, graphDatas); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // AES send back the result of execution of a command - void CAdminServiceProxy::commandResult(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->commandResult(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), commandId, serviceAlias, result); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_commandResult(__message, commandId, serviceAlias, result); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminServiceProxy::buildMessageFor_upServiceUpdate(NLNET::CMessage &__message, const std::vector < TServiceStatus > &serviceStatus) - { - __message.setType("USU"); - nlWrite(__message, serialCont, const_cast < std::vector < TServiceStatus >& > (serviceStatus)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminServiceProxy::buildMessageFor_graphUpdate(NLNET::CMessage &__message, const TGraphDatas &graphDatas) - { - __message.setType("GU"); - nlWrite(__message, serial, const_cast < TGraphDatas& > (graphDatas)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminServiceProxy::buildMessageFor_highRezGraphUpdate(NLNET::CMessage &__message, const THighRezDatas &graphDatas) - { - __message.setType("HRGU"); - nlWrite(__message, serial, const_cast < THighRezDatas& > (graphDatas)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminServiceProxy::buildMessageFor_commandResult(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &result) - { - __message.setType("CR"); - nlWrite(__message, serial, commandId); - nlWrite(__message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(__message, serial, const_cast < std::string& > (result)); - - - return __message; - } - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - - const CAdminExecutorServiceSkel::TMessageHandlerMap &CAdminExecutorServiceSkel::getMessageHandlers() const - { - static TMessageHandlerMap handlers; - static bool init = false; - - if (!init) - { - std::pair < TMessageHandlerMap::iterator, bool > res; - - res = handlers.insert(std::make_pair(std::string("SCO"), &CAdminExecutorServiceSkel::setShardOrders_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("SDS"), &CAdminExecutorServiceSkel::shutdownShard_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("CC"), &CAdminExecutorServiceSkel::controlCmd_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("SCMD"), &CAdminExecutorServiceSkel::serviceCmd_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("CR"), &CAdminExecutorServiceSkel::commandResult_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("GU"), &CAdminExecutorServiceSkel::graphUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("HRGU"), &CAdminExecutorServiceSkel::highRezGraphUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("SSU"), &CAdminExecutorServiceSkel::serviceStatusUpdate_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - init = true; - } - - return handlers; - } - bool CAdminExecutorServiceSkel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message) - { - const TMessageHandlerMap &mh = getMessageHandlers(); - - TMessageHandlerMap::const_iterator it(mh.find(message.getName())); - - if (it == mh.end()) - { - return false; - } - - TMessageHandler cmd = it->second; - (this->*cmd)(sender, message); - - return true; - } - - - void CAdminExecutorServiceSkel::setShardOrders_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_setShardOrders_SCO); - std::string shardName; - nlRead(__message, serial, shardName); - TShardOrders shardOrders; - nlRead(__message, serial, shardOrders); - setShardOrders(sender, shardName, shardOrders); - } - - void CAdminExecutorServiceSkel::shutdownShard_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_shutdownShard_SDS); - std::string shardName; - nlRead(__message, serial, shardName); - uint32 delay; - nlRead(__message, serial, delay); - shutdownShard(sender, shardName, delay); - } - - void CAdminExecutorServiceSkel::controlCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_controlCmd_CC); - uint32 commandId; - nlRead(__message, serial, commandId); - std::string serviceAlias; - nlRead(__message, serial, serviceAlias); - std::string command; - nlRead(__message, serial, command); - controlCmd(sender, commandId, serviceAlias, command); - } - - void CAdminExecutorServiceSkel::serviceCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_serviceCmd_SCMD); - uint32 commandId; - nlRead(__message, serial, commandId); - std::string serviceAlias; - nlRead(__message, serial, serviceAlias); - std::string command; - nlRead(__message, serial, command); - serviceCmd(sender, commandId, serviceAlias, command); - } - - void CAdminExecutorServiceSkel::commandResult_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_commandResult_CR); - uint32 commandId; - nlRead(__message, serial, commandId); - std::string serviceAlias; - nlRead(__message, serial, serviceAlias); - std::string result; - nlRead(__message, serial, result); - commandResult(sender, commandId, serviceAlias, result); - } - - void CAdminExecutorServiceSkel::graphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_graphUpdate_GU); - TGraphDatas graphDatas; - nlRead(__message, serial, graphDatas); - graphUpdate(sender, graphDatas); - } - - void CAdminExecutorServiceSkel::highRezGraphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_highRezGraphUpdate_HRGU); - THighRezDatas graphDatas; - nlRead(__message, serial, graphDatas); - highRezGraphUpdate(sender, graphDatas); - } - - void CAdminExecutorServiceSkel::serviceStatusUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceSkel_serviceStatusUpdate_SSU); - std::string status; - nlRead(__message, serial, status); - serviceStatusUpdate(sender, status); - } - // AS send orders for a shard - void CAdminExecutorServiceProxy::setShardOrders(NLNET::IModule *sender, const std::string &shardName, const TShardOrders &shardOrders) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->setShardOrders(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), shardName, shardOrders); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_setShardOrders(__message, shardName, shardOrders); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // AS send a command to shutdown a shard with a delay - void CAdminExecutorServiceProxy::shutdownShard(NLNET::IModule *sender, const std::string &shardName, uint32 delay) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->shutdownShard(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), shardName, delay); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_shutdownShard(__message, shardName, delay); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // AS send a control command to this AES - void CAdminExecutorServiceProxy::controlCmd(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->controlCmd(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), commandId, serviceAlias, command); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_controlCmd(__message, commandId, serviceAlias, command); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // Send a command to a service. - void CAdminExecutorServiceProxy::serviceCmd(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->serviceCmd(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), commandId, serviceAlias, command); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_serviceCmd(__message, commandId, serviceAlias, command); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // AES client send back the result of execution of a command - void CAdminExecutorServiceProxy::commandResult(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->commandResult(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), commandId, serviceAlias, result); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_commandResult(__message, commandId, serviceAlias, result); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // A service send graph data update - void CAdminExecutorServiceProxy::graphUpdate(NLNET::IModule *sender, const TGraphDatas &graphDatas) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->graphUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), graphDatas); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_graphUpdate(__message, graphDatas); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // A service high rez graph data update - void CAdminExecutorServiceProxy::highRezGraphUpdate(NLNET::IModule *sender, const THighRezDatas &graphDatas) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->highRezGraphUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), graphDatas); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_highRezGraphUpdate(__message, graphDatas); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // A service send an update of of it's status string - void CAdminExecutorServiceProxy::serviceStatusUpdate(NLNET::IModule *sender, const std::string &status) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->serviceStatusUpdate(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), status); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_serviceStatusUpdate(__message, status); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_setShardOrders(NLNET::CMessage &__message, const std::string &shardName, const TShardOrders &shardOrders) - { - __message.setType("SCO"); - nlWrite(__message, serial, const_cast < std::string& > (shardName)); - nlWrite(__message, serial, shardOrders); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_shutdownShard(NLNET::CMessage &__message, const std::string &shardName, uint32 delay) - { - __message.setType("SDS"); - nlWrite(__message, serial, const_cast < std::string& > (shardName)); - nlWrite(__message, serial, delay); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_controlCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - __message.setType("CC"); - nlWrite(__message, serial, commandId); - nlWrite(__message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(__message, serial, const_cast < std::string& > (command)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_serviceCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - __message.setType("SCMD"); - nlWrite(__message, serial, commandId); - nlWrite(__message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(__message, serial, const_cast < std::string& > (command)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_commandResult(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &result) - { - __message.setType("CR"); - nlWrite(__message, serial, commandId); - nlWrite(__message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(__message, serial, const_cast < std::string& > (result)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_graphUpdate(NLNET::CMessage &__message, const TGraphDatas &graphDatas) - { - __message.setType("GU"); - nlWrite(__message, serial, const_cast < TGraphDatas& > (graphDatas)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_highRezGraphUpdate(NLNET::CMessage &__message, const THighRezDatas &graphDatas) - { - __message.setType("HRGU"); - nlWrite(__message, serial, const_cast < THighRezDatas& > (graphDatas)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceProxy::buildMessageFor_serviceStatusUpdate(NLNET::CMessage &__message, const std::string &status) - { - __message.setType("SSU"); - nlWrite(__message, serial, const_cast < std::string& > (status)); - - - return __message; - } - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - - const CAdminExecutorServiceClientSkel::TMessageHandlerMap &CAdminExecutorServiceClientSkel::getMessageHandlers() const - { - static TMessageHandlerMap handlers; - static bool init = false; - - if (!init) - { - std::pair < TMessageHandlerMap::iterator, bool > res; - - res = handlers.insert(std::make_pair(std::string("SCMD"), &CAdminExecutorServiceClientSkel::serviceCmd_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - res = handlers.insert(std::make_pair(std::string("SCMDNR"), &CAdminExecutorServiceClientSkel::serviceCmdNoReturn_skel)); - // if this assert, you have a doubly message name in your interface definition ! - nlassert(res.second); - - init = true; - } - - return handlers; - } - bool CAdminExecutorServiceClientSkel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message) - { - const TMessageHandlerMap &mh = getMessageHandlers(); - - TMessageHandlerMap::const_iterator it(mh.find(message.getName())); - - if (it == mh.end()) - { - return false; - } - - TMessageHandler cmd = it->second; - (this->*cmd)(sender, message); - - return true; - } - - - void CAdminExecutorServiceClientSkel::serviceCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceClientSkel_serviceCmd_SCMD); - uint32 commandId; - nlRead(__message, serial, commandId); - std::string command; - nlRead(__message, serial, command); - serviceCmd(sender, commandId, command); - } - - void CAdminExecutorServiceClientSkel::serviceCmdNoReturn_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message) - { - H_AUTO(CAdminExecutorServiceClientSkel_serviceCmdNoReturn_SCMDNR); - std::string command; - nlRead(__message, serial, command); - serviceCmdNoReturn(sender, command); - } - // execute a command and return the result. - void CAdminExecutorServiceClientProxy::serviceCmd(NLNET::IModule *sender, uint32 commandId, const std::string &command) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->serviceCmd(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), commandId, command); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_serviceCmd(__message, commandId, command); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - // Send a command to a service without waiting for the return value. - void CAdminExecutorServiceClientProxy::serviceCmdNoReturn(NLNET::IModule *sender, const std::string &command) - { - if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported()) - { - // immediate local synchronous dispatching - _LocalModuleSkel->serviceCmdNoReturn(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), command); - } - else - { - // send the message for remote dispatching and execution or local queing - NLNET::CMessage __message; - - buildMessageFor_serviceCmdNoReturn(__message, command); - - _ModuleProxy->sendModuleMessage(sender, __message); - } - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceClientProxy::buildMessageFor_serviceCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &command) - { - __message.setType("SCMD"); - nlWrite(__message, serial, commandId); - nlWrite(__message, serial, const_cast < std::string& > (command)); - - - return __message; - } - - // Message serializer. Return the message received in reference for easier integration - const NLNET::CMessage &CAdminExecutorServiceClientProxy::buildMessageFor_serviceCmdNoReturn(NLNET::CMessage &__message, const std::string &command) - { - __message.setType("SCMDNR"); - nlWrite(__message, serial, const_cast < std::string& > (command)); - - - return __message; - } - -} diff --git a/code/ryzom/server/src/admin_modules/admin_modules_itf.h b/code/ryzom/server/src/admin_modules/admin_modules_itf.h deleted file mode 100644 index 8c25790e7..000000000 --- a/code/ryzom/server/src/admin_modules/admin_modules_itf.h +++ /dev/null @@ -1,2304 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -///////////////////////////////////////////////////////////////// -// WARNING : this is a generated file, don't change it ! -///////////////////////////////////////////////////////////////// - -#ifndef ADMIN_MODULES_ITF -#define ADMIN_MODULES_ITF -#include "nel/misc/types_nl.h" -#include -#include "nel/misc/hierarchical_timer.h" -#include "nel/misc/string_conversion.h" -#include "nel/net/message.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" -#include "nel/net/module_message.h" -#include "nel/net/module_gateway.h" - -#include "game_share/callback_adaptor.h" - -#include "nel/misc/time_nl.h" - -namespace ADMIN -{ - - class TGraphData; - - class TGraphDatas; - - class THighRezData; - - class THighRezDatas; - - class TServiceStatus; - - // This is the interface used by PHP to call methods - // on the Admin service module - - class CAdminServiceWebItf - { - protected: - - /// the callback server adaptor - CUniquePtr _CallbackServer; - - void getCallbakArray(NLNET::TCallbackItem *&arrayPtr, uint32 &arraySize) - { - static NLNET::TCallbackItem callbackArray[] = - { - { "GCMD", CAdminServiceWebItf::cb_globalCmd }, - { "CCMD", CAdminServiceWebItf::cb_controlCmd }, - { "SCMD", CAdminServiceWebItf::cb_serviceCmd }, - { "GSO", CAdminServiceWebItf::cb_getShardOrders }, - { "GS", CAdminServiceWebItf::cb_getStates }, - { "GHRGI", CAdminServiceWebItf::cb_getHighRezGraphInfo }, - { "GHRG", CAdminServiceWebItf::cb_getHighRezGraph }, - - }; - - arrayPtr = callbackArray; - arraySize = sizeofarray(callbackArray); - } - - static void _cbConnection(NLNET::TSockId from, void *arg) - { - H_AUTO(CAdminServiceWeb__cbConnection); - CAdminServiceWebItf *_this = reinterpret_cast(arg); - - _this->on_CAdminServiceWeb_Connection(from); - } - - static void _cbDisconnection(NLNET::TSockId from, void *arg) - { - H_AUTO(CAdminServiceWeb__cbDisconnection); - CAdminServiceWebItf *_this = reinterpret_cast(arg); - - _this->on_CAdminServiceWeb_Disconnection(from); - } - - - public: - /** Constructor, if you specify a replacement adaptor, then the object - * become owner of the adaptor (and it will be released with the - * interface). - */ - CAdminServiceWebItf(ICallbackServerAdaptor *replacementAdaptor = NULL) - { - if (replacementAdaptor == NULL) - { - // use default callback server - _CallbackServer = CUniquePtr(new CNelCallbackServerAdaptor(this)); - } - else - { - // use the replacement one - _CallbackServer = CUniquePtr(replacementAdaptor); - } - } - - virtual ~CAdminServiceWebItf() - { - } - - /// Open the interface socket in the specified port - void openItf(uint16 port) - { - NLNET::TCallbackItem *arrayPtr; - uint32 arraySize; - - - - getCallbakArray(arrayPtr, arraySize); - _CallbackServer->addCallbackArray(arrayPtr, arraySize); - - _CallbackServer->setConnectionCallback (_cbConnection, this); - _CallbackServer->setDisconnectionCallback (_cbDisconnection, this); - - _CallbackServer->init(port); - } - - /** Must be called evenly, update the network subclass to receive message - * and dispatch method invokation. - */ - void update() - { - H_AUTO(CAdminServiceWeb_update); - - try - { - _CallbackServer->update(); - } - catch (...) - { - nlwarning("CAdminServiceWeb : Exception launch in callback server update"); - } - } - - - void commandResult(NLNET::TSockId dest, const std::string &serviceAlias, const std::string &result) - { - H_AUTO(commandResult_commandResult); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::commandResult called"); -#endif - NLNET::CMessage message("CMDR"); - nlWrite(message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(message, serial, const_cast < std::string& > (result)); - - _CallbackServer->send(message, dest); - } - - static void cb_globalCmd (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(globalCmd_on_globalCmd); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_globalCmd received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string command; - nlRead(message, serial, command); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_globalCmd : calling on_globalCmd"); -#endif - - - callback->on_globalCmd(from, command); - - } - - static void cb_controlCmd (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(controlCmd_on_controlCmd); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_controlCmd received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string serviceAlias; - std::string command; - nlRead(message, serial, serviceAlias); - nlRead(message, serial, command); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_controlCmd : calling on_controlCmd"); -#endif - - - callback->on_controlCmd(from, serviceAlias, command); - - } - - static void cb_serviceCmd (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(serviceCmd_on_serviceCmd); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_serviceCmd received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string serviceAlias; - std::string command; - nlRead(message, serial, serviceAlias); - nlRead(message, serial, command); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_serviceCmd : calling on_serviceCmd"); -#endif - - - callback->on_serviceCmd(from, serviceAlias, command); - - } - - static void cb_getShardOrders (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(getShardOrders_on_getShardOrders); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getShardOrders received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getShardOrders : calling on_getShardOrders"); -#endif - - std::vector retValue; - - retValue = callback->on_getShardOrders(from); - - NLNET::CMessage retMsg("R_GSO"); - - nlWrite(retMsg, serialCont, retValue); - - - callback->_CallbackServer->send(retMsg, from); - - } - - static void cb_getStates (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(getStates_on_getStates); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getStates received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getStates : calling on_getStates"); -#endif - - std::vector retValue; - - retValue = callback->on_getStates(from); - - NLNET::CMessage retMsg("R_GS"); - - nlWrite(retMsg, serialCont, retValue); - - - callback->_CallbackServer->send(retMsg, from); - - } - - static void cb_getHighRezGraphInfo (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(getHighRezGraphInfo_on_getHighRezGraphInfo); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getHighRezGraphInfo received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string varAddr; - nlRead(message, serial, varAddr); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getHighRezGraphInfo : calling on_getHighRezGraphInfo"); -#endif - - std::vector retValue; - - retValue = callback->on_getHighRezGraphInfo(from, varAddr); - - NLNET::CMessage retMsg("R_GHRGI"); - - nlWrite(retMsg, serialCont, retValue); - - - callback->_CallbackServer->send(retMsg, from); - - } - - static void cb_getHighRezGraph (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { - H_AUTO(getHighRezGraph_on_getHighRezGraph); -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getHighRezGraph received from class '%s'", typeid(netbase).name()); -#endif - ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData()); - - CAdminServiceWebItf *callback = (CAdminServiceWebItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string varAddr; - uint32 startDate; - uint32 endDate; - uint32 milliStep; - nlRead(message, serial, varAddr); - nlRead(message, serial, startDate); - nlRead(message, serial, endDate); - nlRead(message, serial, milliStep); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWeb::cb_getHighRezGraph : calling on_getHighRezGraph"); -#endif - - std::vector retValue; - - retValue = callback->on_getHighRezGraph(from, varAddr, startDate, endDate, milliStep); - - NLNET::CMessage retMsg("R_GHRG"); - - nlWrite(retMsg, serialCont, retValue); - - - callback->_CallbackServer->send(retMsg, from); - - } - - - /// Connection callback : a new interface client connect - virtual void on_CAdminServiceWeb_Connection(NLNET::TSockId from) =0; - /// Disconnection callback : one of the interface client disconnect - virtual void on_CAdminServiceWeb_Disconnection(NLNET::TSockId from) =0; - - - // Send a command to the AS. - // This is used to issue global commands like 'as.allStart' or 'as.allStop'. - // The result is returned by the return message - // serviceCmdResult. - virtual void on_globalCmd(NLNET::TSockId from, const std::string &command) =0; - - // Send a service related command to the executor - // (not to the controled service) - // The result is returned by the return message - // controlCmdResult. - virtual void on_controlCmd(NLNET::TSockId from, const std::string &serviceAlias, const std::string &command) =0; - - // Send a command to a service. - // The result is returned by the return message - // serviceCmdResult. - virtual void on_serviceCmd(NLNET::TSockId from, const std::string &serviceAlias, const std::string &command) =0; - - // Get the orders of each known shard. - // The return value is a vector of string, one entry by shard - virtual std::vector on_getShardOrders(NLNET::TSockId from) =0; - - // Get the last known state of all services. - // The return value is a vector of string, one entry by service - virtual std::vector on_getStates(NLNET::TSockId from) =0; - - // Get information about a high rez graph. - // The return is a string array containing - // the name of the var, the available sample - // period as two unix date (start dans end) - // and the number of samples available - // If the var is not found, an empty array is returned - virtual std::vector on_getHighRezGraphInfo(NLNET::TSockId from, const std::string &varAddr) =0; - - // Get the data for a high resolution graph. - // The return is a string array, each - // string containing 'time:milliOffset:value - // Set endDate to 0 to specify a start date relative - // to the last sample date. In this case, start date - // is interpreted as the number of second before - // the last sample. - virtual std::vector on_getHighRezGraph(NLNET::TSockId from, const std::string &varAddr, uint32 startDate, uint32 endDate, uint32 milliStep) =0; - - }; - - // This is the interface used by PHP to call methods - // on the Admin service module - - /** This is the client side of the interface - * Derive from this class to invoke method on the callback server - */ - - class CAdminServiceWebClientItf - { - protected: - - /// the callback client adaptor - CUniquePtr < ICallbackClientAdaptor > _CallbackClient; - - - void getCallbakArray(NLNET::TCallbackItem *&arrayPtr, uint32 &arraySize) - { - - static NLNET::TCallbackItem callbackArray[] = - { - { "CMDR", CAdminServiceWebClientItf::cb_commandResult }, - - }; - - arrayPtr = callbackArray; - arraySize = sizeofarray(callbackArray); - - } - - static void _cbDisconnection(NLNET::TSockId from, void *arg) - { - CAdminServiceWebClientItf *_this = reinterpret_cast(arg); - - _this->on_CAdminServiceWebClient_Disconnection(from); - } - - - public: - /// Retreive the message name for a given callback name - static const std::string &getMessageName(const std::string &methodName) - { - static std::map messageNames; - static bool initialized = false; - if (!initialized) - { - messageNames.insert(std::make_pair(std::string("on_commandResult"), std::string("CMDR"))); - - initialized = true; - } - - std::map < std::string, std::string>::const_iterator it(messageNames.find(methodName)); - if (it != messageNames.end()) - return it->second; - - - static std::string emptyString; - - return emptyString; - - } - - CAdminServiceWebClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL) - { - if (adaptorReplacement == NULL) - { - // use the default Nel adaptor - _CallbackClient = CUniquePtr < ICallbackClientAdaptor >(new CNelCallbackClientAdaptor(this)); - } - else - { - // use the replacement one - _CallbackClient = CUniquePtr < ICallbackClientAdaptor >(adaptorReplacement); - } - } - - /// Connect the interface client to the callback server at the specified address and port - virtual void connectItf(NLNET::CInetAddress address) - { - NLNET::TCallbackItem *arrayPtr; - uint32 arraySize; - - static bool callbackAdded = false; - if (!callbackAdded) - { - - getCallbakArray(arrayPtr, arraySize); - _CallbackClient->addCallbackArray(arrayPtr, arraySize); - } - - _CallbackClient->setDisconnectionCallback (_cbDisconnection, this); - - _CallbackClient->connect(address); - } - - /** Must be called evenly, update the network subclass to receive message - * and dispatch invokation returns. - */ - virtual void update() - { - H_AUTO(CAdminServiceWeb_update); - - try - { - _CallbackClient->update(); - } - catch (...) - { - nlwarning("CAdminServiceWeb : Exception launch in callback client update"); - } - } - - // Send a command to the AS. - // This is used to issue global commands like 'as.allStart' or 'as.allStop'. - // The result is returned by the return message - // serviceCmdResult. - - void globalCmd(const std::string &command) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::globalCmd called"); -#endif - NLNET::CMessage message("GCMD"); - nlWrite(message, serial, const_cast < std::string& > (command)); - - _CallbackClient->send(message); - } - // Send a service related command to the executor - // (not to the controled service) - // The result is returned by the return message - // controlCmdResult. - - void controlCmd(const std::string &serviceAlias, const std::string &command) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::controlCmd called"); -#endif - NLNET::CMessage message("CCMD"); - nlWrite(message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(message, serial, const_cast < std::string& > (command)); - - _CallbackClient->send(message); - } - // Send a command to a service. - // The result is returned by the return message - // serviceCmdResult. - - void serviceCmd(const std::string &serviceAlias, const std::string &command) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::serviceCmd called"); -#endif - NLNET::CMessage message("SCMD"); - nlWrite(message, serial, const_cast < std::string& > (serviceAlias)); - nlWrite(message, serial, const_cast < std::string& > (command)); - - _CallbackClient->send(message); - } - // Get the orders of each known shard. - // The return value is a vector of string, one entry by shard - - void getShardOrders() - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::getShardOrders called"); -#endif - NLNET::CMessage message("GSO"); - - _CallbackClient->send(message); - } - // Get the last known state of all services. - // The return value is a vector of string, one entry by service - - void getStates() - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::getStates called"); -#endif - NLNET::CMessage message("GS"); - - _CallbackClient->send(message); - } - // Get information about a high rez graph. - // The return is a string array containing - // the name of the var, the available sample - // period as two unix date (start dans end) - // and the number of samples available - // If the var is not found, an empty array is returned - - void getHighRezGraphInfo(const std::string &varAddr) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::getHighRezGraphInfo called"); -#endif - NLNET::CMessage message("GHRGI"); - nlWrite(message, serial, const_cast < std::string& > (varAddr)); - - _CallbackClient->send(message); - } - // Get the data for a high resolution graph. - // The return is a string array, each - // string containing 'time:milliOffset:value - // Set endDate to 0 to specify a start date relative - // to the last sample date. In this case, start date - // is interpreted as the number of second before - // the last sample. - - void getHighRezGraph(const std::string &varAddr, uint32 startDate, uint32 endDate, uint32 milliStep) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::getHighRezGraph called"); -#endif - NLNET::CMessage message("GHRG"); - nlWrite(message, serial, const_cast < std::string& > (varAddr)); - nlWrite(message, serial, startDate); - nlWrite(message, serial, endDate); - nlWrite(message, serial, milliStep); - - _CallbackClient->send(message); - } - - static void cb_commandResult (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase) - { -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::cb_commandResult received from class '%s'", typeid(netbase).name()); -#endif - ICallbackClientAdaptor *adaptor = static_cast< ICallbackClientAdaptor *>(netbase.getUserData()); - - CAdminServiceWebClientItf *callback = (CAdminServiceWebClientItf *)adaptor->getContainerClass(); - - if (callback == NULL) - return; - std::string serviceAlias; - std::string result; - nlRead(message, serial, serviceAlias); - nlRead(message, serial, result); - - -#ifdef NL_DEBUG - nldebug("CAdminServiceWebClient::cb_commandResult : calling on_commandResult"); -#endif - - callback->on_commandResult(from, serviceAlias, result); - } - - - /// Disconnection callback : the connection to the server is lost - virtual void on_CAdminServiceWebClient_Disconnection(NLNET::TSockId from) =0; - - - virtual void on_commandResult(NLNET::TSockId from, const std::string &serviceAlias, const std::string &result) =0; - - }; - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class TGraphData - { - protected: - // - std::string _ServiceAlias; - // - std::string _VarName; - // - uint32 _SamplePeriod; - // - double _Value; - public: - // - const std::string &getServiceAlias() const - { - return _ServiceAlias; - } - - std::string &getServiceAlias() - { - return _ServiceAlias; - } - - - void setServiceAlias(const std::string &value) - { - - - _ServiceAlias = value; - - - } - // - const std::string &getVarName() const - { - return _VarName; - } - - std::string &getVarName() - { - return _VarName; - } - - - void setVarName(const std::string &value) - { - - - _VarName = value; - - - } - // - uint32 getSamplePeriod() const - { - return _SamplePeriod; - } - - void setSamplePeriod(uint32 value) - { - - _SamplePeriod = value; - - } - // - double getValue() const - { - return _Value; - } - - void setValue(double value) - { - - _Value = value; - - } - - bool operator == (const TGraphData &other) const - { - return _ServiceAlias == other._ServiceAlias - && _VarName == other._VarName - && _SamplePeriod == other._SamplePeriod - && _Value == other._Value; - } - - - // constructor - TGraphData() - { - - } - - void serial(NLMISC::IStream &s) - { - s.serial(_ServiceAlias); - s.serial(_VarName); - s.serial(_SamplePeriod); - s.serial(_Value); - - } - - - private: - - - }; - - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class TGraphDatas - { - protected: - // - uint32 _CurrentTime; - // - std::vector < TGraphData > _Datas; - public: - // - uint32 getCurrentTime() const - { - return _CurrentTime; - } - - void setCurrentTime(uint32 value) - { - - _CurrentTime = value; - - } - // - const std::vector < TGraphData > &getDatas() const - { - return _Datas; - } - - std::vector < TGraphData > &getDatas() - { - return _Datas; - } - - - void setDatas(const std::vector < TGraphData > &value) - { - - - _Datas = value; - - - } - - bool operator == (const TGraphDatas &other) const - { - return _CurrentTime == other._CurrentTime - && _Datas == other._Datas; - } - - - // constructor - TGraphDatas() - { - - } - - void serial(NLMISC::IStream &s) - { - s.serial(_CurrentTime); - s.serialCont(_Datas); - - } - - - private: - - - }; - - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class THighRezData - { - protected: - // - NLMISC::TTime _SampleTick; - // - double _Value; - public: - // - NLMISC::TTime getSampleTick() const - { - return _SampleTick; - } - - void setSampleTick(NLMISC::TTime value) - { - - _SampleTick = value; - - } - // - double getValue() const - { - return _Value; - } - - void setValue(double value) - { - - _Value = value; - - } - - bool operator == (const THighRezData &other) const - { - return _SampleTick == other._SampleTick - && _Value == other._Value; - } - - - // constructor - THighRezData() - { - - } - - void serial(NLMISC::IStream &s) - { - s.serial(_SampleTick); - s.serial(_Value); - - } - - - private: - - - }; - - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class THighRezDatas - { - protected: - // - std::string _ServiceAlias; - // - std::string _VarName; - // - uint32 _CurrentTime; - // - std::vector < THighRezData > _Datas; - public: - // - const std::string &getServiceAlias() const - { - return _ServiceAlias; - } - - std::string &getServiceAlias() - { - return _ServiceAlias; - } - - - void setServiceAlias(const std::string &value) - { - - - _ServiceAlias = value; - - - } - // - const std::string &getVarName() const - { - return _VarName; - } - - std::string &getVarName() - { - return _VarName; - } - - - void setVarName(const std::string &value) - { - - - _VarName = value; - - - } - // - uint32 getCurrentTime() const - { - return _CurrentTime; - } - - void setCurrentTime(uint32 value) - { - - _CurrentTime = value; - - } - // - const std::vector < THighRezData > &getDatas() const - { - return _Datas; - } - - std::vector < THighRezData > &getDatas() - { - return _Datas; - } - - - void setDatas(const std::vector < THighRezData > &value) - { - - - _Datas = value; - - - } - - bool operator == (const THighRezDatas &other) const - { - return _ServiceAlias == other._ServiceAlias - && _VarName == other._VarName - && _CurrentTime == other._CurrentTime - && _Datas == other._Datas; - } - - - // constructor - THighRezDatas() - { - - } - - void serial(NLMISC::IStream &s) - { - s.serial(_ServiceAlias); - s.serial(_VarName); - s.serial(_CurrentTime); - s.serialCont(_Datas); - - } - - - private: - - - }; - - - - - struct TShardOrders - { - enum TValues - { - so_autostart_on, - so_autostart_off, - /// the highest valid value in the enum - last_enum_item = so_autostart_off, - /// a value equal to the last enum item +1 - end_of_enum, - - invalid_val, - - /// Number of enumerated values - nb_enum_items = 2 - }; - - /// Index table to convert enum value to linear index table - const std::map &getIndexTable() const - { - static std::map indexTable; - static bool init = false; - if (!init) - { - // fill the index table - indexTable.insert(std::make_pair(so_autostart_on, 0)); - indexTable.insert(std::make_pair(so_autostart_off, 1)); - - init = true; - } - - return indexTable; - } - - - static const NLMISC::CStringConversion &getConversionTable() - { - NL_BEGIN_STRING_CONVERSION_TABLE(TValues) - NL_STRING_CONVERSION_TABLE_ENTRY(so_autostart_on) - NL_STRING_CONVERSION_TABLE_ENTRY(so_autostart_off) - NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val) - }; - static NLMISC::CStringConversion - conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table) - / sizeof(TValues_nl_string_conversion_table[0]), invalid_val); - - return conversionTable; - } - - TValues _Value; - - public: - TShardOrders() - : _Value(invalid_val) - { - } - TShardOrders(TValues value) - : _Value(value) - { - } - - TShardOrders(const std::string &str) - { - _Value = getConversionTable().fromString(str); - } - - void serial(NLMISC::IStream &s) - { - s.serialEnum(_Value); - } - - bool operator == (const TShardOrders &other) const - { - return _Value == other._Value; - } - bool operator != (const TShardOrders &other) const - { - return ! (_Value == other._Value); - } - bool operator < (const TShardOrders &other) const - { - return _Value < other._Value; - } - - bool operator <= (const TShardOrders &other) const - { - return _Value <= other._Value; - } - - bool operator > (const TShardOrders &other) const - { - return !(_Value <= other._Value); - } - bool operator >= (const TShardOrders &other) const - { - return !(_Value < other._Value); - } - - const std::string &toString() const - { - return getConversionTable().toString(_Value); - } - static const std::string &toString(TValues value) - { - return getConversionTable().toString(value); - } - - TValues getValue() const - { - return _Value; - } - - // return true if the actual value of the enum is valid, otherwise false - bool isValid() - { - if (_Value == invalid_val) - return false; - - // not invalid, check other enum value - return getConversionTable().isValid(_Value); - } - - - uint32 asIndex() - { - std::map::const_iterator it(getIndexTable().find(_Value)); - nlassert(it != getIndexTable().end()); - return it->second; - } - - }; - - - struct TRunningOrders - { - enum TValues - { - ro_deactivated, - ro_activated, - /// the highest valid value in the enum - last_enum_item = ro_activated, - /// a value equal to the last enum item +1 - end_of_enum, - - invalid_val, - - /// Number of enumerated values - nb_enum_items = 2 - }; - - /// Index table to convert enum value to linear index table - const std::map &getIndexTable() const - { - static std::map indexTable; - static bool init = false; - if (!init) - { - // fill the index table - indexTable.insert(std::make_pair(ro_deactivated, 0)); - indexTable.insert(std::make_pair(ro_activated, 1)); - - init = true; - } - - return indexTable; - } - - - static const NLMISC::CStringConversion &getConversionTable() - { - NL_BEGIN_STRING_CONVERSION_TABLE(TValues) - NL_STRING_CONVERSION_TABLE_ENTRY(ro_deactivated) - NL_STRING_CONVERSION_TABLE_ENTRY(ro_activated) - NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val) - }; - static NLMISC::CStringConversion - conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table) - / sizeof(TValues_nl_string_conversion_table[0]), invalid_val); - - return conversionTable; - } - - TValues _Value; - - public: - TRunningOrders() - : _Value(invalid_val) - { - } - TRunningOrders(TValues value) - : _Value(value) - { - } - - TRunningOrders(const std::string &str) - { - _Value = getConversionTable().fromString(str); - } - - void serial(NLMISC::IStream &s) - { - s.serialEnum(_Value); - } - - bool operator == (const TRunningOrders &other) const - { - return _Value == other._Value; - } - bool operator != (const TRunningOrders &other) const - { - return ! (_Value == other._Value); - } - bool operator < (const TRunningOrders &other) const - { - return _Value < other._Value; - } - - bool operator <= (const TRunningOrders &other) const - { - return _Value <= other._Value; - } - - bool operator > (const TRunningOrders &other) const - { - return !(_Value <= other._Value); - } - bool operator >= (const TRunningOrders &other) const - { - return !(_Value < other._Value); - } - - const std::string &toString() const - { - return getConversionTable().toString(_Value); - } - static const std::string &toString(TValues value) - { - return getConversionTable().toString(value); - } - - TValues getValue() const - { - return _Value; - } - - // return true if the actual value of the enum is valid, otherwise false - bool isValid() - { - if (_Value == invalid_val) - return false; - - // not invalid, check other enum value - return getConversionTable().isValid(_Value); - } - - - uint32 asIndex() - { - std::map::const_iterator it(getIndexTable().find(_Value)); - nlassert(it != getIndexTable().end()); - return it->second; - } - - }; - - - struct TRunningState - { - enum TValues - { - rs_stopped, - rs_running, - rs_online, - /// the highest valid value in the enum - last_enum_item = rs_online, - /// a value equal to the last enum item +1 - end_of_enum, - - invalid_val, - - /// Number of enumerated values - nb_enum_items = 3 - }; - - /// Index table to convert enum value to linear index table - const std::map &getIndexTable() const - { - static std::map indexTable; - static bool init = false; - if (!init) - { - // fill the index table - indexTable.insert(std::make_pair(rs_stopped, 0)); - indexTable.insert(std::make_pair(rs_running, 1)); - indexTable.insert(std::make_pair(rs_online, 2)); - - init = true; - } - - return indexTable; - } - - - static const NLMISC::CStringConversion &getConversionTable() - { - NL_BEGIN_STRING_CONVERSION_TABLE(TValues) - NL_STRING_CONVERSION_TABLE_ENTRY(rs_stopped) - NL_STRING_CONVERSION_TABLE_ENTRY(rs_running) - NL_STRING_CONVERSION_TABLE_ENTRY(rs_online) - NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val) - }; - static NLMISC::CStringConversion - conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table) - / sizeof(TValues_nl_string_conversion_table[0]), invalid_val); - - return conversionTable; - } - - TValues _Value; - - public: - TRunningState() - : _Value(invalid_val) - { - } - TRunningState(TValues value) - : _Value(value) - { - } - - TRunningState(const std::string &str) - { - _Value = getConversionTable().fromString(str); - } - - void serial(NLMISC::IStream &s) - { - s.serialEnum(_Value); - } - - bool operator == (const TRunningState &other) const - { - return _Value == other._Value; - } - bool operator != (const TRunningState &other) const - { - return ! (_Value == other._Value); - } - bool operator < (const TRunningState &other) const - { - return _Value < other._Value; - } - - bool operator <= (const TRunningState &other) const - { - return _Value <= other._Value; - } - - bool operator > (const TRunningState &other) const - { - return !(_Value <= other._Value); - } - bool operator >= (const TRunningState &other) const - { - return !(_Value < other._Value); - } - - const std::string &toString() const - { - return getConversionTable().toString(_Value); - } - static const std::string &toString(TValues value) - { - return getConversionTable().toString(value); - } - - TValues getValue() const - { - return _Value; - } - - // return true if the actual value of the enum is valid, otherwise false - bool isValid() - { - if (_Value == invalid_val) - return false; - - // not invalid, check other enum value - return getConversionTable().isValid(_Value); - } - - - uint32 asIndex() - { - std::map::const_iterator it(getIndexTable().find(_Value)); - nlassert(it != getIndexTable().end()); - return it->second; - } - - }; - - - struct TRunningTag - { - enum TValues - { - rt_chain_crashing, - rt_locally_started, - rt_locally_stopped, - rt_globally_stopped, - rt_stopped_for_patch, - rt_externaly_started, - rt_slow_to_stop, - rt_slow_to_start, - /// the highest valid value in the enum - last_enum_item = rt_slow_to_start, - /// a value equal to the last enum item +1 - end_of_enum, - - invalid_val, - - /// Number of enumerated values - nb_enum_items = 8 - }; - - /// Index table to convert enum value to linear index table - const std::map &getIndexTable() const - { - static std::map indexTable; - static bool init = false; - if (!init) - { - // fill the index table - indexTable.insert(std::make_pair(rt_chain_crashing, 0)); - indexTable.insert(std::make_pair(rt_locally_started, 1)); - indexTable.insert(std::make_pair(rt_locally_stopped, 2)); - indexTable.insert(std::make_pair(rt_globally_stopped, 3)); - indexTable.insert(std::make_pair(rt_stopped_for_patch, 4)); - indexTable.insert(std::make_pair(rt_externaly_started, 5)); - indexTable.insert(std::make_pair(rt_slow_to_stop, 6)); - indexTable.insert(std::make_pair(rt_slow_to_start, 7)); - - init = true; - } - - return indexTable; - } - - - static const NLMISC::CStringConversion &getConversionTable() - { - NL_BEGIN_STRING_CONVERSION_TABLE(TValues) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_chain_crashing) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_locally_started) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_locally_stopped) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_globally_stopped) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_stopped_for_patch) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_externaly_started) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_slow_to_stop) - NL_STRING_CONVERSION_TABLE_ENTRY(rt_slow_to_start) - NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val) - }; - static NLMISC::CStringConversion - conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table) - / sizeof(TValues_nl_string_conversion_table[0]), invalid_val); - - return conversionTable; - } - - TValues _Value; - - public: - TRunningTag() - : _Value(invalid_val) - { - } - TRunningTag(TValues value) - : _Value(value) - { - } - - TRunningTag(const std::string &str) - { - _Value = getConversionTable().fromString(str); - } - - void serial(NLMISC::IStream &s) - { - s.serialEnum(_Value); - } - - bool operator == (const TRunningTag &other) const - { - return _Value == other._Value; - } - bool operator != (const TRunningTag &other) const - { - return ! (_Value == other._Value); - } - bool operator < (const TRunningTag &other) const - { - return _Value < other._Value; - } - - bool operator <= (const TRunningTag &other) const - { - return _Value <= other._Value; - } - - bool operator > (const TRunningTag &other) const - { - return !(_Value <= other._Value); - } - bool operator >= (const TRunningTag &other) const - { - return !(_Value < other._Value); - } - - const std::string &toString() const - { - return getConversionTable().toString(_Value); - } - static const std::string &toString(TValues value) - { - return getConversionTable().toString(value); - } - - TValues getValue() const - { - return _Value; - } - - // return true if the actual value of the enum is valid, otherwise false - bool isValid() - { - if (_Value == invalid_val) - return false; - - // not invalid, check other enum value - return getConversionTable().isValid(_Value); - } - - - uint32 asIndex() - { - std::map::const_iterator it(getIndexTable().find(_Value)); - nlassert(it != getIndexTable().end()); - return it->second; - } - - }; - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class TServiceStatus - { - protected: - // - std::string _ShardName; - // - std::string _ServiceLongName; - // - std::string _ServiceShortName; - // - std::string _ServiceAliasName; - // - TRunningState _RunningState; - // - TRunningOrders _RunningOrders; - // - std::set < TRunningTag > _RunningTags; - // - std::string _Status; - public: - // - const std::string &getShardName() const - { - return _ShardName; - } - - std::string &getShardName() - { - return _ShardName; - } - - - void setShardName(const std::string &value) - { - - - _ShardName = value; - - - } - // - const std::string &getServiceLongName() const - { - return _ServiceLongName; - } - - std::string &getServiceLongName() - { - return _ServiceLongName; - } - - - void setServiceLongName(const std::string &value) - { - - - _ServiceLongName = value; - - - } - // - const std::string &getServiceShortName() const - { - return _ServiceShortName; - } - - std::string &getServiceShortName() - { - return _ServiceShortName; - } - - - void setServiceShortName(const std::string &value) - { - - - _ServiceShortName = value; - - - } - // - const std::string &getServiceAliasName() const - { - return _ServiceAliasName; - } - - std::string &getServiceAliasName() - { - return _ServiceAliasName; - } - - - void setServiceAliasName(const std::string &value) - { - - - _ServiceAliasName = value; - - - } - // - TRunningState getRunningState() const - { - return _RunningState; - } - - void setRunningState(TRunningState value) - { - - _RunningState = value; - - } - // - TRunningOrders getRunningOrders() const - { - return _RunningOrders; - } - - void setRunningOrders(TRunningOrders value) - { - - _RunningOrders = value; - - } - // - const std::set < TRunningTag > &getRunningTags() const - { - return _RunningTags; - } - - std::set < TRunningTag > &getRunningTags() - { - return _RunningTags; - } - - - void setRunningTags(const std::set < TRunningTag > &value) - { - - - _RunningTags = value; - - - } - // - const std::string &getStatus() const - { - return _Status; - } - - std::string &getStatus() - { - return _Status; - } - - - void setStatus(const std::string &value) - { - - - _Status = value; - - - } - - bool operator == (const TServiceStatus &other) const - { - return _ShardName == other._ShardName - && _ServiceLongName == other._ServiceLongName - && _ServiceShortName == other._ServiceShortName - && _ServiceAliasName == other._ServiceAliasName - && _RunningState == other._RunningState - && _RunningOrders == other._RunningOrders - && _RunningTags == other._RunningTags - && _Status == other._Status; - } - - - // constructor - TServiceStatus() - { - - } - - void serial(NLMISC::IStream &s) - { - s.serial(_ShardName); - s.serial(_ServiceLongName); - s.serial(_ServiceShortName); - s.serial(_ServiceAliasName); - s.serial(_RunningState); - s.serial(_RunningOrders); - s.serialCont(_RunningTags); - s.serial(_Status); - - } - - - private: - - - }; - - - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminServiceSkel - { - public: - /// the interceptor type - typedef NLNET::CInterceptorForwarder < CAdminServiceSkel> TInterceptor; - protected: - CAdminServiceSkel() - { - // do early run time check for message table - getMessageHandlers(); - } - virtual ~CAdminServiceSkel() - { - } - - void init(NLNET::IModule *module) - { - _Interceptor.init(this, module); - } - - // unused interceptors - std::string fwdBuildModuleManifest() const { return std::string(); } - void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {} - - // process module message interceptor - bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - private: - - typedef void (CAdminServiceSkel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - typedef std::map TMessageHandlerMap; - - const TMessageHandlerMap &getMessageHandlers() const; - - - void upServiceUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void graphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void highRezGraphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void commandResult_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - // declare one interceptor member of the skeleton - TInterceptor _Interceptor; - - // declare the interceptor forwarder as friend of this class - friend class NLNET::CInterceptorForwarder < CAdminServiceSkel>; - public: - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - // An AES send an update of the list of service up - virtual void upServiceUpdate(NLNET::IModuleProxy *sender, const std::vector < TServiceStatus > &serviceStatus) =0; - // An AES send graph data update - virtual void graphUpdate(NLNET::IModuleProxy *sender, const TGraphDatas &graphDatas) =0; - // An AES send high rez graph data update - virtual void highRezGraphUpdate(NLNET::IModuleProxy *sender, const THighRezDatas &graphDatas) =0; - // AES send back the result of execution of a command - virtual void commandResult(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result) =0; - - - }; - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminServiceProxy - { - /// Smart pointer on the module proxy - NLNET::TModuleProxyPtr _ModuleProxy; - - // Pointer on the local module that implement the interface (if the proxy is for a local module) - NLNET::TModulePtr _LocalModule; - // Direct pointer on the server implementation interface for collocated module - CAdminServiceSkel *_LocalModuleSkel; - - - public: - CAdminServiceProxy(NLNET::IModuleProxy *proxy) - { - - _ModuleProxy = proxy; - - // initialize collocated servant interface - if (proxy->getModuleDistance() == 0) - { - _LocalModule = proxy->getLocalModule(); - nlassert(_LocalModule != NULL); - CAdminServiceSkel::TInterceptor *interceptor = NULL; - interceptor = static_cast < NLNET::CModuleBase* >(_LocalModule.getPtr())->getInterceptor(interceptor); - nlassert(interceptor != NULL); - - _LocalModuleSkel = interceptor->getParent(); - nlassert(_LocalModuleSkel != NULL); - } - else - _LocalModuleSkel = 0; - - } - virtual ~CAdminServiceProxy() - { - } - - NLNET::IModuleProxy *getModuleProxy() - { - return _ModuleProxy; - } - - // An AES send an update of the list of service up - void upServiceUpdate(NLNET::IModule *sender, const std::vector < TServiceStatus > &serviceStatus); - // An AES send graph data update - void graphUpdate(NLNET::IModule *sender, const TGraphDatas &graphDatas); - // An AES send high rez graph data update - void highRezGraphUpdate(NLNET::IModule *sender, const THighRezDatas &graphDatas); - // AES send back the result of execution of a command - void commandResult(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_upServiceUpdate(NLNET::CMessage &__message, const std::vector < TServiceStatus > &serviceStatus); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_graphUpdate(NLNET::CMessage &__message, const TGraphDatas &graphDatas); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_highRezGraphUpdate(NLNET::CMessage &__message, const THighRezDatas &graphDatas); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_commandResult(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &result); - - - - - }; - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminExecutorServiceSkel - { - public: - /// the interceptor type - typedef NLNET::CInterceptorForwarder < CAdminExecutorServiceSkel> TInterceptor; - protected: - CAdminExecutorServiceSkel() - { - // do early run time check for message table - getMessageHandlers(); - } - virtual ~CAdminExecutorServiceSkel() - { - } - - void init(NLNET::IModule *module) - { - _Interceptor.init(this, module); - } - - // unused interceptors - std::string fwdBuildModuleManifest() const { return std::string(); } - void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {} - - // process module message interceptor - bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - private: - - typedef void (CAdminExecutorServiceSkel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - typedef std::map TMessageHandlerMap; - - const TMessageHandlerMap &getMessageHandlers() const; - - - void setShardOrders_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void shutdownShard_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void controlCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void serviceCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void commandResult_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void graphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void highRezGraphUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void serviceStatusUpdate_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - // declare one interceptor member of the skeleton - TInterceptor _Interceptor; - - // declare the interceptor forwarder as friend of this class - friend class NLNET::CInterceptorForwarder < CAdminExecutorServiceSkel>; - public: - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - // AS send orders for a shard - virtual void setShardOrders(NLNET::IModuleProxy *sender, const std::string &shardName, const TShardOrders &shardOrders) =0; - // AS send a command to shutdown a shard with a delay - virtual void shutdownShard(NLNET::IModuleProxy *sender, const std::string &shardName, uint32 delay) =0; - // AS send a control command to this AES - virtual void controlCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) =0; - // Send a command to a service. - virtual void serviceCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) =0; - // AES client send back the result of execution of a command - virtual void commandResult(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result) =0; - // A service send graph data update - virtual void graphUpdate(NLNET::IModuleProxy *sender, const TGraphDatas &graphDatas) =0; - // A service high rez graph data update - virtual void highRezGraphUpdate(NLNET::IModuleProxy *sender, const THighRezDatas &graphDatas) =0; - // A service send an update of of it's status string - virtual void serviceStatusUpdate(NLNET::IModuleProxy *sender, const std::string &status) =0; - - - }; - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminExecutorServiceProxy - { - /// Smart pointer on the module proxy - NLNET::TModuleProxyPtr _ModuleProxy; - - // Pointer on the local module that implement the interface (if the proxy is for a local module) - NLNET::TModulePtr _LocalModule; - // Direct pointer on the server implementation interface for collocated module - CAdminExecutorServiceSkel *_LocalModuleSkel; - - - public: - CAdminExecutorServiceProxy(NLNET::IModuleProxy *proxy) - { - - _ModuleProxy = proxy; - - // initialize collocated servant interface - if (proxy->getModuleDistance() == 0) - { - _LocalModule = proxy->getLocalModule(); - nlassert(_LocalModule != NULL); - CAdminExecutorServiceSkel::TInterceptor *interceptor = NULL; - interceptor = static_cast < NLNET::CModuleBase* >(_LocalModule.getPtr())->getInterceptor(interceptor); - nlassert(interceptor != NULL); - - _LocalModuleSkel = interceptor->getParent(); - nlassert(_LocalModuleSkel != NULL); - } - else - _LocalModuleSkel = 0; - - } - virtual ~CAdminExecutorServiceProxy() - { - } - - NLNET::IModuleProxy *getModuleProxy() - { - return _ModuleProxy; - } - - // AS send orders for a shard - void setShardOrders(NLNET::IModule *sender, const std::string &shardName, const TShardOrders &shardOrders); - // AS send a command to shutdown a shard with a delay - void shutdownShard(NLNET::IModule *sender, const std::string &shardName, uint32 delay); - // AS send a control command to this AES - void controlCmd(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command); - // Send a command to a service. - void serviceCmd(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command); - // AES client send back the result of execution of a command - void commandResult(NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result); - // A service send graph data update - void graphUpdate(NLNET::IModule *sender, const TGraphDatas &graphDatas); - // A service high rez graph data update - void highRezGraphUpdate(NLNET::IModule *sender, const THighRezDatas &graphDatas); - // A service send an update of of it's status string - void serviceStatusUpdate(NLNET::IModule *sender, const std::string &status); - // AS send orders for a shard - - // This is the broadcast version of the method. - template < class ProxyIterator > - static void broadcast_setShardOrders(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender, const std::string &shardName, const TShardOrders &shardOrders) - { - NLNET::CMessage message; - - // create the message to send to multiple dest - buildMessageFor_setShardOrders(message , shardName, shardOrders); - - for (; first != last; ++first) - { - NLNET::IModuleProxy *proxy = *first; - - proxy->sendModuleMessage(sender, message); - } - - } - // AS send a command to shutdown a shard with a delay - - // This is the broadcast version of the method. - template < class ProxyIterator > - static void broadcast_shutdownShard(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender, const std::string &shardName, uint32 delay) - { - NLNET::CMessage message; - - // create the message to send to multiple dest - buildMessageFor_shutdownShard(message , shardName, delay); - - for (; first != last; ++first) - { - NLNET::IModuleProxy *proxy = *first; - - proxy->sendModuleMessage(sender, message); - } - - } - // AS send a control command to this AES - - // This is the broadcast version of the method. - template < class ProxyIterator > - static void broadcast_controlCmd(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - NLNET::CMessage message; - - // create the message to send to multiple dest - buildMessageFor_controlCmd(message , commandId, serviceAlias, command); - - for (; first != last; ++first) - { - NLNET::IModuleProxy *proxy = *first; - - proxy->sendModuleMessage(sender, message); - } - - } - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_setShardOrders(NLNET::CMessage &__message, const std::string &shardName, const TShardOrders &shardOrders); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_shutdownShard(NLNET::CMessage &__message, const std::string &shardName, uint32 delay); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_controlCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &command); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_serviceCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &command); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_commandResult(NLNET::CMessage &__message, uint32 commandId, const std::string &serviceAlias, const std::string &result); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_graphUpdate(NLNET::CMessage &__message, const TGraphDatas &graphDatas); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_highRezGraphUpdate(NLNET::CMessage &__message, const THighRezDatas &graphDatas); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_serviceStatusUpdate(NLNET::CMessage &__message, const std::string &status); - - - - - }; - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminExecutorServiceClientSkel - { - public: - /// the interceptor type - typedef NLNET::CInterceptorForwarder < CAdminExecutorServiceClientSkel> TInterceptor; - protected: - CAdminExecutorServiceClientSkel() - { - // do early run time check for message table - getMessageHandlers(); - } - virtual ~CAdminExecutorServiceClientSkel() - { - } - - void init(NLNET::IModule *module) - { - _Interceptor.init(this, module); - } - - // unused interceptors - std::string fwdBuildModuleManifest() const { return std::string(); } - void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {} - void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {} - - // process module message interceptor - bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - private: - - typedef void (CAdminExecutorServiceClientSkel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &message); - typedef std::map TMessageHandlerMap; - - const TMessageHandlerMap &getMessageHandlers() const; - - - void serviceCmd_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - void serviceCmdNoReturn_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message); - - // declare one interceptor member of the skeleton - TInterceptor _Interceptor; - - // declare the interceptor forwarder as friend of this class - friend class NLNET::CInterceptorForwarder < CAdminExecutorServiceClientSkel>; - public: - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - - // execute a command and return the result. - virtual void serviceCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &command) =0; - // Send a command to a service without waiting for the return value. - virtual void serviceCmdNoReturn(NLNET::IModuleProxy *sender, const std::string &command) =0; - - - }; - - ///////////////////////////////////////////////////////////////// - // WARNING : this is a generated file, don't change it ! - ///////////////////////////////////////////////////////////////// - class CAdminExecutorServiceClientProxy - { - /// Smart pointer on the module proxy - NLNET::TModuleProxyPtr _ModuleProxy; - - // Pointer on the local module that implement the interface (if the proxy is for a local module) - NLNET::TModulePtr _LocalModule; - // Direct pointer on the server implementation interface for collocated module - CAdminExecutorServiceClientSkel *_LocalModuleSkel; - - - public: - CAdminExecutorServiceClientProxy(NLNET::IModuleProxy *proxy) - { - - _ModuleProxy = proxy; - - // initialize collocated servant interface - if (proxy->getModuleDistance() == 0) - { - _LocalModule = proxy->getLocalModule(); - nlassert(_LocalModule != NULL); - CAdminExecutorServiceClientSkel::TInterceptor *interceptor = NULL; - interceptor = static_cast < NLNET::CModuleBase* >(_LocalModule.getPtr())->getInterceptor(interceptor); - nlassert(interceptor != NULL); - - _LocalModuleSkel = interceptor->getParent(); - nlassert(_LocalModuleSkel != NULL); - } - else - _LocalModuleSkel = 0; - - } - virtual ~CAdminExecutorServiceClientProxy() - { - } - - NLNET::IModuleProxy *getModuleProxy() - { - return _ModuleProxy; - } - - // execute a command and return the result. - void serviceCmd(NLNET::IModule *sender, uint32 commandId, const std::string &command); - // Send a command to a service without waiting for the return value. - void serviceCmdNoReturn(NLNET::IModule *sender, const std::string &command); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_serviceCmd(NLNET::CMessage &__message, uint32 commandId, const std::string &command); - - // Message serializer. Return the message received in reference for easier integration - static const NLNET::CMessage &buildMessageFor_serviceCmdNoReturn(NLNET::CMessage &__message, const std::string &command); - - - - - }; - -} - -#endif diff --git a/code/ryzom/server/src/admin_modules/admin_modules_itf.xml b/code/ryzom/server/src/admin_modules/admin_modules_itf.xml deleted file mode 100644 index 59823ac30..000000000 --- a/code/ryzom/server/src/admin_modules/admin_modules_itf.xml +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/ryzom/server/src/admin_modules/aes_client_module.cpp b/code/ryzom/server/src/admin_modules/aes_client_module.cpp deleted file mode 100644 index 7cb85f5a4..000000000 --- a/code/ryzom/server/src/admin_modules/aes_client_module.cpp +++ /dev/null @@ -1,478 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#include "stdpch.h" -#include "nel/misc/singleton.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" -#include "nel/net/unified_network.h" -#include "nel/net/service.h" - -#include "admin_modules_itf.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; - -void aesclient_forceLink() {} - -namespace ADMIN -{ - class CAdminExecutorServiceClient - : /*public CManualSingleton,*/ - public CEmptyModuleServiceBehav > >, - public CAdminExecutorServiceClientSkel - { - - enum - { - // Maximum time without sending report string (a kind of 'keep alive') - MAX_DELAY_BETWEEN_REPORT = 30, // 30 seconds - }; - - /// Flag to inform AES that we don't want to be affected by shard orders - bool _DontUseShardOrders; - - /// Admin executor service module - TModuleProxyPtr _AdminExecutorService; - - /// Date of last state reporting to AES - uint32 _LastStateReport; - - /// Last date of status string update - uint32 _LastStatusStringReport; - /// Last status string sent (to avoid double send) - string _LastSentStatus; - - /// The service alias (must be an unique name) - string _ServiceAlias; - - /// A cache of the value because reading it is very slow - uint32 _ProcessUsedMemory; - - struct TGraphSample - { - // The date of the sample (in second) - uint32 TimeStamp; - // The date of the sample (in ms) - TTime HighRezTimeStamp; - // sample value - double SampleValue; - }; - struct TGraphVarInfo - { - /// Name of the graphed var - string VarName; - /** Mean time between two sample in ms - * (in fact, if will be the min period) - * Set it to 1 to have a sample at each tick - * If the period is set less than 1000 ms, - * then the var is considered 'high rez'. - * Otherwise, the period is rounded at the - * nearest integer second. - * For 'high rez' var, the service buffer - * the relative timestamp in ms at each - * tick loop and send update every seconds - * to the AES service. - * In addition, HighRez var are also sent - * every second as normal sample. - */ - uint32 MeanSamplePeriod; - - /// Date of last sample (low rez) - uint32 LastSampleTimeStamp; - /// Date of last sample (high rez) - TTime LastHighRezTimeStamp; - - /// The vector of buffered samples - vector Samples; - - TGraphVarInfo() - : MeanSamplePeriod(1000), - LastSampleTimeStamp(0), - LastHighRezTimeStamp(0) - { - } - }; - - /// The list of variable to graph (build from service config file var 'GraphVars') - vector _GraphVars; - - /// Date of last graph - - public: - - CAdminExecutorServiceClient() - : _DontUseShardOrders(false), - _LastStateReport(0), - _LastStatusStringReport(0), - _ProcessUsedMemory(0) - { - CAdminExecutorServiceClientSkel::init(this); - - } - - std::string makeServiceAlias() - { - string serviceAlias = IService::getInstance()->getServiceAliasName(); - if (serviceAlias.empty()) - { - serviceAlias = IService::getInstance()->getHostName()+"."+IService::getInstance()->getServiceUnifiedName(); - } - return serviceAlias; - } - - string getModuleManifest() const - { - uint32 pid = getpid (); - - string serviceAlias = _ServiceAlias; - - CSString manifest; - - manifest << "LongName=" << IService::getInstance()->getServiceLongName() - << " ShortName=" << IService::getInstance()->getServiceShortName() - << " AliasName=" << serviceAlias - << " PID=" << pid - << " DontUseShardOrders=" << _DontUseShardOrders; - - return manifest; - } - - bool initModule(const TParsedCommandLine &pcl) - { - if (!CModuleBase::initModule(pcl)) - return false; - - // try to read the config file - IService *service = IService::getInstance(); - if (service == NULL) - { - nlwarning("Failed to get the IService singleton instance"); - return false; - } - - CConfigFile::CVar *gv = service->ConfigFile.getVarPtr("GraphVars"); - if (gv) - { - _GraphVars.clear(); - for (uint i =0; isize()/2; ++i) - { - TGraphVarInfo gvi; - - gvi.VarName = gv->asString(i*2); - gvi.MeanSamplePeriod = max(1, gv->asInt((i*2)+1)); - - _GraphVars.push_back(gvi); - } - } - - // precompute the service name - _ServiceAlias = makeServiceAlias(); - - // loop for an optional 'dontUseShardOrders' flag in init params - const TParsedCommandLine *duso = pcl.getParam("dontUseShardOrders"); - if (duso != NULL) - _DontUseShardOrders = (duso->ParamValue == "true" || duso->ParamName == "1"); - - return true; - } - - - void onModuleUp(IModuleProxy *proxy) - { - if (proxy->getModuleClassName() == "AdminExecutorService") - { - nldebug("CAdminExecutorServiceClient : admin executor service up as '%s'", proxy->getModuleName().c_str()); - // we found the manager of AES - if (_AdminExecutorService != NULL) - { - nlwarning("CAdminExecutorServiceClient : admin executor service already known as '%s', replacing with new one", _AdminExecutorService->getModuleName().c_str()); - } - _AdminExecutorService = proxy; - -// // send basic service info to AES -// CAdminExecutorServiceProxy aes(proxy); -// -// uint32 pid = getpid (); -// -// string serviceAlias = IService::getInstance()->getServiceAliasName(); -// if (serviceAlias.empty()) -// serviceAlias = getModuleFullyQualifiedName(); -// -// aes.serviceConnected(this, -// IService::getInstance()->getServiceLongName(), -// IService::getInstance()->getServiceShortName(), -// serviceAlias, -// pid); - // for resend of the current status to the new AES - _LastSentStatus = ""; - sendServiceStatus(); - } - } - - void onModuleDown(IModuleProxy *proxy) - { - if (proxy == _AdminExecutorService) - { - nldebug("CAdminExecutorServiceClient : admin executor service '%s' is down", proxy->getModuleName().c_str()); - - _AdminExecutorService = NULL; - } - } - - void onModuleUpdate() - { - H_AUTO(CAdminExecutorServiceClient_onModuleUpdate); - - uint32 now = CTime::getSecondsSince1970(); - TTime timer = CTime::getLocalTime(); - - // update every HR variables - for (uint i=0; i<_GraphVars.size(); ++i) - { - if (_GraphVars[i].MeanSamplePeriod < 1000) - { - // this is a HR var - TGraphVarInfo &gvi = _GraphVars[i]; - if (gvi.LastHighRezTimeStamp + gvi.MeanSamplePeriod < timer) - { - // it's time to get a sample - // create a sample - gvi.Samples.push_back(TGraphSample()); - TGraphSample &gs = gvi.Samples.back(); - // inialise it - gs.TimeStamp = now; - gs.HighRezTimeStamp = timer; - IVariable *var = dynamic_cast(ICommand::getCommand(gvi.VarName)); - if (var != NULL) - NLMISC::fromString(var->toString(), gs.SampleValue); - } - } - } - - if (_LastStateReport != now) - { - - if ((now & 0xf) == 0) - { - // every 16 seconds because very slow - IVariable *var = dynamic_cast(ICommand::getCommand("ProcessUsedMemory")); - if (var != NULL) - NLMISC::fromString(var->toString(), _ProcessUsedMemory); - } - - // at least one second as passed, check for updates to send to - // AES - - TGraphDatas graphDatas; - graphDatas.setCurrentTime(now); - - THighRezDatas highRezDatas; - highRezDatas.setServiceAlias(_ServiceAlias); - highRezDatas.setCurrentTime(now); - - vector &datas = graphDatas.getDatas(); - - for (uint i=0; i<_GraphVars.size(); ++i) - { - if (_GraphVars[i].LastSampleTimeStamp+(_GraphVars[i].MeanSamplePeriod/1000) < now) - { - TGraphVarInfo &gvi = _GraphVars[i]; - // it's time to send update for this var - // create a new sample entry - datas.push_back(TGraphData()); - // and fill it - TGraphData &gd = datas.back(); - gd.setServiceAlias(_ServiceAlias); - gd.setVarName(gvi.VarName); - gd.setSamplePeriod(max(uint32(1), uint32(gvi.MeanSamplePeriod/1000))); - if (gvi.Samples.empty()) - { - // no sample collected yet, just ask a new one - IVariable *var = dynamic_cast(ICommand::getCommand(gvi.VarName)); - if (var != NULL) - { - float val; - NLMISC::fromString(var->toString(), val); - gd.setValue(val); - } - } - else - { - // we have some sample collected, just use the last one - gd.setValue(gvi.Samples.back().SampleValue); - } - - // if it's a high rez sampler, send the complete buffer - if (gvi.MeanSamplePeriod < 1000 && _AdminExecutorService != NULL) - { - // build the message - highRezDatas.setVarName(gvi.VarName); - highRezDatas.getDatas().clear(); - - for (uint j=0; jgetServiceStatusString(); - } - - if ((status != _LastSentStatus || (now - _LastStatusStringReport) > MAX_DELAY_BETWEEN_REPORT) - && _AdminExecutorService != NULL) - { - CAdminExecutorServiceProxy aes(_AdminExecutorService); - aes.serviceStatusUpdate(this, status); - - _LastSentStatus = status; - _LastStatusStringReport = now; - } - } - - /////////////////////////////////////////////////////////////// - // implementation from Admin executor service client - /////////////////////////////////////////////////////////////// - - // execute a command and return the result. - virtual void serviceCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &command) - { - // create a displayer to gather the output of the command - class CStringDisplayer: public IDisplayer - { - public: - virtual void doDisplay( const CLog::TDisplayInfo& args, const char *message) - { - _Data += message; - } - - std::string _Data; - }; - CStringDisplayer stringDisplayer; - IService::getInstance()->CommandLog.addDisplayer(&stringDisplayer); - - // retrieve the command from the input message and execute it - nlinfo ("ADMIN: Executing command from network : '%s'", command.c_str()); - ICommand::execute (command, IService::getInstance()->CommandLog); - - // unhook our displayer as it's work is now done - IService::getInstance()->CommandLog.removeDisplayer(&stringDisplayer); - - string serviceAlias = IService::getInstance()->getServiceAliasName(); - if (serviceAlias.empty()) - serviceAlias = getModuleFullyQualifiedName(); - - // return the result to AES - CAdminExecutorServiceProxy aes(sender); - aes.commandResult(this, commandId, serviceAlias, stringDisplayer._Data); - } - - // execute a command without result - virtual void serviceCmdNoReturn(NLNET::IModuleProxy *sender, const std::string &command) - { - // retrieve the command from the input message and execute it - nlinfo ("ADMIN: Executing command from network : '%s'", command.c_str()); - ICommand::execute (command, IService::getInstance()->CommandLog); - } - }; - - NLNET_REGISTER_MODULE_FACTORY(CAdminExecutorServiceClient, "AdminExecutorServiceClient"); - - -} // namespace ADMIN - diff --git a/code/ryzom/server/src/admin_modules/aes_module.cpp b/code/ryzom/server/src/admin_modules/aes_module.cpp deleted file mode 100644 index aee6da68a..000000000 --- a/code/ryzom/server/src/admin_modules/aes_module.cpp +++ /dev/null @@ -1,1858 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#include "stdpch.h" -#include "nel/misc/singleton.h" -#include -#include "nel/misc/path.h" -#include "nel/misc/common.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" -#include "nel/net/unified_network.h" -#include "nel/net/service.h" - -#include "game_share/utils.h" - -#include "admin_modules_itf.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; - -void aes_forceLink() {} - -namespace ADMIN -{ - const char* LAUNCH_CTRL_START = "LAUNCH"; - const char* LAUNCH_CTRL_STOP = "STOP"; - - const char *AESPersistentStateFilename = "aes_state.txt"; - - /// We want 10 slot (you can change this, but need at least 3 slots) - const uint32 CRASH_COUNTER_SLOT = 10; - /// The delay (in second) between slots roll. This value * CRASH_COUNTER_SLOT give the total sampling period - const uint32 CRASH_COUNTER_ROLL_DELAY = 10*60; // 10 mn - /// If we have more than 5 start of a service in the sampling period, we tag the service as 'chain crashing' - const uint32 CRASH_COUNTER_CHAIN_THRESHOLD = 5; - - /** the name of the file written by the patch man to request a global shutdown - * of all registered the services before switching to a new version. - */ - CVariable ShutdownRequestFileName("aes","ShutdownRequestFileName", "name of the file to use for shutdown requests", "./global.launch_ctrl", 0, true); - - /** A kind rolling buffer used to count services start from the runner - * script. - */ - class CRunnerLoopCounter - { - /// The slot table. Each slot accumulate the service start for a time frame - uint32 _Slots[CRASH_COUNTER_SLOT]; - /** The last value read from the runner script. This is used to compute - * the delta value to add to the first slot - */ - uint32 _LastValueRead; - /// The total sum of all slot (could be recomputed on demand, but a little more efficient) - uint32 _CounterSum; - public: - - CRunnerLoopCounter() - { - // we need at least 3 slots - nlctassert(CRASH_COUNTER_SLOT >= 3); - - // init all slots with 0 - for (uint i=0; i0; --i) - { - _Slots[i] = _Slots[i-1]; - } - _Slots[0] = 0; - } - - /// Return the sum of all the slots - uint32 getSum() - { - return _CounterSum; - } - - /// Return the sum of the first slot, the tree first slot and - /// the total of all slots. - /// This is useful to understand the behavoir of a crashing - /// service over the sampling period. - void getCounters(uint32 &oneSlot, uint32 &treeSlots, uint32 &allSlots) - { - oneSlot = _Slots[0]; - treeSlots = _Slots[0]+_Slots[1]+_Slots[2]; - allSlots = _CounterSum; - } - - - /// Reset all counter to zero - void resetCounter() - { - for (uint i=0; i,*/ - public CEmptyModuleServiceBehav > >, - public CAdminExecutorServiceSkel, - public IModuleTrackerCb - { - public: - enum - { - SLOW_TO_START_THRESHOLD = 60, // 1 mn - SLOW_TO_STOP_THRESHOLD = 60, // 1 mn - _NagiosReportDelay = 60, // 1 mn - }; - - private: - - typedef CModuleTracker TServiceTracker; - // tracker for admin executor client modules - TServiceTracker _ServiceTracker; - - /// Admin service module - TModuleProxyPtr _AdminService; - - /// Date of last state reporting to AS - uint32 _LastStateReport; - - /// Date of last nagios report output - uint32 _LastNagiosReport; - - typedef string TAliasName; - typedef string TShardName; - typedef set TRegisteredServices; - /// List of 'registered service', ie. those that are configured in aes cfg. - TRegisteredServices _RegisteredServices; - - /// A set of data for each registered or connected service - struct TServiceState - { - string ShardName; - bool DontUseShardOrders; - TRunningState RunningState; - set RunningTags; - string LongName; - string ShortName; - uint32 PID; - string State; - uint32 LastStateDate; - uint32 StopRequestDate; - uint32 StartRequestDate; - TModuleProxyPtr ServiceModule; - CRunnerLoopCounter RunnerLoopCounter; - - TServiceState() - : DontUseShardOrders(false), - RunningState(TRunningState::rs_stopped), - PID(0), - LastStateDate(0), - StopRequestDate(0), - StartRequestDate(0) - {} - }; - - typedef map TServiceStates; - /// States for each connected or registered service - TServiceStates _ServiceStates; - - typedef map TConnectedServiceIndex; - /// Index of connected service proxy to alias name - TConnectedServiceIndex _ConnectedServiceIndex; - - typedef map TPersistentServiceOrders; - /// Persistent service state, i.e state that are restored after a stop/start of the aes - TPersistentServiceOrders _PersistentServiceOrders; - - typedef map TShardsOrders; - /// Shard orders (set by AS) - TShardsOrders _ShardOrders; - - /// flag for shutdown request form patch manager. - bool _ShutdownForPatch; - - /// A flag that mean we need to save the persistent state file - bool _NeedToWriteStateFile; - - /// Date of last roll of the runner loop counters - uint32 _LastRunnerLoopCounterRoll; - - /// Data for each command pending result from a service - struct TPendingWebCommand - { - /// Date of reception of the command for timeout - uint32 ReceptionDate; - /// Name of the target service - string ServiceAlias; - /// Command - string Command; - }; - typedef uint32 TCommandId; - typedef map TPendingWebCommands; - /// A list of pending command sent to service and waiting result - TPendingWebCommands _PendingWebCommands; - - /// information about shard being stopped - struct TStopingShardInfo - { - /// Name of the shard to stop - string ShardName; - /// Delay before stop - uint32 Delay; - /// Begin date of countdown - uint32 BeginDate; - }; - - typedef vector TStopingShardInfos; - - /// The vector of shard to stop. - TStopingShardInfos _StopingShards; - - - public: - CAdminExecutorService() - : _ServiceTracker(TModuleClassPred("AdminExecutorServiceClient")), - _LastStateReport(0), - _LastNagiosReport(0), - _ShutdownForPatch(false), - _NeedToWriteStateFile(false), - _LastRunnerLoopCounterRoll(0) - { - CAdminExecutorServiceSkel::init(this); - _ServiceTracker.init(this, this); - - } - - bool initModule(const TParsedCommandLine &pcl) - { - CModuleBase::initModule(pcl); - - // read the persistent state file if any - string filename = CPath::standardizePath(IService::getInstance()->SaveFilesDirectory.toString(), true)+AESPersistentStateFilename; - FILE *fp = nlfopen(filename, "rt"); - if (fp != NULL) - { - char buffer[1024]; - char *ret; - while ((ret=fgets(buffer, 1024, fp)) != NULL) - { - CSString line(buffer); - CSString cmd(line.firstWord(true)); - - if (cmd == "ServiceState") - { - CSString serviceAlias = line.firstWord(true); - CSString serviceOrders = line.firstWord(true); - - TRunningOrders runningOrders(serviceOrders); - if (!serviceAlias.empty() && runningOrders != TRunningOrders::invalid_val) - { - // add this one in the list of persistent state - _PersistentServiceOrders[serviceAlias] = runningOrders; - } - } - else if (cmd == "ShardOrders") - { - string shardName(line.firstWord(true)); - TShardOrders shardOrders(line.firstWord(true)); - if (shardOrders != TShardOrders::invalid_val) - _ShardOrders[shardName] = shardOrders; - } - } - // clear the flag because 'setGlobalState' has set it - _NeedToWriteStateFile = false; - - fclose(fp); - } - - return true; - } - - void onModuleUp(IModuleProxy *proxy) - { - if (proxy->getModuleClassName() == "AdminService") - { - nldebug("CAdminExecutorService : admin service up as '%s'", proxy->getModuleName().c_str()); - // we found the manager of AES - if (_AdminService != NULL) - { - nlwarning("CAdminExecutorService : admin service already known as '%s', replacing with new one", _AdminService->getModuleName().c_str()); - } - _AdminService = proxy; - - // cleanup the persistent service state by removing any state not in registered or connected service - { - set removeList; - - // first, fill the list with all the persistent state service name - { - TPersistentServiceOrders::iterator first(_PersistentServiceOrders.begin()), last(_PersistentServiceOrders.end()); - for (; first != last; ++first) - { - removeList.insert(first->first); - } - } - - // remove the registered service from the removelist - { - TRegisteredServices::iterator first(_RegisteredServices.begin()), last(_RegisteredServices.end()); - for (; first != last; ++first) - { - removeList.erase(*first); - } - } - // remove any connected service (even unregistered one) - { - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - removeList.erase(first->first); - } - } - - // no remove persistent state that left in the remove list - while (!removeList.empty()) - { - _PersistentServiceOrders.erase(*(removeList.begin())); - - _NeedToWriteStateFile = true; - - removeList.erase(removeList.begin()); - } - - } - // send the current status - sendUpServiceUpdate(); - } - - uint32 now = NLMISC::CTime::getSecondsSince1970(); - // check pending command timeout - TPendingWebCommands::iterator first(_PendingWebCommands.begin()), last(_PendingWebCommands.end()); - for (; first != last; ++first) - { - TPendingWebCommand &pwc = first->second; - - if (now - pwc.ReceptionDate > 10) - { - // timeout - if (_AdminService != NULL) - { - CAdminServiceProxy as(_AdminService); - as.commandResult(this, first->first, pwc.ServiceAlias, "ERROR : AES : no reponse from service"); - } - - _PendingWebCommands.erase(first); - - // check other pending commands at next update - break; - } - } - } - - void onModuleDown(IModuleProxy *proxy) - { - if (proxy == _AdminService) - { - nldebug("CAdminExecutorService : admin service '%s' is down", proxy->getModuleName().c_str()); - - _AdminService = NULL; - } - } - - void onModuleUpdate() - { - H_AUTO(CAdminExecutorService_onModuleUpdate); - - uint32 now = CTime::getSecondsSince1970(); - - if (_LastStateReport < now) - { - // every second - - // check services every second - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - string aliasName = first->first; - TServiceState &ss = first->second; - if (_RegisteredServices.find(aliasName) != _RegisteredServices.end()) - { - // this is a registered service, we need to control is running state - - // read the actual running state from the runner script written file - if (getOfflineServiceState(aliasName) == "RUNNING") - { - // the service is running - ss.RunningTags.erase(TRunningTag::rt_locally_stopped); - ss.RunningTags.erase(TRunningTag::rt_globally_stopped); - ss.RunningTags.erase(TRunningTag::rt_stopped_for_patch); - - if (ss.StopRequestDate != 0) - { - // still not stopped, check for slow to stop service - if (now - ss.StopRequestDate > SLOW_TO_STOP_THRESHOLD) - { - // add a running tag - ss.RunningTags.insert(TRunningTag::rt_slow_to_stop); - } - } - - if (ss.RunningState != TRunningState::rs_online) - { - // tag slow to start service - if (now - ss.StartRequestDate > SLOW_TO_START_THRESHOLD) - { - // add a running tag - ss.RunningTags.insert(TRunningTag::rt_slow_to_start); - } - else - { - ss.RunningState = TRunningState::rs_running; - } - } - } - else - { - // the service is stopped - ss.RunningState = TRunningState::rs_stopped; - ss.RunningTags.erase(TRunningTag::rt_locally_started); - ss.RunningTags.erase(TRunningTag::rt_externaly_started); - ss.RunningTags.erase(TRunningTag::rt_slow_to_stop); - - // clean the stop request date - ss.StopRequestDate = 0; - } - - // try to obtains service orders from its shard - TShardOrders shardOrders(TShardOrders::so_autostart_on); - if (_ShardOrders.find(ss.ShardName) != _ShardOrders.end()) - { - shardOrders = _ShardOrders[ss.ShardName]; - } - // little check, the service must have a entry in the service orders container. - nlassert(_PersistentServiceOrders.find(aliasName) != _PersistentServiceOrders.end()); - - TRunningOrders serviceOrders = _PersistentServiceOrders[aliasName]; - - // look if service need to be started - if (ss.RunningState == TRunningState::rs_stopped // its stopped - && serviceOrders == TRunningOrders::ro_activated // and activated - && shardOrders == TShardOrders::so_autostart_on // and shard is autostart on - && !ss.DontUseShardOrders // and this service follow its shard orders - && !_ShutdownForPatch // and no patch pending - ) - { - // we must start this service ! - startService(aliasName); - } - - // look for service that need to be stopped - if (ss.RunningState != TRunningState::rs_stopped // its not stopped - && (serviceOrders == TRunningOrders::ro_deactivated // and deactivated - || _ShutdownForPatch) // or patch pending - && ss.StopRequestDate == 0 // no stop request send - ) - { - // we must stop this service - stopService(aliasName); - - // store the sop - ss.StopRequestDate = now; - } - // shuted down for patch ? - if (_ShutdownForPatch) - ss.RunningTags.insert(TRunningTag::rt_stopped_for_patch); - else - ss.RunningTags.erase(TRunningTag::rt_stopped_for_patch); - - // chain crashing ? - if (ss.RunnerLoopCounter.getSum() > CRASH_COUNTER_CHAIN_THRESHOLD) - ss.RunningTags.insert(TRunningTag::rt_chain_crashing); - else - ss.RunningTags.erase(TRunningTag::rt_chain_crashing); - - // update the crash counter - ss.RunnerLoopCounter.updateCounter(getServiceStartLoopCounter(aliasName)); - } - - - - } - - // if we have an admin service connected, send it an update of service state - if (_AdminService != NULL) - sendUpServiceUpdate(); - - - if ((now & 0xf) == 0) - { - // every 8 seconds for low frequency work - - // check for shutdown request from patchman - checkShutdownRequest(); - } - - // check for shard to stop (and warning to send) - checkServiceToStop(); - - // time to output the nagios report ? - if (now > _LastNagiosReport+_NagiosReportDelay) - { - // write the nagios report - FILE *fp = nlfopen("aes_nagios_report.txt", "wt"); - if (fp != NULL) - { - // output the current date - time_t t = now; - fprintf(fp, "AESReportDate=%s", ::ctime(&t)); - - fprintf(fp, "NBService=%u\n", (uint)_ServiceStates.size()); - // output state of each service - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - CSString serviceLine; - TServiceState &ss = first->second; - const string &aliasName = first->first; - - CSString runningTags; - set::iterator rtf(ss.RunningTags.begin()), rte(ss.RunningTags.end()); - for (; rtf != rte; ++rtf) - { - runningTags<<"<"<toString()<<">"; - } - - bool registered = _RegisteredServices.find(aliasName) != _RegisteredServices.end(); - - serviceLine << "ServiceAlias='"<second.RunnerLoopCounter.rollCounter(); - } - - _LastRunnerLoopCounterRoll = now; - } - - if (_NeedToWriteStateFile) - { - /// The persistent service orders need to be saved - string filename = CPath::standardizePath(IService::getInstance()->SaveFilesDirectory.toString(), true)+AESPersistentStateFilename; - FILE *fp = nlfopen(filename, "wt"); - if (fp != NULL) - { - { - CSString line; - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - line << "ShardOrders "<first<<" "<second.toString()<<"\n"; - } - - fputs(line.c_str(), fp); - } - - { - TPersistentServiceOrders::iterator first(_PersistentServiceOrders.begin()), last(_PersistentServiceOrders.end()); - for (; first != last; ++first) - { - CSString line; - line << "ServiceState "<first<<" "<second.toString()<<"\n"; - fputs(line.c_str(), fp); - } - } - // clear the flag because 'setGlobalState' has set it - _NeedToWriteStateFile = false; - - fclose(fp); - } - } - } - - void sendUpServiceUpdate() - { - if (_AdminService != NULL) - { - vector serviceStatus; - set missingServices = _RegisteredServices; - // send an updated list to AES - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - const string &aliasName = first->first; - bool registered = _RegisteredServices.find(aliasName) != _RegisteredServices.end(); - TServiceState &ss = first->second; - serviceStatus.push_back(TServiceStatus()); - TServiceStatus &ts = serviceStatus.back(); - ts.setShardName(ss.ShardName); - ts.setServiceLongName(ss.LongName); - ts.setServiceShortName(ss.ShortName); - ts.setServiceAliasName(aliasName); - ts.setRunningState(ss.RunningState); - if (registered) - ts.setRunningOrders(_PersistentServiceOrders[aliasName]); - else - ts.setRunningOrders(TRunningOrders::invalid_val); - ts.setRunningTags(ss.RunningTags); - CSString state; - state << ss.State << "\tNoReportSince=" << (NLMISC::CTime::getSecondsSince1970()-ss.LastStateDate); - - // add the host name - state << "\tHostname=" << IService::getInstance()->getHostName(); - - if (registered) - { - // this is a registered service, send the start counter - uint32 oneSlot, treeSlots, allSlots; - ss.RunnerLoopCounter.getCounters(oneSlot, treeSlots, allSlots); - state << "\tStartCounter="<second == serviceAlias) - { - // ok, we found it - return first->first; - } - } - - // not found - return NULL; - } - - void checkShutdownRequest() - { - // if there's no ctrl file to be found then giveup - if (!NLMISC::CFile::fileExists(ShutdownRequestFileName)) return; - - // if a shutdown ctrl file exists then read it's contents (if the file doesn't exist this returns an empty string) - CSString fileContents; - fileContents.readFromFile(ShutdownRequestFileName.c_str()); - - // see if the file exists - if (!fileContents.empty()) - { - NLMISC::CFile::deleteFile(ShutdownRequestFileName); - fileContents= fileContents.strip().splitToOneOfSeparators(" \t\n\r\x1a"); - - NLMISC::fromString(fileContents, _ShutdownForPatch); - _ShutdownForPatch = !_ShutdownForPatch; - } - } - - void checkServiceToStop() - { - uint32 now = CTime::getSecondsSince1970(); - // for each shard to stop - for (uint i=0; i<_StopingShards.size(); ++i) - { - const TStopingShardInfo &stopShardInfo = _StopingShards[i]; - - bool timeToStop = stopShardInfo.BeginDate + stopShardInfo.Delay <= now; - uint32 timeLeft = (stopShardInfo.BeginDate + stopShardInfo.Delay) - now; - // check every service - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - TServiceState &serviceState = first->second; - - if (serviceState.ServiceModule != NULL && serviceState.ShardName == stopShardInfo.ShardName) - { - // this one belong to the shard to stop - if (!timeToStop) - { - // send a warning every 30 s - if (((now - stopShardInfo.BeginDate) % 30) == 0) - { - CAdminExecutorServiceClientProxy aec(serviceState.ServiceModule); - nlinfo("Sending command 'quitDelay' to service '%s'", first->first.c_str()); - aec.serviceCmdNoReturn(this, toString("quitDelay %u", timeLeft)); - } - } - else - { - // stop the service - stopService(first->first); - } - } - } - - if (timeToStop) - { - nlinfo("All local service for shard %s are stopped", stopShardInfo.ShardName.c_str()); - // shard stopped, erase this entry - _StopingShards.erase(_StopingShards.begin()+i); - --i; - } - } - } - - - // the following routine reads the text string contained in the ".state" file for this service - // it's used to provide a 'state' value for services that are registered but are not connected - // to give info on whether they've been launched, whether their launcher is online, etc - std::string getOfflineServiceState(const std::string& serviceAlias) - { - // open the file for reading - FILE* f= nlfopen(getServiceStateFileName(serviceAlias), "rt"); - if (f==NULL) return "STOPPED"; - - // setup a buffer to hold the text read from the file - uint32 fileSize= NLMISC::CFile::getFileSize(f); - std::string txt; - txt.resize(fileSize); - - // read the text from the file - note that the number of bytes read may be less than the - // number of bytes requested because we've opened the file in text mode and not binary mode - uint32 bytesRead= (uint32)fread(&txt[0],1,fileSize,f); - txt.resize(bytesRead); - fclose(f); - - // return the text read from the file - return txt; - } - - - // the following routine reads the text string contained in the "pid.state" file for this service - // it's used to provide a early pid information to the AES (before the service is connected) - uint32 getOfflineServicePID(const std::string& serviceAlias) - { - // open the file for reading - FILE* f = nlfopen(getServicePIDFileName(serviceAlias), "rt"); - if (f==NULL) return 0; - - // setup a buffer to hold the text read from the file - uint32 fileSize= NLMISC::CFile::getFileSize(f); - std::string txt; - txt.resize(fileSize); - - // read the text from the file - note that the number of bytes read may be less than the - // number of bytes requested because we've opened the file in text mode and not binary mode - uint32 bytesRead= (uint32)fread(&txt[0],1,fileSize,f); - txt.resize(bytesRead); - fclose(f); - - // return the pid read from the file - uint32 pid; - NLMISC::fromString(txt, pid); - - return pid; - } - - - // the following routine reads the text string contained in the ".start_counter" file for this service - // it's used to provide the number of start done by the runner loop on the service - // This is used for the chain crash detector system. - uint32 getServiceStartLoopCounter(const std::string& serviceAlias) - { - // open the file for reading - FILE* f= nlfopen(getServiceLoopCounterFileName(serviceAlias), "rt"); - if (f==NULL) - return 0; - - // setup a buffer to hold the text read from the file - uint32 fileSize= NLMISC::CFile::getFileSize(f); - std::string txt; - txt.resize(fileSize); - - // read the text from the file - note that the number of bytes read may be less than the - // number of bytes requested because we've opened the file in text mode and not binary mode - uint32 bytesRead= (uint32)fread(&txt[0],1,fileSize,f); - txt.resize(bytesRead); - fclose(f); - - // parse the text in the buffer - uint32 counter; - NLMISC::fromString(txt, counter); - - return counter; - } - - // retrieve service launch info in the config file - bool getServiceLaunchInfo(const string& serviceAlias, string& path) - { - string basePath; - CConfigFile::CVar *launchDir = IService::getInstance()->ConfigFile.getVarPtr("AESLauncherDir"); - if (launchDir != NULL) - { - basePath = launchDir->asString()+"/"; - } - - if (_RegisteredServices.find(serviceAlias) == _RegisteredServices.end()) - return false; - path = basePath + serviceAlias+"/"; - - return true; - } - - - std::string getServiceStateFileName(const std::string& serviceAlias) - { - string servicePath; - if (getServiceLaunchInfo(serviceAlias, servicePath)) - return NLMISC::CPath::standardizePath(servicePath)+serviceAlias+".state"; - else - return string(); - } - - std::string getServicePIDFileName(const std::string& serviceAlias) - { - string servicePath; - if (getServiceLaunchInfo(serviceAlias, servicePath)) - return NLMISC::CPath::standardizePath(servicePath)+"pid.state"; - else - return string(); - } - - std::string getServiceLoopCounterFileName(const std::string& serviceAlias) - { - string servicePath; - if (getServiceLaunchInfo(serviceAlias, servicePath)) - return NLMISC::CPath::standardizePath(servicePath)+serviceAlias+".start_count"; - else - return string(); - } - - std::string getServiceLaunchCtrlFileName(const std::string& serviceAlias,const std::string& serviceExecutionPath, bool deferred) - { - return NLMISC::CPath::standardizePath(serviceExecutionPath)+serviceAlias+(deferred?".deferred_":".")+"launch_ctrl"; - } - - - bool writeServiceLaunchCtrl(const std::string& serviceAlias, bool deferred, const std::string& txt) - { - string path; - if (!getServiceLaunchInfo(serviceAlias, path)) - return false; - - // make sure the path exists - NLMISC::CFile::createDirectoryTree(path); - - // open the file for writing - FILE* f = nlfopen(getServiceLaunchCtrlFileName(serviceAlias, path, deferred).c_str(),"wt"); - if (f==NULL) return false; - - // write the text to the file - fprintf(f,"%s",txt.c_str()); - fclose(f); - - return true; - } - - bool startService(const std::string &serviceAlias) - { - if (_ServiceStates.find(serviceAlias) != _ServiceStates.end()) - { - TServiceState &ss = _ServiceStates[serviceAlias]; - if (ss.RunningState != TRunningState::rs_stopped) - { - nlwarning("startService '%s' : the service is already running", serviceAlias.c_str()); - return false; - } - - // store the start date - ss.StartRequestDate = CTime::getSecondsSince1970(); - - } - if (_RegisteredServices.find(serviceAlias) == _RegisteredServices.end()) - { - nlwarning("startService '%s' : the service in not registered, can't start it", serviceAlias.c_str()); - return false; - } - - // write the start command - bool ret = writeServiceLaunchCtrl(serviceAlias, false, LAUNCH_CTRL_START); - - return ret; - } - - bool stopService(const std::string &serviceAlias) - { - // check that the service is running - TServiceStates::iterator it(_ServiceStates.find(serviceAlias)); - if (it == _ServiceStates.end()) - { - nlwarning("stopService : Failed to found service '%s' in the list of services", serviceAlias.c_str()); - return false; - } - - TServiceState &ss = it->second; - // write the launch control to stop - if (_RegisteredServices.find(serviceAlias) != _RegisteredServices.end()) - { - if (!writeServiceLaunchCtrl(serviceAlias, false, LAUNCH_CTRL_STOP)) - { - nlwarning("Failed to write launch control file for service '%s'", serviceAlias.c_str()); - return false; - } - else - nlinfo("Service '%s' launch control file updated", serviceAlias.c_str()); - } - - // set the stopre request date if needed - if (ss.StopRequestDate != 0) - { - ss.StopRequestDate = CTime::getSecondsSince1970(); - } - - if (ss.ServiceModule == NULL) - { - nlwarning("stopService : The service '%s' is not connected, can't ask him to stop", serviceAlias.c_str()); - return false; - } - - // send the "quit" command to the service - CAdminExecutorServiceClientProxy aec(ss.ServiceModule); - nlinfo("Sending command 'quit' to service '%s'", serviceAlias.c_str()); - aec.serviceCmdNoReturn(this, "quit"); - - return true; - } - - - /////////////////////////////////////////////////////////////////////// - //// Virtuals from IModuleTrackerCb - /////////////////////////////////////////////////////////////////////// - - virtual void onTrackedModuleUp(IModuleProxy *moduleProxy) - { - nldebug("Service module '%s' UP", moduleProxy->getModuleName().c_str()); - - - TParsedCommandLine pcl; - if (!pcl.parseParamList(moduleProxy->getModuleManifest())) - { - nlwarning("CAdminExecutorService:onTrackedModuleUp : failed to parse manifest"); - } - - const TParsedCommandLine *pclLongName = pcl.getParam("LongName"); - const TParsedCommandLine *pclShortName = pcl.getParam("ShortName"); - const TParsedCommandLine *pclAliasName = pcl.getParam("AliasName"); - const TParsedCommandLine *pclPID = pcl.getParam("PID"); - const TParsedCommandLine *pclDontUseShardOrders = pcl.getParam("DontUseShardOrders"); - - string aliasName = pclAliasName != NULL ? pclAliasName->ParamValue : moduleProxy->getModuleName(); - - // remove the temporary state and update connected service index - _ServiceStates.erase(moduleProxy->getModuleName()); - _ConnectedServiceIndex[moduleProxy] = aliasName; - - nlinfo("AES client module %s for service %s is up", - moduleProxy->getModuleName().c_str(), - aliasName.c_str()); - - // create a new entry or get an existing one - TServiceState &ss = _ServiceStates[aliasName]; - // update the service state - ss.RunningState = TRunningState::rs_online; - if (pclDontUseShardOrders) - NLMISC::fromString(pclDontUseShardOrders->ParamValue, ss.DontUseShardOrders); - else - ss.DontUseShardOrders = false; - ss.LongName = pclLongName != NULL ? pclLongName->ParamValue : "unknown"; - ss.ShortName = pclShortName != NULL ? pclShortName->ParamValue : "unknown"; - - if (pclPID!= NULL) - { - NLMISC::fromString(pclPID->ParamValue, ss.PID); - } - else - { - ss.PID = 0; - } - - ss.State = ""; - ss.LastStateDate = NLMISC::CTime::getSecondsSince1970(); - ss.ServiceModule = moduleProxy; - ss.StartRequestDate = 0; - ss.RunningTags.erase(TRunningTag::rt_slow_to_start); - if (_RegisteredServices.find(aliasName) == _RegisteredServices.end()) - { - ss.RunningTags.insert(TRunningTag::rt_externaly_started); - } -// else -// { -// // if this service is locally stopped or if the shard it belong to is stopped, -// // then flag it as 'localy started' -// if (_PersistentServiceOrders.find(aliasName) != _PersistentServiceOrders.end() -// && _PersistentServiceOrders[aliasName] == TRunningOrders::ro_stopped) -// { -// // flag it as started -// _PersistentServiceOrders[aliasName] = TRunningOrders::ro_running; -// ss.RunningTags.insert(TRunningTag::rt_locally_started); -// _NeedToWriteStateFile = true; -// } -// else if (_ShardOrders.find(ss.ShardName) != _ShardOrders.end() -// && _ShardOrders[ss.ShardName] == TRunningOrders::ro_stopped) -// { -// // the shard is stopped, flag the service as started -// _PersistentServiceOrders[aliasName] = TRunningOrders::ro_running; -// ss.RunningTags.insert(TRunningTag::rt_locally_started); -// _NeedToWriteStateFile = true; -// } -// } - - sendUpServiceUpdate(); - } - virtual void onTrackedModuleDown(IModuleProxy *moduleProxy) - { - nldebug("Service module '%s' DOWN", moduleProxy->getModuleName().c_str()); - - TConnectedServiceIndex::iterator it(_ConnectedServiceIndex.find(moduleProxy)); - if (it != _ConnectedServiceIndex.end()) - { - string &aliasName = it->second; - nlinfo("AES client module %s of service %s is down", - moduleProxy->getModuleName().c_str(), - aliasName.c_str()); - BOMB_IF(_ServiceStates.find(aliasName) == _ServiceStates.end(), "Service down from "<getModuleName()<<" with alias "< 1) - { - nlinfo("Killing process %u (%s) because aes client module '%s' is down", - ss.PID, - aliasName.c_str(), - moduleProxy->getModuleName().c_str()); - killProgram(ss.PID); - } - } - -retry_pending_command_loop: - // check for pending command - TPendingWebCommands::iterator first(_PendingWebCommands.begin()), last(_PendingWebCommands.end()); - for (; first != last; ++first) - { - TPendingWebCommand &pwc = first->second; - if (pwc.ServiceAlias == aliasName) - { - if (_AdminService != NULL) - { - CAdminServiceProxy as(_AdminService); - as.commandResult(this, first->first, pwc.ServiceAlias, "ERROR : AES : service connection lost during command"); - } - - _PendingWebCommands.erase(first); - // goto to avoid iterator dodging - goto retry_pending_command_loop; - - } - } - - // remove the index record - _ConnectedServiceIndex.erase(it); - } - else - { - nlinfo("AES client module %s is not associated with a service", - moduleProxy->getModuleName().c_str()); - } - - - sendUpServiceUpdate(); - } - - /////////////////////////////////////////////////////////////////////// - //// Virtuals from CAdminExecutorServiceSkel - /////////////////////////////////////////////////////////////////////// - - // AS send orders for a shard - virtual void setShardOrders(NLNET::IModuleProxy *sender, const std::string &shardName, const TShardOrders &shardOrders) - { - nlinfo("AS setShardOrders for shard '%s' to '%s'", shardName.c_str(), shardOrders.toString().c_str()); - - if (_ShardOrders[shardName] == shardOrders) - { - // nothing to do - return; - } - _ShardOrders[shardName] = shardOrders; - _NeedToWriteStateFile = true; - - // nothing more to do, if service need to be started, they are started - // by the module update function - - } - - // AS send a command to shutdown a shard with a delay - virtual void shutdownShard(NLNET::IModuleProxy *sender, const std::string &shardName, uint32 delay) - { - TStopingShardInfo ssi; - ssi.ShardName = shardName; - ssi.Delay = delay; - ssi.BeginDate = CTime::getSecondsSince1970(); - - _StopingShards.push_back(ssi); - - nlinfo("Received command to stop all service of shard %s in %us", ssi.ShardName.c_str(), ssi.Delay); - - // force a first update (to send the first warning message or stop immediately) - checkServiceToStop(); - - } - - // AS send a control command to this AES - virtual void controlCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - // create a displayer to gather the output of the command - class CStringDisplayer: public IDisplayer - { - public: - virtual void doDisplay( const CLog::TDisplayInfo& args, const char *message) - { - _Data += message; - } - - std::string _Data; - }; - - nldebug("Control command from '%s' : '%s' '%s'", - sender->getModuleName().c_str(), - serviceAlias.c_str(), - command.c_str()); - - // look in the list of service for a matching one - IModuleProxy *service = findOnlineService(serviceAlias); - if (service == NULL && _RegisteredServices.find(serviceAlias) == _RegisteredServices.end()) - { - CAdminServiceProxy as(sender); - as.commandResult(this, commandId, serviceAlias, "ERROR : AES : service not found will dispatching the control command"); - return; - } - - // ok, we can execute the command concerning the service. - CStringDisplayer stringDisplayer; - IService::getInstance()->CommandLog.addDisplayer(&stringDisplayer); - - // build the command line - CSString args(command); - CSString cmdName = args.firstWord(true); - CSString cmdLine; - cmdLine << getCommandHandlerName() << "." << cmdName << " " << serviceAlias << " " << args; - // retrieve the command from the input message and execute it - nlinfo ("ADMIN: Executing control command : '%s' for service '%s'", cmdLine.c_str(), serviceAlias.c_str()); - ICommand::execute (cmdLine, IService::getInstance()->CommandLog); - - // unhook our displayer as it's work is now done - IService::getInstance()->CommandLog.removeDisplayer(&stringDisplayer); - - // send the result back to AS - CAdminServiceProxy as(sender); - as.commandResult(this, commandId, serviceAlias, stringDisplayer._Data); - } - - //The return is sent back by another message - virtual void serviceCmd(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &command) - { - // look in the list of service for a matching one - IModuleProxy *proxy = findOnlineService(serviceAlias); - if (proxy == NULL) - { - CAdminServiceProxy as(sender); - as.commandResult(this, commandId, serviceAlias, "ERROR AES : unknown service"); - return; - } - - // ok, we found it ! - TPendingWebCommand pwc; - pwc.Command = command; - pwc.ReceptionDate = NLMISC::CTime::getSecondsSince1970(); - pwc.ServiceAlias = serviceAlias; - - _PendingWebCommands.insert(make_pair(commandId, pwc)); - - CAdminExecutorServiceClientProxy service(proxy); - service.serviceCmd(this, commandId, command); - } - - // AES client send back the result of execution of a command - virtual void commandResult(NLNET::IModuleProxy *sender, uint32 commandId, const std::string &serviceAlias, const std::string &result) - { - // check for waiting commands - TPendingWebCommands::iterator it(_PendingWebCommands.find(commandId)); - - if (it == _PendingWebCommands.end()) - { - if (commandId != 0) - nlwarning("CAdminExecutor::commandResult : service '%s' sent result for command ID %u but not in pending command table", - sender->getModuleName().c_str(), - commandId); - return; - } - - // send the result back to AS - if (_AdminService != NULL) - { - CAdminServiceProxy as(_AdminService); - - as.commandResult(this, commandId, serviceAlias, result); - } - - _PendingWebCommands.erase(commandId); - } - - - // An AES send graph data update - virtual void graphUpdate(NLNET::IModuleProxy *sender, const TGraphDatas &graphDatas) - { - if (_AdminService != NULL) - { - CAdminServiceProxy as(_AdminService); - as.graphUpdate(this, graphDatas); - } - } - - // A service high rez graph data update - virtual void highRezGraphUpdate(NLNET::IModuleProxy *sender, const THighRezDatas &graphDatas) - { - if (_AdminService != NULL) - { - CAdminServiceProxy as(_AdminService); - as.highRezGraphUpdate(this, graphDatas); - } - } - - // A service send an update of of it's status string - virtual void serviceStatusUpdate(NLNET::IModuleProxy *sender, const std::string &status) - { - TConnectedServiceIndex::iterator it(_ConnectedServiceIndex.find(sender)); - if (it == _ConnectedServiceIndex.end()) - { - nlwarning("serviceStatusUpdate : service '%s' send status but is unknown !", sender->getModuleName().c_str()); - return; - } - - string &aliasName = it->second; - TServiceStates::iterator it2(_ServiceStates.find(aliasName)); - BOMB_IF(it2 == _ServiceStates.end(), "serviceStateUpdate : service '" - <getModuleName() - <<"' send an update, but alias '"<second; - ss.State = status; - ss.LastStateDate = NLMISC::CTime::getSecondsSince1970(); - } - - - /////////////////////////////////////////////////////////////////////// - //// commands handlers - /////////////////////////////////////////////////////////////////////// - NLMISC_COMMAND_HANDLER_TABLE_EXTEND_BEGIN(CAdminExecutorService, CModuleBase) - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, dump, "Dump a status report to appropriate output logger", "no args") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, addRegisteredService, "add a registered service", " ") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, removeRegisteredService, "remove a registered service", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, startService, "start a registered service", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, restartService, "stop then start a registered service", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, stopService, "stop a service (registered or not)", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, killService, "kill a (possibly not responding) service (registered or not)", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, abortService, "abort a (possibly not responding) service with SIGABORT (registered or not)", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, activateService, "activate a service, i.e make it startable either manually or from a shard orders", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, deactivateService, "deactivate a service, i.e make it unstartable (either manually or from a shard orders) and stop it if needed", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, execScript, "execute the predefined bash script '/home/nevrax/patchman/aes_runnable_script.sh' and give it the passed parameters", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, resetStartCounter, "reset the start counter to 0", "no params") - NLMISC_COMMAND_HANDLER_ADD(CAdminExecutorService, stopShard, "Stop all service of a given shard aftert the provided delay", " ") - NLMISC_COMMAND_HANDLER_TABLE_END - - - NLMISC_CLASS_COMMAND_DECL(stopShard) - { - if (args.size() != 2) - return false; - - string shardName = args[0]; - uint32 delay; - NLMISC::fromString(args[1], delay); - - log.displayNL("Received command to stop all service of shard %s in %us", shardName.c_str(), delay); - - shutdownShard(NULL, shardName, delay); - - return true; - } - - - NLMISC_CLASS_COMMAND_DECL(resetStartCounter) - { - if (args.size() != 0) - return false; - - - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - TServiceState &ss = first->second; - - ss.RunnerLoopCounter.resetCounter(); - } - - return true; - } - - - NLMISC_CLASS_COMMAND_DECL(execScript) - { - string cmdLine("/home/nevrax/patchman/aes_runnable_script.sh"); - - // add parameters - for (uint i=0; i lines; - output.splitLines(lines); - - log.displayNL("Command returned value %d", ret); - log.displayNL("-------------------- Command output begin -----------------------"); - for (uint i=0; isecond; - if (ss.RunningState == TRunningState::rs_stopped) - { - log.displayNL("The service to abort '%s' is currently stopped", serviceAlias.c_str()); - return true; - } - if (ss.PID < 2) - { - log.displayNL("AES have no valid PID to abort the service '%s'", serviceAlias.c_str()); - return true; - } - - // abort it - log.displayNL("Aborting service '%s' with pid %u", serviceAlias.c_str(), ss.PID); - abortProgram(ss.PID); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(killService) - { - if (args.size() != 1) - return false; - - string serviceAlias = args[0]; - - // check that the service is running - TServiceStates::iterator it(_ServiceStates.find(serviceAlias)); - if (it == _ServiceStates.end()) - { - log.displayNL("Failed to found service '%s' in the list of running services", serviceAlias.c_str()); - return true; - } - - TServiceState &ss = it->second; - if (ss.RunningState == TRunningState::rs_stopped) - { - log.displayNL("The service to kill '%s' is currently stopped", serviceAlias.c_str()); - return true; - } - if (ss.PID < 2) - { - log.displayNL("AES have no valid PID to kill the service '%s'", serviceAlias.c_str()); - return true; - } - // kill it - log.displayNL("Killing service '%s' with pid %u", serviceAlias.c_str(), ss.PID); - killProgram(ss.PID); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(stopService) - { - if (args.size() != 1) - return false; - - string serviceAlias = args[0]; - - if (_ServiceStates.find(serviceAlias) == _ServiceStates.end()) - { - log.displayNL("Unknown service '%s', could not stop it", serviceAlias.c_str()); - return true; - } - - TServiceState &ss = _ServiceStates[serviceAlias]; - // look for a shard orders for this service - TShardsOrders::iterator it(_ShardOrders.find(ss.ShardName)); - if (it != _ShardOrders.end()) - { - TShardOrders &so = it->second; - if (so == TShardOrders::so_autostart_on) - { - log.displayNL("Can't stop service '%s' because shard '%s' is autostarting, considers either to deactivate the service or just restart it", - serviceAlias.c_str(), - ss.ShardName.c_str()); - return true; - } - } - - if (stopService(serviceAlias)) - log.displayNL("Failed to stop the service '%s'", serviceAlias.c_str()); - else - log.displayNL("Service '%s' stop request done", serviceAlias.c_str()); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(restartService) - { - if (args.size() != 1) - return false; - - string serviceAlias = args[0]; - - if (_RegisteredServices.find(serviceAlias) == _RegisteredServices.end()) - { - log.displayNL("startService %s : the service in not registered, can't restart it", serviceAlias.c_str()); - return true; - } - - // look for service orders for this service - if (_PersistentServiceOrders.find(serviceAlias) != _PersistentServiceOrders.end()) - { - if (_PersistentServiceOrders[serviceAlias] == TRunningOrders::ro_deactivated) - { - log.displayNL("Can't restart service '%s' because it is currently deactivated", serviceAlias.c_str()); - return true; - } - } - - - - // check that the service is running - TServiceStates::iterator it(_ServiceStates.find(serviceAlias)); - if (it == _ServiceStates.end()) - { - log.displayNL("Failed to found service '%s' in the list of running services", serviceAlias.c_str()); - return true; - } - - // write the deferred start command - if (!writeServiceLaunchCtrl(serviceAlias, true, LAUNCH_CTRL_START)) - { - log.displayNL("Failed to write deferred start control file to restart service '%s'", serviceAlias.c_str()); - return true; - } - else - log.displayNL("Service '%s' start command written", serviceAlias.c_str()); - - if (it->second.ServiceModule == NULL) - { - log.displayNL("The AES client module proxy is null ! can't send 'quit' command"); - } - - // send the "quit" command to the service - CAdminExecutorServiceClientProxy aec(it->second.ServiceModule); - aec.serviceCmd(this, 0, "quit"); - log.displayNL("Service '%s' command 'quit' sent", serviceAlias.c_str()); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(startService) - { - if (args.size() != 1) - return false; - - string serviceAlias = args[0]; - - if (_ServiceStates.find(serviceAlias) == _ServiceStates.end()) - { - log.displayNL("Unknown service '%s', could not start it", serviceAlias.c_str()); - return true; - } - - TServiceState &ss = _ServiceStates[serviceAlias]; - - // look for service orders for this service - if (_PersistentServiceOrders.find(serviceAlias) != _PersistentServiceOrders.end()) - { - if (_PersistentServiceOrders[serviceAlias] == TRunningOrders::ro_deactivated) - { - log.displayNL("Can't start service '%s' because it is curently deactivated", serviceAlias.c_str()); - return true; - } - } - - // look for a shard orders for this service - TShardsOrders::iterator it(_ShardOrders.find(ss.ShardName)); - if (it != _ShardOrders.end()) - { - TShardOrders &so = it->second; - if (so == TShardOrders::so_autostart_on) - { - log.displayNL("Can't start service '%s' because shard '%s' is autostarting, consider to restart it", - serviceAlias.c_str(), - ss.ShardName.c_str()); - return true; - } - } - - if (!startService(serviceAlias)) - log.displayNL("Failed to start service '%s'", serviceAlias.c_str()); - else - log.displayNL("Service '%s' start command written", serviceAlias.c_str()); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(removeRegisteredService) - { - if (args.size() != 1) - return false; - - string serviceAlias = args[0]; - - if (_ServiceStates.find(serviceAlias) == _ServiceStates.end()) - { - log.displayNL("Unknown service '%s', could not start it", serviceAlias.c_str()); - return true; - } - - TServiceState &ss = _ServiceStates[serviceAlias]; - - _RegisteredServices.erase(serviceAlias); - - if (ss.RunningState == TRunningState::rs_stopped) - { - // remove the record - _ServiceStates.erase(serviceAlias); - } - else - { - // just update some data related the registered service - ss.ShardName = ""; - ss.RunningTags.erase(TRunningTag::rt_locally_started); - ss.RunningTags.erase(TRunningTag::rt_chain_crashing); - ss.RunningTags.insert(TRunningTag::rt_externaly_started); - } - - - _PersistentServiceOrders.erase(serviceAlias); - _NeedToWriteStateFile = true; - - // update the state of services to the AS - sendUpServiceUpdate(); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(addRegisteredService) - { - if (args.size() != 2) - return false; - - string serviceAlias = args[0]; - string shardName = args[1]; - - _RegisteredServices.insert(serviceAlias); - _ServiceStates.insert(make_pair(serviceAlias, TServiceState())); - _ServiceStates[serviceAlias].ShardName = shardName; -// _ServiceRunnerLoopCounters.insert(make_pair(serviceAlias, TRunnerLoopCounter())); - - if (_PersistentServiceOrders.find(serviceAlias) == _PersistentServiceOrders.end()) - { - _PersistentServiceOrders[serviceAlias] = TRunningOrders::ro_activated; - _NeedToWriteStateFile = true; - } - - // update the state of services to the AS - sendUpServiceUpdate(); - - return true; - } - - NLMISC_CLASS_COMMAND_DECL(dump) - { - NLMISC_CLASS_COMMAND_CALL_BASE(CModuleBase, dump); - - log.displayNL("==============================="); - log.displayNL(" Dumping Admin executor states"); - log.displayNL("==============================="); - - { - log.displayNL(" There are %u known shard :", _ShardOrders.size()); - { - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - log.displayNL(" + Shard '%s' orders is '%s'", first->first.c_str(), first->second.toString().c_str()); - } - } - if (_ShutdownForPatch) - log.displayNL(" All service are shuting down for patch !"); - log.displayNL(" There are %u known services :", _ServiceStates.size()); - TServiceStates::iterator first(_ServiceStates.begin()), last(_ServiceStates.end()); - for (; first != last; ++first) - { - TServiceState &ss = first->second; - const string &aliasName = first->first; - - CSString runningTags; - set::iterator rtf(ss.RunningTags.begin()), rte(ss.RunningTags.end()); - for (; rtf != rte; ++rtf) - { - runningTags<<"<"<toString()<<">"; - } - - bool registered = _RegisteredServices.find(aliasName) != _RegisteredServices.end(); - - log.displayNL(" + Service alias='%s' (%s) ShardName = '%s' RunningState='%s' RunningTag='%s'", - aliasName.c_str(), - registered ? "REGISTERED" : "NOT REGISTERED", - ss.ShardName.c_str(), - ss.RunningState.toString().c_str(), - runningTags.c_str()); - - log.display(" | %s", ss.DontUseShardOrders ? "DontUseShardOders" : "UseShardOrders"); - - if (ss.RunningState != TRunningState::rs_stopped) - { - // the pid should be valid - log.display(" PID=%u", ss.PID); - } - if (registered) - { - log.display(" ServiceOrders=%s", _PersistentServiceOrders[aliasName].toString().c_str()); - } - log.displayNL(""); - - - if (ss.ServiceModule != NULL) - { - // dump a connected service - log.displayNL(" | longName='%s' shortName='%s' moduleName='%s'", - ss.LongName.c_str(), - ss.ShortName.c_str(), - ss.ServiceModule->getModuleName().c_str()); - log.displayNL(" | State '%s' (last received %sago)", ss.State.c_str(), NLMISC::CTime::getHumanRelativeTime(NLMISC::CTime::getSecondsSince1970() - ss.LastStateDate).c_str()); - } - else - { - // dump a offline registered service - // dump a connected service - log.displayNL(" | longName='%s' shortName='%s' ", - ss.LongName.c_str(), - ss.ShortName.c_str()); - log.displayNL(" | State '%s' (last received %sago)", ss.State.c_str(), NLMISC::CTime::getHumanRelativeTime(NLMISC::CTime::getSecondsSince1970() - ss.LastStateDate).c_str()); - } - if (registered) - { - uint32 c1, c2, c3; - ss.RunnerLoopCounter.getCounters(c1, c2, c3); - log.displayNL(" | Service Runner Start counter (%u mn:%u run, %u mn:%u run, %u mn:%u run)", - CRASH_COUNTER_ROLL_DELAY/60, c1, - (CRASH_COUNTER_ROLL_DELAY*3)/60, c2, - (CRASH_COUNTER_ROLL_DELAY*CRASH_COUNTER_SLOT)/60, c3); - } - } - } - - return true; - } - - - }; - - NLNET_REGISTER_MODULE_FACTORY(CAdminExecutorService, "AdminExecutorService"); - -} // namespace ADMIN - diff --git a/code/ryzom/server/src/admin_modules/as_module.cpp b/code/ryzom/server/src/admin_modules/as_module.cpp deleted file mode 100644 index b5f8c6fd1..000000000 --- a/code/ryzom/server/src/admin_modules/as_module.cpp +++ /dev/null @@ -1,1063 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "nel/misc/types_nl.h" -#include -#include "nel/misc/file.h" -#include "nel/misc/common.h" -#include "nel/misc/sstring.h" -#include "nel/misc/mutable_container.h" -#include "nel/net/service.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" - -#include "admin_modules_itf.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; - - -void as_forceLink() {} - -namespace ADMIN -{ - - /// name of the persistent state file - const char *ASPersistentStateFilename = "as_state.txt"; - - class CAdminService - : public CEmptyModuleServiceBehav > >, - CAdminServiceSkel, - CAdminServiceWebItf, - IModuleTrackerCb - { - - enum - { - /// The maximum time without report from an AES before flagging it as 'not responding' - AES_REPORT_WARNING_DELAY = 5, - }; - - typedef CModuleTracker TAESTracker; - /// Tracker for EAS modules - TAESTracker _AESTracker; - - struct TAESServices - { - /// The date of last report send by this AES. Used to display 'not responding' AES - uint32 LastReportDate; - /// The list of service known by this AES - vector ServiceStatus; - - TAESServices() - : LastReportDate(0) - {} - }; - - /// all known service status by known AES - typedef map TKnownServices; - TKnownServices _KnownServices; - - /// data for a command comming form web and waiting execution by the module task - struct TPendingWebCommand - { - /// Received command date - uint32 ReceptionDate; - /// Is this a control command (otherwise it's a service command) - bool ControlCommand; - /// Sock id of the web connection that wait the command result - TSockId Requester; - /// Alias of the command target service - string ServiceAlias; - /// the command and it's parameters - string Command; - }; - typedef uint32 TCommandId; - TCommandId _NextCommandId; - typedef map TPendingWebCommands; - /// A stack of web command request to be treated by module task - TPendingWebCommands _PendingWebCommands; - - /// The global running state of the domain -// TRunningOrders _GlobalOrders; - - typedef string TShardName; - - typedef map TShardsOrders; - /// The running state of each shard - TShardsOrders _ShardOrders; - - /// a flag to write the state file at next module update - bool _NeedToWriteStateFile; - - - public: - CAdminService() - : _AESTracker(TModuleClassPred("AdminExecutorService")), - _NextCommandId(0), -// _GlobalOrders(TRunningOrders::ro_running), - _NeedToWriteStateFile(false) - - { - CAdminServiceSkel::init(this); - _AESTracker.init(this, this); - } - - ~CAdminService() - {} - - void setShardOrders(const std::string &shardName, TShardOrders newOrders) - { - _ShardOrders[shardName] = newOrders; -// switch(_GlobalOrders.getValue()) -// { -// case TRunningOrders::ro_stopped: -// IService::getInstance()->addStatusTag("GLOBAL_STOPPED"); -// break; -// case TRunningOrders::ro_running: -// IService::getInstance()->removeStatusTag("GLOBAL_STOPPED"); -// break; -// } - - _NeedToWriteStateFile = true; - - // update all AES with the new state - CAdminExecutorServiceProxy::broadcast_setShardOrders(_AESTracker.getTrackedModules().begin(), _AESTracker.getTrackedModules().end(), - this, shardName, newOrders); - } - - /// Methods called by a module task to handle web command request - void sendCommandToAES(TCommandId commandId, TPendingWebCommand &pwc) - { - // look in the list of known state to retrieve the target of the command - TKnownServices::iterator first(_KnownServices.begin()), last(_KnownServices.end()); - for (; first != last; ++first) - { - const vector &status = first->second.ServiceStatus; - for (uint i=0; ifirst); - - if (pwc.ControlCommand) - { - // this is a control command - aes.controlCmd(this, commandId, pwc.ServiceAlias, pwc.Command); - } - else - { - // this is a service command - aes.serviceCmd(this, commandId, pwc.ServiceAlias, pwc.Command); - } - - // terminate here ! - return; - //----------------------------------------------------- - } - } - } - - // not found ! - CAdminServiceWebItf::commandResult(pwc.Requester, pwc.ServiceAlias, "ERROR : AS : unknown service alias"); - // remove the pending command - _PendingWebCommands.erase(commandId); - } - - - bool initModule(const TParsedCommandLine &pcl) - { - CModuleBase::initModule(pcl); - - // read the command line - const TParsedCommandLine *webPort = pcl.getParam("webPort"); - nlassert(webPort != NULL); - uint16 port; - NLMISC::fromString(webPort->ParamValue, port); - // open the web interface - CAdminServiceWebItf::openItf(port); - - // read the persistent state file if any - string filename = CPath::standardizePath(IService::getInstance()->SaveFilesDirectory.toString(), true)+ASPersistentStateFilename; - FILE *fp = nlfopen(filename, "rt"); - if (fp != NULL) - { - char buffer[1024]; - char *ret; - while ((ret=fgets(buffer, 1024, fp)) != NULL) - { - CSString line(buffer); - string cmd = line.firstWord(true); - - if (cmd == "ShardOrders") - { - string shardName = line.firstWord(true); - string orders = line.firstWord(true); - TShardOrders shardOrders(orders); - if (shardOrders != TShardOrders::invalid_val) - setShardOrders(shardName, shardOrders); - } - } - // clear the flag because 'setGlobalState' has set it - _NeedToWriteStateFile = false; - - fclose(fp); - } - - return true; - } - - void onModuleUpdate() - { - H_AUTO(CAdminService_onModuleUpdate); - - CAdminServiceWebItf::update(); - - if (_NeedToWriteStateFile) - { - string filename = CPath::standardizePath(IService::getInstance()->SaveFilesDirectory.toString(), true)+ASPersistentStateFilename; - FILE *fp = nlfopen(filename, "wt"); - if (fp != NULL) - { - CSString line; - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - line << "ShardOrders "<first<<" "<second.toString()<<"\n"; - } - fputs(line.c_str(), fp); - fclose(fp); - - _NeedToWriteStateFile = false; - } - } - - uint32 now = NLMISC::CTime::getSecondsSince1970(); - - // check for timeout commands - TPendingWebCommands::iterator first(_PendingWebCommands.begin()), last(_PendingWebCommands.end()); - for (; first != last; ++first) - { - TPendingWebCommand &pwc = first->second; - - if (now - pwc.ReceptionDate > 10) - { - CAdminServiceWebItf::commandResult(pwc.Requester, pwc.ServiceAlias, "ERROR : no response from service or AES"); - _PendingWebCommands.erase(first); - // check at next update for the rest - break; - } - } - - { - // save one high rez graph at a time - static string lastCheckedBuffer; - - THighRezBuffers::iterator it(_HighRezBuffers.upper_bound(lastCheckedBuffer)); - if (it == _HighRezBuffers.end()) - lastCheckedBuffer = ""; - else - { - lastCheckedBuffer = it->first; - THighRezBuffer &hrBuffer = it->second; - if (hrBuffer.Dirty) - { - // save this buffer - CMemStream sbuff; - // write the updated buffer - sbuff.serial(hrBuffer); - - string filename = getHighRezBufferFilename(it->first); - NLMISC::COFile of(filename); - - if (of.isOpen()) // test added, because sometime on windows, the file fail to open ! - { - of.serialBuffer((uint8*)sbuff.buffer(), sbuff.size()); - - hrBuffer.Dirty = false; - } - else - { - nlwarning("CAdminService::onUpdateModule : failed to open file %s for writing", filename.c_str()); - } - } - } - } - } - - /////////////////////////////////////////////////////////////////////// - //// Virtuals from IModuleTrackerCb - /////////////////////////////////////////////////////////////////////// - - virtual void onTrackedModuleUp(IModuleProxy *moduleProxy) - { - nldebug("AES module '%s' UP", moduleProxy->getModuleName().c_str()); - - // send it the current global state - CAdminExecutorServiceProxy aes(moduleProxy); - - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - aes.setShardOrders(this, first->first, first->second); - } - } - virtual void onTrackedModuleDown(IModuleProxy *moduleProxy) - { - nldebug("AES module '%s' DOWN", moduleProxy->getModuleName().c_str()); - - - // check for any pending commands with this AES - TAESServices &as = _KnownServices[moduleProxy]; - for (uint i=0; isecond; - if (pwc.ServiceAlias == aliasName) - { - // remove this command - CAdminServiceWebItf::commandResult(pwc.Requester, pwc.ServiceAlias, "ERROR : connection lost with AES during command"); - TCommandId commandId = first->first; - _PendingWebCommands.erase(first); - - // restart the loop to avoid iterator dodging - goto retry_pending_command; - } - } - } - - // remove any service status - _KnownServices.erase(moduleProxy); - - } - - /////////////////////////////////////////////////////////////////////// - //// Virtuals from CAdminServiceSkel - /////////////////////////////////////////////////////////////////////// - - // An AES send an update of the list of service up - virtual void upServiceUpdate(NLNET::IModuleProxy *sender, const std::vector < TServiceStatus > &serviceStatus) - { - if (_AESTracker.getTrackedModules().find(sender) == _AESTracker.getTrackedModules().end()) - { - nlwarning("'%s' send upServiceUpdate but is not an valid AES", sender->getModuleName().c_str()); - return; - } - - _KnownServices[sender].LastReportDate = NLMISC::CTime::getSecondsSince1970(); - _KnownServices[sender].ServiceStatus = serviceStatus; - - // check that we have this shards in the shard orders table - for (uint i=0; iConfigFile.getVar("RRDVarPath").asString()); - rrdfilename << gd.getServiceAlias() <<"." <ConfigFile.getVar("RRDToolPath").asString(), arg); - arg = ""; - } - - arg<<"update "<ConfigFile.getVar("RRDToolPath").asString(), arg); - } - } - - enum - { - HR_BUFFER_SIZE = 5000, - }; - - /// Circular buffer to store high resolution samples - struct THighRezBuffer - { - bool Dirty; - uint32 NBSample; - uint32 FrameStart; - uint32 FrameEnd; // == FrameStart if empty - - struct THighRezItem - { - uint32 Date; - TTime SampleTick; - double Value; - - void serial(NLMISC::IStream &s) - { - s.serial(Date); - s.serial(SampleTick); - s.serial(Value); - } - }; - - vector Datas; - - - THighRezBuffer() - : Dirty(false), - NBSample(HR_BUFFER_SIZE), - FrameStart(0), - FrameEnd(0) - { - Datas.resize(NBSample); - } - - void serial(NLMISC::IStream &s) - { - s.serial(NBSample); - s.serial(FrameStart); - s.serial(FrameEnd); - s.serialCont(Datas); - - if (s.isReading()) - { - // make some adjustment in case of HR_BUFFER_SIZE change - Datas.resize(HR_BUFFER_SIZE); - FrameEnd %= HR_BUFFER_SIZE; - FrameStart %= HR_BUFFER_SIZE; - NBSample = HR_BUFFER_SIZE; - } - } - }; - - typedef map THighRezBuffers; - THighRezBuffers _HighRezBuffers; - - string getHighRezBufferFilename(const std::string &varAddr) - { - CSString filename = CPath::standardizePath (IService::getInstance()->ConfigFile.getVar("RRDVarPath").asString()); - filename << varAddr<<".hrd"; - - return filename; - } - - // An AES send high rez graph data update - virtual void highRezGraphUpdate(NLNET::IModuleProxy *sender, const THighRezDatas &graphDatas) - { - // dump the datas -// nldebug("Received high rez graph info for var %s from service %s", -// graphDatas.getServiceName().c_str(), -// graphDatas.getVarName().c_str()); -// -// for (uint i=0; igetModuleClassName().c_str(), - serviceName.c_str(), - commandId); - return; - } - - TPendingWebCommand &pwc = it->second; - - CAdminServiceWebItf::commandResult(pwc.Requester, pwc.ServiceAlias, result); - - // erase this command - _PendingWebCommands.erase(it); - } - - - // An AES send it's updated state strings -// virtual void updateAESStates(NLNET::IModuleProxy *sender, const std::vector < std::string > &states) -// { -// nlstop; -// } - - // AES send back the result of execution of a control command - virtual void controlCmdResult(NLNET::IModuleProxy *sender, const std::string &serviceName, const std::vector < std::string > &result) - { - nlstop; - } - - - /////////////////////////////////////////////////////////////////////// - //// Virtuals from CAdminServiceWebItf - /////////////////////////////////////////////////////////////////////// - - /// Connection callback : a new interface client connect - virtual void on_CAdminServiceWeb_Connection(NLNET::TSockId from) - { - } - /// Disconnection callback : one of the interface client disconnect - virtual void on_CAdminServiceWeb_Disconnection(NLNET::TSockId from) - { - } - - - // This is used to issue global commands like 'as.allStart' or 'as.allStop'. - // The result is returned by the return message - // serviceCmdResult. - virtual void on_globalCmd(NLNET::TSockId from, const std::string &command) - { - // create a displayer to gather the output of the command - class CStringDisplayer: public IDisplayer - { - public: - virtual void doDisplay( const CLog::TDisplayInfo& args, const char *message) - { - _Data += message; - } - - std::string _Data; - }; - - nldebug("Global command from web : '%s'", - command.c_str()); - - // ok, we can execute the command concerning the service. - CStringDisplayer stringDisplayer; - IService::getInstance()->CommandLog.addDisplayer(&stringDisplayer); - - // build the command line - CSString cmdLine; - cmdLine << getCommandHandlerName() << "." << command; - // retrieve the command from the input message and execute it - nlinfo ("ADMIN: Executing global command : '%s'", cmdLine.c_str()); - ICommand::execute (cmdLine, IService::getInstance()->CommandLog); - - // unhook our displayer as it's work is now done - IService::getInstance()->CommandLog.removeDisplayer(&stringDisplayer); - - // send the result back to the web - CAdminServiceWebItf::commandResult(from, "", stringDisplayer._Data); - } - - // Send a service related command to the executor - // (not to the controled service) - // The return value is a string containing the content - // returned by the command. - virtual void on_controlCmd(NLNET::TSockId from, const std::string &serviceAlias, const std::string &command) - { - // push the request info - TPendingWebCommand pwc; - pwc.ReceptionDate = NLMISC::CTime::getSecondsSince1970(); - pwc.Command = command; - pwc.ControlCommand = true; - pwc.Requester = from; - pwc.ServiceAlias = serviceAlias; - - _PendingWebCommands.insert(make_pair(_NextCommandId, pwc)); - - // send the request to the AES - sendCommandToAES(_NextCommandId++, pwc); - } - - // Send a command to the AS. - // Send a command to a service. - // The return value is a string containing the content returned by the - virtual void on_serviceCmd(NLNET::TSockId from, const std::string &serviceAlias, const std::string &command) - { - // push the request info - TPendingWebCommand pwc; - pwc.ReceptionDate = NLMISC::CTime::getSecondsSince1970(); - pwc.Command = command; - pwc.ControlCommand = false; - pwc.Requester = from; - pwc.ServiceAlias = serviceAlias; - - _PendingWebCommands.insert(make_pair(_NextCommandId, pwc)); - - // send the request to the AES - sendCommandToAES(_NextCommandId++, pwc); - } - - - // Get the orders of each known shard. - // The return value is a vector of string, one entry by shard - virtual std::vector on_getShardOrders(NLNET::TSockId from) - { - vector ret; - - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - CSString orders; - - orders << "ShardName=" << first->first; - orders << "\tOrders=" << first->second.toString(); - - ret.push_back(orders); - } - - - return ret; - } - - // Get the last known state of all services. - // The return value is a vector of string, one entry by service - virtual std::vector on_getStates(NLNET::TSockId from) - { - uint32 now = NLMISC::CTime::getSecondsSince1970(); - vector ret; - TAESTracker::TTrackedModules::iterator first(_AESTracker.getTrackedModules().begin()), last(_AESTracker.getTrackedModules().end()); - for (; first != last; ++first) - { - IModuleProxy *aes = *first; - const vector &status = _KnownServices[*first].ServiceStatus; - - uint32 aesStallDelay = now - _KnownServices[*first].LastReportDate; - bool aesStall = aesStallDelay > AES_REPORT_WARNING_DELAY; - - for (uint i=0; i") -// NLMISC_COMMAND_HANDLER_ADD(CAdminService, stopShard, "stop a shard in the controled domain", "") - NLMISC_COMMAND_HANDLER_ADD(CAdminService, setShardStartMode, "set the autostart mode of a shard", " on|off") - NLMISC_COMMAND_HANDLER_ADD(CAdminService, stopShard, "stop all service of a shard with a programmable timer (can be 0 for immediate shutdown)", " ") - NLMISC_COMMAND_HANDLER_TABLE_END - - NLMISC_CLASS_COMMAND_DECL(setShardStartMode) - { - if (args.size() != 2) - return false; - - string shardName = args[0]; - - if (_ShardOrders.find(shardName) == _ShardOrders.end()) - { - log.displayNL("Unknown shard '%s'", shardName.c_str()); - return true; - } - - TShardOrders shardOrders; - if (args[1] == "on") - shardOrders = TShardOrders::so_autostart_on; - else if (args[1] == "off") - shardOrders = TShardOrders::so_autostart_off; - else - { - log.displayNL("Invalid option '%s', must be 'on' or 'off'", args[1].c_str()); - return true; - } - - setShardOrders(shardName, shardOrders); - - return true; - } - - - -// NLMISC_CLASS_COMMAND_DECL(startShard) -// { -// if (args.size() != 1) -// return false; -// -// string shardName = args[0]; -// -// if (_ShardOrders.find(shardName) == _ShardOrders.end()) -// { -// log.displayNL("Unknown shard '%s'", shardName.c_str()); -// return true; -// } -// -// setShardOrders(shardName, TRunningOrders::ro_running); -// -// return true; -// } - -// NLMISC_CLASS_COMMAND_DECL(stopShard) -// { -// if (args.size() != 1) -// return false; -// -// string shardName = args[0]; -// -// if (_ShardOrders.find(shardName) == _ShardOrders.end()) -// { -// log.displayNL("Unknown shard '%s'", shardName.c_str()); -// return true; -// } -// -// setShardOrders(shardName, TRunningOrders::ro_stopped); -// -// return true; -// } -// - -// NLMISC_CLASS_COMMAND_DECL(allStart) -// { -// if (args.size() != 0) -// return false; -// -// setGlobalOrders(TRunningOrders::ro_running); -// -// return true; -// } -// -// NLMISC_CLASS_COMMAND_DECL(allStop) -// { -// if (args.size() != 0) -// return false; -// -// setGlobalOrders(TRunningOrders::ro_stopped); -// -// return true; -// } - - NLMISC_CLASS_COMMAND_DECL(stopShard) - { - if (args.size() != 2) - return false; - - string shardName = args[0]; - uint32 delay; - NLMISC::fromString(args[1], delay); - - if (_ShardOrders.find(shardName) == _ShardOrders.end()) - { - log.displayNL("Unknown shard '%s'", shardName.c_str()); - return true; - } - - // dispatch the request to all AES (they will apply to the pertinent service) - CAdminExecutorServiceProxy::broadcast_shutdownShard(_AESTracker.getTrackedModules().begin(), _AESTracker.getTrackedModules().end(), - this, shardName, delay); - - return true; - } - - - NLMISC_CLASS_COMMAND_DECL(dump) - { - NLMISC_CLASS_COMMAND_CALL_BASE(CModuleBase, dump); - - log.displayNL("==============================="); - log.displayNL(" Dumping Admin states"); - log.displayNL("==============================="); - -// log.displayNL(" Global orders is '%s'", _GlobalOrders.toString().c_str()); - - log.displayNL(" There are %u known shards :", _ShardOrders.size()); - { - TShardsOrders::iterator first(_ShardOrders.begin()), last(_ShardOrders.end()); - for (; first != last; ++first) - { - log.displayNL(" + Shard '%s' is '%s'", first->first.c_str(), first->second.toString().c_str()); - } - } - log.displayNL(" There are %u AES services :", _AESTracker.getTrackedModules().size()); - TAESTracker::TTrackedModules::iterator first(_AESTracker.getTrackedModules().begin()), last(_AESTracker.getTrackedModules().end()); - for (; first != last; ++first) { - IModuleProxy *aes = *first; - const vector &status = _KnownServices[*first].ServiceStatus; - log.displayNL(" + AES '%s', with %u connected services", - aes->getModuleName().c_str(), - status.size()); - - for (uint i=0; i -// 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 . - -#include "stdpch.h" diff --git a/code/ryzom/server/src/admin_modules/stdpch.h b/code/ryzom/server/src/admin_modules/stdpch.h deleted file mode 100644 index be01e5019..000000000 --- a/code/ryzom/server/src/admin_modules/stdpch.h +++ /dev/null @@ -1,45 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef ADMIN_MODULES_STDPCH_H -#define ADMIN_MODULES_STDPCH_H - -#include -#include - -#include "nel/misc/types_nl.h" - -#include "nel/misc/file.h" -#include "nel/misc/hierarchical_timer.h" -#include "nel/misc/mutable_container.h" -#include "nel/misc/path.h" -#include "nel/misc/singleton.h" -#include "nel/misc/sstring.h" -#include "nel/misc/string_conversion.h" -#include "nel/misc/time_nl.h" -#include "nel/net/message.h" -#include "nel/net/module.h" -#include "nel/net/module_builder_parts.h" -#include "nel/net/module_gateway.h" -#include "nel/net/module_manager.h" -#include "nel/net/module_message.h" -#include "nel/net/service.h" -#include "nel/net/unified_network.h" - -#include "game_share/callback_adaptor.h" -#include "game_share/utils.h" - -#endif diff --git a/code/ryzom/server/src/ags_test/actor.cpp b/code/ryzom/server/src/ags_test/actor.cpp deleted file mode 100644 index d1ad94bbe..000000000 --- a/code/ryzom/server/src/ags_test/actor.cpp +++ /dev/null @@ -1,1166 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -// Nel Misc -#include "nel/misc/command.h" -#include "nel/misc/path.h" -#include "nel/net/message.h" -#include "nel/net/unified_network.h" -#include "nel/misc/aabbox.h" - -//#include "combat_interface.h" - -// Game share -#include "game_share/tick_event_handler.h" -#include "game_share/synchronised_message.h" -//#include "game_share/msg_brick_service.h" - -// Local includes -#include "actor.h" -#include "actor_manager.h" -#include "move_manager.h" -#include "sheets.h" -#include "mirrors.h" -#include "actor_group.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace NLPACS; -using namespace std; - -namespace AGS_TEST -{ - -#define DT_TEMP 200 - -//---------------------------------------------------------------------------------- -CActor::CActor(const std::string &type, const std::string &name, const CEntityId &id, bool &success) -{ - _sheetId=type; -// if (CSheets::lookup(_sheetId)->Name.empty()) - _visualName=name; - // else - // _visualName=CSheets::lookup(_sheetId)->Name; - _name=name; - _id=id; - _activity=SQUARE; //NOTHING; - _DefaultActivity=UNKNOWN; - _target=0; - //_positionChanged=false; - - if ( ! CMirrors::Mirror.createAndDeclareEntity(_id) ) - { - success = false; - return; - } - - _MoveContainer = NULL; - _MovePrimitive = NULL; - _Continent = 0xFF; - - // _mode is setup outside the constructor :o( - _x.init( TheDataset, id, "X" ); - _y.init( TheDataset, id, "Y" ); - _z.init( TheDataset, id, "Z" ); - _angle.init( TheDataset, id, "Theta" ); - _vpa.init( TheDataset, id, "VisualPropertyA" ); - _whoseesme.init( TheDataset, id, "WhoSeesMe" ); - _behaviour.init( TheDataset, id, "Behaviour" ); - _mode.init( TheDataset, id, "Mode" ); - - _AttackDistance = 5.0f; - _PrimZone = NULL; - - SAltLookProp vpa; - vpa.Element.Seed = 1; - - _vpa = vpa.Summary; - _whoseesme = (sint64)(-1); - - _Group = NULL; - _ChatSet = -1; - - _RespawnCounter = -1; - _AlreadyAdded = false; - _CyclesState = STATE_WANDER; - - - _Timer.set( DT_TEMP ); - success = true; -} - -// -CActor::~CActor() -{ - CMirrors::Mirror.removeEntity(_id); -} - -void CActor::removeRefs(CActor *actor) -{ - if (this==0) return; - if (_target==actor) - _target=0; -} - - -//---------------------------------------------------------------------------------- -// set the actor's current group -void CActor::setGroup(CActorGroup *group) -{ - if (this==0) return; - - if (_Group != NULL) - { - _Group->removeActor(this); - } - - if (group != NULL) - { - group->addActor(this); - } - - _Group = group; -} - -//---------------------------------------------------------------------------------- -// displaying the actor's current state -void CActor::display(NLMISC::CLog *log) -{ - if (this==0) return; - - const char *angleNames[]= {"E", "ENE", "NE", "NNE", "N","NNW","NW","WNW","W","WSW","SW","SSW","S","SSE","SE","ESE"}; - - log->displayNL("Actor id=%s sheetId='%s'(%08x) name='%s'", - _id.toString().c_str(), - _sheetId.toString().c_str(), - _sheetId.asInt(), - _name.c_str() ); - log->displayNL("\tpos=(%d,%d,%d) Orientation=%s(%d)", - _x(),_y(),_z(), - angleNames[unsigned((_angle()<0.0?-0.5:0.5)+_angle()*8.0/3.14159265359)&15], - int(_angle()*180.0/3.14159265359)); - log->displayNL("\t attackDist=%f dialogue=%d activity=%s Magnet(%.1f,%.1f,%.1f) MagnetRange=%.1f MagnetDecay=%.1f", - _AttackDistance, - _ChatSet, - getActivityName(), - _Magnet.x,_Magnet.y,_Magnet.z, - _MagnetDistance, - _MagnetDecayDistance); -} - -//---------------------------------------------------------------------------------- -// script management - -void CActor::setActivity(EActivity activity) -{ - if ( this == 0 ) - return; - - if ( _DefaultActivity == CActor::UNKNOWN ) - setDefaultActivity( activity ); - - switch( activity ) - { - case NOTHING: - doNothing(); - break; - - case WANDER: - doWander(); - break; - - case SQUARE: - doSquare(); - break; - - case FAUNA_EAT: - doEat(); - break; - - case FAUNA_SLEEP: - doSleep(); - break; - - case FIGHT: - nlwarning("CActor::setActivity(): can't set activty to FIGHT"); - break; - - case ATTACK: - doAttack(); - break; - - case FLEE: - doFlee(); - break; - - - default: - nlwarning("CActor::setActivity(): unknown activity"); - } -} - -void CActor::doNothing() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = NOTHING; -} - -void CActor::doSquare() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = SQUARE; -} - -void CActor::doWander() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = WANDER; -} - -void CActor::doEat() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = FAUNA_EAT; -} - -void CActor::doSleep() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = FAUNA_SLEEP; -} - -void CActor::doFight(CActorGroup *target) -{ - if ( this == 0 ) - return; - - if ( target->actorCount() == 0 ) - return; - - unsigned i,j=0; - double mindist= calcDist(*(*target)[0]); - for (i=1;iactorCount();i++) - if( calcDist(*(*target)[i]) < mindist) - { - mindist= calcDist(*(*target)[i]); - j=i; - } - doFight((*target)[j]); -} - -void CActor::doFight(CActor *target) -{ - if ( this == 0 || target == 0 ) - return; - - doFight( target->_id ); -} - -void CActor::doFight(const NLMISC::CEntityId &id) -{ - if ( this == 0 ) - return; -// if (_activity==FIGHT) stopFight(); - - // turn to face the target - - _activity=FIGHT; - _target=CActorManager::getActor(id); // returns 0 if the target not managed here - - - nlassert(false); - // send the message to the rules service -// CCombatInterface::attack(_id,id,0,true); - - // make sure the target stands still - if (_target!=0 && !_target->fighting()) - _target->doAttacked(this); -} - -void CActor::doAttack() -{ - if ( this == 0 ) - return; -/* - if ( _activity == FIGHT ) - stopFight(); -*/ - _activity = ATTACK; -} - -void CActor::doFlee() -{ - if ( this == 0 ) - return; - - if ( _activity == FIGHT ) - stopFight(); - - _activity = FLEE; -} - - - -void CActor::doAttacked(CActor *target) -{ - if ( this == 0 ) - return; - - if (_activity!=FIGHT) - doNothing(); -} - -void CActor::stopFight() -{ - if ( this == 0 ) - return; - - if (_activity!=FIGHT) - return; - - _activity=NOTHING; - - nlassert(false); - - // send a 'engage in combat' message to the brick service -// CCombatInterface::disengage(_id); -} - -bool CActor::update() -{ - if (this==0) - return false; - - // generate a position in meters (floating point) - CVectorD pos(_x*0.001, _y*0.001, 0.0); - - checkRespawn(); - checkTimers(); - - switch (_activity) - { - case NOTHING: - break; - - case FAUNA_WAIT: - if ( checkAttack( pos ) ) - break; - - if ( _CyclesState == STATE_WANDER ) - { - setActivity( FAUNA_WANDER ); - break; - } - else if ( _CyclesState == STATE_VERY_TIRED || _CyclesState == STATE_EXHAUSTED ) - { - setActivity( FAUNA_SLEEP ); - break; - } - else if ( _CyclesState == STATE_VERY_HUNGRY || _CyclesState == STATE_STARVING ) - { - setActivity( FAUNA_EAT ); - break; - } - break; - - - case SQUARE: - if ( checkAttack( pos ) ) - break; - - processSquare(); - break; - - case FIGHT: - processFight(); - break; - - case WANDER: - if ( ! computeMove( pos ) ) - return false; - break; - - case FAUNA_WANDER: - if ( checkAttack( pos ) ) - break; - - if ( ! computeMove( pos ) ) - return false; - - if ( _CyclesState == STATE_VERY_TIRED || _CyclesState == STATE_EXHAUSTED ) - { - setActivity( FAUNA_SLEEP ); - break; - } - else if ( _CyclesState == STATE_VERY_HUNGRY || _CyclesState == STATE_STARVING ) - { - setActivity( FAUNA_EAT ); - break; - } - - break; - - case FAUNA_SLEEP: - if ( _CyclesState == STATE_SHAKING ) - { - setActivity( FAUNA_WAIT ); - break; - } - - processSleep(); - break; - - case FAUNA_EAT: - if ( checkAttack( pos ) ) - break; - - if ( _CyclesState == STATE_DIGESTING ) - { - setActivity( FAUNA_WAIT ); - break; - } - - processEat(); - break; - - } - return true; -} - -//---------------------------------------------------------------------------------- -// code requiring network comms - -// connections to the GPMS -void CActor::addToOtherServices() -{ - if (this==0) return; -/* - if (!CMirrors::exists(_id)) - CMirrors::Mirror.createAndDeclareEntity( _id ); -*/ - // add the actor name to the IOS - { - CMessage msgout("CHARACTER_NAME"); - TDataSetRow raw = TheDataset.getDataSetRow( _id ); - msgout.serial( raw ); - ucstring uname( _visualName ); - msgout.serial( uname ); - sendMessageViaMirror( "IOS", msgout ); - } - - _AlreadyAdded = true; -} - -void CActor::removeFromOtherServices() -{ - if (this==0) return; - - CMirrors::Mirror.removeEntity( _id ); - _AlreadyAdded = false; -} - - -// pos management -void CActor::initMovePrimitive(sint32 x, sint32 y, sint32 z) -{ - if (this==0) return; - - // added by ben - sint continent = CMoveManager::Continents.findContinent(CVectorD(x*0.001, y*0.001, z*0.001)); - if (continent == -1) - { - nlwarning("Unable to spawn %s in any continent! Position (%.1f,%.1f) not valid!", _id.toString().c_str(), x*0.001, y*0.001); - continent = 0; - } - - // if a primitive already exists - if (_MovePrimitive != NULL) - { - // previous move container must not be null - nlassert(_Continent != 0xFF); - - // check the previous move container is different (otherwise does not create a primitive) - if (continent != _Continent) - { - // depending on the type of the previous primitive, creates a copy of it - UMovePrimitive *primitive = CMoveManager::Continents.getMoveContainer(continent)->addNonCollisionablePrimitive(_MovePrimitive); - nlassert(primitive != NULL); - - // removes previous primitive - CMoveManager::Continents.getMoveContainer(_Continent)->removePrimitive(_MovePrimitive); - - // and set new one as entity primitive - _MovePrimitive = primitive; - _Continent = continent; - _MoveContainer = CMoveManager::Continents.getMoveContainer(_Continent); - } - } - else - { - const CSheets::CSheet *sheet = CSheets::lookup(_sheetId); - - float primRadius = 0.5f; - float primHeight = 2.0f; - - if (sheet != NULL) - { - primRadius = sheet->Radius; - primHeight = sheet->Height; - } - - _Continent = continent; - _MoveContainer = CMoveManager::Continents.getMoveContainer(_Continent); - - // init pacs primitive - _MovePrimitive = _MoveContainer->addNonCollisionablePrimitive(); - nlassert( _MovePrimitive != 0 ); - _MovePrimitive->UserData = (uint64) this; - _MovePrimitive->setPrimitiveType( UMovePrimitive::_2DOrientedCylinder ); - _MovePrimitive->setReactionType( UMovePrimitive::Slide ); - _MovePrimitive->setTriggerType( UMovePrimitive::NotATrigger ); - _MovePrimitive->setCollisionMask( 0x00000000 ); - _MovePrimitive->setOcclusionMask( 0xffffffff ); - _MovePrimitive->setObstacle( false ); - _MovePrimitive->setAbsorbtion( 0 ); - _MovePrimitive->setHeight( primHeight ); - _MovePrimitive->setRadius( primRadius ); - - // insert actor in grid as an obstacle - CObstacle obstacle; - obstacle.Id = _id; - obstacle.Position = CVector(x*0.001f, y*0.001f, 0.0f); - obstacle.Radius = primRadius; - - _GridIterator = CMoveManager::Grid.insert(obstacle, obstacle.Position); - } - - setPos(x, y, z); - - _Magnet = CVector(x*0.001f, y*0.001f, 0.0f); - _MagnetDistance = 50.0f; - _MagnetDecayDistance = 10.0f; -} - -// simple pos setup, pacs jump to position -void CActor::setPos(sint32 x, sint32 y, sint32 z) -{ - if (this==0) return; - - if (_MovePrimitive == NULL || _MoveContainer == NULL) - initMovePrimitive(x, y, z); - - CVectorD pos(x*0.001, y*0.001, z*0.001); - _MovePrimitive->setGlobalPosition( pos, 0 ); - _MovePrimitive->setOrientation( _angle , 0 ); - _MoveContainer->evalCollision(1, 0); // world image 0 for all - pos = _MovePrimitive->getFinalPosition( 0 ); - - (*_GridIterator).Position = CVector(pos); - CMoveManager::Grid.move(_GridIterator, (*_GridIterator).Position); - - _x = (sint32)(1000*pos.x); - _y = (sint32)(1000*pos.y); - _z = (sint32)(1000*pos.z); - //_positionChanged=true; -} - -// some complex movement - involving GPMS update -void CActor::moveBy(sint32 x, sint32 y, sint32 z) -{ - if (this==0) return; - if ((x|y|z)==0) return; - - // modif by ben - //setPos(_x+x, _y+y, _z+z); - //_positionChanged=true; - - if (_MovePrimitive == NULL || _MoveContainer == NULL) - { - nlwarning("Can't moveBy(%d,%d,%d) actor %s, _MovePrimitive or _MoveContainer not set", x, y, z, _id.toString().c_str()); - return; - } - - _MovePrimitive->move(CVectorD(x*0.001, y*0.001, 0.0), 0); - _MoveContainer->evalNCPrimitiveCollision(1.0, _MovePrimitive, 0); - CVectorD pos = _MovePrimitive->getFinalPosition( 0 ); - - (*_GridIterator).Position = CVector(pos); - CMoveManager::Grid.move(_GridIterator, (*_GridIterator).Position); - - _x = (sint32)(1000*pos.x); - _y = (sint32)(1000*pos.y); - _z = (sint32)(1000*pos.z); - //_positionChanged=true; -} - -/* -void CActor::addPositionChangesToMessage(CMessage &msg) -{ - if (this==0) return; - if (!_positionChanged) return; - - msg.serial( _id ); - msg.serial( _x ); - msg.serial( _y ); - msg.serial( _z ); - msg.serial( _angle ); - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle()-1; - msg.serial( tick ); - - _positionChanged=false; -} -*/ - -void CActor::teleportTo(sint32 x, sint32 y, sint32 z) -{ - if (this==0) return; - - setPos(x, y, z); -/* - // added/modified by ben - initMovePrimitive(x, y, z); - - // displaced by ben - CMessage msgout("ENTITY_TELEPORTATION"); - msgout.serial( _id ); - msgout.serial( _x ); - msgout.serial( _y ); - msgout.serial( _z ); - msgout.serial( _angle ); - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle()-1; - msgout.serial( tick ); - sendMessageViaMirror( "GPMS", msgout ); - - //_positionChanged=false; -*/ -} - - -//---------------------------------------------------------------------------------- -// setting the actor behaviour - -void CActor::setBehaviour(std::string behaviourName) -{ - if (this==0) return; - if (behaviourName.empty()) return; -/* - MBEHAV::EBehaviour behaviour=MBEHAV::stringToBehaviour(behaviourName); - CMessage msgout("SET_BEHAVIOUR"); - msgout.serial( _id ); - MBEHAV::CBehaviour b = behaviour; - msgout.serial( b ); - sendMessageViaMirror( "EGS", msgout ); -*/ - MBEHAV::EBehaviour behaviour=MBEHAV::stringToBehaviour(behaviourName); - MBEHAV::CBehaviour b = behaviour; - - _behaviour = (uint64)b; -} -/* -// setting the actor mode -void CActor::setMode(std::string modeName) -{ - if ( this == 0 ) - return; - if ( modeName.empty() ) - return; - - MBEHAV::EMode mode = MBEHAV::stringToMode( modeName ); - CMessage msgout("SET_MODE"); - msgout.serial( _id ); - MBEHAV::EMode b = mode; - msgout.serialEnum( b ); - sendMessageViaMirror( "EGS", msgout ); -} - -void CActor::setMode(MBEHAV::EMode mode) -{ - if ( this == 0 ) - return; - - CMessage msgout("SET_MODE"); - msgout.serial( _id ); - msgout.serialEnum( mode ); - sendMessageViaMirror( "EGS", msgout ); -} -*/ - - - -//---------------------------------------------------------------------------------- -// setting the objects carried in the actor's hands - -void CActor::setVPA(const SAltLookProp &vpa) -{ - _vpa = vpa.Summary; -} - -void CActor::setLeftHand(NLMISC::CSheetId sheetId) -{ - if (this==0) return; -} - -void CActor::setRightHand(NLMISC::CSheetId sheetId) -{ - if (this==0) return; -} - - -void CActor::checkRespawn() -{ - - // if actor doesn't exist in mirror and has not yet been added to gpms, spawn in and set as wandering - if (!CMirrors::exists(_id) && !_AlreadyAdded) - { - setPos((sint32)(_Magnet.x*1000), (sint32)(_Magnet.y*1000), (sint32)(_Magnet.z*1000)); - addToOtherServices(); - //setMode( MBEHAV::NORMAL ); - - setActivity(_DefaultActivity); // doWander(); - } - - // if actor is dead and was on gpms previously then: - // 1. initialise counter so that actor will respawn when counter reaches 0 - // 2. remove actor from gpms, and lock respawn counter to 0 - if (CMirrors::mode(_id) == MBEHAV::DEATH && _AlreadyAdded) - { - if (_RespawnCounter<0) - { - _RespawnCounter = (int)((_MinSpawnDelay + (_MaxSpawnDelay-_MinSpawnDelay) * (float)(((double)rand()-RAND_MAX/2)/(float)(RAND_MAX/2)))*10.0f); - nlinfo("Actor dies %s, will be respawned soon...", _id.toString().c_str()); - doNothing(); - } - else if (_RespawnCounter == 1) - { - nlinfo("Dead Actor %s removed, will be respawned soon...", _id.toString().c_str()); - // remove agent from gpms - removeFromOtherServices(); - --_RespawnCounter; - } - else if (_RespawnCounter > 0) - { - --_RespawnCounter; - } - } - else - { - _RespawnCounter = -1; - } -} - -bool CActor::processSquare() -{ -/* if (_mode().Mode!=MBEHAV::NORMAL) - return false; -*/ - sint32 speed=sint32(100.0*CSheets::lookup(_sheetId)->WalkSpeed); - sint32 key= (sint32)CTickEventHandler::getGameCycle()-1; - key>>=5; - // key+=(sint32)_sid.Id; // this line makes the actors move out of sync with eachother - moveBy((key&1)*((key&2)-1)*speed,(1-(key&1))*((key&2)-1)*speed,0); // this is a grid - //sint32 keyx=key>>4; - //sint32 keyy=keyx+2; - //moveBy( (keyx&4?speed:-speed)*(keyx&3==3?0:1), (keyy&4?speed:-speed)*(keyy&3==3?0:1), 0 ); // this is an octagon - _angle = (float)::atan2((1-(key&1))*((key&2)-1)*speed, (key&1)*((key&2)-1)*speed); - return true; -} - - -bool CActor::processFight() -{ -/* if (_mode().Mode!=MBEHAV::COMBAT) - return false; - { - sint32 key= (sint32)CTickEventHandler::getGameCycle()-1; - key%=200; - if (!key && _target) - { - nlassert(false); -// CCombatInterface::attack(_id,_target->_id,1,false); - } - - // if we have position info for the target then setup orientation info - if (_target) - { - CMoveManager::TObstacleMap::iterator it; - it = CMoveManager::ObstacleMap.find(_target->_id); - if (it != CMoveManager::ObstacleMap.end()) - { - NLMISC::CVectorD pos(float(_x)/1000.0f,float(_y)/1000.0f,float(_z)/1000.0f); - pos -= (*((*it).second)).Position; - setAngle((float)atan2(pos.y,pos.x)); - } - } - } -*/ - //todo: - // check hitpoints in georges - // check regen rate in george (should be: rate=1000 value=0) - // subscribe to hitpoint mirror (sint16) - // add group management to command to engage in combat - - // if target dead go to idle - - // from time to time insert a 'coup en force' attack - // CBSExecuteMsg msg; - // msg.PlayerId=_sid; - // msg.TargetId=_target; - // msg.Bricks.push_back(CSheetId("coup_en_force.brick_base")); - // msg.send("BS"); - return true; -} - -bool CActor::processEat() -{ -/* - if ( getMode() != MBEHAV::EAT ) - setMode( MBEHAV::EAT ); -*/ return true; -} - -bool CActor::processSleep() -{ -/* if ( getMode() != MBEHAV::REST ) - setMode( MBEHAV::REST ); -*/ return true; -} - - -bool CActor::checkAttack( CVectorD &pos ) -{ - /* - if we're close to an actor then attack them - */ - CAABBox box; - box.setCenter(CVector(_x*0.001f, _y*0.001f, 0.0f)); - box.setHalfSize(CVector(5.0f, 5.0f, 1.0f)); - - CMoveManager::Grid.clearSelection(); - CMoveManager::Grid.select(box); - - CMoveManager::TObstacleGrid::CIterator it; - for (it=CMoveManager::Grid.begin(); it!=CMoveManager::Grid.end(); ++it) - { - CObstacle &other = (*it); - - // attacks player if close to me - CVector d = pos-other.Position; - d.z = 0.0f; - if (other.Id.getType() == RYZOMID::player && d.norm() <= _AttackDistance) - { - nlinfo("Actor <%s> attacks player because _AttackDistance = %f and separation = %f", _name.c_str(), _AttackDistance, d.norm()); - doFight(other.Id); - return true; - } - } - return false; -} - - -// State machine defining transitions between cycle states -void CActor::updateCycles() -{ - _CyclesState = (ECycleState) ( ( (int)_CyclesState ) + 1 ); - if ( _CyclesState == STATE_LAST ) - _CyclesState = STATE_WANDER; -} - -/* -void CActor::updateCycles() -{ - switch( _CyclesState ) - { - case STATE_WANDER: - _CyclesState = STATE_HUNGRY; - setActivity( WANDER ); - break; - - case STATE_HUNGRY: - _CyclesState = STATE_VERY_HUNGRY; - break; - - case STATE_VERY_HUNGRY: - _CyclesState = STATE_STARVING; - break; - - case STATE_STARVING: - _CyclesState = STATE_EATING; - break; - - case STATE_EATING: - { - _CyclesState = STATE_HUNGRY; - setActivity( EAT ); - } - break; - - case STATE_DIGESTING: - _CyclesState = STATE_TIRED; - setActivity( WANDER ); - break; - - case STATE_TIRED: - _CyclesState = STATE_VERY_TIRED; - break; - - case STATE_VERY_TIRED: - _CyclesState = STATE_EXHAUSTED; - break; - - case STATE_EXHAUSTED: - _CyclesState = STATE_SLEEPING; - break; - - case STATE_SLEEPING: - { - _CyclesState = STATE_HUNGRY; - setActivity( SLEEP ); - } - break; - - case STATE_SHAKING: - { - _CyclesState = STATE_SHAKING; - setActivity( WANDER ); - } - break; - } -} -*/ -void CActor::checkTimers() -{ - if ( _Timer.test() ) - { - updateCycles(); - _Timer.add( DT_TEMP ); - } -} - - - - -bool CActor::computeMove( NLMISC::CVectorD &pos) -{ - // use the current tick and the entity's id to decide when to move and when to stand still - // the objective is to move in short bursts, standing still between times - sint32 key= (sint32)CTickEventHandler::getGameCycle()-1; - key>>=2; - key>>=3; - key+=(sint32)_id.getShortId(); // this line makes the actors move out of sync with eachother - if (!(key & 3)) - { - // we're not moving but we can turn round - sint32 lastkey= (sint32)CTickEventHandler::getGameCycle()-2; - lastkey>>=2; - lastkey+=(sint32)_id.getShortId(); // this line makes the actors move out of sync with eachother - lastkey>>=3; - if (!(lastkey & 1)) - _angle = _angle() + (float)(((double)rand()-RAND_MAX/2)/(float)(RAND_MAX/2)*3.14159265359f/2.0f); - - return true; - } - - // lookup my walk and run speeds and so on from my sheetid - const CSheets::CSheet *sheet = CSheets::lookup(_sheetId); - if (!sheet) - { -// nlwarning("Unknown sheet id for entity %s",_Id.toString().c_str()); - return false; - } - float walkSpeed = sheet->WalkSpeed; - float runSpeed = sheet->RunSpeed; - float radius = sheet->Radius; - - double dt = (double)(CTickEventHandler::getGameTimeStep()); - CVectorD move = CVectorD(0.0, 0.0, 0.0); - - // randomly change direction - key= (sint32)CTickEventHandler::getGameCycle()-1; - key+=(sint32)_id.getShortId(); - if ((key & 3) == 3) - { -// _angle += (float)((3.14159265359f/8.0f)*sin((2.0f*3.14159265359f/360.0f)*(float)((CTickEventHandler::getGameCycle()+7*_id.getShortId())%360))); - _angle = _angle() + (float)(((double)rand()-RAND_MAX/2)/(RAND_MAX/2)*5.7*dt); - while (_angle() > +3.14159265359f) _angle = _angle() - 2.0f*3.14159265359f; - while (_angle() < -3.14159265359f) _angle = _angle() + 2.0f*3.14159265359f; - } - move.x = walkSpeed*cos(_angle)*dt; - move.y = walkSpeed*sin(_angle)*dt; - - // some attraction by the magnet - CVectorD dmagnet = _Magnet-pos; - dmagnet.z = 0.0; - double nmagnet = dmagnet.norm(); - - if (nmagnet > _MagnetDistance) - { - if (_MagnetDecayDistance<1) _MagnetDecayDistance=1; // big bad anti-bug - move += dmagnet.normed()*walkSpeed*dt*(nmagnet-_MagnetDistance)/_MagnetDecayDistance; - } - - // avoid obstacles - CVectorD avoid = CVectorD::Null; - - CMoveManager::TObstacleGrid::CIterator it; - for (it=CMoveManager::Grid.begin(); it!=CMoveManager::Grid.end(); ++it) - { - CObstacle &other = (*it); - - // don't avoid self - if (other.Id == _id) - continue; - - CVectorD d = other.Position-pos; - d.z = 0.0; - double dist = d.norm()+0.001; - - const float EntitiesRepulsSpacing = 1.0f; - float EntitiesRepulsDistance = EntitiesRepulsSpacing+radius+other.Radius; - const float EntitiesRepulsStrength = 0.5f; - - if (dist < EntitiesRepulsDistance) - { - double coef = 1.0f - (float)(pow(EntitiesRepulsDistance, EntitiesRepulsStrength)/pow(dist, EntitiesRepulsStrength)); - avoid += d*(walkSpeed*dt*coef/dist); - } - } - - move += avoid; - - CVectorD front = move.normed(); - CVectorD lateral(front.y, -front.x, 0.0); - CVectorD normal; - - // avoid walls - if (!_MoveContainer->testMove(_MovePrimitive, front, 1, 0, &normal)) - move += normal*walkSpeed*0.3*dt; - if (!_MoveContainer->testMove(_MovePrimitive, (front+lateral)*0.5, 1, 0, &normal)) - move += normal*walkSpeed*0.3*dt; - if (!_MoveContainer->testMove(_MovePrimitive, (front+lateral)*0.5, 1, 0, &normal)) - move += normal*walkSpeed*0.3*dt; - - // avoid patat borders - if (!testPositionInPatat(pos+front)) - { - uint j, n=4; - CVector newPos; - for (j=1; j dt*runSpeed) - move *= dt*runSpeed/movenorm; - - //setup the angle field - _angle = (float)::atan2(move.y, move.x); - - moveBy((sint32)(move.x*1000.0), (sint32)(move.y*1000.0), 0); - return true; -} - -} // end of namespace AGS_TEST - -/* - NLMISC::CVectorD posE = e->getExtrapoledPosition(); - agressivite = 0.0; - instinct = 0.0; - TCarrieerCombat carriere = getProfile(c); - - r = getEnnemiFar(posE, c->getCoordinate()); - - double fameCoputed = (double)f; - - - if(fameCoputed >= 0) - return NOCombat; - agressivite = -fameCoputed; - double l = getLevelPoint(c) - getLevelPoint(e->getClass()); - - agressivite += (l>0.0) ? l*20 : 0.0; - - agressivite += getProfileAvantage(carriere, e); - - if ( r < 3) agressivite += 20; - - instinct += (l<0.0) ? -l*20 : 0.0; - double l100 = getNormedLifePoint(c); - if( l100 < 0.5 ) - { - if( l100 < 0.25 ) - instinct += 60; - else - instinct += 40; - } - - double seuil = agressivite - instinct; - if(seuil >= getSeuilBelliqueux(c)) - { - if(r < _REngage) return Attack; - else - { - return Poursuivre; - } - } - else - { - double fuite = getSeuilFuite(c); - if(instinct >= fuite) - return Fuite; - else - return NOCombat; - - } - return NOCombat; -*/ diff --git a/code/ryzom/server/src/ags_test/actor.h b/code/ryzom/server/src/ags_test/actor.h deleted file mode 100644 index 9e25705c5..000000000 --- a/code/ryzom/server/src/ags_test/actor.h +++ /dev/null @@ -1,286 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#ifndef GD_ACTOR_H -#define GD_ACTOR_H - -// Nel Misc -#include "nel/misc/types_nl.h" -#include "nel/misc/sheet_id.h" -#include "nel/misc/entity_id.h" -#include "nel/misc/vectord.h" - -// Nel Pacs -#include "nel/pacs/u_move_primitive.h" -#include "nel/pacs/u_move_container.h" -// Nel Ligo -#include "nel/ligo/primitive.h" - - -// Game share -#include "game_share/mode_and_behaviour.h" -#include "game_share/mirror_prop_value.h" -#include "game_share/ryzom_mirror_properties.h" -#include "game_share/player_visual_properties.h" - -// AgS test -#include "move_manager.h" -#include "ags_timer.h" -#include "mirrors.h" - -namespace AGS_TEST -{ -// external refs -class CActorGroup; - -// the class -class CActor -{ -public: - enum EActivity { - UNKNOWN=-1, - NOTHING=0, - SQUARE, - FIGHT, - WANDER, - FAUNA_WANDER, - FAUNA_WAIT, - FAUNA_EAT, - FAUNA_SLEEP, - ATTACK, - FLEE - }; - - /* - - enum ECycleState - { - STATE_WANDER, - STATE_HUNGRY, - STATE_VERY_HUNGRY, - STATE_STARVING, - STATE_EATING, - STATE_DIGESTING, - STATE_TIRED, - STATE_VERY_TIRED, - STATE_EXHAUSTED, - STATE_SLEEPING, - STATE_SHAKING - }; -*/ - - enum ECycleState - { - STATE_WANDER, - STATE_HUNGRY, - STATE_VERY_HUNGRY, - STATE_STARVING, - STATE_DIGESTING, - STATE_TIRED, - STATE_VERY_TIRED, - STATE_EXHAUSTED, - STATE_SHAKING, - STATE_LAST - }; - - // The only legal constructor - CActor(const std::string &type, const std::string &name, const NLMISC::CEntityId &id, bool &success); - - // - ~CActor(); - - // Removing x-refs to other actors if they are deleted - void removeRefs(CActor *actor); - - // some basic read accessors - std::string getName() { return _name; } - std::string getType() { return _sheetId.toString(); } - sint32 getSheetID() { return _sheetId.asInt(); } - const NLMISC::CEntityId &getSid() { return _id; } - - sint32 getX() { return _x(); } - sint32 getY() { return _y(); } - sint32 getZ() { return _z(); } - float getAngle() { return _angle(); } -// uint8 getMode() { return (uint8)(_mode().Mode); } -// void initMode() { _mode.init( TheDataset, _id, "Mode" ); } - - //bool positionChanged() { return _positionChanged; } - - // some basic write accessors - void setPos(sint32 x, sint32 y, sint32 z); // { _x=x; _y=y; _z=z; _positionChanged=true; } // commented by ben, uses pacs now - void setAngle(float angle) { _angle=angle; /*_positionChanged=true;*/ } - void setMagnetPos(const NLMISC::CVector &pos) { _Magnet = pos; } - void setMagnetRange(float range,float decay) { _MagnetDistance=range; _MagnetDecayDistance=decay; } - void setSpawnTime(float min,float max) { _MinSpawnDelay=min; _MaxSpawnDelay=max; } - void setAttackDistance(float distance) - { - _AttackDistance = distance; - nlinfo("Set attack distance for <%s> to %f meters",_name.c_str(),_AttackDistance); - } - void setPrimZone(NLLIGO::CPrimZone *primZone) { _PrimZone = primZone; } - void setBehaviour(std::string behaviourName); -/* void setMode(std::string behaviourName); - void setMode(MBEHAV::EMode mode);*/ - void setLeftHand(NLMISC::CSheetId sheetId); - void setRightHand(NLMISC::CSheetId sheetId); - void setGroup(CActorGroup *group); - void setVPA(const SAltLookProp &vpa); - void setActivity(EActivity activity); - void setDefaultActivity(EActivity activity) { _DefaultActivity = activity; } - void setChatSet(sint32 set) { _ChatSet = set; } - sint32 getChatSet() const { return _ChatSet; } - - // connections to the other game services - void addToOtherServices(); - void removeFromOtherServices(); - - // the following used to connect to a specific service identified by service ID - //void addToGPMS(uint8 serviceID); - //void addToIOS(uint8 serviceID); - - // some complex movement - involving GPMS update - void initMovePrimitive(sint32 x, sint32 y, sint32 z); - void moveBy(sint32 x, sint32 y, sint32 z); - //void addPositionChangesToMessage(NLNET::CMessage &msg); - void teleportTo(sint32 x, sint32 y, sint32 z); - - // displaying the actor's current state - void display(NLMISC::CLog *log = NLMISC::InfoLog); - const char *getActivityName() { switch(_activity) { case FIGHT: return "FIGHT"; case NOTHING: return "IDLE"; case SQUARE: return "SQUARE"; case WANDER: return "WANDER"; } return ""; } - - // changeing the actor's activity - void resetActivity() { setActivity(_DefaultActivity); } - void doNothing(); - void doSquare(); - void doWander(); - void doEat(); - void doSleep(); - void doFight(CActor *target); - void doFight(const NLMISC::CEntityId &id); - void doFight(CActorGroup *target); - void doAttacked(CActor *target); - void doAttack(); - void doFlee(); - bool fighting() { return _activity==FIGHT; } - - void stopFight(); - - void checkRespawn(); - bool checkAttack( NLMISC::CVectorD & ); - - - // Functions called at each update depending on the current _activity - bool processSquare(); - bool processFight(); - bool processEat(); - bool processSleep(); - - bool computeMove( NLMISC::CVectorD &pos); - bool computeFlee( NLMISC::CVectorD &pos); - - // the update routine that moves the actor and does other stuff - // returns false if the actor is dead, remote controled, etc - bool update(); - - // script management -/* - static void addScript(std::string name, std::vector args, sint32 firstArg); - void assignScript(std::string name); -*/ - - // utility functions - double calcDist(CActor &target) { return (_x-target.getX()) * (_x-target.getX()) + (_y-target.getY()) * (_y-target.getY()); } - bool testPositionInPatat(const NLMISC::CVector &pos) { return (_PrimZone) ? _PrimZone->contains(pos) : true; } // if no prim zone, always true - -//private: - CActor(); - - // basic identity - NLMISC::CEntityId _id; - NLMISC::CSheetId _sheetId; - std::string _name; - std::string _visualName; - - - // Eat and rest cycles - CAGSTimer _Timer; // Timer for eat and sleep cycles ( synchronized with TICK service) - ECycleState _CyclesState; // Current eat and sleep cycles - void updateCycles(); // State machine computing transitions between timer states (eat and sleep) - void checkTimers(); // called at each update to see if the last timer delay has expired (if true calls updateCycles) - - - - // position - CMirrorPropValue1DS _x; - CMirrorPropValue1DS _y; - CMirrorPropValue1DS _z; - CMirrorPropValue1DS _angle; - CMirrorPropValue1DS _vpa; - CMirrorPropValue1DS _whoseesme; - CMirrorPropValue1DS _behaviour; - CMirrorPropValue1DS _mode; - //bool _positionChanged; // to know whether need to send position to GPS - - // properties used to govern the update() code - EActivity _activity; // behavioural activity - EActivity _DefaultActivity; // the activity we were firt attributed and return to when nothing better to do - CActor *_target; // target for combat - - // continent the entity spawned in - uint8 _Continent; - - // pacs move container for the actor - NLPACS::UMoveContainer *_MoveContainer; - - // pacs primitive for the actor - NLPACS::UMovePrimitive *_MovePrimitive; - - // iterator for the move grid - CMoveManager::TObstacleGrid::CIterator _GridIterator; - - // magnet - NLMISC::CVector _Magnet; - float _MagnetDistance; - float _MagnetDecayDistance; - - // attack distance - float _AttackDistance; - - // prim zone - NLLIGO::CPrimZone* _PrimZone; - - // actor group - CActorGroup* _Group; - - // bot page set - sint32 _ChatSet; - - // respawn counter - sint32 _RespawnCounter; - float _MinSpawnDelay; - float _MaxSpawnDelay; - - // added on services - bool _AlreadyAdded; - - -}; - -} // end of namespace AGS_TEST - -#endif // GD_ACTOR_H diff --git a/code/ryzom/server/src/ags_test/actor_group.cpp b/code/ryzom/server/src/ags_test/actor_group.cpp deleted file mode 100644 index 5776ea965..000000000 --- a/code/ryzom/server/src/ags_test/actor_group.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// Nel Misc -#include "nel/misc/command.h" -#include "nel/misc/path.h" -#include "nel/net/message.h" -#include "nel/net/unified_network.h" - -// Game share -#include "game_share/tick_event_handler.h" -//#include "game_share/msg_brick_service.h" - -// Local includes -#include "actor.h" -#include "actor_group.h" -#include "actor_manager.h" -#include "sheets.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - -namespace AGS_TEST -{ - -//---------------------------------------------------------------------------------- -void CActorGroup::removeActor(CActor *actor) -{ - if (this==0) return; - - for (int i=_actors.size();i--;) - if (_actors[i]==actor) - { - _actors[i]=_actors[_actors.size()-1]; - _actors.pop_back(); - } -} - -//---------------------------------------------------------------------------------- -// displaying the actor's current state -void CActorGroup::display() -{ - if (this==0) return; - - nlinfo(""); - nlinfo("ActorGroup: %s",_name.c_str()); - - // diaply the group's actors' stats - for (int i=_actors.size();i--;) - _actors[i]->display(); -} - -void CActorGroup::doFight(CActorGroup *target) -{ - if (this==0) return; - if (target->actorCount()==0) return; - - // tell each actor in the group to fight the opposing group member with matching ID - for (int i=_actors.size();i--;) - _actors[i]->doFight((*target)[i%target->actorCount()]); -} - -void CActorGroup::doFight(CActor *target) -{ - if (this==0) return; - - // tell all the actors in the group to attack the target chap - for (int i=_actors.size();i--;) - _actors[i]->doFight(target); -} - -void CActorGroup::stopFight() -{ - if (this==0) return; - - for (int i=_actors.size();i--;) - _actors[i]->stopFight(); -} - -//---------------------------------------------------------------------------------- -// magnet state control -void CActorGroup::fadeMagnet(const NLMISC::CVector &pos, float distance, float decay, NLMISC::TGameCycle endTime) -{ - _ToStartMagnet = _Magnet; - _ToStartMagnetDistance = _MagnetDistance; - _ToStartMagnetDecay = _MagnetDecay; - _ToStopMagnet = pos; - _ToStopMagnetDistance = distance; - _ToStopMagnetDecay= decay; - _ToStartCycle = CTickEventHandler::getGameCycle(); - _ToStopCycle = endTime; - _ToFade = true; -} - - -//---------------------------------------------------------------------------------- -// overall actors update -void CActorGroup::update() -{ - if (_ToFade) - { - TGameCycle cycle = CTickEventHandler::getGameCycle(); - if (cycle > _ToStopCycle) - { - cycle = _ToStopCycle; - _ToFade = false; - } - - float ratio = (float)(cycle-_ToStartCycle)/(float)(_ToStopCycle-_ToStartCycle); - - _Magnet = _ToStartMagnet*(1.0f-ratio) + _ToStopMagnet*ratio; - _MagnetDistance = _ToStartMagnetDistance*(1.0f-ratio) + _ToStopMagnetDistance*ratio; - _MagnetDecay = _ToStartMagnetDecay*(1.0f-ratio) + _ToStopMagnetDecay*ratio; - } - - if (_MagnetActors) - { - uint i; - for (i=0; i<_actors.size(); ++i) - { - _actors[i]->setMagnetPos(_Magnet); - _actors[i]->setMagnetRange(_MagnetDistance, _MagnetDecay); - } - } -} - - -} // end of namespace AGS_TEST diff --git a/code/ryzom/server/src/ags_test/actor_group.h b/code/ryzom/server/src/ags_test/actor_group.h deleted file mode 100644 index c5e0dc765..000000000 --- a/code/ryzom/server/src/ags_test/actor_group.h +++ /dev/null @@ -1,102 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef GD_ACTOR_GROUP_H -#define GD_ACTOR_GROUP_H - -// Nel Misc -#include "nel/misc/types_nl.h" -#include "nel/misc/vector.h" - -// Game share -#include "game_share/ryzom_entity_id.h" -#include "nel/misc/sheet_id.h" -#include "game_share/mode_and_behaviour.h" - -namespace AGS_TEST -{ -// external refs -class CActor; - -// the class -class CActorGroup -{ -public: - // Constructor - must have a name for the group - CActorGroup(const std::string &name): _name(name), _MagnetActors(false) {} - - // adding actors to the group - void addActor(CActor *actor) { _actors.push_back(actor); } - - // Remove actor from the group (ignore if not found) - void removeActor(CActor *actor); - - // some basic read accessors - std::string getName() { return _name; } - unsigned actorCount() { return (unsigned)_actors.size(); } - CActor *operator[](unsigned index) { return _actors[index]; } - - // displaying the actor's current state - void display(); - - // changeing the actor's activity - void doNothing(); - void doSquare(); - void doFight(CActor *target); - void doFight(CActorGroup *target); - void stopFight(); - - // - void update(); - - // magnet moving/attraction scripting setup - void magnetActors(bool control=true) { _MagnetActors = control; } - void setMagnet(const NLMISC::CVector &pos, float distance, float decay) { _Magnet = pos; _MagnetDistance = distance; _MagnetDecay = decay; _ToFade = false; } - void fadeMagnet(const NLMISC::CVector &pos, float distance, float decay, NLMISC::TGameCycle endTime); - bool fadeComplete() const { return !_ToFade; } - const NLMISC::CVector &getMagnetPos() const { return _Magnet; } - float getMagnetDistance() const { return _MagnetDistance; } - float getMagnetDecay() const { return _MagnetDecay; } - -private: - CActorGroup(); // forbid default constructor - - std::string _name; - std::vector _actors; - - NLMISC::CVector _Magnet; - float _MagnetDistance; - float _MagnetDecay; - bool _MagnetActors; - - NLMISC::CVector _ToStartMagnet; - float _ToStartMagnetDistance; - float _ToStartMagnetDecay; - NLMISC::CVector _ToStopMagnet; - float _ToStopMagnetDistance; - float _ToStopMagnetDecay; - NLMISC::TGameCycle _ToStartCycle, _ToStopCycle; - bool _ToFade; -}; - - -} // end of namespace AGS_TEST - -#endif // GD_ACTOR_GROUP_H -/* End of actor_group.h */ diff --git a/code/ryzom/server/src/ags_test/actor_manager.cpp b/code/ryzom/server/src/ags_test/actor_manager.cpp deleted file mode 100644 index 3c4d49302..000000000 --- a/code/ryzom/server/src/ags_test/actor_manager.cpp +++ /dev/null @@ -1,440 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -// Nel -//#include "nel/net/service.h" - - -// Local headers -#include "position_generator.h" -#include "actor_manager.h" -#include "sheets.h" -#include -#include "game_share/people.h" -#include "game_share/synchronised_message.h" - -#include "nel/misc/variable.h" - -#include - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - - -namespace AGS_TEST -{ - -//------------------------------------------------------------------------- -// Some global variables -extern uint32 GlobalActorCount; -extern uint32 GlobalActorUpdates; -extern uint32 GlobalActorMoves; - -CEntityId LastActorId; - -NLMISC_DYNVARIABLE(string, LastActorId, "Last created actor") -{ - if (get) - *pointer = LastActorId.toString(); - else - LastActorId.fromString((*pointer).c_str()); -} - -//------------------------------------------------------------------------- -// Some function prototypes - -static void cbServiceUp( const string& serviceName, uint16 serviceId, void * ); -static void cbServiceDown( const string& serviceName, uint16 serviceId, void * ); - -//------------------------------------------------------------------------ -// static data for CActorManager - -std::vector CActorManager::_actors; -std::vector CActorManager::_actorGroups; -int CActorManager::_nextActorID=0; -std::set CActorManager::_visionHandlingServices; -CActorGroup *CActorManager::_defaultActorGroup; - -//------------------------------------------------------------------------ -// basic functionality for CActorManager singleton - -void CActorManager::init() -{ - static bool first_time=true; - - if (first_time) - { - // Init callback for service up / down - CUnifiedNetwork::getInstance()->setServiceUpCallback ("*", cbServiceUp, NULL); - CUnifiedNetwork::getInstance()->setServiceDownCallback("*", cbServiceDown, NULL); - first_time=false; - } - else - release(); - - _nextActorID=0; -/* - CPositionGenerator::setPattern(std::string("grid")); - CPositionGenerator::setPosition(17981,-33200); - CPositionGenerator::setSpacing(2000); -*/ - _defaultActorGroup = newActorGroup("defaultGroup"); -} - -void CActorManager::update() -{ - set< pair > iaZones; - - std::vector::iterator itg; - for (itg=_actorGroups.begin(); itg!=_actorGroups.end(); ++itg) - (*itg)->update(); - - - // iterate through all known actors, calling their update - uint16 positionChangeCount=0; - uint16 updateCount=0; - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - bool updated= (*it)->update(); - if (updated) - updateCount++; -/* - if ((*it)->positionChanged()) - positionChangeCount++; - - sint32 zx = (*it)->getX()/160000; - sint32 zy = -(*it)->getY()/160000; - - iaZones.insert(make_pair(zx, zy)); -*/ - } - - - // for all entities, request vision zones - /*CMessage msg("AGENT_VISON"); - sint64 fakeId = 0; - msg.serial(fakeId); - sint32 pos = msg.getPos(); - set< pair >::iterator itz; - for (itz=iaZones.begin(); itz!=iaZones.end(); ++itz) - { - sint32 x = (*itz).first, - y = (*itz).second; - msg.serial(x); - msg.serial(y); - } - if (msg.getPos() > pos) - CUnifiedNetwork::getInstance()->send("GPMS", msg);*/ -/* - // build the position changed message and send it to GPMS - if (positionChangeCount>0) - { - NLNET::CMessage gpmPosMsg("UPDATE_ENTITIES_POSITIONS"); - gpmPosMsg.serial(positionChangeCount); - for (it=_actors.begin(); it!=_actors.end(); ++it) - (*it)->addPositionChangesToMessage(gpmPosMsg); - - sendMessageViaMirror( "GPMS", gpmPosMsg ); - } -*/ - GlobalActorUpdates=updateCount; - //GlobalActorMoves=positionChangeCount; -} - -void CActorManager::release() -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - (*it)->removeFromOtherServices(); - } - _actors.clear(); -} - -// Callback called at service connexion -static void cbServiceUp( const string& serviceName, uint16 serviceId, void * ) -{ - /*if (serviceName==std::string("EGS")) - CActorManager::reconnectEGS((uint8)serviceId); - - if (serviceName==std::string("IOS")) - CActorManager::reconnectIOS((uint8)serviceId); - - if (serviceName==std::string("GPMS")) - CActorManager::reconnectGPMS((uint8)serviceId);*/ - - /*CMessage reqVision("ASK_VISION_ZONE"); - CUnifiedNetwork::getInstance()->send(serviceId, reqVision);*/ -} - -// -static void cbServiceDown( const string& serviceName, uint16 serviceId, void * ) -{ - CActorManager::removeVisionService(serviceId); -} - -//--------------------------------------------------------------------------------- -// methods for dealing with tardy connection of a key service -/*void CActorManager::reconnectEGS(uint8 serviceId) -{ -} - -void CActorManager::reconnectIOS(uint8 serviceId) -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - (*it)->addToIOS(serviceId); - } -} - -void CActorManager::reconnectGPMS(uint8 serviceId) -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - (*it)->addToGPMS(serviceId); - } -}*/ - - -//--------------------------------------------------------------------------------- -// CActorManager methods for creating and killing actors - -// method for adding a new actor to the scene -CActor *CActorManager::newActor(const std::string &type, const std::string &name) -{ - LastActorId = CEntityId::Unknown; - - if (getActor(name)!=NULL) - { - nlinfo("Actor already exists: %s",name.c_str()); - return NULL; - } - - CSheetId sheetId(type); - const CSheets::CSheet *sheet=CSheets::lookup(sheetId); - if (!sheet) - { - nlwarning("ERROR: Can't find static type data for '%s'(%d) for entity %s", type.c_str(), sheetId.asInt(), name.c_str()); - return NULL; - } - - // create a new actor record and COPY it into the actor vector - -// EGSPD::CPeople::TPeople p_type = EGSPD::CPeople::fromString( type ); - bool success = false; - CActor *aNewActor; - if ( sheet->isNpc /*EGSPD::CPeople::isPlayableRace( p_type )*/ ) - aNewActor = new CActor(type,name,CEntityId(RYZOMID::npc,_nextActorID++),success); - else - aNewActor = new CActor(type,name,CEntityId(RYZOMID::creature,_nextActorID++),success); - - if ( ! success ) - { - if (aNewActor) - delete aNewActor; - return NULL; - } - - LastActorId = aNewActor->_id; - - int x,y; - CPositionGenerator::next(x,y); - aNewActor->setPos(x, y, 0); - aNewActor->setAngle(0); - _actors.push_back(aNewActor); - - // get hold of a pointer of the copy of the actor in the actor vector - CActor *theActor=getActor(name); - - // add the actor to the GPMS, the IOS, etc - if (theActor!=0) - theActor->addToOtherServices(); -/* - CMessage msgMode("SET_MODE"); - TDataSetRow index = CMirrors::DataSet->getDataSetRow(theActor->_id); - msgMode.serial(index); - MBEHAV::TMode mode(MBEHAV::NORMAL, x, y); - msgMode.serial(mode); - sendMessageViaMirror("EGS", msgMode); -*/ - CMirrors::initSheet( aNewActor->getSid(), sheetId ); // initialize out the sheet - // Let the position & angle & tick be sent ("UPDATE_ENTITIES_POSITIONS") in update - //aNewActor->initMode(); - - MBEHAV::TMode mode(MBEHAV::NORMAL, x, y); - theActor->_mode = mode.RawModeAndParam; - - aNewActor->display(); - theActor->setGroup(_defaultActorGroup); - - GlobalActorCount++; - return theActor; -} - -// method for retrievng a pointer to a named actor -// returns NULL if the actor doesn't exist -CActor *CActorManager::getActor(const std::string &name) -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - if ((*it)->getName()==name) - return (*it); - } - - return 0; -} - -// method for retrievng a pointer to given actor -CActor *CActorManager::getActor(unsigned index) -{ - if (index>=_actors.size()) - return NULL; - else - return (_actors[index]); -} - -// method for retrievng a pointer to given actor -CActor *CActorManager::getActor(const NLMISC::CEntityId &id) -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - if ((*it)->getSid()==id) - return (*it); - } - - return NULL; -} - -void CActorManager::killActor(const std::string &name) -{ - std::vector::iterator it; - for (it=_actors.begin(); it!=_actors.end(); ++it) - { - if ((*it)->getName()==name) - { - // remove from net refferences - (*it)->removeFromOtherServices(); - - // remove from vision xrefs - std::vector::iterator it2; - for (it2=_actors.begin(); it2!=_actors.end(); ++it2) - { - (*it2)->removeRefs(*it); - } - - for (int i=_actorGroups.size();i--;) - _actorGroups[i]->removeActor(*it); - - // remove from container - delete *it; - _actors.erase(it); - GlobalActorCount--; - return; - } - } -} - -//------------------------------------------------------------------------ -// basic functionality for actor group management - -// method for adding a new actorGroup to the scene -CActorGroup *CActorManager::newActorGroup(const std::string &name) -{ - if (!getActorGroup(name)) - { - // create a new actorGroup record and COPY it into the actorGroup vector - CActorGroup *aNewActorGroup = new CActorGroup(name); - _actorGroups.push_back(aNewActorGroup); - aNewActorGroup->display(); - } - - // get hold of a pointer of the copy of the actorGroup in the actorGroup vector - return getActorGroup(name); -} - -// method for retrievng a pointer to a named actorGroup -// returns NULL if the actorGroup doesn't exist -CActorGroup *CActorManager::getActorGroup(const std::string &name) -{ - std::vector::iterator it; - for (it=_actorGroups.begin(); it!=_actorGroups.end(); ++it) - { - if ((*it)->getName()==name) - return (*it); - } - - return NULL; -} - -// method for retrievng a pointer to given actorGroup -CActorGroup *CActorManager::getActorGroup(unsigned index) -{ - if (index>=_actorGroups.size()) - return NULL; - else - return (_actorGroups[index]); -} - -void CActorManager::removeActorGroup(const std::string &name) -{ - std::vector::iterator it; - for (it=_actorGroups.begin(); it!=_actorGroups.end(); ++it) - { - if ((*it)->getName()==name) - { - // remove all actors from this group into default group - uint i; - for (i=0; i<(*it)->actorCount(); ++i) - (*(*it))[i]->setGroup(_defaultActorGroup); - - // remove from container - delete (*it); - _actorGroups.erase(it); - return; - } - } -} - -// -void CActorManager::setActorsToGroup(const std::string &sourceActorGroup, const std::string &destActorGroup) -{ - CActorGroup *srcGroup = getActorGroup(sourceActorGroup); - if (srcGroup == NULL) - { - nlwarning("source actor group '%s' is unknown, abort setActorsToGroup(%s, %s)", sourceActorGroup.c_str(), sourceActorGroup.c_str(), destActorGroup.c_str()); - return; - } - - CActorGroup *destGroup = getActorGroup(destActorGroup); - if (destGroup == NULL) - { - nlwarning("destination actor group '%s' is unknown, abort setActorsToGroup(%s, %s)", destActorGroup.c_str(), sourceActorGroup.c_str(), destActorGroup.c_str()); - return; - } - - uint i; - for (i=0; iactorCount(); ++i) - (*srcGroup)[i]->setGroup(destGroup); -} - - -} // end of namespace AGS_TEST diff --git a/code/ryzom/server/src/ags_test/actor_manager.h b/code/ryzom/server/src/ags_test/actor_manager.h deleted file mode 100644 index 83e2908d0..000000000 --- a/code/ryzom/server/src/ags_test/actor_manager.h +++ /dev/null @@ -1,107 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef GD_ACTOR_MANAGER_H -#define GD_ACTOR_MANAGER_H - - -// Nel -#include "nel/misc/types_nl.h" -//#include "nel/net/message.h" -//#include "nel/net/unified_network.h" - -// Local headers -#include "actor.h" -#include "actor_group.h" - -#include - -namespace AGS_TEST -{ - -/** - * Singleton, for managing the actors in a scene - * \author Sadge - * \author Nevrax France - * \date 2002 - */ -class CActorManager -{ -public: - // initialisation and housekeeping for the singleton - static void init(); - static void release(); - - // methods for dealing with tardy connection of a key service - static void reconnectEGS(uint8 serviceId); - static void reconnectIOS(uint8 serviceId); - static void reconnectGPMS(uint8 serviceId); - - static void addVisionService(uint serviceId) { _visionHandlingServices.insert(serviceId); } - static void removeVisionService(uint serviceId) { _visionHandlingServices.erase(serviceId); } - - // methods managing the actor set - // getActor() returns NULL if the actor doesn't exist - static CActor *newActor(const std::string &type, const std::string &name); - static void killActor(const std::string &name); - static CActor *getActor(const std::string &name); - static CActor *getActor(const NLMISC::CEntityId &id); - static CActor *getActor(unsigned index); - static uint32 numActors() { return _actors.size(); } - - // Movement script management - static void update(); - -private: - // forbid instantiation - CActorManager(); - - // changed by ben -- std::vector replaced by std::vector because highly unsafe (reallocs might occur) - // to avoid memory fragmentation, use NLMISC::CBlockMemory instead - static std::vector _actors; - static int _nextActorID; - - static std::set _visionHandlingServices; - -public: - // changed by ben -- std::vector replaced by std::vector because highly unsafe (reallocs might occur) - // to avoid memory fragmentation, use NLMISC::CBlockMemory instead - static std::vector _actorGroups; - static CActorGroup * _defaultActorGroup; - - static CActorGroup * newActorGroup(const std::string &name); - static CActorGroup * getActorGroup(const std::string &name); - static CActorGroup * getActorGroup(unsigned index); - static void removeActorGroup(const std::string &name); - - static uint32 numActorGroups() { return _actorGroups.size(); } - - static CActorGroup* getDefaultActorGroup() { return _defaultActorGroup; } - - // move all actors from a group to another group - static void setActorsToGroup(const std::string &sourceActorGroup, const std::string &destActorGroup); - - static sint32 getNextActorId() { return ++_nextActorID; } - -}; - -} // end of namespace AGS_TEST - -#endif // GD_ACTOR_MANAGER_H -/* End of actor_manager.h */ diff --git a/code/ryzom/server/src/ags_test/ags_test.cpp b/code/ryzom/server/src/ags_test/ags_test.cpp deleted file mode 100644 index efb418d90..000000000 --- a/code/ryzom/server/src/ags_test/ags_test.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// Nel Misc -#include "nel/misc/command.h" -#include "nel/misc/path.h" - -// Game share -#include "game_share/container_property_receiver.h" -#include "game_share/msg_brick_service.h" - -// Local includes -#include "ags_test.h" -#include "actor.h" -#include "actor_manager.h" - -#include "../src/agent_game/combat_interface.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace AGS_TEST; - - -CAgsTest* pAgsTest = NULL; - -/** - * CallbackArray - */ -TUnifiedCallbackItem CallbackArray[] = -{ - { "AZERTY", NULL }, -}; - -//--------------------------------------------------- -// Service Init : -// -//--------------------------------------------------- -void CAgsTest::init (void) -{ - // Load the sheet id lookup table - - // Initialise the actor manager - CActorManager::init(); - - // For windows speed update - setUpdateTimeout(100); - - // keep the pointer on class if need use a methode - pAgsTest = this; - - // init the Tick Event Handler - CTickEventHandler::init( serviceUpdate, cbSync ); - - // initialise the property receiver set - CContainerPropertyReceiver::initPropertyReceiver(); - - // init the combat interface - CCombatInterface::init(); - - // Init callback for service up / down - CUnifiedNetwork::getInstance()->setServiceUpCallback ("*", cbServiceUp, NULL); - CUnifiedNetwork::getInstance()->setServiceDownCallback( string("*"), cbServiceDown, 0); -} - -//--------------------------------------------------- -// Service update : -// -//--------------------------------------------------- -bool CAgsTest::update (void) -{ - return true; -} - -//--------------------------------------------------- -// Service release : -// -//--------------------------------------------------- -void CAgsTest::release (void) -{ - CContainerPropertyReceiver::releaseAllPropertiesManagers(); -} - -//--------------------------------------------------- -// Service update : Call at every ticks -// -//--------------------------------------------------- -void CAgsTest::serviceUpdate(void) -{ - CActorManager::update(); -} - -/****************************************************************\ - **************************************************************** - Callback functions - **************************************************************** -\****************************************************************/ -// Callback called at service connexion -void cbServiceUp( const string& serviceName, uint16 serviceId, void * ) -{ - /*if (serviceName==std::string("EGS")) - CActorManager::reconnectEGS((uint8)serviceId); - - if (serviceName==std::string("IOS")) - CActorManager::reconnectIOS((uint8)serviceId); - - if (serviceName==std::string("GPMS")) - CActorManager::reconnectGPMS((uint8)serviceId);*/ -} - -// Callback called at service down -void cbServiceDown( const string& serviceName, uint16 serviceId, void * ) -{ -} - -//--------------------------------------------------- -// cbSync, for service init with current time/tick if needed -// -//--------------------------------------------------- -void cbSync() -{ -} // cbSync // - - -/****************************************************************\ - **************************************************************** - Service register - **************************************************************** -\****************************************************************/ -NLNET_SERVICE_MAIN (CAgsTest, "AgG", "ags_test_service", 0, CallbackArray, "", "") - - - -//------------------------------------------------------------------------- diff --git a/code/ryzom/server/src/ags_test/ags_test.h b/code/ryzom/server/src/ags_test/ags_test.h deleted file mode 100644 index 47f5ba980..000000000 --- a/code/ryzom/server/src/ags_test/ags_test.h +++ /dev/null @@ -1,66 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef GD_AGS_TEST_H -#define GD_AGS_TEST_H - -// Nel Misc -#include "nel/misc/types_nl.h" - -// Nel Net -#include "nel/net/service.h" - -// Game share -#include "game_share/tick_event_handler.h" - - -// Callback called at service connexion -void cbServiceUp( const std::string& serviceName, uint16 serviceId, void * ); - -// Callback called at service down -void cbServiceDown( const std::string& serviceName, uint16 serviceId, void * ); - -// "Callbacks" for Tick service -void cbSync(); - - -/** - * - * \author Alain Saffray - * \author Nevrax France - * \date 2001 - */ -class CAgsTest : public NLNET::IService -{ -public: - // Initialisation of service - void init (void); - - // Update net processing - bool update (void); - - // Update service processing - static void serviceUpdate(void); - - // Release the service - void release (void); -}; - -#endif // GD_AGS_TEST_H -/* End of ags_test.h */ diff --git a/code/ryzom/server/src/ags_test/ags_timer.cpp b/code/ryzom/server/src/ags_test/ags_timer.cpp deleted file mode 100644 index 8239b1fcb..000000000 --- a/code/ryzom/server/src/ags_test/ags_timer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#include "ags_timer.h" -#include "game_share/tick_event_handler.h" - -namespace AGS_TEST -{ - CAGSTimer::CAGSTimer(uint32 dt /*= 0*/) - { - _dt = dt; - } - - void CAGSTimer::set(uint32 dt) - { - _start = (uint32)CTickEventHandler::getGameCycle(); - _dt = dt; - } - - void CAGSTimer::add(uint32 dt) - { - _start = (uint32)CTickEventHandler::getGameCycle(); - _dt += dt; - } - - bool CAGSTimer::test() - { - uint32 curent = (uint32) CTickEventHandler::getGameCycle(); - - uint32 elapsed = curent - _start; - - return ( elapsed >= _dt ); - } - -} diff --git a/code/ryzom/server/src/ags_test/ags_timer.h b/code/ryzom/server/src/ags_test/ags_timer.h deleted file mode 100644 index fbe4efbe8..000000000 --- a/code/ryzom/server/src/ags_test/ags_timer.h +++ /dev/null @@ -1,35 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "nel/misc/types_nl.h" - -namespace AGS_TEST -{ - class CAGSTimer - { - private: - uint32 _start; - uint32 _dt; - public: - CAGSTimer(uint32 dt = 0); - void set(uint32 dt); - void add(uint32 dt); - bool test(); - }; -} - diff --git a/code/ryzom/server/src/ags_test/ai_mgr.cpp b/code/ryzom/server/src/ags_test/ai_mgr.cpp deleted file mode 100644 index 36a0effe8..000000000 --- a/code/ryzom/server/src/ags_test/ai_mgr.cpp +++ /dev/null @@ -1,440 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "ai_mgr.h" - -//-------------------------------------------------------------------------- -// singleton data declaration - -std::vector CAiMgr::_files; - - -//-------------------------------------------------------------------------- -// Utility functions - -// generate indentation strings -static std::string tab(uint indent) -{ - std::string s; - s.resize(indent,'\t'); - return s; -} - -// opening a STRUCT clause in output XML file -static void writeOpenStruct(FILE *outf, uint indent, std::string name=std::string()) -{ - if (name.empty()) - fprintf(outf,"%s\n",tab(1).c_str()); - else - fprintf(outf,"%s\n",tab(1).c_str(),name.c_str()); -} - -// closing a STRUCT clause in output XML file -static void writeCloseStruct(FILE *outf, uint indent) -{ - fprintf(outf,"%s\n",tab(1).c_str()); -} - -// opening an ARRAY clause in output XML file -static void writeOpenArray(FILE *outf, uint indent, std::string name=std::string()) -{ - if (name.empty()) - fprintf(outf,"%s\n",tab(1).c_str()); - else - fprintf(outf,"%s\n",tab(1).c_str(),name.c_str()); -} - -// closing an ARRAY clause in output XML file -static void writeCloseArray(FILE *outf, uint indent) -{ - fprintf(outf,"%s\n",tab(1).c_str()); -} - -// writing an ATOM clause in output XML file -static void writeAtom(FILE *outf, uint indent, std::string name, std::string value) -{ - if (name.empty()) - fprintf(outf,"%s\n",tab(indent).c_str(),value.c_str()); - else - fprintf(outf,"%s\n",tab(indent).c_str(),name.c_str(),value.c_str()); -} - -static void writeAtom(FILE *outf, uint indent, std::string name, int value) -{ - if (name.empty()) - fprintf(outf,"%s\n",tab(indent).c_str(),value); - else - fprintf(outf,"%s\n",tab(indent).c_str(),name.c_str(),value); -} - -static void writeAtom(FILE *outf, uint indent, std::string name, double value) -{ - if (name.empty()) - fprintf(outf,"%s\n",tab(indent).c_str(),value); - else - fprintf(outf,"%s\n",tab(indent).c_str(),name.c_str(),value); -} - - -//-------------------------------------------------------------------------- -// Display -// display contents of hierarchy - -void CAiMgrSpawn::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sSPAWN:",tab(indent).c_str()); - log->displayNL("%s%s",tab(indent+1).c_str(),_place.c_str()); -} - -void CAiMgrPopulation::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sPOPULATION: %s",tab(indent).c_str(),_name.c_str()); - - log->displayNL("%stype: %s",tab(indent+1).c_str(),_creatureType.toString().c_str()); - log->displayNL("%scount: %i",tab(indent+1).c_str(),_quantity); - log->displayNL("%sface: pi * %4.2f",tab(indent+1).c_str(),_orientation/3.14159265359); - log->displayNL("%sspawn: %i..%i ms",tab(indent+1).c_str(),_minTime,_maxTime); -} - -void CAiMgrLocation::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sLOCATION: %s",tab(indent).c_str(),_name.c_str()); - - log->displayNL("%stype: %s",tab(indent+1).c_str(),_type.c_str()); - log->displayNL("%spatat: %s",tab(indent+1).c_str(),_boundary.c_str()); -} - -void CAiMgrInstance::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sMANAGER: %s",tab(indent).c_str(),_name.c_str()); - - log->displayNL("%spatat: %s",tab(indent+1).c_str(),_boundary.c_str()); - log->displayNL("%slimit: %i",tab(indent+1).c_str(),_creatureLimit); - - uint i; - for (i=0;i<_spawn.size();i++) _spawn[i]->display(indent+1); - for (i=0;i<_population.size();i++) _population[i]->display(indent+1); - for (i=0;i<_location.size();i++) _location[i]->display(indent+1); - - for (i=0;i<_children.size();i++) _children[i]->display(indent+1); -} - -void CAiMgrFile::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sFILE: %s",tab(indent).c_str(),_filename.c_str()); - - log->displayNL("%sprim file: %s",tab(indent+1).c_str(),_primFilename.c_str()); - - uint i; - for (i=0;i<_children.size();i++) _children[i]->display(indent+1); -} - -void CAiMgr::display(uint indent, NLMISC::CLog *log) -{ - log->displayNL("%sDISPLAYING PARSED AI_MANAGER FILE CONTENTS",tab(indent).c_str()); - - uint i; - for (i=0;i<_files.size();i++) _files[i]->display(indent+1); -} - - -//-------------------------------------------------------------------------- -// Read -// read .AI_MGR 'george' files - -void CAiMgrSpawn::read() -{ -} - -void CAiMgrPopulation::read() -{ -} - -void CAiMgrLocation::read() -{ -} - -void CAiMgrInstance::read() -{ -} - -void CAiMgrFile::read() -{ - // read a .AI_MGR file and parse the contents -} - -void CAiMgr::read(std::string path,bool recursive) -{ - // recurse through sub directories looking for ai manager files to read -} - - -//-------------------------------------------------------------------------- -// Write -// write .AI_MGR 'george' files - -void CAiMgrSpawn::write(FILE *outf,uint indent) -{ - writeAtom(outf,indent,"",_place.c_str()); -} - -void CAiMgrPopulation::write(FILE *outf,uint indent) -{ - writeOpenStruct(outf,indent,_name); - - // writing the static fields - writeAtom(outf,indent+1,"Name",_name); - writeAtom(outf,indent+1,"CreatureType",_creatureType.toString()); - writeAtom(outf,indent+1,"Population",_quantity); - writeAtom(outf,indent+1,"MinSpawnTime",_minTime); - writeAtom(outf,indent+1,"MaxSpawnTime",_maxTime); - writeAtom(outf,indent+1,"Orientation",_orientation); - - writeCloseStruct(outf,indent); -} - -void CAiMgrLocation::write(FILE *outf,uint indent) -{ - writeOpenStruct(outf,indent,_name); - - // writing the static fields - writeAtom(outf,indent+1,"Name",_name); - writeAtom(outf,indent+1,"LocationType",_type); - writeAtom(outf,indent+1,"Boundary",_boundary); - - writeCloseStruct(outf,indent); -} - -void CAiMgrInstance::write(FILE *outf,uint indent) -{ - uint i; - - writeOpenStruct(outf,indent,_name); - - // writing the static fields - writeAtom(outf,indent+1,"Name",_name); - writeAtom(outf,indent+1,"Boundary",_boundary); - writeAtom(outf,indent+1,"CreatureLimit",_creatureLimit); - - // writing spawn points - if (!_spawn.empty()) - { - writeOpenArray(outf,indent+1,"Spawn"); - for (i=0;i<_spawn.size();i++) _spawn[i]->write(outf,indent+2); - writeCloseArray(outf,indent+1); - } - - // writing populations - if (!_population.empty()) - { - writeOpenArray(outf,indent+1,"Population"); - for (i=0;i<_population.size();i++) _population[i]->write(outf,indent+2); - writeCloseArray(outf,indent+1); - } - - // writing locations - if (!_location.empty()) - { - writeOpenArray(outf,indent+1,"Location"); - for (i=0;i<_location.size();i++) _location[i]->write(outf,indent+2); - writeCloseArray(outf,indent+1); - } - - // writing children - if (!_children.empty()) - { - writeOpenArray(outf,indent+1,"Children"); - for (i=0;i<_children.size();i++) _children[i]->write(outf,indent+2); - writeCloseArray(outf,indent+1); - } - - writeCloseStruct(outf,indent); -} - -void CAiMgrFile::write() -{ - // opening the file - FILE *outf=fopen(_filename.c_str(),"wt"); - if (outf==0) - { - nlwarning("Failed to open file for writing: %s",_filename.c_str()); - return; - } - nlinfo("WRITING: %s",_filename.c_str()); - - // writing the file header - fprintf(outf,"\n"); - fprintf(outf,"
\n"); - writeOpenStruct(outf,1); - - // writing the static fields - writeAtom(outf,2,"Name",_filename); - writeAtom(outf,2,"Prim",_primFilename); - - // iterating through the managers to be written to the file - uint i; - writeOpenArray(outf,2,"Child"); - for (i=0;i<_children.size();i++) - _children[i]->write(outf,3); - writeCloseArray(outf,2); - - // writing the file footer - writeCloseStruct(outf,1); - fprintf(outf,"
\n"); - - // closing the file - fclose(outf); -} - -void CAiMgr::write() -{ - uint i; - for (i=0;i<_files.size();i++) - _files[i]->write(); -} - - -//-------------------------------------------------------------------------- -// Test -// test code to test the interfaces of the different classes - -void CAiMgrSpawn::test() -{ -} - -void CAiMgrPopulation::test() -{ -} - -void CAiMgrLocation::test() -{ -} - -void CAiMgrInstance::test() -{ -} - -void CAiMgrFile::test() -{ -} - -void CAiMgr::test() -{ - CAiMgrSpawn *aiMgrSpawn0 = new CAiMgrSpawn; - CAiMgrSpawn *aiMgrSpawn1 = new CAiMgrSpawn; - CAiMgrSpawn *aiMgrSpawn2 = new CAiMgrSpawn; - CAiMgrPopulation *aiMgrPopulation0 = new CAiMgrPopulation; - CAiMgrPopulation *aiMgrPopulation1 = new CAiMgrPopulation; - CAiMgrPopulation *aiMgrPopulation2 = new CAiMgrPopulation; - CAiMgrLocation *aiMgrLocation0 = new CAiMgrLocation; - CAiMgrLocation *aiMgrLocation1 = new CAiMgrLocation; - CAiMgrLocation *aiMgrLocation2 = new CAiMgrLocation; - CAiMgrInstance *aiMgrInstance0 = new CAiMgrInstance; - CAiMgrInstance *aiMgrInstance1 = new CAiMgrInstance; - CAiMgrInstance *aiMgrInstance2 = new CAiMgrInstance; - CAiMgrFile *aiMgrFile0 = new CAiMgrFile; - CAiMgrFile *aiMgrFile1 = new CAiMgrFile; - CAiMgrFile *aiMgrFile2 = new CAiMgrFile; - - //-------------------------------------- - - aiMgrSpawn0->setPlace("aiMgrSpawn0"); - aiMgrSpawn1->setPlace("aiMgrSpawn1"); - aiMgrSpawn2->setPlace("aiMgrSpawn2"); - - //-------------------------------------- - - aiMgrPopulation0->setName("aiMgrPopulation0_name"); - aiMgrPopulation0->setType(NLMISC::CSheetId("aiMgrPopulation0_type")); - aiMgrPopulation0->setQuantity(0); - aiMgrPopulation0->setOrientation(0); - aiMgrPopulation0->setSpawnRate(0,1); - - aiMgrPopulation1->setName("aiMgrPopulation1_name"); - aiMgrPopulation1->setType(NLMISC::CSheetId("aiMgrPopulation1_type")); - aiMgrPopulation1->setQuantity(1); - aiMgrPopulation1->setOrientation(3.14159265359f/2.0f); - aiMgrPopulation1->setSpawnRate(2,3); - - aiMgrPopulation2->setName("aiMgrPopulation2_name"); - aiMgrPopulation2->setType(NLMISC::CSheetId("aiMgrPopulation2_type")); - aiMgrPopulation2->setQuantity(2); - aiMgrPopulation2->setOrientation(3.14159265359f); - aiMgrPopulation2->setSpawnRate(4,5); - - //-------------------------------------- - - aiMgrLocation0->setName("aiMgrLocation0_name"); - aiMgrLocation0->setType("aiMgrLocation0_type"); - aiMgrLocation0->setBoundary("aiMgrLocation0_boundary"); - - aiMgrLocation1->setName("aiMgrLocation1_name"); - aiMgrLocation1->setType("aiMgrLocation1_type"); - aiMgrLocation1->setBoundary("aiMgrLocation1_boundary"); - - aiMgrLocation2->setName("aiMgrLocation2_name"); - aiMgrLocation2->setType("aiMgrLocation2_type"); - aiMgrLocation2->setBoundary("aiMgrLocation2_boundary"); - - //-------------------------------------- - - aiMgrInstance0->setName("aiMgrInstance0"); - aiMgrInstance0->setBoundary("boundary0"); - aiMgrInstance0->setCreatureLimit(0); - - aiMgrInstance1->setName("aiMgrInstance1"); - aiMgrInstance1->setBoundary("boundary1"); - aiMgrInstance1->setCreatureLimit(1); - - aiMgrInstance2->setName("aiMgrInstance2"); - aiMgrInstance2->setBoundary("boundary2"); - aiMgrInstance2->setCreatureLimit(2); - - aiMgrInstance1->addSpawn(aiMgrSpawn0); - aiMgrInstance1->addSpawn(aiMgrSpawn1); - aiMgrInstance1->addSpawn(aiMgrSpawn2); - - aiMgrInstance1->addPopulation(aiMgrPopulation0); - aiMgrInstance1->addPopulation(aiMgrPopulation1); - aiMgrInstance1->addPopulation(aiMgrPopulation2); - - aiMgrInstance1->addLocation(aiMgrLocation0); - aiMgrInstance1->addLocation(aiMgrLocation1); - aiMgrInstance1->addLocation(aiMgrLocation2); - - aiMgrInstance1->addChild(aiMgrInstance2); - - //-------------------------------------- - - aiMgrFile0->setName("aiMgrFile0"); - aiMgrFile0->setPrim("prim0.prim"); - - aiMgrFile1->setName("aiMgrFile1"); - aiMgrFile0->setPrim("prim1.prim"); - - aiMgrFile2->setName("aiMgrFile2"); - aiMgrFile0->setPrim("prim2.prim"); - - aiMgrFile1->addChild(aiMgrInstance0); - aiMgrFile1->addChild(aiMgrInstance1); - - //-------------------------------------- - - CAiMgr::addFile(aiMgrFile0); - CAiMgr::addFile(aiMgrFile1); - CAiMgr::addFile(aiMgrFile2); -} - diff --git a/code/ryzom/server/src/ags_test/ai_mgr.h b/code/ryzom/server/src/ags_test/ai_mgr.h deleted file mode 100644 index 0b2a071bc..000000000 --- a/code/ryzom/server/src/ags_test/ai_mgr.h +++ /dev/null @@ -1,207 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -//------------------------------------------------------------------------- -// some stuff for manageing the output of AI_MANAGER files - -/* -=========================================================================== - - ------------------------------------------------------------------------- - ** Common methods of the following classes: - - display(uint indent=0) - display the class and all of its child classes recursively - the indent parameter gives the display indentation depth - - read() - read the class and its child classes from a file recursively - - write() - write the class and its child classes to an output file recursively - - test() - runs the class' test routine - - ------------------------------------------------------------------------- - ** The list of classes includes: - - CAiMgrSpawn - A spawn point or spawn zone within an ai manager - CAiMgrPopulation - A population of creatures within an ai manager - CAiMgrLocation - A location with type (eg grass, denn, etc) within an ai manager - CAiMgrInstance - An individual AI manager - CAiMgrFile - The collection of AI managers loaded from or to be saved to a file - - CAiMgr - The singleton that contains the collection of CAiMgrFiles - -=========================================================================== -*/ - - - - -//------------------------------------------------------------------------- -// includes - -#include "nel/misc/types_nl.h" -#include "nel/misc/sheet_id.h" - -#include -#include - - -//------------------------------------------------------------------------- -// class to manage a spawn point or patat for an ai manager - -class CAiMgrSpawn -{ -public: - void setPlace(std::string place) {_place=place;} -public: - void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - void read(); - void write(FILE *outf,uint indent); - void test(); -private: - std::string _place; // names of patat or point (or x y z) -}; - - -//------------------------------------------------------------------------- -// class to manage a bot population for an ai manager - -class CAiMgrPopulation -{ -public: - void setName(std::string name) {_name=name;} - void setType(NLMISC::CSheetId creatureType) {_creatureType=creatureType;} - void setQuantity(int quantity) {_quantity=quantity;} - void setOrientation(float orientation) {_orientation=orientation;} - void setSpawnRate(int minTimeMS, int maxTimeMS) {_minTime=minTimeMS; _maxTime=maxTimeMS;} -public: - void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - void read(); - void write(FILE *outf,uint indent); - void test(); -private: - std::string _name; - NLMISC::CSheetId _creatureType; - int _quantity; - float _orientation; - int _minTime; - int _maxTime; -}; - - -//------------------------------------------------------------------------- -// class to manage a location patat for an ai manager - -class CAiMgrLocation -{ -public: - void setName(std::string name) {_name=name;} - void setType(std::string type) {_type=type;} - void setBoundary(std::string boundary) {_boundary=boundary;} -public: - void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - void read(); - void write(FILE *outf,uint indent); - void test(); -private: - std::string _name; - std::string _type; - std::string _boundary; -}; - - -//------------------------------------------------------------------------- -// class to manage an instance of an ai manager - -class CAiMgrInstance -{ -public: - void setName(const std::string &name) {_name=name;} - void setBoundary(const std::string &boundary) {_boundary=boundary;} - void setCreatureLimit(int creatureLimit) {_creatureLimit=creatureLimit;} - - void addSpawn(CAiMgrSpawn *spawn) {_spawn.push_back(spawn);} - void addPopulation(CAiMgrPopulation *population) {_population.push_back(population);} - void addLocation(CAiMgrLocation *location) {_location.push_back(location);} - - void addChild(CAiMgrInstance *mgr) {_children.push_back(mgr);} -public: - void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - void read(); - void write(FILE *outf,uint indent); - void test(); -private: - std::string _name; - std::string _boundary; - int _creatureLimit; - - std::vector _spawn; - std::vector _population; - std::vector _location; - - std::vector _children; -}; - - -//------------------------------------------------------------------------- -// class to manage the set of ai managers stored in a given file - -class CAiMgrFile -{ -public: - void setName(std::string filename) {_filename=filename;} - void setPrim(std::string primFilename) {_primFilename=primFilename;} - void addChild(CAiMgrInstance *mgr) {_children.push_back(mgr);} -public: - const std::string &getName() {return _filename;} - const std::string &getPrim() {return _primFilename;} - const CAiMgrInstance *getChild(uint i) {return _children[i];} - uint getChildCount() {return _children.size();} -public: - void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - void read(); - void write(); - void test(); -private: - std::string _filename; - std::string _primFilename; - - std::vector _children; -}; - - -//------------------------------------------------------------------------- -// singleton manager of CAiMgrFile instances - -class CAiMgr -{ -public: - static void addFile(CAiMgrFile *file) {_files.push_back(file);} -public: - static void display(uint indent=0,NLMISC::CLog *log = NLMISC::InfoLog); - static void read(std::string path,bool recursive=true); - static void write(); - static void test(); -private: - static std::vector _files; -}; - - -//------------------------------------------------------------------------- diff --git a/code/ryzom/server/src/ags_test/command_event_manager.cpp b/code/ryzom/server/src/ags_test/command_event_manager.cpp deleted file mode 100644 index c55018429..000000000 --- a/code/ryzom/server/src/ags_test/command_event_manager.cpp +++ /dev/null @@ -1,1120 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "command_event_manager.h" -#include "nel/misc/time_nl.h" -#include "nel/misc/file.h" -#include "nel/misc/path.h" -#include "nel/misc/command.h" -#include "nel/misc/variable.h" - -#include "game_share/tick_event_handler.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; - -//using CCommandEventManager::CScript; -//using CCommandEventManager::CScriptNode; -//using CCommandEventManager::CEnvironment; - -#define EXEC_CHILD_AND_EXIT(child) if (child) return executeChild(child, env) -#define EXEC_CHILD_AND_EXIT_ON_HALT_ERROR(child) if (child) { EState state = executeChild(child, env); if (state==Halt || state==Error) return state; } - -CCommandEventManager::TScriptMap CCommandEventManager::_RunningScripts; -string CCommandEventManager::_Empty(""); - -/* - * Constructor - */ -CCommandEventManager::CCommandEventManager() -{ -} - - -// -// Env -// -string CCommandEventManager::CEnvironment::replace(const string &text) -{ - uint start = 0, stop; - string replaced = text; - - do - { - start = replaced.find_first_of('$', start); - if (start == string::npos || start == replaced.size()-1) - break; - - if (replaced[start+1] == '$') - { - replaced.erase(start, 1); - ++start; - continue; - } - else if (replaced[start+1] == '(') - { - stop = replaced.find_first_of(')', start+1); - if (stop == string::npos) - break; - string val = get(replaced.substr(start+2, stop-start-2)); - replaced.erase(start, stop-start+1); - replaced.insert(start, val); - start += val.size(); - } - else if (replaced[start+1] == '[') - { - stop = replaced.find_first_of(']', start+1); - if (stop == string::npos) - break; - - string var = replaced.substr(start+2, stop-start-2); - string val = ""; - ICommand::TCommand::iterator it = ICommand::Commands->find(var); - if (it != ICommand::Commands->end()) - { - IVariable *variable = dynamic_cast((*it).second); - if (variable != NULL) - { - val = variable->toString(); - } - } - replaced.erase(start, stop-start+1); - replaced.insert(start, val); - start += val.size(); - } - else - { - ++start; - } - } - while (start < replaced.size()); - - return replaced; -} - -// -// Script nodes -// - -// ----------------------------------------------------------- -// list node -class CInstListNode : public CCommandEventManager::CScriptNode -{ -public: - vector Nodes; - uint NextToRun; - - CInstListNode() : NextToRun(0) {} - - ~CInstListNode() - { - uint i; - for (i=0; iVerbose) - nldebug("[%s:%d:DEBUG] if %s", Root->Name.c_str(), Line, Condition.c_str()); - - double res; - CEvalNumExpr::TReturnState ev = env.evalExpression(Condition.c_str(), res, NULL); - if (ev == CEvalNumExpr::NoError) - { - if (res != 0.0) - { - // exec true statement - EXEC_CHILD_AND_EXIT(TrueStatement); - } - else - { - // exec false statement - EXEC_CHILD_AND_EXIT(FalseStatement); - } - } - else - { - return Error; - } - - return Ok; - } -}; - -// ----------------------------------------------------------- -// while node -class CWhileNode : public CCommandEventManager::CScriptNode -{ -public: - string Condition; - - CCommandEventManager::CScriptNode *Statement; - - CWhileNode() : Statement(NULL) {} - ~CWhileNode() - { - if (Statement) - delete Statement; - } - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (CurrentRun) - { - EState state = goOnCurrentRun(env); - if (state == Error || state == Halt) - return state; - } - - do - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] while %s", Root->Name.c_str(), Line, Condition.c_str()); - - double res; - CEvalNumExpr::TReturnState ev = env.evalExpression(Condition.c_str(), res, NULL); - if (ev == CEvalNumExpr::NoError) - { - if (res != 0.0) - { - // exec true statement - if (Statement) - { - EXEC_CHILD_AND_EXIT_ON_HALT_ERROR(Statement); - } - } - else - { - break; - } - } - else - { - return Error; - } - } - while (true); - - return Ok; - } -}; - -// ----------------------------------------------------------- -// cmd node -class CCmdNode : public CCommandEventManager::CScriptNode -{ -public: - string Command; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] cmd %s", Root->Name.c_str(), Line, Command.c_str()); - - ICommand::execute(env.replace(Command), *InfoLog); - return Ok; - } -}; - -// ----------------------------------------------------------- -// set text node -class CSetTextNode : public CCommandEventManager::CScriptNode -{ -public: - string Variable; - string Text; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] set$ %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str()); - - env.set(Variable, env.replace(Text)); - return Ok; - } -}; - -// ----------------------------------------------------------- -// set text node -class CSetNumericNode : public CCommandEventManager::CScriptNode -{ -public: - string Variable; - string Text; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] set# %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str()); - - double res; - CEvalNumExpr::TReturnState ev = env.evalExpression(Text.c_str(), res, NULL); - if (ev == CEvalNumExpr::NoError) - { - env.set(Variable, toString(res)); - return Ok; - } - else - { - return Error; - } - } -}; - -// ----------------------------------------------------------- -// erase node -class CEraseNode : public CCommandEventManager::CScriptNode -{ -public: - string Variable; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] erase %s", Root->Name.c_str(), Line, Variable.c_str()); - - env.erase(Variable); - return Ok; - } -}; - -// ----------------------------------------------------------- -// wait node -class CWaitNode : public CCommandEventManager::CScriptNode -{ -public: - uint Wait; - TGameCycle StartCycle; - - CWaitNode() : Wait(0), StartCycle(0) {} - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (!StartCycle) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] wait %d", Root->Name.c_str(), Line, Wait); - - StartCycle = CTickEventHandler::getGameCycle(); - return Halt; - } - else if (CTickEventHandler::getGameCycle() >= StartCycle+Wait) - { - StartCycle = 0; - return Ok; - } - else - { - return Halt; - } - } -}; - -// ----------------------------------------------------------- -// display node -class CDisplayNode : public CCommandEventManager::CScriptNode -{ -public: - string Text; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] ? %s", Root->Name.c_str(), Line, Text.c_str()); - - nlinfo("[%s] %s", Root->Name.c_str(), env.replace(Text).c_str()); - return Ok; - } -}; - -// ----------------------------------------------------------- -// wait node -class CReceiveNode : public CCommandEventManager::CScriptNode -{ -public: - bool Waiting; - string Expression; - - CReceiveNode() : Waiting(false) {} - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (!Waiting) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] receive %s", Root->Name.c_str(), Line, Expression.c_str()); - Waiting = true; - } - - double res; - CEvalNumExpr::TReturnState ev = env.evalExpression(Expression.c_str(), res, NULL); - if (ev != CEvalNumExpr::NoError) - return Error; - else - { - if (res != 0.0) - { - Waiting = false; - return Ok; - } - else - { - return Halt; - } - } - return (ev != CEvalNumExpr::NoError) ? Error : ((res != 0.0) ? Ok : Halt); - } -}; - -// ----------------------------------------------------------- -// wait node -class CSendNode : public CCommandEventManager::CScriptNode -{ -public: - string Variable; - string Text; - - EState execute(CCommandEventManager::CEnvironment &env) - { - if (Root->Verbose) - nldebug("[%s:%d:DEBUG] send %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str()); - - CCommandEventManager::sendEvent(Variable, env.replace(Text)); - return Ok; - } -}; - -// ----------------------------------------------------------- -// Parse script - -CCommandEventManager::CScript *parsedScript = NULL; - -enum -{ - TOKEN_UNKNOWN = 0, - - TOKEN_END, - - TOKEN_COMMENT, - - TOKEN_IF, - TOKEN_ELSE, - TOKEN_ENDIF, - TOKEN_WHILE, - TOKEN_ENDLOOP, - - TOKEN_CMD, // execute a command (while command is evaluated using $(...) syntax) - TOKEN_SETTEXT, // set a variable to a text value (evaluated using $(...) syntax) - TOKEN_SETNUMERIC, // set a variable to a numeric value (evaluated as a normal numeric expression, variables don't need any $(...) form) - TOKEN_ERASE, // erase a variable from env - TOKEN_WAIT, // wait for n game cycles - TOKEN_RECEIVE, // wait for expression to be evaluated to true - TOKEN_SEND, - TOKEN_DISPLAY, -}; - -class CAssociatedToken -{ -public: - CAssociatedToken(uint token, string chars) : Token(token), Chars(chars) {} - uint Token; - string Chars; -}; - -CAssociatedToken CTable[] = -{ - CAssociatedToken(TOKEN_IF, "if"), - CAssociatedToken(TOKEN_ELSE, "else"), - CAssociatedToken(TOKEN_ENDIF, "endif"), - CAssociatedToken(TOKEN_WHILE, "while"), - CAssociatedToken(TOKEN_ENDLOOP, "endloop"), - - CAssociatedToken(TOKEN_CMD, "cmd"), - CAssociatedToken(TOKEN_SETTEXT, "setText"), - CAssociatedToken(TOKEN_SETTEXT, "set$"), - CAssociatedToken(TOKEN_SETNUMERIC, "setNumeric"), - CAssociatedToken(TOKEN_SETNUMERIC, "set#"), - CAssociatedToken(TOKEN_ERASE, "erase"), - CAssociatedToken(TOKEN_WAIT, "wait"), - CAssociatedToken(TOKEN_RECEIVE, "receive"), - CAssociatedToken(TOKEN_SEND, "send"), - CAssociatedToken(TOKEN_DISPLAY, "display"), - CAssociatedToken(TOKEN_DISPLAY, "?"), - - CAssociatedToken(TOKEN_COMMENT, "!"), -}; - -class CParser -{ -public: - const char *Text; - const char *TokenStart; - uint Line; - - CParser() : Text(NULL), Line(0) {} - - - void skipSpace() - { - while (*Text != '\0' && (*Text == ' ' || *Text == '\t')) - ++Text; - } - - void skipAllSpace() - { - while (*Text != '\0' && (*Text == ' ' || *Text == '\t' || *Text == '\r' || *Text == '\n')) - { - if (*Text == '\n') - ++Line; - ++Text; - } - } - - void skipToSpace() - { - while (*Text != '\0' && (*Text != ' ' && *Text != '\t' && *Text != '\r' && *Text != '\n')) - ++Text; - } - - void skipLine() - { - while (*Text != '\0' && (*Text != '\n' && *Text != '\r')) - ++Text; - } - - string getLine() - { - const char *first = Text; - const char *last = Text; - while (*Text != '\0' && (*Text != '\n' && *Text != '\r')) - { - if (*Text != ' ' && *Text != '\t') - last = Text; - ++Text; - } - return string(first, last-first+1); - } - - bool compare(const char *a, const char *t) - { - while (*t>32 && *t==*a) - ++t, ++a; - - return ((*a=='\0' || *a==' ' || *a=='\n' || *a=='\r' || *a=='\t') - && (*t=='\0' || *t==' ' || *t=='\n' || *t=='\r' || *t=='\t')); - } - - string getWord() - { - skipSpace(); - const char *start = Text; - skipToSpace(); - return string(start, Text-start); - } - - uint getToken() - { - skipAllSpace(); - if (*Text == '\0') - return TOKEN_END; - - TokenStart = Text; - skipToSpace(); - skipSpace(); - - uint i; - for (i=0; iRoot = parsedScript; - node->Line = Parser.Line; - node->Condition = Parser.getLine(); - Parser.skipLine(); - - node->TrueStatement = parseInstructionList(); - - uint token = Parser.getToken(); - if (token == TOKEN_ELSE) - { - node->FalseStatement = parseInstructionList(); - token = Parser.getToken(); - } - - if (token != TOKEN_ENDIF) - { - nlwarning("[%s] Unknown token found in structure if, expected endif at line %d. Skip line", parsedScript->Name.c_str(), Parser.Line); - Parser.skipLine(); - } - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseWhile() -{ - Parser.skipSpace(); - - CWhileNode *node = new CWhileNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Condition = Parser.getLine(); - Parser.skipLine(); - - node->Statement = parseInstructionList(); - - if (Parser.getToken() != TOKEN_ENDLOOP) - { - nlwarning("[%s] Unknown token found in structure while, expected endloop at line %d. Skip line", parsedScript->Name.c_str(), Parser.Line); - Parser.skipLine(); - } - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseCmd() -{ - Parser.skipSpace(); - - CCmdNode *node = new CCmdNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Command = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseSetText() -{ - Parser.skipSpace(); - - CSetTextNode *node = new CSetTextNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Variable = Parser.getWord(); - Parser.skipSpace(); - node->Text = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseSetNumeric() -{ - Parser.skipSpace(); - - CSetNumericNode *node = new CSetNumericNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Variable = Parser.getWord(); - Parser.skipSpace(); - node->Text = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseErase() -{ - Parser.skipSpace(); - - CEraseNode *node = new CEraseNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Variable = Parser.getWord(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseWait() -{ - Parser.skipSpace(); - - CWaitNode *node = new CWaitNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Wait = atoi(Parser.getWord().c_str()); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseReceive() -{ - Parser.skipSpace(); - - CReceiveNode *node = new CReceiveNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Expression = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseSend() -{ - Parser.skipSpace(); - - CSendNode *node = new CSendNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Variable = Parser.getWord(); - Parser.skipSpace(); - node->Text = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseDisplay() -{ - Parser.skipSpace(); - - CDisplayNode *node = new CDisplayNode(); - node->Root = parsedScript; - node->Line = Parser.Line; - node->Text = Parser.getLine(); - Parser.skipLine(); - - return (CCommandEventManager::CScriptNode*)node; -} - -// -CCommandEventManager::CScriptNode *parseInstructionList() -{ - CInstListNode *list = new CInstListNode(); - list->Root = parsedScript; - list->Line = Parser.Line; - - do - { - uint token = Parser.getToken(); - - switch (token) - { - case TOKEN_END: - return list; - break; - - case TOKEN_IF: - list->Nodes.push_back(parseIf()); - break; - case TOKEN_ELSE: - Parser.rewindToken(); - return list; - break; - case TOKEN_ENDIF: - Parser.rewindToken(); - return list; - break; - - case TOKEN_WHILE: - list->Nodes.push_back(parseWhile()); - break; - case TOKEN_ENDLOOP: - Parser.rewindToken(); - return list; - break; - - case TOKEN_CMD: - list->Nodes.push_back(parseCmd()); - break; - case TOKEN_SETTEXT: - list->Nodes.push_back(parseSetText()); - break; - case TOKEN_SETNUMERIC: - list->Nodes.push_back(parseSetNumeric()); - break; - case TOKEN_ERASE: - list->Nodes.push_back(parseErase()); - break; - case TOKEN_WAIT: - list->Nodes.push_back(parseWait()); - break; - case TOKEN_RECEIVE: - list->Nodes.push_back(parseReceive()); - break; - case TOKEN_SEND: - list->Nodes.push_back(parseSend()); - break; - case TOKEN_DISPLAY: - list->Nodes.push_back(parseDisplay()); - break; - - case TOKEN_COMMENT: - Parser.skipLine(); - break; - - case TOKEN_UNKNOWN: - nlwarning("[%s] Unknow token at line %d: '%20s...', line ignored", parsedScript->Name.c_str(), Parser.Line, Parser.TokenStart); - Parser.skipLine(); - break; - } - } - while (true); - - return (CCommandEventManager::CScriptNode*)list; -} - - - - - -bool CCommandEventManager::CScript::parse(const char *text) -{ - parsedScript = this; - Parser.Text = text; - Parser.Line = 1; - Root = parseInstructionList(); - return true; -} - -// ----------------------------------------------------------- -// Runs script till it is finished or it waits for an event -bool CCommandEventManager::CScript::run() -{ - CScriptNode::EState state = Root->execute(Environment); - if (state == CScriptNode::Error) - { - nlwarning("[%s] An error occurred in script, script ended", Name.c_str()); - return false; - } - else if (state == CScriptNode::Ok) - { - nlinfo("[%s] Script succesfully terminated, script ended", Name.c_str()); - return false; - } - else - { - return true; - } -} - -// -void cbProcessScriptEvent( CMessage& msgin, const string &serviceName, uint16 serviceId ) -{ - string var; - string value; - - msgin.serial(var, value); - - CCommandEventManager::processEvent(var, value); -} - -TUnifiedCallbackItem CbScriptArray[] = -{ - { "S_EVENT", cbProcessScriptEvent, } -}; - -// -void CCommandEventManager::init() -{ - CUnifiedNetwork::getInstance()->addCallbackArray( CbScriptArray, sizeof(CbScriptArray)/sizeof(CbScriptArray[0]) ); -} - -// -void CCommandEventManager::release() -{ - TScriptMap::iterator it; - for (it = _RunningScripts.begin(); it != _RunningScripts.end(); ++it) - delete (*it).second; - _RunningScripts.clear(); -} - -// -bool CCommandEventManager::update() -{ - TScriptMap::iterator it; - for (it = _RunningScripts.begin(); it != _RunningScripts.end(); ) - if (!((*it).second->run())) - { - TScriptMap::iterator itn = it++; - delete (*itn).second; - _RunningScripts.erase(itn); - } - else - { - ++it; - } - - return true; -} - - -// -bool CCommandEventManager::runScript(const std::string &scriptName, const std::string &scriptFile, bool verbosity) -{ - if (_RunningScripts.find(scriptName) != _RunningScripts.end()) - { - nlwarning("Script '%s' already running, stop script or wait for its end before restarting it", scriptName.c_str()); - return false; - } - - string fname = CPath::lookup(scriptFile, false); - - if (fname == "") - { - nlwarning("Can't find file '%s' to launch script '%s'", scriptFile.c_str(), scriptName.c_str()); - return false; - } - - CIFile file(fname); - - uint sz = file.getFileSize(); - char *buffer = new char[sz+1]; - - try - { - file.serialBuffer((uint8*)buffer, sz); - buffer[sz] = '\0'; - } - catch (EReadError&) - { - nlwarning("Unable to read script file '%s' for script '%s'", scriptFile.c_str(), scriptName.c_str()); - delete buffer; - return false; - } - - CScript *script = new CScript(scriptName); - script->Verbose = verbosity; - - if (!script->parse(buffer)) - { - nlwarning("Unable to parse script file '%s' for script '%s'", scriptFile.c_str(), scriptName.c_str()); - delete buffer; - delete script; - return false; - } - - script->init(); - - nlinfo("Loaded script file '%s' for script '%s' and initialized, ready to run (verbosity %s)", scriptFile.c_str(), scriptName.c_str(), verbosity ? "on":"off"); - _RunningScripts.insert(make_pair(scriptName, script)); - - delete buffer; - - return true; -} - -bool CCommandEventManager::stopScript(const std::string &scriptName) -{ - TScriptMap::iterator it = _RunningScripts.find(scriptName); - if (it == _RunningScripts.end()) - { - nlwarning("Can't stop script '%s', script not found (already stopped?)", scriptName.c_str()); - return false; - } - - // delete script - delete (*it).second; - _RunningScripts.erase(it); - - return true; -} - -const std::string &CCommandEventManager::getVarInScript(const std::string &scriptName, const std::string &varName) -{ - TScriptMap::iterator it = _RunningScripts.find(scriptName); - if (it == _RunningScripts.end()) - { - nlwarning("Can't find script '%s' to get variable '%s'", scriptName.c_str(), varName.c_str()); - return _Empty; - } - - return (*it).second->Environment.get(varName); -} - -void CCommandEventManager::setVarInScript(const std::string &scriptName, const std::string &varName, const std::string &value) -{ - TScriptMap::iterator it = _RunningScripts.find(scriptName); - if (it == _RunningScripts.end()) - { - nlwarning("Can't find script '%s' to set variable '%s' to '%s'", scriptName.c_str(), varName.c_str(), value.c_str()); - return; - } - - (*it).second->Environment.set(varName, value); -} - -void CCommandEventManager::eraseVarInScript(const std::string &scriptName, const std::string &varName) -{ - TScriptMap::iterator it = _RunningScripts.find(scriptName); - if (it == _RunningScripts.end()) - { - nlwarning("Can't find script '%s' to erase variable '%s'", scriptName.c_str(), varName.c_str()); - return; - } - - (*it).second->Environment.erase(varName); -} - -void CCommandEventManager::sendEvent(const std::string &var, const std::string &value) -{ - CMessage msg("S_EVNT"); - msg.serial(const_cast(var)); - msg.serial(const_cast(value)); - //CUnifiedNetwork::getInstance()->sendAll(msg); - - processEvent(var, value); -} - -void CCommandEventManager::processEvent(const std::string &var, const std::string &value) -{ - TScriptMap::iterator it; - for (it = _RunningScripts.begin(); it != _RunningScripts.end(); ++it) - (*it).second->Environment.set(var, value); -} - -// -void CCommandEventManager::setScriptVerbose(const std::string &scriptName, bool verbosity) -{ - TScriptMap::iterator it = _RunningScripts.find(scriptName); - if (it == _RunningScripts.end()) - { - nlwarning("Can't find script '%s' to set verbosity", scriptName.c_str()); - return; - } - - (*it).second->Verbose = verbosity; -} - -// commands -NLMISC_COMMAND(runScript, "Run a script"," [verbosity]") -{ - if (args.size() < 2 || args.size() > 3) - return false; - - bool verb = false; - if (args.size() == 3) - verb = !(args[2] == "0"); - - CCommandEventManager::runScript(args[0], args[1], verb); - return true; -} - -NLMISC_COMMAND(stopScript, "Stop a running script","") -{ - if (args.size() != 1) - return false; - - CCommandEventManager::stopScript(args[0]); - return true; -} - -NLMISC_COMMAND(getVarInScript, "Get a variable value in a script"," ") -{ - if (args.size() != 2) - return false; - - CCommandEventManager::getVarInScript(args[0], args[1]); - return true; -} - -NLMISC_COMMAND(setVarInScript, "Set a variable value in a script"," ") -{ - if (args.size() != 3) - return false; - - CCommandEventManager::setVarInScript(args[0], args[1], args[2]); - return true; -} - -NLMISC_COMMAND(eraseVarInScript, "Erase a variable value in a script"," ") -{ - if (args.size() != 2) - return false; - - CCommandEventManager::eraseVarInScript(args[0], args[1]); - return true; -} - -NLMISC_COMMAND(sendEvent, "Send a script event to all scripts (on all services of the shard)"," ") -{ - if (args.size() != 2) - return false; - - CCommandEventManager::sendEvent(args[0], args[1]); - return true; -} diff --git a/code/ryzom/server/src/ags_test/command_event_manager.h b/code/ryzom/server/src/ags_test/command_event_manager.h deleted file mode 100644 index d66361e9f..000000000 --- a/code/ryzom/server/src/ags_test/command_event_manager.h +++ /dev/null @@ -1,230 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef NL_COMMAND_EVENT_MANAGER_H -#define NL_COMMAND_EVENT_MANAGER_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/common.h" -#include "nel/misc/debug.h" -#include "nel/misc/command.h" -#include "nel/misc/eval_num_expr.h" -#include "nel/net/unified_network.h" - -#include -#include -#include - - -/** - * A Manager that triggers events and is receptive to events - * \author Benjamin Legros - * \author Nevrax France - * \date 2001 - */ -class CCommandEventManager -{ - friend void cbProcessScriptEvent( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); - -public: - /// A type of variable, basically consisting in a name and a value (as a string) - typedef std::pair TVar; - - /// The variable environment of a script - class CEnvironment : public NLMISC::CEvalNumExpr - { - private: - /// The map type of vars - typedef std::map TVarMap; - - /// The map of vars itself - TVarMap _Map; - - /// The empty string - std::string _Empty; - - public: - CEnvironment() : _Empty("") {} - - /// Clear the whole environment - void clear() { _Map.clear(); } - /// Checks if var exists - bool exists(const std::string &var) { return _Map.find(var) != _Map.end(); } - /// Get the value of a var - const std::string &get(const std::string &var) { TVarMap::iterator it=_Map.find(var); return (it!=_Map.end()) ? (*it).second : _Empty; } - /// Set the value of a var - const std::string &set(const std::string &var, const std::string &value) - { - std::pair res = _Map.insert(std::make_pair(var, value)); - if (!res.second) - (*(res.first)).second = value; - return (*(res.first)).second; - } - /// Erases a var - void erase(const std::string &var) { _Map.erase(var); } - /// Replaces text by value in string (variable must have the form $(variable) to be replaced by their value) - std::string replace(const std::string &text); - - protected: - virtual NLMISC::CEvalNumExpr::TReturnState evalValue(const char *value, double &result) - { - TVarMap::iterator it; - if (*value == '?') - { - it = _Map.find(value+1); - if (it == _Map.end()) - result = 0.0; - else - result = 1.0; - return NLMISC::CEvalNumExpr::NoError; - } - else - { - it = _Map.find(value); - if (it == _Map.end()) - return NLMISC::CEvalNumExpr::UnkownValue; - result = atof((*it).second.c_str()); - return NLMISC::CEvalNumExpr::NoError; - } - } - }; - - class CScript; - - /// A script node - class CScriptNode - { - public: - enum EState - { - Ok, - Error, - Halt, - }; - - /// The line in the script for this node - uint Line; - - /// Current running script - CScriptNode *CurrentRun; - - /// The root script - CScript *Root; - - public: - /// default constructor - CScriptNode() : Line(0), CurrentRun(NULL) {} - - /// virtual destructor - virtual ~CScriptNode() {} - - /// Execute the script node, returns the next node to be executed, or NULL if script finished - virtual EState execute(CEnvironment &env) = 0; - - protected: - /// Execute current node (previous run returned halt) - EState goOnCurrentRun(CEnvironment &env) - { - if (!CurrentRun) - return Error; - - EState state = CurrentRun->execute(env); - if (state == Ok) - CurrentRun = NULL; - return state; - } - - /// Execute child - EState executeChild(CScriptNode* child, CEnvironment &env) - { - EState state = child->execute(env); - if (state == Halt || state == Error) - CurrentRun = child; - return state; - } - }; - - /// The script class that receives events, generates events, and triggers commands - class CScript - { - public: - /// The name of the script - std::string Name; - /// The script environment - CEnvironment Environment; - /// The script text - CScriptNode *Root; - /// Verbosity - bool Verbose; - - /// Constructor. - CScript(const std::string &name) : Name(name), Verbose(false) {} - - /// - bool parse(const char *text); - - /// Inits script before execution with no default parameters - void init() { init(std::vector()); } - - /// Inits script before execution, using default parameters - void init(const std::vector &initVars) - { - uint i; - for (i=0; i TScriptMap; - static TScriptMap _RunningScripts; - static std::string _Empty; - -public: - static void init(); - static void release(); - - static bool update(); - - static bool runScript(const std::string &scriptName, const std::string &scriptFile, bool verbose=false); - static bool stopScript(const std::string &scriptName); - static const std::string &getVarInScript(const std::string &scriptName, const std::string &varName); - static void setVarInScript(const std::string &scriptName, const std::string &varName, const std::string &value); - static void eraseVarInScript(const std::string &scriptName, const std::string &varName); - - static void sendEvent(const std::string &var, const std::string &value); - - static void setScriptVerbose(const std::string &scriptName, bool verbosity=true); - -private: - - /// Constructor - CCommandEventManager(); - -protected: - // - static void processEvent(const std::string &var, const std::string &value); -}; - - -#endif // NL_COMMAND_EVENT_MANAGER_H - -/* End of command_event_manager.h */ diff --git a/code/ryzom/server/src/ags_test/commands.cpp b/code/ryzom/server/src/ags_test/commands.cpp deleted file mode 100644 index 4fa955401..000000000 --- a/code/ryzom/server/src/ags_test/commands.cpp +++ /dev/null @@ -1,1347 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// Nel Misc -#include "nel/misc/command.h" -#include "nel/misc/variable.h" -#include "nel/misc/file.h" -#include "nel/misc/i_xml.h" -#include "nel/misc/path.h" -#include "nel/misc/algo.h" - -// Local includes -#include "ags_test.h" -#include "actor.h" -#include "actor_manager.h" -#include "macro_manager.h" -#include "position_generator.h" -#include "sheets.h" -#include "mirrors.h" -#include "ai_mgr.h" - -#include "nel/ligo/primitive.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - -namespace AGS_TEST -{ - - -//------------------------------------------------------------------------- -// Some global variables -uint32 GlobalActorCount=0; -uint32 GlobalActorUpdates=0; -uint32 GlobalActorMoves=0; - -NLMISC_VARIABLE(uint32, GlobalActorCount, "actors"); -NLMISC_VARIABLE(uint32, GlobalActorUpdates, "updates"); -NLMISC_VARIABLE(uint32, GlobalActorMoves, "moves"); - - -//------------------------------------------------------------------------- -// some globals local to this file -static CActor::EActivity DefaultActivity = CActor::SQUARE; -static NLLIGO::CPrimZone * DefaultPatatEvolution = 0; -static float DefaultOrientation = 0.0f; -static float DefaultMagnetRange = 50.0f; -static float DefaultMagnetDecay = 10.0f; -static float DefaultAttackDistance = 0.0f; -static std::string DefaultBehaviour; -static int DefaultDialogue = 0; -static float DefaultMinSpawnTime = 25.0f; -static float DefaultMaxSpawnTime = 25.0f; - -static map PrimOrigin; // map of prim points and zones to prim filename -static std::string SpawnName; // name or coordinates of the spawn point -static CAiMgrFile * AIFile=0; // the file to which ai managers are to be added -static CAiMgrInstance * AIManager=0; // the ai manager to which entities are to be added -static CAiMgrPopulation * AIPopulation=0; // the ai manager to which entities are to be added - -//------------------------------------------------------------------------- -// some stuff for manageing the output of AI_MANAGER files -CAiMgrFile *CurrentAiMgrFile; -CAiMgrInstance *CurrentAiMgrInstance; - - -//------------------------------------------------------------------------- -// CLEANING AND INITIALISING THE SYSTEM - -// Command for resetting the system -NLMISC_COMMAND(actorReset,"Remove all actors and reset the actor system","") -{ - COMMAND_MACRO_RECORD_TEST - - CActorManager::release(); - CActorManager::init(); - GlobalActorCount = 0; - return true; -} - -/* -// Command for removing actors -NLMISC_COMMAND(actorRemove,"Kill one or more actors"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - // iterate through the actor names - for (unsigned i=0;i") -{ - if(args.size() !=1) return false; - - CIFile f(CPath::lookup(args[0])); - NLLIGO::CPrimRegion region; - CIXml xml; - xml.init(f); - region.serial(xml); - - uint i; - // adding zones to move manager - for (i=0; i prim file - for (i=0; i [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args[0]==std::string("grid") && args.size()==1) - {} - else if (args[0]==std::string("line") && args.size()==1) - {} - else if (args[0]==std::string("line") && args.size()==2) - CPositionGenerator::setSpacing(atoi(args[0].c_str())); - else - return false; - - CPositionGenerator::setPattern(args[0]); - return true; -} - -// Command for configuring how actors are placed on landscape -NLMISC_COMMAND(actorCreateSpacing,"Setup spacing for new actors","") -{ - if(args.size() !=1) return false; - COMMAND_MACRO_RECORD_TEST - - CPositionGenerator::setSpacing(atoi(args[0].c_str())); - - return true; -} - -// Command for configuring how actors are placed on landscape -NLMISC_COMMAND(actorCreatePosition,"Setup start position for new actors"," []") -{ - COMMAND_MACRO_RECORD_TEST - - switch(args.size()) - { - case 0: - return false; - case 1: - CPositionGenerator::setPosition(args[0].c_str()); - SpawnName=args[0]; - break; - case 3: - CPositionGenerator::setSpacing(atoi(args[2].c_str())); - // no break - drop through! - case 2: - CPositionGenerator::setPosition(atoi(args[0].c_str()), atoi(args[1].c_str())); - SpawnName=args[0]+" "+args[1]; - break; - default: - return false; - } - - return true; -} - - -//------------------------------------------------------------------------- -// CREATING ACTORS - -static CActor *createActor(std::string type,std::string name) -{ - CActor *theNewActor=CActorManager::newActor(type,name); - if (theNewActor) - { - theNewActor->setActivity (DefaultActivity); - theNewActor->setPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); - } - return theNewActor; -} - -void addPopulation(std::string type,std::string name,uint count) -{ - // if no file has been opened yet then create one - if (AIFile==0) - { - AIFile=new CAiMgrFile; - AIFile->setName(std::string("ags_test.ai_manager")); - CAiMgr::addFile(AIFile); - } - - // create a new ai_manager instance - AIManager= new CAiMgrInstance; - AIFile->addChild(AIManager); - - AIManager->setName(name); - AIManager->setCreatureLimit(count); - if (DefaultPatatEvolution!=0) - AIManager->setBoundary(DefaultPatatEvolution->getName()); - - // add a population record - AIPopulation=new CAiMgrPopulation; - AIManager->addPopulation(AIPopulation); - - AIPopulation->setName(name); - AIPopulation->setOrientation(DefaultOrientation); - AIPopulation->setQuantity(count); - AIPopulation->setSpawnRate(int(DefaultMinSpawnTime*1000.0),int(DefaultMaxSpawnTime*1000.0)); - AIPopulation->setType(NLMISC::CSheetId(type)); - - // add a spawn location - CAiMgrSpawn *spawn=new CAiMgrSpawn; - AIManager->addSpawn(spawn); - - spawn->setPlace(SpawnName); - - // check whether the spawn or evolution patats are in an unrefferenced prim file - if (PrimOrigin.find(CPositionGenerator::getSpawnName())!=PrimOrigin.end()) - { - if (AIFile->getPrim().empty()) - AIFile->setPrim(PrimOrigin[CPositionGenerator::getSpawnName()]); - else - if (AIFile->getPrim()!=PrimOrigin[CPositionGenerator::getSpawnName()]) - nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'", - CPositionGenerator::getSpawnName().c_str(), - PrimOrigin[CPositionGenerator::getSpawnName()].c_str(), - AIFile->getPrim().c_str() ); - } - - if (DefaultPatatEvolution!=0) - if (PrimOrigin.find(DefaultPatatEvolution->getName())!=PrimOrigin.end()) - { - if (AIFile->getPrim().empty()) - AIFile->setPrim(PrimOrigin[DefaultPatatEvolution->getName()]); - else - if (AIFile->getPrim()!=PrimOrigin[DefaultPatatEvolution->getName()]) - nlwarning("WARNING: Can only apply one prim file per AI manager - spawn '%s' in '%s' NOT '%s'", - DefaultPatatEvolution->getName().c_str(), - PrimOrigin[DefaultPatatEvolution->getName()].c_str(), - AIFile->getPrim().c_str() ); - } -} - -// Command for creating actors -NLMISC_COMMAND(actorCreate,"Add one or more moving actors"," [...]") -{ - if(args.size() <2) return false; - COMMAND_MACRO_RECORD_TEST - - // store the population information in an AI_MGR file record - addPopulation(args[0],args[1],args.size()-1); - - // iterate through the actor names - for (unsigned i=1;isetActivity (DefaultActivity); - theNewActor->setPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); -*/ - CActor *theNewActor=createActor(args[0],args[i]); - } - - return true; -} - -// Command for creating actors -NLMISC_COMMAND(actorCreateCustom,"Add one or more moving actors"," [ [-act ] [-pos ] [-ctop ] [-cbot ] [-chair ] [-rhand ] [-lhand ] ] [...]") -{ - if(args.size() <2) return false; - COMMAND_MACRO_RECORD_TEST -/* - uint i; - for (i=1; i ") -{ - if(args.size()!=3 || atoi(args[2].c_str())<=0 || atoi(args[2].c_str())>1024) return false; - COMMAND_MACRO_RECORD_TEST - - CActorGroup *theNewGroup=CActorManager::newActorGroup(args[1]); - - // store the population information in an AI_MGR file record - addPopulation(args[0],args[1],atoi(args[2].c_str())); - - // iterate through the actor names - for (int i=0;iactorCount())); - theNewActor->setActivity (DefaultActivity); - theNewActor->setPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); -*/ - CActor *theNewActor=createActor(args[0],args[1]+toString(theNewGroup->actorCount())); - - if (theNewActor) - theNewGroup->addActor(theNewActor); - } - - return true; -} - - -// Command for creating actors -NLMISC_COMMAND(actorCreateMoving,"Add one or more static actors"," [...]") -{ - if(args.size() ==1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::SQUARE; - } - else - { - // store the population information in an AI_MGR file record - addPopulation(args[0],args[1],args.size()-1); - - // iterate through the actor names - for (unsigned i=1;isetPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); -*/ - CActor *theNewActor=createActor(args[0],args[i]); - - if (theNewActor) - { - theNewActor->doSquare(); - theNewActor->setActivity(CActor::SQUARE); - } - } - } - - return true; -} - - -// Command for creating actors -NLMISC_COMMAND(actorCreateStationary,"Add one or more static actors"," [...]") -{ - if(args.size() ==1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::NOTHING; - } - else - { - // store the population information in an AI_MGR file record - addPopulation(args[0],args[1],args.size()-1); - - // iterate through the actor names - for (unsigned i=1;isetPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); -*/ - CActor *theNewActor=createActor(args[0],args[i]); - - if (theNewActor) - { - theNewActor->doNothing(); - theNewActor->setActivity(CActor::NOTHING); - } - } - } - - return true; -} - - -// Command for creating actors -NLMISC_COMMAND(actorCreateWandering,"Add one or more static actors"," [...]") -{ - if(args.size() ==1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::WANDER; - } - else - { - // store the population information in an AI_MGR file record - addPopulation(args[0],args[1],args.size()-1); - - // iterate through the actor names - for (unsigned i=1;isetPrimZone (DefaultPatatEvolution); - theNewActor->setAngle (DefaultOrientation); - theNewActor->setMagnetRange (DefaultMagnetRange,DefaultMagnetDecay); - theNewActor->setBehaviour (DefaultBehaviour); - theNewActor->setAttackDistance (DefaultAttackDistance); - theNewActor->setChatSet (DefaultDialogue); -*/ - CActor *theNewActor=createActor(args[0],args[i]); - - if (theNewActor) - { - theNewActor->doWander(); - theNewActor->setActivity(CActor::WANDER); - } - } - } - - return true; -} - - -// Command for moving actor from a group to another -NLMISC_COMMAND(moveActorsToGroup,"Move actors from a group to another (source group is emptied). If no source specified, all actors from defaultGroup assumed.","[] ") -{ - COMMAND_MACRO_RECORD_TEST - - if (args.size() < 1) - return false; - - if (args.size() > 2) - return false; - - if (args.size() == 1) - CActorManager::setActorsToGroup("defaultGroup", args[0]); - else - CActorManager::setActorsToGroup(args[0], args[1]); - - return true; -} - - -//------------------------------------------------------------------------- -// MANAGING EXISTING ACTORS - -// Command for setting an actor PrimZone -NLMISC_COMMAND(actorSetPatatEvolution,"Set actor patat evolution"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - NLLIGO::CPrimZone *primZone = CMoveManager::getPrimZone(args[0]); - if (primZone == NULL) - { - nlwarning("Can't find prim zone '%s'", args[0].c_str()); - return false; - } - - if (args.size()==1) - { - // no actor names specified so setup the default value to apply to new actors - DefaultPatatEvolution = primZone; - } - else - { - // apply this evolution patat to the last manager stored in ai manager - if (AIManager) - AIManager->setBoundary(args[0]); - - // iterate through the actor names - uint i; - for (i=1;isetPrimZone(primZone); - } - } - - return true; -} - - - -// Command for setting actor orientations -NLMISC_COMMAND(actorSetOrientation,"Add one or more static actors"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - const char *angleNames[]= {"E", "ENE", "NE", "NNE", "N","NNW","NW","WNW","W","WSW","SW","SSW","S","SSE","SE","ESE"}; - unsigned i; - float theta; - -#ifndef NL_OS_WINDOWS -#define stricmp strcasecmp -#endif - - for (i=0; isetOrientation(theta); - - // iterate through the actor names - for (i=1;isetAngle(theta); - } - } - - return true; -} - - -// Command for setting actor magnet range -NLMISC_COMMAND(actorSetMagnetRange,"Set the magnet properties for wandering behaviour"," [] [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - float range; - NLMISC::fromString(args[0], range); - if (range<=0.0f) return false; - - unsigned start; - float decay; - NLMISC::fromString(args[0], decay); - if (decay<0.0f) return false; - if (decay==0.0f) - { - decay=10.0f; - start=1; - } - else - start=2; - if((sint)args.size() <(start+1)) return false; - - if (args.size()1) - DefaultMagnetDecay = decay; - } - else - { - // iterate through the actor names - for (unsigned i=start;isetMagnetRange(range,decay); - } - } - - return true; -} - -// Command for setting actor attack distance -NLMISC_COMMAND(actorSetAttackDistance,"set actor attack distance"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - float distance; - NLMISC::fromString(args[0], distance); -// if (distance<=0.0f) return false; - - if (args.size()<2) - { - // no actor names specified so setup the default value to apply to new actors - DefaultAttackDistance = distance; - } - else - { - // iterate through the actor names - for (unsigned i=1;isetAttackDistance(distance); - } - } - - return true; -} - -// Command for setting actor mode -/*NLMISC_COMMAND(actorSetMode,"Set actor mode"," [...]") -{ - if(args.size() <2) return false; - COMMAND_MACRO_RECORD_TEST - - // iterate through the named actors setting their mode - for (unsigned i=1;isetMode(args[0]); - } - - return true; -}*/ - -// Command for setting actor behaviour -NLMISC_COMMAND(actorSetBehaviour,"Set actor behaviour"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()<2) - { - // no actor names specified so setup the default value to apply to new actors - DefaultBehaviour = args[0]; - } - else if (args.size() == 2 && args[1] == "all") - { - uint num = CActorManager::numActors(); - uint i; - for (i=0; isetBehaviour(args[0]); - } - } - else - { - // iterate through the named actors setting their behaviour - for (unsigned i=1;isetBehaviour(args[0]); - } - } - - return true; -} - -// Command for setting actor dialogue for bot chat -NLMISC_COMMAND(actorSetDialogue,"Set actor bot-chat dialogue"," [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - int dialogue=atoi(args[0].c_str()); - - if (args.size()<2) - { - // no actor names specified so setup the default value to apply to new actors - DefaultDialogue = dialogue; - } - else - { - // iterate through the named actors setting their behaviour - for (unsigned i=1;isetChatSet(dialogue); - } - } - - return true; -} - - -// Command for setting actor respawn time (when dead) -NLMISC_COMMAND(actorSetRespawnDelay,"set actor respawn delay"," [] [...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - float min; - NLMISC::fromString(args[0], min); - if (min<=0.0f) return false; - - unsigned start; - float max; - NLMISC::fromString(args[0], max); - if (max==0.0f) - { - max=min; - start=1; - } - else - { - if (max1) - DefaultMaxSpawnTime = max; - } - else - { - // apply this orientation to the last manager stored in ai manager - if (AIPopulation) - AIPopulation->setSpawnRate(int(1000.0*min),int(1000.0*max)); - - // iterate through the actor names - for (unsigned i=start;isetSpawnTime(min,max); - } - } - - return true; -} - - -// Command for making actors walk in a square pattern -NLMISC_COMMAND(actorSetActivitySquare,"Make actors walk in a square shape","[...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::SQUARE; - } - else if (args.size() == 1 && args[0] == "all") - { - uint num = CActorManager::numActors(); - uint i; - for (i=0; isetActivity(CActor::SQUARE); - } - } - else - { - // iterate through the actor names - for (unsigned i=0;isetActivity(CActor::SQUARE); - } - } - - return true; -} - -// Command for making actor(s) wander about randomly -NLMISC_COMMAND(actorSetActivityWander,"Make actors walk in a square shape","[...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::WANDER; - } - else if (args.size() == 1 && args[0] == "all") - { - uint num = CActorManager::numActors(); - uint i; - for (i=0; isetActivity(CActor::WANDER); - } - } - else - { - // iterate through the actor names - for (unsigned i=0;isetActivity(CActor::WANDER); - } - } - - return true; -} - -// Command for making actor(s) stand still -NLMISC_COMMAND(actorSetActivityStationary,"Make actors stop walking/ fighting","[...]") -{ - if(args.size() <1) return false; - COMMAND_MACRO_RECORD_TEST - - if (args.size()==0) - { - // no actor names specified so setup the default value to apply to new actors - DefaultActivity = CActor::NOTHING; - } - else if (args.size() == 1 && args[0] == "all") - { - uint num = CActorManager::numActors(); - uint i; - for (i=0; isetActivity(CActor::NOTHING); - } - } - else - { - // iterate through the actor names - for (unsigned i=0;isetActivity(CActor::NOTHING); - } - } - - return true; -} - -// Command for making actors attack entities -NLMISC_COMMAND(actorFight,"Make actors fight eachother"," ") -{ - if(args.size()!=2) return false; - COMMAND_MACRO_RECORD_TEST - - CActor *actor0=CActorManager::getActor(args[0]); - CActor *actor1=CActorManager::getActor(args[1]); - CActorGroup *group0=CActorManager::getActorGroup(args[0]); - CActorGroup *group1=CActorManager::getActorGroup(args[1]); - - - if (actor0) - { - if (actor1) - { - actor0->doFight(actor1); - nlinfo("ACTOR %s Attacking ACTOR: %s",args[0].c_str(),args[1].c_str()); -// actor1->doFight(actor0); - } - else if (group1) - { - actor0->doFight(group1); - nlinfo("ACTOR %s Attacking GROUP: %s",args[0].c_str(),args[1].c_str()); -// group1->doFight(actor0); - } - else - { - CEntityId id; - id.fromString( args[1].c_str() ); - actor0->doFight(id); - nlinfo("ACTOR %s Attacking entity with SID: %s",args[0].c_str(),args[1].c_str()); - } - } - else if (group0) - { - if (actor1) - { - group0->doFight(actor1); - nlinfo("GROUP %s Attacking ACTOR: %s",args[0].c_str(),args[1].c_str()); -// actor1->doFight(group0); - } - else if (group1) - { - group0->doFight(group1); - nlinfo("GROUP %s Attacking GROUP: %s",args[0].c_str(),args[1].c_str()); -// group1->doFight(group0); - } - else - { - CEntityId id; - id.fromString( args[1].c_str() ); - //group0->doFight(id); - nlinfo("GROUP %s Cannot attack: %s (no actor or group of this name found in this service)",args[0].c_str(),args[1].c_str()); - } - } - else nlinfo("Actor or group doesn't exist: %s",args[0].c_str()); - - return true; -} - -// Command for displaying all of or named actors -NLMISC_COMMAND(actorDisplay,"List the actors","[...]") -{ - COMMAND_MACRO_RECORD_TEST - - if(args.size() <1) - { - // list all the actors' stats - for (unsigned i=0;idisplay(); - } - else - { - // iterate through the named actors listing their stats - for (unsigned i=0;idisplay(&log); - } - } - - return true; -} - -//------------------------------------------------------------------------- -// MANAGING AI FILES - -// command to display ai manager hierachy -NLMISC_COMMAND(aiDisplay,"Display the ai manager hierachy","") -{ - if(args.size()!=0) return false; - COMMAND_MACRO_RECORD_TEST - - CAiMgr::display(0, &log); - return true; -} - -// command to set the output file for ai populations -NLMISC_COMMAND(aiFile,"Set the file name for the following ai populations","") -{ - if(args.size()!=1) return false; - COMMAND_MACRO_RECORD_TEST - - AIFile=new CAiMgrFile; - AIFile->setName(args[0]+std::string(".ai_manager")); - CAiMgr::addFile(AIFile); - return true; -} - -// command to write ai manager hierachy to files -NLMISC_COMMAND(aiWrite,"Write the ai manager hierachy to disk","") -{ - if(args.size()!=0) return false; - COMMAND_MACRO_RECORD_TEST - - CAiMgr::write(); - return true; -} - -// command to read ai manager hierachy from files -NLMISC_COMMAND(aiRead,"Read the ai manager hierachy from disk","") -{ - if(args.size()!=1) return false; - COMMAND_MACRO_RECORD_TEST - - CAiMgr::read(args[0],true); - return true; -} - - -//------------------------------------------------------------------------- -// MANAGING MACROS - -// Command for creating a new macro -NLMISC_COMMAND(macroRecord,"Start recording a new macro","") -{ - if(args.size() !=1) - return false; - - CMacroManager::recordMacro(args[0]); - - return true; -} - - -// Command for adding a line to a macro -NLMISC_COMMAND(macroStopRecord,"stop macro recording","") -{ - if(args.size() !=0) - return false; - - CMacroManager::stopRecord(); - - return true; -} - - -// Command for executing a macro -NLMISC_COMMAND(macroExecute,"Execute one or more macros"," [...]") -{ - if(args.size() <1) - return false; - - for (unsigned i=0;i [ ...]") -{ - if (args.size() < 6) - return false; - - const string &scriptName = args[0]; - double spawnX; - NLMISC::fromString(args[1], spawnX); - double spawnY; - NLMISC::fromString(args[2], spawnY); - double spacing; - NLMISC::fromString(args[3], spacing); - uint width; - NLMISC::fromString(args[4], width); - const string &extension = args[5]; - vector filters; - - uint i; - for (i=6; i files; - CPath::getFileList(extension, files); - - if (!filters.empty()) - { - vector::iterator itr; - for (itr=files.begin(); itr!=files.end(); ) - { - bool match = false; - - if (files[i][0] != '_') - { - for (i=0; !match && i= width) - { - cx = spawnX; - cy += spacing; - inLine = 0; - } - } - - script.close(); - - return true; -} - -// -NLMISC_COMMAND(generateAndRun, "Generate and run a sript that spawn a given type of creature", " [ ...]") -{ - string scriptfile = IService::getInstance()->WriteFilesDirectory.toString()+"ags_generated.script"; - string commandLine = "generateScript "+scriptfile; - - uint i; - for (i=0; i [ ...]") -{ - if (args.size() < 6) - return false; - - string scriptName = args[0]; - string filename = scriptName+".script"; - - string scriptfile = CPath::lookup(filename, false, false); - - if (scriptfile.empty()) - { - if (!CFile::isExists("data_shard/")) - CFile::createDirectory("data_shard/"); - if (!CFile::isExists("data_shard/ags_script/")) - CFile::createDirectory("data_shard/ags_script/"); - - scriptfile = string("data_shard/ags_script/")+filename; - - string commandLine = "generateScript "+scriptfile; - uint i; - for (i=1; i [ ...]") -{ - if (args.size() < 2) - return false; - - CEntityId caster; - list targets; - - caster.fromString(args[0].c_str()); - - CMirrorPropValueList targetList(TheDataset, caster, "TargetList"); - - targetList.clear(); - - uint i; - for (i=args.size()-1; i>=2; --i) - { - CEntityId target; - target.fromString(args[i].c_str()); - TDataSetRow targetIndex = CMirrors::DataSet->getDataSetRow(target); - - targetList.push_front(targetIndex); - } - - TGameCycle castTime = CTickEventHandler::getGameCycle() + atoi(args[1].c_str()); - targetList.push_front(*((TDataSetRow*)(&castTime))); - - return true; -} - -//------------------------------------------------------------------------- -} // end of namespace AGS_TEST - - diff --git a/code/ryzom/server/src/ags_test/creatures.cpp b/code/ryzom/server/src/ags_test/creatures.cpp deleted file mode 100644 index 369a48925..000000000 --- a/code/ryzom/server/src/ags_test/creatures.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -// Misc -#include "nel/misc/path.h" -#include "nel/misc/file.h" -#include "nel/misc/smart_ptr.h" -#include "nel/misc/command.h" -// Georges -//#include "nel/georges/u_form.h" -//#include "nel/georges/u_form_elm.h" -//#include "nel/georges/u_form_loader.h" -#include "nel/georges/load_form.h" -// Local -#include "creatures.h" - - -/////////// -// USING // -/////////// -using namespace NLMISC; -using namespace std; -using namespace NLGEORGES; - -namespace AGS_TEST -{ - -//------------------------------------------------------------------------- -// the singleton data - -std::map CCreatures::_creatures; -bool CCreatures::_initialised=false; - - -//------------------------------------------------------------------------- -// init - -void CCreatures::init() -{ - if (_initialised) - return; - - std::vector filters; - filters.push_back("creature"); - filters.push_back("player"); - - loadForm(filters, "ags.packed_sheets", _creatures); - - _initialised=true; -} - - -//------------------------------------------------------------------------- -// display - -void CCreatures::display() -{ - nlassert(_initialised); - - std::map::iterator it; - for(it=_creatures.begin();it!=_creatures.end();++it) - { - nlinfo("CREATURE: %s Walk: %f Run: %f",(*it).first.toString().c_str(), - (*it).second._walkSpeed,(*it).second._runSpeed); - } -} - - -//------------------------------------------------------------------------- -// lookup - -const CCreatures::CCreatureRecord *CCreatures::lookup( CSheetId id ) -{ - nlassert(_initialised); - - // setup an iterator and lookup the sheet id in the map - std::map::iterator it; - it=_creatures.find(id); - - // if we found a valid entry return a pointer to the creature record otherwise 0 - if (it!=_creatures.end()) - return &((*it).second); - else - return 0; -} - - - -} // end of namespace AGS_TEST diff --git a/code/ryzom/server/src/ags_test/creatures.h b/code/ryzom/server/src/ags_test/creatures.h deleted file mode 100644 index a976e08ab..000000000 --- a/code/ryzom/server/src/ags_test/creatures.h +++ /dev/null @@ -1,88 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef AGST_CREATURE_H -#define AGST_CREATURE_H - -// Nel Misc -#include "nel/misc/types_nl.h" -#include "nel/misc/smart_ptr.h" - -#include "nel/georges/u_form.h" -#include "nel/georges/u_form_elm.h" - -// Game share -#include "nel/misc/sheet_id.h" - -namespace AGS_TEST -{ - -/** - * Singleton containing database on information on creatures - * \author Sadge - * \author Nevrax France - * \date 2002 - */ -class CCreatures -{ -public: - class CCreatureRecord - { - public: - CCreatureRecord () : _walkSpeed(1.3f), _runSpeed(6.0f) {} - - float _walkSpeed; - float _runSpeed; - - void readGeorges (const NLMISC::CSmartPtr &form, const NLMISC::CSheetId &sheetId) - { - // the form was found so read the true values from George - form->getRootNode ().getValueByName (_walkSpeed, "Basics.MovementSpeeds.WalkSpeed"); - form->getRootNode ().getValueByName (_runSpeed, "Basics.MovementSpeeds.RunSpeed"); - } - - void serial (NLMISC::IStream &s) - { - s.serial (_walkSpeed, _runSpeed); - } - - static uint getVersion () { return 1; } - }; - - // load the creature data from the george files - static void init(); - - // display the creature data for all known creature types - static void display(); - - // get a creature data record from the database - static const CCreatureRecord *lookup( NLMISC::CSheetId id ); - -private: - // prohibit cnstructor as this is a singleton - CCreatures(); - - static std::map _creatures; - static bool _initialised; -}; - -} // end of namespace AGS_TEST - -#endif // AGST_CREATURE_H -/* End of creatures.h */ diff --git a/code/ryzom/server/src/ags_test/ig_list.h b/code/ryzom/server/src/ags_test/ig_list.h deleted file mode 100644 index 5c3691f9e..000000000 --- a/code/ryzom/server/src/ags_test/ig_list.h +++ /dev/null @@ -1,579 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -typedef char * TFileName; - -TFileName IGFiles[]= -{ -"10_ai.ig", -"10_aj.ig", -"10_ak.ig", -"10_al.ig", -"10_am.ig", -"10_an.ig", -"10_ao.ig", -"10_ap.ig", -"10_aq.ig", -"10_ar.ig", -"10_as.ig", -"10_at.ig", -"10_au.ig", -"10_av.ig", -"10_aw.ig", -"10_ax.ig", -"10_ay.ig", -"10_az.ig", -"10_ba.ig", -"10_bb.ig", -"10_bc.ig", -"10_bd.ig", -"10_be.ig", -"11_ai.ig", -"11_aj.ig", -"11_ak.ig", -"11_al.ig", -"11_am.ig", -"11_an.ig", -"11_ao.ig", -"11_ap.ig", -"11_aq.ig", -"11_ar.ig", -"11_as.ig", -"11_at.ig", -"11_au.ig", -"11_av.ig", -"11_aw.ig", -"11_ax.ig", -"11_ay.ig", -"11_az.ig", -"11_ba.ig", -"11_bb.ig", -"11_bc.ig", -"11_bd.ig", -"11_be.ig", -"12_ai.ig", -"12_aj.ig", -"12_ak.ig", -"12_al.ig", -"12_am.ig", -"12_an.ig", -"12_ao.ig", -"12_ap.ig", -"12_aq.ig", -"12_ar.ig", -"12_as.ig", -"12_at.ig", -"12_au.ig", -"12_av.ig", -"12_aw.ig", -"12_ax.ig", -"12_ay.ig", -"12_az.ig", -"12_ba.ig", -"12_bb.ig", -"12_bc.ig", -"12_bd.ig", -"13_ai.ig", -"13_aj.ig", -"13_ak.ig", -"13_al.ig", -"13_am.ig", -"13_an.ig", -"13_ao.ig", -"13_ap.ig", -"13_aq.ig", -"13_ar.ig", -"13_as.ig", -"13_at.ig", -"13_au.ig", -"13_av.ig", -"13_aw.ig", -"13_ax.ig", -"13_ay.ig", -"13_az.ig", -"13_ba.ig", -"14_aj.ig", -"14_ak.ig", -"14_al.ig", -"14_am.ig", -"14_an.ig", -"14_ao.ig", -"14_ap.ig", -"14_aq.ig", -"14_ar.ig", -"14_as.ig", -"14_at.ig", -"14_au.ig", -"14_av.ig", -"14_aw.ig", -"14_ax.ig", -"15_al.ig", -"15_am.ig", -"15_an.ig", -"15_ao.ig", -"15_ap.ig", -"15_aq.ig", -"15_ar.ig", -"15_as.ig", -"15_at.ig", -"15_au.ig", -"15_av.ig", -"15_aw.ig", -"16_am.ig", -"16_an.ig", -"16_ao.ig", -"16_ap.ig", -"16_aq.ig", -"16_ar.ig", -"16_as.ig", -"16_at.ig", -"16_au.ig", -"16_av.ig", -"16_aw.ig", -"17_am.ig", -"17_an.ig", -"17_ao.ig", -"17_ap.ig", -"17_as.ig", -"17_at.ig", -"17_au.ig", -"17_av.ig", -"17_aw.ig", -"17_ax.ig", -"17_ay.ig", -"17_az.ig", -"18_at.ig", -"18_au.ig", -"18_av.ig", -"18_aw.ig", -"18_ax.ig", -"18_ay.ig", -"18_az.ig", -"19_at.ig", -"19_au.ig", -"19_av.ig", -"19_aw.ig", -"19_ax.ig", -"19_ay.ig", -"19_az.ig", -"19_ba.ig", -"19_bb.ig", -"20_au.ig", -"20_av.ig", -"20_aw.ig", -"20_ax.ig", -"20_ay.ig", -"20_az.ig", -"20_ba.ig", -"20_bb.ig", -"20_bc.ig", -"20_bd.ig", -"20_be.ig", -"21_aw.ig", -"21_ax.ig", -"21_ay.ig", -"21_az.ig", -"21_ba.ig", -"21_bb.ig", -"21_bc.ig", -"21_bd.ig", -"21_be.ig", -"22_aw.ig", -"22_ax.ig", -"22_ay.ig", -"22_az.ig", -"22_ba.ig", -"22_bb.ig", -"22_bc.ig", -"22_bd.ig", -"22_be.ig", -"23_av.ig", -"23_aw.ig", -"23_ax.ig", -"23_ay.ig", -"23_az.ig", -"23_ba.ig", -"23_bb.ig", -"23_bc.ig", -"23_bd.ig", -"23_be.ig", -"24_av.ig", -"24_aw.ig", -"24_ax.ig", -"24_ay.ig", -"24_az.ig", -"24_ba.ig", -"24_bb.ig", -"24_bc.ig", -"24_bd.ig", -"24_be.ig", -"25_av.ig", -"25_aw.ig", -"25_ax.ig", -"25_ay.ig", -"25_az.ig", -"25_ba.ig", -"25_bb.ig", -"25_bc.ig", -"26_az.ig", -"26_ba.ig", -"26_bb.ig", -"26_bc.ig", -"26_bd.ig", -"26_be.ig", -"26_bf.ig", -"27_az.ig", -"27_ba.ig", -"27_bb.ig", -"27_bc.ig", -"27_bd.ig", -"27_be.ig", -"27_bf.ig", -"28_az.ig", -"28_ba.ig", -"28_bb.ig", -"28_bc.ig", -"28_bd.ig", -"28_be.ig", -"28_bf.ig", -"29_bb.ig", -"29_bc.ig", -"29_bd.ig", -"29_be.ig", -"29_bf.ig", -"30_bb.ig", -"30_bc.ig", -"30_bd.ig", -"30_be.ig", -"30_bf.ig", -"31_ay.ig", -"31_az.ig", -"31_ba.ig", -"31_bb.ig", -"31_bc.ig", -"31_bd.ig", -"31_be.ig", -"32_ax.ig", -"32_ay.ig", -"32_az.ig", -"32_ba.ig", -"32_bb.ig", -"32_bc.ig", -"32_bd.ig", -"32_be.ig", -"32_bf.ig", -"33_aw.ig", -"33_ax.ig", -"33_ay.ig", -"33_az.ig", -"33_ba.ig", -"33_bb.ig", -"33_bc.ig", -"33_bd.ig", -"33_be.ig", -"33_bf.ig", -"34_aw.ig", -"34_ax.ig", -"34_ay.ig", -"34_az.ig", -"34_ba.ig", -"34_bb.ig", -"34_bc.ig", -"34_bd.ig", -"34_be.ig", -"34_bf.ig", -"34_bg.ig", -"35_av.ig", -"35_aw.ig", -"35_ax.ig", -"35_ay.ig", -"35_az.ig", -"35_ba.ig", -"35_bb.ig", -"35_bc.ig", -"35_bd.ig", -"35_be.ig", -"35_bf.ig", -"35_bg.ig", -"36_av.ig", -"36_aw.ig", -"36_ax.ig", -"36_ay.ig", -"36_az.ig", -"36_ba.ig", -"36_bb.ig", -"36_bc.ig", -"36_bd.ig", -"36_be.ig", -"36_bf.ig", -"36_bg.ig", -"36_bh.ig", -"36_bi.ig", -"36_bj.ig", -"36_bk.ig", -"36_bl.ig", -"36_bm.ig", -"37_aw.ig", -"37_ax.ig", -"37_ay.ig", -"37_az.ig", -"37_ba.ig", -"37_bb.ig", -"37_bc.ig", -"37_bd.ig", -"37_be.ig", -"37_bf.ig", -"37_bg.ig", -"37_bh.ig", -"37_bi.ig", -"37_bj.ig", -"37_bk.ig", -"37_bl.ig", -"37_bm.ig", -"38_aw.ig", -"38_ax.ig", -"38_ay.ig", -"38_az.ig", -"38_ba.ig", -"38_bb.ig", -"38_bd.ig", -"38_be.ig", -"38_bf.ig", -"38_bg.ig", -"38_bh.ig", -"38_bi.ig", -"38_bj.ig", -"38_bk.ig", -"38_bl.ig", -"38_bm.ig", -"39_aw.ig", -"39_ax.ig", -"39_ay.ig", -"39_az.ig", -"39_ba.ig", -"39_bb.ig", -"39_bf.ig", -"39_bg.ig", -"39_bh.ig", -"39_bi.ig", -"39_bj.ig", -"39_bk.ig", -"39_bl.ig", -"39_bm.ig", -"3_af.ig", -"3_ag.ig", -"3_ah.ig", -"3_ai.ig", -"3_aj.ig", -"3_ak.ig", -"3_bc.ig", -"3_bd.ig", -"3_be.ig", -"40_aw.ig", -"40_ax.ig", -"40_ay.ig", -"40_az.ig", -"40_ba.ig", -"40_bb.ig", -"40_bc.ig", -"40_bf.ig", -"40_bg.ig", -"40_bh.ig", -"40_bi.ig", -"40_bj.ig", -"40_bk.ig", -"40_bl.ig", -"40_bm.ig", -"41_aw.ig", -"41_ax.ig", -"41_ay.ig", -"41_az.ig", -"41_ba.ig", -"41_bb.ig", -"41_bc.ig", -"41_be.ig", -"41_bf.ig", -"41_bg.ig", -"41_bh.ig", -"41_bi.ig", -"41_bj.ig", -"41_bk.ig", -"42_ax.ig", -"42_ay.ig", -"42_az.ig", -"42_ba.ig", -"42_bb.ig", -"42_be.ig", -"42_bf.ig", -"42_bg.ig", -"42_bh.ig", -"42_bi.ig", -"42_bj.ig", -"42_bk.ig", -"43_ax.ig", -"43_ay.ig", -"43_az.ig", -"43_ba.ig", -"43_bb.ig", -"43_be.ig", -"43_bf.ig", -"43_bg.ig", -"43_bh.ig", -"43_bi.ig", -"43_bj.ig", -"43_bk.ig", -"44_bf.ig", -"44_bg.ig", -"44_bh.ig", -"44_bi.ig", -"44_bj.ig", -"44_bk.ig", -"45_bg.ig", -"45_bh.ig", -"45_bi.ig", -"45_bj.ig", -"45_bk.ig", -"46_bh.ig", -"46_bi.ig", -"46_bj.ig", -"46_bk.ig", -"46_bl.ig", -"47_bh.ig", -"47_bi.ig", -"47_bj.ig", -"47_bk.ig", -"47_bl.ig", -"48_bh.ig", -"48_bi.ig", -"48_bj.ig", -"48_bk.ig", -"48_bl.ig", -"49_bh.ig", -"49_bi.ig", -"49_bj.ig", -"4_ac.ig", -"4_ad.ig", -"4_ae.ig", -"4_af.ig", -"4_ag.ig", -"4_ah.ig", -"4_ai.ig", -"4_aj.ig", -"4_ak.ig", -"4_ay.ig", -"4_az.ig", -"4_ba.ig", -"4_bb.ig", -"4_bc.ig", -"4_bd.ig", -"4_be.ig", -"4_bf.ig", -"5_ac.ig", -"5_ad.ig", -"5_ae.ig", -"5_af.ig", -"5_ag.ig", -"5_ah.ig", -"5_ai.ig", -"5_aj.ig", -"5_ak.ig", -"5_al.ig", -"5_ay.ig", -"5_az.ig", -"5_ba.ig", -"5_bb.ig", -"5_bc.ig", -"5_bd.ig", -"5_be.ig", -"5_bf.ig", -"5_bg.ig", -"6_ac.ig", -"6_ad.ig", -"6_ae.ig", -"6_af.ig", -"6_ag.ig", -"6_ah.ig", -"6_ai.ig", -"6_aj.ig", -"6_ak.ig", -"6_al.ig", -"6_ay.ig", -"6_az.ig", -"6_ba.ig", -"6_bb.ig", -"6_bc.ig", -"6_bd.ig", -"6_be.ig", -"6_bf.ig", -"6_bg.ig", -"7_ac.ig", -"7_ad.ig", -"7_ae.ig", -"7_af.ig", -"7_ag.ig", -"7_ah.ig", -"7_ai.ig", -"7_aj.ig", -"7_ak.ig", -"7_al.ig", -"7_ay.ig", -"7_az.ig", -"7_ba.ig", -"7_bb.ig", -"7_bc.ig", -"7_bd.ig", -"7_be.ig", -"7_bf.ig", -"7_bg.ig", -"8_af.ig", -"8_ag.ig", -"8_ah.ig", -"8_ai.ig", -"8_aj.ig", -"8_ak.ig", -"8_ax.ig", -"8_ay.ig", -"8_az.ig", -"8_ba.ig", -"8_bb.ig", -"8_bc.ig", -"8_bd.ig", -"8_be.ig", -"9_af.ig", -"9_ag.ig", -"9_ah.ig", -"9_ai.ig", -"9_aj.ig", -"9_ak.ig", -"9_am.ig", -"9_an.ig", -"9_ao.ig", -"9_ap.ig", -"9_aq.ig", -"9_ar.ig", -"9_as.ig", -"9_at.ig", -"9_au.ig", -"9_av.ig", -"9_ax.ig", -"9_ay.ig", -"9_az.ig", -"9_ba.ig", -"9_bb.ig", -"9_bc.ig", -"9_bd.ig", -"9_be.ig" -}; diff --git a/code/ryzom/server/src/ags_test/ig_loader.cpp b/code/ryzom/server/src/ags_test/ig_loader.cpp deleted file mode 100644 index 6766ce8cb..000000000 --- a/code/ryzom/server/src/ags_test/ig_loader.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "nel/misc/common.h" -#include - -#include "ig_loader.h" -#include "ig_list.h" - -using namespace NL3D; -using namespace NLMISC; -using namespace std; - -void CIGLoader::load() -{ - for (int i=sizeof(IGFiles)/sizeof(IGFiles[0]);i--;) - { - try - { - uint k; - CInstanceGroup ig; - CIFile inputStream; - if (!inputStream.open(IGFiles[i])) - { - nlinfo("unable to open %s", argv[1]); - return -1; - } - ig.serial(inputStream); - CVector gpos = ig.getGlobalPos(); // the origin for the ig - for(k = 0; k < ig._InstancesInfos.size(); ++k) - { - nlinfo("instance %s : x = %.1f, y = %.1f, z = %.1f, sx = %.1f, sy = %.1f, sz = %.1f", ig._InstancesInfos[k].Name.c_str(), ig._InstancesInfos[k].Pos.x + gpos.x, ig._InstancesInfos[k].Pos.y + gpos.y, ig._InstancesInfos[k].Pos.z + gpos.z, ig._InstancesInfos[k].Scale.x, ig._InstancesInfos[k].Scale.y, ig._InstancesInfos[k].Scale.z); - } - } - catch (std::exception &e) - { - nlinfo(e.what()); - } - } -} diff --git a/code/ryzom/server/src/ags_test/macro_manager.cpp b/code/ryzom/server/src/ags_test/macro_manager.cpp deleted file mode 100644 index 59035c52d..000000000 --- a/code/ryzom/server/src/ags_test/macro_manager.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// Nel Misc -// #include "nel/misc/command.h" -// #include "nel/misc/path.h" - -// Game share -//#include "game_share/sid.h" - -// Local headers -#include "macro_manager.h" - -using namespace NLMISC; -//using namespace NLNET; -using namespace std; - - -namespace AGS_TEST -{ - -//------------------------------------------------------------------------ -// static data for CMacroManager - -std::vector CMacroManager::_macros; -bool CMacroManager::_recording=false; - - -//------------------------------------------------------------------------ -// basic functionality for CMacroManager singleton - -void CMacroManager::init() -{ -} - -void CMacroManager::release() -{ - _macros.clear(); -} - - -//--------------------------------------------------------------------------------- - -// display functions -void CMacroManager::listMacros(NLMISC::CLog *log) -{ - log->displayNL("Macro list:"); - std::vector::iterator it; - for (it=_macros.begin(); it!=_macros.end(); ++it) - { - log->displayNL("\t%s",(*it)._name.c_str()); - } -} - -void CMacroManager::displayMacro(const std::string &name, NLMISC::CLog *log) -{ - std::vector::iterator it; - for (it=_macros.begin(); it!=_macros.end(); ++it) - { - if ((*it)._name==name) - { - log->displayNL("MACRO: %s",name.c_str()); - std::vector::iterator mit; - for(mit=(*it)._commands.begin();mit!=(*it)._commands.end();++mit) - { - std::string hold; - std::vector::iterator ait; - for(ait=(*mit)._args.begin();ait!=(*mit)._args.end();++ait) - hold=hold+std::string(" ")+(*ait); - log->displayNL("\t\t%s",hold.c_str()); - } - } - } -} - -//--------------------------------------------------------------------------------- - -void CMacroManager::recordMacro(const std::string &name) -{ - // if a macro already exists by this name then delete it - std::vector::iterator it; - for (it=_macros.begin(); it!=_macros.end(); ++it) - { - if ((*it)._name==name) - { - _macros.erase(it); - break; - } - } - - // create the new macro record - CMacroManager::CMacro newMacro; - newMacro._name=name; - _macros.push_back(newMacro); - - // setup the recording flag - _recording=true; -} - -void CMacroManager::record(NLMISC::ICommand *command,const std::vector &args) -{ - _macros[_macros.size()-1].record(command,args); -} - - -//--------------------------------------------------------------------------------- - -void CMacroManager::execute(const std::string &name, NLMISC::CLog &log) -{ - std::vector::iterator it; - for (it=_macros.begin(); it!=_macros.end(); ++it) - if ((*it)._name==name) - { - nlinfo("Executing macro: %s",name.c_str()); - (*it).execute(log); - return; - } -} - - -} // end of namespace AGS_TEST diff --git a/code/ryzom/server/src/ags_test/macro_manager.h b/code/ryzom/server/src/ags_test/macro_manager.h deleted file mode 100644 index 3e692634e..000000000 --- a/code/ryzom/server/src/ags_test/macro_manager.h +++ /dev/null @@ -1,99 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef GD_MACRO_MANAGER_H -#define GD_MACRO_MANAGER_H - - -// Nel Misc -#include "nel/misc/types_nl.h" -#include "nel/misc/command.h" - -namespace AGS_TEST -{ - -/** - * Singleton, for managing the macros in a scene - * \author Sadge - * \author Nevrax France - * \date 2002 - */ -class CMacroManager -{ -public: - // initialisation and housekeeping for the singleton - static void init(); - static void release(); - - // methods dealing with macro recording - static void recordMacro(const std::string &name); - static void record(NLMISC::ICommand *command,const std::vector &args); - static void stopRecord() { _recording=false; } - static bool recording() { return _recording; } - - // executing a macro - static void execute(const std::string &name, NLMISC::CLog &log); - - // display functions - static void listMacros(NLMISC::CLog *log = NLMISC::InfoLog); - static void displayMacro(const std::string &name,NLMISC::CLog *log = NLMISC::InfoLog); - -private: - class CMacro - { - public: - std::string _name; - typedef struct - { - NLMISC::ICommand *_command; - std::vector _args; - } TMacroCommand; - std::vector _commands; - - void record(NLMISC::ICommand *command,const std::vector &args) - { - TMacroCommand newCommand; - newCommand._command=command; - newCommand._args=args; - _commands.push_back(newCommand); - } - void execute(NLMISC::CLog &log) - { - std::vector::iterator it; - for(it=_commands.begin();it!=_commands.end();++it) - it->_command->execute(it->_args, log, true); - } - }; - - // forbid instantiation - CMacroManager(); - static std::vector _macros; - static bool _recording; - -}; - - -#define COMMAND_MACRO_RECORD_TEST\ - if (CMacroManager::recording()) {CMacroManager::record(this,args); return true;} - - -} // end of namespace AGS_TEST - -#endif // GD_MACRO_MANAGER_H -/* End of macro_manager.h */ diff --git a/code/ryzom/server/src/ags_test/messages.cpp b/code/ryzom/server/src/ags_test/messages.cpp deleted file mode 100644 index 59709f786..000000000 --- a/code/ryzom/server/src/ags_test/messages.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// include files -#include "nel/misc/types_nl.h" -#include "nel/misc/vectord.h" -#include "game_share/tick_event_handler.h" - -#include "messages.h" -#include "mirrors.h" -#include "actor_manager.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace AGS_TEST; - - - -//------------------------------------------------------------------------- -// the callback table - -/* -static void cbEngageFight( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); -static void cbUpdateFightBehaviour( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); -static void cbUpdateFightPosition( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); -static void cbUpdateFightEnd( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); -static void cbAckVisionZone( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); -static void cbAIVision( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ); - -TUnifiedCallbackItem CbArray[] = -{ - - { "ENGAGE_FIGHT", cbEngageFight, }, - { "U_FIGHT_BEHAVIOUR", cbUpdateFightBehaviour, }, - { "U_FIGHT_POS", cbUpdateFightPosition, }, - { "U_END_FIGHT", cbUpdateFightEnd, }, - { "U_FIGHT_END", cbUpdateFightEnd, }, - - { "ACK_VISION_ZONE", cbAckVisionZone, }, - { "AGENT_VISION", cbAIVision, }, -}; -*/ - -//------------------------------------------------------------------------- -// singleton initialisation and release - -void CMessages::init() -{ - // setup the callback array - //CUnifiedNetwork::getInstance()->addCallbackArray( CbArray, sizeof(CbArray)/sizeof(CbArray[0]) ); -} - -void CMessages::release() -{ -} - -//-------------------------------------------------------------------------- -// incoming message callbacks - -/* -static void cbEngageFight( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - CEntityId aggressor, target; - msgin.serial(aggressor); - msgin.serial(target); - CActor *actor=CActorManager::getActor(target); - - if (actor) - { - nlinfo("Responding to ENGAGE_FIGHT: %s %s",aggressor.toString().c_str(),target.toString().c_str()); - actor->doFight(aggressor); - } - else - nlinfo("Ignoring ENGAGE_FIGHT: %s %s",aggressor.toString().c_str(),target.toString().c_str()); - -} - -static void cbUpdateFightBehaviour( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - nlinfo("Received U_FIGHT_BEHAVIOUR - ** Message not treated **"); -} - - -static void cbUpdateFightPosition( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - // forwarding position updates from CMS to GPMS -// nlinfo("Received U_FIGHT_POS: length=%i pos=%i",msgin.length(),msgin.getPos() ); - - // this vector contais the body of the output messsage - - CMessage msgout("UPDATE_ENTITIES_POS"); - CMessage msgoutCMS("U_FIGHT_POS"); - bool CMSChanges=false; - bool GPMSChanges=false; - - // parse the input message - TGameCycle cycle = CTickEventHandler::getGameCycle(); - while (msgin.length()>(unsigned)msgin.getPos()) - { - CEntityId id; - CVectorD pos; - float theta; - msgin.serial(id,pos, theta); - - // make sure that the actor is one of ours and doesn't belong to another service - CActor *pactor = CActorManager::getActor(id); - if (pactor!=0) - { - // check pos - if (pactor->testPositionInPatat(pos)) - { - sint32 x=(sint32)(pos.x*1000.0); - sint32 y=(sint32)(pos.y*1000.0); - sint32 z=(sint32)(pos.z*1000.0); - //float angle=pactor->getAngle(); - - msgout.serial(id,x,y,z,theta,cycle); - GPMSChanges=true; - } - else - { - pos=CVectorD(CMirrors::x(id),CMirrors::y(id),CMirrors::z(id)); - sint32 x = CMirrors::x(id); - sint32 y = CMirrors::y(id); - sint32 z = CMirrors::z(id); - float angle=pactor->getAngle(); - - msgoutCMS.serial(id,x,y,z,angle,cycle); - CMSChanges=true; - } - } - - } - - // create and send the output message - if (GPMSChanges) sendMessageViaMirror( "GPMS", msgout ); - if (CMSChanges) sendMessageViaMirror( "CMS", msgoutCMS ); -} - - -static void cbUpdateFightEnd( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - // dealing with end of fight -// nlinfo("Received U_FIGHT_END: length=%i pos=%i",msgin.length(),msgin.getPos() ); - - while (msgin.length()>(unsigned)msgin.getPos()) - { - // get actor id - CEntityId id; - msgin.serial(id); - - // set actor to wandering mode - CActor *actor = CActorManager::getActor(id); - if (actor) - { - nlinfo("Received U_FIGHT_END for actor: %s (%s)",id.toString().c_str(), actor->getName().c_str()); - actor->resetActivity(); - // at combat end, recover position from mirror (get the last fight position) - actor->setPos(CMirrors::x(actor->getSid()), CMirrors::y(actor->getSid()), CMirrors::z(actor->getSid())); -// actor->doWander(); - } - else - { - nlinfo("Received U_FIGHT_END for unknown actor: %s",id.toString().c_str()); - } - } -} - - - -// -static void cbAIVision( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - CMoveManager::processAIVision(msgin); -} - -// -static void cbAckVisionZone( NLNET::CMessage& msgin, const std::string &serviceName, uint16 serviceId ) -{ - CActorManager::addVisionService(serviceId); -} -*/ diff --git a/code/ryzom/server/src/ags_test/messages.h b/code/ryzom/server/src/ags_test/messages.h deleted file mode 100644 index 4cd95af91..000000000 --- a/code/ryzom/server/src/ags_test/messages.h +++ /dev/null @@ -1,36 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RY_AGST_MESSAGES_H -#define RY_AGST_MESSAGES_H - -#include "game_share/msg_brick_service.h" - -class CMessages -{ -public: - // singleton initialisation and release - static void init(); - static void release(); - -private: -}; - - -#endif // RY_AGST_MESSAGES_H - diff --git a/code/ryzom/server/src/ags_test/mirrors.cpp b/code/ryzom/server/src/ags_test/mirrors.cpp deleted file mode 100644 index 2ba60c888..000000000 --- a/code/ryzom/server/src/ags_test/mirrors.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "mirrors.h" -#include -#include "game_share/ryzom_entity_id.h" -//#include - -using namespace std; -using namespace NLMISC; -using namespace NLNET; -using namespace MBEHAV; - -//static inits -CMirror CMirrors::Mirror; -CMirroredDataSet *CMirrors::DataSet = NULL; - - -/* - * Initialisation 2 - */ -void cbMirrorIsReady( CMirror *mirror ) -{ - CMirrors::initMirror(); -} - - -/* - * Initialisation 1 - */ -void CMirrors::init( void (*cbUpdate)(), void (*cbSync)(), void (*cbRelease)() ) -{ - // Init the mirror system - vector datasetNames; - datasetNames.push_back( "fe_temp" ); - Mirror.init( datasetNames, cbMirrorIsReady, cbUpdate, cbSync, cbRelease ); - - // register the service up and service down callbacks - CUnifiedNetwork::getInstance()->setServiceUpCallback("*", cbServiceUp, 0); - CUnifiedNetwork::getInstance()->setServiceDownCallback( "*", cbServiceDown, 0); -} - - -/* - * Init after the mirror init - */ -void CMirrors::initMirror() -{ - Mirror.declareEntityTypeOwner( RYZOMID::npc, 10000 ); - Mirror.declareEntityTypeOwner( RYZOMID::creature, 10000 ); - - DataSet = &(Mirror.getDataSet("fe_temp")); - DataSet->declareProperty( "X", PSOReadWrite ); - DataSet->declareProperty( "Y", PSOReadWrite ); - DataSet->declareProperty( "Z", PSOReadWrite ); - DataSet->declareProperty( "Theta", PSOReadWrite ); - DataSet->declareProperty( "Sheet", PSOReadWrite ); // read/write - DataSet->declareProperty( "Mode", PSOReadWrite ); - DataSet->declareProperty( "Behaviour", PSOReadOnly ); - DataSet->declareProperty( "VisualPropertyA", PSOReadWrite ); - DataSet->declareProperty( "WhoSeesMe", PSOReadWrite ); - DataSet->declareProperty( "RiderEntity", PSOReadOnly ); - DataSet->declareProperty( "TargetList", PSOReadWrite ); - - Mirror.setNotificationCallback( CMirrors::processMirrorUpdates ); - - // Note: here we don't call initRyzomVisualPropertyIndices(), so we won't be able to used the - // DSProperty* "constants" in this service -} - - -void CMirrors::processMirrorUpdates() -{ - DataSet->processAddedEntities(); - DataSet->processRemovedEntities(); -} - - -void CMirrors::release() -{ - // Calling the destructor explicitely, not waiting for the end - Mirror.release(); -} - -void CMirrors::cbServiceUp( const std::string& serviceName, uint16 serviceId, void * ) -{ -} - -void CMirrors::cbServiceDown( const std::string& serviceName, uint16 serviceId, void * ) -{ -} - - - -/* - * Test of CMirrorPropValueList - */ -/*NLMISC_COMMAND( testMirrorList, "", "" ) -{ - CEntityId id = CEntityId( RYZOMID::npc, 99987, 0x82, 0x85 ); - CMirrors::Mirror.addEntity( id, true ); - TDataSetRow datasetRow = TheDataset.getDataSetRow( id ); - CMirrorPropValueList list( TheDataset, id, "TargetList" ); - log.displayNL( "SIZE %u", list.size() ); - list.resize( 2 ); - log.displayNL( "SIZE %u", list.size() ); - list.push_front( datasetRow ); - CMirrorPropValueList::iterator it; - log.displayNL( "SIZE %u", list.size() ); - for ( it=list.begin(); it!=list.end(); ++it ) - log.displayNL( "%u", (*it)().getIndex() ); - list.resize( 2 ); - log.displayNL( "SIZE %u", list.size() ); - for ( it=list.begin(); it!=list.end(); ++it ) - log.displayNL( "%u", (*it)().getIndex() ); - list.push_front( datasetRow ); - log.displayNL( "SIZE %u", list.size() ); - list.resize( 4 ); - log.displayNL( "SIZE %u", list.size() ); - for ( it=list.begin(); it!=list.end(); ++it ) - log.displayNL( "%u", (*it)().getIndex() ); - return true; -}*/ diff --git a/code/ryzom/server/src/ags_test/mirrors.h b/code/ryzom/server/src/ags_test/mirrors.h deleted file mode 100644 index cf2296f0d..000000000 --- a/code/ryzom/server/src/ags_test/mirrors.h +++ /dev/null @@ -1,65 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RY_CMS_MIRRORS_H -#define RY_CMS_MIRRORS_H - -// include files -#include "nel/misc/types_nl.h" -#include "nel/misc/entity_id.h" -#include "nel/misc/sheet_id.h" -#include "game_share/mode_and_behaviour.h" -#include "game_share/mirror.h" -#include "game_share/mirror_prop_value.h" - -class CMirrors -{ -public: - // singleton initialisation and release - static void init( void (*cbUpdate)(), void (*cbSync)()=NULL, void (*cbRelease)() = NULL ); - static void initMirror(); - static void processMirrorUpdates(); - static void release(); - - static bool exists( const NLMISC::CEntityId& id ) { return (DataSet->getDataSetRow( id ).isValid()); } - - static sint32 x( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "X" ); return (sint32)value(); } - static sint32 y( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "Y" ); return (sint32)value(); } - static sint32 z( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "Z" ); return (sint32)value(); } - static sint32 mode( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "Mode" ); return (sint32)(MBEHAV::TMode(value()).Mode); } - static sint32 behaviour( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "Behaviour" ); return (uint32)value(); } - - static void initSheet( const NLMISC::CEntityId& id, const NLMISC::CSheetId& sheetId ) { CMirrorPropValue value( *DataSet, id, "Sheet" ); value = sheetId.asInt(); } - static NLMISC::CSheetId sheet( const NLMISC::CEntityId& id ) { CMirrorPropValueRO value( *DataSet, id, "Sheet" ); return NLMISC::CSheetId(value()); } - -private: - // callbacks used at service connection and disconnection - static void cbServiceUp( const std::string& serviceName, uint16 serviceId, void * ); - static void cbServiceDown( const std::string& serviceName, uint16 serviceId, void * ); - -public: - static CMirror Mirror; - static CMirroredDataSet *DataSet; -}; - - -#define TheDataset (*CMirrors::DataSet) - - -#endif // RY_CMS_MIRRORS_H - diff --git a/code/ryzom/server/src/ags_test/move_grid.h b/code/ryzom/server/src/ags_test/move_grid.h deleted file mode 100644 index 70790e091..000000000 --- a/code/ryzom/server/src/ags_test/move_grid.h +++ /dev/null @@ -1,444 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef NL_MOVE_GRID_H -#define NL_MOVE_GRID_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/vector.h" -#include "nel/misc/aabbox.h" -#include "nel/misc/block_memory.h" - - /** - * A list of object that must have Next and Previous pointers - * \param T the type of item - * \param TPtr a pointer to T to use in list (useful for smartpointer) - */ - template - class CMoveGridObjectList - { - public: - TPtr Head; - TPtr Tail; - - CMoveGridObjectList() : Head(NULL), Tail(NULL) {} - - void insertAtHead(TT *object) - { - nlassert(object->Next == NULL); - nlassert(object->Previous == NULL); - - object->Next = Head; - if (object->Next != NULL) - object->Next->Previous = object; - Head = object; - } - - void insertAtTail(TT *object) - { - nlassert(object->Next == NULL); - nlassert(object->Previous == NULL); - - object->Previous = Tail; - if (object->Previous != NULL) - object->Previous->Next = object; - Tail = object; - } - - void remove(TT *object) - { - // if object at head - if (object->Previous == NULL) - Head = object->Next; - else - object->Previous->Next = object->Next; - - // if object at tail - if (object->Next == NULL) - Tail = object->Previous; - else - object->Next->Previous = object->Previous; - - object->Previous = NULL; - object->Next = NULL; - } - - TT *getHead() { return (TT*)Head; } - TT *getTail() { return (TT*)Tail; } - }; - -/** - * Move grid, allows to select moving entities fast (template parameter CSIZE is in millimeter) - * \author Benjamin Legros - * \author Nevrax France - * \date 2001 - */ -template -class CMoveGrid -{ -public: - class CIterator; - friend class CIterator; - -protected: - class CCellNode; - class CNode; - -public: - - /// Constructor - CMoveGrid(); - - /// Destructor - ~CMoveGrid(); - - - /// Insert an element in move grid. Return an iterator towards the inserted object - CIterator insert(const T &object, const NLMISC::CVector &position); - - - /// Move an object in grid. - void move(CIterator &it, const NLMISC::CVector &position); - - - /// Remove - void remove(CIterator &it); - void insertNode(CIterator &it, sint x, sint y); - void removeNode(CIterator &it); - - - /// select - void select(const NLMISC::CVector &position); - - /// select - void select(const NLMISC::CAABBox &bbox); - - /// begin - CIterator begin(); - - /// end - CIterator end(); - - /// clearSelection - void clearSelection(); - - /// round value so it is a half of a segment - double round(double v) - { - const double INV = 1000.0 / (double)CSIZE; - return (floor(v*INV)+0.5)*(double)CSIZE*0.001; - } - -protected: - sint convert(float v) - { - const float INV = 1000.0f / (float)CSIZE; - return (sint)(v*INV); - } - - sint convertGrid(float v) - { - const float INV = 1000.0f / (float)CSIZE; - return (sint)(v*INV)&(CELLS-1); - } - - sint convertGrid(sint v) - { - return v&(CELLS-1); - } - - void select(sint X, sint Y); - - -protected: - - /// A node that contains an objects. - typedef CMoveGridObjectList TNodeList; - /// A node that is a cell, containing a list of node inside this cell. - typedef CMoveGridObjectList TCellNodeList; - - class CCellNode - { - public: - sint X, Y; - sint GridX, GridY; - - TNodeList NodeList; - - CCellNode *Previous, *Next; - CCellNode *Selection; - - CCellNode() : X(0), Y(0), GridX(0), GridY(0), Previous(NULL), Next(NULL), Selection(NULL) {} - }; - - class CNode - { - public: - CCellNode *Root; - CNode *Previous, *Next; - T Object; - - CNode() : Previous(NULL), Next(NULL), Root(NULL) {} - }; - - /// The map of cell nodes - TCellNodeList _Grid[CELLS][CELLS]; - - /// The first selected cell node - CCellNode *_Selection; - - /// The allocator of nodes - NLMISC::CBlockMemory _NodeAllocator; - /// The allocator of cell nodes - NLMISC::CBlockMemory _CellNodeAllocator; - -public: - class CIterator - { - friend class CMoveGrid; - public: - CIterator(CNode *node = NULL) : _Node(node) {} - CIterator(const CIterator &it) : _Node(it._Node) {} - - T & operator * () { return _Node->Object; } - - CIterator & operator ++ () - { - if (_Node->Next != NULL) - { - _Node = _Node->Next; - } - else - { - CCellNode *nextCell = _Node->Root->Selection; - _Node = NULL; - // iterate till we have a non empty selected cell - while (nextCell != NULL && (_Node = nextCell->NodeList.getHead()) == NULL) - nextCell = nextCell->Selection; - } - return *this; - } - CIterator operator ++ (int) - { - CIterator ret(_Node); - ++(*this); - return ret; - } - - bool operator == (const CIterator &it) const { return it._Node == _Node; } - bool operator != (const CIterator &it) const { return !(*this == it); } - - CIterator operator = (const CIterator &it) { _Node = it._Node; return *this; } - - protected: - CNode *_Node; - }; -}; - - -// -// TEMPLATE IMPLEMENTATION -// - - -// -template -CMoveGrid::CMoveGrid() -{ - _Selection = NULL; -} - - -// -template -CMoveGrid::~CMoveGrid() -{ - sint i, j; - - for (i=0; iNodeList.getHead()) != NULL) - { - cellNode->NodeList.remove(node); - _NodeAllocator.freeBlock(node); - } - list.remove(cellNode); - _CellNodeAllocator.freeBlock(cellNode); - } - } - } -} - -// -template -void CMoveGrid::insertNode(CIterator &it, sint x, sint y) -{ - sint gridX, gridY; - gridX = convertGrid(x); - gridY = convertGrid(y); - - CCellNode *cellNode = _Grid[gridX][gridY].getHead(); - while (cellNode != NULL && (cellNode->X != x || cellNode->Y != y)) - cellNode = cellNode->Next; - - if (cellNode == NULL) - { - cellNode = _CellNodeAllocator.allocate(); - _Grid[gridX][gridY].insertAtHead(cellNode); - cellNode->X = x; - cellNode->Y = y; - cellNode->GridX = gridX; - cellNode->GridY = gridY; - } - - it._Node->Root = cellNode; - cellNode->NodeList.insertAtHead(it._Node); -} - -// -template -void CMoveGrid::removeNode(CIterator &it) -{ - it._Node->Root->NodeList.remove(it._Node); -} - -// -template -typename CMoveGrid::CIterator CMoveGrid::insert(const T &object, const NLMISC::CVector &position) -{ - CNode *node = _NodeAllocator.allocate(); - - sint X, Y; - - X = convert(position.x); - Y = convert(position.y); - node->Object = object; - - CIterator it(node); - insertNode(it, X, Y); - - return CIterator(node); -} - -template -void CMoveGrid::move(CIterator &it, const NLMISC::CVector &position) -{ - sint X, Y; - X = convert(position.x); - Y = convert(position.y); - - CNode *node = it._Node; - - if (X == node->Root->X && Y == node->Root->Y) - return; - - removeNode(it); - insertNode(it, X, Y); -} - -template -void CMoveGrid::remove(CIterator &it) -{ - CNode *node = it._Node; - - removeNode(it); - it._Node = NULL; - - _NodeAllocator.free(node); -} - - -template -void CMoveGrid::select(const NLMISC::CVector &position) -{ - select(convert(position.x), convert(position.y)); -} - -template -void CMoveGrid::select(const NLMISC::CAABBox &bbox) -{ - sint x0, x1; - sint y0, y1; - - x0 = convert(bbox.getCenter().x-bbox.getHalfSize().x); - x1 = convert(bbox.getCenter().x+bbox.getHalfSize().x); - - y0 = convert(bbox.getCenter().y-bbox.getHalfSize().y); - y1 = convert(bbox.getCenter().y+bbox.getHalfSize().y); - - sint x, y; - - for (y=y0; y<=y1; ++y) - for (x=x0; x<=x1; ++x) - select(x, y); -} - -template -void CMoveGrid::select(sint x, sint y) -{ - sint gx = convertGrid(x), - gy = convertGrid(y); - - CCellNode *cellNode = _Grid[gx][gy].getHead(); - while (cellNode != NULL && (cellNode->X != x || cellNode->Y != y)) - cellNode = cellNode->Next; - - if (cellNode != NULL && cellNode->NodeList.getHead() != NULL) - { - cellNode->Selection = _Selection; - _Selection = cellNode; - } -} - -template -typename CMoveGrid::CIterator CMoveGrid::begin() -{ - return (_Selection != NULL) ? CIterator(_Selection->NodeList.getHead()) : CIterator(NULL); -} - -template -typename CMoveGrid::CIterator CMoveGrid::end() -{ - return CIterator(NULL); -} - -template -void CMoveGrid::clearSelection() -{ - CCellNode *cellNode = _Selection; - _Selection = NULL; - - while (cellNode != NULL) - { - CCellNode *nd = cellNode; - cellNode = cellNode->Selection; - nd->Selection = NULL; - } -} - - -#endif // NL_MOVE_GRID_H - -/* End of move_grid.h */ diff --git a/code/ryzom/server/src/ags_test/move_manager.cpp b/code/ryzom/server/src/ags_test/move_manager.cpp deleted file mode 100644 index 9e43fe034..000000000 --- a/code/ryzom/server/src/ags_test/move_manager.cpp +++ /dev/null @@ -1,220 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "move_manager.h" -#include "nel/misc/config_file.h" -#include "nel/net/service.h" -#include "sheets.h" - -#include "nel/misc/file.h" -#include "nel/misc/path.h" -#include "game_share/ryzom_entity_id.h" - -// -//#include "nel/3d/u_instance_group.h" - -#include "sheets.h" - -// ugly -#include "game_share/ig_list.h" -#include "game_share/used_continent.h" - -using namespace std; -using namespace NLMISC; -using namespace NLPACS; -using namespace NLNET; - -namespace AGS_TEST -{ - -// the actor grid -CMoveManager::TObstacleGrid CMoveManager::Grid; - -// the continents -CContinentContainer CMoveManager::Continents; - -// -CMoveManager::TObstacleMap CMoveManager::ObstacleMap; - -// -CMoveManager::TPrimZoneMap CMoveManager::PrimZoneMap; - - -// init -void CMoveManager::init() -{ - // init continents - Continents.init(30, 30, 8.0, 2, IService::getInstance()->WriteFilesDirectory); - - // load continents - CUsedContinent::TUsedContinentCont usedCont = CUsedContinent::instance().getContinents(); - - for (uint i=0; isetAsStatic(0); - } -/* CConfigFile::CVar& cvUsedContinents = IService::getInstance()->ConfigFile.getVar("UsedContinents"); - uint i; - for (i=0; (sint)isetAsStatic(0); - } -*/ -/* - // load trees ig - for (i=sizeof(IGFiles)/sizeof(IGFiles[0]);i--;) - { - try - { - NL3D::UInstanceGroup *ig = NL3D::UInstanceGroup::createInstanceGroup(IGFiles[i]); - if (ig == NULL) - continue; - - uint k; - for(k = 0; k < ig->getNumInstance(); ++k) - { - const string &name = ig->getShapeName(k); - sint sz = name.size(); - if (sz >= 6 && strlwr(name.substr(sz-6, 6)) == ".shape") - { - const CSheets::CSheet *sheet = CSheets::lookup(CSheetId(ig->getInstanceName(k))); - CObstacle obstacle; - obstacle.Id = CEntityId(RYZOMID::flora, 0xDEADF00D, IService::getInstance()->getServiceId(), IService::getInstance()->getServiceId()); - obstacle.Position = ig->getInstancePos(k); - obstacle.Radius = (sheet != NULL) ? sheet->Radius : 0.5f; - Grid.insert(obstacle, obstacle.Position); - } - } - - delete ig; - } - catch (std::exception &e) - { - nlinfo(e.what()); - } - } -*/ -} - -// update -void CMoveManager::update() -{ - uint i; - for (i=0; (sint)ievalCollision(1, 0); - Continents.getMoveContainer(i)->evalCollision(1, 1); - } -} - - -// process ai vision -void CMoveManager::processAIVision(CMessage &msg) -{ - TObstacleMap::iterator it; - for (it=ObstacleMap.begin(); it!=ObstacleMap.end(); ++it) - (*((*it).second)).Updated = false; - - uint64 AgentId; // should be fakeid... - msg.serial( AgentId ); - - while (msg.getPos() < (sint32)(msg.length())) - { - CEntityId id; - TTime time; - CVectorD pos; - CVector heading; - float speed; - string sheetId; - - // get all from message - msg.serial(id, time, pos, heading, speed, sheetId); - - it = ObstacleMap.find(id); - if (it == ObstacleMap.end()) - { - // if not exists yet, creates an obstacle - CObstacle obstacle; - obstacle.Id = id; - obstacle.Position = CVector(pos); - obstacle.Radius = 0.5f; - obstacle.External = true; - - // get sheet from this sheetId - const CSheets::CSheet *sheet = CSheets::lookup(CSheetId(sheetId)); - if (sheet != NULL) - obstacle.Radius = sheet->Radius; - - // - nlinfo("New Object %s in IA vision at (%.1f,%.1f,%.1f), radius %.1f", id.toString().c_str(), pos.x, pos.y, pos.z, obstacle.Radius); - - // insert in grid - TObstacleGrid::CIterator ito = Grid.insert(obstacle, obstacle.Position); - - // insert in map - pair res = ObstacleMap.insert(make_pair(id, ito)); -/* - it = ObstacleMap.find(id); - nlassert(it != ObstacleMap.end()); -*/ - it = res.first; - } - else - { - (*((*it).second)).Position = pos; - Grid.move((*it).second, pos); - } - - (*((*it).second)).Updated = true; - } - - // erase not updated obstacles - for (it=ObstacleMap.begin(); it!=ObstacleMap.end(); ) - { - if (!(*((*it).second)).Updated && (*((*it).second)).External) - { - nlinfo("Remove old object %s in IA vision", (*it).first.toString().c_str()); - TObstacleMap::iterator itr = it++; - Grid.remove((*itr).second); - ObstacleMap.erase(itr); - } - else - { - ++it; - } - } -} - -// release -void CMoveManager::release() -{ - // remove all continents - uint i; - for (i=0; (sint)i -// 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 . - - - -#ifndef NL_MOVE_MANAGER_H -#define NL_MOVE_MANAGER_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/vector.h" -#include "nel/net/message.h" -#include "nel/misc/entity_id.h" - -#include "nel/ligo/primitive.h" - -#include "move_grid.h" -#include "game_share/continent_container.h" - -#include - -namespace AGS_TEST -{ - -class CObstacle -{ -public: - CObstacle() : External(false), Updated(true) {} - NLMISC::CEntityId Id; - NLMISC::CVector Position; - float Radius; - bool External; - bool Updated; -}; - - /** - * Manager of a unique move grid - * \author Benjamin Legros - * \author Nevrax France - * \date 2002 - */ -class CMoveManager -{ -public: - /// The type of grid - typedef CMoveGrid TObstacleGrid; - - /// A map of obstacle - typedef std::map TObstacleMap; - - /// A map of prim zone - typedef std::map TPrimZoneMap; - -public: - /// The grid - static TObstacleGrid Grid; - - /// The continent container - static CContinentContainer Continents; - - /// The obstacle map - static TObstacleMap ObstacleMap; - - /// The prim zone map - static TPrimZoneMap PrimZoneMap; - -public: - - /// init - static void init(); - - /// update - static void update(); - - /// process ia vision from gpms - static void processAIVision(NLNET::CMessage &msg); - - /// release - static void release(); - - /// Add a prim zone in map - static void addPrimZone(const NLLIGO::CPrimZone &primZone) - { - if (PrimZoneMap.find(primZone.getName()) == PrimZoneMap.end()) - { - PrimZoneMap.insert(std::make_pair(primZone.getName(), primZone)); - nlinfo("Using PrimZone '%s'", primZone.getName().c_str()); - } - else - { - nlwarning("PrimZone '%s' already added, abort...", primZone.getName().c_str()); - } - } - - /// get a prim zone by its name - static NLLIGO::CPrimZone *getPrimZone(const std::string &zoneName) - { - TPrimZoneMap::iterator it = PrimZoneMap.find(zoneName); - if (it == PrimZoneMap.end()) - { - nlwarning("Couldn't find PrimZone '%s', abort...", zoneName.c_str()); - return NULL; - } - return &((*it).second); - } - - -public: -}; - -} // AGS_TEST - -#endif // NL_MOVE_MANAGER_H - -/* End of move_manager.h */ diff --git a/code/ryzom/server/src/ags_test/notes.txt b/code/ryzom/server/src/ags_test/notes.txt deleted file mode 100644 index f9e50fb3e..000000000 --- a/code/ryzom/server/src/ags_test/notes.txt +++ /dev/null @@ -1,120 +0,0 @@ -Alain's code - -/****************************************************************\ - **************************************************************** - Alain's Command section - **************************************************************** -\****************************************************************/ - -// Command for add an entity on the GPMS -NLMISC_COMMAND(add_entity,"Add entity to GPMS","entity Id, sheet Id, entity PosX(meters), entity PosY, entity PosZ, entity Theta angle") -{ - // check args, if there s not the right number of parameter, return bad - if(args.size() != 6) return false; - - // get the values - uint32 Id = atoi(args[0].c_str()); - uint32 SheetId = atoi(args[1].c_str()); - sint32 PosX = atoi(args[2].c_str()) * 1000; //coordinates are in millimeters - uint32 PosY = atoi(args[3].c_str()) * 1000; - sint32 PosZ = atoi(args[4].c_str()) * 1000; - float Theta = (float) atof(args[5].c_str()); //direction of entity in radian (direct angle in radian, front of is on +Y (0 = Y direction), all conversion is now made on client) - - //normaly creature type, but FE not ready for properties of creature type, this constructor set dynamicId and creatorId to serviceId - // At this time they are no namespace for enum of entity type, this be corrected when i'm change Sid/EntityId class and move it in game_share - Sid sid( /*Sid::*/npc, Id); - - //make the message for add entity and send it - CMessage msgout("ADD_ENTITY"); - msgout.serial( sid ); - msgout.serial( PosX ); - msgout.serial( PosY ); - msgout.serial( PosZ ); - msgout.serial( Theta ); - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle(); - //msgout.serial( tick ); //Chaine of time is not complete, must be made in shortly - msgout.serial( SheetId ); - CUnifiedNetwork::getInstance()->send( "GPMS", msgout ); - - return true; -} - -// Command for remove an entity on the GPMS -NLMISC_COMMAND(remove_entity,"Remove entity to GPMS","entity Id") -{ - // check args, if there s not the right number of parameter, return bad - if(args.size() != 1) return false; - - // get the values - uint32 Id = atoi(args[0].c_str()); - - //normaly creature type, but FE not ready for properties of creature type, this constructor set dynamicId and creatorId to serviceId - // At this time they are no namespace for enum of entity type, this be corrected when i'm change Sid/EntityId class and move it in game_share - Sid sid( /*Sid::*/npc, Id); - - CMessage msgout("REMOVE_ENTITY"); - msgout.serial( sid ); - CUnifiedNetwork::getInstance()->send( "GPMS", msgout ); - - return true; -} - -// Command for update position of an entity, remember pacs constraintes reduce the max move in one ticks at two cells (2*16 meters) -NLMISC_COMMAND(update_position,"Update position of an entity","entity Id, entity PosX(meters), entity PosY, entity PosZ, entity Theta angle") -{ - // check args, if there s not the right number of parameter, return bad - if(args.size() != 5) return false; - - // get the values - uint32 Id = atoi(args[0].c_str()); - sint32 PosX = atoi(args[1].c_str()) * 1000; //coordinates are in millimeters - uint32 PosY = atoi(args[2].c_str()) * 1000; - sint32 PosZ = atoi(args[3].c_str()) * 1000; - float Theta = (float) atof(args[4].c_str()); //direction of entity in radian (direct angle in radian, front of is on +Y (0 = Y direction), all conversion is now made on client) - - //normaly creature type, but FE not ready for properties of creature type, this constructor set dynamicId and creatorId to serviceId - // At this time they are no namespace for enum of entity type, this be corrected when i'm change Sid/EntityId class and move it in game_share - Sid sid( /*Sid::*/npc, Id); - - CMessage msgout("UPDATE_ENTITY_POS"); - msgout.serial( sid ); - msgout.serial( PosX ); - msgout.serial( PosY ); - msgout.serial( PosZ ); - msgout.serial( Theta ); - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle(); - msgout.serial( tick ); - CUnifiedNetwork::getInstance()->send( "GPMS", msgout ); - - return true; -} - -// Command for teleport an entity to new position, no limit of distance to move -NLMISC_COMMAND(teleportation,"Teleport entity to gived position","entity Id, entity PosX(meters), entity PosY, entity PosZ, entity Theta angle") -{ - // check args, if there s not the right number of parameter, return bad - if(args.size() != 5) return false; - - // get the values - uint32 Id = atoi(args[0].c_str()); - sint32 PosX = atoi(args[1].c_str()) * 1000; //coordinates are in millimeters - uint32 PosY = atoi(args[2].c_str()) * 1000; - sint32 PosZ = atoi(args[3].c_str()) * 1000; - float Theta = (float) atof(args[4].c_str()); //direction of entity in radian (direct angle in radian, front of is on +Y (0 = Y direction), all conversion is now made on client) - - //normaly creature type, but FE not ready for properties of creature type, this constructor set dynamicId and creatorId to serviceId - // At this time they are no namespace for enum of entity type, this be corrected when i'm change Sid/EntityId class and move it in game_share - Sid sid( /*Sid::*/npc, Id); - - CMessage msgout("ENTITY_TELEPORTATION"); - msgout.serial( sid ); - msgout.serial( PosX ); - msgout.serial( PosY ); - msgout.serial( PosZ ); - msgout.serial( Theta ); - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle(); - msgout.serial( tick ); - CUnifiedNetwork::getInstance()->send( "GPMS", msgout ); - - return true; -} diff --git a/code/ryzom/server/src/ags_test/position_generator.cpp b/code/ryzom/server/src/ags_test/position_generator.cpp deleted file mode 100644 index 2e2e89b06..000000000 --- a/code/ryzom/server/src/ags_test/position_generator.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#include "position_generator.h" -#include - -namespace AGS_TEST -{ - -// instantiating static class variables -int CPositionGenerator::_x=0; -int CPositionGenerator::_y=0; -int CPositionGenerator::_dx=0; -int CPositionGenerator::_dy=0; -int CPositionGenerator::_spacing=0; -std::string CPositionGenerator::_pattern("grid"); -int CPositionGenerator::_linelen=0; -int CPositionGenerator::_leftonline=0; -std::string CPositionGenerator::_spawnZoneName=""; -CPositionGenerator::TSpawnZoneMap CPositionGenerator::_spawnZones; -CPositionGenerator::TSpawnPointMap CPositionGenerator::_spawnPoints; - - -void CPositionGenerator::setPositionInMM(int x, int y) -{ - _x=x; - _y=y; - - _linelen=0; - _leftonline=0; - init(); - - nlinfo("Set spawn position to: %d, %d", (_x+500)/1000, (_y+500)/1000); -} - -void CPositionGenerator::setPosition(int x, int y) -{ - setPositionInMM(1000*x,1000*y); -} - - -void CPositionGenerator::setPosition(std::string spawnName) // name of a spawn point or spawn zone -{ - if (_spawnPoints.find(spawnName)!=_spawnPoints.end()) - { - setPositionInMM( (int)(_spawnPoints[spawnName].Point.x*1000.0f), (int)(_spawnPoints[spawnName].Point.y*1000.0f) ); - } - else if (_spawnZones.find(spawnName)!=_spawnZones.end()) - { - _spawnZoneName=spawnName; - setPattern("spawnZone"); - NLMISC::CVector v=_spawnZones[_spawnZoneName].getNext(); - setPositionInMM((int)(v.x*1000.0f),(int)(v.y*1000.0f)); - - nlinfo("Set spawn Zone to: %s",_spawnZoneName.c_str()); - } - else - { - nlinfo("Unknown spawn zone/point: %s",spawnName.c_str()); - } -} - -void CPositionGenerator::setSpacing(int spacing) -{ - _spacing=1000*spacing; - init(); -} - -void CPositionGenerator::setPattern(const std::string &pattern) -{ - _pattern=pattern; - init(); -} - -void CPositionGenerator::init() -{ - _dx=_spacing; - _dy=0; - - _linelen=0; - _leftonline=0; -} - -void CPositionGenerator::next(int &x, int &y) -{ - x=_x; - y=_y; - -// nlinfo("Pattern: %s: dx: %d dy: %d spacing: %d",_pattern.c_str(),_dx,_dy,_spacing); - if (_pattern==std::string("grid")) - { - if (_leftonline) - _leftonline--; - else - { - if (_dx) - _linelen++; - _leftonline=_linelen; - _dx+=_dy; - _dy-=_dx; - _dx+=_dy; - } - _x+=_dx; - _y+=_dy; - } - else if (_pattern==std::string("line")) - { - _x+=_dx; - _y+=_dy; - } - else if (_pattern==std::string("spawnZone")) - { - NLMISC::CVector v=_spawnZones[_spawnZoneName].getNext(); - _x=(int)(v.x*1000.0f); - _y=(int)(v.y*1000.0f); - } - else - nlwarning("Unknown pattern: %s",_pattern.c_str()); -} - -void CPositionGenerator::addSpawnZone(const NLLIGO::CPrimZone &zone) -{ - if (_spawnZones[zone.getName()].Points.size()!=0) - { - nlinfo("Spawn zone already exists: %s",zone.getName().c_str()); - return; - } - - // determine the extents of the zone - float minx=(float)(((uint)~0)>>1); - float maxx=-minx-1.0f; - float miny=minx; - float maxy=maxx; - for (uint i=0;imaxx) maxx=zone.VPoints[i].x; - if (zone.VPoints[i].ymaxy) maxy=zone.VPoints[i].y; - } - - // round off the zone extents to centre the bounding box about the zone centre - const float SPACING=4.0f; - float xbase= ((maxx-minx)/2.0f+minx); - float ybase= ((maxx-minx)/2.0f+miny); - int xcount=(int)((maxx-xbase)/SPACING); - int ycount=(int)((maxy-ybase)/SPACING); - - // loop through the points in the bounding box seeing whether or not they're in the zone - for (int xi=-xcount;xi -// 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 . - - - - -#ifndef GD_POSITION_GENERATOR_H -#define GD_POSITION_GENERATOR_H - - -#include -#include "nel/misc/types_nl.h" -#include "nel/ligo/primitive.h" - - -namespace AGS_TEST -{ - -class CPositionGenerator -{ -public: - static void setPositionInMM(int x, int y); // x and y are in milimeters - static void setPosition(int x, int y); // x and y are in meters - static void setPosition(std::string spawnName); // name of a spawn point or spawn zone - static void setPattern(const std::string &pattern); - static void setSpacing(int spacing); - - static void addSpawnPoint(const NLLIGO::CPrimPoint &point) { _spawnPoints[point.getName()]=point; } - static void addSpawnZone(const NLLIGO::CPrimZone &zone); - - static void init(); - static void next(int &x, int &y); - - static std::string getSpawnName(); - -private: - class CSpawnZone - { - public: - uint Next; - std::vector Points; - - CSpawnZone(): Next(0) {} - const NLMISC::CVector& getNext() - { - if (Next>=Points.size()) Next=0; - return Points[Next++]; - } - }; - -private: - static int _x, _y; - static int _dx, _dy; - static int _spacing; - static std::string _pattern; - static std::string _spawnZoneName; - - typedef std::map TSpawnZoneMap; - typedef std::map TSpawnPointMap; - - static TSpawnZoneMap _spawnZones; - static TSpawnPointMap _spawnPoints; - - // for grid - static int _linelen, _leftonline; -}; - - -} // end of namespace AGS_TEST - -#endif // GD_POSITION_GENERATOR_H diff --git a/code/ryzom/server/src/ags_test/service_main.cpp b/code/ryzom/server/src/ags_test/service_main.cpp deleted file mode 100644 index 615e28e8c..000000000 --- a/code/ryzom/server/src/ags_test/service_main.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "nel/misc/types_nl.h" -#include "nel/net/service.h" -#include "nel/misc/path.h" -#include "game_share/tick_event_handler.h" -#include "game_share/ryzom_version.h" - -#include "messages.h" // singleton manager for transport class messages -#include "mirrors.h" // singleton manager for data in mirrors -#include "sheets.h" // singleton manager for data from george forms -#include "move_manager.h" // singleton manager for agent movement -#include "command_event_manager.h" - -//#include "combat_interface.h" -//#include "bot_chat_interface.h" - -#include "actor_manager.h" // actor manager - the back end of the service - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace AGS_TEST; - - -static TUnifiedCallbackItem CallbackArray[] = -{ - { "QWERTY", 0, }, -}; - -/*-----------------------------------------------------------------*\ - SERVICE CLASS -\*-----------------------------------------------------------------*/ - -class CAgsTest : public NLNET::IService -{ -public: - void init(); - bool update(); - void release() {} - void tickRelease(); -}; - -// callback for the 'tick' update message -static void cbTick(); - -// callback for the 'tick' release message -void cbTickRelease() -{ - (static_cast(CAgsTest::getInstance()))->tickRelease(); -} - -/*-----------------------------------------------------------------*\ - SERVICE INIT & RELEASE -\*-----------------------------------------------------------------*/ - -///init - -void CAgsTest::init (void) -{ - setVersion (RYZOM_VERSION); - - // setup the update systems -// setUpdateTimeout(200); - - // Load the sheet id lookup table - - // init sub systems - CSheets::init(); - CMirrors::init(cbTick, NULL, cbTickRelease); - CMessages::init(); - CMoveManager::init(); - CActorManager::init(); - //CCombatInterface::init(); - //CBotChatInterface::init(); - CCommandEventManager::init(); - - // setup the debug filters - DebugLog->addNegativeFilter("NETL"); -} - - -///release - -void CAgsTest::tickRelease (void) -{ - // release sub systems - CSheets::release(); - CMessages::release(); - CMoveManager::release(); - CActorManager::release(); - //CCombatInterface::release(); - //CBotChatInterface::release(); - CCommandEventManager::release(); - CMirrors::release(); -} - - -/*-----------------------------------------------------------------*\ - SERVICE UPDATES -\*-----------------------------------------------------------------*/ - -///update called on each 'tick' message from tick service - -void cbTick() -{ - if ( CMirrors::Mirror.mirrorIsReady() ) - { - CActorManager::update(); - CMoveManager::update(); - //CCombatInterface::_events.clear(); - CCommandEventManager::update(); - } -} - - -///update called every complete cycle of service loop - -bool CAgsTest::update (void) -{ - return true; -} - -/*-----------------------------------------------------------------*\ - NLNET_SERVICE_MAIN -\*-----------------------------------------------------------------*/ -NLNET_SERVICE_MAIN (CAgsTest, "AGS", "ags_test_service", 0, CallbackArray, "", "") - diff --git a/code/ryzom/server/src/ags_test/sheets.cpp b/code/ryzom/server/src/ags_test/sheets.cpp deleted file mode 100644 index 78cc06bd0..000000000 --- a/code/ryzom/server/src/ags_test/sheets.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -// Misc -#include "nel/misc/path.h" -#include "nel/misc/file.h" -#include "nel/misc/smart_ptr.h" -#include "nel/misc/command.h" -#include "nel/misc/path.h" -// Georges -#include "nel/georges/u_form.h" -#include "nel/georges/u_form_elm.h" -#include "nel/georges/u_form_loader.h" -#include "nel/georges/load_form.h" -// Local -#include "sheets.h" - - -/////////// -// USING // -/////////// -using namespace NLMISC; -using namespace std; -using namespace NLGEORGES; - -namespace AGS_TEST -{ - -//------------------------------------------------------------------------- -// the singleton data - -std::map CSheets::_Sheets; -bool CSheets::_Initialised=false; - -//------------------------------------------------------------------------- -// init - -void CSheets::init() -{ - if (_Initialised) - return; - - std::vector filters; - filters.push_back("creature"); - filters.push_back("player"); - - loadForm(filters, "data_shard/ags_test.packed_sheets", _Sheets); - - _Initialised=true; -} - - -//------------------------------------------------------------------------- -// display - -void CSheets::display(NLMISC::CLog *log) -{ - nlassert(_Initialised); - - std::map::iterator it; - for(it=_Sheets.begin();it!=_Sheets.end();++it) - { - log->displayNL("SHEET:%s Walk:%f Run:%f Radius:%f Height:%f Bounding:%f Type:%s ChatType: %s",(*it).first.toString().c_str(), - (*it).second.WalkSpeed, - (*it).second.RunSpeed, - (*it).second.Radius, - (*it).second.Height, - (*it).second.BoundingRadius, -// (*it).second.Name.c_str(), - (*it).second.isNpc?"NPC": "CREATURE", - (std::string()+((*it).second.CanChatTP?"TP ":"")+((*it).second.CanChatTrade?"MERCHANT ":"")+((*it).second.CanChatMission?"MISSION ":"")).c_str() - ); - } -} - - -//------------------------------------------------------------------------- -// lookup - -const CSheets::CSheet *CSheets::lookup( CSheetId id ) -{ - nlassert(_Initialised); - - // setup an iterator and lookup the sheet id in the map - std::map::iterator it=_Sheets.find(id); - - // if we found a valid entry return a pointer to the creature record otherwise 0 - if (it!=_Sheets.end()) - return &((*it).second); - else - return NULL; -} - -} //namespace AGS_TEST - diff --git a/code/ryzom/server/src/ags_test/sheets.h b/code/ryzom/server/src/ags_test/sheets.h deleted file mode 100644 index 7c3441add..000000000 --- a/code/ryzom/server/src/ags_test/sheets.h +++ /dev/null @@ -1,178 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RY_AGST_SHEETS_H -#define RY_AGST_SHEETS_H - - -// Nel Misc -#include "nel/misc/types_nl.h" -#include "nel/misc/smart_ptr.h" -#include "nel/misc/sheet_id.h" - -///Nel Georges -#include "nel/georges/u_form.h" -#include "nel/georges/u_form_elm.h" - - -namespace AGS_TEST -{ - - - -/** - * Singleton containing database on information for actors - * \author Sadge - * \author Nevrax France - * \date 2002 - */ -class CSheets -{ -public: - class CSheet - { - public: - CSheet(): WalkSpeed(1.3f), RunSpeed(6.0f), Radius(0.5f), Height(2.0f), BoundingRadius(0.5) {} - - uint32 Level; // Level of the creature - - float AttackThreshold; - float FleeThreshold; - float SurvivalThreshold; - - float WalkSpeed; - float RunSpeed; - float Radius; // pacs primitive's radius - float Height; // pacs primitive's height - float BoundingRadius; // fighting radius - bool isNpc; // is it an Npc or is it a creature? - bool CanChatTP; // true if can access chat teleport sub-menu - bool CanChatTrade; // true if can access chat trade sub-menu - bool CanChatMission; // true if can access chat mission sub-menu -// std::string Name; - - void readGeorges (const NLMISC::CSmartPtr &form, const NLMISC::CSheetId &sheetId) - { - const NLGEORGES::UFormElm *elmt = 0; - std::string s; - uint i; - - // the form was found so read the true values from George - form->getRootNode ().getValueByName (WalkSpeed, "Basics.MovementSpeeds.WalkSpeed"); - form->getRootNode ().getValueByName (RunSpeed, "Basics.MovementSpeeds.RunSpeed"); - form->getRootNode ().getValueByName (Radius, "Collision.CollisionRadius"); - form->getRootNode ().getValueByName (Height, "Collision.Height"); - form->getRootNode ().getValueByName (BoundingRadius, "Collision.BoundingRadius"); - - form->getRootNode().getValueByName(Level, "Basics.Level"); - - form->getRootNode().getValueByName (AttackThreshold, "AI.IsA.combatif.seuil_attaque"); - form->getRootNode().getValueByName (AttackThreshold, "AI.IsA.combatif.seuil_fuite"); - form->getRootNode().getValueByName (SurvivalThreshold, "AI.IsA.combatif.poids_survie"); - -// form->getRootNode ().getValueByName (Name, "Basics.First Name"); -// form->getRootNode ().getValueByName (s, "Basics.CharacterName"); -// if (!Name.empty()) -// Name+=' '; -// Name+=s; - - // are we a creature or an NPC? - form->getRootNode ().getValueByName (s, "Basics.Race"); - isNpc= s=="Fyros"? true: - s=="Tryker"? true: - s=="Zorai"? true: - s=="Matis"? true: - false; - - // can we chat mission? - if (form->getRootNode ().getValueByName (s, "Basics.Race")) - CanChatMission= (s=="Kami"); - - // can we chat trade? - CanChatTrade=false; - for (i=1;i<5;++i) - { - if (form->getRootNode ().getValueByName (s, (std::string("ShopKeeper infos.ObjectType")+char('0'+i)).c_str())) - CanChatTrade|= (s!="UNDEFINED" && s!="Unknown" && !s.empty()); - if (form->getRootNode ().getValueByName (s, (std::string("ShopKeeper infos.ObjectType")+char('0'+i)).c_str())) - CanChatTrade|= (s!="UNDEFINED" && s!="Unknown" && !s.empty()); - } - - if (form->getRootNode ().getNodeByName(&elmt,"ShopKeeper infos.Special Items") && elmt!=0) - { - uint arraySize; - elmt->getArraySize(arraySize); - CanChatTrade|= (arraySize!=0); - } - - if (form->getRootNode ().getNodeByName(&elmt,"ShopKeeper infos.Special Mp") && elmt!=0) - { - uint arraySize; - elmt->getArraySize(arraySize); - CanChatTrade|= (arraySize!=0); - } - - - // can we chat TP? - form->getRootNode ().getValueByName (s, "ShopKeeper infos.TeleportType"); - CanChatTP= (s!="NONE"); - - if (CanChatMission) nlinfo("bot can chat Mission: %s",sheetId.toString().c_str()); - if (CanChatTrade) nlinfo("bot can chat Trade: %s",sheetId.toString().c_str()); - if (CanChatTP) nlinfo("bot can chat TP: %s",sheetId.toString().c_str()); - } - - void serial (NLMISC::IStream &s) - { - s.serial (WalkSpeed, RunSpeed, Radius, Height); - s.serial (BoundingRadius, isNpc/*, Name*/); - s.serial (CanChatTP, CanChatTrade, CanChatMission); - s.serial (Level); - s.serial( AttackThreshold, FleeThreshold, SurvivalThreshold); - } - - void removed() {} - - static uint getVersion () { return 6; } - }; - - // load the creature data from the george files - static void init (); - static void removeUnsuableSheets (); - - // display the creature data for all known creature types - static void display(NLMISC::CLog *log = NLMISC::InfoLog); - - // - static void release() {} - - // get a data record from the database - static const CSheet *lookup( NLMISC::CSheetId id ); - -private: - // prohibit cnstructor as this is a singleton - CSheets(); - - static std::map _Sheets; - static bool _Initialised; -}; - - -} // end of namespace AGS_TEST - -#endif // RY_AGST_SHEETS_H diff --git a/code/ryzom/server/src/ags_test/xml.cpp b/code/ryzom/server/src/ags_test/xml.cpp deleted file mode 100644 index 5543d15f2..000000000 --- a/code/ryzom/server/src/ags_test/xml.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "nel/misc/debug.h" -#include "nel/misc/path.h" - -//#include -#include - -#include "xml.h" - - -using namespace NLMISC; - -static inline bool isBlank(char c) -{ - static bool lookup[]= - {// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0,0,0,0, 0,0,0,0, 0,1,1,0, 0,1,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0 - 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 32 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 64 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 96 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 128 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 160 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 192 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 224 - }; - return lookup[uint8(c)]; -} - -static inline bool isTxt(char c) -{ - static bool lookup[]= - {// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 32 - 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 64 - 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 96 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 128 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 160 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 192 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 224 - }; - return lookup[uint8(c)]; -} - -static inline bool isArgTxt(char c) -{ - static bool lookup[]= - {// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0,0,0,0, 0,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0 - 1,1,0,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 0,1,0,1, // 32 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 64 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 96 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 128 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 160 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 192 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 224 - }; - return lookup[uint8(c)]; -} - -static inline bool isFreeTxt(char c) -{ - static bool lookup[]= - {// 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0,0,0,0, 0,0,0,0, 0,1,1,0, 0,1,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 0,1,0,1, // 32 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 64 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 96 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 128 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 160 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 192 - 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 224 - }; - return lookup[uint8(c)]; -} - -static bool xmlTxtToString(char *txt,uint length,std::string &destination) -{ - bool result=true; - - destination.erase(); - destination.reserve(length); - - for (char *ptr=txt;ptr' - if (*ptr=='!') - { - while (isFreeTxt(*++ptr)) _txt+=*ptr; - // skip the end of comment marker - if (*ptr!='>') - return false; - ptr++; - return true; - } - - // this should be a normal named clause so identify the clause name - while (isBlank(*ptr)) ptr++; - for (marker0=ptr; isTxt(*ptr); ptr++); - xmlTxtToString(marker0,ptr-marker0,_name); - - // extract arguments - while (isBlank(*ptr)) ptr++; - while (isTxt(*ptr)) - { - // extract the argument name for the next argument - for (marker0=ptr; isTxt(*ptr); ptr++); - std::string argName; - xmlTxtToString(marker0,ptr-marker0,argName); - - // skip the '=' sign and following '"' sign - while (isBlank(*ptr)) ptr++; - if(*ptr!='=') - return false; - do { ptr++; }while (isBlank(*ptr)); - if(*ptr!='\"') - return false; - ptr++; - - // find the string delimited by the quotes - for (marker0=ptr; isArgTxt(*ptr); ptr++); - if(*ptr!='\"') - return false; - xmlTxtToString(marker0,ptr-marker0,_args[argName]); - - // skip blanks in preparation for next arg (or end of args) - while (isBlank(*ptr)) ptr++; - } - - // if this is a self-contained clause (ie '<'...'/>') then we've finished - if (*ptr=='/' && ptr[1]=='>') - { - ptr+=2; - return true; - } - - // skip the end of clause header marker - if (*ptr!='>') - return false; - ptr++; - - // read sub-clauses - while (*ptr && !(ptr[0]=='<'&&ptr[1]=='/')) - { - CxmlNode *childClause =new CxmlNode; - _children.push_back(childClause); - childClause->parseInput(ptr); - } - - // skip the opening '' of the clause end marker - while (isBlank(*ptr)) ptr++; - if (*ptr!='>') - return false; - ptr+=2; - - return true; -} - - diff --git a/code/ryzom/server/src/ags_test/xml.h b/code/ryzom/server/src/ags_test/xml.h deleted file mode 100644 index 08630ee29..000000000 --- a/code/ryzom/server/src/ags_test/xml.h +++ /dev/null @@ -1,55 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#include "nel/misc/types_nl.h" - -#include -#include -#include - - -class CxmlNode -{ -public: - bool read(const std::string &filename); - bool parseInput(char * &ptr); - - inline const std::string &txt() const { return _txt; } - inline const std::string &type() const { return _name; } - inline const std::string &arg(const std::string &argName) const - { - static std::string emptyString; - - std::map::const_iterator it; - it=_args.find(argName); - - if (it!=_args.end()) - return (*it).second; - else - return emptyString; - } - - inline uint childCount() const { return _children.size(); } - inline CxmlNode *child(uint index) const { return _children[index]; } - -private: - std::string _txt; - std::string _name; - std::map _args; - std::vector _children; -}; - diff --git a/code/ryzom/server/src/ai_data_service/CMakeLists.txt b/code/ryzom/server/src/ai_data_service/CMakeLists.txt deleted file mode 100644 index 0292b2895..000000000 --- a/code/ryzom/server/src/ai_data_service/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -FILE(GLOB SRC *.cpp *.h) - -#LIST(REMOVE_ITEM SRC ${CMAKE_CURRENT_SOURCE_DIR}/ai_entity_id.cpp)) - -ADD_EXECUTABLE(ai_data_service WIN32 ${SRC}) - -INCLUDE_DIRECTORIES(${RZ_SERVER_SRC_DIR} ${MYSQL_INCLUDE_DIR}) - -TARGET_LINK_LIBRARIES(ai_data_service - admin_modules - ryzom_gameshare - server_share - ai_share - nelmisc - nelnet - nelgeorges - nelpacs - nelligo) - -NL_DEFAULT_PROPS(ai_data_service "Ryzom, Services: AI Data Service (AIDS)") -NL_ADD_RUNTIME_FLAGS(ai_data_service) - -INSTALL(TARGETS ai_data_service RUNTIME DESTINATION sbin COMPONENT services) - diff --git a/code/ryzom/server/src/ai_data_service/ai_files.cpp b/code/ryzom/server/src/ai_data_service/ai_files.cpp deleted file mode 100644 index c16e383fe..000000000 --- a/code/ryzom/server/src/ai_data_service/ai_files.cpp +++ /dev/null @@ -1,534 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include -//#include -#include - -#include "nel/misc/types_nl.h" -#include "nel/misc/path.h" -#include "nel/misc/file.h" -#include "nel/misc/i_xml.h" -#include "nel/misc/o_xml.h" -#include "nel/misc/config_file.h" -#include "nel/net/service.h" - - -#include "game_share/xml.h" -#include "ai_files.h" -#include "ai_manager.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - - -//-------------------------------------------------------------------------------- -// LOCAL GLOBALS - EQUIVALENT TO SINGLETON DATA -//-------------------------------------------------------------------------------- - -class CFileInfo -{ -public: - std::string Source; - uint Size; - uint DateTime; - - void clear() - { - Source.clear(); - Size=0; - DateTime=0; - } -}; - -static CFileInfo mgrObjInfo[RYAI_AI_MANAGER_MAX_MANAGERS]; - - -//-------------------------------------------------------------------------------- -// scan() METHOD -//-------------------------------------------------------------------------------- - -// clear out the data strustures and rescan the directories listed in the config -// file for source and object files - -void CAIFiles::scan() -{ - uint i; - - // clear out out the internal data tables before we begin - for (i=0;i paths=srcPaths(); - for (i = 0; i < paths.size(); i++) - { - nlinfo("SCANNING: %s",paths[i].c_str()); - _scanSrcFiles(paths[i]); - } - - // run through the managers in the AI_Manager singleton, updating parameters - for (i=0;iid(); - nlinfo("Manager: %04d: %s",mgrId,mgr->name().c_str()); - } -} - -//-------------------------------------------------------------------------------- -// clean() METHOD -//-------------------------------------------------------------------------------- - -void CAIFiles::clean(sint mgrId) -{ - remove(fullObjFileName(mgrId).c_str()); -} - -//-------------------------------------------------------------------------------- -// FILE NAME HANDLING METHODS -//-------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------- -// source file name, extension, etc - -// the paths for source files -std::vector CAIFiles::srcPaths() -{ - std::vector v; - try - { - CConfigFile::CVar& var = IService::getInstance()->ConfigFile.getVar("SrcPaths"); - for (uint i = 0; i < var.size(); i++) - v.push_back(CPath::standardizePath(var.asString(i))); - } - catch(EUnknownVar &) - { - nlwarning(" missing variables in config file, using '.'"); - v.push_back(std::string("./")); - } - - return v; -} - -// the standard src extension -std::string CAIFiles::srcExtension() -{ - return std::string("primitive"); -} - -// without path or extension -std::string CAIFiles::srcName(sint mgrId) -{ - return CFile::getFilenameWithoutExtension(fullSrcFileName(mgrId)); -} - -// without path -std::string CAIFiles::srcFileName(sint mgrId) -{ - return CFile::getFilename(fullSrcFileName(mgrId)); -} - -// without extension -std::string CAIFiles::fullSrcName(sint mgrId) -{ - return - CFile::getPath(fullSrcFileName(mgrId))+ - CFile::getFilenameWithoutExtension(fullSrcFileName(mgrId)); -} - -// with path and extension -std::string CAIFiles::fullSrcFileName(sint mgrId) -{ - if (uint(mgrId)>=CAIManager::maxManagers()) - { - nlwarning("CAIFiles::fullSrcFileName(mgrId): mgrId %d not in range 0..%d",mgrId,CAIManager::maxManagers()-1); - return string(); - } - - return mgrObjInfo[mgrId].Source; -} - - -//-------------------------------------------------------------------------------- -// object file name, extension, etc - -// the path for obj files -std::string CAIFiles::objPath() -{ - std::string s; - - // get the object path from the config file - try - { - s=IService::getInstance()->ConfigFile.getVar("ObjPath").asString(); - } - catch(EUnknownVar &) - { - nlwarning(" missing variables in config file, using '.'"); - } - - // if we haven't found a path use the current directory - if (s.empty()) - s="./"; - - return CPath::standardizePath(s); -} - -// the standard obj file extension -std::string CAIFiles::objExtension() -{ - return std::string("aimgr_obj"); -} - -// without path or extension -std::string CAIFiles::objName(sint mgrId) -{ - if (uint(mgrId)>=CAIManager::maxManagers()) - { - nlwarning("CAIFiles::fullSrcFileName(mgrId): mgrId %d not in range 0..%d",mgrId,CAIManager::maxManagers()-1); - return string(); - } - - std::string s; - s+=(mgrId/1000)+'0'; - s+=(mgrId%1000)/100+'0'; - s+=(mgrId%100)/10+'0'; - s+=(mgrId%10)+'0'; - - return s; -} - -// without extension -std::string CAIFiles::objFileName(sint mgrId) -{ - // if the objName() method fails to generate a file name return an empty string - std::string s=objName(mgrId); - if (s.empty()) - return s; - - return s+'.'+objExtension(); -} - -// with path and extension -std::string CAIFiles::fullObjFileName(sint mgrId) -{ - // if the objFileName() method fails to generate a file name return an empty string - std::string s=objFileName(mgrId); - if (s.empty()) - return s; - - return objPath()+s; -} - - - -//-------------------------------------------------------------------------------- -// saved data file name, extension, etc - -// the path for sav files -std::string CAIFiles::savPath() -{ - std::string s; - - // get the sav path from the config file - try - { - s=IService::getInstance()->ConfigFile.getVar("SavPath").asString(); - } - catch(EUnknownVar &) - { - nlwarning(" missing variables in config file, using "); - return objPath(); - } - - // if we haven't found a path use the current directory - if (s.empty()) - s="./"; - - return CPath::standardizePath(s); -} - -// the standard sav file extension -std::string CAIFiles::savExtension() -{ - return std::string("aimgr_sav"); -} - -// without path or extension -std::string CAIFiles::savName(sint mgrId) -{ - return objName(mgrId); -} - -// without extension -std::string CAIFiles::savFileName(sint mgrId) -{ - // if the savName() method fails to generate a file name return an empty string - std::string s=savName(mgrId); - if (s.empty()) - return s; - - return s+'.'+savExtension(); -} - -// with path and extension -std::string CAIFiles::fullSavFileName(sint mgrId) -{ - // if the savName() method fails to generate a file name return an empty string - std::string s=savName(mgrId); - if (s.empty()) - return s; - - return savPath()+s; -} - -//-------------------------------------------------------------------------------- -// CAIFiles PUBLIC METHODS - FOR READING & WRITING OBJ FILES -//-------------------------------------------------------------------------------- - -void CAIFiles::writeObjFile(sint mgrId) -{ - // write the output file - NLMISC::COFile file; - bool fileIsOpen=false; - try - { - NLMISC::COXml output; - - if (!file.open(fullObjFileName(mgrId))) throw(NLMISC::Exception()); - fileIsOpen=true; - if (output.init (&file, "1.0")) - { - output.xmlPush("AI_MANAGER"); - std::string src=CAIFiles::srcName(mgrId); - ((NLMISC::IStream*)&output)->serial(src); - CAIManager::getManagerById(mgrId)->MgrDfnRootNode.serial(output); - output.xmlPop(); - output.flush (); - } - } - catch (NLMISC::Exception &) - { - nlwarning("CAIFiles::writeObjFile(): Failed to write the output file: %s",fullObjFileName(mgrId).c_str()); - } - // close file outside exception handling in case exception thrown somewhere strange - if (fileIsOpen) - file.close(); -} - -//-------------------------------------------------------------------------------- -// CAIFiles PRIVATE METHODS - FOR ADDING FILE RECORDS TO RELAVENT DATA STRUCTURES -//-------------------------------------------------------------------------------- - -void CAIFiles::_addObjFile(sint mgrId, std::string fullFileName, uint timestamp) -{ - // read the input file - NLMISC::CIFile file; - bool fileIsOpen=false; - try - { - NLMISC::CIXml input; - - if (!file.open(fullObjFileName(mgrId))) throw(NLMISC::Exception()); - fileIsOpen=true; - if (input.init (file)) - { - input.xmlPush("AI_MANAGER"); - ((NLMISC::IStream*)&input)->serial(mgrObjInfo[mgrId].Source); - CAIManager::getManagerById(mgrId)->MgrDfnRootNode.serial(input); - input.xmlPop(); - } - } - catch (NLMISC::Exception &) - { - nlwarning("CAIFiles::_addObjFile(): Failed to read the input file: %s",fullObjFileName(mgrId).c_str()); - } - // close file outside exception handling in case exception thrown somewhere strange - if (fileIsOpen) - file.close(); - - // ask the ai manager to initialise itself with name 'name' (fails if manager is running) - if (!CAIManager::getManagerById(mgrId)->set(srcName(mgrId))) - { - nlwarning("Conflict between running manager %04d named '%s' and name in obj file '%s'", - mgrId,CAIManager::getManagerById(mgrId)->name().c_str(),srcName(mgrId).c_str()); - return; - } - - // assign the new record to the designated slot - mgrObjInfo[mgrId].DateTime=timestamp; // timestamp of obj file - - // update the manager flags - CAIManager::getManagerById(mgrId)->setObjFileExists(true); -} - - -void CAIFiles::_addSavFile(sint mgrId, std::string fullFileName) -{ - // open and parse the file - CxmlNode theXmlFile; - if (!theXmlFile.read(fullFileName)) - { - nlwarning("Failed to parse xml file: %s",fullFileName.c_str()); - return; - } - - // make sure the main xml clause is of the correct type for an obj file - if (theXmlFile.type()!=string("ai_manager_dynamic_data")) - { - nlwarning("Ignoring file %s because main clause is not 'ai_manager_dynamic_data'",fullFileName.c_str()); - return; - } - - // extract the 'name' argument from the main clause - std::string name=theXmlFile.arg("name"); - if (name.empty()) - { - nlwarning("No manager name found in save file: %s",fullFileName.c_str()); - return; - } - - // ask the ai manager to initialis itself with name 'name' (fails if manager is running) - if (!CAIManager::getManagerById(mgrId)->set(name)) - { - nlwarning("Conflict between running manager %04d named '%s' and name in sav file '%s'", - mgrId,CAIManager::getManagerById(mgrId)->name().c_str(),name.c_str()); - return; - } -} - - -void CAIFiles::_addSrcFile(std::string fileName,std::string fullFileName, uint timestamp) -{ - // generate a manger name from the file name - std::string name=CFile::getFilenameWithoutExtension(fileName); - - // ask the CAIManager singleton for a manager id for this name - sint mgrId = CAIManager::nameToId(name,true); - if (mgrId==-1) - { - nlwarning("Failed to allocate a manager id for name '%s' (manager ids 0..%d)", - name.c_str(), CAIManager::maxManagers()-1); - return; - } - - // make sure that we don't have another file already allocated to this manager - if (!mgrObjInfo[mgrId].Source.empty() && fullSrcFileName(mgrId)!=fullFileName && srcName(mgrId)!=NLMISC::CFile::getFilenameWithoutExtension(fullFileName)) - { - nlwarning("File name conflict for: %s: %s != %s", - name.c_str(),mgrObjInfo[mgrId].Source.c_str(),NLMISC::CFile::getFilenameWithoutExtension(fullFileName).c_str()); - return; - } - - // assign the file name - mgrObjInfo[mgrId].Source=fullFileName; - - // update the manager flags - if (timestamp>mgrObjInfo[mgrId].DateTime) - CAIManager::getManagerById(mgrId)->setNeedCompile(true); -} - -//-------------------------------------------------------------------------------- -// CAIFiles PRIVATE METHODS - FOR DIRECTORIES FOR FILES -//-------------------------------------------------------------------------------- - -void CAIFiles::_scanSrcFiles(const std::string &path) -{ - //nlinfo("Scanning source directory: %s",path.c_str()); - - // setup the directory scan - _finddata_t fd; - long searchHandle; - if( (searchHandle = _findfirst( (path+"*").c_str(), &fd )) == -1L ) - { - nlwarning("Nothing found in directory: %s",path.c_str()); - return; - } - - // iterate through found entries in the directory - do - { - // if we have a directory then recurse - if ( (fd.attrib & _A_SUBDIR) != 0 ) - { - // ignore '.' and '..' entries - if (fd.name[0]!='.' || (fd.name[1]!=0 && (fd.name[1]!='.' || fd.name[2]!=0) ) ) - _scanSrcFiles(path+std::string(fd.name)+"/"); - } - else - { - // we've found a file so have a look to see whether its one of ours - std::string fileName=std::string(fd.name); - if (CFile::getExtension(fileName)==srcExtension()) - _addSrcFile(fileName, path+fileName, uint32(fd.time_write)); - } - } - while( _findnext( searchHandle, &fd ) == 0 ); - - // housekeeping - _findclose( searchHandle ); -} - -void CAIFiles::_scanObjAndSavFiles() -{ - // setup to scan for obj files - std::string path=objPath(); - nlinfo("Scanning directory: %s for *.%s",path.c_str(),objExtension().c_str()); - - // iterate through manager ids looking for correspoding files - for (uint i=0;iname().empty()) continue; - - // compose the file name - std::string filename=path+savFileName(sint(j)); - _finddata_t fd; - - // look for the file - long searchHandle; - if( (searchHandle=_findfirst(filename.c_str(),&fd)) != -1L ) - _addSavFile(j,filename.c_str()); - _findclose( searchHandle ); - } -} - diff --git a/code/ryzom/server/src/ai_data_service/ai_files.h b/code/ryzom/server/src/ai_data_service/ai_files.h deleted file mode 100644 index fcf3e6e6c..000000000 --- a/code/ryzom/server/src/ai_data_service/ai_files.h +++ /dev/null @@ -1,75 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AI_FILES_H -#define RYAI_AI_FILES_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/sheet_id.h" -#include "nel/misc/entity_id.h" - -#include "nel/net/transport_class.h" - -#include -#include - -class CAIFiles -{ -public: - // clear out the data strustures and rescan the directories listed in the config - // file for source and object files - static void scan(); - - // delete the object files (and temporary files if any) for a given manager - static void clean(sint mgrId); - - // source file name, extension, etc - static std::vector srcPaths(); // the paths for source files - static std::string srcExtension(); // the standard src extension - static std::string srcName(sint mgrId); // without path or extension - static std::string srcFileName(sint mgrId); // without path - static std::string fullSrcName(sint mgrId); // without extension - static std::string fullSrcFileName(sint mgrId); // with path and extension - - // object file name, extension, etc - static std::string objPath(); // the path for obj files - static std::string objExtension(); // the standard obj file extension - static std::string objName(sint mgrId); // without path or extension - static std::string objFileName(sint mgrId); // without extension - static std::string fullObjFileName(sint mgrId); // with path and extension - - // saved data file name, extension, etc - static std::string savPath(); // the path for sav files - static std::string savExtension(); // the standard sav file extension - static std::string savName(sint mgrId); // without path or extension - static std::string savFileName(sint mgrId); // without extension - static std::string fullSavFileName(sint mgrId); // with path and extension - - // Reading & writing object files - static void CAIFiles::writeObjFile(sint mgrId); - -private: - static void CAIFiles::_addSrcFile(std::string fileName,std::string fullFileName, uint timestamp); - static void CAIFiles::_addObjFile(sint mgrId,std::string fullFileName, uint timestamp); - static void CAIFiles::_addSavFile(sint mgrId,std::string fullFileName); - - static void CAIFiles::_scanSrcFiles(const std::string &path); - static void CAIFiles::_scanObjAndSavFiles(); -}; - -#endif \ No newline at end of file diff --git a/code/ryzom/server/src/ai_data_service/ai_manager.cpp b/code/ryzom/server/src/ai_data_service/ai_manager.cpp deleted file mode 100644 index 2d87faf03..000000000 --- a/code/ryzom/server/src/ai_data_service/ai_manager.cpp +++ /dev/null @@ -1,486 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//=================================================================== - - -/* - AI Managers - - -- individual -- - what's my id - what's my root name (what's my source file name) - which service am i on - do I need recompiling - what's my load weighting - - -- container -- - vector? - get manager by name - get manager by id - - queue of managers waiting to be allocated to servers - queue is processed on - service update, dispatching new 'manager up's to services who are currently - not in the process of loading - - *** - if we add a concept of manager families then we can launch rafts of managers together - this can make it easy to explicitly ballance loading - - *** - even better would be to group by service and assume that all services have same power - this way all can be launched and assigned as services come up. if the services are - launched @ 1 per CPU or one per server then we can explictly overload, and - automatically load ballance afterwards... -*/ - -#include "nel/misc/debug.h" -#include "nel/misc/file.h" -#include "nel/misc/config_file.h" -#include "nel/misc/path.h" -#include "nel/net/service.h" - -#include "game_share/xml.h" -#include "ai_share/ai_share.h" - -#include "ai_manager.h" -#include "ai_service.h" -#include "ai_files.h" -#include "aids_actions.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - - -//=================================================================== - -//--------------------------------------------------- -// INSTANTIATED CLASS: Public methods - -//------------- -// a few read accessors (static properties) - -// the manager id (0..255) -sint CAIManager::id() const -{ - return int(this-_managers); -} -// the manager name .. ie the source file name minus extension -const std::string &CAIManager::name() const -{ - return _name; -} - -// the CPU load rating of the manager for auto-load ballancing purposes -uint CAIManager::weightCPU() const -{ - return _weightCPU; -} -// the RAM load rating of the manager for auto-load ballancing purposes -uint CAIManager::weightRAM() const -{ - return _weightRAM; -} - - -//------------- -// a few read accessors (state of the files on disk) - -// indicates whether newer source files than object files have been located -bool CAIManager::needCompile() const -{ - return _needCompile; -} -// indicate whether an object file has been located in the object directory -bool CAIManager::objExists() const -{ - return _objExists; -} - - -//------------- -// a few read accessors (relating to assignment to & execution by an ai service) - -// has the manager been opened (it may still be waiting to be assigned) -bool CAIManager::isOpen() const -{ - return _isOpen; -} -// has the manager been assigned to a service -bool CAIManager::isAssigned() const -{ - return _isAssigned; -} -// is the manager up and running on the assigned service -bool CAIManager::isUp() const -{ - return _isUp; -} - -// the id of the service to which the manager is assigned -NLNET::TServiceId CAIManager::serviceId() const -{ - return _service; -} - - -//------------- -// a few basic actions (relating to disk files) - -const std::string &xmlDelimitedString(CxmlNode *xmlNode,const std::string &delimiter) -{ - static const std::string emptyString; - - for (uint i=0;ichildCount();++i) - { - CxmlNode *child=xmlNode->child(i); - if (child->type()==delimiter) - if (child->childCount()==1) - if (child->child(0)->type()=="") - { - return child->child(0)->txt(); - } - } - - return emptyString; -} - -const std::string &getProp(CxmlNode *xmlNode,const std::string &propertyName) -{ - static const std::string emptyString; - - for (uint i=0;ichildCount();++i) - { - CxmlNode *child=xmlNode->child(i); - if (child->type()=="PROPERTY") - { - const std::string &name= xmlDelimitedString(child,std::string("NAME")); - if (name==propertyName) - return xmlDelimitedString(child,std::string("STRING")); - } - } - return emptyString; -} - - -// compile the source files to generate new object files -void CAIManager::compile() -{ - // get the file names of input and output files - std::string srcFile=CAIFiles::fullSrcFileName(id()); - std::string objFile=CAIFiles::fullObjFileName(id()); - - // make sure this file isn't in the ignore list - CConfigFile::CVar *varPtr; - varPtr=IService::getInstance()->ConfigFile.getVarPtr(std::string("IgnorePrimitives")); - if (varPtr==NULL) - { - nlwarning("Cannot compile file '%s' as IgnorePrimitives variable not found in .cfg file: Please add 'IgnorePrimitives={\"\"};' and try again",CAIFiles::fullSrcFileName(id()).c_str()); - return; - } - for (uint i=0;isize();++i) - if (CAIFiles::srcName(id())==CFile::getFilenameWithoutExtension(varPtr->asString(i))) - { - nlinfo("Skipping file in .cfg ignoreList: %s",CAIFiles::fullSrcFileName(id()).c_str()); - return; - } - - // compile the input file - nlinfo("Compile %s => %s",srcFile.c_str(),objFile.c_str()); - CAIDSActions::CurrentManager=id(); - AI_SHARE::parsePrimFile(srcFile.c_str()); - - // make sure this file isn't in the ignore list (if the compiler found nothing interesting it will have been added) - varPtr=IService::getInstance()->ConfigFile.getVarPtr(std::string("IgnorePrimitives")); - for (uint i=0;isize();++i) - if (CAIFiles::srcName(id())==CFile::getFilenameWithoutExtension(varPtr->asString(i))) - { - nlinfo("- Skipping file as it has just been added to .cfg ignoreList: %s",CAIFiles::fullSrcFileName(id()).c_str()); - return; - } - - // write the output file - CAIFiles::writeObjFile(id()); - - // write the binary output file (for debugging only) - NLMISC::COFile file; - if (file.open(objFile+"_out")) - { - std::string s; - MgrDfnRootNode.serialToString(s); - file.serial(s); - file.close(); - } - else - nlwarning("CAIManager::compile(): Failed to open the output file: %s",(objFile+"_out").c_str()); -} - -// delete the object files (but not the save files) -void CAIManager::clean() -{ - CAIFiles::clean(id()); -} - - -//------------- -// a few basic actions (relating to assignment to & execution by an ai service) - -// open the manager on an unspecified service -// (may be queued until a service is available) -void CAIManager::open() -{ - CAIService::openMgr(id()); -} - -// assign manager to a specified service and begin execution -void CAIManager::assign(NLNET::TServiceId serviceId) -{ - // make sure that the manager isn't assigned to a service already - if (isAssigned()) - { - nlwarning("Cannot assign manager %04d (%s) to service %d as already assigned to %d", - id(), name().c_str(), serviceId.get(), _service.get()); - return; - } - - // flag me as assigned - _isAssigned=true; - _service=serviceId; - - // transfer control to the service's assignMgr() method - CAIService *service=CAIService::getServiceById(serviceId); - if (service!=NULL) - service->assignMgr(id()); -} - -// stop execution on the current service and assign to a new service -void CAIManager::reassign(NLNET::TServiceId serviceId) -{ - CAIService *service=CAIService::getServiceById(_service); - if (service!=NULL) - service->reassignMgr(id(),serviceId); -} - -// stop execution of a manager -void CAIManager::close() -{ - // make sure that the manager isn't assigned to a service already - if (!isAssigned()) - { - nlwarning("Cannot unassign manager %04d (%s) as it is already unassigned", id(), name().c_str()); - return; - } - - // if the service is running then transfer control to the service singleton's closeMgr() method - if (isUp()) - { - CAIService::closeMgr(id()); - return; - } - - // flag me as unassigned - _isAssigned=false; - _isOpen=false; - _service.set(0); -} - - -//------------- -// a few basic actions (miscelaneous) - -// display information about the state of the manager -void CAIManager::display() const -{ - if (isAssigned()) - nlinfo("AI Manager %04d: %s: %s ON SERVICE %d (%s)", id(), _name.c_str(), - isUp()? "UP AND RUNNING": - /* else */ "ASSIGNED TO BUT NOT YET UP", - _service.get(), - isOpen()? "auto-assigned": - /* else */ "manualy assigned" - ); - else - nlinfo("AI Manager %04d: %s: %s", id(), _name.c_str(), - isOpen()? "OPEN - AWAITING ASSIGNMENT": - !objExists()? "NOT OPEN - OBJECT FILE NOT FOUND": - needCompile()? "NOT OPEN - OBJECT FILE OLDER THAN SOURCE": - /* else */ "NOT OPEN - OBJECT FILE IS UP TO DATE" - ); -} - - -//------------- -// a few write accessors (miscelaneous) - -// set the name assigned to manager -// if no name previously assigned then reset all manager properties -// if a name already exists and does not match new name then do nohing and return false -bool CAIManager::set(const std::string &name) -{ - // if we already have a name associated with this slot then simply check that it matches the new name - if (!_name.empty()) - return (_name==name); - _reset(); - _name=name; - return true; -} - -// set the state of the needCompile flag -void CAIManager::setNeedCompile(bool val) -{ - _needCompile=val; -} - -// set the state of the objFileExists flag -void CAIManager::setObjFileExists(bool val) -{ - _objExists=val; -} - -// set the state of the isUp flag -void CAIManager::setIsUp(bool val) -{ - _isUp=val; -} - -// set the state of the isOpen flag -void CAIManager::setIsOpen(bool val) -{ - _isOpen=val; -} - - -//--------------------------------------------------- -// INSTANTIATED CLASS: Private methods - -// default constructor - may only be instantiated by the singleton -CAIManager::CAIManager(): MgrDfnRootNode(std::string()) -{ - // manager id - make sure that the managers are all in the one static array - // note that id is calaulated from the array address and the addess of 'this' - nlassert(uint(id())=maxManagers()) - { - nlwarning("CAIManager::getManagerById(id): id %d not in range 0..%d",id,maxManagers()-1); - return NULL; - } - return &(_managers[id]); -} - -// get a pointer to the manager with given index (0..numManagers-1) -CAIManager *CAIManager::getManagerByIdx(uint idx) -{ - uint count=0; - for (uint i=0;i=numManagers (%d)",idx,count); - return NULL; -} - -// get the handle for the manager of given name and optionally create a new -// handle if none found - return -1 if none found or no free slots -int CAIManager::nameToId(std::string name, bool assignNewIfNotFound) -{ - // see if the name is a numeric version of an id - uint val=atoi(name.c_str()); - if (!name.empty() && name.size()<=4 && - ( (val>0 && val -// 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 . - - - -#ifndef RYAI_AI_MANAGER_H -#define RYAI_AI_MANAGER_H - -#define RYAI_AI_MANAGER_MAX_MANAGERS 1024 - -#include "nel/misc/types_nl.h" -#include "nel/misc/stream.h" -#include "nel/net/unified_network.h" -#include "ai_share/ai_actions.h" - - -/* - --------------------------------------------------------------------------- - - This class defines both the singleton that manages the managers and the - class type of the managers themselves. The singleton interface can be found - at the end of the class - - --------------------------------------------------------------------------- -*/ - -class CAIManager -{ - -//=================================================================== -// *** SUB-CLASSES FOR MGR DEFINITON DATA TREE *** -//=================================================================== - -public: - struct SMgrDfnElm - { - SMgrDfnElm() {} - SMgrDfnElm(uint64 action,const std::vector &args): Action(action) - { - Args.resize(args.size()); - for (uint i=0;i Args; - }; - - struct SMgrDfnNode : public NLMISC::CRefCount - { - SMgrDfnNode() {} - SMgrDfnNode(const std::string &name) - : Name(name) - {} - SMgrDfnNode(const SMgrDfnNode &other) - : Name(other.Name), - Data(other.Data), - Child(other.Child) - {} - - void serial(NLMISC::IStream &f) - { - f.serial(Name); - f.serialCont(Data); - - uint32 count; - f.serial(count); - Child.resize(count); - if (f.isReading()) - { - for (uint i=0; iserialToString(s); - } - - std::string Name; - std::vector Data; - std::vector > Child; - - bool Visited; // used to identify modified nodes in file re-parse operations - }; - - -//=================================================================== -// *** START OF THE INSTANTIATED CLASS *** -//=================================================================== - - -public: - //--------------------------------------------------- - // INSTANTIATED CLASS: Public methods - - //------------- - // a few read accessors (static properties) - - // the manager id (0..255) - sint id() const; - // the manager name .. ie the source file name minus extension - const std::string &name() const; - - // the CPU load rating of the manager for auto-load ballancing purposes - uint weightCPU() const; - // the RAM load rating of the manager for auto-load ballancing purposes - uint weightRAM() const; - - - //------------- - // a few read accessors (state of the files on disk) - - // indicates whether newer source files than object files have been located - bool needCompile() const; - // indicate whether an object file has been located in the object directory - bool objExists() const; - - - //------------- - // a few read accessors (relating to assignment to & execution by an ai service) - - // has the manager been opened (it may still be waiting to be assigned) - bool isOpen() const; - // has the manager been assigned to a service - bool isAssigned() const; - // is the manager up and running on the assigned service - bool isUp() const; - - // the id of the service to which the manager is assigned - NLNET::TServiceId serviceId() const; - - - //------------- - // a few basic actions (relating to disk files) - - // compile the source files to generate new object files - void compile(); - // delete the object files (but not the save files) - void clean(); - - - //------------- - // a few basic actions (relating to assignment to & execution by an ai service) - - // open the manager on an unspecified service - // (may be queued until a service is available) - void open(); - // assign manager to a specified service and begin execution - void assign(NLNET::TServiceId serviceId); - // stop execution on the current service and assign to a new service - void reassign(NLNET::TServiceId serviceId); - // stop execution of a manager - void close(); - - - //------------- - // a few basic actions (miscelaneous) - - // display information about the state of the manager - void display() const; - - - //------------- - // a few write accessors (miscelaneous) - - // set the name assigned to manager - // if no name previously assigned then reset all manager properties - // if a name already exists and does not match new name then do nohing and return false - bool set(const std::string &name); - // set the state of the needCompile flag - void setNeedCompile(bool val); - // set the state of the objFileExists flag - void setObjFileExists(bool val); - // set the state of the isUp flag - void setIsUp(bool val); - // set the state of the isOpen flag - void setIsOpen(bool val); - - -private: - //--------------------------------------------------- - // INSTANTIATED CLASS: Private methods - - // default constructor - may only be instantiated by the singleton - CAIManager(); - // reset properties to initial values - void _reset(); - -private: - //--------------------------------------------------- - // INSTANTIATED CLASS: Private data - - // manager name (file name of source file minus extension) - std::string _name; - // cpu rating for load ballancing - uint _weightCPU; - // ram rating for load ballancing - uint _weightRAM; - // do we need to recompile - bool _needCompile; - // does an object file exist - bool _objExists; - // is the manager open (at least queued in CAIService singleton) - bool _isOpen; - // is manager assigned to a service - bool _isAssigned; - // is manager up and running on the assigned service - bool _isUp; - // id of the service manager is assigned to - NLNET::TServiceId _service; - - -public: - //--------------------------------------------------- - // INSTANTIATED CLASS: Public data - - // the tree of definition data read from (and written to) data files - SMgrDfnNode MgrDfnRootNode; - - -//=================================================================== -// *** END OF THE INSTANTIATED CLASS *** START OF THE SINGLETON *** -//=================================================================== - - -public: - //--------------------------------------------------- - // SINGLETON: Public methods - - // get the number of valid handles (ie the maximum number of managers allowed) - static uint maxManagers() { return RYAI_AI_MANAGER_MAX_MANAGERS; } - - // get the number of allocated managers - static uint numManagers(); - - // get a pointer to the manager with given handle (0..maxManagers-1) - static CAIManager *getManagerById(sint id); - - // get a pointer to the manager with given index (0..numManagers-1) - static CAIManager *getManagerByIdx(uint idx); - - // get the handle for the manager of given name and optionally create a new - // handle if none found - return -1 if none found or no free slots - static sint nameToId(std::string name, bool assignNewIfNotFound=false); - - // clear file name assignments for managers that aren't currently running on - // ai services - static void liberateUnassignedManagers(); - -private: - //--------------------------------------------------- - // SINGLETON: Private methods - - -private: - //--------------------------------------------------- - // SINGLETON: Private data - static CAIManager _managers[RYAI_AI_MANAGER_MAX_MANAGERS]; - - -//=================================================================== -// *** END OF THE SINGLETON *** -//=================================================================== - -}; - -#endif diff --git a/code/ryzom/server/src/ai_data_service/ai_service.cpp b/code/ryzom/server/src/ai_data_service/ai_service.cpp deleted file mode 100644 index 7bc04c9c8..000000000 --- a/code/ryzom/server/src/ai_data_service/ai_service.cpp +++ /dev/null @@ -1,322 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//=================================================================== - -/* - *** - when a service goes down I must remember that the managers are no longer running - in the normal way I can try to bring them back up on the remaining services - - *** - when a service comes up and the rest of the services are over-loaded it would be - good to be able to load ballance (if loading is fast enough) - - tell new service to load static data and prepare to launch. - - wait for new service to say 'ready' - - tell old service to transfer to new service (ie: save to ram & transmit to new service) - - * old service must continue to forward packets to the new service to ensure smooth continuation - - old service tells me when he's down - - new service tells me when he's up - - *** - Need to deal with 'save's as well... - - *** - Need init() and release() in order to register message callbacks, etc? -*/ - -/* -//------------------------------------------------------------------------- -// Some global variables -uint32 GlobalServicesUp=0; -NLMISC_VARIABLE(uint32, GlobalServicesUp, "ServicesUp"); -*/ - -#include "nel/misc/debug.h" - -#include "ai_manager.h" -#include "ai_service.h" -#include "ai_files.h" -#include "messages.h" - -//=================================================================== - -//--------------------------------------------------- -// INSTANTIATED CLASS: Public methods - -// a few read accessors -NLNET::TServiceId CAIService::id() const -{ - // compute the index of this AIService class instance in the array of - // CAIService (this is stored in the _services array) - return NLNET::TServiceId(this-_services); -} - -bool CAIService::isUp() const -{ - return _isUp; -} - - -uint CAIService::powerCPU() const -{ - return _powerCPU; -} - -uint CAIService::powerRAM() const -{ - return _powerRAM; -} - - -// assign a given manager to this service (ie open and run it) -void CAIService::assignMgr(sint mgrId) -{ - // get a pointer to the manager in question - CAIManager *m=CAIManager::getManagerById(mgrId); - if (m==NULL) - return; - - // if this method has not been called by the manager's own method then ping pong - if (!m->isAssigned()) - { - m->assign(id()); - return; - } - - // if the manager is assigned to a different service then bomb - if (m->serviceId()!=id()) - { - nlwarning("Cannot assign manager %04d (%s) to service %d as it is already assigned to service %d", - mgrId, m->name().c_str(), id().get(), m->serviceId().get()); - return; - } - - // if the service is up then send it a message to launch the manager - if (isUp()) - { - // std::string dataBuf - // dataBuf.resize(binFileSize(id())); - // FILE *f=fopen(binFileName(id()),"rb"); - // if (f==NULL) - // { - // nlinfo("Failed to load action list file: %s (try 'aiMake')",binFileName(id())); - // return false; - // } - // if (fread(dataBuf.buffer(),1,binFileSize(id()),f) != binFileSize(id())) - // { - // nlinfo("Read error in binary file: %s",binFileName(id())); - // return false; - // } - // fclose(f); - // CMsgAIUploadActions(id(),dataBuf).send(); -// CMsgAIOpenMgrs(mgrId,m->name()).send(id()); - m->setIsUp(true); - - // return true; - } - // return false; -} - - -// unassign a manager currently running on this service (ie close it) -void CAIService::unassignMgr(sint mgrId) -{ - // if the manager isn't assigned to this service then bomb - if (CAIManager::getManagerById(mgrId)->serviceId()!=id()) - { - nlwarning("Cannot stop manager %04d (%s) on service %d as it is assigned to service %d", - mgrId, CAIManager::getManagerById(mgrId)->name().c_str(), id().get(), CAIManager::getManagerById(mgrId)->serviceId().get()); - return; - } - - // transfer control to the singleton to finish the work - closeMgr(mgrId); -} - - -// reassign a manager currently assigned to this service to another service -void CAIService::reassignMgr(sint mgrId, NLNET::TServiceId serviceId) -{ - // get a pointerto the service - CAIService *s=getServiceById(serviceId); - if (s==NULL) - return; - - // this is a very simple implementation of control transfer... should be revised later - unassignMgr(mgrId); - s->assignMgr(mgrId); -} - - - -//--------------------------------------------------- -// INSTANTIATED CLASS: Private methods - -CAIService::CAIService() -{ - // if the following assert fails it's because a CAIService object has - // been instantiated outside of the singleton's array - nlassert(id().get() < maxServices()); -} - - -//=================================================================== -// *** END OF THE INSTANTIATED CLASS *** START OF THE SINGLETON *** -//=================================================================== - - -//--------------------------------------------------- -// SINGLETON: Data - -class CAIService CAIService::_services[RYAI_AI_SERVICE_MAX_SERVICES]; - - - - -//--------------------------------------------------- -// SINGLETON: Public methods - -// get the number of allocated managers -uint CAIService::numServices() -{ - uint count=0; - for (uint i=0;i= maxServices()) - { - nlwarning("CAIService::getServiceById(id): id %d not in range 0..%d",id.get(),maxServices()-1); - return NULL; - } - return &(_services[NLNET::TServiceId8(id).get()]); -} - - -// get a pointer to the manager with given index (0..numManagers-1) -CAIService *CAIService::getServiceByIdx(uint idx) -{ - uint count=0; - for (uint i=0;i=maxServices (%d)",idx,count); - return NULL; -} - - -// select a service to assign the manager to and assign it -// if no services are available then the manager is queued until one -// becomes available -// managers opened via this interface are queued back up and re-launched -// if their service goes down -void CAIService::openMgr(sint mgrId) -{ - // get a pointer to the manager in question - CAIManager *m=CAIManager::getManagerById(mgrId); - if (m==NULL) - return; - m->setIsOpen(true); -} - - -// close a manager (on whichever service its running) -void CAIService::closeMgr(sint mgrId) -{ - // get a pointer to the manager in question - CAIManager *m=CAIManager::getManagerById(mgrId); - if (m==NULL) - return; - - // if the manager is flagged as up and running on a service then shut it down - if (m->isUp()) - { - CAIService *s=getServiceById(m->serviceId()); - if (s!=NULL && s->isUp()) - { - // send a message to the service to stop the manager - CMsgAICloseMgrs(mgrId).send(m->serviceId()); - } - // clear the manager's isUp() flag - m->setIsUp(false); - } - - // if the manager is assigned to a service then transfer control to the manager's close() - if (m->isAssigned()) - m->close(); -} - -// update routine called by service_main update every net loop -void CAIService::update() -{ - #define IN_TRANSIT_PACKET_LIMIT 1 - - for (uint i=0;iisOpen() && !m->isAssigned()) - if (m->weightRAM()<=s._unusedPowerRAM && m->weightCPU()<=s._unusedPowerCPU) - if (m->weightRAM()+m->weightCPU()/2>=bestScore) - { - best=j; - bestScore=m->weightRAM()+m->weightCPU()/2; - } - } - // if we found a manager then go ahead and assign it - if (best!=~0u) - s.assignMgr(best); - } - - // if we have data waiting to be sent then send it - while (!s._dataToSend.empty() && s._dataSentCount-s._dataAckCountsend( s.id(), *(s._dataToSend.begin()) ); - s._dataToSend.pop_front(); - s._dataSentCount++; - } - } - } - - #undef IN_TRANSIT_PACKET_LIMIT -} - - -//=================================================================== diff --git a/code/ryzom/server/src/ai_data_service/ai_service.h b/code/ryzom/server/src/ai_data_service/ai_service.h deleted file mode 100644 index 4b7c021c9..000000000 --- a/code/ryzom/server/src/ai_data_service/ai_service.h +++ /dev/null @@ -1,148 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AI_SERVICE_H -#define RYAI_AI_SERVICE_H - -#define RYAI_AI_SERVICE_MAX_SERVICES 256 - - -#include "nel/misc/types_nl.h" -#include "nel/net/message.h" -#include "nel/net/unified_network.h" - -#include - - -/* - --------------------------------------------------------------------------- - - This class defines both the singleton that manages the ai services and the - class type of the ai services themselves. The singleton interface can be found - at the end of the class - - --------------------------------------------------------------------------- -*/ - -class CAIService -{ - -//=================================================================== -// *** START OF THE INSTANTIATED CLASS *** -//=================================================================== - - -public: - //--------------------------------------------------- - // INSTANTIATED CLASS: Public methods - - // a few read accessors - NLNET::TServiceId id() const; - bool isUp() const; - - uint powerCPU() const; - uint powerRAM() const; - - // assign a given manager to this service (ie open and run it) - void assignMgr(sint mgrId); - - // unassign a manager currently running on this service (ie close it) - void unassignMgr(sint mgrId); - - // reassign a manager currently assigned to this service to another service - void reassignMgr(sint mgrId, NLNET::TServiceId serviceId); - - -private: - //--------------------------------------------------- - // INSTANTIATED CLASS: Private methods - - CAIService(); // may only be instantiated by the singleton - - -private: - //--------------------------------------------------- - // INSTANTIATED CLASS: Private data - - bool _isUp; // flag says the service is up - - uint _powerCPU; // maximum CPU weight allowed on service - uint _powerRAM; // maximum RAM weight allowed on service - - uint _unusedPowerCPU; // remaining CPU capacity (after counting weight of running managers) - uint _unusedPowerRAM; // remaining RAM capacity (after counting weight of running managers) - - uint _dataSentCount; // number of data packets sent to service - uint _dataAckCount; // number of data acknowledges received from service - - // vector of buffers of data that are waiting to be sent to the service - std::list _dataToSend; - -//=================================================================== -// *** END OF THE INSTANTIATED CLASS *** START OF THE SINGLETON *** -//=================================================================== - - -public: - //--------------------------------------------------- - // SINGLETON: Public methods - - // get the number of valid handles (ie the maximum number of managers allowed) - static uint maxServices() { return RYAI_AI_SERVICE_MAX_SERVICES; } - - // get the number of allocated managers - static uint numServices(); - - // get a pointer to the manager with given handle (0..maxManagers-1) - static CAIService *getServiceById(NLNET::TServiceId id); - - // get a pointer to the manager with given index (0..numManagers-1) - static CAIService *getServiceByIdx(uint idx); - - // select a service to assign the manager to and assign it - // if no services are available then the manager is queued until one - // becomes available - // managers opened via this interface are queued back up and re-launched - // if their service goes down - static void openMgr(sint mgrId); - - // close a manager (on whichever service its running) - static void closeMgr(sint mgrId); - - // update routine called by service_main update every net loop - static void update(); - -private: - //--------------------------------------------------- - // SINGLETON: Private methods - - -private: - //--------------------------------------------------- - // SINGLETON: Private data - static class CAIService _services[RYAI_AI_SERVICE_MAX_SERVICES]; - - -//=================================================================== -// *** END OF THE SINGLETON *** -//=================================================================== - -}; - - -#endif diff --git a/code/ryzom/server/src/ai_data_service/aids_actions.cpp b/code/ryzom/server/src/ai_data_service/aids_actions.cpp deleted file mode 100644 index face248fc..000000000 --- a/code/ryzom/server/src/ai_data_service/aids_actions.cpp +++ /dev/null @@ -1,261 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -//---------------------------------------------------------------------------- - -#include "nel/misc/command.h" -#include "nel/misc/debug.h" -#include "nel/misc/config_file.h" -#include "nel/misc/path.h" -#include "nel/net/service.h" -#include "aids_actions.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - - -//---------------------------------------------------------------------------- -// Stuff for debug message logging -//---------------------------------------------------------------------------- - -static bool verboseLog=false; -#define TAB toString("%*s",CurrentMgrDfnNodes.size()*4,"").c_str() -#define TAB1 toString("%*s",CurrentMgrDfnNodes.size()*4-4,"").c_str() -#define LOG if (!verboseLog) {} else nlinfo - -NLMISC_COMMAND(verboseAIDSActionLog,"Turn on or off or check the state of verbose AIDSAction parser logging","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (verboseLog, args[0]); - - nlinfo("verboseAIDSActionLogging is %s",verboseLog?"ON":"OFF"); - return true; -} - - -//---------------------------------------------------------------------------- -// Singleton data instantiation -//---------------------------------------------------------------------------- - -CAIDSActions *CAIDSActions::Instance=NULL; -uint CAIDSActions::CurrentManager=0; - - -//---------------------------------------------------------------------------- -// Local utility functions and variables -//---------------------------------------------------------------------------- - -static uint BadParseDepth=0; -static CAIManager::SMgrDfnNode DefaultNode; -static std::vector CurrentMgrDfnNodes; -static bool FoundAIData=false; -static std::string FileName; - -static void Prepare(CAIManager::SMgrDfnNode &node) -{ - // recurse through children - for (uint i=0;iConfigFile.getVarPtr(std::string("IgnorePrimitives")); - std::vector ignoreFiles; - for (uint i=0;isize();++i) - ignoreFiles.push_back(CFile::getFilenameWithoutExtension(varPtr->asString(i))); - - //append this file to the vector and pass it back to the config file manager for storage - ignoreFiles.push_back(NLMISC::CFile::getFilenameWithoutExtension(fileName)); - varPtr->setAsString(ignoreFiles); - IService::getInstance()->ConfigFile.save(); - } -} - -void CAIDSActions::begin(const std::string &contextName) -{ - LOG("%s{ // %s",TAB,contextName.c_str()); - uint i; - - // if we've encountered a parse problem just count levels of indentation - if (BadParseDepth) - { - ++BadParseDepth; - return; - } - - // if the CurrentMgrDfnNodes vector is empty then we must be parsing a new manager - if (CurrentMgrDfnNodes.empty()) - { - nlinfo("- Parsing: %s",contextName.c_str()); - - // update variables used in this source file (AIDS_ACTIONS.CPP) - FoundAIData=true; - CurrentMgrDfnNodes.push_back(&(CAIManager::getManagerById(CurrentManager)->MgrDfnRootNode)); - CurrentMgrDfnNodes[0]->Name=contextName; - - // reset the 'visited' flags for the manager's data tree - Prepare(*CurrentMgrDfnNodes[0]); - CurrentMgrDfnNodes[0]->Visited=true; - - // copy the default dfn nodes to the current node and add a 'set_slot' action - CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; - for (uint i=0;iData.push_back(DefaultNode.Data[i]); - // add a set_slot action with value uint slot id = CurrentManager - std::vector args; - args.push_back(CAIActions::CArg(CurrentManager)); - curNode->Data.push_back(CAIManager::SMgrDfnElm(*(uint64*)"SET_SLOT",args)); - } - else - { - CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; - - // try to find a node with the name matching contextName - // if there are a number of nodes with the same name then this code should work ok as - // it uses the 'visited' flags to avoid multi-use of same node slot - CAIManager::SMgrDfnNode *node=NULL; - for (i=0;iChild.size();++i) - if ((curNode->Child[i]->Name.empty() || curNode->Child[i]->Name==contextName) && !curNode->Child[i]->Visited) - { - node=(curNode->Child[i]); - break; - } - - // if need be allocate a new data node - if (i==curNode->Child.size()) - { - curNode->Child.push_back(new CAIManager::SMgrDfnNode(contextName)); - node=curNode->Child[i]; - } - - // add a set_slot action with value uint slot id = i - std::vector args; - args.push_back(CAIActions::CArg(i)); - curNode->Child[i]->Data.push_back(CAIManager::SMgrDfnElm(*(uint64*)"SET_SLOT",args)); - - // update variables used in this source file (AIDS_ACTIONS.CPP) - CurrentMgrDfnNodes.push_back(node); - node->Visited=true; - } -} - -void CAIDSActions::end(const std::string &contextName) -{ - LOG("%s} // %s",TAB1,contextName.c_str()); - - // if we've encountered a parse problem just count levels of indentation - if (BadParseDepth) - { - --BadParseDepth; - return; - } - - // make sure the name of the context that we're closing matches the name of the context that we opened - CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; - nlassert(contextName==curNode->Name); - - // close this context - CurrentMgrDfnNodes.pop_back(); - - // if we've finished then do some housekeeping - if (CurrentMgrDfnNodes.empty()) - { - // run back through tree stripping out unvisitted entries - Clean(*curNode); - } -} - -void CAIDSActions::execute(uint64 action,const std::vector &args) -{ - // if we've encountered a parse problem don't execute... - if (BadParseDepth) - { - return; - } - - // generate a string to describe the action - std::string txt; - txt+=toString("%-8.8s",&action); - txt+='('; - for (uint i=0;iData.push_back(CAIManager::SMgrDfnElm(action,args)); -} - diff --git a/code/ryzom/server/src/ai_data_service/aids_actions.h b/code/ryzom/server/src/ai_data_service/aids_actions.h deleted file mode 100644 index 9f843ebd7..000000000 --- a/code/ryzom/server/src/ai_data_service/aids_actions.h +++ /dev/null @@ -1,78 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AIDS_ACTIONS_H -#define RYAI_AIDS_ACTIONS_H - -#include "ai_share/ai_actions.h" -#include "ai_manager.h" -#include - -class CAIDSActions: public CAIActions::IExecutor -{ -public: - //---------------------------------------------------------------------------- - // init & release - - static void init() - { - if (Instance==NULL) - Instance=new CAIDSActions; - CAIActions::init(Instance); - } - static void release() - { - if (Instance!=NULL) - { - CAIActions::release(); - delete Instance; - Instance=NULL; - } - } - - //---------------------------------------------------------------------------- - // inheritted virtual interface - - virtual void openFile(const std::string &fileName); - virtual void closeFile(const std::string &fileName); - virtual void begin(const std::string &contextName); - virtual void end(const std::string &contextName); - virtual void execute(uint64 action,const std::vector &args); - - virtual void begin(uint32 context) {} - virtual void end(uint32 context) {} - - //---------------------------------------------------------------------------- - // public singleton data - - static uint CurrentManager; - -private: - //---------------------------------------------------------------------------- - // This is a singleton class so make constructor private - CAIDSActions() {} - ~CAIDSActions() {} - - //---------------------------------------------------------------------------- - // the singleton class instance - static CAIDSActions *Instance; -}; - - -#endif - diff --git a/code/ryzom/server/src/ai_data_service/aids_spawn_ctrl.cpp b/code/ryzom/server/src/ai_data_service/aids_spawn_ctrl.cpp deleted file mode 100644 index 44a68928d..000000000 --- a/code/ryzom/server/src/ai_data_service/aids_spawn_ctrl.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//------------------------------------------------------------------------- -// Includes & namespaces - -#include "ai_share/ai_spawn_commands.h" - -using namespace NLMISC; -using namespace std; - -// remove stupid VC6 warnings -void foo_aids_spawn_ctrl_cpp() {} - - -//------------------------------------------------------------------------- -// The CAISpawnCtrl sub-class -/* -class CAIDSSpawnCtrl: public CAISpawnCtrl -{ -protected: - virtual bool _spawn(const std::string &name); - virtual bool _spawnMap(const std::string &name); - virtual bool _spawnMgr(const std::string &name); - virtual bool _spawnGrp(const std::string &name); - virtual bool _spawnAll(); - - virtual bool _despawn(const std::string &name); - virtual bool _despawnMap(const std::string &name); - virtual bool _despawnMgr(const std::string &name); - virtual bool _despawnGrp(const std::string &name); - virtual bool _despawnAll(); - -} AIServiceSpawnCtrl; -*/ - -//------------------------------------------------------------------------- -// The CAISpawnCtrl singleton data -//CAISpawnCtrl *CAISpawnCtrl::_instance=&AIServiceSpawnCtrl; - - -//------------------------------------------------------------------------- -// SPAWNING -/* -bool CAIDSSpawnCtrl::_spawn(const std::string &name) -{ - if (_spawnMap(name)) return true; - if (_spawnMgr(name)) return true; - if (_spawnGrp(name)) return true; - return false; -} - -bool CAIDSSpawnCtrl::_spawnGrp(const std::string &name) -{ - nlinfo("*** spawnGrp(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_spawnMgr(const std::string &name) -{ - nlinfo("*** spawnMgr(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_spawnMap(const std::string &name) -{ - nlinfo("*** spawnMap(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_spawnAll() -{ - nlinfo("*** spawnAll() NOT IMPLEMENTED YET ***"); - - return true; -} - - -//------------------------------------------------------------------------- -// DESPAWNING - -bool CAIDSSpawnCtrl::_despawn(const std::string &name) -{ - if (_despawnMap(name)) return true; - if (_despawnMgr(name)) return true; - if (_despawnGrp(name)) return true; - return false; -} - -bool CAIDSSpawnCtrl::_despawnGrp(const std::string &name) -{ - nlinfo("*** despawnGrp(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_despawnMgr(const std::string &name) -{ - nlinfo("*** despawnMgr(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_despawnMap(const std::string &name) -{ - // for each manager if map's name found in the command arguments then spawn() - nlinfo("*** despawnMap(%s) NOT IMPLEMENTED YET ***",name.c_str()); - - return true; -} - -bool CAIDSSpawnCtrl::_despawnAll() -{ - nlinfo("*** despawnAll() NOT IMPLEMENTED YET ***"); - - return true; -} -*/ diff --git a/code/ryzom/server/src/ai_data_service/commands.cpp b/code/ryzom/server/src/ai_data_service/commands.cpp deleted file mode 100644 index 0521c4dde..000000000 --- a/code/ryzom/server/src/ai_data_service/commands.cpp +++ /dev/null @@ -1,258 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -// Nel Misc -#include "nel/net/service.h" -#include "nel/misc/command.h" - -// Game share -#include "game_share/macro_manager.h" - -// locals -#include "ai_files.h" -#include "ai_manager.h" -#include "ai_service.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - - -//------------------------------------------------------------------------- -// utility routines - -static void argsToManagerVector(const vector &args, vector &theManagers) -{ - if(args.size()==0) - { - for (uint i=0;i theManagers; - argsToManagerVector(args,theManagers); - - // do the work - for (uint i=0;ineedCompile()) - { - //nlinfo("Compiling manager: %04d: %s",theManagers[i]->id(),theManagers[i]->name()); - theManagers[i]->compile(); - } - else - nlinfo("Manager is up to date: %04d: %s",theManagers[i]->id(),theManagers[i]->name().c_str()); - } - - return true; -} - -NLMISC_COMMAND(aiClean,"delete all generated files on the hard disk (next 'make' will rebuild everything)","") -{ - COMMAND_MACRO_RECORD_TEST - - // rescan the source and object directories for files - CAIFiles::scan(); - - // build the list of ai managers to act on - vector theManagers; - argsToManagerVector(args,theManagers); - - // do the work - for (uint i=0;iid(),theManagers[i]->name().c_str()); - theManagers[i]->clean(); - } - - return true; -} - -//------------------------------------------------------------------------- - -NLMISC_COMMAND(aiDisplayServices,"list the ai services, their parameters and their lists of running managers","[[...]]") -{ - if(args.size()!=0) return false; - COMMAND_MACRO_RECORD_TEST - - return true; -} - -NLMISC_COMMAND(aiDisplayManagers,"Display the known ai manager list","[[...]]") -{ - COMMAND_MACRO_RECORD_TEST - - // build the list of ai managers to act on - vector theManagers; - argsToManagerVector(args,theManagers); - - // do the work - for (uint i=0;idisplay(); - - return true; -} - -//------------------------------------------------------------------------- -NLMISC_COMMAND(aiOpenAllManagers,"Open all managers and automatically assign to ai services","") -{ - if(args.size()!=0) return false; - COMMAND_MACRO_RECORD_TEST - - for (uint i=0;iisOpen()) - CAIManager::getManagerByIdx(i)->open(); - - return true; -} - -NLMISC_COMMAND(aiOpenManagers,"Open managers and automatically assign to ai services","[...]") -{ - if(args.size()<1) return false; - COMMAND_MACRO_RECORD_TEST - - for (uint i=0;iopen(); - } - - return true; -} - -NLMISC_COMMAND(aiAssignManagers,"Open managers and assign to specified ai service","[...]") -{ - if(args.size()<2) return false; - COMMAND_MACRO_RECORD_TEST - - // convert args[0] to service id and verify existance in services list - NLNET::TServiceId service(atoi(args[0].c_str())); - if (service.get()==0 && args[0]!="0") - { - nlwarning("Invalid service id: %s",args[0].c_str()); - return false; - } - - // iterate through args assigning managers to service - for (uint i=1;iassign(service); - } - - return true; -} - -NLMISC_COMMAND(aiReassignManagers,"Save & close managers on existing services and open on specified ai service","[...]") -{ - if(args.size()<2) return false; - COMMAND_MACRO_RECORD_TEST - - // convert args[0] to service id and verify existance in services list - NLNET::TServiceId service(atoi(args[0].c_str())); - if (service.get()==0 && args[0]!="0") - { - nlwarning("Invalid service id: %s",args[0].c_str()); - return false; - } - - // iterate through args reassigning managers to service - for (uint i=1;ireassign(service); - } - - return true; -} - -//------------------------------------------------------------------------- -NLMISC_COMMAND(aiCloseAllManagers,"Close all managers across all ai services on the shard","") -{ - if(args.size()!=0) return false; - COMMAND_MACRO_RECORD_TEST - - for (uint i=0;iisOpen()) - CAIManager::getManagerByIdx(i)->close(); - - return true; -} - -NLMISC_COMMAND(aiCloseManagers,"Close listed managers","[...]") -{ - if(args.size()<1) return false; - COMMAND_MACRO_RECORD_TEST - - for (uint i=0;iclose(); - } - - return true; -} - -//------------------------------------------------------------------------- diff --git a/code/ryzom/server/src/ai_data_service/dummy_crunch.cpp b/code/ryzom/server/src/ai_data_service/dummy_crunch.cpp deleted file mode 100644 index e1b0605ff..000000000 --- a/code/ryzom/server/src/ai_data_service/dummy_crunch.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "nel/misc/command.h" - -#include "game_share/bmp4image.h" - -#include - -using namespace std; -using namespace NLMISC; - - - -#include - -class CNeighbour -{ - uint SurfaceCell; - uint CellSurfaceIdx; - - uint8 Heading[16][16]; -}; - -class CSurface -{ -public: - CSurface() - { - memset(Points,0,sizeof(Points)); - } - - void addPoint(uint x,uint y) - { - Points[y]|=(1< Neighbours; -}; - -class CCell -{ -public: - sint8 Points[16][16]; // ends up with set of surface ids - std::vector Surfaces; -}; - -void generateSurfaces(char *topLeft,uint lineLen,CCell &cell) -{ - std::stack stack; - uint i,j; - - // fill the points grid with -1 where accessible and -2 where inaccessible - uint goodCount=0, badCount=0; - for (j=0;j<16;++j) - for (i=0;i<16;++i) - if (*(topLeft+i+lineLen*j)==' ') - { - cell.Points[j][i]= -1; - ++goodCount; - } - else - { - cell.Points[j][i]= -2; - ++badCount; - } - - // flood fill to convert -1s to surface ids - uint surfaceCount=~0u; - for (j=0;j<16;++j) - for (i=0;i<16;++i) - if (cell.Points[j][i]==-1) - { - CSurface *surface=new CSurface; - cell.Surfaces.push_back(surface); - ++surfaceCount; - cell.Points[j][i]=surfaceCount; - stack.push(16*j+i); - while (!stack.empty()) - { - // pop the coordinate off the stack - uint x=stack.top()&0xf; - uint y=stack.top()/16; - stack.pop(); - - // add the point to the surface - surface->addPoint(x,y); - - // look for neighbouring points to add to the same surface - if (x<15 && cell.Points[y][x+1]==-1) { cell.Points[y][x+1]=surfaceCount; stack.push(16*y+ x+1); } - if (x>0 && cell.Points[y][x-1]==-1) { cell.Points[y][x-1]=surfaceCount; stack.push(16*y+ x-1); } - if (y<15 && cell.Points[y+1][x]==-1) { cell.Points[y+1][x]=surfaceCount; stack.push(16*y+16+ x); } - if (y>0 && cell.Points[y-1][x]==-1) { cell.Points[y-1][x]=surfaceCount; stack.push(16*y-16+ x); } - } - surface->displayPoints(); - } - nlinfo("Generated %i surfaces, %i accessible cell.Points, %i inaccessible cell.Points",surfaceCount+1,goodCount,badCount); - for (j=0;j<16;++j) - { - char txt[17]; - for (i=0;i<16;++i) - txt[i]=(cell.Points[j][i]>=0 && cell.Points[j][i]<=9)? cell.Points[j][i]+'0': '#'; - txt[16]=0; - nlinfo("- surfaces: %s", txt); - } -} - -static void generateSurfaceNeighbourhoods( - CCell *tl, CCell *tm, CCell *tr, - CCell *ml, CCell *mm, CCell *mr, - CCell *bl, CCell *bm, CCell *br) -{ - // todo here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - // generate horizontal neighbours - - // generate vertical neighbours - - // * add propagation maps to the surfaces - // for each surface propagate out following neighbour map -} - -NLMISC_COMMAND(dummyCrunch,"Run a test of pacs crunch","") -{ - if(args.size()!=0) - return false; - - char testMap[]= - "0000000000000000111111111111111100000000000000001111111111111111" - "0000000000000000111111111111111100000000000000001111111111111111" - "0000000000000000111111111111111100000000000000001111111111111111" - "000 111000 111" - "000 111" - "000 111000 111" - "000 00000000001111111111 111000 00000000001111111111 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 000000000011111 1 111000 000000000011111 1 111" - "000 000000011111 1 111000 000000011111 1 111" - "222 222222233333 3 333222 222222233333 3 333" - "222222222222222233333 3 333222222222222222233333 3 333" - "222 3 333222 3 333" - "222 3 3 333" - "222 2222222222223333333333 333222 2222222222223333333333 333" - "22222 33322222 333" - "222 333222 333" - "222 333222 333" - "222222222222222233333333333333332222222222 22223333333333333333" - "22222222222222223 32222222222 22223333333333333333" - "22222222222222223 333333333333 32222222222 22223333333333333333" - "22222222222222223 33 33 32222222222 22223333333333333333" - "22222222222222223 33 32222222222 22223333333333333333" - "22222222222222223333 33 32222222222 22223333333333333333" - "222222222222222233333 333 2222 22223333333333333333" - "222222222222222233333333 33333322222 2222 22223333333333333333" - "0000000000000000111111111 1111100000 0000 00001111111111111111" - "00000000000000001111111111 111100000 0000 00001111111111111111" - "000000000000000011111111111 11100000 0000 00001111111111111111" - "000 11000 111" - "000 1000 111" - "000 1 000 111" - "000 00000000001111111111 11 00 00000000001111111111 111" - "000 1 111 0 1 111" - "000 1 1110 1 111" - "000 1 11100 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 1 111000 1 111" - "000 000000000011111 1 111000 000000000011111 1 111" - "000 000000011111 1 111000 000000011111 1 111" - "222 222222233333 3 333222 222222233333 3 333" - "222222222222222233333 3 333222222222222222233333 3 333" - "222 3 333222 3 333" - "222 3 333222 3 333" - "222 2222222222223333333333 333222 2222222222223333333333 333" - "22222 33322222 333" - "222 333222 333" - "222 333222 333" - "2222222222222222333333333333333322222222222222223333333333333333" - "2222 222222222333 333333322 2222233 333" - "22222 22222222223333 33 33333333222 22 22 222222333 3 33333 3333" - "22222 22222222223333 33 33333333222 22 22 222222333 33 333 33333" - "22222 22222222223333 33 33333333222 22 22 222222333 333 3 333333" - "22222 22222222223333 33 33333333222 22 22 222222333 3333 3333333" - "2222 222222222333 333333322 2222233 333" - "2222222222222222333333333333333322222222222222223333333333333333"; - - - int i,j; - - // need to create a dummy cell that links into the cell grid in all slots as - // default value -// *** here *** - - // setup a 4x4 cell grid in a 6x6 grid surrounded by NULLs - typedef CCell *TCellRef; - TCellRef cells[6][6]; - memset (cells,0,sizeof(cells)); - for (j=0;j<4;++j) - for (i=0;i<4;++i) - cells[j+1][i+1]=new CCell; - - // generate surfaces - for (j=0;j<4;++j) - for (i=0;i<4;++i) - generateSurfaces(testMap+i*16+j*64*16,64,*cells[j+1][i+1]); - - // generate surface neighbourhoods - for (j=0;j<4;++j) - for (i=0;i<4;++i) - generateSurfaceNeighbourhoods( - cells[1+j-1][1+i-1], cells[1+j-1][1+i+0], cells[1+j-1][1+i+1], - cells[1+j+0][1+i-1], cells[1+j+0][1+i+0], cells[1+j+0][1+i+1], - cells[1+j+1][1+i-1], cells[1+j+1][1+i+0], cells[1+j+1][1+i+1] - ); - - return true; -} diff --git a/code/ryzom/server/src/ai_data_service/messages.cpp b/code/ryzom/server/src/ai_data_service/messages.cpp deleted file mode 100644 index dc35ea660..000000000 --- a/code/ryzom/server/src/ai_data_service/messages.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -// include files -#include "nel/misc/types_nl.h" - -#include "messages.h" -//#include "actor_manager.h" - -using namespace NLMISC; -using namespace NLNET; - - -//------------------------------------------------------------------------- -// singleton initialisation and release - -void CMessages::init() -{ - // incoming messages - TRANSPORT_CLASS_REGISTER( CMsgAIServiceUp ); - TRANSPORT_CLASS_REGISTER( CMsgAIManagerUp ); - TRANSPORT_CLASS_REGISTER( CMsgAIFeedback ); - - TRANSPORT_CLASS_REGISTER( CMsgAICloseMgrs ); - TRANSPORT_CLASS_REGISTER( CMsgAIBackupMgrs ); -} - -void CMessages::release() -{ -} - - -//------------------------------------------------------------------------- -// incoming message callbacks - -void CMsgAIServiceUp::callback (const std::string &serviceName, NLNET::TServiceId sid) -{ - nlinfo("AI Service Up: %02d (CPU rating: %f RAMrating %f)", sid.get(), ProcessorAllocation,RamAllocation); - for (uint i=0;i -// 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 . - - - -#ifndef RYAI_MESSAGES_H -#define RYAI_MESSAGES_H - -#include "ai_share/aids_messages.h" -#include "ai_share/ais_messages.h" - -class CMessages -{ -public: - // singleton initialisation and release - static void init(); - static void release(); -}; - - -#endif diff --git a/code/ryzom/server/src/ai_data_service/notes.txt b/code/ryzom/server/src/ai_data_service/notes.txt deleted file mode 100644 index 8455f26cb..000000000 --- a/code/ryzom/server/src/ai_data_service/notes.txt +++ /dev/null @@ -1,9 +0,0 @@ -x1. make: identify primitive files and display 'compile (%s)' -x2. link up the compiler - dump contents of the primitive file to console -3. create the binary file to send to the ais & save to disk (with hierachy) -4. setup messages between AIS & AIDS ( & remote ctrl ) - - - -static file name ids? -*** 2 places ais creates gpms message \ No newline at end of file diff --git a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp b/code/ryzom/server/src/ai_data_service/pacs_scan.cpp deleted file mode 100644 index 796ce7b78..000000000 --- a/code/ryzom/server/src/ai_data_service/pacs_scan.cpp +++ /dev/null @@ -1,2976 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -// Nel misc -#include "nel/misc/command.h" -#include "nel/misc/variable.h" - -#include "nel/misc/common.h" -#include "nel/misc/aabbox.h" -#include "nel/misc/vector.h" -#include "nel/misc/vectord.h" -#include "nel/misc/i_xml.h" -#include "nel/misc/array_2d.h" -// TMP TMP -#include "nel/misc/bitmap.h" - - -#include "nel/misc/algo.h" - - -// Nel pacs -#include "nel/pacs/u_collision_desc.h" -#include "nel/pacs/u_global_position.h" -#include "nel/pacs/u_global_retriever.h" -#include "nel/pacs/u_move_container.h" -#include "nel/pacs/u_move_primitive.h" -#include "nel/pacs/u_retriever_bank.h" -#include "nel/pacs/u_primitive_block.h" - -#include "nel/pacs/global_retriever.h" - - -// Nel Ligo -#include "nel/ligo/ligo_config.h" -#include "nel/ligo/primitive.h" - - -// Server share -#include "game_share/bmp4image.h" -#include "server_share/continent_container.h" - - -// AI share -#include "ai_share/world_map.h" -#include "ai_share/ai_spawn_commands.h" - - -// STL -#include -#include - - -using namespace std; -using namespace NLMISC; -using namespace NLPACS; -using namespace RYAI_MAP_CRUNCH; -using namespace NLLIGO; - -extern CLigoConfig LigoConfig; - -//CAISpawnCtrl *CAISpawnCtrl::_instance=NULL; - -string EvaluatedPos; - -/// The start point for each continent -multimap StartPoints; -multimap PrimFiles; -CVectorD DefaultStartPoint = CVectorD::Null; - -/// The output path -string OutputPath = string("./"); -vector PacsPrimPath; -vector LookupPath; -vector LookupNoRecursePath; -bool PathInitialized = false; - -CWorldMap StaticWorldMap; -uint Verbose = 1; -CVectorD BoxMin, BoxMax; - - -namespace RYPACSCRUNCH -{ - -class CPacsCruncher -{ -public: - - CContinentContainer _Continents; - - URetrieverBank *_Bank; - UGlobalRetriever *_Retriever; - UMoveContainer *_Container; - UMovePrimitive *_Primitive; - UMovePrimitive *_Primitive3; - UMovePrimitive *_Primitive5; - - CWorldMap _WorldMap; - - deque _Positions1; - deque _Positions3; - deque _Positions5; - - CVectorD _BMin; - CVectorD _BMax; - CVectorD _BSize; - - uint32 _RetrieverWidth; - uint32 _RetrieverHeight; - uint32 _RetrieverArea; - - typedef std::map TPacsPrimMap; - static TPacsPrimMap _PacsPrimMap; - -protected: - - CSlot getSurfaceAfterMove(UGlobalPosition &pos, const CMapPosition &newPosition, uint maxGabarit) - { - CVectorD target = newPosition.toVectorD()+CVectorD(0.1, 0.1, 0.0); - CVectorD motion = target - _Retriever->getDoubleGlobalPosition(pos); - - motion.z = 0.0; - - UMovePrimitive *prims[3] = { _Primitive, _Primitive3, _Primitive5 }; - sint gabarit; - CSlot slot; - - for (gabarit=maxGabarit; gabarit>=0; --gabarit) - { - UMovePrimitive *prim = prims[gabarit]; - - prim->setGlobalPosition(pos, 0); - prim->move(motion, 0); - //_Container->evalNCPrimitiveCollision(1.0, prim, 0); - _Container->evalCollision(1.0, 0); - - UGlobalPosition newPos; - prim->getGlobalPosition(newPos, 0); - - // DEBUG HERE - // - CVectorD dpos = _Retriever->getDoubleGlobalPosition(pos); - CVectorD dnpos = _Retriever->getDoubleGlobalPosition(newPos); - - //bool test = (static_cast(_Retriever))->testPosition(newPos); - bool test=true; - - NLPACS::CGlobalRetriever* gRetriever = static_cast(_Retriever); - - if (newPos.InstanceId < 0 || newPos.InstanceId >= (sint)gRetriever->getInstances().size()) - test=false; - - const CRetrieverInstance & instance = gRetriever->getInstances()[newPos.InstanceId]; - - if (!instance.getBBox().include(newPos.LocalPosition.Estimation + instance.getOrigin())) - test=false; - else - { - const CLocalRetriever & lRetriever = gRetriever->getRetriever(instance.getRetrieverId()); - - if (!lRetriever.isLoaded()) - test=false; - else if (newPos.LocalPosition.Surface < 0 || newPos.LocalPosition.Surface >= (sint)lRetriever.getSurfaces().size()) - { - nlwarning("can't test inexistant surface %d", newPos.LocalPosition.Surface); - test=false; - } - else if (fabs(newPos.LocalPosition.Estimation.x) >= 256.0 || fabs(newPos.LocalPosition.Estimation.y) >= 256.0) - test=false; - } - - if (!test) - { - if (Verbose) - nlinfo("Move from pos(%d,%d,%f,%f/%f,%f) motion(%f,%f) -> pos(%d,%d,%f,%f/%f,%f) %s", pos.InstanceId, pos.LocalPosition.Surface, pos.LocalPosition.Estimation.x, pos.LocalPosition.Estimation.y, dpos.x, dpos.y, motion.x, motion.y, newPos.InstanceId, newPos.LocalPosition.Surface, newPos.LocalPosition.Estimation.x, newPos.LocalPosition.Estimation.y, dnpos.x, dnpos.y, test ? "succeded" : "failed"); - return slot; - } - // - // - - CVectorD dmotion = dpos+motion-dnpos; - dmotion.z = 0.0; - - // if the move was not accomplished successfully return '3' as "direction blocked" - if ( dmotion.norm() > 1.0e-2 ) - continue; - - CMapPosition checkPosition(_Retriever->getDoubleGlobalPosition(newPos)); - nlassert(newPosition == checkPosition); - - CUnitSlot surfId(newPos); - TCellUnit &slots = _WorldMap.getCellUnit(newPosition); - - // locate a slot to stick the surface in - bool newSlot = false; - for (slot=CSlot(0); slot.isValid(); ++slot) - { - CUnitSlot& unitSlot=slots[slot.slot()]; - if (!unitSlot.used()) - { - unitSlot = surfId; - unitSlot.setHeight((uint)floor(dnpos.z/2.0 + 0.5)); - unitSlot.setInterior(_Retriever->isInterior(newPos)); - float waterHeight; - unitSlot.setWater(_Retriever->isWaterPosition(newPos, waterHeight)); - unitSlot.setGabarit(gabarit); - if (gabarit==0) _Positions1.push_back(newPos); - else if (gabarit==1) _Positions3.push_back(newPos); - else _Positions5.push_back(newPos); - newSlot = true; - break; - } - else if (unitSlot.hasSameSurface(surfId)) - { - break; - } - } - - break; - } - return slot; - } - - void readPrimitive(IPrimitive *primitive, const std::string &insertAt) - { - if (dynamic_cast(primitive) != NULL) - { - CPrimZone *prim = static_cast(primitive); - uint i; - for (i=0; iVPoints.size(); ++i) - { - StartPoints.insert(multimap::value_type(insertAt, prim->VPoints[i])); - } - } - else if (dynamic_cast(primitive) != NULL) - { - CPrimPoint *prim = static_cast(primitive); - StartPoints.insert(multimap::value_type(insertAt, prim->Point)); - } - else if (dynamic_cast(primitive) != NULL) - { - CPrimPath *prim = static_cast(primitive); - uint i; - for (i=0; iVPoints.size(); ++i) - { - StartPoints.insert(multimap::value_type(insertAt, prim->VPoints[i])); - } - } - - // parse children - uint i; - for (i=0; igetNumChildren(); ++i) - { - IPrimitive *child; - - if (!primitive->getChild(child, i)) - continue; - - readPrimitive(child, insertAt); - } - } - - - void readStartupPrims(const std::string &continent) - { - pair::iterator, multimap::iterator> rng; - rng = PrimFiles.equal_range(continent); - - multimap::iterator it; - for (it=rng.first; it!=rng.second; ++it) - { - string prim = (*it).second; - - CIFile f(CPath::lookup(prim)); - CIXml xml; - - CPrimitives prims; - - // load xml file - xml.init(f); - nlinfo("Loaded prim file '%s'", prim.c_str()); - - // read nodes - if (!prims.read(xml.getRootNode(), prim.c_str(), LigoConfig)) - { - nlwarning("Can't use primitive file '%s', xml parse error", prim.c_str()); - continue; - } - } - } - - - -public: - - CPacsCruncher() : _Bank(NULL), _Retriever(NULL), _Container(NULL) - { - } - - void initPackedSheets() - { - if (!PathInitialized) - { - uint i; - for (i=0; igetBBox(); - nlinfo("%s rbox: %.1f,%.1f - %.1f,%.1f", name.c_str(), rBox.getMin().x, rBox.getMin().y, rBox.getMax().x, rBox.getMax().y); - - // compute new box - CAABBox useBox; - if (constraintBox) - { - CVector vmin, vmax; - vmin.maxof(constraintBox->getMin(), rBox.getMin()); - vmax.minof(constraintBox->getMax(), rBox.getMax()); - useBox.setMinMax(vmin, vmax); - } - else - { - useBox = rBox; - } - - useBox.setMinMax(CVector((float)floor(useBox.getMin().x), (float)floor(useBox.getMin().y), (float)floor(useBox.getMin().z)), - CVector((float)ceil(useBox.getMax().x), (float)ceil(useBox.getMax().y), (float)ceil(useBox.getMax().z))); - - nlinfo("Use Box: (%.3f,%.3f)-(%.3f,%.3f)", useBox.getMin().x, useBox.getMin().y, useBox.getMax().x, useBox.getMax().y); - - // setup the grid of surface ids per location - _RetrieverWidth = (uint32)(useBox.getSize().x+1.0); - _RetrieverHeight = (uint32)(useBox.getSize().y+1.0); - _RetrieverArea = _RetrieverWidth*_RetrieverHeight; - - // clear the world map object - _WorldMap.clear(); - - // setup the UMovePrimitive - _Primitive = _Container->addCollisionablePrimitive(0, 1); - _Primitive->setPrimitiveType( UMovePrimitive::_2DOrientedCylinder ); - _Primitive->setReactionType( UMovePrimitive::Stop ); - _Primitive->setTriggerType((UMovePrimitive::TTrigger)UMovePrimitive::NotATrigger); - _Primitive->setCollisionMask( 0xffffffff ); - _Primitive->setOcclusionMask( 0x00000000 ); - _Primitive->setObstacle( true ); - _Primitive->setAbsorbtion( 0 ); - _Primitive->setHeight( 6.0f ); - _Primitive->setRadius( 0.5f ); - - _Primitive3 = _Container->addCollisionablePrimitive(0, 1); - _Primitive3->setPrimitiveType( UMovePrimitive::_2DOrientedCylinder ); - _Primitive3->setReactionType( UMovePrimitive::Stop ); - _Primitive3->setTriggerType((UMovePrimitive::TTrigger)UMovePrimitive::NotATrigger); - _Primitive3->setCollisionMask( 0xffffffff ); - _Primitive3->setOcclusionMask( 0x00000000 ); - _Primitive3->setObstacle( true ); - _Primitive3->setAbsorbtion( 0 ); - _Primitive3->setHeight( 6.0f ); - _Primitive3->setRadius( 1.5f ); - - _Primitive5 = _Container->addCollisionablePrimitive(0, 1); - _Primitive5->setPrimitiveType( UMovePrimitive::_2DOrientedCylinder ); - _Primitive5->setReactionType( UMovePrimitive::Stop ); - _Primitive5->setTriggerType((UMovePrimitive::TTrigger)UMovePrimitive::NotATrigger); - _Primitive5->setCollisionMask( 0xffffffff ); - _Primitive5->setOcclusionMask( 0x00000000 ); - _Primitive5->setObstacle( true ); - _Primitive5->setAbsorbtion( 0 ); - _Primitive5->setHeight( 6.0f ); - _Primitive5->setRadius( 2.5f ); - - _BMin = useBox.getMin(); - _BMax = useBox.getMax(); - - if (BoxMin != CVectorD::Null) - { - if (BoxMin.x > _BMin.x) _BMin.x = BoxMin.x; - if (BoxMin.x > _BMin.x) _BMin.x = BoxMin.x; - } - - if (BoxMax != CVectorD::Null) - { - if (BoxMax.x < _BMax.x) _BMax.x = BoxMax.x; - if (BoxMax.x < _BMax.x) _BMax.x = BoxMax.x; - } - - _BSize = _BMax-_BMin; - - // setup a start position for the primitive - CVectorD zoneCentre = useBox.getCenter(); - zoneCentre.z = 0.0; - - vector startPoints; - pair::iterator, multimap::iterator> range = StartPoints.equal_range(name); - multimap::iterator itsp; - for (itsp=range.first; itsp!=range.second; ++itsp) - startPoints.push_back((*itsp).second); - - if (startPoint != NULL) - { - startPoints.push_back(*startPoint); - startPoints.back().z = 0.0; - } - - if (DefaultStartPoint != CVectorD::Null) - { - startPoints.push_back(DefaultStartPoint); - startPoints.back().z = 0.0; - } - - if (startPoints.empty()) - { - startPoints.push_back(zoneCentre); - } - - - // init time counter - CGlobalRetriever *cgr = (CGlobalRetriever*)_Retriever; - - uint sz = 0; - uint ic; - for (ic = 0; icgetInstances().size(); ++ic) - { - const CRetrieverInstance &inst = cgr->getInstance(ic); - sz += (uint)(inst.getBBox().getHalfSize().x*inst.getBBox().getHalfSize().y*0.6f)*4; - } - - nlinfo("Estimated %d iterations", sz); - uint count=0; - - while (!startPoints.empty()) - { - zoneCentre = startPoints.back(); - startPoints.pop_back(); - - CMapPosition firstIndex = CMapPosition(zoneCentre); - zoneCentre = firstIndex.toVectorD(); - - nlinfo("Start scan at %.1f,%.1f", zoneCentre.x, zoneCentre.y); - - _Positions5.clear(); - _Positions3.clear(); - _Positions1.clear(); - - _Primitive->setGlobalPosition(zoneCentre, 0); - _Container->evalCollision(1.0, 0); - _Primitive3->setGlobalPosition(zoneCentre, 0); - _Container->evalCollision(1.0, 0); - _Primitive5->setGlobalPosition(zoneCentre, 0); - _Container->evalCollision(1.0, 0); - - // setup and intialise the positions to visit stack - _Positions5.push_back(UGlobalPosition()); - _Primitive->getGlobalPosition(_Positions5[0], 0); - - { - TCellUnit &slots = _WorldMap.getCellUnit(firstIndex); - CUnitSlot surfId(_Positions5[0]); - - // locate a slot to stick the surface in - bool newSlot = true; - CSlot slot; - for (slot=CSlot(0); slot.isValid(); ++slot) - { - CUnitSlot& unitSlot=slots[slot.slot()]; - - if (unitSlot.hasSameSurface(surfId)) - { - newSlot = false; - break; - } - } - - if (!newSlot) - continue; - - CWorldPosition worldPosition(_WorldMap.getWorldPositionGeneration(firstIndex,CSlot(0))); - _WorldMap.getUnitSlot(worldPosition) = CUnitSlot(_Positions5[0]); - _WorldMap.getUnitSlot(worldPosition).setGabarit(2); - } - - uint xmaxreached = 0, - xminreached = 0, - ymaxreached = 0, - yminreached = 0; - - TTime startTime = CTime::getLocalTime(); - - uint countGabarits[3] = { 0, 0, 0 }; - - while (!_Positions5.empty() || !_Positions3.empty() || !_Positions1.empty()) - { - // pop the next postion to test off the stack - UGlobalPosition refPos; - - if (!_Positions5.empty()) - { - refPos = _Positions5.front(); - _Positions5.pop_front(); - } - else if (!_Positions3.empty()) - { - refPos = _Positions3.front(); - _Positions3.pop_front(); - } - else - { - refPos = _Positions1.front(); - _Positions1.pop_front(); - } - - if (!(count&0xfff)) - { - TTime itime = CTime::getLocalTime(); - - UGlobalPosition nextPos = refPos; - CVectorD dpos = _Retriever->getDoubleGlobalPosition(nextPos); - - double persec = (double)count*1000.0 / (double)(itime-startTime); - sint toGo = sz-count; - double ttoGo = (double)toGo/persec; - sint elapsed = (sint)((itime-startTime)/1000); - - nlinfo("crunchPacsMap: %d iterations (%d,%d,%d) (%dpct, estimated %s, %s to go) - start at (%d,%d,%f,%f-%f,%f)", count, countGabarits[0], countGabarits[1], countGabarits[2], count*100/sz, secToString(elapsed+(sint)ttoGo).c_str(), secToString((sint)ttoGo).c_str(), nextPos.InstanceId, nextPos.LocalPosition.Surface, nextPos.LocalPosition.Estimation.x, nextPos.LocalPosition.Estimation.y, dpos.x, dpos.y); - } - ++count; - - if (!(count&0xffff) && count>0) - { - //buildBMP("temp_"+name+toString(count)); - } - - CVectorD pos = _Retriever->getDoubleGlobalPosition(refPos); -// EvaluatedPos = toString(refPos.InstanceId)+","+toString(refPos.LocalPosition.Surface)+":"+toString(pos.x)+","+toString(pos.y)+","+toString(pos.z); -/* - CVectorD d = pos - CVectorD(1045.0, -6086.0, 0.0); - d.z = 0.0f; - if (d.norm() < 0.5f) - nlinfo("Bla"); -*/ - CMapPosition refIndex(pos); - - TCellUnit &slots = _WorldMap.getCellUnit(refIndex); - uint slot; - - CUnitSlot refSlot(refPos); - - for (slot=0; slot<3 && !slots[slot].hasSameSurface(refSlot); ++slot) - ; - - if (slot >= 3) - { - nlwarning("Failed to find point in surface slots"); - continue; - } - - uint gabarit = slots[slot].gabarit(); - - nlassert(gabarit <= 2); - ++countGabarits[gabarit]; - - - // check out eastern cell and OR east move into neighbour grid - if (pos.x + 1.0 <= _BMax.x) - slots[slot].cellLink().setESlot(getSurfaceAfterMove(refPos, refIndex.getStepE(), gabarit)); - else - ++xmaxreached; - - // check out westtern cell and OR west move into neighbour grid - if (pos.x - 1.0 >= _BMin.x) - slots[slot].cellLink().setWSlot(getSurfaceAfterMove(refPos, refIndex.getStepW(), gabarit)); - else - ++xminreached; - - // check out southern cell and OR south move into neighbour grid - if (pos.y + 1.0 <= _BMax.y) - slots[slot].cellLink().setNSlot(getSurfaceAfterMove(refPos, refIndex.getStepN(), gabarit)); - else - ++ymaxreached; - - // check out northern cell and OR north move into neighbour grid - if (pos.y - 1.0 >= _BMin.y) - slots[slot].cellLink().setSSlot(getSurfaceAfterMove(refPos, refIndex.getStepS(), gabarit)); - else - ++yminreached; - } - nlinfo("crunchPacsMap: performed %d iterations",count); - } - - - if (count > 1) - { - //filter(); - //checkMap(_WorldMap, true); - - COFile f(OutputPath+name+".wmap"); - - f.serial(_WorldMap); - } - - // HOUSEKEEPING - _Container->removePrimitive(_Primitive); - _Container->removePrimitive(_Primitive3); - _Container->removePrimitive(_Primitive5); - - if (!keep) - { - release(); - } - - _WorldMap.clear(); - } - - void buildGabarit(const string &name, uint gabarit) - { - nlinfo("building gabarit %d map...", gabarit); - - _WorldMap.clear(); - CIFile f(OutputPath+name+".wmap"); - f.serial(_WorldMap); - - checkMap(_WorldMap); - filter(); - checkMap(_WorldMap, true); - - CMapPosition min, max; - _WorldMap.getBounds(min, max); - - CMapPosition scan, scanline; - - for (scan = min; scan.y() != max.y(); scan = scan.stepCell(0, 1)) - { - for (scanline = scan; scanline.x() != max.x(); scanline = scanline.stepCell(1, 0)) - { - //scanline = CMapPosition(0x0380, 0x2650); - - if (!_WorldMap.exist(scanline)) - continue; - - const CComputeCell *cc = const_cast(_WorldMap).getComputeCellCst(scanline); - - uint slot, i, j; - - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - CMapPosition pos=scanline; - pos.setUnitId(j,i); - - TCellUnit &slots = _WorldMap.getCellUnit(pos); - - for (slot=0; slot<3; ++slot) - { - CUnitSlot &unitSlot=slots[slot]; - - // if slot is used but not accessible for my gabarit, reset it - if (unitSlot.getCellLink().used() && unitSlot.gabarit()(_WorldMap).getComputeCellCst(scanline); - - CRootCell *newCell = NULL; - - if (cell == NULL) - continue; - - CMapPosition pos; - - uint i, j; - bool failed = false; - bool white = true; - for (i=0; i<16 && !failed; ++i) - { -// char buff[17]; - for (j=0; j<16 && !failed; ++j) - { - bool sl0 = cell->isSlotUsed(pos, CSlot(0)); - bool sl1 = cell->isSlotUsed(pos, CSlot(1)); - bool sl2 = cell->isSlotUsed(pos, CSlot(2)); - - pos = scanline; - pos.setUnitId(j,i); - const TCellUnit &cunit = cell->getCellUnitCst(pos); - uint32 used = cell->maxUsedSlot(pos); - if (used>=1) - failed = true; - else if (used>0) - white = false; - - if (white && cunit[0].getCellLink().getLinks() != 0) - white = false; - - if (!failed && !white && cunit[0].getCellLink().used()) - { - if ((!cunit[0].getCellLink().isNSlotValid() && _WorldMap.isSlotUsed(pos.getStepN(), CSlot(0))) || - (!cunit[0].getCellLink().isSSlotValid() && _WorldMap.isSlotUsed(pos.getStepS(), CSlot(0))) || - (!cunit[0].getCellLink().isESlotValid() && _WorldMap.isSlotUsed(pos.getStepE(), CSlot(0))) || - (!cunit[0].getCellLink().isWSlotValid() && _WorldMap.isSlotUsed(pos.getStepW(), CSlot(0)))) - failed = true; - } - - if (sl0 && (cunit[0].interior() /*|| cunit[0].water()*/ || cunit[0].topology() != 0)) - white = false; - } - -// buff[16] = '\0'; -// nlinfo("Dump: %s", buff); - } - - uint32 used; - - pos = scanline.getStepS(); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepE()) - if ((used = _WorldMap.maxUsedSlot(pos)) >= 1) - failed = true; - else if (used != 0) - white = false; - - pos = scanline.getStepW(); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepN()) - if ((used = _WorldMap.maxUsedSlot(pos)) >= 1) - failed = true; - else if (used != 0) - white = false; - - pos = scanline.stepCell(0, 1); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepE()) - if ((used = _WorldMap.maxUsedSlot(pos)) >= 1) - failed = true; - else if (used != 0) - white = false; - - pos = scanline.stepCell(1, 0); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepN()) - if ((used = _WorldMap.maxUsedSlot(pos)) >= 1) - failed = true; - else if (used != 0) - white = false; - - if (!failed && white) - { - // replace the compute cell by a white cell - CWhiteCell *wcell = new CWhiteCell(_WorldMap); - wcell->setTopologiesNodes(cell->getTopologiesNodes()); - - // build height map - CFull16x16Layer *heightMap = new CFull16x16Layer(); - for (i=0; i<16; ++i) - for (j=0; j<16; ++j) - heightMap->set(i, j, cell->getHeight(_WorldMap.getWorldPositionGeneration(CMapPosition(j, i),CSlot(0)))); - - wcell->setHeightMap(I16x16Layer::compress(heightMap, 0x7fffffff)); - - newCell = wcell; - -// _WorldMap.setRootCell(scanline, wcell); - } - else if (!failed) - { - // replace the compute cell by a single layer cell - CSingleLayerCell *slcell = new CSingleLayerCell(_WorldMap); - - uint maxtopo = 0; - - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - pos = scanline; - pos.setUnitId(j,i); - - sint maxs = cell->maxUsedSlot(pos); - nlassert(maxs == 0 || maxs == -1); - slcell->setPos(pos, cell->isSlotUsed(pos, CSlot(0))); - - uint topology=cell->getTopology(_WorldMap.getWorldPositionGeneration(pos,CSlot(0))); - if (topology>maxtopo) - maxtopo=topology; - } - - } - - if (maxtopo == 0) - { - slcell->setTopologies(NULL); - } - else if (maxtopo == 1) - { - C1Bit16x16Layer *layer = new C1Bit16x16Layer(); - - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - pos = scanline; - pos.setUnitId(j,i); - - layer->set(i, j, cell->getTopology(_WorldMap.getWorldPositionGeneration(pos,CSlot(0)))); - } - } - - slcell->setTopologies(layer); - } - else - { - C8Bits16x16Layer *layer = new C8Bits16x16Layer(); - - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - pos = scanline; - pos.setUnitId(j,i); - - layer->set(i, j, cell->getTopology(_WorldMap.getWorldPositionGeneration(pos,CSlot(0)))); - } - } - - slcell->setTopologies(layer); - } - - pos = scanline.getStepS(); - for (i=0; i<16; ++i, pos = pos.getStepE()) - { - sint maxs = cell->maxUsedSlot(pos); - nlassert(maxs == 0 || maxs == -1); - slcell->setSLink(i, _WorldMap.maxUsedSlot(pos) == 0); - } - - pos = scanline.getStepW(); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepN()) - { - sint maxs = cell->maxUsedSlot(pos); - nlassert(maxs == 0 || maxs == -1); - slcell->setWLink(i, _WorldMap.maxUsedSlot(pos) == 0); - } - - pos = scanline.stepCell(0, 1); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepE()) - { - sint maxs = cell->maxUsedSlot(pos); - nlassert(maxs == 0 || maxs == -1); - slcell->setNLink(i, _WorldMap.maxUsedSlot(pos) == 0); - } - - pos = scanline.stepCell(1, 0); - for (i=0; i<16 && !failed; ++i, pos = pos.getStepN()) - { - sint maxs = cell->maxUsedSlot(pos); - nlassert(maxs == 0 || maxs == -1); - slcell->setELink(i, _WorldMap.maxUsedSlot(pos) == 0); - } - - slcell->setTopologiesNodes(cell->getTopologiesNodes()); - - // build height map - CFull16x16Layer *heightMap = new CFull16x16Layer(); - for (i=0; i<16; ++i) - for (j=0; j<16; ++j) - heightMap->set(i, j, slcell->isSlotUsed(CMapPosition(j, i), CSlot(0)) ? cell->getHeight(_WorldMap.getWorldPositionGeneration(CMapPosition(j,i),CSlot(0))) : - 0x7fffffff); - - slcell->setHeightMap(I16x16Layer::compress(heightMap, 0x7fffffff)); - - newCell = slcell; - -// _WorldMap.setRootCell(scanline, slcell); - } - else - { - // build multi layer - - CMultiLayerCell *mlcell = new CMultiLayerCell(_WorldMap); - - uint32 slot; - - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - pos = scanline; - pos.setUnitId(j,i); - - for (slot=0; slot<3; ++slot) - { - CWorldPosition wp = _WorldMap.getWorldPositionGeneration(pos,CSlot(slot)); - const CUnitSlot &uslot = cell->getUnitSlotCst(wp); - if (uslot.getCellLink().used()) - { - mlcell->setLinks(wp, uslot.getCellLink()); - mlcell->setTopology(wp, uslot.topology()); - } - } - } - } - - // build height map - CFull16x16Layer *heightMap[3] = { NULL, NULL, NULL }; - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - for (slot=0; slot<3; ++slot) - { - CFull16x16Layer* heightMapPt=heightMap[slot]; - - if (mlcell->isSlotUsed(CMapPosition(j, i), CSlot(slot))) - { - if (!heightMapPt) - { - heightMapPt=new CFull16x16Layer(); - heightMap[slot]=heightMapPt; - } - nlassert(heightMapPt); - heightMapPt->set(i, j, cell->getHeight(_WorldMap.getWorldPositionGeneration(CMapPosition(j, i), CSlot(slot)))); - } - else - { - if (heightMapPt) - heightMapPt->set(i, j, 0x7fffffff); - } - } - } - } - - for (slot=0; slot<3; ++slot) - if (heightMap[slot] != NULL) - mlcell->setHeightMap(CSlot(slot), I16x16Layer::compress(heightMap[slot], 0x7fffffff)); - - mlcell->setTopologiesNodes(cell->getTopologiesNodes()); - - newCell = mlcell; - } - - nlassert(newCell != NULL); - - pos = scanline; - uint32 slot; - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - pos.setUnitId(j, i); - - for (slot=0; slot<3; ++slot) - { - CWorldPosition wpos = _WorldMap.getWorldPositionGeneration(pos, CSlot(slot)); - bool sused = cell->isSlotUsed(pos, CSlot(slot)), - nsused = newCell->isSlotUsed(pos, CSlot(slot)); - nlassert(sused == nsused); - - if (cell->isSlotUsed(pos, CSlot(slot))) - { - CCellLinkage lnk=cell->getCellLink(wpos), - nlnk=newCell->getCellLink(wpos); - uint top=cell->getTopology(wpos), - ntop=newCell->getTopology(wpos); - if (failed || !white) - nlassert(cell->getCellLink(wpos).getLinks() == newCell->getCellLink(wpos).getLinks()); - nlassert(cell->getHeight(wpos) == newCell->getHeight(wpos)); - nlassert(cell->getTopology(wpos) == newCell->getTopology(wpos)); - } - } - } - } - - _WorldMap.setRootCell(scanline, newCell); - } - } - - checkMap(_WorldMap); - - buildMotionLayers(); - -// nlassert(false); - COFile out(OutputPath+name+".cwmap2"); - out.serial(_WorldMap); - } - - void checkMap(CWorldMap &wmap, bool fix=false) - { - nlinfo("Checking Wmap link integrity..."); - - CMapPosition min, max; - _WorldMap.getBounds(min, max); - - CMapPosition posy; - - for (posy=min; posy.y() toposcount; - - struct CTopoGrid - { - sint getTopo(const CSlot &slot) const - { - return topos[slot.slot()]; - } - sint topos[3]; - bool testGrid; - }; - CTopoGrid toposGridList[16][16]; - - for (scan = min; scan.y() != max.y(); scan = scan.stepCell(0, 1)) - { - for (scanline = scan; scanline.x() != max.x(); scanline = scanline.stepCell(1, 0)) - { - if (!_WorldMap.exist(scanline)) - continue; - - //scanline = CMapPosition(0x02e0, 0xd440); - - CComputeCell *cell = _WorldMap.getComputeCell(scanline); - - { - for (uint i = 0; i < 16; ++i) - { - for (uint j = 0; j < 16; ++j) - { - toposGridList[i][j].topos[0] = - toposGridList[i][j].topos[1] = - toposGridList[i][j].topos[2] = -1; - } - } - } - - uint i = 0; // current topo - - CMapPosition sp = scanline; - sp.setUnitId(0,0); - - uint spx, spy, spslot; - - for (spy=0; spy<16; ++spy) - { - for (spx=0; spx<16; ++spx) - { - sp.setUnitId(spx, spy); - - for (spslot=0; spslot<3; ++spslot) - { - if (!cell->isSlotUsed(sp, CSlot(spslot))) - continue; - - CTopoGrid &topoGrid=toposGridList[sp.yCoord().getUnitId()][sp.xCoord().getUnitId()]; - sint &curTopos=topoGrid.topos[spslot]; - - if (curTopos<0) - { - - { // -- clean flood fill table -- - uint gi, gj; - for (gi=0; gi<16; ++gi) - for (gj=0; gj<16; ++gj) - toposGridList[gi][gj].testGrid=false; - } // ---------------------------- - - topoGrid.testGrid=true; - curTopos=i; - - CUnitSlot &unitslot = _WorldMap.getUnitSlot(_WorldMap.getWorldPosition(sp,CSlot(spslot))); - - unitslot.setTopology(i); - - bool interior = unitslot.interior(); - bool water = unitslot.water(); - bool nogo = unitslot.nogo(); - - CVector totalPos(0.0f, 0.0f, 0.0f); - uint totalElm = 0; - - vector stack; - stack.push_back(_WorldMap.getWorldPosition(sp, CSlot(spslot))); - - bool topoHasNeighb = false; - - while (!stack.empty()) - { - CWorldPosition wp(stack.back()); - stack.pop_back(); - - totalPos+=CVector(wp.toVectorD()); - ++totalElm; - - static const CDirection::TDirection dirs[] = - { - CDirection::W, - CDirection::E, - CDirection::S, - CDirection::N - }; - - - for (uint dir=0; dir<4; ++dir) - { - const CDirection direction=CDirection(dirs[dir]); - CWorldPosition tm(wp); - uint x = tm.xCoord().getUnitId()+direction.dx(); - uint y = tm.yCoord().getUnitId()+direction.dy(); - - //InfoLog->displayRaw("Test move from %4X,%4X,%d to %4X,%4X", tm.x(), tm.y(), tm.slot(), tm.x()+direction.dx(), tm.y()+direction.dy()); - - // store if move succeded - bool mvres = _WorldMap.move(tm, direction); - -/* - bool test1 = false; - bool test2 = false; - bool test3 = false; - bool test4 = false; - bool test5 = false; - bool test6 = false; - bool test7 = false; - - // check move is on same cell, and position hasn't been visited (nor in same topo or in another) - // and moves in same kind of floor - if ( (test1 = ((x&0xf0)==0)) - && (test2 = ((y&0xf0)==0)) - && (test3 = (!toposGridList[y][x].testGrid)) - && (test4 = (mvres)) - && (test5 = (toposGridList[y][x].topos[tm.slot()]<0)) - && (test6 = (_WorldMap.getUnitSlot(tm).interior() == interior)) - && (test7 = (_WorldMap.getUnitSlot(tm).water() == water))) -*/ - - if ( ((x&0xf0)==0) - && ((y&0xf0)==0) - && (!toposGridList[y][x].testGrid) - && (mvres) - && (toposGridList[y][x].topos[tm.slot()]<0) - && (_WorldMap.getUnitSlot(tm).interior() == interior) - && (_WorldMap.getUnitSlot(tm).water() == water) - && (_WorldMap.getUnitSlot(tm).nogo() == nogo) ) - { - toposGridList[y][x].testGrid=true; - toposGridList[y][x].topos[tm.slot()] = i; - _WorldMap.getUnitSlot(tm).setTopology(i); - stack.push_back(tm); - // fakes move result so if on same topo, doesn't add a neighbour - mvres = false; - - //InfoLog->displayRawNL(" SUCCESS"); - } - else - { - //InfoLog->displayRawNL(" FAILED (test1=%d test2=%d test3=%d test4=%d test5=%d test6=%d test7=%d)", test1, test2, test3, test4, test5, test6, test7); - } - - if (mvres) - topoHasNeighb = true; - } - } - - if (topoHasNeighb) - { - CTopology &topology = cell->getTopologyNode(i); - topology.Id = CTopology::TTopologyId(scanline, i); - topology.Position = totalPos/(float)totalElm; - topology.Flags = (interior ? Interior : 0) | (water ? Water : 0) | (nogo ? NoGo : 0); - - //nlinfo("Topology %08X %04X", topology.Id.getVal(), topology.Flags); - - ++i; - } - else - { - nlinfo("Unactivated topo %d in cell (%4X,%4X)",i, scanline.x()&0xffff, scanline.y()&0xffff); - uint i, j, s; - for (i=0; i<16; ++i) - { - for (j=0; j<16; ++j) - { - for (s=0; s<3; ++s) - { - if (toposGridList[i][j].topos[s] == (sint)i) - { - CMapPosition errp = scanline; - errp.setUnitId(j, i); - _WorldMap.resetUnitSlot(_WorldMap.getWorldPosition(errp, CSlot(s))); - toposGridList[i][j].topos[s] = 0xffff; - } - } - } - } - } - } - } - } - } - - if (i>50) - nlstop; - - if (i>maxtopo) - maxtopo = i; - - if (i >= toposcount.size()) - toposcount.resize(i+1); - - toposcount[i]++; - } - } - - nlinfo("Found %d topologies maximum", maxtopo); - uint i; - for (i=0; i 5000) - { - startTime = CTime::getLocalTime(); - nlinfo("buildMotionLayers: %d pct done...", compCells*100/total); - } - - // - //scanline = CMapPosition(0x3A40, 0x8330); - - if (!_WorldMap.exist(scanline)) - continue; - - //if (scanline.x() == 4436 && scanline.y() == -4240) - // nlstop; - - ++compCells; - - CRootCell *cell = _WorldMap.getRootCell(scanline); - uint topo = 0; - uint maxtopo = 0; - const CMapPosition mincell = scanline.stepCell(-1, -1), - maxcell = scanline.stepCell( 2, 2); - - while (true) - { - CMotionTrace fillGrid[16*3][16*3][3]; - - bool found = false; - uint stx = 0, sty = 0; - uint32 stsl=0; - CMapPosition sp = scanline; - const CMapPosition soffset = sp.stepCell(-1, -1); - - set visited; - - const CTopology::TTopologyId startTId(scanline, topo); - - for (sty=0; sty<16; ++sty) - { - for (stx=0; stx<16; ++stx) - { - sp.setUnitId(stx,sty); - - for (stsl=0; stsl<3; ++stsl) - { - if (!cell->isSlotUsed(sp, CSlot(stsl))) - continue; - - CWorldPosition stwp = _WorldMap.getWorldPosition(sp, CSlot(stsl)); - const uint topology=cell->getTopology(stwp); - - if (topology>maxtopo && topology<0x80) - maxtopo=topology; - - // find a point in the current topo - if (topology==topo && fillGrid[sty+16][stx+16][stsl].distance == 0xffffffff) - { - // this point exists, is not marked in fill grid and belongs to the current topo - found = true; - - // - // HERE: use multimap instead of vector so the position stack is always sorted, and thus - // the flood fill should be minimal (Dijkstra like graph route) - // - //vector stack; - multimap stacks[5]; - - // mark start point - CMotionTrace &first = fillGrid[sp.y()-soffset.y()][sp.x()-soffset.x()][stsl]; - first.dx = 0; - first.dy = 0; - first.distance = 0; - const CTopology& topNode = stwp.getTopologyRef().getCstTopologyNode(); - first.flags = (topNode.isInWater() ? 1 : 0) + (topNode.isInNogo() ? 2 : 0); - - // push first position - stacks[first.flags].insert(std::pair(first.flags, stwp)); - - while (true) - { - uint stack; - for (stack=0; stack<5; ++stack) - if (!stacks[stack].empty()) - break; - if (stack == 5) - break; - - CWorldPosition next((*(stacks[stack].begin())).second); - stacks[stack].erase(stacks[stack].begin()); - - const CTopology& nextNode = next.getTopologyRef().getCstTopologyNode(); - uint8 nextflags = (nextNode.isInWater() ? 1 : 0) + (nextNode.isInNogo() ? 2 : 0); - - CTopology::TTopologyRef nextTId(next); - - sint cdist = fillGrid[next.y()-soffset.y()][next.x()-soffset.x()][next.slot()].distance; - - if ( nextTId != startTId - && cdist<=CDirection::MAX_COST) // check if it is a touching topology - visited.insert(nextTId); - - uint dir; - for (dir=0; dir<8; ++dir) - { - CWorldPosition tmp(next); - - CDirection direction((CDirection::TDirection)dir); - - if (_WorldMap.moveSecure(tmp,direction)) - { - // don't move more than 1 cell - if ( tmp.x() < mincell.x() - || tmp.x() >= maxcell.x() - || tmp.y() < mincell.y() - || tmp.y() >= maxcell.y()) - continue; - - // check we can move back - CDirection opp = direction; - opp.addStep(CDirection::HALF_TURN); - CWorldPosition checkBackMove(tmp); - if (!_WorldMap.move(checkBackMove, opp)) - { - nlwarning("Can't move back from pos (%d,%d,%d) to pos (%d,%d,%d)", - next.x(), next.y(), next.slot(), - tmp.x(), tmp.y(), tmp.slot()); - continue; - } - else if (checkBackMove != next) - { - - if (Verbose) - nlwarning("Reverse move from pos (%d,%d,%d) to pos (%d,%d,%d) gave a different path", - next.x(), next.y(), next.slot(), - tmp.x(), tmp.y(), tmp.slot()); - continue; - } - - const CTopology& tmpNode = tmp.getTopologyRef().getCstTopologyNode(); - uint8 tmpflags = (tmpNode.isInWater() ? 1 : 0) + (tmpNode.isInNogo() ? 2 : 0); -/* - if (tmpNode.Id != nextNode.Id) - nlinfo("tamere"); - - if (tmpflags != 0) - nlinfo("blabla"); -*/ - - uint ndist = (_WorldMap.getTopology(tmp)==topo && tmp.hasSameFullCellId(sp) ) ? 0 : cdist+direction.getWeight(); - - CMotionTrace& motionTrace = fillGrid[tmp.y()-soffset.y()][tmp.x()-soffset.x()][tmp.slot()]; - - uint forbid = nextflags & (~tmpflags); - if ((motionTrace.distance == 0xffffffff) || - (forbid == 0 && motionTrace.distance > ndist)) - { - /*nlinfo("stack=%d ndist=%d move from (%04X,%04X,%d - topo=%08X,flags=%d) to (%04X,%04X,%d - topo=%08X,flags=%d) - %d %d %d %d", - stack, ndist, - next.x(), next.y(), next.slot(), nextNode.Id.getVal(), nextflags, - tmp.x(), tmp.y(), tmp.slot(), tmpNode.Id.getVal(), tmpflags, - stacks[0].size(), stacks[1].size(), stacks[2].size(), stacks[3].size());*/ - - motionTrace.distance = ndist; - if (ndist == 0) - { - motionTrace.dx = - motionTrace.dy = 0; - } - else - { - motionTrace.dx=-direction.dx(); - motionTrace.dy=-direction.dy(); - } - if (tmp.getTopologyNode().Id == topNode.Id) - { - stacks[0].insert(std::pair(ndist, tmp)); - } - else - { - stacks[tmpflags + 1].insert(std::pair(ndist, tmp)); - } - } - } - } - } - } - } - } - } - - if (found) - { - // generate direction map for this topo - CDirectionMap *dmap = new CDirectionMap(); - - uint x, y, s; - for (s=0; s<3; ++s) - { - CDirectionLayer* directionLayer=dmap->Layers[s]; - - for (y=0; y<16*3; ++y) - { -// char output[256]; - for (x=0; x<16*3; ++x) - { -// static const char ht[]= "0123456789ABCDEF"; - CMotionTrace &motionTrace=fillGrid[y][x][s]; - -// output[x] = ht[motionTrace.distance&15]; - - if (motionTrace.distance != 0xffffffff) - { - // create CDirectionLayer if it do not exists - if (!directionLayer) - { - directionLayer = new CDirectionLayer(); - nlassert(directionLayer!=NULL); - dmap->Layers[s] = directionLayer; - } - - CGridDirectionLayer* dirLayer=directionLayer->getGridLayer(y>>4,x>>4); - - // create CGridDirectionLayer if it do not exists - if (!dirLayer) - { - directionLayer->setGridLayer(y>>4,x>>4, new C4Bits16x16Layer()); - dirLayer=directionLayer->getGridLayer(y>>4,x>>4); - nlassert(dirLayer); - } - dirLayer->setDirection(y&15, x&15, (motionTrace.dx == 0 && motionTrace.dy == 0 ? CDirection(CDirection::UNDEFINED) : CDirection(motionTrace.dx,motionTrace.dy))); - } - - } -// output[x] = '\0'; -// nlinfo("%s", output); - } - - } - - for (s=0; s<3; ++s) - { - CDirectionLayer* directionLayer=dmap->Layers[s]; - - if (!directionLayer) - continue; - - for (y=0; y<3; ++y) - { - for (x=0; x<3; ++x) - { - CGridDirectionLayer *layer=directionLayer->getGridLayer(y,x); - - if (layer==NULL) - continue; - - uint i, j; - uint cmotion = 15; - bool different = false; - - for (i=0; i<16 && !different; ++i) - { - for (j=0; j<16 && !different; ++j) - { - uint nm = layer->get(i, j); - if (cmotion != 15 && nm != 15 && nm != cmotion) - { - different = true; - } - else if (nm != 15) - { - cmotion = layer->get(i, j); - } - - } - - } - - if (!different) - { - CWhite16x16Layer *nlayer = new CWhite16x16Layer(); - - nlayer->set (0, 0, cmotion); - - delete directionLayer->getGridLayer(y,x); - directionLayer->setGridLayer(y,x,nlayer); - } - - } - - } - - } - -// dmap->dump(); - - cell->setDirectionMap(dmap, topo); - - CTopology &topology = cell->getTopologyNode(topo); - - topology.Id = CTopology::TTopologyId(scanline, topo); - topology.Neighbours.clear(); - - set::iterator it; - for (it=visited.begin(); it!=visited.end(); ++it) - { - CTopology::TTopologyRef topId(*it); - const CTopology &node = topId.getCstTopologyNode(); // _WorldMap.getTopologyNode(topId) - float Norm=(topology.Position-node.Position).norm(); - topology.Neighbours.push_back(CTopology::CNeighbourLink(topId, Norm)); - } - } - else if (Verbose) - { - nlwarning("Topo %d not found, probably not accessible, left unchecked", topo); - } - - ++topo; - - if (topo > maxtopo) - break; - } - } - } - - for (scan = min; scan.y() != max.y(); scan = scan.stepCell(0, 1)) - { - for (scanline = scan; scanline.x() != max.x(); scanline = scanline.stepCell(1, 0)) - { - if (!_WorldMap.exist(scanline)) - continue; - - CRootCell *cell = _WorldMap.getRootCell(scanline); - if (cell == NULL) - continue; - - vector &tops = cell->getTopologiesNodes(); - uint i, j; - - // for all topologies in cell - for (i=0; i::iterator it; - - // look for all neighbours - for (it=node.Neighbours.begin(); it!=node.Neighbours.end();) - { - // and check that it is a neighbour of the neighbour - const CTopology &neighb = (*it).getTopologyRef().getCstTopologyNode(); - for (j=0; j::SHdr imageHdr(imageWidth, imageHeight); - CBMP4Image<2,2>::SPalette imagePalette; - - FILE *outf = nlfopen(OutputPath+name+".bmp", "wb"); - - if (outf == NULL) - return; - - uint16 BM = 0x4D42; - imagePalette.setupForCol(); - fwrite((void *)&BM, 1, sizeof(BM), outf); - fwrite((void *)&imageHdr, 1, sizeof(imageHdr), outf); - fwrite((void *)&imagePalette, 1, sizeof(imagePalette), outf); - - uint8 *lineBuffer = new uint8[imageWidth/2]; - memset(lineBuffer, 255, imageWidth/2); - - CMapPosition scanpos(min.x(),min.y()); - uint x, y; - - const CWorldMap *wmap = &_WorldMap; - - for (y=0; ygetRootCellCst(pos); - - if (cell != NULL) - { - uint ns; - for (ns=0; ns<3; ++ns) - { - CWorldPosition wp = _WorldMap.getSafeWorldPosition(pos, CSlot(ns)); - - if (!wp.isValid()) - continue; - - ++slot; - - CCellLinkage links = cell->getCellLink(wp); - sint32 height = cell->getHeight(wp); - uint8 cl = 0; - - if (!links.isESlotValid()) ++cl; - if (!links.isWSlotValid()) ++cl; - if (!links.isSSlotValid()) ++cl; - if (!links.isNSlotValid()) ++cl; - - if (cl > color) - color = cl; - - if (height > colorHM) - colorHM = height; - } - } - - pointBuffer = ((pointBuffer<<4) | (color+((uint8)slot<<2))); - - if (x & 1) - { - *(linePtr++) = pointBuffer; - } - - pos = pos.getStepE(); - } - scanpos = scanpos.getStepN(); - - fwrite((void*)lineBuffer, 1, imageWidth/2, outf); - } - - fclose(outf); - delete [] lineBuffer; - } - - - - // - void buildBitMap(const string &name) - { -// nlassert(false); - nlinfo("building bitmap..."); - - _WorldMap.clear(); - string ext = CFile::getExtension(name); - if (ext.empty()) - ext = "cwmap2"; - CIFile f(OutputPath+CFile::getFilenameWithoutExtension(name)+"."+ext); - f.serial(_WorldMap); - - uint compute = 0, white = 0, simple = 0, multi = 0, other = 0; - _WorldMap.countCells(compute, white, simple, multi, other); - uint total = compute+white+simple+multi+other; - - nlinfo("%d cells : compute=%d, white=%d, simple=%d, multi=%d, other=%d", total, compute, white, simple, multi, other); - - nlinfo("Build bmp..."); - - CMapPosition min, max; - _WorldMap.getBounds(min, max); - - uint scanWidth = max.x()-min.x(); - uint scanHeight = max.y()-min.y(); - - uint imageWidth = (scanWidth+15)&~15; - uint imageHeight = (scanHeight); - - CBMP4Image<2,2>::SHdr imageHdr(imageWidth, imageHeight); - CBMP4Image<2,2>::SPalette imagePalette; - - FILE *outf = nlfopen(OutputPath+name+".bmp", "wb"); - FILE *outfh = nlfopen(OutputPath+name+"_hm.bmp", "wb"); - - if (outf == NULL) - return; - - uint16 BM = 0x4D42; - imagePalette.setupForCol(); - fwrite((void *)&BM, 1, sizeof(BM), outf); - fwrite((void *)&imageHdr, 1, sizeof(imageHdr), outf); - fwrite((void *)&imagePalette, 1, sizeof(imagePalette), outf); - - imagePalette.setupHueCircle(); - fwrite((void *)&BM, 1, sizeof(BM), outfh); - fwrite((void *)&imageHdr, 1, sizeof(imageHdr), outfh); - fwrite((void *)&imagePalette, 1, sizeof(imagePalette), outfh); - - uint8 *lineBuffer = new uint8[imageWidth/2]; - memset(lineBuffer, 255, imageWidth/2); - - uint8 *lineBufferHM = new uint8[imageWidth/2]; - memset(lineBufferHM, 255, imageWidth/2); - - CMapPosition scanpos(min.x(),min.y()); - uint x, y; - - const CWorldMap *wmap = &_WorldMap; - - CTGAImage tgaImage; - - tgaImage.setup((uint16)imageWidth, (uint16)imageHeight, OutputPath+name+".tga", (uint16)min.x(), (uint16)-max.y()); - tgaImage.setupForCol(); - - for (y=0; ygetRootCellCst(pos); - - if (cell != NULL) - { - uint ns; - for (ns=0; ns<3; ++ns) - { - CWorldPosition wp = _WorldMap.getSafeWorldPosition(pos, CSlot(ns)); - - if (!wp.isValid()) - continue; - - ++slot; - - CCellLinkage links = cell->getCellLink(wp); - sint32 height = cell->getHeight(wp); - uint8 cl = 0; - - if (!links.isESlotValid()) ++cl; - if (!links.isWSlotValid()) ++cl; - if (!links.isSSlotValid()) ++cl; - if (!links.isNSlotValid()) ++cl; - - if (cl > color) - color = cl; - - if (height > colorHM) - colorHM = height; - } - } - - tgaImage.set(x, color+((uint8)slot<<2)); - - pointBuffer = ((pointBuffer<<4) | (color+((uint8)slot<<2))); - pointBufferHM = ((pointBufferHM<<4) | (colorHM & 0xf)); - - if (x & 1) - { - *(linePtr++) = pointBuffer; - *(linePtrHM++) = pointBufferHM; - } - - pos = pos.getStepE(); - } - scanpos = scanpos.getStepN(); - - fwrite((void*)lineBuffer, 1, imageWidth/2, outf); - fwrite((void*)lineBufferHM, 1, imageWidth/2, outfh); - - tgaImage.writeLine(); - } - - fclose(outf); - fclose(outfh); - delete [] lineBuffer; - delete [] lineBufferHM; - - _WorldMap.clear(); - } - - - // build a height map of sint16. Full path should be given for the input cw_map2 - void buildHeightMap16(const string &name) - { -// nlassert(false); - nlinfo("building heightmap for %s", name.c_str()); - - _WorldMap.clear(); - string ext = CFile::getExtension(name); - if (ext.empty()) - ext = "cw_map2"; - - CIFile f(CFile::getPath(name) + CFile::getFilenameWithoutExtension(name)+"."+ext); - f.serial(_WorldMap); - - uint compute = 0, white = 0, simple = 0, multi = 0, other = 0; - _WorldMap.countCells(compute, white, simple, multi, other); - uint total = compute+white+simple+multi+other; - - nlinfo("%d cells : compute=%d, white=%d, simple=%d, multi=%d, other=%d", total, compute, white, simple, multi, other); - - nlinfo("Build bmp..."); - - CMapPosition min, max; - _WorldMap.getBounds(min, max); - - uint scanWidth = max.x()-min.x(); - uint scanHeight = max.y()-min.y(); - - - - CMapPosition scanpos(min.x(),min.y()); - uint x, y; - - const CWorldMap *wmap = &_WorldMap; - - CArray2D heightMap; - heightMap.init(scanWidth, scanHeight); - - sint16 *dest = &heightMap(0, 0); - - for (y=0; ygetRootCellCst(pos); - - if (cell != NULL) - { - uint ns; - for (ns=0; ns<3; ++ns) - { - CWorldPosition wp = _WorldMap.getSafeWorldPosition(pos, CSlot(ns)); - if (!wp.isValid()) - continue; - sint32 newHeight = cell->getHeight(wp); - if (newHeight < (sint16) height) - height = (sint16) newHeight; - } - } - - *dest ++ = height; - pos = pos.getStepE(); - } - scanpos = scanpos.getStepN(); - } - // write result - COFile output(OutputPath + CFile::getFilenameWithoutExtension(name)+".cw_height"); - sint32 xmin = (sint32) min.x(); - sint32 xmax = (sint32) max.x(); - sint32 ymin = (sint32) (sint16) min.y(); - sint32 ymax = (sint32) (sint16) max.y(); - output.serialCheck(NELID("OBSI")); - output.serial(xmin); - output.serial(xmax); - output.serial(ymin); - output.serial(ymax); - output.serial(heightMap); - // TMP TMP - /* - CBitmap tgaHM; - tgaHM.resize(heightMap.getWidth(), heightMap.getHeight()); - sint16 hMax = -32768; - sint16 hMin= 32767; - uint numPix = heightMap.getWidth() * heightMap.getHeight(); - for(CArray2D::iterator it = heightMap.begin(); it != heightMap.end(); ++it) - { - if (*it != 32767) - { - hMax = std::max(hMax, *it); - hMin = std::min(hMin, *it); - } - } - - float scale = 255.f / favoid0((float) (hMax - hMin)); - float bias = (float) - hMin; - CRGBA *destCol = (CRGBA *) &tgaHM.getPixels()[0]; - for(CArray2D::iterator it = heightMap.begin(); it != heightMap.end(); ++it) - { - if (*it == 0x7fff) - { - *destCol++ = CRGBA::Magenta; - } - else - { - float height = scale * ((*it) + bias); - clamp(height, 0.f, 255.f); - *destCol++ = CRGBA((uint8) height, (uint8) height, (uint8) height); - } - } - // - COFile tgaOut("d:\\tmp\\whole_world_height_map.tga"); - tgaHM.writeTGA(tgaOut, 0, true); - */ - // - _WorldMap.clear(); - } - - - - // - void findPath(const string &name, CVectorD start, CVectorD end) - { - _WorldMap.clear(); - CIFile f(OutputPath+name+".cwmap2"); - f.serial(_WorldMap); - - CAStarPath path; - path.setStartPos(_WorldMap.getWorldPosition(start)); - path.setEndPos(_WorldMap.getWorldPosition(end)); - _WorldMap.findAStarPath(path.getStartPos(), path.getEndPos(), path.topologiesPathForCalc()); - - uint step=0; - - CWorldPosition cpos(_WorldMap.getWorldPosition(start)); - while (_WorldMap.move(cpos, path, step)) - { - CVectorD dpos = cpos.getPosition(); // _WorldMap.getPosition(cpos) - CMapPosition mpos = cpos; - nldebug("Move: (%.1f,%.1f,%.1f)/(%04x,%04x)", dpos.x, dpos.y, dpos.z, mpos.x(), mpos.y()); - } - - _WorldMap.clear(); - } - - // - void findInsidePath(const string &name, CVectorD start, CVectorD end) - { - _WorldMap.clear(); - CIFile f(OutputPath+name+".cwmap2"); - f.serial(_WorldMap); - - CInsideAStarPath path; - path.setStartPos(_WorldMap.getWorldPosition(start)); - path.setEndPos(_WorldMap.getWorldPosition(end)); - _WorldMap.findInsideAStarPath(path.getStartPos(), path.getEndPos(), path.getStepPathForCalc()); - - uint step=0; -/* - CWorldPosition cpos = _WorldMap.getWorldPosition(start); - while (_WorldMap.move(cpos, path, step)) - { - CVectorD dpos = _WorldMap.getWorldPosition(cpos); - CMapPosition mpos = cpos.getMapPosition(); - nldebug("Move: (%.1f,%.1f,%.1f)/(%04x,%04x)", dpos.x, dpos.y, dpos.z, mpos.x.c, mpos.y.c); - } -*/ - _WorldMap.clear(); - } - - // - void testMove(const string &name, CVectorD start, CVectorD end) - { - _WorldMap.clear(); - CIFile f(OutputPath+name+".cwmap2"); - f.serial(_WorldMap); - - CWorldPosition pos(_WorldMap.getWorldPosition(start)); - CMapPosition towards = _WorldMap.getWorldPosition(end); - _WorldMap.move (pos,towards, Nothing); - _WorldMap.clear (); - } -}; - -CPacsCruncher::TPacsPrimMap CPacsCruncher::_PacsPrimMap; - - - - -NLMISC_COMMAND(setStartPoint,"Set the start point for a continent"," [startz]") -{ - if (args.size() < 3) - return false; - - CVectorD startPoint; - - NLMISC::fromString(args[1], startPoint.x); - NLMISC::fromString(args[2], startPoint.y); - - if (args.size() < 4) - { - startPoint.z = 0.0; - } - else - { - NLMISC::fromString(args[3], startPoint.z); - } - - StartPoints.insert(multimap::value_type(args[0], startPoint)); - - nlinfo("Set start point (%.1f,%.1f,%.1f) for continent '%s'", startPoint.x, startPoint.y, startPoint.z, args[0].c_str()); - - return true; -} - -NLMISC_COMMAND(setBoundingBox, "Set the working bounding box", " ") -{ - if (args.size() < 4) - return false; - - NLMISC::fromString(args[0], BoxMin.x); - NLMISC::fromString(args[1], BoxMin.y); - NLMISC::fromString(args[2], BoxMax.x); - NLMISC::fromString(args[3], BoxMax.y); - - return true; -} - -NLMISC_COMMAND(setStartPrimFile,"Adds a .primitive file for a continent"," ") -{ - if (args.size() < 2) - return false; - - string continent = args[0]; - string primFile = args[1]; - - PrimFiles.insert(multimap::value_type(continent, primFile)); - - nlinfo("Added primitive file %s to continent '%s'", primFile.c_str(), continent.c_str()); - - return true; -} - -NLMISC_COMMAND(setPacsPrimPath,"the pacs prim path","") -{ - if (args.size() < 1) - return false; - - PacsPrimPath.push_back(args[0]); - - return true; -} - -NLMISC_COMMAND(setDefaultStart,"Set the default start point for all continents"," [startz]") -{ - if (args.size() < 2) - return false; - - CVectorD startPoint; - - NLMISC::fromString(args[0], startPoint.x); - NLMISC::fromString(args[1], startPoint.y); - - if (args.size() > 2) - { - NLMISC::fromString(args[2], startPoint.z); - } - else - { - startPoint.z = 0.0; - } - - DefaultStartPoint = startPoint; - - nlinfo("Set default start point (%.1f,%.1f,%.1f)", startPoint.x, startPoint.y, startPoint.z); - - return true; -} - - -NLMISC_COMMAND(setOutputPath,"Set the output path","") -{ - if (args.size() < 1) - return false; - - OutputPath = CPath::standardizePath(args[0]); - - return true; -} - - -NLMISC_COMMAND(pacsCrunch,"Run a test of pacs crunch"," [ ]") -{ - if(args.size()<1) - return false; - - //crunchPacsMap(args[0]); - - CPacsCruncher pc; - - if (args.size() == 5) - { - float bxmin, bymin, bxmax, bymax; - - bxmin = (float)atof(args[1].c_str()); - bymin = (float)atof(args[2].c_str()); - bxmax = (float)atof(args[3].c_str()); - bymax = (float)atof(args[4].c_str()); - - CAABBox box; - - box.setMinMax(CVector(bxmin, bymin, -10000.0f), CVector(bxmax, bymax, +10000.0f)); - - pc.crunch(args[0], &box); - } - else - { - pc.crunch(args[0]); - } - - return true; -} - -NLMISC_COMMAND(pacsCrunchStart,"Run a test of pacs crunch"," [ ]") -{ - if(args.size()<3) - return false; - - //crunchPacsMap(args[0]); - - - float startx, starty; - - startx = (float)atof(args[1].c_str()); - starty = (float)atof(args[2].c_str()); - - CVector start(startx, starty, 0.0f); - - CPacsCruncher pc; - - if (args.size() == 7) - { - float bxmin, bymin, bxmax, bymax; - - bxmin = (float)atof(args[3].c_str()); - bymin = (float)atof(args[4].c_str()); - bxmax = (float)atof(args[5].c_str()); - bymax = (float)atof(args[6].c_str()); - - CAABBox box; - - box.setMinMax(CVector(bxmin, bymin, -10000.0f), CVector(bxmax, bymax, +10000.0f)); - - pc.crunch(args[0], &box, "", &start); - } - else - { - pc.crunch(args[0], NULL, "", &start); - } - - return true; -} - -NLMISC_COMMAND(pacsCrunchLoop,"Run a serie of tests of pacs crunch"," [=160]") -{ - if(args.size()<5 || args.size()>6) - return false; - - CPacsCruncher pc; - - float startx, starty; - uint loopx, loopy; - uint x, y; - float size = 160.0f; - - startx = (float)atof(args[1].c_str()); - starty = (float)atof(args[2].c_str()); - NLMISC::fromString(args[3], loopx); - NLMISC::fromString(args[4], loopy); - - if (args.size() >= 6) - NLMISC::fromString(args[5], size); - - pc.init(args[0]); - - for (y=0; y") -{ - if(args.size()<1) - return false; - - CPacsCruncher pc; - - pc.buildBitMap(args[0]); - - return true; -} - -NLMISC_COMMAND(pacsBuildHeightMap16, "build a sint16 heightmap from a world map","") -{ - if(args.size()<1) - return false; - - CPacsCruncher pc; - - pc.buildHeightMap16(args[0]); - - return true; -} - -NLMISC_COMMAND(pacsBuildWmap,"build crunched world map from a world map","") -{ - if(args.size()<1) - return false; - - CPacsCruncher pc; - - pc.buildCrunchedMap(args[0]); - - return true; -} - -NLMISC_COMMAND(pacsBuildGabarit,"build gabarit maps from a world map","") -{ - if(args.size()<1) - return false; - - CPacsCruncher pc; - - uint i; - for (i=0; i<3; ++i) - pc.buildGabarit(args[0], i); - - return true; -} - -NLMISC_COMMAND(pacsClearHeightmap,"build gabarit maps from a world map","") -{ - if(args.size()<1) - return false; - - CPacsCruncher pc; - - uint i; - for (i=1; i<3; ++i) - pc.clearHeightMap(args[0], i); - - return true; -} - - - -NLMISC_COMMAND(testAstar, "test astar", "file startx starty endx endy (m)") -{ - if (args.size() < 4) - return false; - - CPacsCruncher pc; - - pc.findPath(args[0], CVectorD(atof(args[1].c_str()), atof(args[2].c_str()), 0.0), CVectorD(atof(args[3].c_str()), atof(args[4].c_str()), 0.0)); - - return true; -} - -NLMISC_COMMAND(testInsideAstar, "test inside astar", "file startx starty endx endy (m)") -{ - if (args.size() < 4) - return false; - - CPacsCruncher pc; - - pc.findInsidePath(args[0], CVectorD(atof(args[1].c_str()), atof(args[2].c_str()), 0.0), CVectorD(atof(args[3].c_str()), atof(args[4].c_str()), 0.0)); - - return true; -} - -NLMISC_COMMAND(testLine, "test linear movement", "file startx starty endx endy (m)") -{ - if (args.size() < 4) - return false; - - CPacsCruncher pc; - - pc.testMove(args[0], CVectorD(atof(args[1].c_str()), atof(args[2].c_str()), 0.0), CVectorD(atof(args[3].c_str()), atof(args[4].c_str()), 0.0)); - - return true; -} - - - -// -NLMISC_COMMAND(checkPackedSheets, "checks continents.packed_sheets file", "") -{ - // a simple pc will automatically checks for continents.packed_sheets file - CPacsCruncher pc; - pc.initPackedSheets(); - - return true; -} - - -// -NLMISC_COMMAND(loadWmap, "Loads a worldmap in static world map", "") -{ - if (args.size() < 1) - return false; - - StaticWorldMap.clear(); - CIFile f(OutputPath+args[0]); - f.serial(StaticWorldMap); - - return true; -} - -NLMISC_COMMAND(clearWmap, "Clears static world map", "") -{ - StaticWorldMap.clear(); - - return true; -} - -NLMISC_COMMAND(dumpMotionLayer, "Dumps motion layer around a position", " ") -{ -/* - if (args.size() < 3) - return false; - - CVectorD vpos; - CWorldPosition pos; - - vpos.x = atof(args[0].c_str()); - vpos.y = atof(args[1].c_str()); - vpos.z = atof(args[2].c_str()); - - StaticWorldMap.setWorldPosition(pos, CMapPosition(vpos)); - - if (!pos.isValid()) - return false; - - CTopology::TTopologyId topoId = StaticWorldMap.getTopologyId(pos); - const CTopology &topo = StaticWorldMap.getTopologyNode(topoId); - - topo.DirectionMap->dump(); -*/ - return true; -} - -NLMISC_COMMAND(dumpTopo, "Dumps motion layer around a position", "topoId in hexa") -{ - if (args.size() < 1) - return false; - - uint32 id; - - sscanf(args[0].c_str(), "%x", &id); - - CTopology::TTopologyId topoId(id); - const CTopology &topo = StaticWorldMap.getTopologyNode(topoId); - - topo.DirectionMap->dump(); - - uint i; - nlinfo("%08X neighbours (%d neighbours)", id, topo.Neighbours.size()); - for (i=0; igetMetricHeight(start); - - nlinfo("Pos at (%d,%d,%d), z=%d", start.x(), start.y(), start.slot(), h); - - return true; -} - -NLMISC_COMMAND(testPacsMove, "test a pacs move", " ") -{ - if (args.size() != 5) - return false; - - CPacsCruncher pc; - - string name = args[0]; - - double x, y, dx, dy; - NLMISC::fromString(args[1], x); - NLMISC::fromString(args[2], y); - NLMISC::fromString(args[3], dx); - NLMISC::fromString(args[4], dy); - - pc.init(name); - - UMovePrimitive *primitive = pc._Container->addNonCollisionablePrimitive(); - primitive->setPrimitiveType( UMovePrimitive::_2DOrientedCylinder ); - primitive->setReactionType( UMovePrimitive::Stop ); - primitive->setTriggerType((UMovePrimitive::TTrigger)(UMovePrimitive::EnterTrigger+ - UMovePrimitive::ExitTrigger) ); - primitive->setCollisionMask( 0xffffffff ); - primitive->setOcclusionMask( 0x00000000 ); - primitive->setObstacle( true ); - primitive->setAbsorbtion( 0 ); - primitive->setHeight( 6.0f ); - primitive->setRadius( 0.5f ); - - CVectorD startPos(x, y, 0); - primitive->setGlobalPosition(startPos, 0); - pc._Container->evalCollision(1.0, 0); - - primitive->move(CVectorD(dx, dy, 0.0), 0); - pc._Container->evalNCPrimitiveCollision(1.0, primitive, 0); - - UGlobalPosition newPos; - primitive->getGlobalPosition(newPos, 0); - - return true; -} -// - -} - -NLMISC_VARIABLE(string, EvaluatedPos, "Last evaluated pacs position"); -NLMISC_VARIABLE(uint, Verbose, "Verbosity"); diff --git a/code/ryzom/server/src/ai_data_service/primitive_crunch.cpp b/code/ryzom/server/src/ai_data_service/primitive_crunch.cpp deleted file mode 100644 index c08be9c58..000000000 --- a/code/ryzom/server/src/ai_data_service/primitive_crunch.cpp +++ /dev/null @@ -1,424 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//=================================================================== - - -#include "nel/misc/debug.h" - -#include "game_share/xml.h" - -#include "ai_manager.h" -#include "ai_service.h" -#include "ai_files.h" - -//=================================================================== - -//--------------------------------------------------- -// INSTANTIATED CLASS: Public methods - -//------------- -// a few read accessors (static properties) - -// the manager id (0..255) -sint CAIManager::id() const -{ - return int(this-_managers); -} -// the manager name .. ie the source file name minus extension -const std::string &CAIManager::name() const -{ - return _name; -} - -// the CPU load rating of the manager for auto-load ballancing purposes -uint CAIManager::weightCPU() const -{ - return _weightCPU; -} -// the RAM load rating of the manager for auto-load ballancing purposes -uint CAIManager::weightRAM() const -{ - return _weightRAM; -} - - -//------------- -// a few read accessors (state of the files on disk) - -// indicates whether newer source files than object files have been located -bool CAIManager::needCompile() const -{ - return _needCompile; -} -// indicate whether an object file has been located in the object directory -bool CAIManager::objExists() const -{ - return _objExists; -} - - -//------------- -// a few read accessors (relating to assignment to & execution by an ai service) - -// has the manager been opened (it may still be waiting to be assigned) -bool CAIManager::isOpen() const -{ - return _isOpen; -} -// has the manager been assigned to a service -bool CAIManager::isAssigned() const -{ - return _isAssigned; -} -// is the manager up and running on the assigned service -bool CAIManager::isUp() const -{ - return _isUp; -} - -// the id of the service to which the manager is assigned -sint CAIManager::serviceId() const -{ - return _service; -} - - -//------------- -// a few basic actions (relating to disk files) - -const std::string &xmlDelimitedString(CxmlNode *xmlNode,const std::string &delimiter) -{ - static const std::string emptyString; - - for (uint i=0;ichildCount();++i) - { - CxmlNode *child=xmlNode->child(i); - if (child->type()==delimiter) - if (child->childCount()==1) - if (child->child(0)->type()=="") - { - return child->child(0)->txt(); - } - } - - return emptyString; -} - -const std::string &getProp(CxmlNode *xmlNode,const std::string &propertyName) -{ - static const std::string emptyString; - - for (uint i=0;ichildCount();++i) - { - CxmlNode *child=xmlNode->child(i); - if (child->type()=="PROPERTY") - { - const std::string &name= xmlDelimitedString(child,std::string("NAME")); - if (name==propertyName) - return xmlDelimitedString(child,std::string("STRING")); - } - } - return emptyString; -} - -// compile the source files to generate new object files -void CAIManager::compile() -{ - std::string srcFile=CAIFiles::fullSrcFileName(id()); - std::string objFile=CAIFiles::fullObjFileName(id()); - nlinfo("Compile %s => %s",srcFile.c_str(),objFile.c_str()); - - // open and parse the xml file - CxmlNode xmlfile; - xmlfile.read(srcFile); - - // locate the mgr node in the file - std::list nodes; - nodes.push_back(&xmlfile); - while (!nodes.empty()) - { - // pop the next node off the list - CxmlNode *node=*nodes.begin(); - nodes.pop_front(); - - // push our children so that they can be treated too - for (uint i=0;ichildCount();++i) - nodes.push_back(node->child(i)); - - // if this is a child node then we're in business so dump a few infos to the screen - if (node->type()=="CHILD" && !getProp(node,std::string("AI_TYPE")).empty()) - { - nlinfo("child: AI_TYPE: %s NAME: %s",getProp(node,std::string("AI_TYPE")).c_str(),getProp(node,std::string("Name")).c_str()); - } - } -} - -// delete the object files (but not the save files) -void CAIManager::clean() -{ - CAIFiles::clean(id()); -} - - -//------------- -// a few basic actions (relating to assignment to & execution by an ai service) - -// open the manager on an unspecified service -// (may be queued until a service is available) -void CAIManager::open() -{ - CAIService::openMgr(id()); -} - -// assign manager to a specified service and begin execution -void CAIManager::assign(sint serviceId) -{ - // make sure that the manager isn't assigned to a service already - if (isAssigned()) - { - nlwarning("Cannot assign manager %04d (%s) to service %d as already assigned to %d", - id(), name(), serviceId, _service); - return; - } - - // flag me as assigned - _isAssigned=true; - _service=serviceId; - - // transfer control to the service's assignMgr() method - CAIService *service=CAIService::getServiceById(serviceId); - if (service!=NULL) - service->assignMgr(id()); -} - -// stop execution on the current service and assign to a new service -void CAIManager::reassign(sint serviceId) -{ - CAIService *service=CAIService::getServiceById(_service); - if (service!=NULL) - service->reassignMgr(id(),serviceId); -} - -// stop execution of a manager -void CAIManager::close() -{ - // make sure that the manager isn't assigned to a service already - if (!isAssigned()) - { - nlwarning("Cannot unassign manager %04d (%s) as it is already unassigned", id(), name()); - return; - } - - // if the service is running then transfer control to the service singleton's closeMgr() method - if (isUp()) - { - CAIService::closeMgr(id()); - return; - } - - // flag me as unassigned - _isAssigned=false; - _isOpen=false; - _service=-1; -} - - -//------------- -// a few basic actions (miscelaneous) - -// display information about the state of the manager -void CAIManager::display() const -{ - if (isAssigned()) - nlinfo("AI Manager %04d: %s: %s ON SERVICE %d (%s)", id(), _name.c_str(), - isUp()? "UP AND RUNNING": - /* else */ "ASSIGNED TO BUT NOT YET UP", - _service, - isOpen()? "auto-assigned": - /* else */ "manualy assigned" - ); - else - nlinfo("AI Manager %04d: %s: %s", id(), _name.c_str(), - isOpen()? "OPEN - AWAITING ASSIGNMENT": - !objExists()? "NOT OPEN - OBJECT FILE NOT FOUND": - needCompile()? "NOT OPEN - OBJECT FILE OLDER THAN SOURCE": - /* else */ "NOT OPEN - OBJECT FILE IS UP TO DATE" - ); -} - - -//------------- -// a few write accessors (miscelaneous) - -// set the name assigned to manager -// if no name previously assigned then reset all manager properties -// if a name already exists and does not match new name then do nohing and return false -bool CAIManager::set(const std::string &name) -{ - // if we already have a name associated with this slot then simply check that it matches the new name - if (!_name.empty()) - return (_name==name); - _reset(); - _name=name; - return true; -} - -// set the state of the needCompile flag -void CAIManager::setNeedCompile(bool val) -{ - _needCompile=val; -} - -// set the state of the objFileExists flag -void CAIManager::setObjFileExists(bool val) -{ - _objExists=val; -} - -// set the state of the isUp flag -void CAIManager::setIsUp(bool val) -{ - _isUp=val; -} - -// set the state of the isOpen flag -void CAIManager::setIsOpen(bool val) -{ - _isOpen=val; -} - - -//--------------------------------------------------- -// INSTANTIATED CLASS: Private methods - -// default constructor - may only be instantiated by the singleton -CAIManager::CAIManager() -{ - // manager id - make sure that the managers are all in the one static array - // note that id is calaulated from the array address and the addess of 'this' - nlassert(uint(id())=maxManagers()) - { - nlwarning("CAIManager::getManagerById(id): id %d not in range 0..%d",id,maxManagers()-1); - return NULL; - } - return &(_managers[id]); -} - -// get a pointer to the manager with given index (0..numManagers-1) -CAIManager *CAIManager::getManagerByIdx(uint idx) -{ - uint count=0; - for (uint i=0;i=numManagers (%d)",idx,count); - return NULL; -} - -// get the handle for the manager of given name and optionally create a new -// handle if none found - return -1 if none found or no free slots -int CAIManager::nameToId(std::string name, bool assignNewIfNotFound) -{ - // see if the name is a numeric version of an id - uint val=atoi(name.c_str()); - if (!name.empty() && name.size()<=4 && - ( (val>0 && val -// 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 . - - - -#include "nel/misc/types_nl.h" -#include "nel/net/service.h" -#include "nel/misc/path.h" -#include "nel/ligo/primitive.h" -#include "nel/ligo/ligo_config.h" -#include "game_share/ryzom_version.h" -#include "ai_share/ai_share.h" - -#include "ai_files.h" -#include "ai_manager.h" -#include "ai_service.h" -#include "aids_actions.h" -#include "messages.h" // singleton manager for transport class messages - -using namespace NLMISC; -using namespace NLNET; -using namespace std; - -// The ligo config -NLLIGO::CLigoConfig LigoConfig; - -static TUnifiedCallbackItem CallbackArray[] = -{ - { "QWERTY", 0, }, -}; - -extern string OutputPath; -extern vector PacsPrimPath; -extern vector LookupPath; -extern vector LookupNoRecursePath; - - -/*-----------------------------------------------------------------*\ - SERVICE CLASS -\*-----------------------------------------------------------------*/ - -class CAIDataService : public NLNET::IService -{ -public: - void init(); - bool update(); - void release(); -}; - -// callback for the tick service 'tick' message -static void cbTick(); - - -/*-----------------------------------------------------------------*\ - SERVICE INIT & RELEASE -\*-----------------------------------------------------------------*/ - -///init - -void CAIDataService::init (void) -{ - setVersion (RYZOM_VERSION); - - // this is the init for the ligo pri;itive parser lib - NLLIGO::Register (); - - // setup the update systems - setUpdateTimeout(200); - - // Init ligo - if (!LigoConfig.readPrimitiveClass ("world_editor_classes.xml", false)) - { - // Should be in l:\leveldesign\world_edit_files - nlerror ("Can't load ligo primitive config file world_editor_classes.xml"); - } - - // init sub systems - AI_SHARE::init(&LigoConfig); - CMessages::init(); - CAIDSActions::init(); - - - // - CConfigFile &cf = ConfigFile; - CConfigFile::CVar *var; - - var = cf.getVarPtr("Paths"); - if (var != NULL) - { - uint i; - for (i=0; (sint)isize(); ++i) - LookupPath.push_back(var->asString(i)); - } - - var = cf.getVarPtr("NoRecursePaths"); - if (var != NULL) - { - uint i; - for (i=0; (sint)isize(); ++i) - LookupNoRecursePath.push_back(var->asString(i)); - } - - var = cf.getVarPtr("PacsPrimPaths"); - if (var != NULL) - { - uint i; - for (i=0; (sint)isize(); ++i) - PacsPrimPath.push_back(var->asString(i)); - } - - var = cf.getVarPtr("OutputPath"); - if (var != NULL) - { - OutputPath = CPath::standardizePath(var->asString()); - } -} - - -///release - -void CAIDataService::release (void) -{ - // release sub systems - CMessages::release(); -} - - -/*-----------------------------------------------------------------*\ - SERVICE UPDATES -\*-----------------------------------------------------------------*/ - -///update called every coplete cycle of service loop - -bool CAIDataService::update (void) -{ - CAIService::update(); - return true; -} - -/*-----------------------------------------------------------------*\ - NLNET_SERVICE_MAIN -\*-----------------------------------------------------------------*/ -NLNET_SERVICE_MAIN (CAIDataService, "AIDS", "ai_data_service", 0, CallbackArray, "", "") - diff --git a/code/ryzom/server/src/ai_service/CMakeLists.txt b/code/ryzom/server/src/ai_service/CMakeLists.txt deleted file mode 100644 index fb439820d..000000000 --- a/code/ryzom/server/src/ai_service/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -IF(APPLE) - add_definitions("-ftemplate-depth=100") -ENDIF() -FILE(GLOB SRC *.cpp *.h) - -LIST(REMOVE_ITEM SRC - ${CMAKE_CURRENT_SOURCE_DIR}/ai_entity_id.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ai_entity_id.h - ${CMAKE_CURRENT_SOURCE_DIR}/ai_entity_id_inline.h - ${CMAKE_CURRENT_SOURCE_DIR}/ai_world_map.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ai_world_map.h - ${CMAKE_CURRENT_SOURCE_DIR}/combat_move.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/combat_move.h - ${CMAKE_CURRENT_SOURCE_DIR}/gpms_interface.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/gpms_interface.h - ${CMAKE_CURRENT_SOURCE_DIR}/ios_interface.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ios_interface.h) - -ADD_EXECUTABLE(ryzom_ai_service WIN32 ${SRC}) - -INCLUDE_DIRECTORIES(${RZ_SERVER_SRC_DIR} ${MYSQL_INCLUDE_DIR}) - -TARGET_LINK_LIBRARIES(ryzom_ai_service - ryzom_adminmodules - ryzom_gameshare - ryzom_servershare - ryzom_aishare - nelmisc - nelnet - nelgeorges - nelligo) - -NL_DEFAULT_PROPS(ryzom_ai_service "Ryzom, Services: AI Service (AIS)") -NL_ADD_RUNTIME_FLAGS(ryzom_ai_service) - -IF(WITH_PCH) - ADD_NATIVE_PRECOMPILED_HEADER(ryzom_ai_service ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) -ENDIF() - -INSTALL(TARGETS ryzom_ai_service RUNTIME DESTINATION sbin COMPONENT services) - diff --git a/code/ryzom/server/src/ai_service/admin.h b/code/ryzom/server/src/ai_service/admin.h deleted file mode 100644 index ed677eb19..000000000 --- a/code/ryzom/server/src/ai_service/admin.h +++ /dev/null @@ -1,158 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_ADMIN_H -#define RYAI_ADMIN_H - -#include "nel/misc/types_nl.h" -#include "ai_share/ai_types.h" - - -void selectEntities (const string &entityName, vector &entities) -{ - if (entityName.empty ()) - return; - - /* - - valid name formats: - ALL MGRS: - - * - - MGR: - - = - - - - - - <8 digit hex mgr CAIEntityId> - - ALL GRPS IN MGR: - - * - - GRP: - - = - - - - <8 digit hex grp CAIEntityId> - - : - - ALL BOTS IN GRP: - - * - - INDIVIDUAL: - - = - - - - <8 digit hex bot CAIEntityId> - - : - - RANGE OF INDIVIDUALS: - - - - - */ - - uint32 entity = atoi (entityName.c_str()); - - if (entityName == "*") - { - // we want all entities - for (uint i = 0; i < Entities.size(); i++) - entities.push_back (i); - } - else if (entityName.find ("-") != string::npos) - { - // it's a range - uint ent2; - NLMISC::fromString(entityName.substr(entityName.find("-")+1), ent2); - for (uint i = entity; i <= ent2; i++) - entities.push_back (i); - } - else - { - // we want a specific entity - entities.push_back (entity); - } -} - - - -#define ENTITY_VARIABLE(__name,__help) \ -struct __name##Class : public NLMISC::ICommand \ -{ \ -__name##Class () : NLMISC::ICommand(#__name, __help, " -[]") { Type = Variable; } \ - virtual bool execute(const std::vector &args, -NLMISC::CLog &log) \ - { \ - if (args.size () != 1 && args.size () != 2) \ - return false; \ - \ - vector entities; \ - selectEntities (args[0], entities); \ - \ - for (uint i = 0; i < entities.size(); i++) \ - { \ - string value; \ - if (args.size()==2) \ - value = args[1]; \ - else \ - value = "???"; \ - pointer (entities[i], (args.size()==1), value); \ - log.displayNL ("Entity %d Variable %s = %s", entities[i], _CommandName.c_str(), value.c_str()); \ - } \ - return true; \ - } \ - void pointer(uint32 entity, bool get, std::string &value); \ -}; \ -__name##Class __name##Instance; \ -void __name##Class::pointer(uint32 entity, bool get, std::string &value) - -ENTITY_VARIABLE(test, "test") -{ - if (get) - { - // get the value if available - if(entity < Entities.size()) - value = toString(Entities[entity].first); - } - else - { - // set the variable with the new value - if(entity >= Entities.size()) - Entities.resize(entity+1); - - NLMISC::fromString(value, Entities[entity].first); - } -} - -ENTITY_VARIABLE(test2, "test2") -{ - if (get) - { - // get the value if available - if(entity < Entities.size()) - value = toString(Entities[entity].second); - } - else - { - // set the variable with the new value - if(entity >= Entities.size()) - Entities.resize(entity+1); - - NLMISC::fromString(value, Entities[entity].second); - } -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai.cpp b/code/ryzom/server/src/ai_service/ai.cpp deleted file mode 100644 index 49144fa9d..000000000 --- a/code/ryzom/server/src/ai_service/ai.cpp +++ /dev/null @@ -1,915 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" - -#include - -#include "child_container.h" -#include "ai_mgr.h" -#include "ai_entity_matrix.h" -#include "ai_player.h" -#include "ai_mgr_pet.h" -#include "ai_grp.h" -#include "ai_mgr_fauna.h" -#include "ai_mgr_npc.h" -#include "ai_bot_npc.h" -#include "ai_grp_npc.h" -#include "ai_grp_pet.h" - -#include "ai_script_data_manager.h" - -#include "ais_user_models.h" -#include "continent.h" -#include "client_message.h" -#include "ai_outpost.h" -// Georges -#include "nel/georges/u_form_loader.h" -#include "nel/georges/u_form_elm.h" -#include "nel/georges/u_form.h" -#include "nel/georges/u_form_dfn.h" -// Game share -#include "game_share/emote_list_parser.h" -#include "game_share/backup_service_interface.h" - -#include "ai_variables.h" -#include "server_share/r2_variables.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace NLGEORGES; - -//-------------------------------------------------------------------------- -// SINGLETON DATA -//-------------------------------------------------------------------------- - - -CAIS *CAIS::_Instance = NULL; - -CRandom CAIS::_random; - -const std::string disengageString("DISENGAGE"); -const std::string egsString("EGS"); - - -const uint32 Default_MaxPlayers=5000; -const uint32 Default_MaxBotsPet=Default_MaxPlayers*4; -const uint32 Default_MaxBotsFauna=40000; -const uint32 Default_MaxBotsNpc=20000; -const uint32 Default_MaxBotsFx=200; - -CAIS &CAIS::instance() -{ - if (_Instance == NULL) - { - _Instance = new CAIS(); - // init the AI engine - _Instance->initAI(); - } - - return *_Instance; -} - - -CAIS::CAIS() -: _PetBotCounter(TotalMaxPet), - _FaunaBotCounter(TotalMaxFauna), - _NpcBotCounter(TotalMaxNpc) -{ -// _initialised=false; - _TotalBotsSpawned = 0; - _ClientCreatureDebug=false; -} - -void setMaxPetCallBack(IVariable &var) -{ - uint32 newMax=NLMISC::safe_cast*>(&var)->get(); - if (CAIS::instanceCreated()) - CAIS::instance()._PetBotCounter.setMax(newMax); -} -void setMaxFaunaCallBack(IVariable &var) -{ - uint32 newMax=NLMISC::safe_cast*>(&var)->get(); - if (CAIS::instanceCreated()) - CAIS::instance()._FaunaBotCounter.setMax(newMax); -} -void setMaxNpcCallBack(IVariable &var) -{ - uint32 newMax=NLMISC::safe_cast*>(&var)->get(); - if (CAIS::instanceCreated()) - CAIS::instance()._NpcBotCounter.setMax(newMax); -} - -CVariable TotalMaxPlayer("ai", "NbPlayersLimit", "Security absolute limit to the number of Player", Default_MaxPlayers, 0, true ); -CVariable TotalMaxPet("ai", "NbPetLimit", "Security absolute limit to the number of Pets", Default_MaxBotsPet, 0, true, setMaxPetCallBack ); -CVariable TotalMaxFauna("ai", "NbFaunaLimit", "Security absolute limit to the number of Faunas", Default_MaxBotsFauna, 0, true, setMaxFaunaCallBack ); -CVariable TotalMaxNpc("ai", "NbNpcLimit", "Security absolute limit to the number of Npcs", Default_MaxBotsNpc, 0, true, setMaxNpcCallBack ); -CVariable TotalMaxFx("ai", "NbFxLimit", "Security absolute limit to the number of Fx", Default_MaxBotsFx, 0, true ); - -CVariable BotRepopFx("ai", "BotRepopFx", "Fx sheet to use when changing the sheet of a bot", string(), 0, true ); - -//-------------------------------------------------------------------------- -// DATA TABLES FOR ENTITY MATRIX -//-------------------------------------------------------------------------- - -// a series of tables giving the minimum iterator table forms for entity matrix iterators for all sizes up to 127m -static uint32 EntityMatrixTbl0[] = { 3, 3, 3}; -static uint32 EntityMatrixTbl16[] = { 3, 5, 5, 5, 3}; -static uint32 EntityMatrixTbl23[] = { 5, 5, 5, 5, 5}; -static uint32 EntityMatrixTbl32[] = { 3, 5, 7, 7, 7, 5, 3}; -static uint32 EntityMatrixTbl36[] = { 5, 7, 7, 7, 7, 7, 5}; -static uint32 EntityMatrixTbl46[] = { 7, 7, 7, 7, 7, 7, 7}; -static uint32 EntityMatrixTbl48[] = { 3, 7, 7, 9, 9, 9, 7, 7, 3}; -static uint32 EntityMatrixTbl51[] = { 5, 7, 9, 9, 9, 9, 9, 7, 5}; -static uint32 EntityMatrixTbl58[] = { 7, 9, 9, 9, 9, 9, 9, 9, 7}; -static uint32 EntityMatrixTbl64[] = { 3, 7, 9, 9, 11, 11, 11, 9, 9, 7, 3}; -static uint32 EntityMatrixTbl66[] = { 5, 7, 9, 11, 11, 11, 11, 11, 9, 7, 5}; -static uint32 EntityMatrixTbl68[] = { 5, 9, 9, 11, 11, 11, 11, 11, 9, 9, 5}; -static uint32 EntityMatrixTbl72[] = { 7, 9, 11, 11, 11, 11, 11, 11, 11, 9, 7}; -static uint32 EntityMatrixTbl80[] = { 3, 9, 11, 11, 11, 13, 13, 13, 11, 11, 11, 9, 3}; -static uint32 EntityMatrixTbl82[] = { 5, 9, 11, 11, 13, 13, 13, 13, 13, 11, 11, 9, 5}; -static uint32 EntityMatrixTbl87[] = { 7, 9, 11, 13, 13, 13, 13, 13, 13, 13, 11, 9, 7}; -static uint32 EntityMatrixTbl91[] = { 7, 11, 11, 13, 13, 13, 13, 13, 13, 13, 11, 11, 7}; -static uint32 EntityMatrixTbl94[] = { 9, 11, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 9}; -static uint32 EntityMatrixTbl96[] = { 3, 9, 11, 13, 13, 13, 15, 15, 15, 13, 13, 13, 11, 9, 3}; -static uint32 EntityMatrixTbl98[] = { 5, 9, 11, 13, 13, 15, 15, 15, 15, 15, 13, 13, 11, 9, 5}; -static uint32 EntityMatrixTbl102[] = { 7, 9, 11, 13, 15, 15, 15, 15, 15, 15, 15, 13, 11, 9, 7}; -static uint32 EntityMatrixTbl103[] = { 7, 11, 13, 13, 15, 15, 15, 15, 15, 15, 15, 13, 13, 11, 7}; -static uint32 EntityMatrixTbl108[] = { 9, 11, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 13, 11, 9}; -static uint32 EntityMatrixTbl112[] = { 3, 9, 11, 13, 15, 15, 15, 17, 17, 17, 15, 15, 15, 13, 11, 9, 3}; -static uint32 EntityMatrixTbl114[] = { 5, 9, 13, 13, 15, 15, 17, 17, 17, 17, 17, 15, 15, 13, 13, 9, 5}; -static uint32 EntityMatrixTbl116[] = { 5, 11, 13, 15, 15, 15, 17, 17, 17, 17, 17, 15, 15, 15, 13, 11, 5}; -static uint32 EntityMatrixTbl117[] = { 7, 11, 13, 15, 15, 17, 17, 17, 17, 17, 17, 17, 15, 15, 13, 11, 7}; -static uint32 EntityMatrixTbl122[] = { 9, 11, 13, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 15, 13, 11, 9}; -static uint32 EntityMatrixTbl125[] = { 9, 13, 15, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 15, 15, 13, 9}; - -// a few larger special case matrices -static uint32 EntityMatrixTblUpTo150[] = { 7, 11, 15, 17, 17, 19, 19, 21, 21, 21, 21, 21, 21, 21, 19, 19, 17, 17, 15, 11, 7}; -static uint32 EntityMatrixTblUpTo200[] = { 9, 13, 17, 19, 21, 23, 23, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 23, 23, 21, 19, 17, 13, 9}; -static uint32 EntityMatrixTblUpTo250[] = {11, 15, 19, 23, 25, 27, 27, 29, 29, 31, 31, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 31, 31, 29, 29, 27, 27, 25, 23, 19, 15, 11}; - -static void initLinearMatrixIteratorTables(std::vector &vect) -{ - // initialise the vector with the first table - vect.push_back(new CAIEntityMatrixIteratorTblLinear(&(EntityMatrixTbl0[0]),3)); - - // local macro undefined at end of function - #define ADD_TBL(d) \ - { \ - while (vect.size()::iterator it=_AIInstances.begin(), itEnd=_AIInstances.end(); it!=itEnd;++it) - { - // first: tag the dynamic regions in the continents - for_each(it->continents().begin(), it->continents().end(), - bind2nd(mem_fun(&CContinent::markTagForDelete), fileId)); - - for_each(it->managers().begin(),it->managers().end(), - CAliasTreeRoot::CMarkTagForDelete(fileId)); - } - return true; -} - -void CAIS::deleteTaggedAlias(const std::string &filename) -{ - const TStringId fileId = CStringMapper::map(filename); - FOREACH(it, CCont, _AIInstances) - { - // first: tag the dynamic regions in the continents - for_each(it->continents().begin(), it->continents().end(), - bind2nd(mem_fun(&CContinent::deleteTaggedAlias),fileId)); - - for_each(it->managers().begin(),it->managers().end(), - CAliasTreeRoot::CDeleteTagged(it->managers())); - } - -} - - -uint32 CAIS::getEmotNumber(const std::string &name) -{ - std::map::iterator it(_EmotNames.find(name)); - if (it==_EmotNames.end()) - return std::numeric_limits::max(); - return it->second; -} - - - -bool CAIS::advanceUserTimer (uint32 nbTicks) -{ - // for each manager, look for a timer event - for_each(AIList().begin(), AIList().end(), bind2nd(mem_fun(&CAIInstance::advanceUserTimer),nbTicks) ); - return true; -} - - - -// initialise the singleton -void CAIS::initAI() -{ -// if (_initialised) -// return; -// _initialised=true; - nlinfo("---------- Initialising AI Singleton ----------"); - - // setup the random number generator - _random.srand( (sint32)NLMISC::CTime::getLocalTime() ); - - // allocate RAM for the players - - // setup the standard iterator tables for scanning the entity matrices - _matrixIterator2x2.push_back(-1,-1); _matrixIterator2x2.push_back(1,0); - _matrixIterator2x2.push_back(-1, 1); _matrixIterator2x2.push_back(1,0); - - _matrixIterator3x3.push_back(-1,-1); _matrixIterator3x3.push_back(1,0); _matrixIterator3x3.push_back(1,0); - _matrixIterator3x3.push_back(-2, 1); _matrixIterator3x3.push_back(1,0); _matrixIterator3x3.push_back(1,0); - _matrixIterator3x3.push_back(-2, 1); _matrixIterator3x3.push_back(1,0); _matrixIterator3x3.push_back(1,0); - - // setup the set of linear iterator tables for generating visions of given distances - initLinearMatrixIteratorTables(_matrixIteratorsByDistance); - - EMOTE_LIST_PARSER::initEmoteList(_EmotNames); - - // init the client message callbacks - CAIClientMessages::init(); -} - - -uint32 CAIS::createAIInstance(const std::string &continentName, uint32 instanceNumber) -{ - // first, check that an instance with this number is not already running - - for (CCont::iterator it=_AIInstances.begin(), itEnd=_AIInstances.end();it!=itEnd;++it) - { - if (it->getInstanceNumber()!=instanceNumber) - continue; - - nlwarning("CAIS::createAIInstance: instance number %u is already in use, can't create new instance.", instanceNumber); - return std::numeric_limits::max(); - } - - CAIInstance *aii = _AIInstances.addChild(new CAIInstance(this)); - - // ok, set the continent name and instance number - aii->initInstance(continentName, instanceNumber); - - return aii->getChildIndex(); -} - -void CAIS::destroyAIInstance(uint32 instanceNumber, bool displayWarningIfInstanceNotExist) -{ - // this method is not fully tested for a Ryzom shard - // but it should work as expected for a Ring shard - nlassert(IsRingShard.get()); - - CRefPtr aii = getAIInstance(instanceNumber); - if (aii == NULL) - { - if (displayWarningIfInstanceNotExist) - { - nlwarning("AI instance %u does not exist but it was asked to delete here", instanceNumber); - } - return; - } - aii->despawn(); - _AIInstances.removeChildByIndex(aii->getChildIndex()); - nlassert(aii == NULL); - - // notify the EGS - if (EGSHasMirrorReady) - { - CReportAIInstanceDespawnMsg msg; - msg.InstanceNumbers.push_back(instanceNumber); - msg.send("EGS"); - } -} - - -// release the singleton before program exit -void CAIS::release () -{ - // force an update to save the persistent var if needed - updatePersistentVariables(); - - // erase all ai instance. - AIList().clear(); - - CAIUserModelManager::getInstance()->destroyInstance(); - // release the client message callbacks - CAIClientMessages::release(); - - - // free up the vision matrix iterator tables - if (!_matrixIteratorsByDistance.empty()) - { - for (uint i=0;i<_matrixIteratorsByDistance.size();) - { - // erase the iterator table - delete _matrixIteratorsByDistance[i]; - // run i forwards past repeated refs to the iterator tbl that we just deleted - for (++i;i<_matrixIteratorsByDistance.size() && _matrixIteratorsByDistance[i]==_matrixIteratorsByDistance[i-1];++i) {} - } - _matrixIteratorsByDistance.clear(); - } - _Instance = NULL; - delete this; -} - -void CAIS::serviceEvent (const CServiceEvent &info) -{ - if (info.getEventType() == CServiceEvent::SERVICE_UP && info.getServiceName() == "EGS") - { - // send the list of available collision data - CReportAICollisionAvailableMsg msg; - msg.ContinentsCollision = CWorldContainer::getContinentList(); - msg.send(info.getServiceId()); - } - - // event on all ai instance - -// for_each(_AIInstances.begin(), _AIInstances.end(), bind2nd(mem_fun1(&CAIInstance::serviceEvent), info)); -// don't compile coz we need to pass an object and not a reference (info). have to build an object that represents the reference. - - FOREACH(it, CCont, _AIInstances) - it->serviceEvent (info); -} - - -//-------------------------------------------------------------------------- -// update() & save() -//-------------------------------------------------------------------------- - -// the update routine called once per tick -// this is the routine that calls the managers' updates -extern void execBufferedCommands(); -extern void execNamedEntityChanges(); - -void CAIS::update() -{ - if (!EGSHasMirrorReady) - return; - - H_AUTO(AIUpdate); - - - // Init stat counters - AISStat::countersBegin(); - - // Execute buffered Task - uint32 tick = CTimeInterface::gameCycle(); - _TickedTaskList.execute(tick); - - // Execute buffered functions that need to be executed in the correct context - execBufferedCommands(); - - - execNamedEntityChanges(); - - // Update AI instances - FOREACH(it, CCont, CAIS::instance().AIList()) - (*it)->CAIInstance::update(); - - // Send systematic messages to EGS - if (EGSHasMirrorReady) - { - // send the fauna description message to EGS then clear the content. - if (!_FaunaDescriptionList.Bots.empty()) - { - nlassert(_FaunaDescriptionList.Bots.size() == _FaunaDescriptionList.GrpAlias.size()); - _FaunaDescriptionList.send("EGS"); - _FaunaDescriptionList.Bots.clear(); - _FaunaDescriptionList.GrpAlias.clear(); - } - // send agglomerated hp changes - if (!_CreatureChangeHPList.Entities.empty()) - { - nlassert(_CreatureChangeHPList.Entities.size()==_CreatureChangeHPList.DeltaHp.size()); - _CreatureChangeHPList.send("EGS"); - _CreatureChangeHPList.Entities.clear(); - _CreatureChangeHPList.DeltaHp.clear(); - } - if (!_CreatureChangeMaxHPList.Entities.empty()) - { - nlassert(_CreatureChangeMaxHPList.Entities.size()==_CreatureChangeMaxHPList.MaxHp.size()); - nlassert(_CreatureChangeMaxHPList.Entities.size()==_CreatureChangeMaxHPList.SetFull.size()); - _CreatureChangeMaxHPList.send("EGS"); - _CreatureChangeMaxHPList.Entities.clear(); - _CreatureChangeMaxHPList.MaxHp.clear(); - _CreatureChangeMaxHPList.SetFull.clear(); - } - } - - // - // update persistent variables every 1024 tick if AI script data manager is flagged - if ((tick & 0x3FF) == 0) - { - updatePersistentVariables(); - } - - //TODO: UserModelManager must send UserModels to EGS if not done yet - //CAIUserModelManager::getInstance()->sendUserModels(); - // Terminate counters and store stats in an accessible place - AISStat::countersEnd(); -} - -// provoke a general 'save to backup' across the whole service -void CAIS::save() -{ - nlinfo("*** save() NOT IMPLEMENTED YET ***"); -} - - -//-------------------------------------------------------------------------- -// management of iterator tables for vision matrices -//-------------------------------------------------------------------------- - -const CAIEntityMatrixIteratorTblLinear* CAIS::bestLinearMatrixIteratorTbl(uint32 distInMeters) -{ -#if !FINAL_VERSION - nlassert(!_matrixIteratorsByDistance.empty()); -#endif - - if (distInMeters >= _matrixIteratorsByDistance.size()) - { - //nlwarning("Try to access to a Vision Matrix to far %u the farest is only %u", distInMeters, _matrixIteratorsByDistance.size()); - return _matrixIteratorsByDistance.back(); - } - - return _matrixIteratorsByDistance[distInMeters]; -} - -int getInt64FromStr (const char* str) -{ - if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - return (int) atoiInt64(str+2,16); - return (int) atoiInt64(str,10); -} - -// all these dynamics casts can be throwned away .. -CAIInstance* CAIS::tryToGetAIInstance(const char* str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_INSTANCE)); -} - -CContinent *CAIS::tryToGetContinent (const char *str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_CONTINENT)); -} - -CRegion *CAIS::tryToGetRegion (const char *str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_REGION)); -} - -CCellZone *CAIS::tryToGetCellZone (const char *str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_CELL_ZONE)); -} - -CFamilyBehavior *CAIS::tryToGetFamilyBehavior (const char *str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_FAMILY_BEHAVIOR)); -} - - -CManager* CAIS::tryToGetManager(const char* str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_MANAGER)); -} - -CGroup* CAIS::tryToGetGroup(const char* str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_GROUP)); -} - -CBot* CAIS::tryToGetBot(const char* str) -{ - return dynamic_cast (tryToGetEntity(str,CAIS::AI_BOT)); -} - -CAIEntity* CAIS::tryToGetAIEntity(const char* str) -{ - return dynamic_cast (tryToGetEntity(str)); -} - -CAIEntityPhysical* CAIS::tryToGetEntityPhysical(const char* str) -{ - CEntityId entityId; - entityId.fromString(str); - return CAIS::getEntityPhysical(CMirrors::DataSet->getDataSetRow(entityId)); -} - -CAIEntity* CAIS::tryToGetEntity(const char* str, TSearchType searchType) -{ - CAIInstance *aii = NULL; - CManager *mgr = NULL; - CBot *bot = NULL; - CGroup *grp = NULL; - - - vector parts; - explode(string(str), string(":"), parts, false); - - if (parts.empty() || parts[0].empty()) - return NULL; - - // skip AIS number if any - if (parts[0].substr(0, 4) == "AIS_") - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // instance index - uint32 index = atoui(parts[0].c_str()); - if (index >= CAIS::instance().AIList().size()) - goto tryWithEntityId; - aii = CAIS::AIList()[index]; - if (!aii) - goto tryWithEntityId; - if (searchType==CAIS::AI_INSTANCE - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return aii; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // branch on static or dynamic system - // manager index - if (parts[0].find("dyn_") == 0) - { - // parse dynamic id - - // continent index - index = atoui(parts[0].substr(4).c_str()); - if (index >= aii->continents().size()) - return NULL; - CContinent *continent = aii->continents()[index]; - if (searchType==CAIS::AI_CONTINENT - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return continent; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // region index - index = atoui(parts[0].c_str()); - if (index >= continent->regions().size()) - return NULL; - CRegion *region = continent->regions()[index]; - if (searchType==CAIS::AI_REGION - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return region; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // cellzone index - index = atoui(parts[0].c_str()); - if (index >= region->cellZones().size()) - return NULL; - CCellZone *cz = region->cellZones()[index]; - if (searchType==CAIS::AI_CELL_ZONE - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return cz; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // family behavior index - index = atoui(parts[0].c_str()); - if (index >= cz->familyBehaviors().size()) - return NULL; - CFamilyBehavior *fb = cz->familyBehaviors()[index]; - if (searchType==CAIS::AI_FAMILY_BEHAVIOR - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return fb; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) - return NULL; - - // manager index - if (parts[0] == "npc") - mgr = fb->mgrNpc(); - else if (parts[0] == "fauna") - mgr = fb->mgrFauna(); - - if (!mgr) - return NULL; - - if (searchType==CAIS::AI_MANAGER - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1) - || mgr == NULL) - return mgr; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - } - else - { - // parse static id - - // Manager index - index = atoui(parts[0].c_str()); - if (index >= aii->managers().size()) - return NULL; - mgr = aii->managers()[index]; - if (searchType==CAIS::AI_MANAGER - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1) - || mgr == NULL) - return mgr; - - parts.erase(parts.begin()); - - - // check - if (parts.empty() || parts[0].empty()) return NULL; - } - - // group index - index = atoui(parts[0].c_str()); - if (index >= mgr->groups().size()) - return NULL; - grp = mgr->groups()[index]; - if (searchType==CAIS::AI_GROUP - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return grp; - - parts.erase(parts.begin()); - - // check - if (parts.empty() || parts[0].empty()) return NULL; - - // bot index - index = atoui(parts[0].c_str()); - if (index >= grp->bots().size()) - return NULL; - bot = grp->bots()[index]; - if (searchType==CAIS::AI_BOT - || (searchType == CAIS::AI_UNDEFINED && parts.size() == 1)) - return bot; - - // what ? - return NULL; - -tryWithEntityId: - - CEntityId entityId; - entityId.fromString(str); - - if (entityId.isUnknownId()) - return NULL; - - CCont::iterator instanceIt=CAIS::instance().AIList().begin(), instanceItEnd=CAIS::instance().AIList().end(); - - while (instanceIt!=instanceItEnd) - { - CAIInstance *instancePtr=*instanceIt; - - CCont::iterator it=instancePtr->managers().begin(), itEnd=instancePtr->managers().end(); - - while (it!=itEnd) - { - CManager *mgrPtr = *it; - - CGroup *grpPtr = mgrPtr->getNextValidGroupChild (); - while (grpPtr) - { - CBot *botPtr = grpPtr->getNextValidBotChild(); - while (botPtr) - { - if ( botPtr->isSpawned() - && botPtr->getSpawnObj()->getEntityId() == entityId) - return dynamic_cast (botPtr); - botPtr = grpPtr->getNextValidBotChild (botPtr); - } - grpPtr=mgrPtr->getNextValidGroupChild (grpPtr); - } - ++it; - } - ++instanceIt; - } - return NULL; -} - - - - - - -//-------------------------------------------------------------------------- -// manageing the set of maps -//-------------------------------------------------------------------------- - -CAIEntityPhysical *CAIS::getEntityPhysical(const TDataSetRow& row) -{ - CHashMap >::iterator it(_CAIEntityByDataSetRow.find(row.getIndex())); - - if (it!=_CAIEntityByDataSetRow.end()) - return (*it).second; - else - return NULL; -// the code below generates an error .. :( hu ! -} - - -//------------------------------------------------------------------- -// Interface to bot chat - callbacks called when bots start or -// stop chatting with player(s) -//------------------------------------------------------------------- - -void CAIS::beginBotChat(const TDataSetRow &bot,const TDataSetRow &player) -{ -#ifdef NL_DEBUG - /// Is this still true? - nlwarning("Chat can't work now as bot are now splitted in persistent and spawnable part. Have to rework on this part."); -#endif - - // get a pointer to the bot - CSpawnBotNpc* botNpc=dynamic_cast(CAIS::getEntityPhysical(bot)); - if (!botNpc) - { -// nlwarning("CAIS::beginBotChat(): Bot chat message identifies an entity that isn't an NPC!!!"); - return; - } - - // get a pointer to the player - CBotPlayer* plrPtr = dynamic_cast(CAIS::getEntityPhysical(player)); - if (plrPtr==NULL) - { -// nlwarning("CAIS::beginBotChat(): Bot chat message identifies an unknown player!!!"); - return; - } - - // have the bot register the chat - botNpc->beginBotChat(plrPtr); -} - -void CAIS::endBotChat(const TDataSetRow &bot, const TDataSetRow &player) -{ - // get a pointer to the bot - CSpawnBotNpc* botNpc=dynamic_cast(CAIS::getEntityPhysical(bot)); - if (!botNpc) - { -// nlwarning("CAIS::endBotChat(): Bot chat message identifies an entity that isn't an NPC!!!"); - return; - } - - // get a pointer to the player - CBotPlayer* plrPtr = dynamic_cast(CAIS::getEntityPhysical(player)); - if (!plrPtr) - { -// nlwarning("CAIS::endBotChat(): Bot chat message identifies an unknown player!!!"); - return; - } - - // have the bot register the chat end - botNpc->endBotChat(plrPtr); -} - -void CAIS::beginDynChat(const TDataSetRow &bot) -{ - // get a pointer to the bot - CSpawnBotNpc* botNpc=dynamic_cast(CAIS::getEntityPhysical(bot)); - if (!botNpc) - { -// nlwarning("CAIS::beginBotChat(): Bot chat message identifies an entity that isn't an NPC!!!"); - return; - } - - // have the bot register the chat - botNpc->beginDynChat(); - nldebug( "DYNCHT: E%u: %u dyn chats", bot.getIndex(), botNpc->getNbActiveDynChats() ); -} - -void CAIS::endDynChat(const TDataSetRow &bot) -{ - // get a pointer to the bot - CSpawnBotNpc* botNpc=dynamic_cast(CAIS::getEntityPhysical(bot)); - if (!botNpc) - { -// nlwarning("CAIS::endBotChat(): Bot chat message identifies an entity that isn't an NPC!!!"); - return; - } - - // have the bot register the chat end - botNpc->endDynChat(); - nldebug( "DYNCHT: E%u: %u dyn chats", bot.getIndex(), botNpc->getNbActiveDynChats() ); -} - - -void CAIPlaceXYR::display(CStringWriter &stringWriter) const -{ - stringWriter.append("XYR: ("+_pos.x().toString() - +" " - +_pos.y().toString() - +" "+toString(_pos.h()) - +") Radius " - +toString(_radius) - +" " - +getName()); - -// nlinfo("XYR: (%s,%s,%d) x %f :%s",_pos.x().toString().c_str(),_pos.y().toString().c_str(),_pos.h(),_radius,getName().c_str()); -} - - -void CAIS::warnBadInstanceMsgImp(const std::string &serviceName, TServiceId serviceId, CWarnBadInstanceMsgImp &msg) -{ - // EGS says that an instance is spoofing an instance number or using a bad static instance number/continent name association. - // we must despawn/delete the aiinstance - - FOREACH(it, CCont, _AIInstances) - { - if ((*it)->getInstanceNumber()!=msg.InstanceNumber) - continue; - - // ok, we found the bad guy ! - nlwarning("CAIS::warnBadInstanceMsgImp: despawning AIInstance %u, instance number %u, continent '%s'", - (*it)->getChildIndex(), msg.InstanceNumber, (*it)->getContinentName().c_str()); - _AIInstances.removeChildByIndex((*it)->getChildIndex()); - return; - } - - // not found - nlwarning("CAIS::warnBadInstanceMsgImp: can't find AIInstance with instance number %u ! Can't despawn it", msg.InstanceNumber); -} - -void CAIS::updatePersistentVariables() -{ - if (CAIScriptDataManager::getInstance()->needsPersistentVarUpdate() == true) - { - // sending data to bs - CPersistentDataRecord pdr("AiTokenFamily"); - - CAIScriptDataManager::getInstance()->getPersistentVariables().store(pdr); - - uint32 bufSize= pdr.totalDataSize(); - vector buffer; - buffer.resize(bufSize); - pdr.toBuffer(&buffer[0],bufSize); - - CBackupMsgSaveFile msg( CAIScriptDataManager::getInstance()->makePdrFileName(), CBackupMsgSaveFile::SaveFile, Bsi ); - msg.DataMsg.serialBuffer((uint8*)&buffer[0], bufSize); - - Bsi.sendFile( msg ); - CAIScriptDataManager::getInstance()->clearDirtyFlag(); - } -} - -CAIInstance *CAIS::getAIInstance(uint32 instanceNumber) -{ - FOREACH(it, CCont, _AIInstances) - { - if ((*it)->getInstanceNumber()==instanceNumber) - return *it; - } - return NULL; -} diff --git a/code/ryzom/server/src/ai_service/ai.h b/code/ryzom/server/src/ai_service/ai.h deleted file mode 100644 index 57ff524ec..000000000 --- a/code/ryzom/server/src/ai_service/ai.h +++ /dev/null @@ -1,311 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AI_H -#define RYAI_AI_H - - -#include "child_container.h" -#include "server_share/msg_ai_service.h" -#include "nel/misc/random.h" -#include "nel/misc/variable.h" -#include "ai_entity_matrix.h" -#include "service_dependencies.h" -#include "game_share/task_list.h" - - -class CBot; -class CGroup; -class CManager; -class CContinent; -class CRegion; -class CCellZone; -class CFamilyBehavior; - -extern bool IOSHasMirrorReady; -extern bool EGSHasMirrorReady; - -extern const std::string disengageString; -extern const std::string egsString; - -extern NLMISC::CVariable TotalMaxPlayer; -extern NLMISC::CVariable TotalMaxPet; -extern NLMISC::CVariable TotalMaxFauna; -extern NLMISC::CVariable TotalMaxNpc; -extern NLMISC::CVariable TotalMaxFx; - -extern NLMISC::CVariable BotRepopFx; - - -template class CAIEntityMatrix; -class CAIEntityMatrixIteratorTblRandom; -class CAIEntityMatrixIteratorTblLinear; - - -//class CManager; -class CAIEntityPhysical; -class CAIEntity; -class CMgrPet; -class CManagerPlayer; -class CGroupNpc; -class CPersistentOfPhysical; - - -int getInt64FromStr (const char* str); - -/* - ----------------------------------------------------------------------------- - - AI is the singleton manager class for the high speed ai system - - ----------------------------------------------------------------------------- -*/ - -class CManagerPlayer; -class CAIInstance; - -class CWarnBadInstanceMsgImp : public CWarnBadInstanceMsg -{ -public: - void callback(const std::string &name, NLNET::TServiceId id); -}; - - -class CAIS : public CServiceEvent::CHandler -{ -public: - - // singleton access - static CAIS &instance(); - - static bool instanceCreated() { return _Instance != NULL; } - - static std::string getIndexString() { return NLMISC::toString("AIS_%u", NLNET::IService::getInstance()->getServiceId().get()); } - - //------------------------------------------------------------------- - // Constants - - //------------------------------------------------------------------- - // classic init(), update() and release() - - /** create an AI instance, return the instance index in the AIList - * Return std::numeric_limits::max() if the instance number is already in use. - */ - uint32 createAIInstance(const std::string &continentName, uint32 instanceNumber); - /** destroy an AI Instance (useful for ring creation / destruction of session) - @param instanceNumber is the AiInstance Id - @param displayWarningIfInstanceNotExist If false nothing happends when the specified instance do not exist - */ - void destroyAIInstance(uint32 instanceNumber, bool displayWarningIfInstanceNotExist); - - // the update routine called once per tick - // this is the routine that calls the managers' updates - void update(); - - // This routine is called once every 1000 ticks - // updates the persistent ai script variables values on the Backup Service - void updatePersistentVariables(); - - // release the singleton before program exit - void release(); - - void serviceEvent (const CServiceEvent &info); - - // Management of deleted root alias - bool markTagForDelete(const std::string &filename); - void deleteTaggedAlias(const std::string &filename); - - //------------------------------------------------------------------- - // dealing with backups (save and restore) - - // provoke a general 'save to backup' across the whole service - void save(); - - inline void setClientCreatureDebug (bool clientCreatureDebug) - { - _ClientCreatureDebug=clientCreatureDebug; - } - - inline bool clientCreatureDebug () - { - return _ClientCreatureDebug; - } - - - - //------------------------------------------------------------------- - // Interface to bot chat - callbacks called when bots start or - // stop chatting with player(s) - void beginBotChat (const TDataSetRow &bot, const TDataSetRow &player); - void endBotChat (const TDataSetRow &bot, const TDataSetRow &player); - void beginDynChat (const TDataSetRow &bot); - void endDynChat (const TDataSetRow &bot); - - //------------------------------------------------------------------- - // manageing the set of managers - - // a method that parse a supposed know type of manager:group:bot hierarchy and return the element as CAIEntity. - CAIEntityPhysical *tryToGetEntityPhysical (const char *str); - CAIInstance *tryToGetAIInstance (const char *str); - - // dynamic system branch - CContinent *tryToGetContinent (const char *str); - CRegion *tryToGetRegion (const char *str); - CCellZone *tryToGetCellZone (const char *str); - CFamilyBehavior *tryToGetFamilyBehavior (const char *str); - - // generic branch - CManager *tryToGetManager (const char *str); - CGroup *tryToGetGroup (const char *str); - CBot *tryToGetBot (const char *str); - CAIEntity *tryToGetAIEntity (const char *str); - - //------------------------------------------------------------------- - // the previous interfaces for searching the data structures for named objects are transfered in CAIEntityId - // as its one of their object behavior. a solution to build id directly was added. - - // to update the map. - friend class CAIEntityPhysical; - CAIEntityPhysical *getEntityPhysical(const TDataSetRow &); - - //------------------------------------------------------------------- - // Interface to the vision management matrices - - // read accessors for getting hold of the vision matrices and their associated iterator tables - inline const CAIEntityMatrixIteratorTblRandom *matrixIterator2x2(); - inline const CAIEntityMatrixIteratorTblRandom *matrixIterator3x3(); - const CAIEntityMatrixIteratorTblLinear *bestLinearMatrixIteratorTbl(uint32 distInMeters); - - //------------------------------------------------------------------- - // Interface to the random number generator - static inline sint32 randPlusMinus(uint16 mod); - static inline float frand(double mod=1.0); - static inline float frandPlusMinus(double mod); - static inline uint32 rand32(); - // WARNING : this rand has a 'coherent' behavior : ie it return value between 0 and mod-1 - static inline uint32 rand32(uint32 mod); - // WARNING : this rand has a 'coherent' behavior : ie it return value between 0 and mod-1 - static inline uint32 rand16(uint32 mod); - - /// Time warp managment. This method is called when time as warped more than 600ms - bool advanceUserTimer(uint32 nbTicks); - - /// Retreive emot number given it's name, return std::numeric_limits::max() if not found - uint32 getEmotNumber(const std::string &name); - - CCont &AIList () { return _AIInstances; } - CCont &aiinstances() { return _AIInstances; } ///< This is a synonym for AIList, but should replace it as it's more coherent with general 'nomenclature' - - CAIInstance *getAIInstance(uint32 instanceNumber); - - CFaunaBotDescription &getFaunaDescription() - { - return _FaunaDescriptionList; - } - CChangeCreatureHPMsg &getCreatureChangeHP() - { - return _CreatureChangeHPList; - } - - CChangeCreatureMaxHPMsg &getCreatureChangeMaxHP() - { - return _CreatureChangeMaxHPList; - } - - enum TSearchType - { - AI_INSTANCE = 0, - AI_CONTINENT, - AI_REGION, - AI_CELL_ZONE, - AI_FAMILY_BEHAVIOR, - AI_MANAGER, - AI_GROUP, - AI_BOT, - AI_UNDEFINED - }; - - class CCounter - { - public: - CCounter(const uint32 max=std::numeric_limits::max()):_Total(0),_Max(max) - {} - virtual ~CCounter() - {} - void setMax(const uint32 max) { _Max=max; } - void inc() { _Total++; } - void dec() { _Total--; } - uint32 getTotal() const { return _Total; } - bool remainToMax (uint32 nbMore=1) const { return (_Total+nbMore)<_Max; } - protected: - private: - uint32 _Total; - uint32 _Max; - }; - - CCounter _PetBotCounter; - CCounter _NpcBotCounter; - CCounter _FaunaBotCounter; - - // message from EGS about bad aiinstance - void warnBadInstanceMsgImp(const std::string &serviceName, NLNET::TServiceId serviceId, CWarnBadInstanceMsgImp &msg); - - void addTickedTask(uint32 tick, CTask* task) { _TickedTaskList.addTaskAt(tick, task); } - - -private: - - // private constructor - CAIS(); - - // initialise the singleton - void initAI(); - - /// Singleton instance - static CAIS *_Instance; - - CAIEntity* tryToGetEntity (const char* str, TSearchType searchType=AI_UNDEFINED); - // Global map of entity in this shard - CHashMap > _CAIEntityByDataSetRow; - - // the random number generator - static NLMISC::CRandom _random; - - CAIEntityMatrixIteratorTblRandom _matrixIterator2x2; - CAIEntityMatrixIteratorTblRandom _matrixIterator3x3; - std::vector _matrixIteratorsByDistance; - - // Faunas descriptions to be sent each frame - CFaunaBotDescription _FaunaDescriptionList; - CChangeCreatureHPMsg _CreatureChangeHPList; - CChangeCreatureMaxHPMsg _CreatureChangeMaxHPList; - - /// The emot identifiers - std::map _EmotNames; - CCont _AIInstances; - - uint32 _TotalBotsSpawned; - bool _ClientCreatureDebug; - CTaskList _TickedTaskList; -}; - - - -#include "ai_inline.h" - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_aggro.cpp b/code/ryzom/server/src/ai_service/ai_aggro.cpp deleted file mode 100644 index 5d771f569..000000000 --- a/code/ryzom/server/src/ai_service/ai_aggro.cpp +++ /dev/null @@ -1,621 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#include "stdpch.h" -#include "ai_aggro.h" -#include "ai_entity_physical.h" -#include "ai_entity_physical_inline.h" -#include "ai_instance.h" -#include "ai_player.h" - -////////////////////////////////////////////////////////////////////////////// -// CBotAggroEntry // -////////////////////////////////////////////////////////////////////////////// - -CBotAggroEntry::CBotAggroEntry(TDataSetRow const& bot, float aggro, CBotAggroOwner const& owner, NLMISC::CSmartPtr place) -: _Bot(bot) -, _Owner(owner) -, _LastHitPlace(place) -{ -#ifdef NL_DEBUG - nlassert(aggro>=0.f); -#endif - _Aggro = aggro; - _Owner.aggroGain(_Bot); -} - -CBotAggroEntry::~CBotAggroEntry() -{ - if(_Owner.getSendAggroLostToEGS()) - _Owner.aggroLost(_Bot); -} - -void CBotAggroEntry::operator =(CBotAggroEntry const& other) -{ -#ifdef NL_DEBUG - nlassert(&_Owner==&other._Owner); // same owner ? -#endif - _Bot = other._Bot; - _Aggro = other._Aggro; -} - -void CBotAggroEntry::addAggro(float aggro, NLMISC::CSmartPtr place) -{ - // prevent to add aggro on a bot more than one time per tick. - _Aggro += (1.f-_Aggro)*(aggro); - if (place!=NULL) - _LastHitPlace = place; -} - -bool CBotAggroEntry::updateTime(uint32 const& ticks) const -{ - const_cast(this)->decrementAggros(ticks); - return _Aggro==0.f; -} - -void CBotAggroEntry::setMinimum(float aggro, NLMISC::CSmartPtr place) -{ - if (aggro>=0.f && aggro<=1.f && _Aggro=0.f && aggro<=1.f && _Aggro>aggro) - { - _Aggro = aggro; - } -} - -void CBotAggroEntry::decrementAggros(uint32 ticks) -{ - static float const TOTAL_DECAY_TIME_SEC = 120.f; // temporary. - static float const AGGRO_DEC = (1.f/(TOTAL_DECAY_TIME_SEC*10.f)); - float const decay = (float)(ticks*AGGRO_DEC); - - if (_Aggro>decay) - { - _Aggro -= decay; - } - else - { - _Aggro = 0.f; - } -} - -////////////////////////////////////////////////////////////////////////////// -// CBotAggroOwner // -////////////////////////////////////////////////////////////////////////////// -/* -double CBotAggroOwner::defaultReturnDistCheck = 1.5; -uint32 CBotAggroOwner::defaultD1Radius = 100 * 1000; // en mm -uint32 CBotAggroOwner::defaultD2Radius = 50 * 1000; // en mm -float CBotAggroOwner::defaultPrimaryGroupAggroCoef = 0.f; // %age, entre 0 et 1 -float CBotAggroOwner::defaultSecondaryGroupAggroCoef = 0.f; // %age, entre 0 et 1 -uint32 CBotAggroOwner::defaultAggroPropagationRadius = 60; // en m -*/ -float CBotAggroOwner::getReturnDistCheck() const -{ - return AggroReturnDistCheck; -} - -float CBotAggroOwner::getD1Radius() const -{ - return AggroD1Radius; -} - -float CBotAggroOwner::getD2Radius() const -{ - return AggroD2Radius; -} - -float CBotAggroOwner::getPrimaryGroupAggroDist() const -{ - return AggroPrimaryGroupDist; -} - -float CBotAggroOwner::getPrimaryGroupAggroCoef() const -{ - return AggroPrimaryGroupCoef; -} - -float CBotAggroOwner::getSecondaryGroupAggroDist() const -{ - return AggroSecondaryGroupDist; -} - -float CBotAggroOwner::getSecondaryGroupAggroCoef() const -{ - return AggroSecondaryGroupCoef; -} - -float CBotAggroOwner::getAggroPropagationRadius() const -{ - return AggroPropagationRadius; -} - - -CBotAggroOwner::CBotAggroOwner() -: _LastHitTime(CTimeInterface::gameCycle()) -, _AggroBlocked(false) -, _ReturnAggroIgnored(false) -, _DontAggro(false) -, _SendAggroLostToEGS(true) -, _ReturnPos() -, _FirstHitPlace(NULL) -//, _State(NoAggro) -{ -} - -CBotAggroOwner::~CBotAggroOwner() -{ -#ifdef NL_DEBUG - nlassert(_BotAggroList.size()==0); // have to clear this vector before call destructor (coz of call back). -#endif -} - -void CBotAggroOwner::mergeAggroList(CBotAggroOwner const& otherList, float scale) -{ - H_AUTO(AGGRO_mergeAggroList); - NLMISC::clamp(scale, 0.0f, 1.0f); - - FOREACHC(it, TBotAggroList, otherList._BotAggroList) - { - CBotAggroEntry* bae = it->second; - setAggroMinimumFor(bae->getBot(), bae->finalAggro()*scale, true, bae->getLastHitPlace()); - } -} - - -void CBotAggroOwner::updateListAndMarkBot(std::vector& botList, float coef) -{ - H_AUTO(AGGRO_ULAMB); - std::list botsToRemove; - { - H_AUTO(AGGRO_ULAMB_buildList); - FOREACH(it, TBotAggroList, _BotAggroList) - { - if (!isAggroValid(it->first)) - { - botsToRemove.push_back(it->first); - continue; - } - CAIEntityPhysical* const entity = CAIS::instance().getEntityPhysical(it->second->getBot()); - nlassert(entity); // if this entry is no more valid, then isAggroValid is bugged - if (entity->_ChooseLastTime!=CTimeInterface::gameCycle()) - { - entity->_ChooseLastTime = CTimeInterface::gameCycle(); - entity->_AggroScore = it->second->finalAggro()*coef; - botList.push_back(entity); - } - else - { - entity->_AggroScore += it->second->finalAggro()*coef; - } - } - } - { - H_AUTO(AGGRO_ULAMB_removeInvalids); - FOREACH(it, std::list, botsToRemove) - { - _BotAggroList.erase(*it); - } - } -} - -void CBotAggroOwner::blockAggro(sint32 blockTime) -{ - if (!_AggroBlocked || _AggroBlockTimer.timeRemaining() botsToRemove; - FOREACH(it, TBotAggroList, _BotAggroList) - { - // :TODO: Check aggro validity (target position), but it's too expensive I think - if (it->second->updateTime(ticks)) - { - botsToRemove.push_back(it->first); - } - else - { - CAIEntityPhysical* const entity = CAIS::instance().getEntityPhysical(it->second->getBot()); - if (!entity) - botsToRemove.push_back(it->first); - } - } - FOREACH(it, std::deque, botsToRemove) - { - _BotAggroList.erase(*it); - } - if (_BotAggroList.empty() && _FirstHitPlace) - { - if (_ReturnPos.toAIVector().quickDistTo(getAggroPos().toAIVector()) < getReturnDistCheck()) - _FirstHitPlace = NULL; - } -} - -// :NOTE: If you modify this method modify isNewAggroValid accordingly. -bool CBotAggroOwner::isAggroValid(TDataSetRow const& bot) -{ - H_AUTO(AGGRO_isAggroValid); - TBotAggroList::iterator it = _BotAggroList.find(bot); - // Bot has no aggro - if (it==_BotAggroList.end()) - return false; - // Other bot don't exist - CAIEntityPhysical const* entity = CAIS::instance().getEntityPhysical(bot); - if (!entity) - return false; - // Bot fled too far from last time he hit - if (!it->second->atPlace(entity)) - return false; - // He's outside of first hit place - if (!this->atPlace(entity)) - return false; - // He seems OK, let's aggro him - return true; -} - -// :NOTE: If you modify this method modify isAggroValid accordingly. -bool CBotAggroOwner::isNewAggroValid(TDataSetRow const& bot) -{ - H_AUTO(AGGRO_isNewAggroValid); - // Other bot don't exist - CAIEntityPhysical const* entity = CAIS::instance().getEntityPhysical(bot); - if (!entity) - return false; - // He's outside of first hit place - if (!this->atPlace(entity)) - return false; - // He seems OK, let's aggro him - return true; -} - -bool CBotAggroOwner::haveAggroWithEntity(const TDataSetRow& rowId) const -{ - H_AUTO(AGGRO_haveAggroWithEntity); - return _BotAggroList.find(rowId) != _BotAggroList.end(); -} - -void CBotAggroOwner::addAggroFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place, bool transferAggro) -{ - H_AUTO(AGGRO_AA_Total); - if (!isAggroable(bot) || (_ReturnAggroIgnored && !forceReturnAggro)) - return; - - if (_DontAggro) - return; - - // If group aggro build a bot list who aggro (self included), and return - if (transferAggro && getPrimaryGroupAggroCoef()>0.f) - { - std::set primaryGroup, secondaryGroup; - { - H_AUTO(AGGRO_AA_BuildAggroTransferList); - primaryGroup = getAggroGroup(true); - primaryGroup.erase(this); - FOREACH(it, std::set, primaryGroup) - { - if (*it) - { - std::set aggroGroup = (*it)->getAggroGroup(false); - std::set_difference(aggroGroup.begin(), aggroGroup.end(), primaryGroup.begin(), primaryGroup.end(), std::inserter(secondaryGroup, secondaryGroup.end())); - } - } - secondaryGroup.erase(this); - } - this->addAggroFor(bot, aggro, forceReturnAggro, place, false); - FOREACH(it, std::set, primaryGroup) - (*it)->addAggroFor(bot, aggro*getPrimaryGroupAggroCoef(), forceReturnAggro, place, false); - FOREACH(it, std::set, secondaryGroup) - (*it)->addAggroFor(bot, aggro*getSecondaryGroupAggroCoef(), forceReturnAggro, place, false); - return; - } - -#ifdef NL_DEBUG - nlassert(aggro<=0); -#endif - - // If we have no firstHitPlace start fight - if (!_FirstHitPlace) - { - H_AUTO(AGGRO_AA_BuildFirstHitPlace); - _ReturnPos = getAggroPos(); - _FirstHitPlace = buildFirstHitPlace(bot); - } - // Else verify this bot is still in range - else - { - H_AUTO(AGGRO_AA_CheckFirstHitPlace); - // If aggro is not valid for that bot (he's outside of range) - if (!isNewAggroValid(bot)) - { - // Forget him - forgetAggroFor(bot, true); - // And ignore him - return; - } - } - if (!place) - { - H_AUTO(AGGRO_AA_BuildLastHitPlace); - CAIEntityPhysical const* entity = NULL; - H_TIME(AGGRO_AA_BLHP_GetEntity, entity = CAIS::instance().getEntityPhysical(bot);); - if (entity) - { - NLMISC::CSmartPtr newPlace(NULL); - H_TIME(AGGRO_AA_BLHP_AllocPlace, newPlace = NLMISC::CSmartPtr(new CAIPlaceFastXYR(NULL));); - H_TIME(AGGRO_AA_BLHP_ParamPlace, newPlace->setPosAndRadius(AITYPES::vp_auto, entity->pos(), (uint32)(getD2Radius()*1000.f));); - place = newPlace; - } - } - - _LastHitTime = CTimeInterface::gameCycle(); - - TBotAggroList::iterator it = _BotAggroList.find(bot); - if (it!=_BotAggroList.end()) - { - H_AUTO(AGGRO_AA_AddAggro); - it->second->addAggro(-aggro, place); - } - else - { - H_AUTO(AGGRO_AA_CreateAggro); - // not found, so add it. - // as its the first time, majorate aggro (square its effect).. - float firstAggro = 1+aggro; - firstAggro = 1-firstAggro*firstAggro; - - _BotAggroList.insert(std::make_pair(bot, TAggroEntryPtr(new CBotAggroEntry(bot, firstAggro, *this, place)))); - } -} - -void CBotAggroOwner::setAggroMinimumFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place, bool transferAggro) -{ - H_AUTO(AGGRO_SAM_Total); - if (!isAggroable(bot) || (_ReturnAggroIgnored && !forceReturnAggro)) - return; - - if (_DontAggro) - return; - - // If group aggro build a bot list who aggro (self included), and return - if (transferAggro && getPrimaryGroupAggroCoef()>0.f) - { - std::set primaryGroup, secondaryGroup; - { - H_AUTO(AGGRO_SAM_BuildAggroTransferList); - primaryGroup = getAggroGroup(true); - primaryGroup.erase(this); - FOREACH(it, std::set, primaryGroup) - { - if (*it) - { - std::set aggroGroup = (*it)->getAggroGroup(false); - std::set_difference(aggroGroup.begin(), aggroGroup.end(), primaryGroup.begin(), primaryGroup.end(), std::inserter(secondaryGroup, secondaryGroup.end())); - } - } - secondaryGroup.erase(this); - } - this->setAggroMinimumFor(bot, aggro, forceReturnAggro, place, false); - FOREACH(it, std::set, primaryGroup) - (*it)->setAggroMinimumFor(bot, aggro*getPrimaryGroupAggroCoef(), forceReturnAggro, place, false); - FOREACH(it, std::set, secondaryGroup) - (*it)->setAggroMinimumFor(bot, aggro*getSecondaryGroupAggroCoef(), forceReturnAggro, place, false); - return; - } - -#ifdef NL_DEBUG - nlassert(aggro>=0); -#endif - if (!_FirstHitPlace) - { - H_AUTO(AGGRO_SAM_BuildFirstHitPlace); - _ReturnPos = getAggroPos(); - _FirstHitPlace = buildFirstHitPlace(bot); - } - // Else verify this bot is still in range - else - { - H_AUTO(AGGRO_SAM_CheckFirstHitPlace); - // If aggro is not valid for that bot (he's outside of range) - if (!isNewAggroValid(bot)) - { - // Forget him - forgetAggroFor(bot, true); - // And ignore him - return; - } - } - if (!place) - { - H_AUTO(AGGRO_SAM_BuildLastHitPlace); - CAIEntityPhysical const* entity = NULL; - H_TIME(AGGRO_SAM_BLHP_GetEntity, entity = CAIS::instance().getEntityPhysical(bot);); - if (entity) - { - NLMISC::CSmartPtr newPlace(NULL); - H_TIME(AGGRO_SAM_BLHP_AllocPlace, newPlace = NLMISC::CSmartPtr(new CAIPlaceFastXYR(NULL));); - H_TIME(AGGRO_SAM_BLHP_ParamPlace, newPlace->setPosAndRadius(AITYPES::vp_auto, entity->pos(), (uint32)(getD2Radius()*1000.f));); - place = newPlace; - } - } - - TBotAggroList::iterator it = _BotAggroList.find(bot); - if (it!=_BotAggroList.end()) - { - H_AUTO(AGGRO_SAM_SetMinimum); - it->second->setMinimum(aggro, place); - } - else - { - H_AUTO(AGGRO_SAM_CreateAggro); - // not found, so add it. - _BotAggroList.insert(std::make_pair(bot, TAggroEntryPtr(new CBotAggroEntry(bot, aggro, *this, place)))); - } -} - -void CBotAggroOwner::maximizeAggroFor(TDataSetRow const& bot) -{ - H_AUTO(AGGRO_maximizeAggroFor); - if (!isAggroable(bot)) - return; - - if (_DontAggro) - return; - - TBotAggroList::iterator it = _BotAggroList.find(bot); - if (it!=_BotAggroList.end()) - { - it->second->setMinimum(0.999f); - FOREACH(it2, TBotAggroList, _BotAggroList) - { - if (it2!=it) - it2->second->scaleBy(0.15f); - } - } - else - { - _BotAggroList.insert(std::make_pair(bot, TAggroEntryPtr(new CBotAggroEntry(bot, 0.999f, *this)))); - } -} - -void CBotAggroOwner::minimizeAggroFor(TDataSetRow const& bot) -{ - H_AUTO(AGGRO_minimizeAggroFor); - if (!isAggroable(bot)) - return; - - if (_DontAggro) - return; - - TBotAggroList::iterator it = _BotAggroList.find(bot); - if (it!=_BotAggroList.end()) - { - it->second->setMaximum(0.1f); - FOREACH(it2, TBotAggroList, _BotAggroList) - { - if (it2!=it) - it2->second->setMinimum(0.15f); - } - } - else - { - _BotAggroList.insert(std::make_pair(bot, TAggroEntryPtr(new CBotAggroEntry(bot, 0.1f, *this)))); - } -} - -void CBotAggroOwner::forgetAggroFor(TDataSetRow const& bot, bool forgetDamages) -{ - H_AUTO(AGGRO_forgetAggroFor); - _BotAggroList.erase(bot); - if (forgetDamages && getAggroOwnerEid()!=NLMISC::CEntityId::Unknown) - { - CAIEntityPhysical* const entity = CAIS::instance().getEntityPhysical(bot); - if (entity) - { - // Tell EGS that player is a cheater - if (entity->getRyzomType()==RYZOMID::player) - { - NLMISC::CEntityId targetId = entity->getEntityId(); - NLMISC::CEntityId botId = getAggroOwnerEid(); - - NLNET::CMessage msgout("PLAYER_UNREACHABLE"); - msgout.serial(botId); - msgout.serial(targetId); - sendMessageViaMirror("EGS", msgout); - } - } - } -} - -bool CBotAggroOwner::hasBeenHit(uint32 ticks) const -{ - return (CTimeInterface::gameCycle()-_LastHitTime)<=ticks; -} - -bool CBotAggroOwner::isAggroable(TDataSetRow const& dataSetRow) -{ - H_AUTO(AGGRO_isAggroable); - if (CMirrors::getEntityId(dataSetRow).getType()!=RYZOMID::player) - return true; - - CAIEntityPhysical* ep = CAIS::instance().getEntityPhysical(dataSetRow); - if (!ep) - return false; - - CBotPlayer const* const player = NLMISC::safe_cast(ep); - if (!player) - return true; - return player->isAggroable(); -} - -RYAI_MAP_CRUNCH::CWorldPosition CBotAggroOwner::getAggroPos() const -{ - return RYAI_MAP_CRUNCH::CWorldPosition(); -} - -NLMISC::CEntityId CBotAggroOwner::getAggroOwnerEid() const -{ - return NLMISC::CEntityId::Unknown; -} - -NLMISC::CSmartPtr CBotAggroOwner::buildFirstHitPlace(TDataSetRow const& aggroBot) const -{ - return NLMISC::CSmartPtr(NULL); -} - -void CBotAggroOwner::clearAggroList(bool sendMessageToEGS) -{ - _SendAggroLostToEGS = sendMessageToEGS; - _BotAggroList.clear(); - _SendAggroLostToEGS = true; -} - -float CBotAggroOwner::getAggroFor(TDataSetRow const& bot) -{ - TBotAggroList::iterator it = _BotAggroList.find(bot); - if (it!=_BotAggroList.end()) - return it->second->finalAggro(); - else - return 0.f; -} diff --git a/code/ryzom/server/src/ai_service/ai_aggro.h b/code/ryzom/server/src/ai_service/ai_aggro.h deleted file mode 100644 index 07081ef5d..000000000 --- a/code/ryzom/server/src/ai_service/ai_aggro.h +++ /dev/null @@ -1,167 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef AI_AGGRO_H -#define AI_AGGRO_H - -#include "timer.h" -#include "ai.h" -#include "ai_place.h" - -class CBotAggroOwner; -class CAIEntityPhysical; - -////////////////////////////////////////////////////////////////////////////// -// CBotAggroEntry // -////////////////////////////////////////////////////////////////////////////// - -/** A pair of aggro/entity values. - * - * Aggro values are between 0 and 1. 0 means no aggro, 1 means full aggro. - */ -class CBotAggroEntry -: public NLMISC::CRefCount -{ -public: - CBotAggroEntry(TDataSetRow const& bot, float aggro, CBotAggroOwner const& owner, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL)); - virtual ~CBotAggroEntry(); - - float finalAggro() const { return _Aggro; } - - void addAggro(float aggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL)); - void decrementAggros(uint32 ticks); - - bool updateTime(uint32 const& ticks) const; - - TDataSetRow const& getBot() const { return _Bot; } - NLMISC::CSmartPtr getLastHitPlace() const { return _LastHitPlace; } - - void setMinimum(float aggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL)); - void setMaximum(float aggro); - - void scaleBy(float const& scale) { _Aggro *= scale; } - - void operator=(CBotAggroEntry const& other); - - virtual bool atPlace(CAIVector const& pos) const { if (_LastHitPlace) return _LastHitPlace->atPlace(pos); else return true; } - virtual bool atPlace(CAIVectorMirror const& pos) const { if (_LastHitPlace) return _LastHitPlace->atPlace(pos); else return true; } - virtual bool atPlace(CAIEntityPhysical const* entity) const { if (_LastHitPlace) return _LastHitPlace->atPlace(entity); else return true; } - -private: - CBotAggroOwner const& _Owner; - TDataSetRow _Bot; - float _Aggro; - NLMISC::CSmartPtr _LastHitPlace; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotAggroOwner // -////////////////////////////////////////////////////////////////////////////// - -class CBotAggroOwner -{ -public: - typedef NLMISC::CSmartPtr TAggroEntryPtr; - typedef std::map TBotAggroList; - -public: - CBotAggroOwner(); - virtual ~CBotAggroOwner(); - - static bool isAggroable(TDataSetRow const& dataSetRow); - - void update(uint32 ticks); - - /// @name Management of an aggro entry - //@{ - /// Command used by fight script only - void blockAggro(sint32 blockTime); - void ignoreReturnAggro(bool ignored); - virtual void maximizeAggroFor(TDataSetRow const& botRow); - /// Command used by fight script only - void minimizeAggroFor(TDataSetRow const& botRow); - void addAggroFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL), bool transferAggro = true); - // Sets the minimum value the aggro can have in [0;1] - void setAggroMinimumFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL), bool transferAggro = true); - void forgetAggroFor(TDataSetRow const& bot, bool forgetDamages = false); - bool isAggroValid(TDataSetRow const& bot); - bool isNewAggroValid(TDataSetRow const& bot); - bool haveAggro() const { return !_BotAggroList.empty(); } - bool haveAggroWithEntity(const TDataSetRow& rowId) const; - bool haveAggroOrReturnPlace() const { return haveAggro() || _FirstHitPlace!=NULL; } - virtual RYAI_MAP_CRUNCH::CWorldPosition getAggroPos() const; - virtual NLMISC::CEntityId getAggroOwnerEid() const; - virtual NLMISC::CSmartPtr buildFirstHitPlace(TDataSetRow const& aggroBot) const; - virtual std::set getAggroGroup(bool primary) const { return std::set(); } - virtual void propagateAggro() const { } - - virtual float getReturnDistCheck() const; - virtual float getD1Radius() const; - virtual float getD2Radius() const; - virtual float getPrimaryGroupAggroDist() const; - virtual float getPrimaryGroupAggroCoef() const; - virtual float getSecondaryGroupAggroDist() const; - virtual float getSecondaryGroupAggroCoef() const; - virtual float getAggroPropagationRadius() const; - //@} - - float getAggroFor(TDataSetRow const& bot); - - /// Used by CSpawnBotFauna for assist only - bool hasBeenHit(uint32 ticks) const; - - /// Used by group fight profile only - /// merge all the aggro value from the other aggro list into this aggro list - void mergeAggroList(CBotAggroOwner const& otherList, float scale); - - void updateListAndMarkBot(std::vector& botList, float coef); - - void setCanAggro(bool canAggro); - - bool getSendAggroLostToEGS() const { return _SendAggroLostToEGS; } - - /// @name Accessors - //@{ - TBotAggroList const& getBotAggroList() const { return _BotAggroList; } - void clearAggroList(bool sendMessageToEGS = true); - bool isReturning() const { return _BotAggroList.empty() && _FirstHitPlace; } - RYAI_MAP_CRUNCH::CWorldPosition getReturnPos() const { return _ReturnPos; } - //@} - - /// @name Event handlers - //@{ - virtual void aggroLost(TDataSetRow const& aggroBot) const = 0; - virtual void aggroGain(TDataSetRow const& aggroBot) const = 0; - //@} - -private: - virtual bool atPlace(CAIVector const& pos) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(pos); else return true; } - virtual bool atPlace(CAIVectorMirror const& pos) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(pos); else return true; } - virtual bool atPlace(CAIEntityPhysical const* entity) const { if (_FirstHitPlace) return _FirstHitPlace->atPlace(entity); else return true; } - -private: - TBotAggroList _BotAggroList; - uint32 _LastHitTime; - bool _AggroBlocked; - bool _ReturnAggroIgnored; - bool _DontAggro; - bool _SendAggroLostToEGS; - CAITimer _AggroBlockTimer; - RYAI_MAP_CRUNCH::CWorldPosition _ReturnPos; - NLMISC::CSmartPtr _FirstHitPlace; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot.cpp b/code/ryzom/server/src/ai_service/ai_bot.cpp deleted file mode 100644 index 6698de755..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot.cpp +++ /dev/null @@ -1,844 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_bot.h" -#include "visual_properties_interface.h" -#include "server_share/msg_brick_service.h" -#include "server_share/r2_variables.h" - -using namespace MULTI_LINE_FORMATER; - -extern NLLIGO::CLigoConfig LigoConfig; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBot // -////////////////////////////////////////////////////////////////////////////// - -CSpawnBot::CSpawnBot(TDataSetRow const& entityIndex, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CModEntityPhysical(owner, entityIndex, id, radius, level, denyFlags) -, _SpawnGroup(owner.getOwner()->getSpawnObj()) -, CProfileOwner() -, CDynSpawnBot(owner) -, _DamageSpeedCoef(1.f) -, _DamageCoef(1.f) -, _LastHealTick(0) -, _LastSelfHealTick(0) -, _SpeedFactor(1.f) -{ - nlassert(owner.getOwner()->getSpawnObj()); - spawnGrp().incSpawnedBot(getPersistent()); - getPersistent().getSpawnCounter().inc(); - setInstanceNumber(getAIInstance()->getInstanceNumber()); -} - -CSpawnBot::~CSpawnBot() -{ - clearAggroList(); - getPersistent().unlinkFromWorldMap(); - spawnGrp().decSpawnedBot(); - getPersistent().getSpawnCounter().dec(); -} - -CAIInstance* CSpawnBot::getAIInstance() const -{ - return getPersistent().getAIInstance(); -} - -void CSpawnBot::setVisualPropertiesName() -{ - CBot& botRef = CSpawnBot::getPersistent(); - ucstring name = botRef.getName(); - - if (CVisualPropertiesInterface::UseIdForName) - { - name = NLMISC::toString("AI:%s", botRef.getIndexString().c_str()); - } - - if (name.empty() && CVisualPropertiesInterface::ForceNames) - { - name = NLMISC::CFile::getFilenameWithoutExtension(botRef.getSheet()->SheetId().toString().c_str()); - } - - if (!botRef.getCustomName().empty()) - name = botRef.getCustomName(); - - // no name the bot will appear without name on the client. - if (name.empty()) - return; - - - // In ringshard we use npc with fauna sheet but we want to be enable to change theire name - if (! botRef.getFaunaBotUseBotName()) //false by default - { - if (botRef.getSheet()->ForceDisplayCreatureName()) - return; - // the npc name is displayed as a fauna - } - - CVisualPropertiesInterface::setName(dataSetRow(), name); -} - -float CSpawnBot::fightWeight() const -{ - if (getPersistent().isSheetValid()) - { - AISHEETS::ICreatureCPtr sheet = getPersistent().getSheet(); - if (!sheet->FightConfig(AISHEETS::FIGHTCFG_MELEE).isNULL()) - { - // Melee fighters use a lot of space - return .98f; - } - else - { - if (!sheet->FightConfig(AISHEETS::FIGHTCFG_NUKE).isNULL()) - return .01f; - if (!sheet->FightConfig(AISHEETS::FIGHTCFG_RANGE).isNULL()) - return .01f; - // :FIXME: We consider healers are melee, coz they can't heal for the moment and use default attack. - if (!sheet->FightConfig(AISHEETS::FIGHTCFG_HEAL).isNULL()) - return .98f; - // All others are like melee (default attack) - return .98f; - } - } - return this->CAIEntityPhysical::fightValue(); -} - -float CSpawnBot::fightValue() const -{ - if (getPersistent().isSheetValid()) - { - AISHEETS::ICreatureCPtr sheet = getPersistent().getSheet(); - return (float)(sheet->XPLevel() * sheet->NbPlayers()); - } - return this->CAIEntityPhysical::fightValue(); -} - -CSpawnGroup& CSpawnBot::spawnGrp() const -{ -#if !FINAL_VERSION - nlassert(NLMISC::safe_cast(getPersistent().getGroup().getSpawnObj()) == _SpawnGroup); -#endif - return *_SpawnGroup; -} - -std::vector CSpawnBot::getMultiLineInfoString() const -{ - std::vector container; - - - pushTitle(container, "CSpawnBot"); - pushEntry(container, "dataSetRow=" + NLMISC::toString("%x", dataSetRow().counter()) + ":" + NLMISC::toString("%X", dataSetRow().getIndex())); - container.back() += " pos/rot=" + pos().toString(); - if ((CAIEntityPhysical*)getTarget()) - container.back() += NLMISC::toString(" target=%s", getTarget()->getEntityId().toString().c_str()); - if (isBlinded()) - container.back() += NLMISC::toString(" blinded"); - if (isRooted()) - container.back() += NLMISC::toString(" rooted"); - if (isStuned()) - container.back() += NLMISC::toString(" stuned"); - if (isFeared()) - container.back() += NLMISC::toString(" feared"); - pushEntry(container, "outpost: "); - container.back() += " alias=" + LigoConfig.aliasToString(outpostAlias()); - container.back() += " side="; - container.back() += outpostSide()?"attacker":"defender"; - pushEntry(container, "haveAggro=" + NLMISC::toString(haveAggro())); - container.back() += " isReturning=" + NLMISC::toString(isReturning()); - pushFooter(container); - - - return container; -} - -NLMISC::CSmartPtr CSpawnBot::buildFirstHitPlace(TDataSetRow const& aggroBot) const -{ - NLMISC::CSmartPtr thisPlace, groupPlace; - { - NLMISC::CSmartPtr place = NLMISC::CSmartPtr(new CAIPlaceFastXYR(NULL)); - place->setPosAndRadius(AITYPES::vp_auto, pos(), (uint32)(getD1Radius()*1000.f)); - thisPlace = place; - } - groupPlace = getPersistent().getOwner()->getSpawnObj()->buildFirstHitPlace(aggroBot); - if (groupPlace) - { - NLMISC::CSmartPtr place = NLMISC::CSmartPtr(new CAIPlaceIntersect(NULL)); - place->setPlace1(thisPlace); - place->setPlace2(groupPlace); - thisPlace = place; - } - return thisPlace; -} - -std::set CSpawnBot::getAggroGroup(bool primary) const -{ - if (primary) - { - if (getPrimaryGroupAggroDist()>0.f) - return std::set(); /// @TODO Fill this - else - return std::set(); - } - else - { - if (getSecondaryGroupAggroDist()>0.f) - return std::set(); /// @TODO Fill this - else - return std::set(); - } -} - -float CSpawnBot::getReturnDistCheck() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroReturnDistCheck()>=0.f) - return getPersistent().getSheet()->AggroReturnDistCheck(); - else - return CBotAggroOwner::getReturnDistCheck(); -} - -float CSpawnBot::getD1Radius() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroRadiusD1()>=0.f) - return getPersistent().getSheet()->AggroRadiusD1(); - else - return CBotAggroOwner::getD1Radius(); -} - -float CSpawnBot::getD2Radius() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroRadiusD2()>=0.f) - return getPersistent().getSheet()->AggroRadiusD2(); - else - return CBotAggroOwner::getD2Radius(); -} - -float CSpawnBot::getPrimaryGroupAggroDist() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroPrimaryGroupDist()>=0.f) - return getPersistent().getSheet()->AggroPrimaryGroupDist(); - else - return CBotAggroOwner::getPrimaryGroupAggroDist(); -} - -float CSpawnBot::getPrimaryGroupAggroCoef() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroPrimaryGroupCoef()>=0.f) - return getPersistent().getSheet()->AggroPrimaryGroupCoef(); - else - return CBotAggroOwner::getPrimaryGroupAggroCoef(); -} - -float CSpawnBot::getSecondaryGroupAggroDist() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroSecondaryGroupDist()>=0.f) - return getPersistent().getSheet()->AggroSecondaryGroupDist(); - else - return CBotAggroOwner::getSecondaryGroupAggroDist(); -} - -float CSpawnBot::getSecondaryGroupAggroCoef() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroSecondaryGroupCoef()>=0.f) - return getPersistent().getSheet()->AggroSecondaryGroupCoef(); - else - return CBotAggroOwner::getSecondaryGroupAggroCoef(); -} - -float CSpawnBot::getAggroPropagationRadius() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroPropagationRadius()>=0.f) - return getPersistent().getSheet()->AggroPropagationRadius(); - else - return CBotAggroOwner::getAggroPropagationRadius(); -} - -bool CSpawnBot::canHeal() -{ - if (!getPersistent().getSheet()->FightConfig(AISHEETS::FIGHTCFG_HEAL)->_HasNormalAction) - return false; - if (_LastHealTick==0) - return true; - else - return (CTimeInterface::gameCycle() - _LastHealTick) > HealSpecificDowntime; -} - -bool CSpawnBot::canSelfHeal() -{ - if (!getPersistent().getSheet()->FightConfig(AISHEETS::FIGHTCFG_HEAL)->_HasSelfAction) - return false; - if (_LastSelfHealTick==0) - return true; - else - return (CTimeInterface::gameCycle() - _LastSelfHealTick) > HealSpecificDowntimeSelf; -} - -void CSpawnBot::healTriggered() -{ - _LastHealTick = CTimeInterface::gameCycle(); -} - -void CSpawnBot::selfHealTriggered() -{ - _LastSelfHealTick = CTimeInterface::gameCycle(); -} - -void CSpawnBot::aggroLost(TDataSetRow const& aggroBot) const -{ - sAggroLost(aggroBot, dataSetRow()); -} - -void CSpawnBot::aggroGain(TDataSetRow const& aggroBot) const -{ - sAggroGain(aggroBot, dataSetRow()); -} - -bool CSpawnBot::getProp(size_t Id, uint32& value) const -{ - TPropList::const_iterator it = _PropList.find(Id); - if (it==_PropList.end()) - return false; - - value = it->second; - return true; -} - -void CSpawnBot::setProp(size_t Id, uint32 value) -{ - _PropList[Id] = value; -} - -CBot& CSpawnBot::getPersistent() const -{ - return static_cast(CSpawnable::getPersistent()); -} - -void CSpawnBot::setTheta(CAngle theta) -{ - if (getPersistent().getSheet()->CanTurn()) - CModEntityPhysical::setTheta(theta); -} - -// :KLUDGE: This method change the sheet of the bot in the mirror. It appear -// that the client is totally unable to handle a sheet change during an entity -// lifetime. So this method should not be called. -/// @TODO Remove the method from spawn classes since its now longer called -// when sheet changes, and since spawn object is in fact destroyed and -// recreated. -void CSpawnBot::sheetChanged() -{ -// CMirrors::initSheet(dataSetRow(), getPersistent().getSheet()->SheetId()); -} - -void CSpawnBot::sendInfoToEGS() const -{ - if (!EGSHasMirrorReady) - return; - - const uint32& maxHp = getPersistent().getCustomMaxHp(); - if (maxHp > 0.f) - { - CChangeCreatureMaxHPMsg& msgList = CAIS::instance().getCreatureChangeMaxHP(); - - msgList.Entities.push_back(dataSetRow()); - msgList.MaxHp.push_back((uint32)(maxHp)); - msgList.SetFull.push_back((uint8)(1)); - } -} - - -////////////////////////////////////////////////////////////////////////////// -// CBot // -////////////////////////////////////////////////////////////////////////////// - -CBot::CBot(CGroup* owner, CAIAliasDescriptionNode* alias) -: CAliasChild(owner, alias) -, _VerticalPos(AITYPES::vp_auto) -, _Sheet(NULL) -, _ClientCSheet(NULL) -, _Stuck(false) -, _IgnoreOffensiveActions(false) -, _Healer(false) -, _SetSheetData(NULL) -, _Observers(NULL) -, _ProfileData(NULL) -, _CustomMaxHp(0) -{ -} - -CBot::CBot(CGroup* owner, uint32 alias, std::string const& name) -: CAliasChild(owner,alias, name) -, _VerticalPos(AITYPES::vp_auto) -, _Sheet(NULL) -, _ClientCSheet(NULL) -, _Stuck(false) -, _IgnoreOffensiveActions(false) -, _Healer(false) -, _SetSheetData(NULL) -, _Observers(NULL) -, _ProfileData(NULL) -, _CustomMaxHp(0.f) -{ -} - -CBot::~CBot() -{ - // despawn before calling this destructor, because it may will generate a pure virtual call error! -#if !FINAL_VERSION - nlassert(!isSpawned()); -#endif - - if (_Observers != NULL) - { - notifyBotDespawn(); - delete _Observers; - } -} - -std::string CBot::getOneLineInfoString() const -{ - return std::string("Bot '") + getName() + "'"; -} - -std::vector CBot::getMultiLineInfoString() const -{ - std::vector container; - std::vector strings; - - - pushTitle(container, "CBot"); - pushEntry(container, "id=" + getIndexString()); - container.back() += " eid=" + getEntityIdString(); - container.back() += " alias=" + getAliasTreeOwner()->getAliasString() + " raw alias=" + NLMISC::toString(getAliasTreeOwner()->getAlias()); - pushEntry(container, " name=" + getName()); - if (isSheetValid()) - container.back() += " sheet=" + NLMISC::CFile::getFilenameWithoutExtension(getSheet()->SheetId().toString()); - pushEntry(container, "fullname=" + getFullName()); - if (isSheetValid()) - { - strings = getSheet()->getMultiLineInfoString(); - FOREACHC(it, std::vector, strings) - pushEntry(container, *it); - } - else - pushEntry(container, ""); - if (isSpawned()) - { - strings = getSpawnObj()->getMultiLineInfoString(); - FOREACHC(it, std::vector, strings) - pushEntry(container, *it); - } - else - pushEntry(container, ""); - pushFooter(container); - - - return container; -} - -std::string CBot::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":b%u", getChildIndex()); -} - -std::string CBot::getEntityIdString() const -{ - if (isSpawned()) - return getSpawnObj()->getEntityId().toString() ; - else - return NLMISC::CEntityId().toString(); -} - -CAIInstance* CBot::getAIInstance() const -{ - return getOwner()->getAIInstance(); -} - - -void CBot::addEnergy() const -{ - getOwner()->getOwner()->getOwner()->addEnergy(botEnergyValue()); -} - -void CBot::removeEnergy() const -{ - getOwner()->getOwner()->getOwner()->removeEnergy(botEnergyValue()); -} - -std::string CBot::getFullName() const -{ - return std::string(getOwner()->getFullName() +":"+ getName()); -} - -NLMISC::CEntityId CBot::createEntityId() const -{ - // motif is always 0 as we use automatic id assignement from mirror - uint64 motif = 0; - - // fake, just waiting real pets implementation in mirror. - RYZOMID::TTypeId botType=getRyzomType(); - if (botType==RYZOMID::pack_animal) - botType=RYZOMID::creature; - -#ifndef NL_DEBUG - nlassert(botType!=RYZOMID::player); -#endif - return NLMISC::CEntityId(botType,motif); -} - -bool CBot::isHealer() const -{ - return _Healer && isSheetValid() && !getSheet()->FightConfig(AISHEETS::FIGHTCFG_HEAL).isNULL(); -} - -void CBot::initEnergy(float energyCoef) -{ - if (isSheetValid()) - setBotEnergyValue((uint32)((double)energyCoef*(double)getSheet()->EnergyValue())); -} - -void CBot::serviceEvent(CServiceEvent const& info) -{ - if (!isSpawned()) - return; - - CSpawnBot* spawnBot = getSpawnObj(); - - if (info.getEventType()==CServiceEvent::SERVICE_UP) - { - if (info.getServiceName()=="IOS") - { - spawnBot->setVisualPropertiesName(); - } - else if (info.getServiceName()=="EGS") - { - spawnBot->sendInfoToEGS(); - spawnBot->removeActionFlags(RYZOMACTIONFLAGS::Attacks); // clear Action Flags to avoid stuck problems with EGS. - spawnBot->stun()=0; - spawnBot->blind()=0; - spawnBot->root()=0; - } - } -} - -CSpawnBot* CBot::getSpawnObj() const -{ - return static_cast(CPersistentOfPhysical::getSpawnObj()); -} - -// :KLUDGE: This method is was created to avoid duplication of code. It -// results that it doesn't have a meaning without prior code to be executed -// (see sheetChanged and spawn). It's a trick that should be removed since -// there is code duplication anyway in sheetChanged method and its overrides. -/// @TODO Clean that mess -bool CBot::finalizeSpawn(RYAI_MAP_CRUNCH::CWorldPosition const& botWPos, CAngle const& spawnTheta, float botMeterSize) -{ - // Create eid - NLMISC::CEntityId eid = createEntityId(); - // Create row - TDataSetRow const row = CMirrors::createEntity(eid); - if (!row.isValid()) - { - nlwarning("***> Not Enough Mirror Space for Type: %s", RYZOMID::toString(getRyzomType()).c_str()); - return false; - } - - if (_ClientSheet!=NLMISC::CSheetId::Unknown) - CMirrors::initSheet(row, _ClientSheet); - else - CMirrors::initSheet(row, getSheet()->SheetId()); - - // get the spawn of this persistent objet. - setSpawn(getSpawnBot(row, eid, botMeterSize)); - - CSpawnBot* spawnBot = getSpawnObj(); - nlassert(spawnBot); - - spawnBot->setVisualPropertiesName(); - - CAIPos botPos; - if (!isStuck() && !IsRingShard) - botPos = CAIPos(botWPos.toAIVector(),0,0); - else - botPos = CAIPos(lastTriedPos, 0, 0); - spawnBot->setPos(botPos, botWPos); - // Use base class method to avoid overload in - spawnBot->CModEntityPhysical::setTheta(spawnTheta); - - this->initAdditionalMirrorValues(); // let derived class do its additional inits before declaring the entity - CMirrors::declareEntity(row); - linkToWorldMap(this, spawnBot->pos(), getAIInstance()->botMatrix()); - - return true; -} - -bool CBot::spawn() -{ - nlassert(!isSpawned()); - nlassert(getChildIndex()!=-1); // significates that we spawn an unattached bot. - - // Check we can spawn - if (isSpawned()) - return true; - if (getSheet()->SheetId() == NLMISC::CSheetId::Unknown) - { - nlwarning("Bot '%s'%s: invalid sheet id", getAliasFullName().c_str(), getAliasString().c_str()); - return false; - } - if (!getSpawnCounter().remainToMax()) - return false; - - // Get initial state - RYAI_MAP_CRUNCH::CWorldPosition botWPos; - CAngle spawnTheta; - getSpawnPos(lastTriedPos, botWPos, CWorldContainer::getWorldMap(), spawnTheta); - float botMeterSize = getSheet()->Scale()*getSheet()->Radius(); - - // Check the initial position is valid - if (!botWPos.isValid() && !isStuck()) - { - nlwarning("Bot '%s'%s: invalid spawn pos and not stuck", getAliasFullName().c_str(), getAliasString().c_str()); - return false; - } - - // Finalize spawn object creation - return finalizeSpawn(botWPos, spawnTheta, botMeterSize); -} - -void CBot::despawnBot() -{ -#if !FINAL_VERSION - nlassert(isSpawned()); -#endif - if (!isSpawned()) - return; - - CMirrors::removeEntity(getSpawnObj()->getEntityId()); - setSpawn(NULL); // automatic smart pointer deletion - notifyBotDespawn(); -} - -bool CBot::reSpawn(bool sendMessage) -{ - return spawn(); -} - -/// @KLUDGE This method is overridden in npc and fauna classes in a strange -/// way. The initial code is copied'n'pasted, and the finalizeSpawn method is -/// called along with a more specific one. This may confuse future coders and -/// be hard to maintain. -/// @TODO Clean that mess -void CBot::sheetChanged() -{ - if (getSpawnObj()) - { - // Get bot state - RYAI_MAP_CRUNCH::CWorldPosition botWPos = getSpawnObj()->wpos(); - CAngle spawnTheta = getSpawnObj()->theta(); - float botMeterSize = getSheet()->Scale()*getSheet()->Radius(); - // :TODO: Save profile info - - // If stuck bot position may be outside collision and must be recomputed - if (isStuck() || IsRingShard) - getSpawnPos(lastTriedPos, botWPos, CWorldContainer::getWorldMap(), spawnTheta); - - // Delete old bot - CMirrors::removeEntity(getSpawnObj()->getEntityId()); - setSpawn(NULL); // automatic smart pointer deletion - notifyBotDespawn(); - - // Finalize spawn object creation - finalizeSpawn(botWPos, spawnTheta, botMeterSize); - } -} - -class CSetSheetTimerEvent -: public CTimerEvent -{ - NLMISC::CSmartPtr _Bot; - uint32 _Step; -public: - CSetSheetTimerEvent(CBot* bot, uint32 step) : _Bot(bot), _Step(step) { } - virtual void timerCallback(CTimer* owner) - { - if (!_Bot.isNull()) - _Bot->setSheetDelayed(_Step); - } -}; - -void CBot::setSheet(AISHEETS::ICreatureCPtr const& sheet) -{ - _Sheet = sheet; - sheetChanged(); -} - -void CBot::setClientSheet(const std::string & clientSheetName) -{ - // Message warning is print if clientSheetName is not in sheet id - if (!clientSheetName.empty()) - { - if (!_ClientSheet.buildSheetId(clientSheetName)) - { - nlwarning("Invalid CLIENT_SHEET %s", clientSheetName.c_str()); - return; - } - - AISHEETS::ICreatureCPtr sheet = AISHEETS::CSheets::getInstance()->lookup(NLMISC::CSheetId(clientSheetName)); - - if (!sheet || sheet->SheetId() == NLMISC::CSheetId::Unknown) - { - nlwarning("Unknown sheet %s", clientSheetName.c_str()); - return; - } - - _ClientCSheet = sheet; - - sheetChanged(); - } -} - -// 1: Stop the bot -void CBot::triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet) -{ - if (_SetSheetData) - { - nlwarning("Another sheet change is going, this one is canceled"); - return; - } - - NLMISC::CSheetId sheetId= (BotRepopFx.get().empty()? NLMISC::CSheetId::Unknown: NLMISC::CSheetId(BotRepopFx)); - if (getSpawnObj() && sheetId!=NLMISC::CSheetId::Unknown) - { - _SetSheetData = new CSetSheetData(); - _SetSheetData->_FxSheetId = sheetId; - _SetSheetData->_SheetToSet = sheet; - // Timer 1 is to let time for the bot to stop moving - _SetSheetTimer.setRemaining(12, new CSetSheetTimerEvent(this, 0)); - - getSpawnObj()->setSpeedFactor(0.f); - } - else - { - setSheet(sheet); - } -} - -// 2: Trigger Fx -void CBot::setSheetDelayed0() -{ - nlassert(_SetSheetData); - // Timer 2 is to let time for the fx to hide the bot despawn - _SetSheetTimer.setRemaining(8, new CSetSheetTimerEvent(this, 1)); - - - _SetSheetData->_Fx = CFxEntityManager::getInstance()->create(getSpawnObj()->pos(), _SetSheetData->_FxSheetId); - if (!_SetSheetData->_Fx->spawn()) - { - nlwarning("Unable to spawn fx entity (mirror range full?)"); - CFxEntityManager::getInstance()->destroy(_SetSheetData->_Fx); - _SetSheetData->_Fx = NULL; - } -} - -// 3: Change the sheet (depop/repop) -void CBot::setSheetDelayed1() -{ - nlassert(_SetSheetData); - // Timer 3 is to let time for the fx to hide the bot spawn - _SetSheetTimer.setRemaining(15, new CSetSheetTimerEvent(this, 2)); - - setSheet(_SetSheetData->_SheetToSet); - _SetSheetData->_SheetToSet = NULL; -} - -// 4: Stop the Fx -void CBot::setSheetDelayed2() -{ - nlassert(_SetSheetData); - if (!_SetSheetData->_Fx.isNull()) - { - _SetSheetData->_Fx->despawn(); - CFxEntityManager::getInstance()->destroy(_SetSheetData->_Fx); - } - delete _SetSheetData; - _SetSheetData = NULL; -} - -void CBot::setSheetDelayed(uint32 step) -{ - switch (step) - { - case 0: setSheetDelayed0(); break; - case 1: setSheetDelayed1(); break; - case 2: setSheetDelayed2(); break; - default: nlerror("setSheetDelayed called with an invalid step number"); - } -} - -void CBot::attachObserver(IObserver* obs) -{ - if (_Observers == NULL) - { - _Observers = new std::vector; - _Observers->push_back(obs); - return; - } - - std::vector::const_iterator it = std::find(_Observers->begin(), _Observers->end(), obs); - if (it == _Observers->end()) - _Observers->push_back(obs); -} - -void CBot::detachObserver(IObserver* obs) -{ - if (_Observers == NULL) - return; - - std::vector::iterator it = std::find(_Observers->begin(), _Observers->end(), obs); - if (it != _Observers->end()) - { - *it = _Observers->back(); - _Observers->pop_back(); - } -} - -void CBot::notifyBotDespawn() -{ - if (_Observers == NULL) - return; - - FOREACH(it, std::vector, (*_Observers)) - (*it)->notifyBotDespawn(this); -} - -void CBot::notifyBotDeath() -{ - if (_Observers == NULL) - return; - - FOREACH(it, std::vector, (*_Observers)) - (*it)->notifyBotDeath(this); -} - -void CBot::notifyStopNpcControl() -{ - if (_Observers == NULL) - return; - - FOREACH(it, std::vector, (*_Observers)) - (*it)->notifyStopNpcControl(this); -} diff --git a/code/ryzom/server/src/ai_service/ai_bot.h b/code/ryzom/server/src/ai_service/ai_bot.h deleted file mode 100644 index 9810dcd41..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot.h +++ /dev/null @@ -1,308 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_BOT_H -#define RYAI_BOT_H - -#include "nel/misc/path.h" -#include "ai_entity_physical.h" -#include "ai_entity_physical_inline.h" -#include "ai_instance.h" -#include "ai_pos.h" -#include "states.h" -#include "debug_history.h" -#include "sheets.h" -#include "profile.h" -#include "ai_aggro.h" -#include "dyn_grp.h" -#include "nel/misc/variable.h" -#include "service_dependencies.h" -#include "game_share/timer.h" -#include "fx_entity_manager.h" - -class CGroup; - -template class CSpawnable; -template class CPersistent; - -void sAggroLost(TDataSetRow playerBot, TDataSetRow targetBot); -void sAggroGain(TDataSetRow playerBot, TDataSetRow targetBot); - -class CSpawnGroup; - -class CSpawnGroup; - -extern CAIVector lastTriedPos; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBot // -////////////////////////////////////////////////////////////////////////////// - -class CSpawnBot -: public NLMISC::CDbgRefCount -, public CModEntityPhysical -, public CProfileOwner -, public CProfilePtr -, public CBotAggroOwner -, public CDynSpawnBot -{ -public: - typedef CHashMap TPropList; - -public: - - CSpawnBot(TDataSetRow const& entityIndex, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - virtual ~CSpawnBot(); - - virtual void setTheta(CAngle theta); - - virtual void sendInfoToEGS() const; - - CBot& getPersistent() const; - - CSpawnGroup& spawnGrp() const; - - /// @name CBotAggroOwner implementation - //@{ - virtual void aggroLost(TDataSetRow const& aggroBot) const; - virtual void aggroGain(TDataSetRow const& aggroBot) const; - - virtual NLMISC::CEntityId getAggroOwnerEid() const { return getEntityId(); } - virtual RYAI_MAP_CRUNCH::CWorldPosition getAggroPos() const { return wpos(); } - virtual NLMISC::CSmartPtr buildFirstHitPlace(TDataSetRow const& aggroBot) const; - virtual std::set getAggroGroup(bool primary) const; - - virtual float getReturnDistCheck() const; - virtual float getD1Radius() const; - virtual float getD2Radius() const; - virtual float getPrimaryGroupAggroDist() const; - virtual float getPrimaryGroupAggroCoef() const; - virtual float getSecondaryGroupAggroDist() const; - virtual float getSecondaryGroupAggroCoef() const; - virtual float getAggroPropagationRadius() const; - //@} - - virtual void setVisualPropertiesName(); - - // as there not a lot of prop (1 or 2, maybe 3) stores in this comportment, we don't need hash. - bool getProp(size_t Id, uint32& value) const; - void setProp(size_t Id, uint32 value); - - virtual float fightWeight() const; - virtual float fightValue() const; - - CAIInstance* getAIInstance() const; - std::vector getMultiLineInfoString() const; - - void setSpawnGroup(CSpawnGroup* spawnGroup) { _SpawnGroup = spawnGroup; } - - bool isHitting() const { return (getActionFlags()&RYZOMACTIONFLAGS::Attacks)!=0; } - - virtual void sheetChanged(); - - bool canHeal(); - bool canSelfHeal(); - void healTriggered(); - void selfHealTriggered(); - - virtual float getSpeedFactor() const { return _SpeedFactor; } - virtual void setSpeedFactor(float value) { _SpeedFactor = value; } - -public: - TPropList _PropList; - - float _DamageSpeedCoef; - float _DamageCoef; - -private: - CSpawnGroup* _SpawnGroup; - -private: - uint32 _LastHealTick; - uint32 _LastSelfHealTick; - - float _SpeedFactor; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBot // -////////////////////////////////////////////////////////////////////////////// - -class CBot -: public CAliasChild -, public CPersistentOfPhysical -, public CAIEntity -, public CDebugHistory -, public NLMISC::CRefCount -, public CDynBot -, public CServiceEvent::CHandler -{ - friend class CGroup; - -public: - /// @name Ctors and dtor - //@{ - CBot(CGroup* owner, CAIAliasDescriptionNode* alias = NULL); - CBot(CGroup* owner, uint32 alias, std::string const& name); - virtual ~CBot(); - //@} - - /// @name CChild implementation - //@{ - virtual std::string getIndexString() const; - virtual std::string getEntityIdString() const; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - virtual std::string getFullName() const; - //@} - - /// @name Sheet management - //@{ - virtual AISHEETS::ICreatureCPtr getSheet() const { return _Sheet; } - virtual bool isSheetValid() const { return !_Sheet.isNull(); } - virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet); - - virtual void triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet); - //@} - - /// @name AI objects hierarchy access - //@{ - CAIInstance* getAIInstance() const; - - AISHEETS::ICreatureCPtr getClientCSheet() const - { - if (_ClientSheet != NLMISC::CSheetId::Unknown && _ClientCSheet) - return _ClientCSheet; - return _Sheet; - } - - NLMISC::CSheetId getClientSheet() const - { - return _ClientSheet; - } - - CGroup& getGroup() { return *getOwner(); } - CAliasTreeOwner const* getAliasTreeOwner() const { return this; } - CSpawnBot* getSpawnObj() const; - //@} - - /// @name CDynBot stuff - //@{ - void addEnergy() const; - void removeEnergy() const; - CDynBot const& getDynBot() const { return *this; }; - void initEnergy(float energyCoef); - //@} - - /// @name Observers management - //@{ - class IObserver - { - public: - virtual void notifyBotDespawn(CBot* bot) {} - virtual void notifyBotDeath(CBot* bot) {} - virtual void notifyStopNpcControl(CBot* bot) {} - }; - void attachObserver(IObserver* obs); - void detachObserver(IObserver* obs); - - void notifyBotDespawn(); - void notifyBotDeath(); - void notifyStopNpcControl(); - //@} - - /// Debugging stuff - CDebugHistory* getDebugHistory() { return this; } - - void serviceEvent(CServiceEvent const& info); - - virtual AITYPES::TFaunaType type() const { return AITYPES::FaunaTypeBadType; } - virtual RYZOMID::TTypeId getRyzomType() const = 0; - - virtual void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta) = 0; - - virtual CAIS::CCounter& getSpawnCounter() = 0; - - virtual bool spawn(); - virtual void despawnBot(); - virtual bool reSpawn(bool sendMessage = true); - - bool isStuck() const { return _Stuck; } - void setStuck(bool value) { _Stuck = value; } - - bool isBuildingBot() const { return _BuildingBot; } - void setBuildingBot(bool value) { _BuildingBot = value; } - - bool ignoreOffensiveActions() const { return _IgnoreOffensiveActions; } - void setIgnoreOffensiveActions(bool value) { _IgnoreOffensiveActions = value; } - - bool isHealer() const; - void setHealer(bool value) { _Healer = value; } - - NLMISC::CEntityId createEntityId() const; - - const ucstring& getCustomName() const { return _CustomName; } - void setCustomName(const ucstring &name) { _CustomName = name; } - - const uint32& getCustomMaxHp() const { return _CustomMaxHp; } - void setCustomMaxHp(const uint32 &maxHp) { _CustomMaxHp = maxHp; } - - virtual void setClientSheet(const std::string & clientSheetName); - - // Can be redefine by NpcGroup in case of a BotNpc with a fauna sheet but that we don't want the name to ignore - // Especialy for Ring Creatures - virtual bool getFaunaBotUseBotName() const { return false;} - -protected: - virtual CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius) = 0; - - virtual void sheetChanged(); - bool finalizeSpawn(RYAI_MAP_CRUNCH::CWorldPosition const& botWPos, CAngle const& spawnTheta, float botMeterSize); - virtual void initAdditionalMirrorValues() {} - void setSheetDelayed(uint32 step); - void setSheetDelayed0(); - void setSheetDelayed1(); - void setSheetDelayed2(); - friend class CSetSheetTimerEvent; - -protected: - AITYPES::TVerticalPos _VerticalPos; - -private: - AISHEETS::ICreatureCPtr _Sheet; - AISHEETS::ICreatureCPtr _ClientCSheet; - NLMISC::CSheetId _ClientSheet; - bool _Stuck; - bool _IgnoreOffensiveActions; - bool _Healer; - bool _BuildingBot; - ucstring _CustomName; - uint32 _CustomMaxHp; - CTimer _SetSheetTimer; - struct CSetSheetData - { - AISHEETS::ICreatureCPtr _SheetToSet; - NLMISC::CSheetId _FxSheetId; - CFxEntityPtr _Fx; - }; - CSetSheetData* _SetSheetData; - std::vector* _Observers; - -public: - void* _ProfileData; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot_easter_egg.cpp b/code/ryzom/server/src/ai_service/ai_bot_easter_egg.cpp deleted file mode 100644 index 64a40f83b..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_easter_egg.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_bot_easter_egg.h" - -using namespace std; - -////////////////////////////////////////////////////////////////////////////// -// CBotEasterEgg // -////////////////////////////////////////////////////////////////////////////// - -CBotEasterEgg::CBotEasterEgg(CGroup* owner, uint32 alias, std::string const& name, uint32 easterEggId) -: CBotNpc(owner, alias, name) -, _EasterEggId(easterEggId) -{ -} - -CBotEasterEgg::~CBotEasterEgg() -{ -} - -std::string CBotEasterEgg::getOneLineInfoString() const -{ - string desc = NLMISC::toString("Easter Egg bot %u '%s'", getEasterEggId(), getName().c_str()); - return desc; -} diff --git a/code/ryzom/server/src/ai_service/ai_bot_easter_egg.h b/code/ryzom/server/src/ai_service/ai_bot_easter_egg.h deleted file mode 100644 index b54352057..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_easter_egg.h +++ /dev/null @@ -1,41 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_BOT_EASTER_EGG_H -#define RYAI_BOT_EASTER_EGG_H - -#include "ai_bot_npc.h" - -////////////////////////////////////////////////////////////////////////////// -// CBotEasterEgg // -////////////////////////////////////////////////////////////////////////////// - -class CBotEasterEgg : public CBotNpc -{ -public: - CBotEasterEgg(CGroup* owner, uint32 alias, std::string const& name, uint32 easterEggId); - virtual ~CBotEasterEgg(); - - /// get the easter egg ID - uint32 getEasterEggId() const { return _EasterEggId; } - - virtual std::string getOneLineInfoString() const; - -private: - uint32 _EasterEggId; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp b/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp deleted file mode 100644 index 53afcd30a..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_fauna.cpp +++ /dev/null @@ -1,1507 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "ai_bot_fauna.h" -#include "ai_grp_fauna.h" -#include "ai_mgr_fauna.h" -#include "ai_player.h" -#include "ai_bot_npc.h" -#include "ai_grp_npc.h" -#include "ai_profile_fauna.h" - -#include "dyn_grp_inline.h" - -using namespace NLMISC; -using namespace std; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -/****************************************************************************/ -/* File configuration */ -/****************************************************************************/ - -// --------------------------------------------------------------------------- -// Debug defines -// --------------------------------------------------------------------------- -// COMPACT_POS_WARNINGS compress flooding warnings concerning path problems. -// Positions where the problems occures are stored and displayed and cleared -// every minute. -// :TODO: /!\ As it cannot be tested without long-time run with several -// players the following define can be commented to restore previous behavior. -#define COMPACT_POS_WARNINGS 1 - -// --------------------------------------------------------------------------- -// Some combat constants -static float const CONSIDER_MIN_DIST = 6.f; - -// --------------------------------------------------------------------------- - -// --------------------------------------------------------------------------- -// Stuff used for management of log messages -#ifdef NL_DEBUG -static bool VerboseLog = false; -#endif -#ifndef NL_DEBUG -static bool VerboseLog = false; -#endif - -#define LOG if (!VerboseLog) {} else nlinfo - -// --------------------------------------------------------------------------- -// Control over verbose nature of logging -NLMISC_COMMAND(verboseFaunaLog,"Turn on or off or check the state of verbose fauna activity logging","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (VerboseLog, args[0]); - - log.displayNL("verboseLogging is %s",VerboseLog?"ON":"OFF"); - return true; -} - -//---------------------------------------------------------------------------- -// Control over verbose nature of logging -NLMISC_COMMAND(verboseFaunaBot,"Turn on or off or check the state of verbose fauna bot","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (VerboseLog, args[0]); - - nlinfo("VerboseLogging is %s",VerboseLog?"ON":"OFF"); - return true; -} - -/****************************************************************************/ -/* Local classes definition and function declatations */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileGoAway // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileGoAway -: public CAIBaseProfile -{ -public: - CBotProfileGoAway(CProfileOwner* owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlags, float speed = 0.f, CAIFaunaActivityBaseSpawnProfile* lastProfile = NULL); - - virtual void beginProfile(); - - virtual void endProfile() { } - - // Speed is in the range [0;1] - void setSpeed(float speed) { _Speed = speed; } - - float speed () { return _Speed; } - - CAIVector& getDecalageRef() { return _Decalage; } - - CAIFaunaActivityBaseSpawnProfile* lastProfile() const { return _LastProfile; } - - virtual void updateProfile(uint ticksSinceLastUpdate); - - virtual std::string getOneLineInfoString() const { return std::string("go_away profile"); } - - virtual TProfiles getAIProfileType () const { return BOT_GO_AWAY; } - -public: - RYAI_MAP_CRUNCH::CDirection _LastDir; - RYAI_MAP_CRUNCH::CMapPosition _LastStartPos; - - CPathPosition _PathPos; - CPathCont _fightGoAwayPathContainer; - -protected: - CAIVector _Decalage; - CSpawnBot* _Bot; - float _Speed; - NLMISC::CSmartPtr _LastProfile; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileGoAway // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileGoAwayFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner); -}; - -CBotProfileGoAwayFactory BotProfileGoAway; - -////////////////////////////////////////////////////////////////////////////// -// Global functions // -////////////////////////////////////////////////////////////////////////////// - -static const char *cyclesStateName(CFaunaActivity::TCycleState s); - -/****************************************************************************/ -/* Function definitions */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotFauna // -////////////////////////////////////////////////////////////////////////////// - -CSpawnBotFauna::CSpawnBotFauna(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CSpawnBot(row, owner, id, radius, level, denyFlags) -{ - setCycleState(CFaunaActivity::CycleStateUndefined); - - // we start with a wander activity. - setAIProfile(this, &WanderFaunaProfileFactory, false); - - _NextBestTargetUpdate.set(1); // next. - _Hungry = 1.f; -} - -CSpawnBotFauna::~CSpawnBotFauna () -{ -} - -CBotFauna& CSpawnBotFauna::getPersistent() const -{ - return static_cast(CSpawnBot::getPersistent()); -} - -bool CSpawnBotFauna::canMove() const -{ - return /*!isRooted() && */walkSpeed() != 0 && getPersistent().faunaType()!=AITYPES::FaunaTypePlant; -} - -float CSpawnBotFauna::getCollisionDist(float angTo) const -{ - // :TODO: Rehabilitate behaviour based on sheet (see this function history in CVS) - return radius(); -} - -void CSpawnBotFauna::sendInfoToEGS() const -{ - CFaunaBotDescription &fbd = CAIS::instance().getFaunaDescription(); - fbd.Bots.push_back(dataSetRow()); - fbd.GrpAlias.push_back(getPersistent().grp().getAlias()); -} - -void CSpawnBotFauna::update(TProfiles activity, uint32 ticksSinceLastUpdate) -{ - H_AUTO(CSpawnBotFauna_update); - - nlassert(!getAISpawnProfile().isNull()); - // this piece of code change the current comportment of the fauna in regards of the group comportment. - - ++AISStat::BotTotalUpdCtr; - ++AISStat::BotFaunaUpdCtr; - - TProfiles faunaActivity = getAIProfileType(); - if (faunaActivity==BOT_FLEE && !isFeared() && getUnreachableTarget().isNULL()) - { - setDefaultComportment(); - faunaActivity=getAIProfileType(); - } - - { - if ( spawnGrp().mustDespawnBots() - && ( spawnGrp().despawnImmediately() - || ( faunaActivity!=BOT_FIGHT - && faunaActivity!=BOT_FLEE - ) - ) - ) // if its group is out of time. - { - spawnGrp().addBotToDespawnAndRespawnTime(&getPersistent(), 1, 2); // .. set the bot to be despawn and gives the control to its group. - return; - } - - if ( faunaActivity!=ACTIVITY_CORPSE - && (spawnGrp().getUpdatePriority()<(2<<2)) ) // 2*40 -> 80 meters - { - if ( faunaActivity!=BOT_FIGHT - || !NLMISC::safe_cast(getAIProfile())->isHitting()) - { - - if ( _NextBestTargetUpdate.test() - || faunaActivity==BOT_GO_AWAY) - { - getBestTarget (); - faunaActivity=getAIProfileType(); // activity could have changed. - _NextBestTargetUpdate.set(15); // getbesttarget every 1.5 secs .. - } - } - } - - if ( faunaActivity==ACTIVITY_GRAZING - || faunaActivity==ACTIVITY_RESTING - || faunaActivity==ACTIVITY_WANDERING ) - { - if (faunaActivity!=activity) - { - CAIFaunaActivityBaseSpawnProfile *profile=NLMISC::safe_cast(getAIProfile()); - if (!(profile->getMovementMagnet().isNull())) - { - if (profile->getMovementMagnet()->getMovementType()==CMovementMagnet::Movement_Move) - { - switch(activity) - { - case ACTIVITY_RESTING: - setAIProfile(this,&RestFaunaProfileFactory, false); - break; - case ACTIVITY_GRAZING: - setAIProfile(this,&GrazeFaunaProfileFactory, false); - break; - case ACTIVITY_WANDERING: - setAIProfile(this,&WanderFaunaProfileFactory, false); - break; - case ACTIVITY_PLANTIDLE: - setAIProfile(this,&PlanteIdleFaunaProfileFactory, false); - break; - default: - nlwarning("Unsupported activity for fauna bot"); - break; - } - } - } - } - } - } - - // the behaviour update. - if (!isStuned()) - { - updateProfile(ticksSinceLastUpdate); - - // if normal activity .. update Aggro. - if ( faunaActivity!=BOT_FIGHT - && faunaActivity!=BOT_FLEE ) - { - this->CBotAggroOwner::update(ticksSinceLastUpdate); - } - } -} - -float CSpawnBotFauna::getReturnDistCheck() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroReturnDistCheck()>=0.f) - return getPersistent().getSheet()->AggroReturnDistCheck(); - else - return AggroReturnDistCheckFauna; -} - -void CSpawnBotFauna::eventEngaged(TDataSetRow const& originId) -{ -} - -void CSpawnBotFauna::processEvent(CCombatInterface::CEvent const& event) -{ - // no self aggro. - if (event._targetRow==event._originatorRow) - return; - - // To remove when debug done .. - CAIEntityPhysical *ep = CAIS::instance().getEntityPhysical(event._originatorRow); - if (ep==NULL || ep->getAIInstance()->getChildIndex()!=getAIInstance()->getChildIndex()) - { - nlwarning("AIInstance Problem !!"); - return; - } - - if ((event._nature==ACTNATURE::FIGHT || event._nature==ACTNATURE::OFFENSIVE_MAGIC) && !getPersistent().ignoreOffensiveActions()) - { - float aggro = event._weight; - if (aggro>-0.15f) - { - aggro = -0.15f; - } - if (event._nature==ACTNATURE::OFFENSIVE_MAGIC) - { - aggro = (float)((1.f+aggro)*0.5f-1.f); // maximize aggro for magic - //insure if aggressor is player, player have it's target seted for BOSS assist - CBotPlayer *player=dynamic_cast(ep); - if(player) - { - CAIEntityPhysical *target=player->getVisualTarget(); - if (target) - player->setTarget(target); - } - } - addAggroFor(event._originatorRow, aggro, true); - } -} - -void CSpawnBotFauna::getBestTarget() -{ - // Get ourself - CBotFauna& thisBotFauna = getPersistent(); - // Get our group - CGrpFauna& grp = thisBotFauna.grp(); - // Get our type - TFaunaType faunaType = grp.getType(); - // Compute an aggro radius - float const AggroRadius = faunaType==FaunaTypeHerbivore?30.f:aggroRadius(); - - // used if the bot is too far from its group center to use its vision. ??? - CAIVision vision; - CAIVision::iterator itVision, itVisionEnd; - - // VISUAL_LOOK_AT_DIST - // ASSistDist - - float const VISUAL_LOOK_AT_DIST = 10.f; - - // Compute a test radius - float testradius = AggroRadius; // is a minimum for other bot consideration. - if (testradiusAssistDist()) - testradius=thisBotFauna.getSheet()->AssistDist(); - testradius+=radius(); - - // Get the vision - vision.updateBotsAndPlayers(getAIInstance(), CAIVector(pos()), (uint32)(testradius+3.f), (uint32)(testradius+3.f)); - itVision = vision.begin(); - itVisionEnd = vision.end(); - - // Vars for the most interesting player - float bestCuriosityScore = (radius()+1.5f)*2000.f; - CAIEntityPhysical* curiosityPlayer = NULL; - - // Vars for the most appealing target - float bestVisualScore = 0.f; - CAIEntityPhysical* visualTarget = NULL; - - if (!getVisualTarget().isNULL()) - { - if ( getTarget().isNULL() // check if we are looking to a too far visual target. - && ( _VisualTargetTimer.test() - || getVisualTarget()->pos().quickDistTo(pos())>VISUAL_LOOK_AT_DIST ) // if the target is too far .. - ) - { - _VisualTargetTimer.set(CAIS::rand32(40)+25); - bestVisualScore=1.f; - setVisualTarget(NULL); - } - - if (!_VisualTargetTimer.test()) - { - bestVisualScore=1.f; - } - - } - - // (yet) unknown vars - float bestScore = 0.f; - bool goAway = false; - TProfiles thisProfileType = getAIProfile()->getAIProfileType(); - uint32 const thisFaunaGroupIndex = thisBotFauna.getSheet()->GroupPropertiesIndex(); - sint32 const thisHeight = wpos().getMetricHeight (); - - // For each entity in the visual range - for ( ; itVision!=itVisionEnd; ++itVision) - { - // The other entity - CAIEntityPhysical* const entity = itVision->getSpawnObj(); - - // If the other entity is not real or if it is us, skip it - if (entity==NULL || entity==this) - continue; - - // We compute the vector to the other entity - CAIVector delta = pos(); - delta -= entity->pos(); - // We compute the dist to it - double const dist = delta.quickNorm(); - - // Check that the entity is in the test radius - if (dist <= (testradius+entity->radius())) - { - // inf 10 m .. this second test was only put here for test .. need more tuning before generalization. - bool const tooHigh = abs(entity->wpos().getMetricHeight()-thisHeight)>10000; - if (tooHigh) - continue; - - // Depending on the type of the entity - switch (entity->getRyzomType()) - { -////////////////////////////////////////////////////////////////////////////// -// The other is a player - case RYZOMID::player: - { - // Depending what we are... - switch(faunaType) - { - // ...but in fact whathever we are - case FaunaTypePlant: - case FaunaTypeHerbivore: - case FaunaTypePredator: - { - // Get the root cell of the player (for safe zone stuff) - CRootCell const* const rootCell = entity->wpos().getRootCell(); - // If player is a valid target and if we dont like him - if ( entity->isAlive() - && distgetPropertiesCst(AISHEETS::CSheets::getInstance()->playerGroupIndex()).attack() - && rootCell - && rootCell->getFlag()==0) // not in safe zone. - { - // Set some aggro - setAggroMinimumFor(entity->dataSetRow(), 0.8f*0.5f, false); - } - // If we don't have to aggro, and we're not a plant - else if (faunaType!=FaunaTypePlant) - { - // Cast to player - CBotPlayer* player = NLMISC::type_cast(entity); - // CBotPlayer* player = NLMISC::safe_cast(entity); - - // If player is aggressive and close enough - if (player->isAggressive() && distAssistDist())) - { - // If we are in an interruptible state - if ( thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING - || thisProfileType==ACTIVITY_WANDERING) - { - // Get our profile - IMouvementMagnetOwner* magnetOwner = dynamic_cast(getAIProfile()); - if (magnetOwner) - { - // Get our movement magnet - CMovementMagnet* movementMagnet = magnetOwner->getMovementMagnet(); - // If we have one and we are not moving finish it - if (movementMagnet!=NULL && movementMagnet->getMovementType()!=CMovementMagnet::Movement_Move) - movementMagnet->stateTimer().set(0); - } - } - // Get out of the switch, next tick we'll aggro him - break; - } - - // Check for curiosity - if ( canMove() - && !player->isAggressive() - && entity->wpos().isValid() - && (entity->wpos().getFlags()&entity->getAStarFlag())==0) - { - // Suppose we can go to him - bool canChange = true; - // If we are doing something not very interesting - if ( thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING - || thisProfileType==ACTIVITY_WANDERING) - { - // We change only... - canChange = false; - IMouvementMagnetOwner* magnetOwner = dynamic_cast(getAIProfile()); - if (magnetOwner && !(magnetOwner->getMovementMagnet().isNull())) - { - // ...if we are just moving - canChange = magnetOwner->getMovementMagnet()->getMovementType()==CMovementMagnet::Movement_Move; - } - } - - if (canChange) - { - // Compute a curiosity score, taking into account the time and the dist - float const targetterNumber = (float)entity->totalTargeterCount(); - float const targetterScore = 1 + targetterNumber*targetterNumber*targetterNumber; - float const time = (float)_TimeBeforeNextCuriosity.timeRemaining(); - float const curiosityScore = targetterScore * time * (float)dist; - // If it's the most interesting player - if (curiosityScore=(VISUAL_LOOK_AT_DIST-1.f)) ) - // Skip it - break; - - // If we have no visual target - if ( !((CAIEntityPhysical*)getVisualTarget()) - && !((CAIEntityPhysical*)getTarget())) - { - float const score = (float)(1.f/(1.f+dist+CAIS::rand32(7))); - if (score>bestVisualScore) - { - bestVisualScore=score; - visualTarget = entity; - } - } - } - } - break; - default: - break; - } - } - break; -////////////////////////////////////////////////////////////////////////////// -// The other is a npc - case RYZOMID::npc: - { - // Depending on what we are - switch(faunaType) - { - // If we're a plant - case FaunaTypePlant: - // Ignore the npc - break; - // If we're an herbivore - case FaunaTypeHerbivore: - { - // If we already have a visual target or the entity is too far - if ( bestVisualScore==1.f - || dist>(VISUAL_LOOK_AT_DIST-1.f) - || ( ((CAIEntityPhysical*)getVisualTarget()) - || ((CAIEntityPhysical*)getTarget())) ) - // Skip it - break; - - // If we are doing something not interesting - if ( thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING - || thisProfileType==ACTIVITY_WANDERING) - { - // We look at the npc if he is appealing - float const score = (float)(1.f/(1.f+dist+CAIS::rand32(7))); - if (score>bestVisualScore) - { - bestVisualScore=score; - visualTarget=entity; - } - } - } - break; - // If we are a predator - case FaunaTypePredator: - { - // Get the entity as a npc bot - CSpawnBotNpc* botNpc = NLMISC::safe_cast(entity); - // If it is an escorted entity - if (botNpc->spawnGrp().activityProfile().getAIProfileType() == ACTIVITY_ESCORTED) - { - // Aggro it - setAggroMinimumFor(entity->dataSetRow(), 0.8f, false); - } - } - break; - default: - break; - } - } - break; -////////////////////////////////////////////////////////////////////////////// -// The other is an animal -// :TODO: Finish the doc of that method - case RYZOMID::creature: - case RYZOMID::pack_animal: - { - CSpawnBot *botCreat=NLMISC::safe_cast(entity); - CGroup &creatGrp=botCreat->getPersistent().getGroup(); - const uint32 otherCreatGrpIndex=botCreat->getPersistent().getSheet()->GroupPropertiesIndex(); - const AISHEETS::CGroupProperties &groupProp=thisBotFauna.getSheet()->getPropertiesCst(otherCreatGrpIndex); - - ////////////////////////////////////////////////////////////// - // Assist it ? - - // if creature is fighting - if (botCreat->hasBeenHit(20)) // 20 ticks (2 seconds) persistent test .. - { - // if nearest than assist dist .. - // and same group - // or assist compatibility. - if ( distAssistDist() - && ( &creatGrp==&grp - || groupProp.assist()) - ) - { - const CAIEntityPhysical *const target=botCreat->getTarget(); - if ( target - && target->getRyzomType()==RYZOMID::player) - { - setAggroMinimumFor(target->dataSetRow(), 0.2f, false); - } - - // check attackers and give minimum aggro. - CAIEntityPhysical const* attacker = botCreat->firstTargeter(); - while (attacker!=NULL) - { - if (attacker->getRyzomType()==RYZOMID::player) - { - setAggroMinimumFor(attacker->dataSetRow(), 0.2f, false); - } - attacker = attacker->nextTargeter(); - } - } - } - - ////////////////////////////////////////////////////////////// - // Attack it ? - if (groupProp.attack()) - { - if ( canMove () - && hungry ()>0 ) - { - if (entity->isAlive()) - { - if (!((CAIEntityPhysical*)getTarget())) - { - if (runSpeed()>entity->runSpeed()) - { - // got enought life ? (more than 75%). - if ((4*currentHitPoints())>(3*maxHitPoints())) - { - // check if the herbivore is in the current place - const CAIPlace *place=spawnGrp().targetPlace(); - float alpha((float)place->midPos().quickDistTo(CAIVector(entity->wpos()))); - alpha -= place->getRadius(); - if (alpha<0) - alpha=0; - alpha=(float)(1/(1+alpha*0.1)); - setAggroMinimumFor(entity->dataSetRow(), 0.8f*alpha*0.5f, false); - } - } - } - } - else - { - if (entity->food()>0) - { - if ( ( ( thisProfileType!=BOT_FIGHT - && thisProfileType!=BOT_FLEE ) - || (((CAIEntityPhysical*)getTarget())==NULL || ((CAIEntityPhysical*)getTarget())==entity) ) - && thisProfileType!=BOT_GO_AWAY - && thisProfileType!=ACTIVITY_EAT_CORPSE ) - { - CSpawnBot *botCreat=NLMISC::safe_cast(entity); - // if its a corpse, change our behaviour to eat. - IAIProfile* profile = botCreat->getAIProfile(); - if ( profile - && profile->getAIProfileType()==ACTIVITY_CORPSE - && botCreat->wpos().isValid() - && !(botCreat->wpos().getFlags()&botCreat->getAStarFlag()) - ) - { - CCorpseFaunaProfile *corpseProfile=NLMISC::safe_cast(profile); - if ( !corpseProfile->haveEater() - && !corpseProfile->eated() ) - { // start a eater comportment. - corpseProfile->setEater(true); - setAIProfile(new CEatCorpseFaunaProfile(this,entity->dataSetRow(), getAStarFlag())); - } - } - } - } - } - } - } - else - { - ////////////////////////////////////////////////////////////// - // Flee from it ? - const AISHEETS::CGroupProperties &groupProp=botCreat->getPersistent().getSheet()->getPropertiesCst(thisFaunaGroupIndex); - - // the other creature may attack us .. :O - if (groupProp.attack()) - { - if ( canMove() - && entity->isAlive() - && runSpeed()runSpeed()) - { - TProfiles creatActivity=getAIProfileType(); - if (dist<(testradius*0.5f)) - { - if ( creatActivity==ACTIVITY_GRAZING - || creatActivity==ACTIVITY_RESTING - || creatActivity==ACTIVITY_WANDERING ) - { - CAIFaunaActivityBaseSpawnProfile *botProfile=NLMISC::safe_cast(getAIProfile()); - setAIProfile(new CBotProfileGoAway(this,getAStarFlag(), 1.f, botProfile)); - creatActivity=BOT_GO_AWAY; - } - else - { - if (creatActivity==ACTIVITY_CURIOSITY) - { - setAIProfile(new CBotProfileGoAway(this,getAStarFlag(), 1.f, NULL)); - creatActivity=BOT_GO_AWAY; - } - } - - } - - if (creatActivity==BOT_GO_AWAY) - { - CAIVector dir=delta; - const float qNorm=(float)dir.quickNorm(); - dir.normalize(1000.f/(qNorm+1.f)); - CBotProfileGoAway *const profile=NLMISC::safe_cast(getAIProfile()); - profile->getDecalageRef()+=dir; - float speed=100.f/(qNorm*qNorm+1.f); - if (speed>1.f) - speed=1.f; - profile->setSpeed(speed); - goAway=true; - } - } - } - } - - if ( bestVisualScore==1.f - || dist>(VISUAL_LOOK_AT_DIST-1.f)) - break; - - // if no visual target. - if (!((CAIEntityPhysical*)getVisualTarget()) && !((CAIEntityPhysical*)getTarget())) - { - if ( thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING - || thisProfileType==ACTIVITY_WANDERING ) - { - const float score=(float)(1.f/(1.f+dist+CAIS::rand32(7))); - if (score>bestVisualScore) - { - bestVisualScore=score; - visualTarget=entity; - } - } - } - } - break; - default: - break; - } - } // if entity is in test radius - } // for each entity in visual range - - TProfiles faunaActivity=getAIProfileType(); - if (faunaActivity==BOT_GO_AWAY) - { - CBotProfileGoAway *profile=NLMISC::safe_cast(getAIProfile()); - if (!goAway) //profile->decalage().isNull()) - { - CAIFaunaActivityBaseSpawnProfile* lastProfile = profile->lastProfile(); - if (canMove() && lastProfile) - { - IMouvementMagnetOwner* magnetOwner = NLMISC::safe_cast(lastProfile); - CMovementMagnet* movementMagnet = magnetOwner->getMovementMagnet(); - if (movementMagnet) - { - movementMagnet->setState(CMovementMagnet::Movement_Wait_Anim); - movementMagnet->stateTimer().set(CAIS::rand32(51)+50); // wait between 5 and 10 seconds. - } - setAIProfile(lastProfile, CProfilePtr::START_RESUME); - } - else - { - setDefaultComportment(); - } - } - } - - thisProfileType=getAIProfile()->getAIProfileType(); - - if (curiosityPlayer) - { - if ( thisProfileType==ACTIVITY_WANDERING - || thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING ) - { - setAIProfile(new CCuriosityFaunaProfile(this,curiosityPlayer->dataSetRow(), getAStarFlag())); - } - } - else - { - if (_TimeBeforeNextCuriosity.test()) - { - _TimeBeforeNextCuriosity.set((CAIS::rand32(120)+120)*10); // consider every 2 to 4 minutes; - } - } - - if (visualTarget) - { - thisProfileType=getAIProfile()->getAIProfileType(); - if ( thisProfileType==ACTIVITY_GRAZING - || thisProfileType==ACTIVITY_RESTING - || thisProfileType==ACTIVITY_WANDERING ) - { - setVisualTarget(visualTarget); - _VisualTargetTimer.set(CAIS::rand32(60)+10); - } - } -} - - -float CSpawnBotFauna::aggroRadius() -{ - switch (cycleState()) - { - case CFaunaActivity::CycleStateVeryHungry: - case CFaunaActivity::CycleStateStarving: - if (spawnGrp().getPersistent().places()[CGrpFauna::EAT_PLACE]->atPlace(CAIVector(pos()))) - return getPersistent().getSheet()->AggroRadiusHunting(); - else - return getPersistent().getSheet()->AggroRadiusHungry(); - default: - return getPersistent().getSheet()->AggroRadiusNotHungry(); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CMovementMagnet // -////////////////////////////////////////////////////////////////////////////// - -CMovementMagnet::CMovementMagnet(CSpawnBotFauna& botFauna, RYAI_MAP_CRUNCH::TAStarFlag flag) -: _BotFauna(botFauna) -, _PathPos(botFauna.theta()) -, _PathCont(flag) -, _denyFlags(flag) -{ - // start by moving during a variable time, just to disperse bot in their place.(must be initialised by constructor) - _StateTimer.set(0); // do not wait a long time .. :) - _State = Movement_Wait_Anim; - _PathPos._Angle = _BotFauna.theta(); - _Speed = _BotFauna.walkSpeed(); -} - -CMovementMagnet::~CMovementMagnet() -{ -} - -void CMovementMagnet::setBotAngle() -{ - _PathPos._Angle = _BotFauna.theta(); -} - -CAIVector const& CMovementMagnet::getDestination() const -{ -#ifdef NL_DEBUG - nlassert(isDestinationValid ()); -#endif - return _PathCont.getDestination(); -} - -bool CMovementMagnet::isDestinationValid() const -{ - return _PathCont.getDestPos().isValid(); -} - -void CMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag) -{ - if (CAIS::frand()>_BotFauna.getPersistent().getSheet()->GroupDispersion()) // to make some variety. - { - // first, try to take the same way as another bot of the group with the same comportment. - CCont &bots = _BotFauna.spawnGrp().bots(); - uint32 nbBots=(uint32)bots.size(); - - float bestScore=0.f; - CAIVector bestDest; - - for (uint32 i=0;i(bots[i]); - if (!bot) - continue; - - CSpawnBotFauna *faunaBot=bot->getSpawn(); - if ( !faunaBot - || faunaBot==&_BotFauna - || faunaBot->getAIProfileType()!=_BotFauna.getAIProfileType() ) - continue; - - IMouvementMagnetOwner* magnetOwner = dynamic_cast(faunaBot->getAIProfile()); - if (!magnetOwner) - continue; - - const CMovementMagnet *const movementMagnet = magnetOwner->getMovementMagnet(); - if ( !movementMagnet - || !movementMagnet->isDestinationValid()) - continue; - - const CAIVector &destPos=movementMagnet->getDestination (); - if ( destPos==_LastDest - || destPos==_PathCont.getDestination()) - continue; - - if ( !faunaBot->wpos().isValid() - || (faunaBot->wpos().getFlags()&denyFlag)!=0) - continue; - - // can be optimize by in avoid inversion. - const float distToBot=(float)(1.f/(faunaBot->pos().quickDistTo(_BotFauna.pos())+1.f)); - if (distToBot0) - { - _LastDest=_PathCont.getDestination(); - _PathCont.setDestination(vp_auto, bestDest); - return; - } - } - - // if failed, then try to take an random destination. - - // here, we have to find another place to go (!) - uint32 nbTries = 64; - CWorldPosition newPos; - float bestScore = 0; - - CSpawnGroupFauna const& grpFauna = _BotFauna.spawnGrp(); - CAIPlace const* const place = grpFauna.targetPlace(); - - do - { - --nbTries; - - CWorldPosition wRndPos; - _BotFauna.spawnGrp().targetPlace()->getRandomPos(wRndPos); - - // check if its a nogo and water proof position. - if ( !wRndPos.isValid() - || (wRndPos.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)!=0 ) - continue; - - #if !FINAL_VERSION - nlassertex(wRndPos.isValid(), ("Error: can't find a valid pos in place '%s'", _BotFauna.spawnGrp().targetPlace()->getAliasFullName().c_str())); - #else - if (!wRndPos.isValid()) - nlwarning("Error: can't find a valid pos in place '%s'", _BotFauna.spawnGrp().targetPlace()->getAliasFullName().c_str()); - #endif - - CAIVector const newPosVector = CAIVector(wRndPos); - - double const distToGrp = newPosVector.quickDistTo(grpFauna.getCenterPos()); - double distToBot = newPosVector.quickDistTo(_BotFauna.pos()); - - // if too near, then make this score not too good, else add some value to minimize the effect of bot dist / group dist. - distToBot += (distToBot<=1.0)?30.0:4.0; - - float const score = (float)(distToGrp/distToBot); - - if (score0); - - if (!newPos.isValid()) - { - _PathCont.setDestination(vp_auto, alternativePos); // the alternative pos given by parameters. - nlwarning("Error: can't find a valid pos in place '%s' near %s", _BotFauna.spawnGrp().targetPlace()->getAliasFullName().c_str(), _BotFauna.spawnGrp().targetPlace()->worldValidPos().toString().c_str()); - } - else - _PathCont.setDestination(vp_auto, newPos); -} - -void CMovementMagnet::update(uint32 waitTime, uint32 ticksSinceLastUpdate, bool ignoreBadPos) -{ - H_AUTO(MovementMagnet); - - switch (_State) - { - BeginAnim: - _State=Movement_Anim; - _StateTimer.set((uint32)((waitTime*0.5)+CAIS::rand16(waitTime))); - // drop through to Wait - - case Movement_Anim: - // this is a small hack to allow migration code to avoid turning - if (waitTime==0) - goto BeginMove; - // this is the basic wait code - it waits! - if (_StateTimer.test()) - goto BeginWaitAnim; - break; - - BeginWaitAnim: - // select a random angle in range +/-pi, biased towards 0 - // and setup dTheta and dThetaTimer to avoid turning again at start of movement - _StateTimer.set(100); //secs (wait for the anim to stop) - _State=Movement_Wait_Anim; - - case Movement_Wait_Anim: - if (_StateTimer.test()) - goto BeginMove; - break; - - BeginMove: - _State=Movement_Move; - getNewDestination (_BotFauna.wpos(), _denyFlags); // drop through to Move - - case Movement_Move: - { - if (!_BotFauna.canMove()) - break; - - float distToDest=(float)_PathCont.getDestination().quickDistTo(_BotFauna.pos()); - distToDest-=((_BotFauna.getPersistent().getChildIndex()&7)+1.5f); - - _Speed=_BotFauna.walkSpeed(); - float dist=_Speed*ticksSinceLastUpdate; - CAIVector lastPos=_BotFauna.pos(); - { - CAIVector deviateVector(CAngle(_BotFauna.theta().asRadians()+(Pi*0.5f)*sin(CTimeInterface::gameCycle()*0.03f+_BotFauna.getPersistent().getChildIndex())).asVector2d()); - _BotFauna.setMoveDecalage(_BotFauna.moveDecalage()+deviateVector); - } - CFollowPath::TFollowStatus status = CFollowPath::getInstance()->followPath( - &_BotFauna, - _PathPos, - _PathCont, - dist, - dist*.5f, - .5f); - - if (!ignoreBadPos) - { - if (status==CFollowPath::FOLLOW_NO_PATH) // No Path Found ! - getNewDestination (_BotFauna.wpos(), _denyFlags); // drop through to Move - - if (distToDest<=0 || lastPos.quickDistTo(_BotFauna.pos())<(dist*0.5f)) // too much people. - { - goto BeginAnim; - } - } - } - break; - } -} - -////////////////////////////////////////////////////////////////////////////// -// CReturnMovementMagnet // -////////////////////////////////////////////////////////////////////////////// - -CReturnMovementMagnet::CReturnMovementMagnet(RYAI_MAP_CRUNCH::CWorldPosition const& forcedDest, CSpawnBotFauna& botFauna, RYAI_MAP_CRUNCH::TAStarFlag flag) -: CMovementMagnet(botFauna, flag) -, _ForcedDest(forcedDest) -{ - /* - RYAI_MAP_CRUNCH::CWorldPosition wpos; - if (CWorldContainer::getWorldMap().setWorldPosition(forcedDest.h(), wpos, forcedDest.toAIVector())) - { - setWPos(wpos); - } - else - { - nlerror("Impossible to create a valid world pos for return magnet.") - } - */ -// sint32 z = forcedDest.h(); -// CAIVector const vect = forcedDest.toAIVector(); -// bool res = CWorldContainer::getWorldMap().setWorldPosition(z, _ForcedDest, vect); -// nlassert(res); -} - -void CReturnMovementMagnet::getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag) -{ - if (_ForcedDest.isValid() && (_ForcedDest.getTopologyRef().getCstTopologyNode().getFlags()&denyFlag)==0) - _PathCont.setDestination(_ForcedDest); - else - CMovementMagnet::getNewDestination(alternativePos, denyFlag); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotFauna // -////////////////////////////////////////////////////////////////////////////// - -CAIS::CCounter& CBotFauna::getSpawnCounter() -{ - return CAIS::instance()._FaunaBotCounter; -} - -CBotFauna::CBotFauna(AITYPES::TFaunaType type, CGroup* owner, CAIAliasDescriptionNode* alias) -: CBot(owner, alias) -, _Type(type) -, _Sheet(NULL) -{ - _Sheet = CBotFaunaSheetPtr(new CBotFaunaSheet(NULL)); - _Sheet->setSheet(CBot::getSheet()); -} - -CBotFauna::~CBotFauna() -{ - if (isSpawned()) - { - despawnBot(); - } -} - -CSpawnBot* CBotFauna::getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius) -{ - return new CSpawnBotFauna(row, *this, id, radius, getSheet()->Level(), getGroup().getAStarFlag()); -} - -bool CBotFauna::reSpawn(bool sendMessage) -{ - // we made some tries because its an random positionned spawn that may failed some times .. - uint32 maxtries = 100; - while (!spawn() && maxtries>0) - { - --maxtries; - } - - if (!isSpawned() && sendMessage) - { - LOG("Cannot spawn a fauna bot %s", getFullName().c_str()); - } - return isSpawned(); -} - -// :KLUDGE: This methods is a part of the trick for bot respawn -// :TODO: Clean that mess -bool CBotFauna::finalizeSpawnFauna() -{ - getSpawn()->sendInfoToEGS(); - - // execute birth script :) - AISHEETS::ICreature::TScriptCompList const& scriptList = getSheet()->BirthScriptList(); - FOREACHC(it, AISHEETS::ICreature::TScriptCompList, scriptList) - (*it)->update(*getSpawn()); - return true; -} - -// nothing special is made, its a simple bot spawn. -bool CBotFauna::spawn() -{ - // initialise the energy value. - initEnergy(NLMISC::safe_cast(getOwner())->getEnergyCoef()); - - if (!CBot::spawn()) - return false; - - // :KLUDGE: Last part calls a tricky method also called by sheetChanged - // :TODO: Clean that mess - return finalizeSpawnFauna(); -} - -void CBotFauna::despawnBot() -{ - CBot::despawnBot(); -} - -CGrpFauna& CBotFauna::grp() const -{ - return *static_cast(getOwner()); -} - -CMgrFauna& CBotFauna::mgr() const -{ - return *static_cast(grp().getOwner()); -} - -void CBotFauna::getSpawnPos(CAIVector& triedPos, CWorldPosition& pos, CWorldMap const& worldMap, CAngle& spawnTheta) -{ - nlassert(grp().getSpawnObj()); - CSpawnGroupFauna* grpFauna = grp().getSpawnObj(); - CBotFauna* leader = grpFauna->leader(); - - spawnTheta = CAngle(CAIS::frand(2*NLMISC::Pi)); - - // if possible, fauna must spawn near its leader. - if (leader && leader->isSpawned() && getSheet()->FaunaType()!=FaunaTypePlant) - { - RYAI_MAP_CRUNCH::CWorldPosition leaderPos=leader->getSpawn()->wpos(); - // if the leader is not in the current place .. - if (!grpFauna->targetPlace()->atPlace(leaderPos)) - { // spawn the fauna near the leader (same place for instance). - pos = leaderPos; - } - } - - if (!pos.isValid()) - { - // if we try to spawn a plant, try to find a position where no plant already are. - if (getSheet()->FaunaType()==FaunaTypePlant) - { - bool rejected = true; - uint32 nbTry = 64; - while (nbTry-- > 0 && rejected) - { - grpFauna->targetPlace()->getRandomPos(pos); - - // Check if this place is Valid for us .. - CAIVision vision; - vision.updateBotsAndPlayers(getAIInstance(), pos,0,2); - std::vector > const& bots = vision.bots(); - - rejected = false; - FOREACHC(it, std::vector >, bots) - { - CAIEntityPhysical const* const phys = (*it)->getSpawnObj(); - if (!phys || phys->getRyzomType()!=RYZOMID::creature) - continue; - - CSpawnBotFauna const* const fauna = NLMISC::safe_cast(phys); - if ( fauna!=NULL - && fauna->getPersistent().getSheet()->FaunaType()==FaunaTypePlant - && fauna->pos().quickDistTo(pos.toAIVector())<2) - { - rejected = true; - break; - } - } - }; - #if !FINAL_VERSION - if (rejected) - { - nlwarning ("Solo Plant Pos Spawn Not Found at: %s", pos.toString().c_str()); - } - #endif - } - else - { - uint32 tries = 100; // think we won't be so expensive in the average case. - while (tries-- > 0) - { - RYAI_MAP_CRUNCH::CCompatibleResult res; - grpFauna->targetPlace()->getRandomPos(pos); - areCompatiblesWithoutStartRestriction(pos, grpFauna->targetPlace()->worldValidPos(), getGroup().getAStarFlag(), res); - if (res.isValid()) // Cool! - break; - } - } - } - triedPos = pos.toAIVector(); -} - -std::string CBotFauna::getOneLineInfoString() const -{ - return std::string("Fauna bot '") + getName() + "'" + "(AliasName : "+getAliasFullName()+")"; -} - - -void CBotFauna::sheetChanged() -{ - if (getSpawnObj()) - { - // Get bot state - RYAI_MAP_CRUNCH::CWorldPosition botWPos = getSpawnObj()->wpos(); - CAngle spawnTheta = getSpawnObj()->theta(); - float botMeterSize = getSheet()->Scale()*getSheet()->Radius(); - // :TODO: Save profile info - - // If stuck bot position may be outside collision and must be recomputed - if (isStuck() || IsRingShard) - getSpawnPos(lastTriedPos, botWPos, CWorldContainer::getWorldMap(), spawnTheta); - - // Delete old bot - CMirrors::removeEntity(getSpawnObj()->getEntityId()); - setSpawn(NULL); // automatic smart pointer deletion - notifyBotDespawn(); - - // Finalize spawn object creation - if (!finalizeSpawn(botWPos, spawnTheta, botMeterSize)) - return; - - // :KLUDGE: Both finalizeSpawn and finalizeSpawnFauna are called, - // sheetChanged has a strange herited meaning and may confuse future - // coders - // :TODO: Clean that mess and find a more elegant C++ solution to the - // problem - finalizeSpawnFauna(); - } -} - -void CBotFauna::triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet) -{ - // :KLUDGE: This test is there to mimick the behaviour of the client. This - // is not the better way to do this, but the client is so... well, you see - // what I mean. - if (EGSPD::CPeople::Creature<=sheet->Race() && sheet->Race()(owner)) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _Speed(speed) -, _LastProfile(lastProfile) -, _fightGoAwayPathContainer(denyFlags) -{ -} - -void CBotProfileGoAway::beginProfile() -{ - _LastDir = RYAI_MAP_CRUNCH::CDirection(RYAI_MAP_CRUNCH::CDirection::UNDEFINED); - _fightGoAwayPathContainer.setDestination(vp_auto, CAIVector(_Bot->pos())); - _Bot->setMode(MBEHAV::NORMAL); -} - -void CBotProfileGoAway::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(BotGoAwayProfileUpdate) - CFollowPathContext fpcBotGoAwayProfileUpdate("BotGoAwayProfileUpdate"); - - if (!_Bot->canMove()) - return; - - bool calcDone=true; - - if (_Decalage.isNull()) - _Decalage.setX(1+_Decalage.x()); // hum .. - RYAI_MAP_CRUNCH::CDirection startDir(_Decalage.x(), _Decalage.y(), true); - - // if we need to change our destination. - if ( startDir!=_LastDir - || _fightGoAwayPathContainer.getDestPos(/*_Bot->size()*/).hasSameFullCellId(_Bot->wpos()) ) - { - float BestScore=-1.f; - RYAI_MAP_CRUNCH::CWorldPosition BestPos; - - const RYAI_MAP_CRUNCH::CWorldMap &worldMap=CWorldContainer::getWorldMap(/*_Bot->size()*/); - calcDone=false; - - sint nbStep=0; - - while (nbStep<8) - { - // try to find a direction around startDir. - RYAI_MAP_CRUNCH::CDirection dir(startDir); - dir.addStep((RYAI_MAP_CRUNCH::CDirection::TDeltaDirection) ((nbStep&1)?(nbStep>>1):(-(nbStep>>1)))); - - const RYAI_MAP_CRUNCH::CRootCell *rootCell=worldMap.getRootCellCst(_Bot->wpos().stepCell(dir.dx(),dir.dy())); // _Bot->wpos() - if (rootCell) - { - for (uint32 pointIndex=0;pointIndex<4;pointIndex++) - { - const RYAI_MAP_CRUNCH::CWorldPosition &wpos=rootCell->getWorldPosition(pointIndex); - - if (wpos.isValid()) - { - CCompatibleResult res; - areCompatiblesWithoutStartRestriction(_Bot->wpos(), wpos, _fightGoAwayPathContainer.getDenyFlags(), res); - if (!res.isValid()) - { - // nlwarning("Error case avoided. Please report this warning to jvuarand."); - continue; - } - - CAIVector deltaToDest(wpos-_Bot->wpos()); - const float score=(float) CAIVector(wpos-_Bot->wpos()).dot(_Decalage); //*deltaToDest.norm(); - if ( score>BestScore - && deltaToDest.quickNorm()>2.f) // minimum distance requires. - { - BestScore=score; - BestPos=wpos; - } - } - } - } - nbStep++; - } - - RYAI_MAP_CRUNCH::CCompatibleResult res; - if (_Bot->wpos().isValid() && BestPos.isValid()) - { - areCompatiblesWithoutStartRestriction(_Bot->wpos(), BestPos, _fightGoAwayPathContainer.denyFlags(), res, true); - if (BestPos.isValid() && res.isValid()) - { - _LastDir=startDir; - _LastStartPos=_Bot->wpos(); - calcDone=true; - _fightGoAwayPathContainer.setDestination(vp_auto, BestPos); - } - } - } - - // if we found somewhere to go, then go there .. - if (calcDone) - { - const float dist= ((1.f-_Speed)*_Bot->walkSpeed()+_Speed*_Bot->runSpeed())*ticksSinceLastUpdate; - - _Decalage.normalize(100.f*1000.f); - _Decalage += CAIVector(_Bot->pos()); - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _fightGoAwayPathContainer, - dist, - dist*.71f, - .5f, - true, - &_Decalage); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - #if !FINAL_VERSION - nlwarning("GoAway followpath problem (!!)"); - #endif - } - } - else - { - _LastDir=RYAI_MAP_CRUNCH::CDirection(RYAI_MAP_CRUNCH::CDirection::UNDEFINED); - } - _Decalage=CAIVector(0,0); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileGoAway // -////////////////////////////////////////////////////////////////////////////// - -NLMISC::CSmartPtr CBotProfileGoAwayFactory::createAIProfile(CProfileOwner* owner) -{ - nlassert(false); - return NULL; -} - -////////////////////////////////////////////////////////////////////////////// -// Global functions // -////////////////////////////////////////////////////////////////////////////// - -static const char *cyclesStateName(CFaunaActivity::TCycleState s) -{ - switch (s) - { - case CFaunaActivity::CycleStateHungry: return "HUNGRY"; - case CFaunaActivity::CycleStateVeryHungry: return "VERY_HUNGRY"; - case CFaunaActivity::CycleStateStarving: return "STARVING"; - case CFaunaActivity::CycleStateDigesting: return "DIGESTING"; - case CFaunaActivity::CycleStateTired: return "TIRED"; - case CFaunaActivity::CycleStateVeryTired: return "VERY_TIRED"; - case CFaunaActivity::CycleStateExhausted: return "EXHAUSTED"; - case CFaunaActivity::CycleStateShaking: return "SHAKING"; - default: - break; - } - return "UNKNOWN STATE"; -} - diff --git a/code/ryzom/server/src/ai_service/ai_bot_fauna.h b/code/ryzom/server/src/ai_service/ai_bot_fauna.h deleted file mode 100644 index bb0306afc..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_fauna.h +++ /dev/null @@ -1,341 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_BOT_FAUNA_H -#define RYAI_BOT_FAUNA_H - -#define FAUNA_BEHAVIOR_GLOBAL_SCALE (4) - -#include "ai_bot.h" -#include "timer.h" -#include "path_behaviors.h" - -class CFauna; -class CSpawnGroupFauna; -class CBotPlayer; -class CBotFauna; -class CGrpFauna; -class CMgrFauna; - -class CGeneralFaunaUpdate; - -////////////////////////////////////////////////////////////////////////////// -// CFaunaActivity // -////////////////////////////////////////////////////////////////////////////// - -class CFaunaActivity -{ -public: - virtual ~CFaunaActivity() { } - - enum TCycleState - { - // eat behaviour cycles. - CycleStateHungry = 0, - CycleStateVeryHungry, - CycleStateStarving, - CycleStateDigesting, - - // sleep behaviour cycles. - CycleStateTired, - CycleStateVeryTired, - CycleStateExhausted, - CycleStateShaking, - - CycleStateUndefined - }; - - virtual void update() = 0; - virtual AITYPES::TProfiles getActivityType() = 0; -}; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotFauna // -////////////////////////////////////////////////////////////////////////////// - -class CSpawnBotFauna -: public CSpawnBot -{ -public: - CSpawnBotFauna(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - virtual ~CSpawnBotFauna(); - - CSpawnGroupFauna& spawnGrp(); - - void update(AITYPES::TProfiles activity, uint32 ticksSinceLastUpdate); - - bool canMove() const; - - ////////////////////////////////////////////////////////////////////////// - // Specific - ////////////////////////////////////////////////////////////////////////// - - CFaunaActivity::TCycleState const& cycleState() const { return _CycleState; } - void setCycleState(CFaunaActivity::TCycleState const& cycleState) { _CycleState=cycleState; } - - ////////////////////////////////////////////////////////////////////////// - // Fight Features. - ////////////////////////////////////////////////////////////////////////// - - void getBestTarget(); - - void processEvent(CCombatInterface::CEvent const& event); - void eventEngaged(TDataSetRow const& originId); - - /// @name Profiles transition - //@{ - void doFight(CAIEntityPhysical* ennemy); - void setDefaultComportment(); - //@} - - - float aggroRadius(); - - float getCollisionDist(float angTo) const; - - void setHungry() { _Hungry = 1.f; } - float& hungry() { return _Hungry; } - - // fauna are always attackable by other bots - virtual bool isBotAttackable() const { return true; } - - ////////////////////////////////////////////////////////////////////////// - // Specific ( Comportement ) - ////////////////////////////////////////////////////////////////////////// - - //---------------------------------------------------------------------------------------------- - // Dispatching message to EGS to describe chat possibilities - //---------------------------------------------------------------------------------------------- - - void sendInfoToEGS() const; - - CBotFauna& getPersistent() const; - - // replace by 'getRYZOMType' - virtual RYZOMID::TTypeId getRyzomType() const { return RYZOMID::creature; } - - ////////////////////////////////////////////////////////////////////////// - // Specific ( Comportement ) - ////////////////////////////////////////////////////////////////////////// - - CFaunaActivity::TCycleState _CycleState; - - CAITimer& timeBeforeNextCuriosity() { return _TimeBeforeNextCuriosity; } - - CAITimer& VisualTargetTimer() { return _VisualTargetTimer; } - - float getReturnDistCheck() const; - -private: - float _Hungry; - float _Food; - CAITimer _TimeBeforeNextCuriosity; - CAITimer _VisualTargetTimer; - CAITimer _NextBestTargetUpdate; -}; - -////////////////////////////////////////////////////////////////////////////// -// CMovementMagnet // -////////////////////////////////////////////////////////////////////////////// - -class CMovementMagnet -: public NLMISC::CRefCount -{ -public: - enum TMovementType - { - Movement_Anim = 0, - Movement_Wait_Anim, - Movement_Move - }; - - CMovementMagnet(CSpawnBotFauna& botFauna, RYAI_MAP_CRUNCH::TAStarFlag flag); - virtual ~CMovementMagnet(); - virtual void update(uint32 waitTime, uint32 ticksSinceLastUpdate) { update(waitTime, ticksSinceLastUpdate, false); } - void setBotAngle(); - - virtual void getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag); - CAIVector const& getDestination() const; - bool isDestinationValid() const; - TMovementType getMovementType() const { return _State; } - - CAITimer& stateTimer() { return _StateTimer; } - - void setState(TMovementType state) { _State = state; } - -protected: - void update(uint32 waitTime, uint32 ticksSinceLastUpdate, bool ignoreBadPos); - CPathCont _PathCont; -private: - float _Speed; - CAngle _dTheta; // the change in orientation at last update - CAITimer _dThetaTimer; // the time for which the current rotation will be applied - - CAITimer _StateTimer; - TMovementType _State; - - RYAI_MAP_CRUNCH::TAStarFlag _denyFlags; - - CSpawnBotFauna& _BotFauna; - CPathPosition _PathPos; - CAIVector _LastDest; -}; - -////////////////////////////////////////////////////////////////////////////// -// CReturnMovementMagnet // -////////////////////////////////////////////////////////////////////////////// - -class CReturnMovementMagnet -: public CMovementMagnet -{ -public: - CReturnMovementMagnet(RYAI_MAP_CRUNCH::CWorldPosition const& forcedDest, CSpawnBotFauna& botFauna, RYAI_MAP_CRUNCH::TAStarFlag flag); - virtual void getNewDestination(RYAI_MAP_CRUNCH::CWorldPosition const& alternativePos, RYAI_MAP_CRUNCH::TAStarFlag denyFlag); - virtual void update(uint32 waitTime, uint32 ticksSinceLastUpdate) { CMovementMagnet::update(waitTime, ticksSinceLastUpdate, true); } - -private: - RYAI_MAP_CRUNCH::CWorldPosition _ForcedDest; -}; - -////////////////////////////////////////////////////////////////////////////// -// IMouvementMagnetOwner // -////////////////////////////////////////////////////////////////////////////// - -class IMouvementMagnetOwner -{ -public: - virtual NLMISC::CSmartPtr const& getMovementMagnet() const = 0; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotFaunaSheet // -////////////////////////////////////////////////////////////////////////////// - -class CBotFaunaSheet -: public AISHEETS::CCreatureProxy -{ -public: - CBotFaunaSheet(AISHEETS::ICreatureCPtr const& sheet) - : AISHEETS::CCreatureProxy(sheet) - , _AggroRadiusNotHungry(0.f) - , _AggroRadiusHungry(0.f) - , _AggroRadiusHunting(0.f) - { - reset(); - } - - virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet) - { - CCreatureProxy::setSheet(sheet); - reset(); - } - - ///@name ICreature overloads - //@{ - virtual float AggroRadiusNotHungry() const { return _AggroRadiusNotHungry; } - virtual float AggroRadiusHungry() const { return _AggroRadiusHungry; } - virtual float AggroRadiusHunting() const { return _AggroRadiusHunting; } - //@} - - ///@name Setters - //@{ - void setAggroRadiusNotHungry(float val) { _AggroRadiusNotHungry = val; } - void setAggroRadiusHungry(float val) { _AggroRadiusHungry = val; } - void setAggroRadiusHunting(float val) { _AggroRadiusHunting = val; } - //@} - - void reset() - { - if (_Sheet) - { - _AggroRadiusNotHungry = _Sheet->AggroRadiusNotHungry(); - _AggroRadiusHungry = _Sheet->AggroRadiusHungry(); - _AggroRadiusHunting = _Sheet->AggroRadiusHunting(); - } - } - -private: - float _AggroRadiusNotHungry; - float _AggroRadiusHungry; - float _AggroRadiusHunting; -}; -typedef NLMISC::CSmartPtr CBotFaunaSheetPtr; -typedef NLMISC::CSmartPtr CBotFaunaSheetCPtr; - -////////////////////////////////////////////////////////////////////////////// -// CBotFauna // -////////////////////////////////////////////////////////////////////////////// - -class CBotFauna -: public NLMISC::CDbgRefCount -, public CBot -{ -public: - CBotFauna(AITYPES::TFaunaType type, CGroup* owner, CAIAliasDescriptionNode* alias = NULL); - - virtual ~CBotFauna(); - - AITYPES::TFaunaType faunaType() const { return _Type; } - - CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius); - - CAIS::CCounter& getSpawnCounter(); - - virtual bool spawn(); - void despawnBot(); - bool reSpawn(bool sendMessage = true); - - CSpawnBotFauna* getSpawn() { return static_cast(getSpawnObj()); } - - RYZOMID::TTypeId getRyzomType() const { return RYZOMID::creature; } - - CGrpFauna& grp() const; - CMgrFauna& mgr() const; - - // (assuming targetPlace is always valid ..) - void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta); - - virtual std::string getOneLineInfoString() const; - - virtual AISHEETS::ICreatureCPtr getSheet() const { return _Sheet.getPtr(); } - virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet) - { - _Sheet->setSheet(sheet); - sheetChanged(); - } - virtual bool isSheetValid() const - { - return _Sheet!=NULL && _Sheet->isValid(); - } - - void setAggroRadiusNotHungry(float val) { _Sheet->setAggroRadiusNotHungry(val); } - void setAggroRadiusHungry(float val) { _Sheet->setAggroRadiusHungry(val); } - void setAggroRadiusHunting(float val) { _Sheet->setAggroRadiusHunting(val); } - void resetAggroRadius() { _Sheet->reset(); } - - void triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet); - -protected: - virtual void sheetChanged(); - bool finalizeSpawnFauna(); - -private: - AITYPES::TFaunaType _Type; - CAIPos _SpawnPos; - CBotFaunaSheetPtr _Sheet; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot_inline.h b/code/ryzom/server/src/ai_service/ai_bot_inline.h deleted file mode 100644 index 13e0978c7..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_inline.h +++ /dev/null @@ -1,22 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_BOT_INLINE_H -#define RYAI_BOT_INLINE_H - -// This file is now obsolete - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp b/code/ryzom/server/src/ai_service/ai_bot_npc.cpp deleted file mode 100644 index 77870adb7..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_npc.cpp +++ /dev/null @@ -1,1261 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" - -#include "game_share/visual_slot_manager.h" -#include "server_share/r2_variables.h" - -#include "ai_bot_npc.h" -#include "ai_grp_npc.h" -#include "ai_mgr_npc.h" -#include "ai_player.h" -#include "states.h" -#include "ai_profile_npc.h" -#include "ai_control_npc.h" - -#include "ais_user_models.h" -#include "dyn_grp_inline.h" - -using namespace MULTI_LINE_FORMATER; - -using namespace std; -using namespace RYAI_MAP_CRUNCH; - -// Stuff used for management of log messages -static bool VerboseLog = false; -#define LOG if (!VerboseLog) { } else nlinfo - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotNpc // -////////////////////////////////////////////////////////////////////////////// - -CSpawnBotNpc::CSpawnBotNpc(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CSpawnBot(row, owner, id, radius, level, denyFlags) -{ - _OldHpPercentage = -1.f; - _NbCurrentDynChats = 0; - _FacingTheta = 0; - _FacingTick = 0; -} - -bool CSpawnBotNpc::isBotAttackable() const -{ - return getPersistent().grp().getBotAttackable(); -} - -void CSpawnBotNpc::sendInfoToEGS() const -{ - if (!EGSHasMirrorReady) - return; - - CSpawnBot::sendInfoToEGS(); - - TGenNpcDescMsgImp msg; - msg.setEntityIndex(dataSetRow()); - - getPersistent().fillDescriptionMsg(msg); - - msg.setChat(_CurrentChatProfile); - msg.send("EGS"); -} - -CSpawnGroupNpc& CSpawnBotNpc::spawnGrp() const -{ - return static_cast(CSpawnBot::spawnGrp()); -} - -void CSpawnBotNpc::processEvent(CCombatInterface::CEvent const& event) -{ - // no self aggro. - if (event._targetRow==event._originatorRow) - return; - - if ((event._nature==ACTNATURE::FIGHT || event._nature==ACTNATURE::OFFENSIVE_MAGIC) && !getPersistent().ignoreOffensiveActions()) - { - float aggro = event._weight; - if (aggro > -0.20f) - { - aggro = -0.20f; - } - if (event._nature==ACTNATURE::OFFENSIVE_MAGIC) - { - aggro=(1.f+aggro)*0.5f-1.f; // maximize aggro for magic - //insure if aggressor is player, player have it's target seted for BOSS assist - CAIEntityPhysical *ep=CAIS::instance().getEntityPhysical(event._originatorRow); - CBotPlayer *player=dynamic_cast(ep); - if(player) - { - CAIEntityPhysical *target=player->getVisualTarget(); - if (target) - player->setTarget(target); - } - } - addAggroFor(event._originatorRow, aggro, true); - spawnGrp().addAggroFor(event._originatorRow, aggro, true); - } -} - - void CSpawnBotNpc::update(uint32 ticks) -{ - ++AISStat::BotTotalUpdCtr; - ++AISStat::BotNpcUpdCtr; - - { - H_AUTO(AIHpTrig); - // Fix for HP triggers - // :FIXME: Clean that triggering stuff, make it generic - CGroupNpc& persGrp = spawnGrp().getPersistent(); - if (persGrp.haveHpTriggers()) - { - float newHpPercentage = getPhysical().hpPercentage(); - if (_OldHpPercentage>=0.f && newHpPercentage!=_OldHpPercentage) - { - persGrp.hpTriggerCb(_OldHpPercentage, newHpPercentage); - } - _OldHpPercentage = newHpPercentage; - } - else - { - _OldHpPercentage = getPhysical().hpPercentage(); - } - } - - // Bot chat and dyn chat override AI profile unless fighting - // The directing adjustment is done client-slide (each player sees the NPC facing him) - if (!getActiveChats().empty()) - return; - if (getNbActiveDynChats() > 0) - return; - if (isStuned()) - return; - - // position before profile update - CAIPos const startPos = CAIPos(pos()); - - // nullify _PlayerController if it is not valid anymore - if (_PlayerController != NULL && !_PlayerController->isValid()) - { - CSpawnBot* sp = _PlayerController->getSpawnBot(); - if (sp) - { - sp->getPersistent().notifyStopNpcControl(); - } - - _PlayerController = NULL; - - } - - if (_PlayerController == NULL) - { - if (!getAISpawnProfile().isNull()) - { - H_AUTO(BotNpcUpdateProfile); - updateProfile(ticks); // then we can update the current bot profile. - } - } - else - { - H_AUTO(BotNpcUpdateControl); - // if there is a valid player controller, it overrides the current profile - _PlayerController->updateControl(ticks); - } - - { - H_AUTO(BotNpcUpdateAgro); - // every time we need to update bot aggros. - this->CBotAggroOwner::update(ticks); - } - - // If sit and move then stand up - - if (IsRingShard) - { - if (getMode() == MBEHAV::SIT - && (x().asInt() != startPos.x().asInt() || y().asInt() != startPos.y().asInt()) ) - { - setMode(MBEHAV::NORMAL); - } - - - if (_FacingTick != 0) - { - uint32 tick = CTimeInterface::gameCycle(); - if ( (tick - _FacingTick) > 40) - { - setTheta(_FacingTheta); - _FacingTick = 0; - } - } - } - -} - -void CSpawnBotNpc::setFacing(CAngle theta) -{ - if (_FacingTick == 0) - { - _FacingTheta = pos().theta(); - } - - setTheta(theta); - _FacingTick = CTimeInterface::gameCycle(); -} - -void CSpawnBotNpc::setUserModelId(const std::string &id) -{ - _UserModelId = id; -} - -void CSpawnBotNpc::setCustomLootTableId(const std::string &id) -{ - _CustomLootTableId = id; -} - - -void CSpawnBotNpc::setPrimAlias(uint32 primAlias) -{ - _PrimAlias = primAlias; -} -void CSpawnBotNpc::updateChat(CAIState const* state) -{ - if (!state) - return; - CBotNpc const& botNpc = getPersistent(); - - FOREACHC(itChat, CCont, state->chats()) - { - if (!itChat->testCompatibility(botNpc)) - continue; - - // update chat information if any - CNpcChatProfileImp const* const chatProfile = botNpc.getChat(); - if (!chatProfile) - { - _CurrentChatProfile = CNpcChatProfileImp::combineChatProfile(*chatProfile, itChat->getChat()); - // the chat profile has been combined, send it to EGS - sendInfoToEGS(); - } - break; - } -} - -std::vector CSpawnBotNpc::getMultiLineInfoString() const -{ - std::vector container; - std::vector strings; - - - pushTitle(container, "CSpawnBotNpc"); - strings.clear(); - strings = CSpawnBot::getMultiLineInfoString(); - FOREACHC(itString, std::vector, strings) - pushEntry(container, *itString); - pushEntry(container, "profile: " + CProfilePtr::getOneLineInfoString()); - pushEntry(container, "state: " + spawnGrp().getPersistent().buidStateInstanceDebugString()); - std::string userModelId = getPersistent().getUserModelId(); - if (!(userModelId.empty())) - { - pushEntry(container, "UserModelId: " + userModelId); - } - if (_CurrentChatProfile.getMissions().empty()) - pushEntry(container, "no mission"); - else - { - vector const& missions = _CurrentChatProfile.getMissions(); - pushEntry(container, "missions:"); - for (size_t i=0; ifindMissionName(missions[i]); - pushEntry(container, NLMISC::toString(" %u (%s)", missions[i], name.c_str())); - } - } - pushFooter(container); - - - return container; -} - -void CSpawnBotNpc::beginBotChat(CBotPlayer* plr) -{ -#ifdef NL_DEBUG - for (size_t i=0; i<_ActiveChats.size(); ++i) - { - if (_ActiveChats[i]==plr) - nlwarning("Chat pair added more than once!!!"); - } -#endif - - // add an entry to the bot chat vector - _ActiveChats.push_back(plr); -} - -void CSpawnBotNpc::endBotChat(CBotPlayer* plr) -{ - // run through the bot chat vector looking for a player to erase - for (size_t i=0;i<_ActiveChats.size();++i) - { - if (_ActiveChats[i]!=plr) - continue; - - // we've found a match for the player so remove the entry from the _aciveChats vector and return - _ActiveChats[i] = _ActiveChats[_ActiveChats.size()-1]; - _ActiveChats.pop_back(); - -#ifdef NL_DEBUG - for (size_t j=i;j<_ActiveChats.size();++j) - { - if (_ActiveChats[i]==plr) - { - nlwarning("Chat pair removed but another of the same still exists!!!"); - } - } -#endif - return; - } - // we should never end up here! - nlwarning("Chat pair removed but not previously added!!!"); -} - -void CSpawnBotNpc::propagateAggro() const -{ - if (getAggroPropagationRadius()<0.f) - return; - CGroup* pGroup = getPersistent().getOwner(); - CSpawnGroup* spGroup = pGroup->getSpawnObj(); - CDynGrpBase* myDgb = pGroup->getGrpDynBase(); - nlassert(myDgb); - CFamilyBehavior* myfb = myDgb->getFamilyBehavior(); - - CAIVision vision; - // look for bots around - vision.updateBotsAndPlayers(pGroup->getAIInstance(), CAIVector(pos()), 0, (uint32)getAggroPropagationRadius()); - - typedef map TCandidatesCont; - TCandidatesCont candidates; - - if (myfb!=NULL) - { - FOREACH(it, CAIVision, vision) - { - CBot& otherPBot = static_cast(*it); - CSpawnBot* otherSpBot = otherPBot.getSpawnObj(); - CGroup* otherPGroup = otherPBot.getOwner(); - CSpawnGroup* otherSpGroup = otherPGroup->getSpawnObj(); - - // If bot is in our group skip it - if (otherSpGroup==spGroup) - continue; - - // If bot is not in a dynamic system skip it - CDynGrpBase* otherDGB = otherPGroup->getGrpDynBase(); - if (!otherDGB) - continue; - - // If bot is not in our family skip it - CFamilyBehavior* otherFB = otherDGB->getFamilyBehavior(); - if (otherFB!=myfb) - continue; - - // ok, this group should help us ! - - // TODO : take only groups with the 'activity_figth' property - // filter out if the group is already in combat mode - - // If group is not spawned skip it (???) (:TODO: See why this test) - if (!otherPGroup->isSpawned()) - continue; - - CProfilePtr& otherFightProfile = otherSpGroup->fightProfile(); - - if (!otherFightProfile.getAIProfile() || otherFightProfile.getAIProfileType()!=AITYPES::FIGHT_NORMAL || !(static_cast(otherFightProfile.getAIProfile())->stillHaveEnnemy())) - { - float dist = (float)CAIVector(otherSpBot->pos()).quickDistTo(pos()); - if (distsecond / getAggroPropagationRadius()); - nldebug(" prop aggro from %p to %p at %f meters, prop factor = %f", - this, - it->first, - it->second, - propFactor); - // add aggro list of this group to the other group pondered by distance - it->first->mergeAggroList(*this, propFactor); - } -} - -float CSpawnBotNpc::getReturnDistCheck() const -{ - if (getPersistent().isSheetValid() && getPersistent().getSheet()->AggroReturnDistCheck()>=0.f) - return getPersistent().getSheet()->AggroReturnDistCheck(); - else - return AggroReturnDistCheckNpc; -} - -void CSpawnBotNpc::setPlayerController(CBotPlayer* player) -{ - if (player != NULL) - { - _PlayerController = new CPlayerControlNpc(player, this); - nlassert(_PlayerController->isValid()); - - } - else - { - _PlayerController = NULL; - } -} - -void CSpawnBotNpc::setCurrentChatProfile(CNpcChatProfileImp* chatProfile) -{ - if (chatProfile) - _CurrentChatProfile = *chatProfile; - else - _CurrentChatProfile.clear(); // clear the chat profile -} - -CBotNpc& CSpawnBotNpc::getPersistent() const -{ - return static_cast(CSpawnBot::getPersistent()); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotNpc // -////////////////////////////////////////////////////////////////////////////// - -CBotNpc::CBotNpc(CGroup* owner, CAIAliasDescriptionNode* alias) -: CBot(owner, alias) -, _Sheet(NULL) -{ - _Sheet = CBotNpcSheetPtr(new CBotNpcSheet(NULL)); - _Sheet->setSheet(CBot::getSheet()); - init(); -} - -CBotNpc::CBotNpc(CGroup* owner, uint32 alias, std::string const& name) -: CBot(owner, alias, name) -, _Sheet(NULL) -{ - _Sheet = CBotNpcSheetPtr(new CBotNpcSheet(NULL)); - _Sheet->setSheet(CBot::getSheet()); - init(); -} - -CBotNpc::~CBotNpc() -{ - if (isSpawned()) - { - despawnBot(); - } -} - -void CBotNpc::calcSpawnPos(RYAI_MAP_CRUNCH::CWorldMap const& worldMap) -{ - CAIStatePositional const* const state = static_cast(grp().getStartState()); - RYAI_MAP_CRUNCH::CWorldPosition wp; - uint32 maxTries = 100; - - breakable - { - if (!state) - break; - - if (state->shape().hasPatat() && state->shape().getRandomPosCount()) - { - do - { - RYAI_MAP_CRUNCH::CWorldPosition wp; - state->shape().getRandomPos(wp); - _StartPos.setXY(wp); - maxTries--; - } while(!worldMap.setWorldPosition(_VerticalPos, wp, _StartPos) && maxTries); - _StartPos.setTheta(0); // to initialise among vertices deltas (no?). - break; - } - - if (!state->shape().hasPoints()) - break; - - std::vector const& posList = state->shape().getGeometry(); - do - { - const uint32 a=CAIS::rand16((uint32)posList.size()); - const uint32 b=(a+1)%posList.size(); - const double weight=CAIS::frand(); - _StartPos.setXY(posList[a].toAIVector()+(posList[b].toAIVector()-posList[a].toAIVector())*weight); - --maxTries; - } while (!worldMap.setWorldPosition(_VerticalPos, wp, _StartPos) && maxTries); - _StartPos.setTheta(0); // to initialise among vertices deltas (no?). - } - - if (!wp.isValid() && !isStuck()) - nlwarning("Cannot generate a valid position for Npc %s", getFullName().c_str()); -} - -CGroupNpc& CBotNpc::grp() const -{ - return *static_cast(getOwner()); -} - -void CBotNpc::setUserModelId(const std::string &userModelId) -{ - if (!userModelId.empty()) - { - if (!CAIUserModelManager::getInstance()->isUserModel(_PrimAlias, userModelId)) - { - nlwarning("Error while parsing equipment params: cannot find user model id '%s' associated to primAlias '%u'", userModelId.c_str(), _PrimAlias); - _UserModelId = ""; - return; - } - _UserModelId = userModelId; - } -} - -void CBotNpc::setCustomLootTableId(const std::string &customLootTableId) -{ - if (!customLootTableId.empty()) - { - if (!CAIUserModelManager::getInstance()->isCustomLootTable(_PrimAlias, customLootTableId)) - { - nlwarning("Error while parsing equipment params: invalid customLootTableId specified: '%s'", customLootTableId.c_str()); - _CustomLootTableId = ""; - return; - } - _CustomLootTableId = customLootTableId; - } -} - -std::string CBotNpc::getUserModelId() -{ - return _UserModelId; -} - -std::string CBotNpc::getCustomLootTableId() -{ - return _CustomLootTableId; -} - -void CBotNpc::setPrimAlias(uint32 alias) -{ - _PrimAlias = alias; -} - - -uint32 CBotNpc::getPrimAlias() const -{ - return _PrimAlias; -} - - -void CBotNpc::fillDescriptionMsg(RYMSG::TGenNpcDescMsg& msg) const -{ - msg.setPlayerAttackable(grp().getPlayerAttackable()); - msg.setBotAttackable(grp().getBotAttackable()); - msg.setAlias(getAlias()); - msg.setGrpAlias(grp().getAlias()); - - msg.setSheet(getSheet()->SheetId()); - - msg.setRightHandItem(getSheet()->RightItem()); - msg.setRightHandItemQuality(1); - - msg.setLeftHandItem(getSheet()->LeftItem()); - msg.setLeftHandItemQuality(1); - - msg.setDontFollow(isStuck()); - msg.setBuildingBot(isBuildingBot()); - - for (size_t i=0; i<_LootList.size(); ++i) - { - NLMISC::CSheetId const& sheetRef = _LootList[i]; - if (sheetRef!=NLMISC::CSheetId::Unknown) - msg.getLootList().push_back(sheetRef); - } - - CGroupNpc::TFactionAttackableSet const& factionAttackableAbove = grp().getFactionAttackableAbove(); - FOREACHC(itFaction, CGroupNpc::TFactionAttackableSet, factionAttackableAbove) - msg.getOptionalProperties().push_back("FactionAttackableAbove:" + itFaction->first + ":" + NLMISC::toString(itFaction->second)); - CGroupNpc::TFactionAttackableSet const& factionAttackableBelow = grp().getFactionAttackableBelow(); - FOREACHC(itFaction, CGroupNpc::TFactionAttackableSet, factionAttackableBelow) - msg.getOptionalProperties().push_back("FactionAttackableBelow:" + itFaction->first + ":" + NLMISC::toString(itFaction->second)); - - msg.setMaxHitRangeForPC(_MaxHitRangeForPC); - -// msg.setIsMissionStepIconDisplayable(_MissionIconFlags.IsMissionStepIconDisplayable); -// msg.setIsMissionGiverIconDisplayable(_MissionIconFlags.IsMissionGiverIconDisplayable); - msg.setUserModelId(_UserModelId); - msg.setCustomLootTableId(_CustomLootTableId); - msg.setPrimAlias(_PrimAlias); -} - -// :KLUDGE: This methods is a part of the trick for bot respawn -// :TODO: Clean that mess -bool CBotNpc::finalizeSpawnNpc() -{ - // For squads, setup specific mirror properties - COutpost* ownerOutpost = dynamic_cast(getOwner()->getOwner()->getOwner()); - if (ownerOutpost) - { - // Propagate the alliance id and outpost alias to the instanciated bot - // Currently, all squads are assumed to be defender of the outpost (not attacker) - getSpawn()->setOutpostAlias(ownerOutpost->getAlias()); - getSpawn()->setOutpostSide(_OutpostSide); - } - - CMirrors::initSheetServer(getSpawn()->dataSetRow(), getSheet()->SheetId()); - - getSpawn()->setCurrentChatProfile(_ChatProfile); - getSpawn()->sendInfoToEGS(); - - if (_useVisualProperties) // use VisualPropertyA, B, C - { - sendVisualProperties(); - } - else // use alternate VPA - { - sendVPA (); - } - - getSpawn()->spawnGrp().botHaveSpawn(this); - - return true; -} - -void CBotNpc::initAdditionalMirrorValues() -{ - // Write the Mission Alias to mirror now - it must be done before CMirrors::declareEntity() - // to ensure the FS will receive the Sheet and it at the same time, hence it can't be - // done in finalizeSpawnNpc(), which is called after that - EGSPD::CPeople::TPeople race = getSheet()->Race(); - if (race < EGSPD::CPeople::Creature || - race == EGSPD::CPeople::Kami || - race == EGSPD::CPeople::Unknown) // only for humanoid NPCs and bot objects (beware, even some creatures have the entity type RYZOMID::npc) - { - //if ((_ChatProfile != NULL) && (!_ChatProfile->getMissions().empty())) // only if the bot has missions to give: not - CMirrors::initNPCAlias(getSpawn()->dataSetRow(), getAlias()); - } -} - -bool CBotNpc::spawn() -{ - if (!isSheetValid()) - { - nlwarning("spawn() Aborted for bot '%s' due to bad sheet", getFullName().c_str()); - return false; - } - - if (!CBot::spawn()) - return false; - - // :KLUDGE: Last part calls a tricky method also called by sheetChanged - // :TODO: Clean that mess - return finalizeSpawnNpc(); -} - -void CBotNpc::sendVPA() // alternate VPA -{ - SAltLookProp visProp; - // sets weapons information. - { - CVisualSlotManager* visualSlotManager = CVisualSlotManager::getInstance(); - NLMISC::CSheetId rightSheet = getSheet()->RightItem(); - NLMISC::CSheetId leftSheet = getSheet()->LeftItem(); - - visProp.Element.WeaponRightHand = visualSlotManager->rightItem2Index(rightSheet); - visProp.Element.WeaponLeftHand = visualSlotManager->leftItem2Index(leftSheet); - } - - // setting up the visual property A mirror record - visProp.Element.ColorTop = getSheet()->ColorBody(); - visProp.Element.ColorBot = getSheet()->ColorLegs(); - visProp.Element.ColorHair = getSheet()->ColorHead(); - visProp.Element.ColorGlove = getSheet()->ColorHands(); - visProp.Element.ColorBoot = getSheet()->ColorFeets(); - visProp.Element.ColorArm = getSheet()->ColorArms(); - visProp.Element.Hat = _Hat; - visProp.Element.Seed = getAlias()!=0?getAlias():(uint32)(size_t)(void*)this; - LOG("BOT: %s L: %d R: %u H: %u CHEAD: %u CARMS: %u CHANDS: %u CBODY: %u CLEGS: %u CFEETS: %u SEED: %u", - getName().c_str(), - visProp.Element.WeaponLeftHand, - visProp.Element.WeaponRightHand, - visProp.Element.Hat, - visProp.Element.ColorTop, - visProp.Element.ColorBot, - visProp.Element.ColorHair, - visProp.Element.ColorGlove, - visProp.Element.ColorBoot, - visProp.Element.ColorArm, - visProp.Element.Seed); - - CMirrors::setVPA(getSpawn()->dataSetRow(), visProp); -} - -void CBotNpc::sendVisualProperties() // VisualPropertyA, B, C -{ - if (getSpawn()) - { - CMirrors::setVisualPropertyA( getSpawn()->dataSetRow(), _VisualPropertyA ); - CMirrors::setVisualPropertyB( getSpawn()->dataSetRow(), _VisualPropertyB ); - CMirrors::setVisualPropertyC( getSpawn()->dataSetRow(), _VisualPropertyC ); - } -} - -bool CBotNpc::reSpawn(bool sendMessage) -{ - if (!spawn()) - return false; - - getSpawn()->updateChat(grp().getCAIState()); - return true; -} - -void CBotNpc::despawnBot() -{ - if (isSpawned()) - { - getSpawn()->spawnGrp().botHaveDespawn(this); - CBot::despawnBot(); - } -} - -void CBotNpc::equipmentInit() -{ - _Sheet->reset(); - _Hat = false; - _useVisualProperties = false; // default is to use alternate VPA - _VisualPropertyA = 0; - _VisualPropertyB = 0; - _VisualPropertyC = 0; - _FaunaBotUseBotName = false; -} - -void CBotNpc::equipmentAdd(std::string const& input) -{ - // if string is empty just return without making a fuss - if (input.empty()) - return; - - // split string into keyword and tail - std::string keyword, tail; - if (!AI_SHARE::stringToKeywordAndTail(input,keyword,tail)) - { - nlwarning("Bot '%s'%s: failed to parse equipment text: '%s'", - getAliasFullName().c_str(), - getAliasString().c_str(), - input.c_str()); - return; - } - - // do something depending on keyword - if (NLMISC::nlstricmp(keyword,"ri")==0) - { - if (tail.empty()) - { - nlwarning("No sheet name supplied for equipment slot 'ri': '%s'%s",getAliasFullName().c_str(),getAliasString().c_str()); - _Sheet->setRightItem(NLMISC::CSheetId::Unknown); - } - else if (NLMISC::nlstricmp(tail,"none")==0) - { - _Sheet->setRightItem(NLMISC::CSheetId::Unknown); - } - else - { - _Sheet->setRightItem(NLMISC::CSheetId(tail)); - } - } - else if (NLMISC::nlstricmp(keyword,"li")==0) - { - if (tail.empty()) - { - nlwarning("No sheet name supplied for equipment slot 'li': '%s'%s",getAliasFullName().c_str(),getAliasString().c_str()); - _Sheet->setLeftItem(NLMISC::CSheetId::Unknown); - } - else if (NLMISC::nlstricmp(tail,"none")==0) - { - _Sheet->setLeftItem(NLMISC::CSheetId::Unknown); - } - else - { - _Sheet->setLeftItem(NLMISC::CSheetId(tail)); - } - } - else if (NLMISC::nlstricmp(keyword,"HAT")==0 || NLMISC::nlstricmp(keyword,"IH")==0) - { - _Hat = true; - } - else if ( - NLMISC::nlstricmp(keyword,"UPPER" )==0 || NLMISC::nlstricmp(keyword,"CU")==0 || - NLMISC::nlstricmp(keyword,"LOWER" )==0 || NLMISC::nlstricmp(keyword,"CL")==0 || - NLMISC::nlstricmp(keyword,"HAIR" )==0 || NLMISC::nlstricmp(keyword,"CH")==0 || - NLMISC::nlstricmp(keyword,"CHEAD" )==0 || - NLMISC::nlstricmp(keyword,"CARMS" )==0 || - NLMISC::nlstricmp(keyword,"CHANDS")==0 || - NLMISC::nlstricmp(keyword,"CBODY" )==0 || - NLMISC::nlstricmp(keyword,"CLEGS" )==0 || - NLMISC::nlstricmp(keyword,"CFEETS")==0 - ) - { - setColours(input); - } - else if( - NLMISC::nlstricmp(keyword,"VPA")==0 || NLMISC::nlstricmp(keyword,"VPB")==0 || - NLMISC::nlstricmp(keyword,"VPC")==0 - ) - { - - setVisualProperties(input); - } - else if ( NLMISC::nlstricmp(keyword,"CLIENT_SHEET")==0 ) - { - setClientSheet(tail + ".creature"); - } - else if (NLMISC::nlstricmp(keyword,"loot")==0) - { - if (tail.empty()) - { - nlwarning("No sheet name supplied for loot list entry: '%s'%s",getAliasFullName().c_str(),getAliasString().c_str()); - } - else - { - _LootList.push_back(NLMISC::CSheetId(tail)); - } - } - else if (NLMISC::nlstricmp(keyword,"FAUNA_BOT_USE_BOTNAME")==0) - { - _FaunaBotUseBotName = true; - } - else if (NLMISC::nlstricmp(keyword, "USER_MODEL") == 0) - { - - uint32 primAlias = getAlias() >> LigoConfig.getDynamicAliasSize(); - nldebug("Parsing userModelId '%s' with primAlias: '%u'", tail.c_str(), primAlias); - setPrimAlias(primAlias); - setUserModelId(tail); - } - else if (NLMISC::nlstricmp(keyword, "CUSTOM_LOOT_TABLE") == 0) - { - uint32 primAlias = getAlias() >> LigoConfig.getDynamicAliasSize(); - nldebug("Parsing customLootTableId '%s' with primAlias: '%u'", tail.c_str(), primAlias); - setPrimAlias(primAlias); - setCustomLootTableId(tail); - } - else - { - nlwarning("Bot '%s'%s:failed to parse equipment argument: '%s'", - getAliasFullName().c_str(), - getAliasString().c_str(), - input.c_str()); - } -} - -/* -Colors are something like that: - 3D INTERFACE MP -0: ROUGE ROUGE RED -1: BEIGE ORANGE BEIGE -2: VERT CITRON VERT CITRON GREEN -3: VERT VERT TURQUOISE -4: BLEU BLEU BLUE -5: ROUGE dark ROUGE (normal) CRIMSON -6: BLANC JAUNE WHITE -7: NOIR BLEU very dark BLACK - -3D column is (probably) used for equipment -*/ -void CBotNpc::setColour(uint8 colour) -{ - _Sheet->setColorHead(colour); - _Sheet->setColorArms(colour); - _Sheet->setColorHands(colour); - _Sheet->setColorBody(colour); - _Sheet->setColorLegs(colour); - _Sheet->setColorFeets(colour); -} - -void CBotNpc::setColours(std::string input) -{ - // stuff for manageing colour names - int const numColours = 8; - static std::vector colourNames[numColours]; - static bool init = false; - - // if string is empty just return without making a fuss - if (input.empty()) - return; - - if (!init) - { - // lookup 'ColourNames' in config file (should be a multi-line field) - NLMISC::CConfigFile::CVar* varPtr = NLNET::IService::getInstance()->ConfigFile.getVarPtr(std::string("ColourNames")); - if (varPtr!=NULL) - { - // for each line in config file var try to add an alternative name for one of the colour slots - for (uint i=0; isize(); ++i) - { - // split line into name and idx (line example: 'red: 5') - std::string name, idxStr; - if (AI_SHARE::stringToKeywordAndTail(varPtr->asString(i),name,idxStr)) - { - // split succeeded so verify that idxStr contains anumber in range 0..7 and add - // the name to the list of valid names for the given slot - uint32 idx; - NLMISC::fromString(idxStr, idx); - if (NLMISC::toString(idx)==idxStr && idxfullName().c_str()); - return; - } - - // do something depending on keyword - if (NLMISC::nlstricmp(keyword,"UPPER" )==0 || NLMISC::nlstricmp(keyword,"CU")==0 || - NLMISC::nlstricmp(keyword,"LOWER" )==0 || NLMISC::nlstricmp(keyword,"CL")==0 || - NLMISC::nlstricmp(keyword,"HAIR" )==0 || NLMISC::nlstricmp(keyword,"CH")==0 || - NLMISC::nlstricmp(keyword,"CHEAD" )==0 || - NLMISC::nlstricmp(keyword,"CARMS" )==0 || - NLMISC::nlstricmp(keyword,"CHANDS")==0 || - NLMISC::nlstricmp(keyword,"CBODY" )==0 || - NLMISC::nlstricmp(keyword,"CLEGS" )==0 || - NLMISC::nlstricmp(keyword,"CFEETS")==0 - ) - { - std::vector results; - std::string colour; - while (!tail.empty()) - { - // extract the next word from the tail - AI_SHARE::stringToWordAndTail(tail,colour,tail); - // if the colour string is a number then treat it directly - uint32 idx; - NLMISC::fromString(colour, idx); - if (NLMISC::toString(idx)==colour) - { - // we've got a number so make sue it's in valid range and add to results vector - if (idxsetColorArms(val); - _Sheet->setColorHands(val); - _Sheet->setColorBody(val); - } - else if ( NLMISC::nlstricmp(keyword,"LOWER")==0 || NLMISC::nlstricmp(keyword,"CL")==0 ) - { - // lower body colour - generator.srand(seed+977*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorLegs(val); - _Sheet->setColorFeets(val); - } - else if ( NLMISC::nlstricmp(keyword,"HAIR")==0 || NLMISC::nlstricmp(keyword,"CH")==0 ) - { - // hair colour, mapped to head - generator.srand(seed+976*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorHead(val); - } - else if ( NLMISC::nlstricmp(keyword,"CHEAD")==0) - { - // head color - generator.srand(seed+979*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorHead(val); - } - else if ( NLMISC::nlstricmp(keyword,"CARMS")==0) - { - // arms color - generator.srand(seed+981*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorArms(val); - } - else if ( NLMISC::nlstricmp(keyword,"CHANDS")==0) - { - // arms color - generator.srand(seed+983*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorHands(val); - } - else if ( NLMISC::nlstricmp(keyword,"CBODY")==0) - { - // arms color - generator.srand(seed+985*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorBody(val); - } - else if ( NLMISC::nlstricmp(keyword,"CLEGS")==0) - { - // arms color - generator.srand(seed+987*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorLegs(val); - } - else if ( NLMISC::nlstricmp(keyword,"CFEETS")==0) - { - // arms color - generator.srand(seed+989*0x10000); - uint8 val = (uint8)results[generator.rand((uint16)results.size()-1)]; - _Sheet->setColorFeets(val); - } - } - else - { - nlwarning("Bot '%s'%s: failed to parse colours argument: '%s'", - getAliasFullName().c_str(), - getAliasString().c_str(), - input.c_str()); - } -} - - - -void CBotNpc::setVisualProperties(std::string input) // AJM -{ - // set the VisualPropertyA, VisualPropertyB, VisualPropertyC bitfield values - // using a hexadecimal entry format - - // if string is empty just return without making a fuss - if(input.empty()) - return; - - // split 'input' string into keyword and tail - std::string keyword, tail; - if(!AI_SHARE::stringToKeywordAndTail(input,keyword,tail)) - { - nlwarning("Failed to parse visual property text: '%s' for bot: '%s'",input.c_str(),getAliasNode()->fullName().c_str()); - return; - } - - // load val from tail - // accept 64bit hex value - uint64 val; - sscanf( tail.c_str(), "%" NL_I64 "x", &val ); - - // can't set into mirror row until bot is spawned, so save away - if( NLMISC::nlstricmp( keyword,"VPA")==0 ) // VisualPropertyA - { - _VisualPropertyA = val; - _useVisualProperties = true; - } - else if( NLMISC::nlstricmp( keyword,"VPB")==0 ) // VisualPropertyB - { - _VisualPropertyB = val; - _useVisualProperties = true; - } - else if( NLMISC::nlstricmp( keyword,"VPC")==0 ) // VisualPropertyC - { - _VisualPropertyC = val; - _useVisualProperties = true; - } - - else - { - nlwarning("Bot '%s'%s: failed to parse visual property argument: '%s'", - getAliasFullName().c_str(), - getAliasString().c_str(), - input.c_str()); - } -} - -void CBotNpc::setStartPos(double x, double y, float theta, AITYPES::TVerticalPos verticalPos) -{ - _StartPos = CAIPos(x, y, 0, theta); - _VerticalPos = verticalPos; -} - -void CBotNpc::init() -{ - _ChatProfile = NULL; - _MaxHitRangeForPC = -1.0f; -// _MissionIconFlags.IsMissionStepIconDisplayable = true; -// _MissionIconFlags.IsMissionGiverIconDisplayable = true; - - equipmentInit(); -} - -CSpawnBotNpc* CBotNpc::getSpawn() -{ - return static_cast(getSpawnObj()); -} - -CSpawnBotNpc const* CBotNpc::getSpawn() const -{ - return static_cast(getSpawnObj()); -} - -void CBotNpc::getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta) -{ - if (_StartPos.isNull()) - calcSpawnPos(worldMap); - - if (isStuck() || IsRingShard) - worldMap.setWorldPosition(_VerticalPos, pos, _StartPos); - else - CWorldContainer::calcNearestWPosFromPosAnRadius(_VerticalPos, worldMap, pos, _StartPos, 10, 200, CWorldContainer::CPosValidatorDefault()); - -#ifdef NL_DEBUG - if (!pos.isValid() && !isStuck()) - { - nlwarning("Npc Spawn Pos Error %s", pos.toString().c_str()); - } -#endif - - spawnTheta = _StartPos.theta(); - triedPos = _StartPos; -} - -CSpawnBot* CBotNpc::getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius) -{ - return new CSpawnBotNpc(row, *this, id, radius, getSheet()->Level(), getGroup().getAStarFlag()); -} - -void CBotNpc::newChat() -{ - _ChatProfile = new CNpcChatProfileImp(); -} - -CAIS::CCounter& CBotNpc::getSpawnCounter() -{ - return CAIS::instance()._NpcBotCounter; -} - -void CBotNpc::setSheet(AISHEETS::ICreatureCPtr const& sheet) -{ - _Sheet->setSheet(sheet); - sheetChanged(); -} - -// :KLUDGE: This method is very tricky. It's a copy'n'paste of the method in CBot (BAD!) with more content -// :TODO: Clean that mess -void CBotNpc::sheetChanged() -{ - if (getSpawnObj()) - { - // Get bot state - RYAI_MAP_CRUNCH::CWorldPosition botWPos = getSpawnObj()->wpos(); - CAngle spawnTheta = getSpawnObj()->theta(); - float botMeterSize = getSheet()->Scale()*getSheet()->Radius(); - // :TODO: Save profile info - - // If stuck bot position may be outside collision and must be recomputed - if (isStuck() || IsRingShard) - getSpawnPos(lastTriedPos, botWPos, CWorldContainer::getWorldMap(), spawnTheta); - - // Delete old bot - CMirrors::removeEntity(getSpawnObj()->getEntityId()); - setSpawn(NULL); // automatic smart pointer deletion - notifyBotDespawn(); - - // Finalize spawn object creation - if (!finalizeSpawn(botWPos, spawnTheta, botMeterSize)) - return; - - // :KLUDGE: Both finalizeSpawn and finalizeSpawnNpc are called, - // sheetChanged has a strange herited meaning and may confuse future - // coders - // :TODO: Clean that mess and find a more elegant C++ solution to the - // problem - finalizeSpawnNpc(); - } -} - -////////////////////////////////////////////////////////////////////////////// -// Commmands // -////////////////////////////////////////////////////////////////////////////// - -// Control over verbose nature of logging -NLMISC_COMMAND(verboseNPCBotProfiles, "Turn on or off or check the state of verbose bot profile change logging","") -{ - if (args.size()>1) - return false; - - if (args.size()==1) - NLMISC::fromString(args[0], VerboseLog); - - nlinfo("VerboseLogging is %s",VerboseLog?"ON":"OFF"); - return true; -} -// virtual function so do not need to be inlined -bool CBotNpc::getFaunaBotUseBotName() const -{ - return _FaunaBotUseBotName; -} - diff --git a/code/ryzom/server/src/ai_service/ai_bot_npc.h b/code/ryzom/server/src/ai_service/ai_bot_npc.h deleted file mode 100644 index 3455e7f58..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_npc.h +++ /dev/null @@ -1,366 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_BOT_NPC_H -#define RYAI_BOT_NPC_H - -#include "game_share/msg_ais_egs_gen.h" -#include "ai_bot.h" -#include "owners.h" -#include "npc_description_msg.h" -#include "states.h" -#include "ai_player.h" - -class CBotNpc; -class CNpc; -class CSpawnGroupNpc; -class CBotPlayer; -class CPlayerControlNpc; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotNpc // -////////////////////////////////////////////////////////////////////////////// - -class CSpawnBotNpc -: public NLMISC::CDbgRefCount -, public CSpawnBot -, public CPetOwner -{ -public: - CSpawnBotNpc(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - - void update(uint32 ticks); - - CSpawnGroupNpc& spawnGrp() const; - - // Accessors for NPC dynamic parameters ----------------------------- - void setCurrentChatProfile(CNpcChatProfileImp* chatProfile); - - void updateChat(CAIState const* state); - - virtual void processEvent(CCombatInterface::CEvent const& event); - - CAIEntityPhysical& getPhysical() { return *this; } - - /// @name Chat parameter management - //@{ - void beginBotChat(CBotPlayer* plr); - void endBotChat(CBotPlayer* plr); - void beginDynChat() { ++_NbCurrentDynChats; } - void endDynChat() { --_NbCurrentDynChats; } - //@} - - // Return the active bot chats - std::vector& getActiveChats() { return _ActiveChats; } - - // Return the number of dyn chats (these chats are not managed by the AIS) - uint getNbActiveDynChats() { return _NbCurrentDynChats; } - - /// Dispatching message to EGS to describe chat possibilities - void sendInfoToEGS() const; - - virtual std::vector getMultiLineInfoString() const; - - CBotNpc& getPersistent() const; - - virtual RYZOMID::TTypeId getRyzomType() const { return RYZOMID::npc; } - - virtual bool isBotAttackable() const; - - virtual void propagateAggro() const; - - float getReturnDistCheck() const; - - void setPlayerController(CBotPlayer* player); - - void setFacing(CAngle theta); - - void setUserModelId(const std::string &id); - - std::string getUserModelId(); - - void setCustomLootTableId(const std::string &id); - - std::string getCustomLootTableId(); - - void setPrimAlias(uint32 alias); - uint32 getPrimAlias() const; - -private: - std::vector _ActiveChats; // vector of ptrs to players currently chatting with bot - float _OldHpPercentage; // Fix for HP triggers - - CNpcChatProfileImp _CurrentChatProfile; - sint32 _NbCurrentDynChats; - NLMISC::CSmartPtr _PlayerController; - uint32 _FacingTick; - CAngle _FacingTheta; - - std::string _UserModelId; - std::string _CustomLootTableId; - uint32 _PrimAlias; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotNpcSheet // -////////////////////////////////////////////////////////////////////////////// - -class CBotNpcSheet -: public AISHEETS::CCreatureProxy -{ -public: - CBotNpcSheet(AISHEETS::ICreatureCPtr const& sheet) - : AISHEETS::CCreatureProxy(sheet) - , _LeftItem(NLMISC::CSheetId::Unknown) - , _RightItem(NLMISC::CSheetId::Unknown) - , _ColorHead(0) - , _ColorArms(0) - , _ColorHands(0) - , _ColorBody(0) - , _ColorLegs(0) - , _ColorFeets(0) - { - reset(); - } - - ///@name ICreature overloads - //@{ - virtual uint8 ColorHead() const { return _ColorHead; } - virtual uint8 ColorArms() const { return _ColorArms; } - virtual uint8 ColorHands() const { return _ColorHands; } - virtual uint8 ColorBody() const { return _ColorBody; } - virtual uint8 ColorLegs() const { return _ColorLegs; } - virtual uint8 ColorFeets() const { return _ColorFeets; } - - virtual NLMISC::CSheetId const& LeftItem() const - { - if (_LeftItem!=NLMISC::CSheetId::Unknown) - return _LeftItem; - else - return this->CCreatureProxy::LeftItem(); - } - virtual NLMISC::CSheetId const& RightItem() const - { - if (_RightItem!=NLMISC::CSheetId::Unknown) - return _RightItem; - else - return this->CCreatureProxy::RightItem(); - } - //@} - - ///@name Setters - //@{ - void setColorHead(uint8 val) { _ColorHead = val; } - void setColorArms(uint8 val) { _ColorArms = val; } - void setColorHands(uint8 val) { _ColorHands = val; } - void setColorBody(uint8 val) { _ColorBody = val; } - void setColorLegs(uint8 val) { _ColorLegs = val; } - void setColorFeets(uint8 val) { _ColorFeets = val; } - - void setLeftItem(NLMISC::CSheetId const& val) { _LeftItem = val; } - void setRightItem(NLMISC::CSheetId const& val) { _RightItem = val; } - //@} - - void reset() - { - if (_Sheet) - { - _LeftItem = _Sheet->LeftItem(); - _RightItem = _Sheet->RightItem(); - _ColorHead = _Sheet->ColorHead(); - _ColorArms = _Sheet->ColorArms(); - _ColorHands = _Sheet->ColorHands(); - _ColorBody = _Sheet->ColorBody(); - _ColorLegs = _Sheet->ColorLegs(); - _ColorFeets = _Sheet->ColorFeets(); - } - } - -private: - NLMISC::CSheetId _LeftItem; - NLMISC::CSheetId _RightItem; - uint8 _ColorHead; - uint8 _ColorArms; - uint8 _ColorHands; - uint8 _ColorBody; - uint8 _ColorLegs; - uint8 _ColorFeets; -}; -typedef NLMISC::CSmartPtr CBotNpcSheetPtr; -typedef NLMISC::CSmartPtr CBotNpcSheetCPtr; - -////////////////////////////////////////////////////////////////////////////// -// CBotNpc // -////////////////////////////////////////////////////////////////////////////// - -class CBotNpc -: public CBot -, public CKeyWordOwner -{ -public: - friend class CSpawnBotNpc; // allows CSpawnBotNpc to acceed his definition. - -public: - CBotNpc(CGroup* owner, CAIAliasDescriptionNode* alias = NULL); - CBotNpc(CGroup* owner, uint32 alias, std::string const& name); - virtual ~CBotNpc(); - - void init(); - - RYZOMID::TTypeId getRyzomType() const { return RYZOMID::npc; } - - CSpawnBotNpc* getSpawn(); - CSpawnBotNpc const* getSpawn() const; - - CAIS::CCounter& getSpawnCounter(); - - void calcSpawnPos(RYAI_MAP_CRUNCH::CWorldMap const& worldMap); - - void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& pos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta); - - CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius); - - // spawn & despawn -------------------------------------------------- - virtual bool spawn(); - virtual void despawnBot(); - - bool reSpawn(bool sendMessage = true); - - //------------------------------------------------------------ - // accessing the parent mgr, group, etc - CGroupNpc& grp() const; - - // Carried equipment management ------------------------------------- - void equipmentInit(); - void equipmentAdd(std::string const& kit); - - // Write accessors for NPC base parameters -------------------------- - void setStartPos(double x, double y, float theta, AITYPES::TVerticalPos verticalPos); - - void setColour(uint8 colour); - void setColours(std::string colours); - - void setVisualProperties(std::string input); - - inline void setMaxHitRangeForPlayer(float maxHitRange) { _MaxHitRangeForPC = maxHitRange; } -// void setMissionStepIconHidden(bool hide) { _MissionIconFlags.IsMissionStepIconDisplayable = !hide; } -// void setMissionGiverIconHidden(bool hide) { _MissionIconFlags.IsMissionGiverIconDisplayable = !hide; } - - // Read accessors for NPC base parameters --------------------------- - NLMISC::CSheetId getStats() const { return getSheet()->SheetId(); } - CAIPos const& getStartPos() const { return _StartPos; } - AITYPES::TVerticalPos getStartVerticalPos() const { return _VerticalPos; } - - // Callback called on state change of parent group (including changes to/from punctual states) - - // the update routine (delegates control to the _aiProfile object) -- - // void update(uint32 ticks); - - // do nothing for 'ticks' ticks - // return number of ticks of movement time left after destination reached (or 0) - - - void sendVPA(); - void sendVisualProperties(); - - void newChat(); - - NLMISC::CSmartPtr const& getChat() const { return _ChatProfile; } - void setUserModelId(const std::string &userModelId); - std::string getUserModelId(); - - void setCustomLootTableId(const std::string &customLootTableId); - std::string getCustomLootTableId(); - - void setPrimAlias(uint32 alias); - uint32 getPrimAlias() const; - -// void fillDescriptionMsg(CNpcBotDescriptionImp& msg) const; - void fillDescriptionMsg(RYMSG::TGenNpcDescMsg& msg) const; - - - virtual std::string getOneLineInfoString() const { return std::string("NPC bot '") + getName() + "'"; } - - virtual AISHEETS::ICreatureCPtr getSheet() const { return _Sheet.getPtr(); } - - virtual void setSheet(AISHEETS::ICreatureCPtr const& sheet); - - virtual bool isSheetValid() const - { - return _Sheet!=NULL && _Sheet->isValid(); - } - - void setOutpostSide(OUTPOSTENUMS::TPVPSide side) { _OutpostSide = side; } - - virtual bool getFaunaBotUseBotName() const; - -protected: - virtual void sheetChanged(); - bool finalizeSpawnNpc(); - virtual void initAdditionalMirrorValues(); - -protected: - // stuff supplied by CAIBot ------------------ - // sheet (.creature) for game parameters - // position & orientation - // mode and behaviour - - // A static bot object with a fauna sheet must not display SheetName but botobject name - bool _FaunaBotUseBotName; - -// struct -// { -// /// Allows to hide icons for current missions steps having interactions with this NPC -// bool IsMissionStepIconDisplayable : 1; -// -// /// Allows to hide icons for missions proposed by this NPC -// bool IsMissionGiverIconDisplayable : 1; -// } _MissionIconFlags; - - // look parameters --------------------------- - bool _Hat; - - bool _useVisualProperties; // true => use VisualPropertyA, B, C instead of alternate VPA - uint64 _VisualPropertyA; - uint64 _VisualPropertyB; - uint64 _VisualPropertyC; - - CBotNpcSheetPtr _Sheet; - - - // spawn place ------------------------------- - CAIPos _StartPos; - - std::vector _LootList; - - // static chat parameters -------------------- - NLMISC::CSmartPtr _ChatProfile; - - // Outpost side - OUTPOSTENUMS::TPVPSide _OutpostSide; - - // Max range a PC can hit this bot - float _MaxHitRangeForPC; - - //userModelId used for this bot - std::string _UserModelId; - - std::string _CustomLootTableId; - - uint32 _PrimAlias; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_bot_pet.cpp b/code/ryzom/server/src/ai_service/ai_bot_pet.cpp deleted file mode 100644 index 1c2a79ee1..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_pet.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_bot_pet.h" -#include "visual_properties_interface.h" - -#include "nel/misc/random.h" -#include "ai_grp_pet.h" -#include "owners.h" - -using namespace NLMISC; -using namespace std; -using namespace RYAI_MAP_CRUNCH; - -////////////////////////////////////////////////////////////////////////////// -// CBotPet // -////////////////////////////////////////////////////////////////////////////// - -void CBotPet::getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& spawnPos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta) -{ - // return can be false. - worldMap.setWorldPosition(_SpawnPos.h(), spawnPos, _SpawnPos); - spawnTheta = _SpawnPos.theta(); - triedPos = _SpawnPos; -} - -CGrpPet& CBotPet::getPetGroup() -{ - return *static_cast(getOwner()); -} - -void CBotPet::update(uint32 ticks, CAIEntityPhysical const* petOwner) -{ - CSpawnBotPet* const spawnPet = getSpawn(); - if (spawnPet) - { - if (spawnPet->isAlive()) - { - if (spawnPet->isMounted()) - spawnPet->updatePos(); // take position from GPMS - else - spawnPet->updateProfile(ticks); // update pathfinding profile - } - } -} - -void CBotPet::triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet) -{ - nlwarning("Changing the sheet of a pet bot is not currently possible"); // The guy that wrote that is a lazy bastard... -} - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotPet // -////////////////////////////////////////////////////////////////////////////// - -/// Return true if the animal is mounted (thus controlled by the GPMS) -bool CSpawnBotPet::isMounted() const -{ - // Do not control a pet when in mount mode (controlled by the GPMS) - CMirrorPropValueRO currentMode( TheDataset, dataSetRow(), DSPropertyMODE ); - return currentMode().isMountMode(); -} - -/// Take position from mirror -void CSpawnBotPet::updatePos() -{ - RYAI_MAP_CRUNCH::CWorldPosition wpos; - if (!CWorldContainer::getWorldMap().setWorldPosition(pos().h(), wpos, CAIVector(pos()))) - return; - setWPos(wpos); - - if (wpos.getFlags() & RYAI_MAP_CRUNCH::Water) - setActionFlags(RYZOMACTIONFLAGS::InWater); - else - removeActionFlags(RYZOMACTIONFLAGS::InWater); -} - -CSpawnGroupPet& CSpawnBotPet::spawnGrp() -{ - return static_cast(CSpawnBot::spawnGrp()); -} - -void CSpawnBotPet::setVisualPropertiesName() -{ - CBotPet& botRef = CSpawnBotPet::getPersistent(); - ucstring name = botRef.getName(); - - if (CVisualPropertiesInterface::UseIdForName) - { - name = NLMISC::toString("AI:%s", botRef.getIndexString().c_str()); - } - - if (name.empty() && CVisualPropertiesInterface::ForceNames) - { - name = NLMISC::CFile::getFilenameWithoutExtension(botRef.getSheet()->SheetId().toString().c_str()); - } - - if (!botRef.getCustomName().empty()) - name = botRef.getCustomName(); - - // no name the bot will appear without name on the client. - if (name.empty()) - return; - - CVisualPropertiesInterface::setName(dataSetRow(), name); -} diff --git a/code/ryzom/server/src/ai_service/ai_bot_pet.h b/code/ryzom/server/src/ai_service/ai_bot_pet.h deleted file mode 100644 index 67252b10c..000000000 --- a/code/ryzom/server/src/ai_service/ai_bot_pet.h +++ /dev/null @@ -1,172 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifdef NL_OS_WINDOWS -#pragma warning (disable : 4355) // warning C4355: 'this' : used in base member initializer list -#endif // NL_OS_WINDOWS - -#ifndef RYAI_BOT_PET_H -#define RYAI_BOT_PET_H - -#include "ai_bot.h" -#include "path_behaviors.h" - -class CBotPet; -class CGrpPet; -class CPetOwner; - -class IAIBotCAIProfile; -class CSpawnGroupPet; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotPet // -////////////////////////////////////////////////////////////////////////////// - -class CSpawnBotPet -: public NLMISC::CDbgRefCount -, public CSpawnBot -{ -public: - CSpawnBotPet(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - - void processEvent(CCombatInterface::CEvent const& event) { } - - RYZOMID::TTypeId getRyzomType() const { return RYZOMID::pack_animal; } - - CBotPet& getPersistent (); - CBotPet const& getPersistent() const; - - CSpawnGroupPet& spawnGrp(); - - void sendInfoToEGS() const { } - - // pets are always attackable by bots - virtual bool isBotAttackable() const { return true; } - - // Take position from mirror - void updatePos(); - - // Return true if the animal is mounted (thus controlled by the GPMS) - bool isMounted() const; - - CPathPosition& pathPos() { return _PathPos; } - - uint32 _DeathTime; - - void setVisualPropertiesName(); - -private: - - CPathPosition _PathPos; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotPet // -////////////////////////////////////////////////////////////////////////////// - -class CBotPet -: public CBot -{ -public: - CBotPet(CGroup* owner, CAIAliasDescriptionNode* alias = NULL); - ~CBotPet(); - - void getSpawnPos(CAIVector& triedPos, RYAI_MAP_CRUNCH::CWorldPosition& spawnPos, RYAI_MAP_CRUNCH::CWorldMap const& worldMap, CAngle& spawnTheta); - void setSpawnPos(CAIPos const& spawnPos) { _SpawnPos = spawnPos; } - CGrpPet& getPetGroup(); - - void update(uint32 ticks, CAIEntityPhysical const* petOwner); - - CSpawnBotPet* getSpawn() { return static_cast(getSpawnObj()); } - - CAIS::CCounter& getSpawnCounter(); - - void setDespawn() { _MustDespawn = true; } - bool haveToDespawn() const { return _MustDespawn; } - - void changeOwner(NLMISC::CEntityId const& newOwner); - - virtual std::string getOneLineInfoString() const { return std::string("Pet bot '") + getName() + "'"; } - - virtual void triggerSetSheet(AISHEETS::ICreatureCPtr const& sheet); - -protected: - RYZOMID::TTypeId getRyzomType() const { return RYZOMID::pack_animal; } - - CSpawnBot* getSpawnBot(TDataSetRow const& row, NLMISC::CEntityId const& id, float radius) - { - return new CSpawnBotPet(row, *this, id, radius, getSheet()->Level(), getGroup().getAStarFlag()); - } - -private: - CAIPos _SpawnPos; - bool _MustDespawn; -}; - -/****************************************************************************/ -/* Inlined methods */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotPet // -////////////////////////////////////////////////////////////////////////////// - -inline -CSpawnBotPet::CSpawnBotPet(TDataSetRow const& row, CBot& owner, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CSpawnBot(row, owner, id, radius, level, denyFlags) -, _DeathTime(0) -, _PathPos(CAngle()) -{ -} - -inline -CBotPet& CSpawnBotPet::getPersistent() -{ - return static_cast(CSpawnBot::getPersistent()); -} - -inline -CBotPet const& CSpawnBotPet::getPersistent() const -{ - return static_cast(CSpawnBot::getPersistent()); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotPet // -////////////////////////////////////////////////////////////////////////////// - -inline -CBotPet::CBotPet(CGroup* owner, CAIAliasDescriptionNode* alias) -: CBot(owner, alias) -, _MustDespawn(false) -{ -} - -inline -CBotPet::~CBotPet() -{ - if (!isSpawned()) - return; - despawnBot(); -} - -inline -CAIS::CCounter& CBotPet::getSpawnCounter() -{ - return CAIS::instance()._PetBotCounter; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_continent.h b/code/ryzom/server/src/ai_service/ai_continent.h deleted file mode 100644 index d6eb9335d..000000000 --- a/code/ryzom/server/src/ai_service/ai_continent.h +++ /dev/null @@ -1,45 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -class CAIContinent; - -#ifndef RYAI_CONTINENT_H -#define RYAI_CONTINENT_H - -#include "nel/misc/types_nl.h" -#include "ai_route.h" - -/* - This class implements the data set and related methods for a continent. - Continent data includes collision maps and so on. -*/ - - -class CAIContinent -{ -public: - // classic init(), update() and release() - static void init() {} - static void update() {} - static void release() {} - - // the name of the continent - std::string Name; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_control_npc.cpp b/code/ryzom/server/src/ai_service/ai_control_npc.cpp deleted file mode 100644 index e46349f82..000000000 --- a/code/ryzom/server/src/ai_service/ai_control_npc.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "game_share/mode_and_behaviour.h" -#include "ai_control_npc.h" -#include "ai_bot_npc.h" -#include "ai_player.h" -#include "ai_profile_npc.h" -#include "ais_control.h" -using namespace std; - -////////////////////////////////////////////////////////////////////////////// -// CPlayerControlNpc // -////////////////////////////////////////////////////////////////////////////// - -CPlayerControlNpc::CPlayerControlNpc(CBotPlayer* player, CSpawnBotNpc* bot) -{ - _Player = player; - _Bot = bot; - _LastPathUpdate = 0; - _CPlayerEntityId = player->getEntityId(); - _CNpcEntityId = bot->getEntityId(); - IAisControl::getInstance()->reportNpcControl(_CPlayerEntityId, _CNpcEntityId); -} - -CPlayerControlNpc::~CPlayerControlNpc() -{ - IAisControl::getInstance()->reportStopNpcControl(_CPlayerEntityId, _CNpcEntityId); -} - -bool CPlayerControlNpc::isValid() const -{ - if (_Player == NULL) - return false; - - if (_Bot == NULL) - return false; - - return true; -} - -void CPlayerControlNpc::updateControl(uint ticks) -{ - nlassert(isValid()); - -// static double baseDist = 1.0; -// const double wantedDist = baseDist + _Bot->radius() + _Player->radius(); - const AITYPES::TVerticalPos vertPos = AITYPES::vp_auto; - - RYAI_MAP_CRUNCH::CMapPosition mapPos(CAIVector(_Player->pos())); - RYAI_MAP_CRUNCH::CWorldPosition wantedWPos( mapPos.x(), mapPos.y()); - - //const RYAI_MAP_CRUNCH::CWorldPosition wantedWPos = _Player->wpos(); - - // :BUG: _Player->wpos().x() == 0 && _Player->wpos().x() == 0 where colision are wrong (like prime roots) - if (wantedWPos.x() == 0 && wantedWPos.y()==0) - { - _Player = NULL; - _Bot = NULL; - return; - } - -// CBotProfileMoveTo* moveToProfile = dynamic_cast(_ControlProfileManager.getAIProfile()); -// -// // do not path finding more than once per second -// const uint32 currentTime = CTimeInterface::gameCycle(); -// const uint32 dt = currentTime - _LastPathUpdate; -// if ( moveToProfile == NULL -// || dt >= 10) -// { -// moveToProfile = new CBotProfileMoveTo(vertPos, wantedWPos, _Bot); -// _ControlProfileManager.setAIProfile(moveToProfile); -// _LastPathUpdate = currentTime; -// } -// -// breakable -// { -// if (!moveToProfile->destinationReach()) -// { -// const double dist = _Bot->pos().quickDistTo( wantedWPos.toAIVector() ); -// if (dist > wantedDist) -// { -// _ControlProfileManager.updateProfile(ticks); -// break; -// } -// } - - _Bot->setPos(_Player->pos()); - _Bot->setTheta(_Player->theta()); - _Bot->setMode(_Player->getMode()); - CMirrorPropValueRO playerBehaviour( TheDataset, _Player->dataSetRow(), DSPropertyBEHAVIOUR ); - CMirrorPropValue npcBehaviour( TheDataset, _Bot->dataSetRow(), DSPropertyBEHAVIOUR ); - npcBehaviour = playerBehaviour.getValue(); -// } -} - - -CSpawnBotNpc* CPlayerControlNpc::getSpawnBot() const -{ - return _Bot; -} diff --git a/code/ryzom/server/src/ai_service/ai_control_npc.h b/code/ryzom/server/src/ai_service/ai_control_npc.h deleted file mode 100644 index cac88a679..000000000 --- a/code/ryzom/server/src/ai_service/ai_control_npc.h +++ /dev/null @@ -1,57 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_CONTROL_NPC_H -#define RYAI_CONTROL_NPC_H - -#include "profile.h" - -class CBotPlayer; -class CSpawnBotNpc; - -////////////////////////////////////////////////////////////////////////////// -// CPlayerControlNpc // -////////////////////////////////////////////////////////////////////////////// - -class CPlayerControlNpc : public NLMISC::CRefCount -{ -public: - /// ctor - /// \param player : the player which controls the bot - /// \param bot : the npc which is controlled by the player - CPlayerControlNpc(CBotPlayer* player, CSpawnBotNpc* bot); - ~CPlayerControlNpc(); - - /// check if the object is valid - /// WARNING: you cannot call any other method if this returns false - bool isValid() const; - - /// update the control on the npc - void updateControl(uint ticks); - CSpawnBotNpc* getSpawnBot() const; - -private: - /// the player controlling the bot - NLMISC::CRefPtr _Player; - CSpawnBotNpc* _Bot; - CProfilePtr _ControlProfileManager; - uint32 _LastPathUpdate; - NLMISC::CEntityId _CPlayerEntityId; - NLMISC::CEntityId _CNpcEntityId; - -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_entity.h b/code/ryzom/server/src/ai_service/ai_entity.h deleted file mode 100644 index 0d7e84fec..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity.h +++ /dev/null @@ -1,81 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_ENTITY_H -#define RYAI_ENTITY_H - -#include -#include - -//-------------------------------------------------------------------------- -// The CAIEntiy class -//-------------------------------------------------------------------------- -class CAIEntity; -class CAIInstance; - -extern void removeFromWatch(CAIEntity* entity); - -class CAIEntity -{ -public: - /// @name Destructor - //@{ - virtual ~CAIEntity(); - //@} - - /// @name Virtual interface - //@{ - virtual CAIInstance* getAIInstance() const = 0; - // display verbose status information regarding the entity -// virtual void display(CStringWriter& stringWriter) const; -// virtual std::string getIndexString() const = 0; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - //@} - -public: - /// @name Debug info display methods - //@{ - // public interface for the 'buildDebugString' virtual - // method set - it is safe, returning cleanly if called on a NULL pointer -// std::string debugString(uint idx = 0) const; - //@} -}; - -inline -CAIEntity::~CAIEntity() -{ - removeFromWatch(this); -} - -inline -std::string CAIEntity::getOneLineInfoString() const -{ - return std::string(""); -} - -inline -std::vector CAIEntity::getMultiLineInfoString() const -{ - std::vector container; - MULTI_LINE_FORMATER::pushTitle(container, "CAIEntity"); - MULTI_LINE_FORMATER::pushEntry(container, ""); - MULTI_LINE_FORMATER::pushEntry(container, getOneLineInfoString()); - MULTI_LINE_FORMATER::pushFooter(container); - return container; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_entity_id.cpp b/code/ryzom/server/src/ai_service/ai_entity_id.cpp deleted file mode 100644 index fd106a818..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_id.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -/* -#include "stdpch.h" - - -//-------------------------------------------------------------------------- -// CAIEntityId creation from string methods -//-------------------------------------------------------------------------- - -CAIEntityId CAIEntityId::entityId(const std::string &name) -{ - CAIEntityId eid; - - eid = CAIEntityId::mgrId(name); - if (!eid.isInvalid()) - return (eid); - - eid = CAIEntityId::grpId(name); - if (!eid.isInvalid()) - return (eid); - - eid = CAIEntityId::botId(name); - if (!eid.isInvalid()) - return (eid); - - return CAIEntityId(); -} - -CAIEntityId CAIEntityId::botId(const std::string &name) -{ - CAIEntityId id; - - // see if we have a CAIEntityId.toString() - id=CAIEntityId(name); - if (id.isBot() && id.exists()) - return id; - - // see if we have a NLMISC::CEntityId.toStirng() - if (name[0]=='(') - { - id=CAIEntityId(NLMISC::CEntityId(name.c_str())); - if (id.isBot() && id.exists()) - return id; - } - - // see if we have a bot number, group number and manager number - uint mgridx, grpidx, botidx; - char s[30]; - - sscanf(name.c_str(),"%i:%i:%i",&mgridx,&grpidx,&botidx); - sprintf(s,"%i:%i:%i",mgridx,grpidx,botidx); - if (name==std::string(s)) - return CAIEntityId::botId(mgridx,grpidx,botidx); - - sscanf(name.c_str(),"%i,%i,%i",&mgridx,&grpidx,&botidx); - sprintf(s,"%i,%i,%i",mgridx,grpidx,botidx); - if (name==std::string(s)) - return CAIEntityId::botId(mgridx,grpidx,botidx); - - sscanf(name.c_str(),"%i.%i.%i",&mgridx,&grpidx,&botidx); - sprintf(s,"%i.%i.%i",mgridx,grpidx,botidx); - if (name==std::string(s)) - return CAIEntityId::botId(mgridx,grpidx,botidx); - - // we're out of options so give up - return CAIEntityId(); -} - - - -CAIEntityId CAIEntityId::grpId(const std::string &name) -{ - CAIEntityId id; - - // see if we have a CAIEntityId.toStirng() - id=CAIEntityId(name); - if (id.isGrp() && id.exists()) - return id; - - // see if we have a NLMISC::CEntityId.toStirng() - if (name[0]=='(') - { - id=CAIEntityId(NLMISC::CEntityId(name.c_str())); - if (id.isGrp() && id.exists()) - return id; - } - - // see if name corresponds to the name of one of the groups - for (id=CAIEntityId::firstMgr().firstGrp();!id.isInvalid();id=id.nextGrp()) - if (id.exists()) - if (id.grpPtr()->getName()==name || - id.grpPtr()->getName()+"."+id.grpPtr()->getName()==name || - id.grpPtr()->getName()+":"+id.grpPtr()->getName()==name ) - return id; - - // see if we have a group number and manager number - uint mgridx, grpidx; - char s[30]; - - sscanf(name.c_str(),"%i:%i",&mgridx,&grpidx); - sprintf(s,"%i:%i",mgridx,grpidx); - if (name==std::string(s)) - return CAIEntityId::grpId(mgridx,grpidx); - - sscanf(name.c_str(),"%i,%i",&mgridx,&grpidx); - sprintf(s,"%i,%i",mgridx,grpidx); - if (name==std::string(s)) - return CAIEntityId::grpId(mgridx,grpidx); - - sscanf(name.c_str(),"%i.%i",&mgridx,&grpidx); - sprintf(s,"%i.%i",mgridx,grpidx); - if (name==std::string(s)) - return CAIEntityId::grpId(mgridx,grpidx); - - // we're out of options so give up - return CAIEntityId(); -} - - - -CAIEntityId CAIEntityId::mgrId(const std::string &name) -{ - CAIEntityId id; - - // see if we have a CAIEntityId.toString() - id=CAIEntityId(name); - if (id.isMgr() && id.exists()) - return id; - - // see if we have a NLMISC::CEntityId.toString() - if (name[0]=='(') - { - id=CAIEntityId(NLMISC::CEntityId(name.c_str())); - if (id.isMgr() && id.exists()) - return id; - } - - // see if name corresponds to the name of one of the manager - for (id=CAIEntityId::firstMgr();!id.isInvalid();id=id.nextMgr()) - if (id.exists()) - if (id.mgrPtr()->getName()==name) - return id; - - // see if we have a manager number - uint idx; - char s[256]; - sscanf(name.c_str(),"%i",&idx); - sprintf(s,"%i",idx); - if (name==std::string(s)) - return CAIS::getMgr(idx)->id(); - - // toString no more accepts to compile and not have the time to look at, so its remplaced by the upper piece of code .. - // uint idx=atoi(name.c_str()); - // if (toString(idx)==name) - // return CAIS::getMgr(idx)->id(); - - // we're out of options so give up - return CAIEntityId(); -} -*/ diff --git a/code/ryzom/server/src/ai_service/ai_entity_id.h b/code/ryzom/server/src/ai_service/ai_entity_id.h deleted file mode 100644 index baad9ab69..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_id.h +++ /dev/null @@ -1,157 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -/* -#ifndef RYAI_ENTITY_ID_H -#define RYAI_ENTITY_ID_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/common.h" -#include "nel/misc/debug.h" -#include "nel/misc/entity_id.h" -#include "game_share/ryzom_entity_id.h" - -#include - - -//-------------------------------------------------------------------------- -// Advanced declaration of some classes with circular refferences -//-------------------------------------------------------------------------- -/* -class AI; -class CAIBot; -class CAIGrp; -class CAIMgr; -class CAIEntity; -class CAIPlayer; -*/ - -//-------------------------------------------------------------------------- -// The class itself -//-------------------------------------------------------------------------- - -/* -class CAIEntityId -{ -public: - // default ctor - inline CAIEntityId(); - - /////////////////// - // Statics Start // - - // returns the highest numbers allowed for bot, grp and mgr id components - inline static uint32 maxBotId(); - inline static uint32 maxGrpId(); - inline static uint32 maxMgrId(); - - // building an id from component parts - inline static CAIEntityId botId(uint mgr, uint grp, uint bot); - inline static CAIEntityId botId(CAIEntityId grp, uint bot); - - inline static CAIEntityId grpId(uint mgr, uint grp); - inline static CAIEntityId grpId(CAIEntityId mgr, uint grp); - - inline static CAIEntityId mgrId(uint mgr); - - inline static CAIEntityId plrId(const TDataSetRow& entityIndex); - - // these methods are not intended to be fast but they should be thorough, - // trying every sensible way of interpretting the strings to identify bots - // including: CAIEntitId format, CEntityId format, mgr_name.grp_name.bot_name - // format, stand alone name and mgr_name:grp_name:bot_name format - // Not inlined coz they thake a large amount of code. - static CAIEntityId botId(const std::string &name); - static CAIEntityId grpId(const std::string &name); - static CAIEntityId mgrId(const std::string &name); - static CAIEntityId entityId(const std::string &name); - - // get the ptr of the CAIEntity generated with the parameter String .. - inline static CAIBot *botPtr(const std::string &name); // get ptr to Bot (NULL if !isBot() or !getGrp() or bot>=getGrp()->size) - inline static CAIGrp *grpPtr(const std::string &name); // get ptr to Grp (NULL if (!isBot()&&!isGrp()) or !getMgr() or bot>=getMgr()->size) - inline static CAIMgr *mgrPtr(const std::string &name); // get ptr to Mgr (NULL if isInvalid() or !getMgr()) - inline static CAIEntity *entityPtr(const std::string &name); // get ptr to Plr, Mgr, Grp or Bot - - // Statics End // - ///////////////// - - - // What kind of id is this - is it a bot, grp, mgr, plr or invalid - - inline bool isBot() const; // syntactically, is this a bot id - inline bool isGrp() const; // syntactically, is this a grp id - inline bool isMgr() const; // syntactically, is this a mgr id - inline bool isPlr() const; // syntactically, is this a player id - inline bool isValid() const; // syntactically, is this a valid id ( not invalid, may it be ? ). - inline bool isInvalid() const; // syntactically, is this an invalid id - - // Getting ptr to object of this id ---------------------------------------- - inline bool exists() const; // traverse entity hierachy to see whether this entity exists - inline CAIBot *botPtr() const; // get ptr to Bot (NULL if !isBot() or !getGrp() or bot>=getGrp()->size) - inline CAIGrp *grpPtr() const; // get ptr to Grp (NULL if (!isBot()&&!isGrp()) or !getMgr() or bot>=getMgr()->size) - inline CAIMgr *mgrPtr() const; // get ptr to Mgr (NULL if isInvalid() or !getMgr()) - inline CAIPlayer *plrPtr() const; // get ptr to Plr (NULL if isInvalid() or !getMgr()) - - inline CAIEntity *entityPtr() const; // get ptr to Plr, Mgr, Grp or Bot - - // Routines for iterating through ids - inline static CAIEntityId firstMgr(); // get first mgr in the ai singleton - inline CAIEntityId firstGrp() const; // get first grp for the mgr part of this CAIEntityId - inline CAIEntityId firstBot() const; // get first bot for the grp part of this CAIEntityId - - inline CAIEntityId nextMgr() const; - inline CAIEntityId nextGrp(bool sameMgr=false) const; - inline CAIEntityId nextBot(bool sameGrp=false,bool sameMgr=false) const; - - // Basic accessors - inline bool setBotId(uint32 id); - inline bool setGrpId(uint32 id); - inline bool setMgrId(uint32 id); - - - inline uint32 getBotId() const; - inline uint32 getGrpId() const; - inline uint32 getMgrId() const; - inline uint32 getPlrId() const; - - - // Convertions to and from string, int and CEntityId - inline CAIEntityId(const NLMISC::CEntityId &id); - inline CAIEntityId(const std::string &str); - inline CAIEntityId(uint32 val); - inline uint32 toInt32() const; - - inline NLMISC::CEntityId toEntityId() const; - inline std::string toString() const; - - // Handy basic operators - inline bool operator==(const CAIEntityId &other) const; - inline bool operator!=(const CAIEntityId &other) const; - inline bool operator>=(const CAIEntityId &other) const; - inline bool operator<=(const CAIEntityId &other) const; - inline bool operator>(const CAIEntityId &other) const; - inline bool operator<(const CAIEntityId &other) const; - -protected: -private: - uint32 _id; -}; - -#endif -*/ - diff --git a/code/ryzom/server/src/ai_service/ai_entity_id_inline.h b/code/ryzom/server/src/ai_service/ai_entity_id_inline.h deleted file mode 100644 index 3cd6b43ba..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_id_inline.h +++ /dev/null @@ -1,480 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -/* - THE FOLLOWING 32 BIT CODING IS ASSUMED TO BE THE WAY FORWARDS - AS SUCH IT IS - RESPECTED BY THE LOW 32 BITS OF THE ENTITY IDS CREATED HERE - - notes: - there are many more items than anything else in the game so the high bit switches 'item/other' - there are a lot more ais than anything else (once items removed) so bit 30 switches 'ai/other' - there are a lot of players, a lot of sheets and not a huge lot of anything else so the coding follows: - bit 29 'player/other' - bit 28 'sheet/other' - bits 20..27 'type' for remaining types (player groups/ guilds/ buildings/ etc - - this means that: - items: 1xxx <31 bit id> - ais: 01xx <30 bit id> - players: 001x <29 bit id> (32 slots for 16M players) - sheets: 0001 <28 bit id> - others: 0000 <8 bit type> <20 bit id> - - for ais the structure of the id is type dependent (all of them start with 10 bit manager id) - fauna: <10 bit manager id> <12 bit group id><8 bit bot id> - others: <10 bit manager id> ... the remaining 20 bits TBD ... - - for ais as a rule std::numeric_limits::max() is used as a reserved value - managers are: 01 <10 bit manager id> 1111 1111 1111 1111 1111 - fauna groups are: 01 <10 bit manager id> <12 bit grp id> 1111 1111 -*/ - -/* -#ifndef RYAI_ENTITY_ID_INLINE_H -#define RYAI_ENTITY_ID_INLINE_H - - -//-------------------------------------------------------------------------- -// Some local defines that'll be undefined before the end of the file -//-------------------------------------------------------------------------- - -#define PLR_HDR_BITS 3 -#define PLR_ID_BITS ( 32 - PLR_HDR_BITS ) -#define PLR_ID_BIT_MASK ( ( 1<< PLR_ID_BITS ) -1 ) -#define PLR_HDR_BIT_SHIFT PLR_ID_BITS -#define PLR_HDR_BIT_MASK (std::numeric_limits::max()<=getGrp()->size -inline CAIBot *CAIEntityId::botPtr() const -{ - #ifdef NL_DEBUG - nlassert(isBot()); - #endif - CAIGrp *grp=grpPtr(); - if (grp==NULL) return NULL; - return grp->getBot(getBotId()); -} -// get ptr to Grp (NULL if (!isBot()&&!isGrp()) or !getMgr() or bot>=getMgr()->size -inline CAIGrp *CAIEntityId::grpPtr() const -{ - // the following line is the optimised version of: if (!isGrp() && !isBot()) return NULL; - if ((_id&HDR_BIT_MASK)!=HDR ||(_id&(BOT_BIT_MASK|GRP_BIT_MASK))==(BOT_BIT_MASK|GRP_BIT_MASK)) return NULL; - CAIMgr *mgr=CAIS::getMgr(getMgrId()); - if (mgr==NULL) return NULL; - return mgr->getGrp(getGrpId()); -} -// get ptr to Mgr (NULL if isInvalid() or !getMgr() -inline CAIMgr *CAIEntityId::mgrPtr() const -{ -// if (isInvalid()) return NULL; - return CAIS::getMgr(getMgrId()); -} -// get ptr to Player (NULL if isInvalid() or !getMgr() -inline CAIPlayer *CAIEntityId::plrPtr() const -{ -// if ( isInvalid() ) -// return NULL; - - return CAIS::getPlayer( *this ); -} - -// get ptr to Mgr, Grp or Bot -inline CAIEntity *CAIEntityId::entityPtr() const -{ - switch (_id>>29) - { - case 1: return plrPtr(); // 0x2... - case 2: break; // 0x4... - case 3: break; // 0x6... - default: return NULL; - } - if ( (_id&BOT_BIT_MASK) != BOT_BIT_MASK) return botPtr(); - if ( (_id&GRP_BIT_MASK) != GRP_BIT_MASK) return grpPtr(); - return mgrPtr(); -} - -// Routines for iterating through ids -inline CAIEntityId CAIEntityId::firstMgr() -{ - CAIEntityId result=mgrId(0); - - while (!result.exists()) - if (!result.setMgrId(result.getMgrId()+1)) - return CAIEntityId(); - - return result; -} -inline CAIEntityId CAIEntityId::firstGrp() const -{ - CAIEntityId result(_id); - if (result.isBot()) - result.setBotId(-1); - if (!isInvalid()) - result.setGrpId(0); - CAIMgr *mgr=mgrPtr(); - if (mgr==NULL) - return CAIEntityId(); - return result; -} -inline CAIEntityId CAIEntityId::firstBot() const -{ - CAIEntityId result(_id); - if (result.isMgr()) - result.setGrpId(0); - if (!isInvalid()) - result.setBotId(0); - CAIGrp *grp=grpPtr(); - if (grp==NULL) - return CAIEntityId(); - return result; -} - -inline CAIEntityId CAIEntityId::nextMgr() const -{ - CAIEntityId result(_id); - result.setBotId(-1); // turn the id into a mgr id - result.setGrpId(-1); // turn the id into a mgr id - do - { - if (!result.setMgrId(result.getMgrId()+1)) - return CAIEntityId(); - } - while (!result.exists()); - return result; -} - -inline CAIEntityId CAIEntityId::nextGrp(bool sameMgr) const -{ - uint32 mgrId=getMgrId(); - uint32 grpId=getGrpId()+1; - do - { - CAIMgr *mgr=CAIS::getMgr(mgrId); - while (mgr!=NULL && grpIdgrpCount()) - { - if (mgr->getGrp(grpId)!=NULL) - return grpId(mgrId,grpId); - ++grpId; - } - if (sameMgr) - return CAIEntityId(); - grpId=0; - } - while (++mgrId>BOT_BITS)&( (1<>(BOT_BITS+GRP_BITS))&( (1<mask && id!=~0u) return false; // Test for bit count overflow - if (id==~0u) id=mask; // Special case ~0u - _id=(_id&~mask)|id; - return true; -} -inline bool CAIEntityId::setGrpId(uint32 id) -{ - uint32 mask=((1<=mask && id!=~0u) return false; // Test for bit count overflow - if (id==~0u) id=mask; // Special case ~0u - mask<<=BOT_BITS; - id<<=BOT_BITS; - _id=(_id&~mask)|id; - return true; -} -inline bool CAIEntityId::setMgrId(uint32 id) -{ - uint32 mask=((1<=mask && id!=std::numeric_limits::max()) return false; // Test for bit count overflow - //if (id==~0u) id=mask; - id&=mask; // Special case ~0u - mask<<=BOT_BITS+GRP_BITS; - id<<=BOT_BITS+GRP_BITS; - _id=(_id&~mask)|id; - return true; -} - -// Convertions to and from string, int and CEntityId -inline CAIEntityId::CAIEntityId(const NLMISC::CEntityId &eid) -{ - if (eid==NLMISC::CEntityId::Unknown) - *this=CAIEntityId(); - else - { - if (eid.getType()==RYZOMID::player) - *this = CAIS::getPlayer(eid)->id(); // buildPlrId(id); - else if (eid.getType()&0x80) - _id=(uint32)eid.getShortId(); - else - *this=CAIEntityId(); - } -} -inline CAIEntityId::CAIEntityId(const std::string &str) -{ - _id=CAIEntityId()._id; - sscanf(str.c_str(),"AI:%x",&_id); -} -inline CAIEntityId::CAIEntityId(uint32 val) -{ - _id=val; -} - -inline NLMISC::CEntityId CAIEntityId::toEntityId() const -{ - if (isPlr()) - { - return plrPtr()->eid(); - } - if (isBot() && exists() && botPtr()->isNPC()) - return NLMISC::CEntityId(RYZOMID::npc,(uint64)_id); - else - return NLMISC::CEntityId(RYZOMID::creature,(uint64)_id); -} -inline std::string CAIEntityId::toString() const -{ - char result[30]; - if (isInvalid()) sprintf(result,"AI:%04x:INVALID_ID",_id); - if (isBot()) sprintf(result,"AI:%04x:BOT:%04x:%04x:%04x",_id,getMgrId(),getGrpId(),getBotId()); - if (isGrp()) sprintf(result,"AI:%04x:GRP:%04x:%04x",_id,getMgrId(),getGrpId()); - if (isMgr()) sprintf(result,"AI:%04x:MGR:%04x",_id,getMgrId()); - if (isPlr()) sprintf(result,"AI:%04x:PLR:%s",_id,toEntityId().toString().c_str()); - return std::string(result); -} - - -inline uint32 CAIEntityId::toInt32() const -{ - return _id; -} - - // Statics that return the highest numbers allowed for bot, grp and mgr id components -inline uint32 CAIEntityId::maxBotId() { return (1<=(const CAIEntityId &other) const { return _id>=other._id; } -inline bool CAIEntityId::operator<=(const CAIEntityId &other) const { return _id<=other._id; } -inline bool CAIEntityId::operator>(const CAIEntityId &other) const { return _id>other._id; } -inline bool CAIEntityId::operator<(const CAIEntityId &other) const { return _id -// 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 . - - - -#ifndef RYAI_ENTITY_MATRIX_H -#define RYAI_ENTITY_MATRIX_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/common.h" -#include "nel/misc/debug.h" -#include "nel/misc/command.h" - -#include -#include -#include - -#include "ai_share/ai_entity_physical_list_link.h" -#include "ai_pos.h" - -//-------------------------------------------------------------------------- -// The CAIEntityMatrixIteratorTblLinear class -//-------------------------------------------------------------------------- -// This class uses a vector of horizontal run lengths to represent -// the aea to be scanned. -// The form represented by the data is assumed to be symetrical in both x and y. -// Linear tables use a better RAM access patern than random access tables -// and should be used whenever possible - -class CAIEntityMatrixIteratorTblLinear -{ -public: - struct STblEntry - { - STblEntry() {} - STblEntry(uint32 runLength, sint32 previousRunLength) - { - RunLength=(uint16)(runLength-1); // we assume all runs are at least 1 unit long - this is the excess - StartDx=(sint16)(-(previousRunLength/2)-(((sint32)runLength)/2)); - - #ifdef NL_DEBUG - nlassert(runLength>0); // runs must be at least 1 unit long - nlassert(runLength<32768); // this is the limit where StartDx runs out of bits - nlassert(previousRunLength>=0); - nlassert(previousRunLength<32768); - #endif - } - - uint16 RunLength; - sint16 StartDx; - }; - typedef std::vector TTbl; - typedef TTbl::iterator iterator; - - inline CAIEntityMatrixIteratorTblLinear(); - inline CAIEntityMatrixIteratorTblLinear(uint32 *runLengths,uint32 count); - - inline void push_back(uint32 runLength, sint32 previousRunLength); - inline const STblEntry &operator[](uint32 idx) const; - inline const iterator begin() const; - inline const iterator end() const; - inline uint32 size() const; - -private: - TTbl _tbl; -}; - - -//-------------------------------------------------------------------------- -// The CAIEntityMatrixIteratorTblRandom class -//-------------------------------------------------------------------------- -// This class uses a vector of xy offsets to apply to the 'read position' ptr -// as it iterates across the grid. -// The first xy offset is applied at initalisation time in order to allow for -// the use of tables that do not scan the '0,0' cell. -// These tables use a less efficient RAM access pattern than Linear tables but -// benefit from a higher degree of control over the area scanned and the order -// of scanning. - -class CAIEntityMatrixIteratorTblRandom -{ -public: - struct STblEntry - { - STblEntry() {} - STblEntry(sint32 dxdy) { dxdy=dxdy; } - STblEntry(sint16 dx, sint16 dy) { dx=dx; dy=dy; } - union - { - struct { sint16 dx, dy; }; - uint32 dxdy; - }; - }; - typedef std::vector TTbl; - typedef TTbl::iterator iterator; - - inline CAIEntityMatrixIteratorTblRandom(); - - inline void push_back(sint16 dx,sint16 dy); - inline const STblEntry &operator[](uint32 idx) const; - inline const iterator begin() const; - inline const iterator end() const; - inline uint32 size() const; - -private: - TTbl _tbl; -}; - - -//-------------------------------------------------------------------------- -// The CAIEntityMatrix class -//-------------------------------------------------------------------------- - -template -class CAIEntityMatrix : - public NLMISC::CDbgRefCount > -{ -public: - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix::CCellTblIteratorRandom - - This class provides an iterator for iterating across the cells of a matrix '_matrix' following the - pattern described by a cell iteration table '_tbl' - - An iterator '_it' refferences the current position in '_tbl' - - A compact coordinate pair '_xy' reffernces the current position in '_matrix' - Note that because the matrix super imposes coordinates with the same low byte, the upper bytes of - the '_xy' coordinates is needed for position proximity tests - ----------------------------------------------------------------------------------------------------- - */ - class CCellTblIteratorRandom - { - public: - - inline CCellTblIteratorRandom(): - _matrix(NULL), _tbl(NULL), _x(0), _y(0) - { - } - - inline CCellTblIteratorRandom(const CAIEntityMatrix *matrix,const CAIEntityMatrixIteratorTblRandom *tbl,const CAIVector &pos): - _matrix(matrix), _tbl(tbl), _x((uint16)pos.x().asInt16Meters()), _y((uint16)pos.y().asInt16Meters()) - { - _it=_tbl->begin(); - // apply the first entry in the iterator table in order to setup the start position correctly - ++*this; - } - - inline const CEntityListLink * operator*() const - { - const typename CAIEntityMatrix::SMatrixLine &line =(*_matrix)[_yl]; - const CEntityListLink &cellEntityListLink=line[_xl]; - return &cellEntityListLink; - } - - inline const CCellTblIteratorRandom &operator++() - { -#ifdef NL_DEBUG - // make sure we aren't trying to access an uninitialised iterator - nlassert(_it!=_tbl->end()); -#endif - - _x+=(*_it).dx; - _y+=(*_it).dy; - ++_it; - - return *this; - } - - inline const CCellTblIteratorRandom &operator=(const CCellTblIteratorRandom &other) - { - _xy= other._xy; - _matrix= other._matrix; - _tbl= other._tbl; - _it= other._it; - - return *this; - } - - inline bool end() const - { - return _it==_tbl->end(); - } - - inline const uint32 &xy() const { return _xy; } - inline const uint16 &x() const { return _x; } - inline const uint16 &y() const { return _y; } - inline const uint8 &xl() const { return _xl; } - inline const uint8 &xh() const { return _xh; } - inline const uint8 &yl() const { return _yl; } - inline const uint8 &yh() const { return _yh; } - - inline const CAIEntityMatrix *matrix() const - { - return _matrix; - } - - private: - union - { - uint32 _xy; - struct { uint16 _x, _y; }; - struct { uint8 _xl, _xh, _yl, _yh; }; - }; - const CAIEntityMatrix *_matrix; - const CAIEntityMatrixIteratorTblRandom *_tbl; - CAIEntityMatrixIteratorTblRandom::iterator _it; - }; - - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix::CCellTblIteratorLinear - - This class provides an iterator for iterating across the cells of a matrix '_matrix' following the - pattern described by a cell iteration table '_tbl' - - An iterator '_it' refferences the current position in '_tbl' - The _runLengthRemaining property is setup each time the iterator _it is advanced by the ++operator. - Subsequent calls to operator++() will only increment _it if _runLengthRemaining==0 - - A compact coordinate pair '_xy' reffernces the current position in '_matrix' - Note that because the matrix super imposes coordinates with the same low byte, the upper bytes of - the '_xy' coordinates is needed for position proximity tests - ----------------------------------------------------------------------------------------------------- - */ - class CCellTblIteratorLinear - { - public: - inline CCellTblIteratorLinear(): - _x(0), _y(0), _matrix(NULL), _tbl(NULL), _runLengthRemaining(0) - { - } - - inline CCellTblIteratorLinear(const CAIEntityMatrix *matrix,const CAIEntityMatrixIteratorTblLinear *tbl,const CAIVector &pos): - _x((uint16)pos.x().asInt16Meters()), _y((uint16)pos.y().asInt16Meters()), _matrix(matrix), _tbl(tbl) - { -#ifdef NL_DEBUG - nlassert(_tbl!=NULL); - nlassert(_tbl->size()>0); - nlassert(_tbl->size()<32768); // a numeric over-run limit - nlassert(_matrix!=NULL); -#endif - - // setup the iterator to point to the strat of the iterator table and setup properties accordingly - _it=_tbl->begin(); - _runLengthRemaining=(*_tbl)[0].RunLength; - _x-=(sint16)(_runLengthRemaining/2); - _y-=(sint16)(_tbl->size()/2); - } - - inline const CEntityListLink *operator*() const - { - return &(*_matrix)[_yl][_xl]; - } - - inline const CCellTblIteratorLinear &operator++() - { -#ifdef NL_DEBUG - // make sure we aren't trying to access an uninitialised iterator - nlassert(_it!=_tbl->end()); -#endif - - // if we're not at the end of the current run continue run else move on to next line - if (_runLengthRemaining!=0) - { - --_runLengthRemaining; - ++_x; - } - else - { - ++_it; - if (_it==_tbl->end()) - return *this; - - _runLengthRemaining=(*_it).RunLength; - _x+=(*_it).StartDx; - ++_y; - } - - return *this; - } - - inline const CCellTblIteratorLinear &operator=(const CCellTblIteratorLinear &other) - { - _xy= other._xy; - _matrix= other._matrix; - _tbl= other._tbl; - _it= other._it; - _runLengthRemaining= other._runLengthRemaining; - - return *this; - } - - inline bool end() const - { - return _it==_tbl->end(); - } - - inline const uint32 &xy() const { return _xy; } - inline const uint16 &x() const { return _x; } - inline const uint16 &y() const { return _y; } - inline const uint8 &xl() const { return _xl; } - inline const uint8 &xh() const { return _xh; } - inline const uint8 &yl() const { return _yl; } - inline const uint8 &yh() const { return _yh; } - - inline const CAIEntityMatrix *matrix() const - { - return _matrix; - } - - private: - union - { - uint32 _xy; - struct { uint16 _x, _y; }; - struct { uint8 _xl, _xh, _yl, _yh; }; - }; - const CAIEntityMatrix *_matrix; - const CAIEntityMatrixIteratorTblLinear *_tbl; - CAIEntityMatrixIteratorTblLinear::iterator _it; - uint32 _runLengthRemaining; - }; - - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix::CEntityIteratorTemplate - class CAIEntityMatrix::CEntityIteratorLinear - class CAIEntityMatrix::CEntityIteratorRandom - - This class provides an iterator for iterating across the entities listed in the cells of a matrix - '_matrix' following the pattern described by a cell iteration table '_tbl' - - The class is composed of a CCellTblIteratorLinear '_cellIt' responsible for iterating across the matrix - and an entity pointer '_entity' used for iterating over the entities in each matrix cell - - Note that unlinking, moving or deleting the entity refferenced by a CEntityIteratorLinear iterator - invalidates it. - ----------------------------------------------------------------------------------------------------- - */ - - template - class CEntityIteratorTemplate - { - public: - - inline CEntityIteratorTemplate() : _cellIt() - { - _entity=NULL; - } - - inline CEntityIteratorTemplate(const CAIEntityMatrix *matrix,const CTbl *tbl,const CAIVector &pos) : _cellIt(matrix,tbl,pos) - { - // get a pointer to the list link for the first entity in the cell -// _entity=(*_cellIt)->next(); - - _entity=(*_cellIt); - ++*this; - - // if the cell is empty then start iterating to find a non-empty cell -// if (_entity->unlinked()) -// ++*this; - } - - inline CEntityIteratorTemplate(const CAIEntityMatrix *matrix,const CTbl *tbl,const T *entity) : _cellIt(matrix,tbl,entity->pos()) - { - // get a poniter to the list link for the first entity in the same cell as the given entity -// _entity=(*_cellIt)->next(); - - _entity=(*_cellIt); - ++*this; - } - - inline T &operator*() - { - #ifdef NL_DEBUG - // make sure we aren't trying to access passed the end of list - nlassert(!end()); - #endif - - return *NLMISC::safe_cast(_entity->entity()); - } - - inline const CEntityIteratorTemplate &operator++() - { -#ifdef NL_DEBUG - - // if you are on a breakpoint here it is because you've tried to do a ++ on an iterator - // that has reached its end marker - nlassert(!_cellIt.end()); - - // make sure the entity is in the cell that the iterator reffers to - // if you are on a breakpoint here it is because you've moved or removed an entity - // and have invalidated this iterator - // nlassert(_entity->xyCellAsInt()==_cellIt.xy()); -#endif - // repeat the following loop until either we come to the end of the cell iterator or we find an entity with - // xy coords that match our own - do - { - // try to get the next entity in the cell - _entity=_entity->next(); - if (_entity==*_cellIt) - { - // we're at the end of the entity list for this cell so try to find another cell with a valid entity - do - { - ++_cellIt; - } - while ( !_cellIt.end() - && (*_cellIt)->unlinked()); - - if (_cellIt.end()) - return *this; - _entity=(*_cellIt)->next(); - } - - } - while ( !_cellIt.end() - && ( _entity->unlinked() - || !_entity->entity()->isAt16MetersPos(_cellIt.x(),_cellIt.y())) ); - // as cells are tiled over the world, we need to check if our entity have a real good match with the scanned position. - return *this; - } - - inline const CEntityIteratorTemplate &operator=(const CEntityIteratorTemplate & other) - { - _cellIt= other._cellIt; - _entity= other._entity; - return *this; - } - - // method for testing iterator for end of current sequence - inline bool end() - { - // the following can only happen if there are no more entites in cell and no more deltas in cell iterator tbl - return _cellIt.end(); - } - - private: - CIt _cellIt; // the cell iterator - const CEntityListLink *_entity; // which entity are we pointing at (within the cell) - }; - - typedef CEntityIteratorTemplate CEntityIteratorLinear; - typedef CEntityIteratorTemplate CEntityIteratorRandom; - - - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix::SMatrixLine - - The class used to represent a matrix row - ----------------------------------------------------------------------------------------------------- - */ - - struct SMatrixLine - { - // data - CEntityListLink Line[256]; - - // one and only accessor - inline CEntityListLink &operator[](uint8 x) const { return const_cast &>(Line[x]); } - }; - - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix methods - ----------------------------------------------------------------------------------------------------- - */ - -public: - // ctor - inline CAIEntityMatrix(); - - // table lookup operator - should be used as myMatrix[y][x] - inline SMatrixLine &operator[](uint8 y) const; - - // methods for initialising iterators - inline const typename CAIEntityMatrix::CCellTblIteratorRandom beginCells(const CAIEntityMatrixIteratorTblRandom *tbl,const CAIVector &pos) const; - inline const typename CAIEntityMatrix::CEntityIteratorRandom beginEntities(const CAIEntityMatrixIteratorTblRandom *tbl,const CAIVector &pos) const; - - inline const typename CAIEntityMatrix::CCellTblIteratorLinear beginCells(const CAIEntityMatrixIteratorTblLinear *tbl,const CAIVector &pos) const; - inline const typename CAIEntityMatrix::CEntityIteratorLinear beginEntities(const CAIEntityMatrixIteratorTblLinear *tbl,const CAIVector &pos) const; - - -private: - /* - ----------------------------------------------------------------------------------------------------- - class CAIEntityMatrix data - ----------------------------------------------------------------------------------------------------- - */ - - SMatrixLine _matrix[256]; -}; - -//-------------------------------------------------------------------------- -// The CAIEntityMatrix inlines -//-------------------------------------------------------------------------- -template -inline CAIEntityMatrix::CAIEntityMatrix() -{ -} - -template -inline typename CAIEntityMatrix::SMatrixLine &CAIEntityMatrix::operator[](uint8 y) const -{ - return const_cast::SMatrixLine &>(_matrix[y]); -} - -template -inline const typename CAIEntityMatrix::CCellTblIteratorRandom CAIEntityMatrix::beginCells(const CAIEntityMatrixIteratorTblRandom *tbl, const CAIVector &pos) const -{ - return CCellTblIteratorRandom(this,tbl,pos); -} - -template -inline const typename CAIEntityMatrix::CEntityIteratorRandom CAIEntityMatrix::beginEntities(const CAIEntityMatrixIteratorTblRandom *tbl, const CAIVector &pos) const -{ - CEntityIteratorRandom newIt(this,tbl,pos); - return newIt; -} - -template -inline const typename CAIEntityMatrix::CCellTblIteratorLinear CAIEntityMatrix::beginCells(const CAIEntityMatrixIteratorTblLinear *tbl, const CAIVector &pos) const -{ - return CCellTblIteratorLinear(this,tbl,pos); -} - -template -inline const typename CAIEntityMatrix::CEntityIteratorLinear CAIEntityMatrix::beginEntities(const CAIEntityMatrixIteratorTblLinear *tbl, const CAIVector &pos) const -{ - CEntityIteratorLinear newIt(this,tbl,pos); - return newIt; -} - - -//-------------------------------------------------------------------------- -// The CAIEntityMatrixIteratorTblRandom inlines -//-------------------------------------------------------------------------- - -inline CAIEntityMatrixIteratorTblRandom::CAIEntityMatrixIteratorTblRandom() -{ -} - -inline void CAIEntityMatrixIteratorTblRandom::push_back(sint16 dx,sint16 dy) -{ - _tbl.push_back(CAIEntityMatrixIteratorTblRandom::STblEntry(dx,dy)); -} - -inline const CAIEntityMatrixIteratorTblRandom::STblEntry &CAIEntityMatrixIteratorTblRandom::operator[](uint32 idx) const -{ - #ifdef NL_DEBUG - nlassert(idx<_tbl.size()); - #endif - - return _tbl[idx]; -} - -inline const CAIEntityMatrixIteratorTblRandom::iterator CAIEntityMatrixIteratorTblRandom::begin() const -{ - return const_cast(_tbl).begin(); -} - -inline const CAIEntityMatrixIteratorTblRandom::iterator CAIEntityMatrixIteratorTblRandom::end() const -{ - return const_cast(_tbl).end(); -} - -inline uint32 CAIEntityMatrixIteratorTblRandom::size() const -{ - return (uint32)_tbl.size(); -} - - -//-------------------------------------------------------------------------- -// The CAIEntityMatrixIteratorTblLinear inlines -//-------------------------------------------------------------------------- - -inline CAIEntityMatrixIteratorTblLinear::CAIEntityMatrixIteratorTblLinear() -{ -} - -inline CAIEntityMatrixIteratorTblLinear::CAIEntityMatrixIteratorTblLinear(uint32 *runLengths,uint32 count) -{ - uint32 lastRun=0; - for(uint i=0;i(_tbl).begin(); -} - -inline const CAIEntityMatrixIteratorTblLinear::iterator CAIEntityMatrixIteratorTblLinear::end() const -{ - return const_cast(_tbl).end(); -} - -inline uint32 CAIEntityMatrixIteratorTblLinear::size() const -{ - return (uint32)_tbl.size(); -} - - -//-------------------------------------------------------------------------- -#endif diff --git a/code/ryzom/server/src/ai_service/ai_entity_physical.cpp b/code/ryzom/server/src/ai_service/ai_entity_physical.cpp deleted file mode 100644 index 5a6ea603d..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_physical.cpp +++ /dev/null @@ -1,422 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "server_share/r2_variables.h" -#include "ai_mgr.h" -#include "ai_entity_physical.h" -#include "ai_entity_physical_inline.h" -#include "ai_instance.h" - - -// critical routine, get backward of weak technical design legacy. - -const float repulsCoef=1.f/6.f; // arbitrary - -int CAIEntityPhysical::_PlayerVisibilityDistance = 64; -bool CAIEntityPhysical::havePlayersAround() const -{ - // todo Sadge: fixme! The correct fix is to handle the vision count mirror field in GPMS - // until then, ring shard swill do much more work than required moving NPCs about - if (IsRingShard) - { -#ifdef NL_DEBUG - nlwarning("FIXME: Quick hack to work round drunken NPC problem"); -#endif - return true; - } - - TYPE_VISION_COUNTER n = 255-currentVisionCounter(); - ++AISStat::VisionCtr[n]; - if (n==255) - return false; - - return n <= _PlayerVisibilityDistance; -} - -template <> CKnapsackSolver::Algorithm CTargetable::_TargeterChoiceAlgorithm = CKnapsackSolver::FastSingleReplace; -template <> float const CTargetable::_DefaultFightTargetersWeightMax = 6.f; -template <> float const CTargetable::_DefaultFightWeight = .98f; -template <> float const CTargetable::_DefaultFightValue = 1.f; - -CAIEntityPhysicalLocator* CAIEntityPhysicalLocator::_Instance = NULL; -CAIEntityPhysicalLocator* CAIEntityPhysicalLocator::getInstance() -{ - if (!_Instance) - _Instance = new CAIEntityPhysicalLocator(); - return _Instance; -} - -CAIEntityPhysical* CAIEntityPhysicalLocator::getEntity(TDataSetRow const& row) const -{ - std::map::const_iterator it = _EntitiesByRow.find(row); - if (it!=_EntitiesByRow.end()) - return it->second; - else - return NULL; -} - -CAIEntityPhysical* CAIEntityPhysicalLocator::getEntity(NLMISC::CEntityId const& id) const -{ - std::map::const_iterator it = _EntitiesById.find(id); - if (it!=_EntitiesById.end()) - return it->second; - else - return NULL; -} - -void CAIEntityPhysicalLocator::addEntity(TDataSetRow const& row, NLMISC::CEntityId const& id, CAIEntityPhysical* entity) -{ - _EntitiesByRow.insert(std::make_pair(row, entity)); - _EntitiesById.insert(std::make_pair(id, entity)); -} - -void CAIEntityPhysicalLocator::delEntity(TDataSetRow const& row, NLMISC::CEntityId const& id, CAIEntityPhysical* entity) -{ - _EntitiesById.erase(id); - _EntitiesByRow.erase(row); -} - -sint32 CAIEntityPhysical::getFameIndexed(uint32 factionIndex, bool modulated, bool returnUnknownValue) const -{ - return CFameInterface::getInstance().getFameIndexed(getEntityId(), factionIndex, modulated, returnUnknownValue); -} - -sint32 CAIEntityPhysical::getFame(std::string const& faction, bool modulated, bool returnUnknownValue) const -{ - return CFameInterface::getInstance().getFame(getEntityId(), NLMISC::CStringMapper::map(faction), modulated, returnUnknownValue); -} - -////////////////////////////////////////////////////////////////////////////// - -CModEntityPhysical::CModEntityPhysical(CPersistentOfPhysical& owner, TDataSetRow const& entityIndex, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag const& AStarFlags) -: CAIEntityPhysical(owner, entityIndex, id, radius, level, AStarFlags) -, _Decalage(0, 0) -{ - setMode (MBEHAV::NORMAL); - setBehaviour (MBEHAV::IDLE); -} - -inline -CAIVector CModEntityPhysical::calcRepulsionFrom(const CAIVector& pos, const std::vector& entities) const -{ - H_AUTO(CalcRepulsionFrom) - - const double thisDist=radius()+0.5; - CAIVector repulse; - - // collide with entities - FOREACHC(it, std::vector, entities) - { - const CAIEntityPhysical* entityPhysical = *it; - nlassert(entityPhysical != NULL); - - CAIVector deltaPos=pos; - deltaPos -=entityPhysical->pos(); - - const double norm = deltaPos.quickNorm(); - const double cmpDist = thisDist+entityPhysical->radius(); - if (norm& entities, CAIVector& repulsion) const -{ - H_AUTO(CalcStraightRepulsionFrom) - - // init the repulsion to (0,0) - repulsion.setXY(0.0, 0.0); - - const CAIVector move = pos - this->pos(); - const double moveNorm = move.quickNorm(); - const double moveAngle = move.asAngle().asRadians(); - const double orientation = theta().asRadians(); - - // collide with entities - FOREACHC(it, std::vector, entities) - { - const CAIEntityPhysical* entityPhysical = *it; - nlassert(entityPhysical != NULL); - - CAIVector deltaPos = pos; - deltaPos -= entityPhysical->pos(); - const double norm = deltaPos.quickNorm(); - const double cmpDist = radius() + entityPhysical->radius() + 0.5; - - // if the entity is colliding us - if (norm < cmpDist) - { - // first do a perpendicular repulsion - deltaPos.normalize(float( 1000.0 * (cmpDist - norm) )); - repulsion += deltaPos; - - // then add an oriented repulsion - double speedFactor = 1.0; - double repulsionAngle = deltaPos.asAngle().asRadians(); - double angle = computeShortestAngle( moveAngle, (-deltaPos).asAngle().asRadians() ); - if (angle > -NLMISC::Pi/2 && angle < NLMISC::Pi/2) - { - const double angle1 = NLMISC::Pi/2 - angle; - const double angle2 = -NLMISC::Pi/2 - angle; - const double deviation1 = computeShortestAngle(orientation, repulsionAngle + angle1); - const double deviation2 = computeShortestAngle(orientation, repulsionAngle + angle2); - if (fabs(deviation1) < fabs(deviation2)) - { - angle = angle1; - } - else - { - angle = angle2; - } - speedFactor = 1.0 - fabs(angle)/NLMISC::Pi; - repulsionAngle += angle; - deltaPos = CAngle(repulsionAngle).asVector2d() * norm; - } - deltaPos.normalize(float( 1000.0 * speedFactor * (cmpDist - norm) )); - repulsion += deltaPos; - } - } - - // now check that the repulsed position does not collide any entity - const CAIVector repulsedPos = pos + repulsion; - FOREACHC(it, std::vector, entities) - { - const CAIEntityPhysical* entityPhysical = *it; - nlassert(entityPhysical != NULL); - - CAIVector deltaPos = repulsedPos; - deltaPos -= entityPhysical->pos(); - - const double norm = deltaPos.quickNorm(); - const double cmpDist = radius() + entityPhysical->radius(); - if (norm < cmpDist) - { - return false; - } - } - - // ok the repulsion is successful - return true; -} - -CAIVector CModEntityPhysical::calcRepulsion(const CAIPos& pos) const -{ - H_AUTO(CalcRepulsion) - - const double thisDist=radius()+0.5; - const double botDist=(double)thisDist+5; // worth case scenario FOR BOTS. - const double humanDist=(double)thisDist+2; // worth case scenario FOR HUMANS. - - std::vector nearbyEntities; - { - CAIEntityMatrix::CEntityIteratorLinear it; - - // get nearby bots - for (it=getAIInstance()->botMatrix().beginEntities(CAIS::instance().bestLinearMatrixIteratorTbl((uint32) botDist),pos);!it.end();++it) - { - const CAIEntityPhysical* entityPhysical=(*it).getSpawnObj(); - if ( entityPhysical - && entityPhysical->isAlive() - && entityPhysical!=this) - { - nearbyEntities.push_back(entityPhysical); - } - } - - // get nearby players - for (it=getAIInstance()->playerMatrix().beginEntities(CAIS::instance().bestLinearMatrixIteratorTbl((uint32) humanDist),pos);!it.end();++it) - { - const CAIEntityPhysical* entityPhysical=(*it).getSpawnObj(); - if ( entityPhysical - && entityPhysical->isAlive() - && entityPhysical!=this) - { - nearbyEntities.push_back(entityPhysical); - } - } - } - - return calcRepulsionFrom(pos, nearbyEntities); -} - -bool CModEntityPhysical::calcStraightRepulsion(CAIPos const& pos, CAIVector& repulsion) const -{ - H_AUTO(CalcStraightRepulsion) - - const CAIVector move = pos - this->pos(); - const double moveNorm = move.quickNorm(); - const CAngle moveAngle = move.asAngle(); - - const double thisDist=radius()+0.5; - const double botDist=(double)thisDist+5; // worth case scenario FOR CREATURES. - const double humanDist=(double)thisDist+2; // worth case scenario FOR HUMANS. - - std::vector nonTraversableBots; - std::vector nearbyEntities; - { - CAIEntityMatrix::CEntityIteratorLinear it; - - // get nearby bots - for (it=getAIInstance()->botMatrix().beginEntities(CAIS::instance().bestLinearMatrixIteratorTbl((uint32) botDist),pos);!it.end();++it) - { - const CBot* bot = NLMISC::safe_cast(&*it); - const CAIEntityPhysical* entityPhysical = bot->getSpawnObj(); - if ( entityPhysical - && entityPhysical->isAlive() - && entityPhysical!=this) - { - // if it is a bot object with a significant radius - // TODO: kxu: add a sheet param to recognize these bots that MUST not be crossed by other bots - if ( bot->getSheet()->NotTraversable() - && entityPhysical->radius() > 1.f - && entityPhysical->walkSpeed() == 0.f - && entityPhysical->runSpeed() == 0.f) - { - nonTraversableBots.push_back(entityPhysical); - } - else - { - nearbyEntities.push_back(entityPhysical); - } - } - } - - // get nearby players - for (it=getAIInstance()->playerMatrix().beginEntities(CAIS::instance().bestLinearMatrixIteratorTbl((uint32) humanDist),pos);!it.end();++it) - { - const CAIEntityPhysical* entityPhysical=(*it).getSpawnObj(); - if ( entityPhysical - && entityPhysical->isAlive() - && entityPhysical!=this) - { - nearbyEntities.push_back(entityPhysical); - } - } - } - - repulsion = calcRepulsionFrom(pos, nearbyEntities); - // scale the repulsion - // repulsion speed is 71% of movement speed - repulsion.normalize(float( 710.0 * std::max(moveNorm, 0.025) )); - if (nonTraversableBots.empty()) - { - return true; - } - - CAIVector straightRepulsion; - if (calcStraightRepulsionFrom(repulsion+pos, nonTraversableBots, straightRepulsion)) - { - repulsion += straightRepulsion; - return true; - } - - // did not find a repulsion without collision - return false; -} - -void CModEntityPhysical::setPos(const CAIPos &pos, const RYAI_MAP_CRUNCH::CWorldPosition &wpos) -{ - // coherence test. -#ifdef NL_DEBUG - nlassert(RYAI_MAP_CRUNCH::CMapPosition(pos)==wpos); -#endif - - _pos.setXY(pos); - _wpos = wpos; // setWPos(wpos); coz no test. - _pos.setH((sint32)(_wpos.getRootCell()?_wpos.getRootCell()->getMetricHeight(_wpos) : 0)); - - // if we're not linked to the world map then nothing to do - CPersistentOfPhysical &persOfPhys=getPersistent(); - if (persOfPhys.isLinkedToWorldMap()) - { - CAIInstance* aii = getAIInstance(); - persOfPhys.linkEntityToMatrix(pos, aii->botMatrix()); - } -} - -////////////////////////////////////////////////////////////////////////////// - -NLMISC_COMMAND(targeterChoiceAlgorithm,"Set algorithm used to select targeters","[list|]") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - { - if (args[0]=="list") - { - log.displayNL("Possible algorithms are:"); - CKnapsackSolver::Algorithm algorithms[] = { - CKnapsackSolver::Optimal, - // CKnapsackSolver::FullAddCheck, - // CKnapsackSolver::AddCheck, - CKnapsackSolver::FastAddCheck, - // CKnapsackSolver::FullSingleReplace, - // CKnapsackSolver::SingleReplace, - CKnapsackSolver::FastSingleReplace, - CKnapsackSolver::VeryFastSingleReplace - }; - size_t algorithmCount = sizeof(algorithms)/sizeof(algorithms[0]); - for (size_t i=0; i::_TargeterChoiceAlgorithm = algorithm; - } - } - - log.displayNL("targeterChoiceAlgorithm is %s", CKnapsackSolver::toString(CTargetable::_TargeterChoiceAlgorithm).c_str()); - return true; -} - -////////////////////////////////////////////////////////////////////////////// - -NLMISC_COMMAND(entityPlayerVisibilityDistance,"Set distance (0 to 255) at which entities consider they see a player","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - { - sint n; - NLMISC::fromString(args[0], n); - if (n>=0 && n<=255) - CAIEntityPhysical::_PlayerVisibilityDistance = n; - } - - log.displayNL("entityPlayerVisibilityDistance is %d",CAIEntityPhysical::_PlayerVisibilityDistance); - return true; -} diff --git a/code/ryzom/server/src/ai_service/ai_entity_physical.h b/code/ryzom/server/src/ai_service/ai_entity_physical.h deleted file mode 100644 index 5eb30b34f..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_physical.h +++ /dev/null @@ -1,449 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef RYAI_ENTITY_PHYSICAL_H -#define RYAI_ENTITY_PHYSICAL_H - -#include "ai_entity.h" -#include "ai_pos_mirror.h" -#include "persistent_spawnable.h" -#include "ai_share/world_map.h" -#include "server_share/combat_state.h" -#include "world_container.h" -#include "ai_entity_matrix.h" -#include "server_share/action_flags.h" -#include "combat_interface.h" - -#include "world_map_link.h" - -#include "knapsack_solver.h" - -#include "nel/misc/variable.h" - -class CAIEntityPhysical; -class CPetOwner; -class CFightFaunaProfile; - -extern NLMISC::CVariable SpeedFactor; - -////////////////////////////////////////////////////////////////////////////// -// CTargetable // -////////////////////////////////////////////////////////////////////////////// - -/** Targeting system - There are both the targeter and the targetable in the same class for - template easier manipulation reasons. - @note Don't forget to call detachFromTargeting() in T dtor. -*/ -template -class CTargetable -{ -#ifdef NL_OS_WINDOWS -# ifndef NL_COMP_MINGW - friend class CTargetable; -# endif -#endif -public: - typedef NLMISC::CDbgPtr TPtr; -// typedef T* TPtr; - enum TTargetType - { - TARGET_TYPE_FIGHT = 0, - TARGET_TYPE_VISUAL, - TARGET_TYPE_UNREACHABLE, - TARGET_TYPE_MAX - }; - - float _AggroScore; - uint32 _ChooseLastTime; - - /// @name Constructor and destructor - //@{ - CTargetable(); - virtual ~CTargetable(); - //@} - - virtual void targetDied () { } - - /// @name Accessors - //@{ - TPtr const& firstTargeter() const { return _FirstTargeters[TARGET_TYPE_FIGHT]; } - TPtr const& firstVisualTargeter() const { return _FirstTargeters[TARGET_TYPE_VISUAL]; } - TPtr const& firstUnreachableTargeter() const { return _FirstTargeters[TARGET_TYPE_UNREACHABLE]; } - - TPtr const& nextTargeter() const { return _NextTargeter; } - - uint32 targeterCount() const { return _TargeterCount[TARGET_TYPE_FIGHT]; } - uint32 visualTargeterCount() const { return _TargeterCount[TARGET_TYPE_VISUAL]; } - uint32 unreachableTargeterCount() const { return _TargeterCount[TARGET_TYPE_UNREACHABLE]; } - uint32 totalTargeterCount() const; - //@} - - /// @name Target management - //@{ - virtual void setTarget(T* target); - virtual void setVisualTarget(T* target); - virtual void setUnreachableTarget(T* target); - - TPtr getTarget() const; - TPtr getVisualTarget() const; - TPtr getUnreachableTarget() const; - - void detachFromTargeters(); - /// Detach from targeters and target - void detachFromTargeting(); - //@} - - /// @name Fight management - //@{ - virtual float getFreeFightSpaceRatio() const { return std::max(fightTargetersFreeWeight()/fightTargetersWeightMax(), 0.f); } - virtual float fightWeight() const { return _DefaultFightWeight; } - virtual float fightValue() const { return _DefaultFightValue; } - virtual float fightTargetersWeightMax() const { return _DefaultFightTargetersWeightMax; } - virtual float fightTargetersWeight() const { return _FightTargetersWeight; } - virtual float fightTargetersFreeWeight() const { return fightTargetersWeightMax() - fightTargetersWeight(); } - virtual float fightTargetersValue() const { return _FightTargetersValue; } - //@} - -private: - void setTarget(TTargetType type, TPtr const& target); - TPtr getTarget(TTargetType type) const; - - /// @name Targeter management - /// These functions are responsible to set/unset the actual _Target pointer in targeters - //@{ - void linkTargeter (TTargetType type, TPtr const& targeter, TPtr const& nextTargeter); - void unlinkTargeter (TTargetType type, TPtr const& targeter); - void addTargeter (TTargetType type, TPtr const& targeter); - void removeTargeter (TTargetType type, TPtr const& targeter); - void tryToAddTargeter(TTargetType type, TPtr const& targeter); - //@} - -private: - // Target stuff - uint32 _TargeterCount[TARGET_TYPE_MAX]; - TPtr _FirstTargeters[TARGET_TYPE_MAX]; - // Targeter stuff - TPtr _Target; - TTargetType _TargetType; - TPtr _NextTargeter; - - /// @name Fight management - //@{ - float _FightTargetersWeight; - float _FightTargetersValue; - //@} - -public: - static CKnapsackSolver::Algorithm _TargeterChoiceAlgorithm; -private: - static float const _DefaultFightTargetersWeightMax; - static float const _DefaultFightWeight; - static float const _DefaultFightValue; -}; - -class CPersistentOfPhysical : - public NLMISC::CDbgRefCount, - public CPersistent, - public CWorldMapLink -{ -public: - bool isAt16MetersPos(uint16 x, uint16 y) const; - - /// You must overload this access to cast the objet with a custom more proper type. ( you know what StepH meant? ) - CAIEntityPhysical* getSpawnObj() const; - - /// Retrieve an info string on the entity - virtual std::string getOneLineInfoString() const =0; -}; - -typedef std::vector > TPersistentList; - -////////////////////////////////////////////////////////////////////////////// -// CAIEntityPhysical // -////////////////////////////////////////////////////////////////////////////// - -// :KLUDGE: These should be in game_share -typedef uint32 TAllianceId; -typedef uint32 TAIAlias; - -class IAIEntityPhysicalHealer -{ -public: - virtual void healerAdded(CAIEntityPhysical* entity) = 0; - virtual void healerRemoved(CAIEntityPhysical* entity) = 0; -}; - -class CAIEntityPhysical; - -class CAIEntityPhysicalLocator -{ -public: - static CAIEntityPhysicalLocator* getInstance(); -private: - static CAIEntityPhysicalLocator* _Instance; - -public: - CAIEntityPhysical* getEntity(TDataSetRow const& row) const; - CAIEntityPhysical* getEntity(NLMISC::CEntityId const& id) const; - void addEntity(TDataSetRow const& row, NLMISC::CEntityId const& id, CAIEntityPhysical* entity); - void delEntity(TDataSetRow const& row, NLMISC::CEntityId const& id, CAIEntityPhysical* entity); -private: - std::map _EntitiesByRow; - std::map _EntitiesById; -}; - -/// CAIEntityPhysical is the common parent of bots, players and any other -/// physical objects that have an existence in the world. -class CAIEntityPhysical -: public NLMISC::CDbgRefCount -, public CAIEntity -, public CSpawnable -, public CTargetable -{ -public: - /// @name Constructor and destructor - //@{ - CAIEntityPhysical(CPersistentOfPhysical &owner, TDataSetRow const& entityIndex, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag const& AStarFlags); - virtual ~CAIEntityPhysical(); - //@} - - /// @name Accessors - //@{ - NLMISC::CEntityId const& getEntityId() const { return _id; } - float radius() const { return _radius; } - CAIPosMirror const& pos() const { return _pos; } - virtual CAIPos aipos() const { return CAIPos(_pos); } - CAICoord const& x() const { return _pos.x(); } - CAICoord const& y() const { return _pos.y(); } - sint32 h() const { return _pos.h(); } - CAngle theta() const { return _pos.theta(); } - float hpPercentage() const { return (float)currentHitPoints()/(float)maxHitPoints(); } - TDataSetRow const& dataSetRow() const { return _dataSetRow; } - uint32 level() const { return _Level; } - RYAI_MAP_CRUNCH::CWorldPosition const& wpos() const { return _wpos; } - void setWPos(RYAI_MAP_CRUNCH::CWorldPosition const& pos); - RYAI_MAP_CRUNCH::TAStarFlag const& getAStarFlag() const { return _AStarFlags; } - //@} - - /// @name Mirror accessors - //@{ - TYPE_CURRENT_HIT_POINTS currentHitPoints() const { return _CurrentHitPoint(); } - TYPE_MAX_HIT_POINTS maxHitPoints() const { return _MaxHitPoint(); } - TYPE_VISION_COUNTER currentVisionCounter() const { return _VisionCounter(); } - bool havePlayersAround() const; - - /// Return the alias of the outpost where the bot is, or 0 if outside of an outpost - TAIAlias outpostAlias() const { return _InOutpostAlias.getValue(); } - uint8 outpostSide() const { return _InOutpostSide.getValue(); } - - uint32 getInstanceNumber() const { return _instanceNumber(); }; - MBEHAV::EMode getMode() const { return (MBEHAV::EMode)_mode().Mode; } - MBEHAV::EBehaviour getBehaviour() const { return (MBEHAV::EBehaviour)_behaviour().Behaviour; } - bool isAlive() const { return getMode()!=MBEHAV::DEATH; } - - RYZOMACTIONFLAGS::TActionFlag getActionFlags() const { return (RYZOMACTIONFLAGS::TActionFlag)_ActionFlags(); } - void setActionFlags(RYZOMACTIONFLAGS::TActionFlag const& flag); - void removeActionFlags(RYZOMACTIONFLAGS::TActionFlag const& flag); - //@} - - /// @name Virtual accessors - //@{ - virtual bool isBotAttackable() const = 0; - - /// The returned type can be different from the type in the CEntityId (ex: pack_animal instead of creature for all player's mektoubs) - virtual RYZOMID::TTypeId getRyzomType() const = 0; - virtual float getCollisionDist(float angTo) const; - //@} - - /// @name Fighting - //@{ - virtual void processEvent(CCombatInterface::CEvent const& event) = 0; - //@} - - /// @name Effects - //@{ - // Food - float& food() { return _food; } - - // Stun cast - sint32& stun() { return _Stuned; } - bool isStuned() const { return _Stuned!=0; } - - sint32& root() { return _Rooted; } - bool isRooted() const { return _Rooted!=0; } - - sint32& blind() { return _Blinded; } - bool isBlinded() const { return _Blinded!=0; } - - sint32& fear() { return _Feared; } - bool isFeared() const { return _Feared!=0; } - //@} - - /// @name Movement - //@{ - virtual bool canMove() const; - float walkSpeed() const; - float runSpeed() const; - //@} - - /// @name Healer count management - //@{ - virtual void addHealer(IAIEntityPhysicalHealer* healer) { _Healers.insert(healer); if (healer) healer->healerAdded(this); } - virtual void delHealer(IAIEntityPhysicalHealer* healer) { _Healers.erase(healer); if (healer) healer->healerRemoved(this); } - virtual sint getHealerCount() { return (sint)_Healers.size(); } - //@} - - static int _PlayerVisibilityDistance; - - virtual sint32 getFame(std::string const& faction, bool modulated = false, bool returnUnknowValue = false) const; - virtual sint32 getFameIndexed(uint32 factionIndex, bool modulated = false, bool returnUnknowValue = false) const; - -protected: - virtual float getSpeedFactor() const { return 1.f; } - -protected: - friend class CFightFaunaProfile; - - // position and orientation (only changeable by bots). - CAIPosMirror _pos; - -private: - - // done to hide access except for CModEntityPhysical .. - friend class CModEntityPhysical; - - // entity index - for MIRRORS - TDataSetRow _dataSetRow; - - RYAI_MAP_CRUNCH::CWorldPosition _wpos; - - // instance number - CMirrorPropValue _instanceNumber; - - // generic visual properties - CMirrorPropValue _mode; - CMirrorPropValueRO _behaviour; - CMirrorPropValue _targetRow; - - CMirrorPropValueRO _RunSpeed; - CMirrorPropValueRO _WalkSpeed; - - CMirrorPropValueRO _CurrentHitPoint; - CMirrorPropValueRO _MaxHitPoint; - CMirrorPropValueRO _VisionCounter; - CMirrorPropValue _InOutpostAlias; - CMirrorPropValue _InOutpostSide; - - /// flags used by AI service to know the state of the entity - CMirrorPropValue _ActionFlags; - - sint32 _Stuned; // Is the bot stuned ? - sint32 _Rooted; // Is the bot rooted ? - sint32 _Blinded; // Is the bot blinded ? - sint32 _Feared; // Is the bot Feared ? - - NLMISC::CEntityId _id; - float _radius; - float _food; - - uint32 _Level; - - RYAI_MAP_CRUNCH::TAStarFlag _AStarFlags; - - std::multiset _Healers; -}; - -////////////////////////////////////////////////////////////////////////////// -// CModEntityPhysical // -////////////////////////////////////////////////////////////////////////////// - -class CModEntityPhysical -: public NLMISC::CDbgRefCount -, public CAIEntityPhysical -{ -public: - /// @name Constructor - //@{ - CModEntityPhysical(CPersistentOfPhysical& owner, TDataSetRow const& entityIndex, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag const& AStarFlags); - //@} - - /// @name Accessors (setters) - //@{ - virtual void setTheta(CAngle theta) { _pos.setTheta(theta); } - void setMode(MBEHAV::EMode m); - void setInstanceNumber(uint32 instanceNumber) { _instanceNumber = instanceNumber; }; - void setBehaviour(MBEHAV::EBehaviour b) { CMirrors::setBehaviour(dataSetRow(), b); } - - /// The AIS may set only the alias of the outpost where a bot is, or a character the EGS sets is - void setOutpostAlias(TAIAlias alias) { _InOutpostAlias = alias; } - /// - void setOutpostSide(OUTPOSTENUMS::TPVPSide side) { _InOutpostSide = (side==OUTPOSTENUMS::OutpostAttacker); } - //@} - - /// @name Targeting overrides - //@{ - virtual void targetDied() { _targetRow = TDataSetRow(); } - virtual void setTarget(CAIEntityPhysical* target); - virtual void setVisualTarget(CAIEntityPhysical* target); - virtual void setUnreachableTarget(CAIEntityPhysical* target); - //@} - - /// @name Movement - //@{ - /// Fast routine (but you must ensure that pos and wpos are related) - void setPos(CAIPos const& pos, RYAI_MAP_CRUNCH::CWorldPosition const& wpos); - /// Slow routine - bool setPos(CAIPos const& pos); - /// Set position - bool moveTo(CAIPos const& newPos, RYAI_MAP_CRUNCH::TAStarFlag const& denyFlags); - /// Change position - /// If this method is extracted from the class definition VC++ fails to instantiate it. - template - bool moveBy(W vect, RYAI_MAP_CRUNCH::TAStarFlag const& denyFlags) - { - if (!wpos().isValid()) - return false; - - CAIVector posVect(pos()); - posVect += vect; - - // first we try from the real position (not bound). - CAIPos destPos(posVect, h(), theta()); - return moveTo(destPos, denyFlags); - } - - /// Calculate the repulsion with other bots and players - CAIVector calcRepulsion(CAIPos const& pos) const; - bool calcStraightRepulsion(CAIPos const& pos, CAIVector& repulsion) const; - - void setMoveDecalage(CAIVector const& decalage) { _Decalage = decalage; } - CAIVector const& moveDecalage() const { return _Decalage; } - void resetDecalage(); - //@} - -private: - CAIVector calcRepulsionFrom(CAIVector const& pos, const std::vector& entities) const; - bool calcStraightRepulsionFrom(CAIVector const& pos, const std::vector& entities, CAIVector& repulsion) const; - -private: - CAIVector _Decalage; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_entity_physical_inline.h b/code/ryzom/server/src/ai_service/ai_entity_physical_inline.h deleted file mode 100644 index a865edb6f..000000000 --- a/code/ryzom/server/src/ai_service/ai_entity_physical_inline.h +++ /dev/null @@ -1,612 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef RYAI_ENTITY_PHYSICAL_INLINE_H -#define RYAI_ENTITY_PHYSICAL_INLINE_H - -#include "ai.h" -#include "game_share/fame.h" -/* - - The following base class is the common parent of bots, plrs and any other - physical object that has an existance in the world - -*/ - -////////////////////////////////////////////////////////////////////////////// -// CAIEntityPhysical // -////////////////////////////////////////////////////////////////////////////// - -#ifdef NL_OS_WINDOWS -#pragma warning (push) -#pragma warning (disable : 4355) -#endif - -inline -CAIEntityPhysical::CAIEntityPhysical(CPersistentOfPhysical& owner, TDataSetRow const& entityIndex, NLMISC::CEntityId const& id, float radius, uint32 level, RYAI_MAP_CRUNCH::TAStarFlag const& AStarFlags) -: CAIEntity() -, CSpawnable(owner) -, _pos(entityIndex) -, _dataSetRow(entityIndex) -, _Stuned(0) -, _Rooted(0) -, _Blinded(0) -, _Feared(0) -//, _UnreachableTarget((CAIEntityPhysical*)NULL) -, _id(id) -, _radius(radius) -, _food(_radius) -, _Level(level) -, _AStarFlags(AStarFlags) -{ - _instanceNumber.init(*CMirrors::DataSet, entityIndex, DSPropertyAI_INSTANCE); - _mode.init (*CMirrors::DataSet, entityIndex, DSPropertyMODE); - _behaviour.init (*CMirrors::DataSet, entityIndex, DSPropertyBEHAVIOUR); - _targetRow.init (*CMirrors::DataSet, entityIndex, DSPropertyTARGET_ID); - _ActionFlags.init (*CMirrors::DataSet, entityIndex, DSPropertyACTION_FLAGS); - - _RunSpeed.init (*CMirrors::DataSet, entityIndex, DSPropertyCURRENT_RUN_SPEED); - _WalkSpeed.init (*CMirrors::DataSet, entityIndex, DSPropertyCURRENT_WALK_SPEED); - - _CurrentHitPoint.init (*CMirrors::DataSet, entityIndex, DSPropertyCURRENT_HIT_POINTS); - _MaxHitPoint.init (*CMirrors::DataSet, entityIndex, DSPropertyMAX_HIT_POINTS); - _VisionCounter.init (*CMirrors::DataSet, entityIndex, DSPropertyVISION_COUNTER); - _InOutpostAlias.init (*CMirrors::DataSet, entityIndex, DSPropertyIN_OUTPOST_ZONE_ALIAS); - _InOutpostSide.init (*CMirrors::DataSet, entityIndex, DSPropertyIN_OUTPOST_ZONE_SIDE); - -#ifdef NL_DEBUG - const NLMISC::CDbgRefCount &ref=*(static_cast * const>(this)); - NLMISC::CDbgPtr dummyPtr; - - nlassert(ref.getDbgRef(dummyPtr)==0); - nlassert(CAIS::instance()._CAIEntityByDataSetRow.find(entityIndex.getIndex())==CAIS::instance()._CAIEntityByDataSetRow.end()); - ref.setCheckMax(false); -#endif - CAIS::instance()._CAIEntityByDataSetRow.insert(std::make_pair(entityIndex.getIndex(),this)); // we don't want to register players. -#ifdef NL_DEBUG - ref.setCheckMax(true); - nlassert(ref.getDbgRef(dummyPtr)==1); - nlassert(CAIS::instance()._CAIEntityByDataSetRow.find(entityIndex.getIndex())!=CAIS::instance()._CAIEntityByDataSetRow.end()); -#endif - - CAIEntityPhysicalLocator::getInstance()->addEntity(_dataSetRow, _id, this); -} - -inline -CAIEntityPhysical::~CAIEntityPhysical() -{ - CAIEntityPhysicalLocator::getInstance()->delEntity(_dataSetRow, _id, this); - -#ifdef NL_DEBUG - const NLMISC::CDbgRefCount &ref=*(static_cast * const>(this)); - NLMISC::CDbgPtr dummyPtr; -#endif - - // Remove healers - std::multiset::iterator it, itEnd; - for (it=_Healers.begin(), itEnd=_Healers.end(); it!=itEnd; ++it) - { - (*it)->healerRemoved(this); - } - - detachFromTargeting(); - CAIS::instance()._CAIEntityByDataSetRow.erase(dataSetRow().getIndex()); - -#ifdef NL_DEBUG - nlassert(ref.getDbgRef(dummyPtr)==0); - nlassert(CAIS::instance()._CAIEntityByDataSetRow.find(dataSetRow().getIndex())==CAIS::instance()._CAIEntityByDataSetRow.end()); -#endif -} - -#ifdef NL_OS_WINDOWS -#pragma warning (pop) -#endif - -inline -void CAIEntityPhysical::setActionFlags(RYZOMACTIONFLAGS::TActionFlag const& flag) -{ - _ActionFlags = (_ActionFlags.getValue() | flag ); -} - -inline -void CAIEntityPhysical::removeActionFlags(RYZOMACTIONFLAGS::TActionFlag const& flag) -{ - _ActionFlags = (_ActionFlags.getValue() & ~flag ); -} - -inline -float CAIEntityPhysical::getCollisionDist(float angTo) const -{ - return 0.5; -} - -inline -bool CAIEntityPhysical::canMove() const -{ - return !isRooted() && (walkSpeed() != 0); -} - -inline -float CAIEntityPhysical::walkSpeed() const -{ - return _WalkSpeed()*0.1f*SpeedFactor*getSpeedFactor(); -} - -inline -float CAIEntityPhysical::runSpeed() const -{ - return _RunSpeed()*0.1f*SpeedFactor*getSpeedFactor(); -} - -inline -void CAIEntityPhysical::setWPos(RYAI_MAP_CRUNCH::CWorldPosition const& pos) -{ - nlassert(pos.isValid()); - _wpos = pos; -} - -////////////////////////////////////////////////////////////////////////////// -// CPersistentOfPhysical // -////////////////////////////////////////////////////////////////////////////// - -inline -bool CPersistentOfPhysical::isAt16MetersPos(uint16 x, uint16 y) const -{ - CAIEntityPhysical const* phys = getSpawnObj(); - if (!phys) - return false; - return ( (uint16)(phys->x().asInt16Meters())==x - && (uint16)(phys->y().asInt16Meters())==y ); -} - -inline -CAIEntityPhysical* CPersistentOfPhysical::getSpawnObj() const -{ - return CPersistent::getSpawnObj(); -} - -////////////////////////////////////////////////////////////////////////////// -// CModEntityPhysical // -////////////////////////////////////////////////////////////////////////////// - -inline -void CModEntityPhysical::setMode(MBEHAV::EMode m) -{ - if (_mode().Mode == MBEHAV::DEATH) // to remove (can be replaced with the above assertion in debug mode). - return; - - if (_mode().Mode == m) - return; - _mode = MBEHAV::TMode(m, pos().x().asInt(), pos().y().asInt()); -} - -inline -void CModEntityPhysical::setTarget(CAIEntityPhysical* target) -{ - CTargetable::setTarget(target); -// if (CTargetable::getTarget()==target) - const CAIEntityPhysical* tgt=CTargetable::getTarget(); - if (tgt==target) - _targetRow = target ? target->dataSetRow() : TDataSetRow(); -} - -inline -void CModEntityPhysical::setVisualTarget(CAIEntityPhysical* target) -{ - CTargetable::setVisualTarget(target); -// if (CTargetable::getVisualTarget()==target) - const CAIEntityPhysical* tgt=CTargetable::getVisualTarget(); - if (tgt==target) - _targetRow = target ? target->dataSetRow() : TDataSetRow(); -} - -inline -void CModEntityPhysical::setUnreachableTarget(CAIEntityPhysical* target) -{ - CTargetable::setUnreachableTarget(target); -// if (CTargetable::getUnreachableTarget()==target) - const CAIEntityPhysical* tgt=CTargetable::getUnreachableTarget(); - if (tgt==target) - _targetRow = target ? target->dataSetRow() : TDataSetRow(); -} - -inline -bool CModEntityPhysical::setPos(CAIPos const& pos) -{ - RYAI_MAP_CRUNCH::CWorldPosition wpos; - if (!CWorldContainer::getWorldMap().setWorldPosition(AITYPES::vp_auto, wpos,pos)) - return false; - setPos(pos, wpos); - return true; -} - -inline -bool CModEntityPhysical::moveTo(CAIPos const& newPos, RYAI_MAP_CRUNCH::TAStarFlag const& denyFlags) -{ - if (!wpos().isValid()) - return false; - - RYAI_MAP_CRUNCH::CWorldPosition tmpWPos(wpos()); - if (CWorldContainer::getWorldMap().move(tmpWPos, RYAI_MAP_CRUNCH::CMapPosition(newPos), denyFlags)) - { -#ifdef NL_DEBUG - nlassert(RYAI_MAP_CRUNCH::CMapPosition(newPos)==tmpWPos); -#endif - setPos(newPos, tmpWPos); - return true; - } - else - { - // a part of move has been done. - if (tmpWPos!=wpos()) - { - CAIPos partNewPos(tmpWPos.toAIVector(),newPos.h(),newPos.theta()); - setPos(partNewPos, tmpWPos); - return true; - } - - } - // no move at all.. - return false; -}; - -inline -void CModEntityPhysical::resetDecalage() -{ - _Decalage.setXY(0, 0); -} - -////////////////////////////////////////////////////////////////////////////// -// CWorldMapLink // -////////////////////////////////////////////////////////////////////////////// - -template -void CWorldMapLink::linkEntityToMatrix(const CAICoord &x,const CAICoord &y,CAIEntityMatrix& matrix) -{ - _matrixListLink.link(matrix[(uint8)(y.asInt16Meters())][(uint8)(x.asInt16Meters())]); -} - -template -void CWorldMapLink::linkEntityToMatrix(const CAIVectorMirror &pos,CAIEntityMatrix& matrix) -{ - linkEntityToMatrix(pos.x(),pos.y(),matrix); -} - -template -void CWorldMapLink::linkEntityToMatrix(const CAIVector &pos,CAIEntityMatrix& matrix) -{ - linkEntityToMatrix(pos.x(),pos.y(),matrix); -} - -template -void CWorldMapLink::linkToWorldMap(T *entityPtr, const CAIVector &pos,CAIEntityMatrix& matrix) -{ - _matrixListLink.setEntity (entityPtr); - linkEntityToMatrix (pos,matrix); -} - -template -void CWorldMapLink::linkToWorldMap(T *entityPtr, const CAIVectorMirror &pos,CAIEntityMatrix& matrix) -{ - _matrixListLink.setEntity (entityPtr); - linkEntityToMatrix (pos,matrix); -} - -////////////////////////////////////////////////////////////////////////////// -// CTargetable // -////////////////////////////////////////////////////////////////////////////// - -template -CTargetable::CTargetable() -: _FightTargetersWeight(0.f) -, _FightTargetersValue(0.f) -{ - for (size_t i=0; i -CTargetable::~CTargetable() -{ - // This should be done in Derived class dtor, but just in case of since we're instanciable - detachFromTargeting(); -} - -template -void CTargetable::detachFromTargeters() -{ - for (size_t i=0; itargetDied(); - // This method is a bit more intrusive than targeter->setTarget(NULL), but it avoids possible infinite loops - _FirstTargeters[i] = targeter->_NextTargeter; - unlinkTargeter((TTargetType)i, targeter); - } - } -} - -template -void CTargetable::detachFromTargeting() -{ - setTarget((T*)NULL); - detachFromTargeters(); -} - -template -void CTargetable::linkTargeter(TTargetType type, TPtr const& targeter, TPtr const& nextTargeter) -{ - ++_TargeterCount[type]; - if (type==TARGET_TYPE_FIGHT) - { - _FightTargetersWeight += targeter->fightWeight(); - _FightTargetersValue += targeter->fightValue(); - } - targeter->_Target = dynamic_cast(this); - targeter->_TargetType = type; - targeter->_NextTargeter = nextTargeter; - // Some verifications to avoid algorithm bugs -// nlassert(fightTargetersFreeWeight()>=-0.00001f); - nlassert(!targeter->_Target.isNULL()); -} - -template -void CTargetable::unlinkTargeter(TTargetType type, TPtr const& targeter) -{ -#ifdef NL_DEBUG - nlassert((T*)targeter->_Target == this); -#else - if ((T*)targeter->_Target != this) - nlwarning("Targeter's target is not me!"); -#endif - targeter->_Target = (T*)NULL; - targeter->_NextTargeter = (T*)NULL; - --_TargeterCount[type]; - if (type==TARGET_TYPE_FIGHT) - { - _FightTargetersWeight -= targeter->fightWeight(); - _FightTargetersValue -= targeter->fightValue(); - } -} - -template -void CTargetable::addTargeter(TTargetType type, TPtr const& targeter) -{ - linkTargeter(type, targeter, _FirstTargeters[type]); - _FirstTargeters[type] = targeter; -} - -template -void CTargetable::removeTargeter(TTargetType type, TPtr const& targeter) -{ - if (targeter.isNULL()) - return; - if (_FirstTargeters[type] == targeter) - { - _FirstTargeters[type] = targeter->_NextTargeter; - unlinkTargeter(type, targeter); - return; - } - - NLMISC::CDbgPtr current = _FirstTargeters[type]; - while (!current.isNULL()) - { - NLMISC::CDbgPtr next = current->_NextTargeter; - if (next == targeter) - { - current->_NextTargeter = targeter->_NextTargeter; - unlinkTargeter(type, targeter); - break; - } - else - { - current = next; - } - } -} - -template -void CTargetable::tryToAddTargeter(TTargetType type, TPtr const& targeter) -{ - H_AUTO(CTargetable_addTargeter); - - if (type==TARGET_TYPE_FIGHT) - { - - // Prepare data to optimize ---------------------------------------------- - size_t opponentCount = targeterCount(); - // Allocate arrays filled with 0.f - float* weights = new float[opponentCount+1]; - float* values = new float[opponentCount+1]; - bool* take = new bool[opponentCount+1]; - for (size_t i=0; ifightWeight(); - values[i] = opponent->fightValue(); - opponent = opponent->nextTargeter(); - take[i] = true; - ++i; - } - // Add the new targeter - weights[opponentCount] = targeter->fightWeight(); - values[opponentCount] = targeter->fightValue(); - take[opponentCount] = false; - } - // Create the context - CKnapsackContext context(opponentCount+1, weights, values); - // Configure and run the solver ------------------------------------------ - CKnapsackSolver solver(&context, take); - { - H_AUTO(addTargeterOptimize); - solver.optimize(fightTargetersWeightMax(), _TargeterChoiceAlgorithm); - } - // Save the data --------------------------------------------------------- - // If the new set is better than the old one - if (solver.totalValue()>fightTargetersValue()) - { - // Unlink the old ones if needed - T* opponent = _FirstTargeters[type]; - TPtr* previousPtr = &_FirstTargeters[type]; - size_t i = 0; - while (opponent!=NULL) - { - if (!solver.take(i)) - { - *previousPtr = opponent->_NextTargeter; - unlinkTargeter(type, opponent); - } - else - { - previousPtr = &opponent->_NextTargeter; - opponent = opponent->_NextTargeter; - } - ++i; - } - // Link the new targeter if needed - if (solver.take(opponentCount)) - { - addTargeter(type, targeter); - } -#ifdef NL_DEBUG - // Debug verifications - { - opponent = _FirstTargeters[type]; - float value = 0.f; - float weight = 0.f; - while (opponent!=NULL) - { - value += opponent->fightValue(); - weight += opponent->fightWeight(); - opponent = opponent->_NextTargeter; - } - // Verify linking system - nlassert(fabs(fightTargetersValue() - value) < 0.0001); - nlassert(fabs(fightTargetersWeight() - weight) < 0.0001); - - // Verify solver behaviour - nlassert(fabs(fightTargetersValue() - solver.totalValue()) < 0.0001); - nlassert(fabs(fightTargetersWeight() - solver.totalWeight()) < 0.0001); - } -#endif - } - delete [] take; - delete [] values; - delete [] weights; - - } - else - { - // Just link the new targeter (no limit on visual targeters) - addTargeter(type, targeter); - } -} - -template -void CTargetable::setTarget(T* target) -{ - setTarget(TARGET_TYPE_FIGHT, target); -} - -template -void CTargetable::setVisualTarget(T* target) -{ - setTarget(TARGET_TYPE_VISUAL, target); -} - -template -void CTargetable::setUnreachableTarget(T* target) -{ - setTarget(TARGET_TYPE_UNREACHABLE, target); -} - -template -void CTargetable::setTarget(TTargetType type, TPtr const& target) -{ - if (target==_Target && type==_TargetType) - return; - - if (!_Target.isNULL()) - { - _Target->removeTargeter(_TargetType, dynamic_cast(this)); - } - if (!target.isNULL()) - { - target->tryToAddTargeter(type, dynamic_cast(this)); - } -} - -template -typename CTargetable::TPtr CTargetable::getTarget() const -{ - return getTarget(TARGET_TYPE_FIGHT); -} - -template -typename CTargetable::TPtr CTargetable::getVisualTarget() const -{ - return getTarget(TARGET_TYPE_VISUAL); -} - -template -typename CTargetable::TPtr CTargetable::getUnreachableTarget() const -{ - return getTarget(TARGET_TYPE_UNREACHABLE); -} - -template -typename CTargetable::TPtr CTargetable::getTarget(TTargetType type) const -{ - if (_TargetType==type) - return _Target; - else - return (T*)NULL; -} - -template -uint32 CTargetable::totalTargeterCount() const -{ - uint32 count = 0; - for (size_t i = 0; i -// 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 . - - - -#ifndef AI_FACTORY_H -#define AI_FACTORY_H - -#include -#include - - -template -class IAiFactory - :public NLMISC::CDbgRefCount > -{ -public: - virtual BaseClass *createObject(const typename BaseClass::CtorParam& ctorParam) = 0; -}; - - -template -class CAiFactoryContainer -{ - typedef std::map > > TRegisterCont; - -public: - - static CAiFactoryContainer &instance() - { - if (!_Instance) - { - _Instance = new CAiFactoryContainer(); - } - return *_Instance; - } - - virtual ~CAiFactoryContainer() - { - } - - void release() - { - delete this; - _Instance = NULL; - } - - void registerFactory(const KeyType &key, IAiFactory *factoryRegister) - { - nlassert(_FactoryRegisters.find(key) == _FactoryRegisters.end()); - _FactoryRegisters.insert(std::make_pair(key, factoryRegister)); - } - - - IAiFactory* getFactory (const KeyType &key) - { - typename TRegisterCont::iterator it (_FactoryRegisters.find(key)); - if (it!=_FactoryRegisters.end()) - return it->second; - return NULL; - } - -protected: - static CAiFactoryContainer *_Instance; -private: - TRegisterCont _FactoryRegisters; -}; - - -template -class CAiFactory : public IAiFactory -{ -public: - CAiFactory () - { - } - - BaseClass *createObject(const typename BaseClass::CtorParam& ctorParam) - { - return new SpecializedClass(ctorParam); - } -}; - -///////////////////////////////////////////////////////// -// Factory indirect - -template -class IAiFactoryIndirectRegister -{ -public: - virtual BaseFactoryClass *getFactory() = 0; -}; - - - -template -class CAiFactoryIndirect -{ - typedef std::map*> TRegisterCont; - -public: - static CAiFactoryIndirect &instance() - { - if (!_Instance) - { - _Instance = new CAiFactoryIndirect(); - } - return *_Instance; - } - - void registerClass(const KeyType &key, IAiFactoryIndirectRegister *factoryRegister) - { - nlassert(_FactoryRegisters.find(key) == _FactoryRegisters.end()); - _FactoryRegisters.insert(std::make_pair(key, factoryRegister)); - } - - BaseFactoryClass *getFactory(const KeyType &key) - { - typename TRegisterCont::const_iterator it (_FactoryRegisters.find(key)); - if (it == _FactoryRegisters.end()) - return NULL; - else - return it->second->getFactory(); - } -private: - static CAiFactoryIndirect *_Instance; - - TRegisterCont _FactoryRegisters; -}; - - -template -class CAiFactoryIndirectRegister : public IAiFactoryIndirectRegister -{ - SpecializedFactoryClass _FactoryClass; -public: - CAiFactoryIndirectRegister(const KeyType &key) - { - IndirectFactoryClass::instance().registerClass(key, this); - } - - BaseFactoryClass *getFactory() - { - return &_FactoryClass; - } -}; - -#define RYAI_IMPLEMENT_FACTORY_INDIRECT(baseFactoryClass, keyType) template <> CAiFactoryIndirect *CAiFactoryIndirect::_Instance = NULL - -#define RYAI_REGISTER_FACTORY(baseFactoryClass, specializedFactoryClass, keyType, keyValue) CAiFactoryIndirectRegister, baseFactoryClass, specializedFactoryClass, keyType> RegisterIndirect##specializedFactoryClass(keyValue) -#define RYAI_DECLARE_FACTORY(baseFactoryClass, specializedFactoryClass, keyType) extern CAiFactoryIndirectRegister, baseFactoryClass, specializedFactoryClass, keyType> RegisterIndirect##specializedFactoryClass - -#define RYAI_GET_FACTORY(specializedFactoryClass) RegisterIndirect##specializedFactoryClass.getFactory() - -#endif // FACTORY_H diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp b/code/ryzom/server/src/ai_service/ai_generic_fight.cpp deleted file mode 100644 index c88a93b8f..000000000 --- a/code/ryzom/server/src/ai_service/ai_generic_fight.cpp +++ /dev/null @@ -1,698 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "ai_generic_fight.h" -#include "ai_player.h" -#include "server_share/msg_brick_service.h" -#include "ai_profile_npc.h" - -extern bool simulateBug(int bugId); - -RYZOMID::TTypeId ai_generic_fight_debugCheckedType = RYZOMID::unknown; -#define debugCheckedType ai_generic_fight_debugCheckedType - -RYAI_REGISTER_PROFILE_FACTORY(CBotProfileFleeFactory, "bot_flee"); -RYAI_REGISTER_PROFILE_FACTORY(CBotProfileFightFactory, "bot_fight"); - -using namespace NLMISC; -//using namespace std; - -std::string CBotProfileFlee::getOneLineInfoString() const -{ - return std::string("flee profile: bot="+_Bot->dataSetRow().toString()+" "+CMirrors::getEntityId(_Bot->dataSetRow()).toString()); -} - -std::string CBotProfileFight::getOneLineInfoString() const -{ - return std::string("fight profile: bot="+_Bot->dataSetRow().toString()+" ennemy="+_Ennemy->dataSetRow().toString()+", Hitting: "+toString(isHitting())+" SearchPath: "+toString(_SearchAlternativePath)); -} - -std::string CBotProfileHeal::getOneLineInfoString() const -{ - return std::string("heal profile: bot="+_Row.toString()+" "+CMirrors::getEntityId(_Row).toString()+", Hitting: "+toString(isHitting())+" SearchPath: "+toString(_SearchAlternativePath)); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFight // -////////////////////////////////////////////////////////////////////////////// - -void CBotProfileFight::beginProfile() -{ - _Engaged = false; - _Bot->setTarget(_Ennemy); - eventBeginFight (); -} - -void CBotProfileFight::resumeProfile() -{ - _Engaged = false; - _Bot->setTarget(_Ennemy); -} - -CBotProfileFight::CBotProfileFight(CProfileOwner* owner, CAIEntityPhysical* ennemy) -: CBotProfileFightHeal() -, _Bot(NLMISC::safe_cast(owner)) -, _Ennemy(ennemy) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _PathCont(NLMISC::safe_cast(owner)->getAStarFlag()) -, _RangeCalculated(false) -, _SearchAlternativePath(false) -{ -#ifdef NL_DEBUG_PTR - _Bot.setData(this); -#endif -} - -CBotProfileFight::~CBotProfileFight() -{ - if ( _Bot.isNULL() - || _Bot->isAlive()) - return; - - AISHEETS::ICreature::TScriptCompList const& scriptList = _Bot->getPersistent().getSheet()->DeathScriptList(); - FOREACHC(it, AISHEETS::ICreature::TScriptCompList, scriptList) - (*it)->update(*_Bot); -} - -float CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_MAX] = { 0.5f, 80.f, 80.f, 80.f }; -float CBotProfileFightHeal::fightDefaultMinRange = 0.01f; -float CBotProfileFightHeal::fightDefaultMaxRange = 0.5f; -float CBotProfileFightHeal::fightMeleeMinRange = 0.01f; -float CBotProfileFightHeal::fightMeleeMaxRange = 0.5f; -float CBotProfileFightHeal::fightRangeMinRange = 0.4f; -float CBotProfileFightHeal::fightRangeMaxRange = 80.f; -float CBotProfileFightHeal::fightMixedMinRange = 0.01f; -float CBotProfileFightHeal::fightMixedMaxRange = 45.f; -float CBotProfileFightHeal::giveUpDistance = 100.f; -bool CBotProfileFightHeal::fleeUnreachableTargets = true; - - -NLMISC_COMMAND(fightMeleeDist, "Generic fight melee attack range","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_MELEE] = (float)atof(args[0].c_str()); - log.displayNL("Melee fight range is %f", CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_MELEE]); - return true; -} -NLMISC_COMMAND(fightRangeDist, "Generic fight range attack range","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_RANGE] = (float)atof(args[0].c_str()); - log.displayNL("Range fight range is %f", CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_RANGE]); - return true; -} -NLMISC_COMMAND(fightNukeDist, "Generic fight nuke attack range","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_NUKE] = (float)atof(args[0].c_str()); - log.displayNL("Nuke fight range is %f", CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_NUKE]); - return true; -} -NLMISC_COMMAND(fightHealDist, "Generic fight heal range","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_HEAL] = (float)atof(args[0].c_str()); - log.displayNL("Heal fight range is %f", CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_HEAL]); - return true; -} -NLMISC_COMMAND(fightDefaultRange, "Generic default fight range","") -{ - if (args.size()==0 || args.size()==2) - { - if (args.size()==2) - { - NLMISC::fromString(args[0], CBotProfileFightHeal::fightDefaultMinRange); - NLMISC::fromString(args[1], CBotProfileFightHeal::fightDefaultMaxRange); - } - log.displayNL("Generic default fight range is [%f;%f]", CBotProfileFightHeal::fightDefaultMinRange, CBotProfileFightHeal::fightDefaultMaxRange); - return true; - } - return false; -} -NLMISC_COMMAND(fightMeleeRange, "Generic melee fight range","") -{ - if (args.size()==0 || args.size()==2) - { - if (args.size()==2) - { - CBotProfileFightHeal::fightMeleeMinRange = (float)atof(args[0].c_str()); - CBotProfileFightHeal::fightMeleeMaxRange = (float)atof(args[1].c_str()); - } - log.displayNL("Generic melee fight range is [%f;%f]", CBotProfileFightHeal::fightMeleeMinRange, CBotProfileFightHeal::fightMeleeMaxRange); - return true; - } - return false; -} -NLMISC_COMMAND(fightRangeRange, "Generic range fight range","") -{ - if (args.size()==0 || args.size()==2) - { - if (args.size()==2) - { - CBotProfileFightHeal::fightRangeMinRange = (float)atof(args[0].c_str()); - CBotProfileFightHeal::fightRangeMaxRange = (float)atof(args[1].c_str()); - } - log.displayNL("Generic range fight range is [%f;%f]", CBotProfileFightHeal::fightRangeMinRange, CBotProfileFightHeal::fightRangeMaxRange); - return true; - } - return false; -} -NLMISC_COMMAND(fightMixedRange, "Generic mixed fight range","") -{ - if (args.size()==0 || args.size()==2) - { - if (args.size()==2) - { - CBotProfileFightHeal::fightMixedMinRange = (float)atof(args[0].c_str()); - CBotProfileFightHeal::fightMixedMaxRange = (float)atof(args[1].c_str()); - } - log.displayNL("Generic mixed fight range is [%f;%f]", CBotProfileFightHeal::fightMixedMinRange, CBotProfileFightHeal::fightMixedMaxRange); - return true; - } - return false; -} -NLMISC_COMMAND(fightGiveUpDistance, "Generic fight give up distance","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFightHeal::giveUpDistance = (float)atof(args[0].c_str()); - log.displayNL("Give up distance is %f", CBotProfileFightHeal::giveUpDistance); - return true; -} -NLMISC_COMMAND(fleeUnreachableTargets, "Tells if creatures flee an unreachable player","") -{ - if(args.size()>1) return false; - if(args.size()==1) - { - bool b; - fromString(args[0], b); - CBotProfileFightHeal::fleeUnreachableTargets = b; - } - log.displayNL("Creatures do%s flee unreachable targets", CBotProfileFightHeal::fleeUnreachableTargets?"":" not"); - return true; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHeal // -////////////////////////////////////////////////////////////////////////////// - -void CBotProfileHeal::beginProfile() -{ - _Engaged=false; - _Bot->setTarget(CAIS::instance().getEntityPhysical(_Row)); - // eventBeginFight(); // :TODO: Reactivate this -} - -void CBotProfileHeal::resumeProfile() -{ - _Engaged=false; - _Bot->setTarget(CAIS::instance().getEntityPhysical(_Row)); -} - -CBotProfileHeal::CBotProfileHeal(const TDataSetRow &row, CProfileOwner *owner) -: CBotProfileFightHeal() -, _Bot(NLMISC::safe_cast(owner)) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _PathCont(NLMISC::safe_cast(owner)->getAStarFlag()) -, _Row(row) -, _RangeCalculated(false) -, _SearchAlternativePath(false) -{ -} - -CBotProfileHeal::~CBotProfileHeal() -{ - if ( _Bot.isNULL() - || _Bot->isAlive()) - return; - - AISHEETS::ICreature::TScriptCompList const& scriptList = _Bot->getPersistent().getSheet()->DeathScriptList(); - for (AISHEETS::ICreature::TScriptCompList::const_iterator it=scriptList.begin(), itEnd=scriptList.end(); it!=itEnd; ++it) - (*it)->update(*_Bot); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFlee // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileFlee::CBotProfileFlee(CProfileOwner *owner) -: CAIBaseProfile() -, _DenyFlags(NLMISC::safe_cast(owner)->getAStarFlag()) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _fightFleePathContainer(NLMISC::safe_cast(owner)->getAStarFlag()) -, _Bot(NLMISC::safe_cast(owner)) -{ -} - -CBotProfileFlee::~CBotProfileFlee() -{ -} - -void CBotProfileFlee::beginProfile() -{ - _LastDir = RYAI_MAP_CRUNCH::CDirection(RYAI_MAP_CRUNCH::CDirection::UNDEFINED); -} - -void CBotProfileFlee::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(BotFleeProfileUpdate); - CFollowPathContext fpcBotFleeProfileUpdate("BotFleeProfileUpdate"); - - if (!_Bot->getUnreachableTarget().isNULL()) - { - CAIVector delta = CAIVector(_Bot->getUnreachableTarget()->aipos()); - delta -= CAIVector(_Bot->pos()); - if (delta.quickNorm()>giveUpDistanceUnreachable) - _Bot->setUnreachableTarget((CAIEntityPhysical*)NULL); - } - if (!_Bot->canMove()) - return; - - bool calcDone=true; - - CAIVector fleeVector(_Bot->moveDecalage()); - _Bot->resetDecalage(); - if (fleeVector.isNull()) - fleeVector.setX(1+fleeVector.x()); // hum .. - RYAI_MAP_CRUNCH::CDirection startDir(fleeVector.x(), fleeVector.y(), true); - - // if we need to change our destination. - if ( startDir!=_LastDir - || !_LastStartPos.hasSameFullCellId(_Bot->wpos())) - { - const RYAI_MAP_CRUNCH::CWorldMap &worldMap=CWorldContainer::getWorldMap(); - calcDone=false; - - for (sint nbStep=0;nbStep<8;nbStep++) - { - // try to find a direction around startDir. - RYAI_MAP_CRUNCH::CDirection dir(startDir); - dir.addStep((RYAI_MAP_CRUNCH::CDirection::TDeltaDirection) ((nbStep&1)?(nbStep>>1):(-(nbStep>>1)))); - - const RYAI_MAP_CRUNCH::CRootCell *rootCell=worldMap.getRootCellCst(_Bot->wpos().stepCell(dir.dx(),dir.dy())); - if (rootCell) - { - RYAI_MAP_CRUNCH::CWorldPosition wpos=rootCell->getWorldPosition(_Bot->getPersistent().getChildIndex()&3); - if ( wpos.isValid() - && (wpos.getFlags()&_DenyFlags)==0 ) // verify that we got some compatible flags .. - { - _LastDir=startDir; - _LastStartPos=_Bot->wpos(); - - calcDone=true; - _fightFleePathContainer.setDestination(/*AITYPES::vp_auto, */wpos); - break; - } - - } - - } - - } - - // if we found somewhere to go, then go there .. - if (calcDone) - { - float dist=_Bot->runSpeed()*ticksSinceLastUpdate; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _fightFleePathContainer, - dist, - dist*.71f, - .5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - // :KLUDGE: Warning has been removed to avoid flooding, without solving the problem -// nlwarning("Flee problem with destination properties (Water, Nogo)"); - // :TODO: Rework that case - _LastDir=RYAI_MAP_CRUNCH::CDirection(RYAI_MAP_CRUNCH::CDirection::UNDEFINED); - } - } - else - { - _LastDir=RYAI_MAP_CRUNCH::CDirection(RYAI_MAP_CRUNCH::CDirection::UNDEFINED); - } - -} - -float CBotProfileFlee::giveUpDistanceUnreachable = 75.f; - -NLMISC_COMMAND(fleeGiveUpDistanceUnreachable, "Generic flee give up distance when fleeing an unreachable player","") -{ - if(args.size()>1) return false; - if(args.size()==1) CBotProfileFlee::giveUpDistanceUnreachable = (float)atof(args[0].c_str()); - log.displayNL("Give up distance is %f", CBotProfileFlee::giveUpDistanceUnreachable); - return true; -} - -////////////////////////////////////////////////////////////////////////////// -// CFightOrganizer // -////////////////////////////////////////////////////////////////////////////// - -CFightOrganizer::CFightOrganizer() -: _HaveEnnemy(true) -{ -} - -bool CFightOrganizer::healIteration(CBot* bot, CBot* otherBot) -{ - if (bot && otherBot) - { - CSpawnBot* spBot = bot->getSpawnObj(); - CSpawnBot* otherSpBot = otherBot->getSpawnObj(); - if (spBot && otherSpBot && otherSpBot->isAlive()) - { - float hp = otherSpBot->hpPercentage(); - int neededHealers = 0; - if (hp<.90f) ++neededHealers; - if (hp<.75f) ++neededHealers; - if (hp<.50f) ++neededHealers; - if (hp<.25f) ++neededHealers; - if (neededHealers > otherSpBot->getHealerCount()) - { - IAIProfile* profile = spBot->getAIProfile(); - AITYPES::TProfiles profileType = profile?profile->getAIProfileType():AITYPES::BAD_TYPE; - if (profileType!=AITYPES::BOT_HEAL) - setHeal(spBot, otherSpBot); - spBot->setTarget(otherSpBot); - return true; - } - } - } - return false; -} - -bool CFightOrganizer::reorganizeIteration(CBot* bot) -{ - CSpawnBot *spawnBot=bot->getSpawnObj(); - if ( !spawnBot - || !spawnBot->isAlive ()) - return true; - - IAIProfile *profile=spawnBot->getAIProfile(); - AITYPES::TProfiles profileType=profile?profile->getAIProfileType():AITYPES::BAD_TYPE; - - // special comp if feared bypass every other comp .. (panic mode !) - if (spawnBot->isFeared()) - { - CAIVector fleeVect; - CAIEntityPhysical* aggroer = spawnBot->firstVisualTargeter(); - while (aggroer!=NULL) - { - CAIVector delta(spawnBot->aipos()); - delta -= aggroer->aipos(); - fleeVect += delta; - aggroer = aggroer->nextTargeter(); - } - - CAIS& inst = CAIS::instance(); - - FOREACHC(itEntry, CBotAggroOwner::TBotAggroList, spawnBot->getBotAggroList()) - { - CAIEntityPhysical* const phys = inst.getEntityPhysical(itEntry->second->getBot()); - if (!phys) - continue; - CAIVector delta(spawnBot->aipos()); - delta -= phys->aipos(); - fleeVect += delta; - } - - fleeVect.normalize(1000); - CAIVector toGroup = spawnBot->spawnGrp().getCenterPos(); - toGroup -= spawnBot->aipos(); - toGroup.normalize(1000); - fleeVect += toGroup; - // :TODO: Uncomment following line and test extensively (may reduce flee speed or dist, but is more correct) - // toGroup.normalize(1000); - setFlee(spawnBot, fleeVect); - return true; - } - // special comp if healer bypass every other comp - if (profileType==AITYPES::BOT_HEAL) - { - CBotProfileHeal* healProfile = NLMISC::safe_cast(profile); - if (healProfile->isHitting()) - { - _HaveEnnemy = true; - return true; - } - } - if (bot->isHealer()) - { - CGroup* group = bot->getOwner(); - CBot* otherBot = NULL; - CSpawnBot* otherSp = NULL; - // Heal leader - if (spawnBot->canHeal() && healIteration(bot, group->getSquadLeader(true))) - return true; - // Heal self - if (spawnBot->canSelfHeal() && healIteration(bot, bot)) - return true; - // Heal healers - if (spawnBot->canHeal()) - { - FOREACH(itBot, CCont, group->bots()) - { - if (*itBot && bot!=*itBot && (*itBot)->isHealer()) - if (healIteration(bot, *itBot)) - return true; - } - } - // Heal others - if (spawnBot->canHeal()) - { - FOREACH(itBot, CCont, group->bots()) - { - if (*itBot && bot!=*itBot) - if (healIteration(bot, *itBot)) - return true; - } - } - } - - if (profileType==AITYPES::BOT_FIGHT) - { - CBotProfileFight *fightProfile=NLMISC::safe_cast(profile); - if (fightProfile->isHitting()) - { - _HaveEnnemy=true; - return true; - } - - } - - std::vector botList; - AISHEETS::ICreatureCPtr botSheet = bot->getSheet(); - - float grpAggroCoef = 0.5f*botSheet->GroupCohesionModulator(); - - spawnBot->updateListAndMarkBot(botList, 1.f-grpAggroCoef); - - // unmarkBot list and choose target. - double BestChooseScore=0; //botSheet.ScoreModulator; - - CAIEntityPhysical * ennemy = NULL; - CAIEntityPhysical const * fleeEnnemy = NULL; - double BestFleeScore=0; //botSheet.FearModulator; - - CAIVector movingVector; - double fear=1.0f; - - CAIEntityPhysical* target = (CAIEntityPhysical*)spawnBot->getTarget(); - - FOREACH(it, std::vector, botList) - { - CAIEntityPhysical *const entity=(*it); - - if (!entity->isAlive()) - { - if (ai_profile_npc_VerboseLog) - { - nldebug("Entity %s have aggro for dead entity %s, forgetting it.", spawnBot->getEntityId().toString().c_str(), entity->getEntityId().toString().c_str()); - } - - spawnBot->forgetAggroFor(entity->dataSetRow()); - continue; - } - if (!entity->isBotAttackable()) - { - if (ai_profile_npc_VerboseLog) - { - nldebug("Entity %s have aggro for non bot attackable entity %s, forgetting it.", spawnBot->getEntityId().toString().c_str(), entity->getEntityId().toString().c_str()); - } - - spawnBot->forgetAggroFor(entity->dataSetRow()); - continue; - } - - // is there a problem. - if (entity->_AggroScore>0) - { - CAIVector targetToPos(spawnBot->aipos()); - targetToPos -= entity->aipos(); - - double slotCoef; - { - // 1 near - 0 far. - slotCoef = 1.f/(1.f+targetToPos.quickNorm()*botSheet->DistModulator()); // melee consideration. (don't know correct dist for caster or range may be in munition sheet !?). - - if (((CAIEntityPhysical*)entity->getTarget())!=spawnBot) - { - int nbOtherTargeter = entity->targeterCount(); - if (entity==((CAIEntityPhysical*)spawnBot->getTarget())) - --nbOtherTargeter; - float targetCoef = 1.f/(1.f+nbOtherTargeter*nbOtherTargeter*botSheet->TargetModulator()); - slotCoef *= targetCoef; - } - slotCoef *= entity->getFreeFightSpaceRatio(); - } - -////////////////////////////////////////////////////////////////////////////// - - float score = (float)(entity->_AggroScore*slotCoef); - - if (target && target->getRyzomType() == RYZOMID::player) - { - if (entity != target) - { - CBotPlayer const* const ptarget = NLMISC::safe_cast(target); - if (entity->getRyzomType() == RYZOMID::player) - { - CBotPlayer const* const player = NLMISC::safe_cast(entity); - if ( ptarget && player && spawnBot->getAggroFor(entity->dataSetRow()) <= spawnBot->getAggroFor(ptarget->dataSetRow()) && ( - ptarget->getCurrentTeamId() == CTEAM::InvalidTeamId || - player->getCurrentTeamId() == CTEAM::InvalidTeamId || - player->getCurrentTeamId() != ptarget->getCurrentTeamId() - ) - ) - { - score = 0; - } - } - } - } - - if (score>=BestChooseScore) // add distance and bot profile compatibility. - { - BestChooseScore=score; - ennemy=entity; - } - } - entity->_ChooseLastTime = std::numeric_limits::max(); - } - - if (fleeEnnemy==NULL && !spawnBot->getUnreachableTarget().isNULL()) - { - fleeEnnemy = spawnBot->getUnreachableTarget(); - } - - if (ennemy) - { - _HaveEnnemy=true; - nlassert(ennemy->getRyzomType()!=debugCheckedType); - if (target == ennemy) - { - return true; - } - - // set the correct profile, if its not the case, otherwise, just change the target. - if (profileType!=AITYPES::BOT_FIGHT) - { - setFight(spawnBot, ennemy); - } - spawnBot->setTarget(ennemy); - } - else if (fleeEnnemy) - { - CAIVector fleeVect(spawnBot->aipos()); - fleeVect -= fleeEnnemy->aipos(); - // :TODO: Check if following block is wanted by game design - /* - CAIVector toGroup = spawnBot->spawnGrp().getCenterPos(); - toGroup -= spawnBot->aipos(); - fleeVect += toGroup; - */ - fleeVect.normalize(1000); - setFlee(spawnBot, fleeVect); - } - else if (spawnBot->isReturning()) - { - _HaveEnnemy=true; - setReturnAfterFight(spawnBot); - } - else - { - setNoFight(spawnBot); - } - return true; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFight // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileReturnAfterFight::CBotProfileReturnAfterFight(CProfileOwner* owner) -: CAIBaseProfile() -//, _PathCont(NLMISC::safe_cast(owner)->getPersistent().getOwner()->getAStarFlag()) -{ - _Bot = static_cast(owner); -// PROFILE_LOG("bot", "return_after_fight", "ctor", ""); -// CSpawnBot* spawnBot = static_cast(owner); -// _PathCont.setDestination(spawnBot->getReturnPos()); -// _MoveProfile = new CBotProfileFollowPos(&_PathCont, owner); -} - -CBotProfileReturnAfterFight::~CBotProfileReturnAfterFight() -{ -// PROFILE_LOG("bot", "return_after_fight", "dtor", ""); -} - -void CBotProfileReturnAfterFight::beginProfile() -{ -// PROFILE_LOG("bot", "return_after_fight", "begin", ""); -// _MoveProfile->beginProfile(); - _Bot->ignoreReturnAggro(true); -} - -void CBotProfileReturnAfterFight::endProfile() -{ -// PROFILE_LOG("bot", "return_after_fight", "end", ""); -// _MoveProfile->endProfile(); - _Bot->ignoreReturnAggro(false); -} - -void CBotProfileReturnAfterFight::stateChangeProfile() -{ -// _MoveProfile->stateChangeProfile(); -} - -void CBotProfileReturnAfterFight::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CBotProfileReturnAfterFightUpdate); -// _MoveProfile->updateProfile(ticksSinceLastUpdate); -} - -std::string CBotProfileReturnAfterFight::getOneLineInfoString() const -{ - std::string info = "return_after_fight bot profile"; -// info += " ("; -// info += _MoveProfile?_MoveProfile->getOneLineInfoString():std::string(""); -// info += ")"; - return info; -} diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight.h b/code/ryzom/server/src/ai_service/ai_generic_fight.h deleted file mode 100644 index 9ff94de78..000000000 --- a/code/ryzom/server/src/ai_service/ai_generic_fight.h +++ /dev/null @@ -1,378 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_GENERIC_FIGHT_H -#define RYAI_GENERIC_FIGHT_H - -#include "profile.h" -#include "sheets.h" -#include "path_behaviors.h" - - -// Forward declarations -class CAIEntityPhysical; -class CModEntityPhysical; -class CBotPlayer; - -// a big bad global var ! -extern CAIEntityPhysical *TempSpeaker; -extern CBotPlayer *TempPlayer; -extern float getDistBetWeen(CAIEntityPhysical& creat1, CAIEntityPhysical& creat2); - -template -float buildDecalage(TVectorSrc const& src, TVectorDst const& dst, CAIVector* decalage) -{ - if (decalage!=NULL) - { - CAIVector& vect = *decalage; - vect = dst; - vect -= src; - float normXY = (float)vect.norm(); - float normZ = (dst.h()-src.h())/1000.f; - // :KLUDGE: This is a dirty dirty hack - // As z precision is 2m, entities can be near contact but considered 2m away if they are on differents PACS planes. - // So we bring back all z dists 2m closer to 0. - if (normZ > 2.f) normZ -= 2.f; - else if (normZ < -2.f) normZ += 2.f; - else normZ = 0.f; - // End of hack - float normXYZ = (float)sqrt(normXY*normXY + normZ*normZ); - return normXYZ; - } - else - { - CAIVector vect; - return buildDecalage(src, dst, &vect); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightHeal // -////////////////////////////////////////////////////////////////////////////// -class CBotProfileFightHeal -: public CAIBaseProfile -{ -public: - CBotProfileFightHeal() : CAIBaseProfile() { } - virtual void eventTargetKilled() = 0; - virtual void noMoreTarget() = 0; - -public: - /// @name Fight ranges/distances parameters - //@{ - static float fightDists[AISHEETS::FIGHTCFG_MAX]; - static float fightDefaultMinRange; - static float fightDefaultMaxRange; - static float fightMeleeMinRange; - static float fightMeleeMaxRange; - static float fightRangeMinRange; - static float fightRangeMaxRange; - static float fightMixedMinRange; - static float fightMixedMaxRange; - static float giveUpDistance; - static bool fleeUnreachableTargets; - //@} -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFight // -////////////////////////////////////////////////////////////////////////////// - -/// Generic fight profile class -class CBotProfileFight -: public CBotProfileFightHeal -, public NLMISC::IDbgPtrData -{ -public: - /// @name Constructors, destructor - //@{ - CBotProfileFight(CProfileOwner* owner, CAIEntityPhysical* ennemy); - virtual ~CBotProfileFight(); - //@} - - /// @name Event handlers - //@{ - virtual void eventBeginFight() = 0; - virtual void eventTargetKilled() = 0; - //@} - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void resumeProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual std::string getOneLineInfoString() const; - //@} - - virtual void noMoreTarget() = 0; - -public: - /// @name Accessors - //@{ - bool isHitting() const { return _Bot->isHitting(); } - bool atAttackDist() const { return _AtAttackDist; } - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_FIGHT; } - //@} - -protected: - NLMISC::CDbgPtr _Bot; - NLMISC::CRefPtr _Ennemy; - - bool _Engaged; - - CPathPosition _PathPos; - CPathCont _PathCont; - - bool _RangeCalculated; - bool _UseFightConfig; - float _RangeMin; - float _RangeMax; - - bool _AtAttackDist; - - bool _SearchAlternativePath; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHeal // -////////////////////////////////////////////////////////////////////////////// - -/// Generic fight profile class -class CBotProfileHeal -: public CBotProfileFightHeal -{ -public: - /// @name Constructors, destructor - //@{ - CBotProfileHeal(TDataSetRow const& row, CProfileOwner* owner); - virtual ~CBotProfileHeal(); - //@} - - /// @name Event handlers - //@{ -// virtual void eventBeginFight() = 0; - virtual void eventTargetKilled() { nlwarning("eventTargetKilled called on a heal profile"); } - //@} - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void resumeProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual std::string getOneLineInfoString() const; - //@} - - virtual void noMoreTarget() = 0; - -public: - /// @name Accessors - //@{ - bool isHitting() const { return (_Bot->getActionFlags()&RYZOMACTIONFLAGS::Attacks)!=0; } - bool atAttackDist() const { return _AtAttackDist; } - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_HEAL; } - //@} - -protected: - NLMISC::CDbgPtr _Bot; - - bool _Engaged; - - CPathPosition _PathPos; - CPathCont _PathCont; - TDataSetRow _Row; - - bool _RangeCalculated; - bool _UseFightConfig; - float _RangeMin; - float _RangeMax; - - bool _AtAttackDist; - - bool _SearchAlternativePath; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFlee // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFlee -: public CAIBaseProfile -{ -public: - /// @name Constructor and destructor - //@{ - CBotProfileFlee(CProfileOwner *owner); - virtual ~CBotProfileFlee(); - //@} - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile() { } - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::BOT_FLEE; } - virtual std::string getOneLineInfoString() const; - //@} - -private: - RYAI_MAP_CRUNCH::CDirection _LastDir; - RYAI_MAP_CRUNCH::CMapPosition _LastStartPos; - - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - - CPathPosition _PathPos; - CPathCont _fightFleePathContainer; - -public: - /// @name Flee ranges/distances parameters - //@{ - static float giveUpDistanceUnreachable; - //@} - -protected: - NLMISC::CDbgPtr _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFight // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFollowPos; - -class CBotProfileReturnAfterFight -: public CAIBaseProfile -{ -public: - /// @name Constructor and destructor - //@{ - CBotProfileReturnAfterFight(CProfileOwner *owner); - virtual ~CBotProfileReturnAfterFight(); - //@} - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::BOT_RETURN_AFTER_FIGHT; } - virtual std::string getOneLineInfoString() const; - virtual void stateChangeProfile(); - //@} - -private: - /* - RYAI_MAP_CRUNCH::CDirection _LastDir; - RYAI_MAP_CRUNCH::CMapPosition _LastStartPos; - - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - - CPathPosition _PathPos; - CPathCont _fightFleePathContainer; - */ -// CPathCont _PathCont; -// NLMISC::CSmartPtr _MoveProfile; - -public: - /// @name Flee ranges/distances parameters - //@{ -// static float giveUpDistanceUnreachable; - //@} - -protected: - NLMISC::CDbgPtr _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CFightOrganizer // -////////////////////////////////////////////////////////////////////////////// - -class CFightOrganizer -{ -public: - CFightOrganizer(); - - template - void reorganize(TContainerIterator const& first, TContainerIterator const& last) - { - H_AUTO(CFightOrganizer_reorganize); - _HaveEnnemy = false; - - for (TContainerIterator it=first, itEnd=last;it!=itEnd;++it) - { - CBot* bot = (*it); - if (!reorganizeIteration(bot)) - break; - } - } - - /// @name Virtual interface - //@{ - virtual void setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy) = 0; - virtual void setHeal(CSpawnBot* bot, CAIEntityPhysical* target) = 0; - virtual void setNoFight(CSpawnBot* bot) = 0; - virtual void setFlee(CSpawnBot* bot, CAIVector& fleeVect) = 0; - virtual void setReturnAfterFight(CSpawnBot* bot) = 0; - //@} - -private: - bool healIteration(CBot* bot, CBot* otherBot); - bool reorganizeIteration(CBot* bot); - -protected: - bool _HaveEnnemy; -}; - -/****************************************************************************/ -/* Profile factories */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightFactory // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFightFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { - nlassert(false); - return NULL; - } -}; -RYAI_DECLARE_PROFILE_FACTORY(CBotProfileFightFactory); - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFleeFactory // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFleeFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { - nlassert(false); - return NULL; - } -}; -RYAI_DECLARE_PROFILE_FACTORY(CBotProfileFleeFactory); - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp b/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp deleted file mode 100644 index 4b655422c..000000000 --- a/code/ryzom/server/src/ai_service/ai_generic_fight_helpers.cpp +++ /dev/null @@ -1,730 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . -#include "stdpch.h" -#include "ai_generic_fight.h" -#include "ai_player.h" -#include "server_share/msg_brick_service.h" -#include "ai_profile_npc.h" - -using namespace NLMISC; - -extern RYZOMID::TTypeId ai_generic_fight_debugCheckedType; -#define debugCheckedType ai_generic_fight_debugCheckedType - -static bool s_attack(CAIEntityPhysical const& target, float const& dist, - NLMISC::CDbgPtr const& _Bot, - bool const _UseFightConfig, - bool const heal) -{ -#ifdef NL_DEBUG - nlassert(EGSHasMirrorReady); -#endif - if (_UseFightConfig) // coz we don't want to lose time for faunas .. - { - AISHEETS::ICreatureCPtr sheet = _Bot->getPersistent().getSheet(); - - uint32 nbchoice = 0; - AISHEETS::TFightCfg choices[AISHEETS::FIGHTCFG_MAX]; - - bool useFightMelee = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_MELEE).isNULL(); - bool useFightRange = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_RANGE).isNULL(); - bool useFightNuke = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_NUKE).isNULL(); - bool useFightHeal = heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_HEAL).isNULL(); - - if (useFightMelee && dist<(CBotProfileFightHeal::fightDists[AISHEETS::FIGHTCFG_MELEE] + _Bot->getPersistent().getSheet()->Radius() * _Bot->getPersistent().getSheet()->Scale())) - { - choices[nbchoice] = AISHEETS::FIGHTCFG_MELEE; - ++nbchoice; - } - if (useFightRange && dist0) - { - AISHEETS::TFightCfg const choice = choices[CAIS::rand16(nbchoice)]; - AISHEETS::CActionList const* fightConfig = sheet->FightConfig(choice); - if (fightConfig) - { - bool self = _Bot->dataSetRow()==target.dataSetRow(); - std::vector phraseList; - FOREACHC(itAction, std::vector, fightConfig->_Actions) - { - AISHEETS::IAIActionCPtr const& action = *itAction; - if (action->SelfAction() == self) - phraseList.push_back(action); - } - uint32 const size = (uint32)phraseList.size(); - if (size>0) - { - nlassert(target.getRyzomType()!=debugCheckedType); - CEGSExecuteAiActionMsg msg(_Bot->dataSetRow(), target.dataSetRow(), phraseList[CAIS::rand16(size)]->SheetId(), _Bot->_DamageCoef, _Bot->_DamageSpeedCoef); - msg.send(egsString); - return true; - } - return false; - } - } - } - - if (heal) - { - return false; - } - else - { - nlassert(target.getRyzomType()!=debugCheckedType); - static NLMISC::CSheetId const defaultAttack("abf01.sphrase"); - - CEGSExecutePhraseMsg msg(_Bot->dataSetRow(), target.dataSetRow(), defaultAttack); - msg.send(egsString); - return true; - } -} - -static void s_updatePosInFloatMode(CAIEntityPhysical* target, - NLMISC::CDbgPtr const& _Bot) -{ -#ifdef NL_DEBUG - nlassert(_Bot->getMode()==MBEHAV::COMBAT_FLOAT); - nlassert(target); -#endif - // determine the position from the angle. - CAngle theta = CAIVector(_Bot->pos()).angleTo(CAIVector(target->aipos())); - _Bot->setTheta(theta); - float thetaAngle = theta.asRadians(); - - // get the which distance. - float dist = (float)(_Bot->getCollisionDist(thetaAngle) + target->getCollisionDist(-thetaAngle) + 0.5); - - CAIVector delta(-theta.asVector2d()*dist); - // update the current position. - _Bot->setPos(CAIPos(CAIVector(target->aipos())+delta, _Bot->h(), theta)); -} - -static void s_disengage(CModEntityPhysical& originator, - bool& _RangeCalculated, - bool const heal) -{ - NLNET::CMessage msgout(disengageString); - msgout.serial(const_cast(originator.dataSetRow())); - sendMessageViaMirror(egsString, msgout); - _RangeCalculated = false; -} - -static void s_disengage( - NLMISC::CDbgPtr const& _Bot, - bool& _RangeCalculated, - bool& _Engaged, - bool const heal) -{ - if (_Bot->getMode()!=MBEHAV::NORMAL) - { - _Bot->setMode(MBEHAV::NORMAL); - } - - if (_Bot->getMode()==MBEHAV::COMBAT_FLOAT) - { - CAIEntityPhysical* target = _Bot->getTarget(); - if (target) - s_updatePosInFloatMode(target, _Bot); - } - - if (_Engaged) - { - s_disengage(*_Bot, _RangeCalculated, heal); - _Engaged = false; - } - _RangeCalculated = false; -} - -// Returns true if we attacked -static bool s_hit( - bool& _RangeCalculated, - bool& _Engaged, - CBotProfileFightHeal* profile, - NLMISC::CDbgPtr const& _Bot, - bool const _UseFightConfig, - float const norm, - float const _RangeMax, - CAIEntityPhysical* const target, - bool const heal) -{ - // Updates scripts - FOREACHC(it, AISHEETS::ICreature::TScriptCompList, _Bot->getPersistent().getSheet()->UpdateScriptList()) - { - (*it)->update(*_Bot); - } - // If hit distance is correct - if (norm<=_RangeMax) - { - float const dist = norm; - // If we are not yet hitting and attack succeeds - if (!_Bot->isHitting()) - { - if (s_attack(*target, dist, _Bot, _UseFightConfig, heal)) - { - // Set action flags - _Bot->setActionFlags(RYZOMACTIONFLAGS::Attacks); - if (heal) - { - if (_Bot->dataSetRow()==target->dataSetRow()) - _Bot->selfHealTriggered(); - else - _Bot->healTriggered(); - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - _Bot->setTarget(NULL); - profile->noMoreTarget(); - } - return true; - } - } - } - // If hit distance is out of range... - else - { - float const dist = 0.f; - // (Check if we have a problem between real and theorical position for player) - if (target->getRyzomType()==RYZOMID::player && NLMISC::safe_cast(target)->isUnReachable()) - { - // Attack anyway - if (s_attack(*target, dist, _Bot, _UseFightConfig, heal)) - { - // Set action flags - _Bot->setActionFlags(RYZOMACTIONFLAGS::Attacks); - if (heal) - { - if (_Bot->dataSetRow()==target->dataSetRow()) - _Bot->selfHealTriggered(); - else - _Bot->healTriggered(); - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - _Bot->setTarget(NULL); - profile->noMoreTarget(); - } - return true; - } - } - } - return false; -} - -static void s_calcRanges( - NLMISC::CDbgPtr const& _Bot, - bool& _RangeCalculated, - float& _RangeMax, - float& _RangeMin, - bool& _UseFightConfig, - bool const heal) -{ - if (_Bot.isNULL()) - return; - - AISHEETS::ICreatureCPtr sheet = _Bot->getPersistent().getSheet(); - - bool useFightMelee = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_MELEE).isNULL(); - bool useFightRange = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_RANGE).isNULL(); - bool useFightNuke = !heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_NUKE).isNULL(); - bool useFightHeal = heal && !sheet->FightConfig(AISHEETS::FIGHTCFG_HEAL).isNULL(); - - _UseFightConfig = useFightMelee || useFightRange || useFightNuke || useFightHeal; - - // Default values - _RangeMin = CBotProfileFightHeal::fightDefaultMinRange; - _RangeMax = CBotProfileFightHeal::fightDefaultMaxRange; - if (_UseFightConfig) - { - if (useFightMelee && (useFightRange || useFightNuke || useFightHeal)) - { - _RangeMin = CBotProfileFightHeal::fightMixedMinRange; - _RangeMax = CBotProfileFightHeal::fightMixedMaxRange; - } - else if (useFightMelee) - { - _RangeMin = CBotProfileFightHeal::fightMeleeMinRange; - _RangeMax = CBotProfileFightHeal::fightMeleeMaxRange; - } - else - { - _RangeMin = CBotProfileFightHeal::fightRangeMinRange; - _RangeMax = CBotProfileFightHeal::fightRangeMaxRange; - } - } - if (_Bot->getPersistent().getClientSheet() != NLMISC::CSheetId::Unknown && _Bot->getPersistent().getClientCSheet()) - _RangeMax += _Bot->getPersistent().getClientCSheet()->Radius() * _Bot->getPersistent().getClientCSheet()->Scale(); - else - _RangeMax += _Bot->getPersistent().getSheet()->Radius() * _Bot->getPersistent().getSheet()->Scale(); - - _RangeCalculated = true; -} - -// Returns true if we moved properly -bool s_move( - // Output (and i/o) - NLMISC::CDbgPtr const& _Bot, - CPathPosition& _PathPos, - bool& _SearchAlternativePath, - CAIEntityPhysical* target, - float& norm, - CAIVector& decalage, - bool& _RangeCalculated, - bool& _Engaged, - CPathCont& _PathCont, - // Input - float const contactDist, - float const _RangeMax, - float const _RangeMin, - bool const targetInForbiddenZone, - uint const ticksSinceLastUpdate, - bool const heal) -{ - // If we are not looking for an alternative path - if (!_SearchAlternativePath) - { - // Look at the target - _PathPos._Angle = CAIVector(_Bot->pos()).angleTo(CAIVector(target->aipos())); - // If we are not in combat mode, change mode - if (_Bot->getMode()!=MBEHAV::COMBAT) - { - // If we were in COMBAT_FLOAT (???), update position a last time - if (_Bot->getMode()==MBEHAV::COMBAT_FLOAT) - { - s_updatePosInFloatMode(target, _Bot); - // The position has changed, so we have to recalculate everything about it. - norm = buildDecalage(_Bot->pos(), target->aipos(), &decalage) - contactDist; - } - // Set mode to COMBAT - _Bot->setMode(MBEHAV::COMBAT); - } - } - - // If we cannot move - if (!_Bot->canMove()) - { - // Remember that we cannot search for an alternative path - _SearchAlternativePath = false; - } - // :KLUDGE: useless variable - bool canResetSearchingPath = !_SearchAlternativePath; - // If we can move and the target is out of range or we have to look for an alternative path - if ( _Bot->canMove () - && ( norm<_RangeMin - || norm>_RangeMax - || _SearchAlternativePath) - && !_Bot->isHitting()) - { -////////////////////////////////////////////////////////////////////////////// -// Compute distance to go //////////////////////////////////////////////////// - // rescale is the distance between real target distance and the mean range - float rescale = norm - (_RangeMin+_RangeMax)*0.5f; -////////////////////////////////////////////////////////////////////////////// -// Try to go straight to the target ////////////////////////////////////////// - // We are on the main path and the target is reachable - if (!_SearchAlternativePath && !targetInForbiddenZone) - { - // Save our current pos - CAIPos const lastPos = _Bot->pos(); - // ??? - _Bot->setMoveDecalage(decalage); - // Let's run - float speed = _Bot->runSpeed()*ticksSinceLastUpdate; - // If we got to go back move -speed or +rescale - if (rescale<0) - rescale = std::max(-speed, rescale); - // If we go forward move +speed or +rescale - else - rescale = std::min(speed, rescale); - - // Compute a new intermediate position along the path - CPathPosition localPathPos(_PathPos._Angle); - localPathPos._PathState = CPathPosition::NO_PATH; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - localPathPos, - _PathCont, - speed, - rescale, - 0.5f); - // If we can't follow the path or the computed pos is invalid - if ( status==CFollowPath::FOLLOW_NO_PATH - || (_Bot->wpos().isValid() && (_Bot->wpos().getFlags()&_Bot->getAStarFlag())!=0)) - { - // Restore position - _Bot->setPos(lastPos); - // Find another path - _SearchAlternativePath = true; - if (heal) - canResetSearchingPath = false; - else - canResetSearchingPath = !_SearchAlternativePath; - } - - // If we didn't move enough - if ( rescale>0 - && lastPos.quickDistTo(CAIVector(_Bot->pos()))<(rescale*0.5)) - { - // Find another path - _SearchAlternativePath = true; - canResetSearchingPath = false; - } - } -////////////////////////////////////////////////////////////////////////////// -// Compute a more complex path to the target ///////////////////////////////// - // We are looking for an alternative path and the target is reachable - if ( _SearchAlternativePath - && !targetInForbiddenZone ) - { - // Compute a vector to the target - CAIVector delta = CAIVector(target->aipos()) - CAIVector(_Bot->pos()); - // Keep the distance to the target - double const lastDist = delta.norm(); - // Save our position - CAIPos const lastPos = _Bot->pos(); - // Set our destination to the target pos - _PathCont.setDestination(target->wpos()); - // Let's run - float speed = _Bot->runSpeed()*ticksSinceLastUpdate; - // If we got to go back move -speed or +rescale - if (rescale<0) - rescale = std::max(-speed, rescale); - // If we go forward move +speed or +rescale - else - rescale = std::min(speed, rescale); - // Move to the target - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _PathCont, - speed, - rescale, - 0.5f); - // If we cannot reach the target... - if (status==CFollowPath::FOLLOW_NO_PATH) - { - // ...forget it - // (exploit?, seems to be a short term memory problem). - _Bot->forgetAggroFor(target->dataSetRow(), true); - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - if (!heal && CBotProfileFightHeal::fleeUnreachableTargets) - _Bot->setUnreachableTarget(target); - else - _Bot->setTarget(NULL); - return false; - } - // Recompute distance to the target - delta = CAIVector(target->aipos()) - CAIVector(_Bot->pos()); - // If we didn't come closer recompute a path - double const epsilon = 0.0000001; // This is to prevent a gcc optimization problem - _SearchAlternativePath = (delta.norm()+epsilon) > lastDist; - } - else - { - // Force a correct angle (coz of the repulsion prob) - _Bot->setTheta(_PathPos._Angle); - } - // Recompute vector and dist to target - norm = buildDecalage(_Bot->pos(), target->aipos(), &decalage) - contactDist; - // (???) - if (canResetSearchingPath) - { - _PathPos._PathState = CPathPosition::NOT_INITIALIZED; - } - } - // If we cannot move or the target is in range - else - { - // Force a correct angle (coz of the repulsion prob) - _Bot->setTheta(_PathPos._Angle); - CPathPosition localPathPos(_PathPos._Angle); - localPathPos._PathState = CPathPosition::NO_PATH; - // Speed is half the walking speed. - float const speed = _Bot->walkSpeed()*ticksSinceLastUpdate*0.5f; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - localPathPos, - _PathCont, - 0.f, - 0.f, - 0.5f, - true, - NULL, - speed, - false); - } - return true; -} - -// 33 if, 6+ levels -static void s_updateProfile( - // Output (or input/output) - NLMISC::CRefPtr& _Ennemy, - CBotProfileFightHeal* profile, - bool& _RangeCalculated, - bool& _AtAttackDist, - float& _RangeMax, - CPathCont& _PathCont, - bool& _Engaged, - bool& _SearchAlternativePath, - CPathPosition& _PathPos, - float& _RangeMin, - bool& _UseFightConfig, - NLMISC::CDbgPtr const& _Bot, - // Input - uint const ticksSinceLastUpdate, - bool const heal) -{ - H_AUTO(BotFightHealProfileUpdate); - CFollowPathContext fpcBotFightHealProfileUpdate("BotFightHealProfileUpdate"); - -#ifdef NL_DEBUG - nlassert(_Bot->isAlive()); -#endif - -/****************************************************************************/ -/* Early exits */ -/****************************************************************************/ - - // If we are paralysed due to a spell or special effect - if (_Bot->isFeared()) - return; - - ////////////////////////////////////////////////////////////////////////////// - // X. VALIDATE TARGET //////////////////////////////////////////////////////// - CAIEntityPhysical* target = NULL; - // Get the current target - target = _Bot->getTarget(); - - // Assert target is valid and if it has changed take its row - while (!_Bot->isHitting() && target && target!=_Ennemy) - { - // Disengage from fight - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - // Change the target row reference - _Ennemy = target; - // Synchronize target row refs (shouldn't it be asserted, since _Row is extracted from getTarget) - _Bot->setTarget(_Ennemy); - // Get the current target - target = _Bot->getTarget(); - } - // Assert target is valid and alive - if (!target || !target->isAlive() || (heal && target->hpPercentage()>.9f)) - { - // If we are hitting an invalid or dead target just wait we finish hitting, else disengage - if (!_Bot->isHitting()) - { - // If the target died signal it to whoever is interested - if (target && !heal) - { - profile->eventTargetKilled(); - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); // Disengage from fight - _Bot->forgetAggroFor(target->dataSetRow()); - } - else - { - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); // Disengage from fight - } - if (heal) - _Bot->setTarget(NULL); - profile->noMoreTarget(); - } - return; - } - // X. VALIDATE TARGET //////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - // Compute a vector from us to the target - CAIVector decalage; - // contactDist is the distance between our center and our target's when we are touching - float const contactDist = getDistBetWeen(*_Bot, *target) + 0.5f; - // norm is the distance between our skin and our target's - float norm = buildDecalage(_Bot->pos(), target->aipos(), &decalage) - contactDist; - - // If target is more than giveUpDistance meters far, quit fight and forget aggro. - if (norm>CBotProfileFightHeal::giveUpDistance) - { - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - _Bot->forgetAggroFor(target->dataSetRow(), true); - return; - } - - // Forget aggro on players in water - // :TODO: Replace in water test with a cleaner prop - // :KLUDGE: bit manipulation - if (target->getRyzomType()==RYZOMID::player && (target->getActionFlags() & RYZOMACTIONFLAGS::InWater)) - { - // Disengage from fight - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - // Forget the aggro on target - _Bot->forgetAggroFor(target->dataSetRow(), true); - return; - } - // Ignore players that go out of authorized zones - if (!heal && !_Bot->isAggroValid(target->dataSetRow())) - { - _Bot->forgetAggroFor(target->dataSetRow(), true); - s_disengage(_Bot, _RangeCalculated, _Engaged, heal); - _Bot->setTarget(NULL); - return; - } - -/****************************************************************************/ -/* Data extraction */ -/****************************************************************************/ - - // Compute attack ranges - if (!_RangeCalculated) - s_calcRanges(_Bot, _RangeCalculated, _RangeMax, _RangeMin, _UseFightConfig, heal); - // Check if we can attack our target - _AtAttackDist = norm < _RangeMax; - - // Check if target can be attacked - bool const targetInForbiddenZone = ((!target->wpos().isValid())||(target->wpos().getFlags()&_Bot->getAStarFlag())!=0); - -/****************************************************************************/ -/* Profile main processing */ -/****************************************************************************/ - - // If the target is further than our max range - if (norm>(_RangeMax+5.f) && targetInForbiddenZone) - { - // If we can move - if (_Bot->canMove()) - { - H_AUTO(AntiExploit1_BotFightProfileUpdate); - CFollowPathContext fpcAntiExploit1_BotFightProfileUpdate("AntiExploit1_BotFightProfileUpdate"); - - // Run... - float botSpeed = _Bot->runSpeed(); - // ...to the target - _PathCont.setDestination(target->wpos()); - // If we are in COMBAT_FLOAT (???) update the pos accordingly - if (_Bot->getMode()==MBEHAV::COMBAT_FLOAT) - s_updatePosInFloatMode(target, _Bot); - // Anyway set mode to (normal) combat - _Bot->setMode(MBEHAV::COMBAT); - } - } - // If the target is near enough - else - { - // Set the engaged state - _Engaged = true; - -////////////////////////////////////////////////////////////////////////////// -// A. MOVE TO THE BOT //////////////////////////////////////////////////////// - // Let's move (if return false movement failed and then stop there) - if (!s_move( - /* Output (and i/o): */_Bot, _PathPos, _SearchAlternativePath, target, norm, decalage, _RangeCalculated, _Engaged, _PathCont, - /* Input: */ contactDist, _RangeMax, _RangeMin, targetInForbiddenZone, ticksSinceLastUpdate, heal)) - return; -// A. MOVE TO THE BOT //////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////////// -// B. HIT THE TARGET ///////////////////////////////////////////////////////// - // If we are not searching for another path and we are not already hitting, then it's time to hit - if ( !_Bot->isHitting() - && !_SearchAlternativePath) - { - // Let's hit (if return true we attacked and then stop there) - if (s_hit(_RangeCalculated, _Engaged, profile, _Bot, _UseFightConfig, norm, _RangeMax, target, heal)) - return; - } -// B. HIT THE TARGET ///////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - } - // If we are not hitting although we could - if (!_Bot->isHitting() && !_Bot->isRooted()) - { - // Change target - _Bot->CBotAggroOwner::update(ticksSinceLastUpdate); - } -} - -void CBotProfileFight::endProfile() -{ - s_disengage(_Bot, _RangeCalculated, _Engaged, /*heal*/false); - if (((CAIEntityPhysical*)_Bot->getTarget())!=NULL) - _Bot->setTarget(NULL); // this bot doesn't have any more target now. -} - -void CBotProfileFight::updateProfile(uint ticksSinceLastUpdate) -{ - s_updateProfile( - // Output (or input/output) - _Ennemy, - this, - _RangeCalculated, - _AtAttackDist, - _RangeMax, - _PathCont, - _Engaged, - _SearchAlternativePath, - _PathPos, - _RangeMin, - _UseFightConfig, - _Bot, - // Input - ticksSinceLastUpdate, - /*heal?*/false); -} - -void CBotProfileHeal::endProfile() -{ - s_disengage(_Bot, _RangeCalculated, _Engaged, /*heal*/true); - if (((CAIEntityPhysical*)_Bot->getTarget())!=NULL) - _Bot->setTarget(NULL); // this bot doesn't have any more target now. -} - -void CBotProfileHeal::updateProfile(uint ticksSinceLastUpdate) -{ - NLMISC::CRefPtr ennemy = CAIS::instance().getEntityPhysical(_Row); - s_updateProfile( - // Output (or input/output) - ennemy, - this, - _RangeCalculated, - _AtAttackDist, - _RangeMax, - _PathCont, - _Engaged, - _SearchAlternativePath, - _PathPos, - _RangeMin, - _UseFightConfig, - _Bot, - // Input - ticksSinceLastUpdate, - /*heal?*/true); - if (ennemy) - _Row = ennemy->dataSetRow(); - else - _Row = TDataSetRow(); -} diff --git a/code/ryzom/server/src/ai_service/ai_grp.cpp b/code/ryzom/server/src/ai_service/ai_grp.cpp deleted file mode 100644 index e77618731..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp.cpp +++ /dev/null @@ -1,509 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "ai_grp.h" -#include "visual_properties_interface.h" -#include "ai_profile_npc.h" - -using namespace MULTI_LINE_FORMATER; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -//-------------------------------------------------------------------------- -// METHODS for debugging stuff -//-------------------------------------------------------------------------- - -bool GrpHistoryRecordLog = true; -CAIVector lastTriedPos; - -CGroup::CGroup (CManager *owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlags, CAIAliasDescriptionNode *aliasTree) : - CAliasChild(owner,aliasTree), - CPersistent(), - _EscortTeamId(CTEAM::InvalidTeamId), - _EscortRange(30), - _AutoSpawn(true), - _DenyFlags(denyFlags), - _AutoDestroy(false), - _AggroRange(0), - _UpdateNbTicks(30) -{ - owner->getAIInstance()->addGroupInfo(this); -} - -CGroup::CGroup (CManager *owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlags, uint32 alias, std::string const& name) : - CAliasChild(owner, alias, name), - CPersistent(), - _EscortTeamId(CTEAM::InvalidTeamId), - _EscortRange(30), - _AutoSpawn(true), - _DenyFlags(denyFlags), - _AutoDestroy(false), - _AggroRange(0), - _UpdateNbTicks(30) -{ - owner->getAIInstance()->addGroupInfo(this); -} - -CGroup::~CGroup () -{ - getAIInstance()->removeGroupInfo(this, this); - getOwner()->removeFromSpawnList (this); - if (isSpawned()) - { - despawnGrp (); - } - -} - -CBot* CGroup::getLeader() -{ - FOREACH(itBot, CCont, bots()) - { - CSpawnBot* const bot = itBot->getSpawnObj(); - if (bot && bot->isAlive()) - return *itBot; - } - // no bots alive, no leader ! - return NULL; -} - -CBot* CGroup::getSquadLeader(bool checkAliveStatus) -{ - CCont::iterator itBot = bots().begin(); - if (itBot!=bots().end()) - { - CSpawnBot* const bot = itBot->getSpawnObj(); - if (bot && (!checkAliveStatus || bot->isAlive())) - return *itBot; - } - // first bot not alive, no squad leader ! - return NULL; -} - -void CGroup::serviceEvent (const CServiceEvent &info) -{ - CCont::iterator it=bots().begin(), itEnd=bots().end(); - while (it!=itEnd) - { - it->serviceEvent (info); - ++it; - } - -} - -void CGroup::despawnBots () -{ - for (CCont::iterator it=_Bots.begin(), itEnd=_Bots.end(); it!=itEnd;++it) - { - if (it->isSpawned()) - it->despawnBot(); - } - -} - -std::string CGroup::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":g%u", getChildIndex()); -} - -std::string CGroup::getOneLineInfoString() const -{ - return std::string("Group '") + getName() + "'"; -} - -std::vector CGroup::getMultiLineInfoString() const -{ - std::vector container; - - pushTitle(container, "CGroup"); - pushEntry(container, "id=" + getIndexString()); - container.back() += " alias=" + getAliasString(); - container.back() += " name=" + getName(); - pushEntry(container, "fullname=" + getFullName()); - pushEntry(container, "autoSpawn=" + NLMISC::toString(_AutoSpawn)); - pushEntry(container, "aggroRange=" + NLMISC::toString(_AggroRange)); - container.back() += " updateNbTicks=" + NLMISC::toString(_UpdateNbTicks); - if (isSpawned()) - { - std::vector strings = getSpawnObj()->getMultiLineInfoString(); - FOREACHC(it, std::vector, strings) - pushEntry(container, *it); - } - else - pushEntry(container, ""); - pushFooter(container); - - return container; -} - -std::string CGroup::getFullName() const -{ - return std::string(getOwner()->getFullName()+":"+getName()); -} - -void CGroup::lastBotDespawned() -{ - // send message -} - -void CGroup::firstBotSpawned() -{ - // send message -} - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroup // -////////////////////////////////////////////////////////////////////////////// - -CSpawnGroup::~CSpawnGroup() -{ - FOREACH(it, CCont,bots()) - { - if ((*it)->isSpawned()) - (*it)->despawnBot(); - } - - getPersistent().despawnBots(); - - // clear profiles - _MovingProfile = CProfilePtr(); - _FightProfile = CProfilePtr(); - _ActivityProfile = CProfilePtr(); - _PunctualHoldActivityProfile = CProfilePtr(); - _PunctualHoldMovingProfile = CProfilePtr(); -} - -bool CSpawnGroup::calcCenterPos(CAIVector& grp_pos, bool allowDeadBot) -{ - if (bots().size()<=0) - return false; - - double x(0), y(0); - uint count(0); - - FOREACH(it, CCont, bots()) - { - CSpawnBot const* const spawnBot = it->getSpawnObj(); - if (!spawnBot || (!allowDeadBot && !spawnBot->isAlive())) - continue; - - x += spawnBot->pos().x().asDouble(); - y += spawnBot->pos().y().asDouble(); - ++count; - } - if (count==0) - return false; - - grp_pos.setX(x/count); - grp_pos.setY(y/count); - return true; -} - -void CSpawnGroup::spawnBotOfGroup() -{ - CCont::iterator it = bots().begin(); - CCont::iterator itEnd = bots().end(); - while (it!=itEnd) - { - CBot* bot = *it; - if (!bot->isSpawned()) - { - bool ok= bot->spawn(); -// code removed by Sadge because it didn't fix the problem it was added for -// if (ok) -// { -// // the spawn succeeded -// // make sure the bot isn't in the despawn list -// for (uint32 i= _BotsToDespawn.size(); i--;) -// { -// if (_BotsToDespawn[i].getBotIndex()== bot->getChildIndex()) -// { -// nldebug("Removing bot from the despawn list because they just respawned: %s",bot->getFullName().c_str()); -// _BotsToDespawn[i]= _BotsToDespawn.back(); -// _BotsToDespawn.pop_back(); -// } -// } -// } - if (!ok) - { - // the spawn failed - std::string name; - - if (!bot->getFullName().empty()) - name = bot->getFullName(); - else - { - if (!bot->getOwner()->getFullName().empty()) - name = std::string("from group ") + bot->getOwner()->getFullName(); - else - name = std::string("Unknown"); - } - - if (bot->getSheet()->SheetId()==NLMISC::CSheetId::Unknown) - nlwarning("***> Spawn failed position(%s), UNKNOWN SHEET! Bot %s ", lastTriedPos.toString().c_str(), name.c_str()); - else - nlwarning("***> Spawn failed position(%s), sheetId(%s) Bot %s ", lastTriedPos.toString().c_str(), bot->getSheet()->SheetId().toString().c_str(), name.c_str()); - } - } - ++it; - } -} - -void CSpawnGroup::addBotToDespawnAndRespawnTime(CBot* bot, uint32 despawnTime, uint32 respawnTime) -{ - nlassert(bot->isSpawned()); - nlassert(bot->getOwner()==&getPersistent()); - - uint32 const botIndex = bot->getChildIndex(); - - FOREACH(it, std::vector, _BotsToDespawn) - { - if (it->getBotIndex()==botIndex) - { - *it = CBotToSpawn(botIndex, despawnTime, respawnTime); - return; - } - } - _BotsToDespawn.push_back(CBotToSpawn(botIndex, despawnTime, respawnTime)); -} - -void CSpawnGroup::checkDespawn() -{ - if (_BotsToDespawn.empty()) - return; - - //FOREACH_NOINC(it, std::vector, _BotsToDespawn) - for(uint32 i = 0; i < _BotsToDespawn.size();) - { - CBotToSpawn& botToDespawn = _BotsToDespawn[i]; - if (botToDespawn.waitingDespawnTimeOver()) - { - if (botToDespawn.getBotIndex()>=getPersistent().bots().size()) - { - STOP("Array overflow in despawn code!"); - } - else if (getPersistent().bots()[botToDespawn.getBotIndex()]==NULL) - { - STOP("Trying to despawn a bot who doesn't exist!!"); - } - else - { - getPersistent().bots()[botToDespawn.getBotIndex()]->despawnBot(); - if (getPersistent().isAutoSpawn()) - _BotsToRespawn.push_back(botToDespawn); - } - - // pop this entry out of the bots to despawn vector - // ace: we don't use iterator because when pop_back(), all iterators are invalidated - _BotsToDespawn[i] = _BotsToDespawn.back(); - _BotsToDespawn.pop_back(); - continue; - } - i++; - } - - if (_NbSpawnedBot==0 && _BotsToRespawn.size()==0) - { - // Warn the parent manager that this group is now dead. - getPersistent().getOwner()->getOwner()->groupDead(&getPersistent()); - if (getPersistent()._AutoDestroy) - getPersistent().getOwner()->groups().removeChildByIndex(getPersistent().getChildIndex()); - } -} - - -void CSpawnGroup::incSpawnedBot(CBot& spawnBot) -{ -#if !FINAL_VERSION - uint32 botIndex = spawnBot.getChildIndex(); - for (uint32 i=(uint32)_BotsToRespawn.size(); i--; ) - { - if (_BotsToRespawn[i].getBotIndex()==botIndex) - { - nldebug("Removing bot from _BotsToRespawn because they just respawned: %s",spawnBot.getFullName().c_str()); -// nlwarning("WARNING!!! Old assert \"_BotsToRespawn[i].getBotIndex()!=botIndex\" would have failed"); - _BotsToRespawn[i]=_BotsToRespawn.back(); - _BotsToRespawn.pop_back(); - } - } - for (uint32 i=(uint32)_BotsToDespawn.size(); i--; ) - { - if (_BotsToDespawn[i].getBotIndex()==botIndex) - { - nldebug("Removing bot from _BotsToDespawn because they just respawned: %s",spawnBot.getFullName().c_str()); -// nlwarning("WARNING!!! Old assert \"_BotsToDespawn[i].getBotIndex()!=botIndex\" would have failed"); - _BotsToDespawn[i]=_BotsToDespawn.back(); - _BotsToDespawn.pop_back(); - } - } -#endif - if (_NbSpawnedBot==0) - { - getPersistent().firstBotSpawned(); - } - _NbSpawnedBot++; -} - -void CSpawnGroup::decSpawnedBot() -{ - --_NbSpawnedBot; - if (_NbSpawnedBot==0) - { - getPersistent().lastBotDespawned(); - } -} - -void CSpawnGroup::checkRespawn() -{ - // respawn if there is not too much dead .. (no more than one at each tick). - if (_BotsToRespawn.size()<=0) - return; - - //FOREACH_NOINC(it, std::vector, _BotsToRespawn) - for(uint32 i = 0; i < _BotsToRespawn.size();) - { - CBotToSpawn const& botToSpawn = _BotsToRespawn[i]; - if (botToSpawn.waitingRespawnTimeOver()) - { - CBot* botPt = getPersistent().bots()[botToSpawn.getBotIndex()]; - - CBotToSpawn const botToSpawn = _BotsToRespawn.back(); - - // remove the entry - _BotsToRespawn[i] = _BotsToRespawn.back(); - _BotsToRespawn.pop_back(); - - if (botPt->isSpawned()) - { - nlwarning("CSpawnGroup::checkRespawn : trying to respawn a spawned bot"); - } - if (botPt->isSpawned() || botPt->reSpawn(false)) - { - continue; // directly test the same it (the next in fact). - } - else - { - _BotsToRespawn.insert(_BotsToRespawn.begin(), botToSpawn); // push_front so the end doesn't change. - } - } - ++i; - } - -} - -CBot* CSpawnGroup::findLeader() -{ - FOREACH(itBot, CCont, bots()) - { - CBot* bot = *itBot; - if (bot->isSpawned()) - { - if (bot->getSpawnObj()->isAlive()) - return bot; - } - } - return NULL; -} - -std::vector CSpawnGroup::getMultiLineInfoString() const -{ - std::vector container; - - pushTitle(container, "CSpawnGroup"); - pushEntry(container, "move profile: " + _MovingProfile.getOneLineInfoString()); - pushEntry(container, "activity profile: " + _ActivityProfile.getOneLineInfoString()); - pushEntry(container, "fight profile: " + _FightProfile.getOneLineInfoString()); - pushFooter(container); - - return container; -} - -NLMISC::CSmartPtr CSpawnGroup::buildFirstHitPlace(TDataSetRow const& aggroBot) const -{ - if (_ActivityProfile.getAIProfileType()==AITYPES::ACTIVITY_SQUAD) - return static_cast(_ActivityProfile.getAIProfile())->buildFirstHitPlace(aggroBot); - return NULL; -} - -void CSpawnGroup::addAggroFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place) -{ - CGroup& grp = getPersistent(); - FOREACH(itBot, CCont, grp.bots()) - { - CBot* pBot = *itBot; - if (pBot) - { - CSpawnBot* spBot = pBot->getSpawnObj(); - if (spBot) - { - spBot->addAggroFor(bot, aggro, forceReturnAggro, place, false); - } - } - } -} -void CSpawnGroup::setAggroMinimumFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place) -{ - CGroup& grp = getPersistent(); - FOREACH(itBot, CCont, grp.bots()) - { - CBot* pBot = *itBot; - if (pBot) - { - CSpawnBot* spBot = pBot->getSpawnObj(); - if (spBot) - { - spBot->setAggroMinimumFor(bot, aggro, forceReturnAggro, place, false); - } - } - } -} - -bool CSpawnGroup::haveAggro() const -{ - CGroup const& group = getPersistent(); - FOREACHC(itBot, CCont, group.bots()) - { - CBot const* pBot = *itBot; - if (pBot) - { - CSpawnBot const* spBot = pBot->getSpawnObj(); - if (spBot && spBot->haveAggro()) - return true; - } - } - return false; -} - -bool CSpawnGroup::haveAggroOrReturnPlace() const -{ - CGroup const& group = getPersistent(); - FOREACHC(itBot, CCont, group.bots()) - { - CBot const* pBot = *itBot; - if (pBot) - { - CSpawnBot const* spBot = pBot->getSpawnObj(); - if (spBot && spBot->haveAggroOrReturnPlace()) - return true; - } - } - return false; -} diff --git a/code/ryzom/server/src/ai_service/ai_grp.h b/code/ryzom/server/src/ai_service/ai_grp.h deleted file mode 100644 index 2866f3c04..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp.h +++ /dev/null @@ -1,383 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_GRP_H -#define RYAI_GRP_H - -#include "persistent_spawnable.h" -#include "ai_mgr.h" -#include "ai_bot.h" -#include "keyword_owner.h" -#include "debug_history.h" -#include "game_share/misc_const.h" -#include "profile_in_state.h" -#include "ai_aggro.h" -#include "dyn_grp.h" -#include "service_dependencies.h" - -// forward decl -class CDebugHistory; -class CGroup; -class CBot; -class CSpawnBot; -class CPersistentStateInstance; - -extern bool GrpHistoryRecordLog; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroup // -////////////////////////////////////////////////////////////////////////////// - -/// This is a common parent for all grp classes (bot group classes) -/// Group contains a container of Bots. -class CSpawnGroup -: public NLMISC::CDbgRefCount -, public CSpawnable > -, public CProfileOwner -, public CProfileParameters -{ -public: - CSpawnGroup(CPersistent& owner); - - virtual ~CSpawnGroup(); - - virtual void spawnBotOfGroup(); - - void aggroLost(TDataSetRow const& aggroBot) const { } - - void aggroGain(TDataSetRow const& aggroBot) const { } - - virtual void spawnBots() = 0; - virtual void despawnBots(bool immediately) = 0; - - virtual void update() = 0; - - // Update Rate feature. - virtual int getUpdatePriority() const { return 0; } - - virtual void recalcUpdatePriorityDelta() { } - - CGroup& getPersistent() const; - - CAliasCont const& bots() const; - CAliasCont& bots(); - - CBot* findLeader(); - - CProfilePtr& movingProfile() { return _MovingProfile; } - CProfilePtr& activityProfile() { return _ActivityProfile; } - CProfilePtr const& activityProfile() const { return _ActivityProfile; } - CProfilePtr& fightProfile() { return _FightProfile; } - - /// only for use by State Machine (or problems will occurs -> callStateChanged if same ) - void setMoveProfileFromStateMachine(IAIProfileFactory* staticProfile); - /// only for use by State Machine (or problems will occurs -> callStateChanged if same ) - void setActivityProfileFromStateMachine(IAIProfileFactory* staticProfile); - - - bool calcCenterPos(CAIVector& grp_pos, bool allowDeadBot = false); - - // Respawn bot list - class CBotToSpawn - { - private: - friend class CSpawnGroup; - CBotToSpawn(uint32 botIndex, uint32 despawnTime, uint32 respawnTime) - : _botIndex(botIndex) - { - _despawnTimer.set(despawnTime); - _respawnTimer.set(respawnTime); - } - bool waitingDespawnTimeOver() const - { - return _despawnTimer.test(); - } - bool waitingRespawnTimeOver() const - { - return _respawnTimer.test(); - } - uint32 getBotIndex() const - { - return _botIndex; - } - CAITimer& respawnTimer() - { - return _respawnTimer; - } - uint32 _botIndex; - CAITimer _despawnTimer; - CAITimer _respawnTimer; - }; - - void incSpawnedBot(CBot& spawnBot); - - void decSpawnedBot(); - - void addBotToDespawnAndRespawnTime(CBot* faunaBot, uint32 despawnTime, uint32 respawnTime); - - void checkDespawn(); - void checkRespawn(); - - uint32 nbSpawnedBot() const { return _NbSpawnedBot; } - - uint32 nbBotToRespawn() const { return (uint32)_BotsToRespawn.size(); } - - uint32 nbBotToDespawn() const { return (uint32)_BotsToDespawn.size(); } - - bool isGroupAlive(uint32 const nbMoreKilledBot = 0) const; - - CAIVector const& getCenterPos() const { return _CenterPos; } - - void setCenterPos(CAIVector const& pos) { _CenterPos = pos; } - - std::vector getMultiLineInfoString() const; - - virtual NLMISC::CSmartPtr buildFirstHitPlace(TDataSetRow const& aggroBot) const; - - void addAggroFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL)); - void setAggroMinimumFor(TDataSetRow const& bot, float aggro, bool forceReturnAggro, NLMISC::CSmartPtr place = NLMISC::CSmartPtr(NULL)); - bool haveAggro() const; - bool haveAggroOrReturnPlace() const; - -protected: - CProfilePtr _PunctualHoldMovingProfile; - CProfilePtr _PunctualHoldActivityProfile; - - // The group center pos (not always updated) - CAIVector _CenterPos; - -private: - uint32 _NbSpawnedBot; - - std::vector _BotsToRespawn; - std::vector _BotsToDespawn; - - CProfilePtr _MovingProfile; - CProfilePtr _ActivityProfile; - CProfilePtr _FightProfile; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGroup // -////////////////////////////////////////////////////////////////////////////// - -class CGroup -: public NLMISC::CDbgRefCount -, public CPersistent -, public CAliasChild -, public CAIEntity -, public CDebugHistory -, public NLMISC::CRefCount -, public CProfileParameters -, public CServiceEvent::CHandler -{ -public: - friend class CSpawnGroup; - - CGroup(CManager* owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlag, CAIAliasDescriptionNode* aliasTree = NULL); - CGroup(CManager* owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlag, uint32 alias, std::string const& name); - virtual ~CGroup(); - - void serviceEvent(CServiceEvent const& info); - - CBot* getLeader(); - CBot* getSquadLeader(bool checkAliveStatus = true); - - void despawnBots(); - - virtual CDynGrpBase* getGrpDynBase() = 0; - - CAliasTreeOwner* aliasTreeOwner() { return this; } - - bool _AutoDestroy; - void autoDestroy(bool ad) { _AutoDestroy = ad; } - - /// @name CChild implementation - //@{ - virtual std::string getIndexString() const; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - virtual std::string getFullName() const; - //@} - - virtual void lastBotDespawned(); - virtual void firstBotSpawned(); - - virtual CPersistentStateInstance* getPersistentStateInstance() = 0; - - RYAI_MAP_CRUNCH::TAStarFlag getAStarFlag() const { return _DenyFlags; } - - virtual CAIS::CCounter& getSpawnCounter() = 0; - virtual RYZOMID::TTypeId getRyzomType() = 0; - virtual void setEvent(uint eventId) = 0; - - virtual bool spawn(); - - virtual NLMISC::CSmartPtr createSpawnGroup() = 0; - - virtual void despawnGrp(); - - void despawnBots(bool immediately); - - CAliasCont const& bots() const { return _Bots; } - CAliasCont& bots() { return _Bots; } - - void display(CStringWriter& stringWriter); - - CBot* getBot(uint32 index); - - // debugging stuff - CDebugHistory* getDebugHistory() { return this; } - - CBot* getNextValidBotChild(CBot* child = NULL) { return _Bots.getNextValidChild(child); } - - CManager& getManager() { return *getOwner(); } - - void setEscortTeamId(uint16 teamId) { _EscortTeamId = teamId; } - uint16 getEscortTeamId() const { return _EscortTeamId; } - - void setEscortRange(float range) { _EscortRange = range; } - float getEscortRange() const { return _EscortRange; } - - virtual void setAutoSpawn(bool autoSpawn) { _AutoSpawn = autoSpawn; } - bool isAutoSpawn() const { return _AutoSpawn; } - - CAIInstance* getAIInstance() const { return getOwner()->getAIInstance(); } - - void setEventParams(const std::vector &a) { _EventParams = a; } - std::string getEventParamString(uint32 i) { if (i >= _EventParams.size()) return ""; return _EventParams[i]; } - float getEventParamFloat(uint32 i) { if (i >= _EventParams.size()) return 0.0f; return (float)atof(_EventParams[i].c_str()); } - - float _AggroRange; - uint32 _UpdateNbTicks; - -protected: - CAliasCont _Bots; - /// Team Id of the escort (if any). - uint16 _EscortTeamId; - /// The range of the escort, ie the maximal distance of any escorter player that alow the group to be escorted - float _EscortRange; - /// The bots automaticaly spawn when the group is spawned. - bool _AutoSpawn; - - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - - std::vector _EventParams; -}; - -/****************************************************************************/ -/* Inlined methods */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroup // -////////////////////////////////////////////////////////////////////////////// - -inline -CSpawnGroup::CSpawnGroup(CPersistent& owner) -: CSpawnable >(owner) -, CProfileOwner() -, _NbSpawnedBot(0) -{ -} - -inline -void CSpawnGroup::setMoveProfileFromStateMachine(IAIProfileFactory* staticProfile) -{ - _MovingProfile.setAIProfile(this, staticProfile, true); -} - -inline -void CSpawnGroup::setActivityProfileFromStateMachine(IAIProfileFactory* staticProfile) -{ - _ActivityProfile.setAIProfile(this, staticProfile, true); -} - -inline -bool CSpawnGroup::isGroupAlive(uint32 const nbMoreKilledBot) const -{ - return ((sint32)_NbSpawnedBot-(sint32)_BotsToDespawn.size()-(sint32)nbMoreKilledBot)>0; -} - -inline -CGroup& CSpawnGroup::getPersistent() const -{ - return static_cast(CSpawnable >::getPersistent()); -} - -inline -CAliasCont const& CSpawnGroup::bots() const -{ - return getPersistent()._Bots; -} - -inline -CAliasCont& CSpawnGroup::bots() -{ - return getPersistent()._Bots; -} - -////////////////////////////////////////////////////////////////////////////// -// CGroup // -////////////////////////////////////////////////////////////////////////////// - -inline -bool CGroup::spawn() -{ - if (isSpawned()) - return true; - - if (!getSpawnCounter().remainToMax()) - return false; - - setSpawn(createSpawnGroup()); - return true; -} - -inline -void CGroup::despawnGrp() -{ - if (!isSpawned()) - return; - setSpawn(NULL); - if (_AutoDestroy) - getOwner()->groups().removeChildByIndex(getChildIndex()); -} - -inline -void CGroup::despawnBots(bool immediately) -{ - if (!isSpawned()) - return; - getSpawnObj()->despawnBots(immediately); -} - -inline -CBot* CGroup::getBot(uint32 index) -{ - if (index>=_Bots.size()) - return NULL; - return _Bots[index]; -} - -#endif - - - - - diff --git a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp b/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp deleted file mode 100644 index 5738af614..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_fauna.cpp +++ /dev/null @@ -1,1275 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_grp_fauna.h" -#include "ai_mgr_fauna.h" - -#include "continent_inline.h" -#include "dyn_grp_inline.h" - -using namespace MULTI_LINE_FORMATER; - -using namespace NLMISC; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -static char const* stateName(CSpawnGroupFauna::TState s) -{ - switch (s) - { - case CSpawnGroupFauna::StateDespawned: return "DESPAWNED"; - case CSpawnGroupFauna::StateSpawning: return "SPAWNING"; - case CSpawnGroupFauna::StateGrazing: return "GRAZING"; - case CSpawnGroupFauna::StateWandering: return "WANDERING"; - case CSpawnGroupFauna::StateResting: return "RESTING"; - default: - break; - } - return "UNKNOWN STATE"; -} - - -// helper : get a fauna xyr zone from a base zone or a zone reference -static inline const CFaunaGenericPlace *getFaunaGenericPlace(const CAIPlace *place) -{ - const CFaunaGenericPlace *faunaPlace = dynamic_cast(place); - nlassert(faunaPlace); - return faunaPlace; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpFauna static data // -////////////////////////////////////////////////////////////////////////////// - -CGrpFauna::CCycleDef const CGrpFauna::cycles[] = -{ - { CSpawnGroupFauna::StateSpawning, CGrpFauna::SPAWN_TIME, CGrpFauna::SPAWN_PLACE }, - { CSpawnGroupFauna::StateGrazing, CGrpFauna::EAT_TIME, CGrpFauna::EAT_PLACE }, - { CSpawnGroupFauna::StateResting, CGrpFauna::REST_TIME, CGrpFauna::REST_PLACE } -}; - -uint32 const CGrpFauna::nbCycle = sizeof(CGrpFauna::CCycleDef) / sizeof(CGrpFauna::cycles); - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupFauna // -////////////////////////////////////////////////////////////////////////////// - -CSpawnGroupFauna::CSpawnGroupFauna(CPersistent& owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlag) -: CSpawnGroup(owner) -, _DespawnImmediately(false) -, _PathCont(denyFlag) -{ - // variables for CAIMgrFauna's update prioritisation system - _UpdatePriority = 0; // 0..15 - priority class (distance based - 0 is highest priority) - - _Leader = (CBotFauna*)NULL; - - _Timer.set(0); - - // pick a spawn place - sint spawnPlace = getPersistent().getNextPlace(NULL, CAIPlaceXYRFauna::FLAG_SPAWN); - if (spawnPlace == CGrpFauna::INVALID_PLACE) - { - std::vector candidates; - // seek place with the smallest index - sint minIndex = INT_MAX; - for (uint k = 0; k < getPersistent().places().size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(getPersistent().places()[k]); - minIndex = std::min((sint) place->getIndex(), minIndex); - } - for (uint k = 0; k < getPersistent().places().size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(getPersistent().places()[k]); - if ((sint) place->getIndex() == minIndex) - { - candidates.push_back(k); - } - } - spawnPlace = (sint) candidates[rand() % candidates.size()]; - //nlwarning("No spawn place found for group %s, using place with smallest index", getPersistent().getName().c_str()); - } - setPlace(spawnPlace); - _CenterPos = _TargetPlace->midPos(); - - // make sure memory's been allocated for the bots - if (bots().size()==0) - getPersistent().allocateBots(); - - if (bots().size()!=0) - { - uint32 const spawnTimer = getPersistent().timer(CGrpFauna::SPAWN_TIME); - _Timer.set(spawnTimer); - } - - // setup the update priority system variables - _LastUpdate = CTimeInterface::gameCycle(); - _DeltaTime = 1; - - _CurrentCycle = 0; - - setMustDespawnBots(false); -} - -CSpawnGroupFauna& CSpawnBotFauna::spawnGrp() -{ - return static_cast(CSpawnBot::spawnGrp()); -} - -void CSpawnGroupFauna::despawnGrp() // critical code (despawn 'this' object). -{ - CGrpFauna* faunaGrpPtr = &getPersistent(); - faunaGrpPtr->mgr().addToSpawn(faunaGrpPtr); - faunaGrpPtr->despawnGrp(); -} - -void CSpawnGroupFauna::recalcUpdatePriorityDeltaAndGroupPos() -{ - // recalculate the priority delta score for the group based on players in vision - bool speedUpdate = false; - - sint32 grpPosx = 0; - sint32 grpPosy = 0; - sint32 nbBots = 0; - - FOREACH(it, CCont, bots()) - { - CBotFauna *bot=NLMISC::safe_cast(*it); - CSpawnBotFauna *botFauna=bot->getSpawn(); - if (botFauna) - { - if (botFauna->isAlive()) - { - const CAIPosMirror &pos=botFauna->pos(); - grpPosx+=(sint32)(pos.x().asInt()*(1.0/1000.0)); - grpPosy+=(sint32)(pos.y().asInt()*(1.0/1000.0)); - nbBots++; - } - - if (botFauna->havePlayersAround()) - { - speedUpdate=true; - break; - } - - } - - } - - if (nbBots>0) - { - _CenterPos = CAIVector(grpPosx/nbBots,grpPosy/nbBots); - } - - if (speedUpdate) - _UpdatePriority = 1; - else - _UpdatePriority = 31; - - // if players are approaching then crop our move time - uint32 curTime = CTimeInterface::gameCycle (); - if (((sint32)(curTime-_LastUpdate))>(_UpdatePriority+1)) - _LastUpdate = curTime-(_UpdatePriority+1); - - _DeltaTime = curTime-_LastUpdate; -} - -CBotFauna* CSpawnGroupFauna::findLeader() -{ - CBotFauna* possibleLeader = NULL; - - CCont::iterator it = bots().begin(); - CCont::iterator itEnd = bots().end(); - while (it!=itEnd) - { - CBotFauna* botPtr = static_cast(*it); - if (botPtr->isSpawned()) // if bot is spawned - { - if (botPtr->getSpawnObj()->isAlive()) // is alive - { - possibleLeader=botPtr; - if (_TargetPlace->atPlace(possibleLeader->getSpawn()->pos())) // and eventually in place - return possibleLeader; - } - } - ++it; - } - return possibleLeader; -} - -void CSpawnGroupFauna::update() -{ - H_AUTO(GrpFaunaUpdate); - - ++AISStat::GrpTotalUpdCtr; - ++AISStat::GrpFaunaUpdCtr; - - getPersistent().updateStateInstance(); - - if (_CurrentCycle==std::numeric_limits::max()) - return; - - // Respawn -// breakable - { - H_AUTO(GrpFaunaUpdateDealWithDead); - checkDespawn (); - - if (nbBotToRespawn()>0) - { - if (nbSpawnedBot()>0) // (getPersistent().bots().size()/2)) - { - if (getPersistent().timeAllowSpawn ()) - { - checkRespawn(); - } - } - else - { - // critical code (despawn 'this' object). - despawnGrp(); - return; // forced becoz the group is despawn and respawned (will be updated next time). - } - } - } - - // recalculate our priority rating in function of distance from player - // if players are approaching then crop our move time - recalcUpdatePriorityDeltaAndGroupPos(); - - // identify the leader, call type-dependent update and calculate group position and radius - { - H_AUTO(GrpFaunaUpdateByType); - - H_TIME(GrpFaunaUpdateFindLeader, _Leader = findLeader();); - // locate the first live bot and treat them as the group leader - - // update the state variable (think about changing state) - H_TIME(GrpFaunaUpdateCheckTimer, checkTimers();); - - H_TIME(GrpFaunaUpdateGeneralUpdate, generalUpdate();); - - // re-find leader as it could have been despawn .. - _Leader = findLeader(); - } - // record the current tick as last update time for the group - _LastUpdate = CTimeInterface::gameCycle(); -} - -void CSpawnGroupFauna::generalUpdate(TState state) -{ - H_TIME(GrpFaunaReorganize, reorganize(bots().begin(), bots().end());); - - { - H_AUTO(GrpFaunaUpdDespawnTest); - - if ( !mustDespawnBots() - && getUpdatePriority ()>(2<<3) - && !getPersistent().timeAllowSpawn() ) // 40*3 -> more than 120 meters far from players - { - setMustDespawnBots (true); - } - } - - if (state==StateUndefined) - state=CGrpFauna::cycles[_CurrentCycle]._Activity; - - // call a type-dependent update - switch (getPersistent().getType()) - { - case FaunaTypeHerbivore: - case FaunaTypePredator: - { - H_AUTO(GrpFaunaUpdNonPlant); - switch (state) // updateAnimals. - { - case StateDespawned: break; - case StateSpawning: updateSpawning(); break; - case StateGrazing: updateActivity(ACTIVITY_GRAZING); break; - case StateWandering: updateActivity(ACTIVITY_WANDERING); break; - case StateResting: updateActivity(ACTIVITY_RESTING); break; - default: nlwarning("CSpawnGroupFauna::updateAnimals FAILED because state not valid: %d",state); - } - } - break; - - case FaunaTypePlant: - { - H_AUTO(GrpFaunaUpdPlant); - // run the state behaviour code - switch (state) // updatePlants. - { - case StateDespawned: break; - case StateSpawning: updateSpawning(); break; - case StateGrazing: updateActivity(ACTIVITY_PLANTIDLE); break; - case StateWandering: updateActivity(ACTIVITY_PLANTIDLE); break; - case StateResting: updateActivity(ACTIVITY_PLANTIDLE); break; - default: nlwarning("CSpawnGroupFauna::updatePlants FAILED because state not valid: %d",state); - } - } - break; - - default: nlwarning("CSpawnGroupFauna::update() FAILED because group type not valid: %d",getPersistent().getType()); - } -} - -bool CSpawnGroupFauna::isSpawning() -{ - return CGrpFauna::cycles[_CurrentCycle]._Activity == StateSpawning; -} - -void CSpawnGroupFauna::updateSpawning() -{ - // check if we have some bots to spawn to reach timer (proportionnaly). - if ( (!mustDespawnBots()) - && ( ( _Timer.timeRemaining()==0 - && nbSpawnedBot()isSpawned()) - { - incCurrentCycle(); - generalUpdate(); - return; - } - - // identify the bot to spawn - uint count=0; - { - CBot* faunaPt=NULL; - for (i=0;iisSpawned()) - break; - } - if (j(bots()[count]); - - faunaPt->setSheet (/*const_cast(*/curPop[i].getCreatureSheet()/*)*/); - faunaPt->reSpawn (); - } - - // if this is the first bot to be spawned in the group then st up the leader pointer to point to it - // and set the group type - if (count==0) - { - _Leader = findLeader(); - } - - } - // to all intent and purpose consider that our bots are wandering - generalUpdate(StateWandering); -} - -void CSpawnGroupFauna::incCurrentCycle() -{ - setCurrentCycle(_CurrentCycle + 1); -} - -void CSpawnGroupFauna::setCurrentCycle(uint32 cycle) -{ - if (getPersistent().places().isEmpty()) - { - nlwarning("No places in fauna group %s", getPersistent().getName().c_str()); - return; - } - // did we start a new cycle ? - if (cycle>=(sizeof(CGrpFauna::cycles)/sizeof(CGrpFauna::CCycleDef))) - cycle=1; - - const CFaunaGenericPlace *targetPlacePtr = getFaunaGenericPlace(targetPlace()); - - sint nextPlace = CGrpFauna::INVALID_PLACE; - // search a place that match current cycle - // First we search a neighbour place that has wanted activity - // otherwise we change activity to the one we found - switch(CGrpFauna::cycles[cycle]._Place) - { - case CGrpFauna::EAT_PLACE: - nextPlace = getPersistent().getNextPlace(targetPlacePtr, CAIPlaceXYRFauna::FLAG_EAT); - if (nextPlace == CGrpFauna::INVALID_PLACE) - { - nextPlace = getPersistent().getNextPlace(targetPlacePtr, CAIPlaceXYRFauna::FLAG_REST); - if (nextPlace != CGrpFauna::INVALID_PLACE) - { - cycle = CGrpFauna::REST_PLACE; // force to rest - } - else - { - nextPlace = targetPlace()->getChildIndex(); - // remains in the same place - if (!targetPlacePtr->getFlag(CAIPlaceXYRFauna::FLAG_EAT)) - { - // can't eat there, so force to rest - cycle = CGrpFauna::REST_PLACE; // force to rest - } - } - } - break; - case CGrpFauna::REST_PLACE: - nextPlace = getPersistent().getNextPlace(targetPlacePtr, CAIPlaceXYRFauna::FLAG_REST); - if (nextPlace == CGrpFauna::INVALID_PLACE) - { - nextPlace = getPersistent().getNextPlace(targetPlacePtr, CAIPlaceXYRFauna::FLAG_EAT); - if (nextPlace != CGrpFauna::INVALID_PLACE) - { - cycle = CGrpFauna::EAT_PLACE; // force to eat - } - else - { - nextPlace = targetPlace()->getChildIndex(); - // remains in the same place - if (!targetPlacePtr->getFlag(CAIPlaceXYRFauna::FLAG_REST)) - { - // can't rest there, so force to eat - cycle = CGrpFauna::EAT_PLACE; // force to rest - } - } - } - break; - } - _CurrentCycle = cycle; - setPlace(nextPlace); - - if (_CurrentCycle==CGrpFauna::EAT_PLACE) - { - for (CCont::iterator it=bots().begin(), itEnd=bots().end();it!=itEnd;++it) - { - CBotFauna *const faunaBot=NLMISC::safe_cast(*it); - CSpawnBotFauna *const faunaSpawnBot= faunaBot->getSpawn(); - if (!faunaSpawnBot) - continue; - - faunaSpawnBot->hungry()=faunaSpawnBot->radius(); - } - } -} - -void CSpawnGroupFauna::updateActivity(TProfiles activity) -{ - FOREACH(it, CCont, bots()) - { - CBotFauna* bot=NLMISC::safe_cast(*it); - if (bot->isSpawned()) - bot->getSpawn()->update(activity,getDt()); - } -} - -void CSpawnGroupFauna::checkTimers() -{ - if (CGrpFauna::cycles[_CurrentCycle]._Activity==StateSpawning) - return; - - if (!_ArrivedInZone) // if we are changing the current activity zone. - { - if ( !_Leader.isNULL() - && _Leader->isSpawned()) - { - const CAIPos leaderPos(_Leader->getSpawn()->pos()); - const CAIPos midPos=_TargetPlace->midPos(); // better is very possible. - - if (leaderPos.distTo(midPos)<_TargetPlace->getRadius()) // si leader dans la zone. - { - _ArrivedInZone=true; // we desactivate the boolean. - const CFaunaGenericPlace *faunaPlace = getFaunaGenericPlace(targetPlace()); - NLMISC::CRandom rnd; - uint32 stayTime = faunaPlace->getMinStayTime() + (sint32) (rnd.frand() * ((sint32) faunaPlace->getMaxStayTime() - (sint32) faunaPlace->getMinStayTime())); - _Timer.set(stayTime); - /* - nlwarning("Group %s : Setting stay time to %d in place %s with index %d", - getPersistent().getName().c_str(), - (int) stayTime, - faunaPlace->getName().c_str(), - (int) faunaPlace->getIndex()); - */ - - } - - } - - } - else - { - // nlwarning("Group %s : Timer = %d", getPersistent().getName().c_str(), (int) (100 * _Timer.timeRemaining() / _Timer.totalTime())); - if (_Timer.test()) // si fin de timer. - incCurrentCycle(); - } -} - -void CSpawnGroupFauna::spawnBots() -{ - setMustDespawnBots(false); - _CurrentCycle = 0; // first activity == spawning. - nlassert(bots().size()>0); - _Timer.set(getPersistent().timer(CGrpFauna::SPAWN_TIME)); -} - -void CSpawnGroupFauna::despawnBots(bool immediately) -{ - setDespawnImmediately(immediately); - setMustDespawnBots(); -} - -CAIPos const& CSpawnGroupFauna::magnetPos() const -{ - return targetPlace()->midPos(); -} - -float CSpawnGroupFauna::magnetRadiusNear() const -{ - return targetPlace()->getRadius()*(7.0f/8.0f); -} - -float CSpawnGroupFauna::magnetRadiusFar() const -{ - return targetPlace()->getRadius()*(9.0f/8.0f); -} - -CGrpFauna& CSpawnGroupFauna::getPersistent() -{ - return static_cast(CSpawnGroup::getPersistent()); -} - -uint32 CSpawnGroupFauna::getCurrentCycleTime() -{ - return getPersistent().timer(CGrpFauna::cycles[_CurrentCycle]._Time); -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpFauna // -////////////////////////////////////////////////////////////////////////////// - - -uint32 CGrpFauna::refTimer(TTime time) -{ - switch(time) - { - case EAT_TIME: return 250; - case REST_TIME: return 250; - case SPAWN_TIME: return 30; - case CORPSE_TIME: return 120; - case RESPAWN_TIME: return 45; // "Backward" compatibility: 45 seconds after the corpse is despawned (after corpse time, or when looted) - default: - nlassert(0); - break; - } - return 0; -} - -CGrpFauna::CGrpFauna(CMgrFauna* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CGroup(mgr, denyFlags, aliasTree) -, CDynGrpBase() -, CPersistentStateInstance(*mgr->getStateMachine()) -{ - - // state - - _CurPopulation = std::numeric_limits::max(); - - _CurrentCycle = std::numeric_limits::max(); - - // default values. - setTimer(EAT_TIME, refTimer(EAT_TIME)); - setTimer(REST_TIME, refTimer(REST_TIME)); - setTimer(SPAWN_TIME, refTimer(SPAWN_TIME)); - setTimer(CORPSE_TIME, refTimer(CORPSE_TIME)); - setTimer(RESPAWN_TIME, refTimer(RESPAWN_TIME)); -} - -void CGrpFauna::stateChange(CAIState const* oldState, CAIState const* newState) -{ -} - -std::string CGrpFauna::getOneLineInfoString() const -{ - return std::string("Fauna group '") + getName() + "'"; -} - -std::vector CGrpFauna::getMultiLineInfoString() const -{ - std::vector container; - - - pushTitle(container, "CGrpFauna"); - pushEntry(container, "id=" + CGroup::getIndexString()); - container.back() += " alias=" + getAliasString(); - container.back() += " name=" + getName(); - pushEntry(container, "fullname=" + CGroup::getFullName()); - FOREACHC(it, CCont, _Populations) - { - CPopulation const* pop = *it; - uint32 index = pop->getChildIndex(); - pushEntry(container, "- population["+toString(index)+"]: "+((_CurPopulation==index)? "* ACTIVE *": "")); - - for (uint j=0; jsize(); ++j) - { - CPopulationRecord& popRecord = (*pop)[j]; - pushEntry(container, "bots:"); - container.back() += " count="+toString(popRecord.getBotCount(getCountMultiplierFlag())); - if (popRecord.getCreatureSheet()==NULL) - container.back() += " "; - else - container.back() += " sheet='"+popRecord.getCreatureSheet()->SheetId().toString()+"'"; - } - } - FOREACHC(it, CCont, bots()) - { - std::vector strings = it->getMultiLineInfoString(); - FOREACHC(itString, std::vector, strings) - container.push_back(" " + *itString); - } - pushFooter(container); - - - return container; -} - -IAliasCont* CGrpFauna::getAliasCont(TAIType type) -{ - switch(type) - { - case AITypePlaceFauna: - case AITypePlace: - return &_Places; - case AITypeGrpFaunaPop: - return &_Populations; - default: - return NULL; - } -} - -CAliasTreeOwner* CGrpFauna::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - if (!cont) - return NULL; - - CAliasTreeOwner* child = NULL; - - switch (aliasTree->getType()) - { - // create the child and adds it to the corresponding position. - case AITypePlaceFauna: - child = new CAIPlaceXYRFauna(this, aliasTree); - break; - case AITypePlace: - { - std::string const& name = aliasTree->getName(); - CAIPlaceXYRFauna *faunaPlace = new CAIPlaceXYRFauna(this, aliasTree); - child = faunaPlace; - uint placeIndex = faunaPlace->setupFromOldName(name); - nlassert(placeIndex!=std::numeric_limits::max()); - - if (placeIndex!=std::numeric_limits::max()) - cont->addAliasChild(child, placeIndex); - - return child; - } - break; - case AITypeGrpFaunaPop: - child = new CPopulation(this, aliasTree); - break; - } - - if (child) - cont->addAliasChild(child); - return child; -} - -void CGrpFauna::displayPlaces(CStringWriter& stringWriter) const -{ - FOREACHC(it, CCont, _Places) - { - it->display(stringWriter); - } -} - - -CGrpFauna::~CGrpFauna() -{ - if (isSpawned()) // to avoid bad CDbgPtr link interpretation - { - despawnGrp(); - } - - // unlink all child persistent state instance - while (!_PSIChilds.empty()) - { - _PSIChilds.back()->setParentStateInstance(NULL); - } - _PSIChilds.clear(); -} - -void CGrpFauna::setEvent(uint eventId) -{ - nlassert(eventId<10); - processStateEvent(getEventContainer().EventUserEvent[eventId]); -} - -void CGrpFauna::serviceEvent (const CServiceEvent &info) -{ - CGroup::serviceEvent(info); - - if ((info.getServiceName() == "EGS") && (info.getEventType() == CServiceEvent::SERVICE_UP)) - { - processStateEvent(getEventContainer().EventEGSUp); - } - -} - -NLMISC::CSmartPtr CGrpFauna::createSpawnGroup() -{ - return new CSpawnGroupFauna(*this, getAStarFlag()); -} - -bool CGrpFauna::spawn() -{ - if (!getSpawnCounter().remainToMax()) - return false; - - setStartState(getStartState()); // stateInstance. - return spawnPop(std::numeric_limits::max()); -} - -bool CGrpFauna::timeAllowSpawn(uint32 popVersion) const -{ - if (popVersion==12345) - { - popVersion = _CurPopulation; - } - - CPopulation* popPtr = _Populations[popVersion]; -#ifdef NL_DEBUG - nlassert(popPtr); -#endif - if (!popPtr) - { - return false; - } - TSpawnType st = popPtr->getSpawnType(); - - bool const& isDay = CTimeInterface::isDay(); - - return (st==SpawnTypeAlways) || (isDay&&st==SpawnTypeDay) || (!isDay&&st==SpawnTypeNight); -} - -bool CGrpFauna::spawnPop(uint popVersion) -{ - if (places().isEmpty()) return false; - for (uint k = 0; k < places().size(); ++k) - { - if (!places()[k]->worldValidPos().isValid()) return false; - } - /* - if ( !places()[SPAWN_PLACE]->worldValidPos().isValid() - || !places()[EAT_PLACE]->worldValidPos().isValid() - || !places()[REST_PLACE]->worldValidPos().isValid()) // coz time is not initialized yet .. - return false;*/ - - // check compatibility. - /* - { - RYAI_MAP_CRUNCH::CCompatibleResult res; - areCompatiblesWithoutStartRestriction(places()[SPAWN_PLACE]->worldValidPos(), places()[EAT_PLACE]->worldValidPos(), getAStarFlag(), res); - if (!res.isValid()) - return false; - areCompatiblesWithoutStartRestriction(places()[SPAWN_PLACE]->worldValidPos(), places()[REST_PLACE]->worldValidPos(), getAStarFlag(), res); - if (!res.isValid()) - return false; - areCompatiblesWithoutStartRestriction(places()[EAT_PLACE]->worldValidPos(), places()[REST_PLACE]->worldValidPos(), getAStarFlag(), res); - if (!res.isValid()) - return false; - } - */ - // check each arc of the graph - for (uint k = 0; k < places().size(); ++k) - { - nlassert(_Places[k]); - checkArcs(*_Places[k]); - } - - - // check flags .. - for (uint32 i=0;iworldValidPos().isValid()) - return false; - const RYAI_MAP_CRUNCH::TAStarFlag flags=places()[i]->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); - if ((flags&getAStarFlag())!=0) - return false; - } - - // check the validity of the input parameter - if (popVersion!=std::numeric_limits::max() && popVersion>=_Populations.size()) - { - nlwarning("CGrpFauna::spawn(idx) FAILED for group %s because idx (%d) >= _Populations.size() (%d)",this->CGroup::getFullName().c_str(),popVersion,_Populations.size()); - return false; - } - - popVersion = std::numeric_limits::max(); - - // if we are in a cycle. - if (_CurrentCycle != std::numeric_limits::max()) - { - Cycle const& cycle = _Cycles[_CurrentCycle]; - - // this to avoid bug dues to bad data initialization. - do - { - ++_CurrentCycleIndex; - } - while ( _CurrentCycleIndex<(sint32)cycle._PopList.size() - && !_Populations[cycle._PopList[_CurrentCycleIndex]]); - - if (_CurrentCycleIndex<(sint32)cycle._PopList.size()) - { - popVersion=cycle._PopList[_CurrentCycleIndex]; - - if (!timeAllowSpawn(popVersion)) - { - popVersion = std::numeric_limits::max(); - } - } - - if (popVersion == std::numeric_limits::max()) - { - _CurrentCycle = std::numeric_limits::max(); - } - } - - // if the population version has not been specified then select one at weighted random with day/night difference. - if (popVersion == std::numeric_limits::max()) - { - uint32 totalWeight = 0; - - // we can precalculate this, but it won't appears so much to be called. - FOREACH(it, CCont, _Populations) - { - CPopulation const& pop = *(*it); - if (!timeAllowSpawn(pop.getChildIndex())) - continue; - totalWeight += pop.getWeight(); - } - - if (totalWeight==0) - return false; - - { - sint32 rnd = CAIS::rand32(totalWeight); - FOREACH(it, CCont, _Populations) - { - CPopulation const& pop = *(*it); - if (!timeAllowSpawn(pop.getChildIndex())) - continue; - - rnd -= pop.getWeight(); - if (rnd>0) // we found the population to spawn. :) - continue; - - popVersion=pop.getChildIndex(); - break; - } - } - -#if !FINAL_VERSION - nlassert(popVersion != std::numeric_limits::max()); -#endif - if (popVersion == std::numeric_limits::max()) - return false; - - // find if we are starting a new cycle .. - for (uint32 i=0;i<_Cycles.size();i++) - { - nlassert(_Cycles[i]._PopList.size()>0); - if (_Cycles[i]._PopList[0]!=popVersion) - continue; - - _CurrentCycle = i; - _CurrentCycleIndex = 0; - } - } - - if (popVersion >= _Populations.size()) - { - nlwarning("Problem with pop size for group id %s, NAME = %s", this->CGroup::getFullName().c_str(), getName().c_str() ); - return false; - } - - // setup the pointer to the current population - _CurPopulation = popVersion; - - // check that we have a defined spawn location - if (!_Places[SPAWN_PLACE]) - { - nlwarning("CGrpFauna::spawn(idx) FAILED for group %s because _spawnPlace==NULL",this->CGroup::getFullName().c_str()); - return false; - } - - // if the group is already spawned despawn it - if (isSpawned()) - { - despawnGrp(); - } - - nlassert(_CurPopulation != std::numeric_limits::max()); - - ////////////////////////////////////////////////////////////////////////// - // Init the group type. - setType ((*_Populations[_CurPopulation])[0].getCreatureSheet()->FaunaType()); // gets the first population record of the population to spawn. - - { - uint32 botCount=0; - uint32 i; - CPopulation& curPop = *populations()[_CurPopulation]; - for (i=0; iFaunaType() == getType()) - continue; - - if (getGroupDesc()) // Dyn system. - { - nlwarning("****** WARNING: Different Fauna Type in Template Group %s", getGroupDesc()->getFullName().c_str()); - } - else - { - nlwarning("****** WARNING: Different Fauna Type in group %s", this->CGroup::getFullName().c_str()); - } - } - bots().setChildSize(botCount); // set the good size for bots vector. - - for (i=0;i::max(); -} - -// reads cycle from primitive (string representation). -void CGrpFauna::setCyles(std::string const& cycles) -{ - uint32 strIndex = 0; - uint32 curCycle = std::numeric_limits::max(); - - while (strIndex='A' && carac<='Z') - carac += 'a'-'A'; - - if (carac>='a' && carac<='z') - { - if (curCycle == std::numeric_limits::max()) - { - curCycle = (uint32)_Cycles.size(); - _Cycles.push_back(Cycle()); - } - Cycle& CycleRef = _Cycles[curCycle]; - CycleRef._PopList.push_back((uint16)(carac-'a')); - } - else - { - curCycle = std::numeric_limits::max(); - } - } -} - -void CGrpFauna::setPopulation(CPopulation* pop) -{ - CPopulation* sameAliasPop = NULL; - uint32 index = std::numeric_limits::max(); - - if (pop) - sameAliasPop = _Populations.getChildByAlias(pop->getAlias()); - - if (pop && pop->size()==0) // no population record :( - pop=NULL; - - if (sameAliasPop) // Alias already present ? - { - index = sameAliasPop->getChildIndex(); - _Populations.addChild(pop, index); // automatic deletion with smart pointers - } - else - { - _Populations.addChild(pop); // else simply add it to the populations container - } - - // if it was the current population, respawn it. (to check with designers?) - if (index==_CurPopulation) - { - if (isSpawned()) // if spawned, despawn. - getSpawnObj()->despawnGrp(); - } -} - -//---------------------------------------------------------------------------- -// private utilities -//---------------------------------------------------------------------------- - -void CGrpFauna::allocateBots() -{ - uint maxPopulation = 0; - - // work out how much space we need - CCont::iterator it = populations().begin(); - CCont::iterator itEnd = populations().end(); - - while (it!=itEnd) - { - CPopulation* pop = *(it); - uint count=0; - - for (sint j=(sint)pop->size()-1;j>=0;j--) - count+=(*pop)[j].getBotCount(getCountMultiplierFlag()); - - if (count>maxPopulation) - maxPopulation=count; - ++it; - } - - _Bots.setChildSize(maxPopulation); - for (uint32 i=0;i(getOwner()); -} - -CAIS::CCounter& CGrpFauna::getSpawnCounter() -{ - return CAIS::instance()._FaunaBotCounter; -} - -void CGrpFauna::lastBotDespawned() -{ - // send message - processStateEvent(getEventContainer().EventLastBotDespawned); -} - -void CGrpFauna::firstBotSpawned() -{ - setFirstBotSpawned(); -} - -sint CGrpFauna::getNextPlace(const CFaunaGenericPlace *startPlace, CAIPlaceXYRFauna::TFlag wantedFlag) const -{ - nlassert(wantedFlag < CAIPlaceXYRFauna::FLAG_COUNT); - std::vector candidates; - std::vector activeCandidates; - if (!startPlace) - { - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - if (place->getFlag(wantedFlag)) - { - if (place->getActive()) - { - activeCandidates.push_back(_Places[k]->getChildIndex()); - } - else - { - candidates.push_back(_Places[k]->getChildIndex()); - } - } - } - } - else - { - sint minIndex = INT_MAX; - sint firstIndex = INT_MAX; - if (startPlace->getReachNext()) - { - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - firstIndex = std::min(firstIndex, (sint) place->getIndex()); - if (place->getIndex() < minIndex && place->getIndex() > startPlace->getIndex()) - { - minIndex = place->getIndex(); - } - } - minIndex = std::max(minIndex, firstIndex); - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - if ((sint) place->getIndex() == minIndex) - { - if (place->getActive()) - { - activeCandidates.push_back(_Places[k]->getChildIndex()); - } - else - { - candidates.push_back(_Places[k]->getChildIndex()); - } - } - } - } - // includes all places reachable from the arcs list - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - if (place != startPlace && place->getFlag(wantedFlag)) - { - // if this place is reachable from current place arcs ... - if (std::find(startPlace->getArcs().begin(), startPlace->getArcs().end(), place->getIndex()) != startPlace->getArcs().end()) - { - // ... then it is a candidate. - if (place->getActive()) - { - activeCandidates.push_back(_Places[k]->getChildIndex()); - } - else - { - candidates.push_back(_Places[k]->getChildIndex()); - } - } - } - } - } - // active vertices are taken in priority - // nlwarning("%d active place, %d unactive places", (int) activeCandidates.size(), (int) candidates.size()); - if (!activeCandidates.empty()) - { - return (sint) activeCandidates[rand() % activeCandidates.size()]; - } - // if current place is valid then don't move - if (startPlace && startPlace->getActive()) return CAIPlaceXYRFauna::INVALID_PLACE; - // otherwise select a place in unactive places - if (candidates.empty()) return CAIPlaceXYRFauna::INVALID_PLACE; - return (sint) candidates[rand() % candidates.size()]; -} - -bool CGrpFauna::checkArcs(const CAIPlace &startPlace) const -{ - const CFaunaGenericPlace *startPlaceGeneric = getFaunaGenericPlace(&startPlace); - // TODO nico : this function has a lot of similarities with CGrpFauna::getNextPlace - // adding a getArcs function would be nice - sint minIndex = INT_MAX; - sint firstIndex = INT_MAX; - if (startPlaceGeneric->getReachNext()) - { - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - firstIndex = std::min(firstIndex, (sint) place->getIndex()); - if (place->getIndex() < minIndex && place->getIndex() > startPlaceGeneric->getIndex()) - { - minIndex = place->getIndex(); - } - } - minIndex = std::max(minIndex, firstIndex); - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - if ((sint) place->getIndex() == minIndex) - { - RYAI_MAP_CRUNCH::CCompatibleResult res; - areCompatiblesWithoutStartRestriction(startPlace.worldValidPos(), _Places[k]->worldValidPos(), getAStarFlag(), res); - if (!res.isValid()) return false; - } - } - } - // includes all places reachable from the arcs list - for (uint k = 0; k < _Places.size(); ++k) - { - const CFaunaGenericPlace *place = getFaunaGenericPlace(_Places[k]); - if (place != startPlaceGeneric) - { - if (std::find(startPlaceGeneric->getArcs().begin(), startPlaceGeneric->getArcs().end(), place->getIndex()) != startPlaceGeneric->getArcs().end()) - { - // this place is in current arc list - RYAI_MAP_CRUNCH::CCompatibleResult res; - areCompatiblesWithoutStartRestriction(startPlace.worldValidPos(), _Places[k]->worldValidPos(), getAStarFlag(), res); - if (!res.isValid()) return false; - } - } - } - return true; -} - -void CSpawnGroupFauna::setPlace(int placeIndex) -{ - const CFaunaGenericPlace *place = getFaunaGenericPlace(getPersistent().places()[placeIndex]); - //nlwarning("Going to place %s with index %d", getPersistent().places()[placeIndex]->getName().c_str(), place->getIndex()); - - if ((int) getPersistent().places().size() <= placeIndex) - { - nlwarning("Bad place index for fauna group %s", getPersistent().getName().c_str()); - } - - // const CFaunaGenericPlace *faunaPlace = getFaunaGenericPlace(getPersistent().places()[placeIndex]); - // nlwarning("Group %s : Chosing place %s (%d) with graph index %d", getPersistent().getName().c_str(), faunaPlace->getName().c_str(), placeIndex, (int) faunaPlace->getIndex()); - - _TargetPlace = getPersistent().places()[placeIndex]; -#if !FINAL_VERSION - const RYAI_MAP_CRUNCH::TAStarFlag flags=targetPlace()->worldValidPos().getTopologyRef().getCstTopologyNode().getFlags(); - nlassert((flags&getPersistent().getAStarFlag())==0); -#endif - _PathCont.setDestination(targetPlace()->getVerticalPos(), targetPlace()->worldValidPos()); - _ArrivedInZone = false; -} - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_grp_fauna.h b/code/ryzom/server/src/ai_service/ai_grp_fauna.h deleted file mode 100644 index e6363aa5d..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_fauna.h +++ /dev/null @@ -1,344 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_GRP_FAUNA_H -#define RYAI_GRP_FAUNA_H - -#include "server_share/r2_variables.h" -#include "ai_vision.h" -#include "timer.h" -#include "ai_place_xyr.h" -#include "ai_grp.h" -#include "ai_bot_fauna.h" -#include "owners.h" -#include "state_instance.h" - -#include "ai_generic_fight.h" - -class CGrpFauna; -class CSpawnGroupFauna; - -#define GROUP_VISION_UPDATE_RADIUS (80) - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupFauna // -////////////////////////////////////////////////////////////////////////////// - -/// This class represents a fauna group - it may be specialised at a later date -class CSpawnGroupFauna -: public CSpawnGroup -, public CFightOrganizer -{ -public: - // public enums ---------------------------------------------------- - enum TState - { - StateUndefined, - StateDespawned, - StateSpawning, - StateGrazing, - StateWandering, - StateResting - }; - -public: - CSpawnGroupFauna(CPersistent& owner, RYAI_MAP_CRUNCH::TAStarFlag denyFlag); - - bool isSpawning(); - - void update(); - - /// @name CFightOrganizer implementation - //@{ - virtual void setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy); - virtual void setHeal(CSpawnBot* bot, CAIEntityPhysical* target); - virtual void setNoFight(CSpawnBot* bot); - virtual void setFlee(CSpawnBot* bot, CAIVector& fleeVect); - virtual void setReturnAfterFight(CSpawnBot* bot); - //@} - - virtual void spawnBots(); - virtual void despawnBots(bool immediately); - - // overrides the init to avoid automatic bot spawn .. - void spawnBotOfGroup() { } - - virtual void despawnGrp(); // critical code (despawn 'this' object). - - uint32 getLastUpdate() const { return _LastUpdate; } - - // Update Rate feature. - int getUpdatePriority() const { return IsRingShard? (_UpdatePriority&7): _UpdatePriority; } - // overloading to recalc the priority update rate. - void recalcUpdatePriorityDeltaAndGroupPos(); - - CAIPos const& magnetPos() const; - float magnetRadiusNear() const; - float magnetRadiusFar() const; - - void resetTimer() { _Timer.set(0); } - - CGrpFauna& getPersistent(); - -// std::string buildDebugString(uint idx) const; - - void setPlace(int placeIndex); - - void incCurrentCycle(); - - void setCurrentCycle(uint32 cycle); - - uint32 getCurrentCycleTime(); - - CAIPlace* targetPlace() const { return _TargetPlace; } - - CPathCont& getPathCont() { return _PathCont; } - - CBotFauna* leader() const { return _Leader; } - - void setDespawnImmediately(bool immediately) { _DespawnImmediately = immediately; } - - bool despawnImmediately() { return _DespawnImmediately; } - - void setMustDespawnBots(bool toDespawnBots = true) { _MustDespawnBots=toDespawnBots; } - - bool mustDespawnBots() { return _MustDespawnBots; } - -private: - uint32 getDt() const { return _DeltaTime; } - - CBotFauna* findLeader(); - - // Behavior update method. - void generalUpdate(TState state = StateUndefined); - - // Update method for different states. - void updateSpawning(); - void updateActivity(AITYPES::TProfiles activity); - - void checkTimers(); // called at each update to see if the last timer delay has expired (if true calls updateCycles) - -private: - CPathCont _PathCont; - - NLMISC::CDbgPtr _TargetPlace; // a dynamic pointer to one of the above places - - bool _ArrivedInZone; // indicates that we have not reach the new zone - - NLMISC::CDbgPtr _Leader; // the individual in the group who is treated as the leader - CAITimer _Timer; - - uint32 _CurrentCycle; - - int _UpdatePriority; - uint32 _LastUpdate; // gamecycle at which update() last called - uint32 _DeltaTime; // Dt, simply - - bool _MustDespawnBots; // if its a day group and its night for instance. - bool _DespawnImmediately; // when MustdespawnBots, indicate if we must done it immedialtely or at best when no player can see it -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpFauna // -////////////////////////////////////////////////////////////////////////////// - -class CGrpFauna -: public CPlaceOwner -, public CPersistentStateInstance -, public CGroup -, public CDynGrpBase -, public CPopulationOwner -{ -public: - enum - { - INVALID_PLACE = CFaunaGenericPlace::INVALID_PLACE - }; - enum TPlaces - { - SPAWN_PLACE = 0, - EAT_PLACE, - REST_PLACE - }; - enum TTime - { - SPAWN_TIME = 0, - EAT_TIME, - REST_TIME, - CORPSE_TIME, - RESPAWN_TIME, - LAST_TIME - }; - struct CCycleDef - { - CSpawnGroupFauna::TState _Activity; - TTime _Time; - TPlaces _Place; - uint32 _NextCycle; - }; - - class Cycle - { - public: - virtual ~Cycle() { } - friend class CGrpFauna; - uint16 getPopIndex(int ind) - { - return _PopList[ind]; - } - std::vector _PopList; - }; - -public: - CGrpFauna(CMgrFauna* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - - virtual ~CGrpFauna(); - - RYZOMID::TTypeId getRyzomType() { return RYZOMID::creature; } - - CDynGrpBase* getGrpDynBase() { return this; } - - ////////////////////////////////////////////////////////////////////////// - // PersistentStateInstance - - CAliasTreeOwner* aliasTreeOwner() { return this; } - - CAIS::CCounter& getSpawnCounter(); - - bool timeAllowSpawn(uint32 popVersion = 12345) const; - - void stateChange(CAIState const* oldState, CAIState const* newState); - - CGroup* getGroup() { return this; } - - ////////////////////////////////////////////////////////////////////////// - - virtual void lastBotDespawned(); - virtual void firstBotSpawned(); - - // debugging stuff - CDebugHistory* getDebugHistory() { return this; } - - CPersistentStateInstance* getPersistentStateInstance() { return this; } - - virtual void setEvent(uint eventId); - virtual void serviceEvent (const CServiceEvent &info); - - virtual std::string getFullName() const { return CGroup::getFullName(); } - virtual std::string getIndexString() const { return CGroup::getIndexString(); } - - IAliasCont* getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree); - - NLMISC::CSmartPtr createSpawnGroup(); - - CSpawnGroupFauna* getSpawnObj() const { return NLMISC::type_cast(CGroup::getSpawnObj()); } - - void allocateBots(); - - // This struct is used to manage dead creatures and their corresponding respawned creature. - - // inheritted virtual interface ------------------------------------ - virtual bool spawn(); - bool spawnPop(uint popVersion); - virtual void despawnGrp(); - - // Methods for setting up static data ------------------------------ - void setType(AITYPES::TFaunaType type); - void setCyles(std::string const& cycles); - - // Methods for manageing population descriptions - void setPopulation(CPopulation *pop); - - // Methods for managing places - void setPlace(CAIPlace*& variable, CAIPlace* place); - void setupWanderPlace(); - - // Miscelaneous accessors ------------------------------------------ - CMgrFauna& mgr() const; - - // reference timer value - static uint32 refTimer(TTime time); - uint32 timer(TTime time) const { return _Timer[time]; } - void setTimer(TTime timer, uint32 time) { _Timer[timer] = time*10; } ///< we set time in seconds. - - AITYPES::TFaunaType getType() const { return _Type; } - - void setSpawnType(AITYPES::TSpawnType sp_type) { _SpawnType = sp_type; } - - void displayPlaces(CStringWriter& stringWriter) const; - - CAliasCont& places() { return _Places; } - CAliasCont& populations() { return _Populations; } - - AITYPES::CPropertySet& faction() { return _Faction; } - - static const CCycleDef cycles[]; - static const uint32 nbCycle; - - void setAutoSpawn(bool autoSpawn) { CGroup::setAutoSpawn(autoSpawn); if (!isAutoSpawn()) _CurrentCycle=std::numeric_limits::max(); } - - /// @name CChild implementation - //@{ - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - //@} - - /** Find next valid place with the wanted flags. - * If several places are valid, then one is picked randomly - * \return INVALID_PLACE if no such place exist - */ - sint getNextPlace(const CFaunaGenericPlace *startPlace, CAIPlaceXYRFauna::TFlag wantedFlag) const; - - // check that all places designated by the arcs of a given place are reachable - bool checkArcs(const CAIPlace &startPlace) const; - -public: - // Dynamic data modified during normal activity -------------------- - uint32 _CurPopulation; // which alternative bot population is active - -protected: - - // Static data initilised at init time ----------------------------- - - // basic data (name, id, pointer to manager, etc) - AITYPES::TFaunaType _Type; // FaunaTypeHerbivore, FaunaTypePredator, ... etc - - // Definition of a vector of vectors of classes for populations ---- - - CAliasCont _Populations; - CAliasCont _Places; - - AITYPES::TSpawnType _SpawnType; - - CAITimer _priorityRecalcTimer; // timer used to determine time of next recalc of _updateMask - - uint32 _Timer[LAST_TIME]; - - float _Aggro; - - /// Animat Addon - double _MotivationGroupProtection; // A value between 0 an 1 giving the importance of the group protection. - double _MotivationHarvestSap; // Motivation for the sap harvest. - - std::vector _Cycles; // Cycles List. - uint32 _CurrentCycle; // current Cycle. - sint32 _CurrentCycleIndex; // the pop index in the cycle - - AITYPES::CPropertySet _Faction; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_grp_npc.cpp b/code/ryzom/server/src/ai_service/ai_grp_npc.cpp deleted file mode 100644 index 056293a25..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_npc.cpp +++ /dev/null @@ -1,1219 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "server_share/r2_variables.h" -#include "ai_grp_npc.h" -#include "ai_mgr_npc.h" -#include "ai_bot_npc.h" -#include "game_share/base_types.h" -#include "npc_description_msg.h" -#include "ai_player.h" -#include "ai_profile_npc.h" -#include "server_share/r2_variables.h" - -extern bool simulateBug(int bugId); - -#include "dyn_grp_inline.h" - -using namespace MULTI_LINE_FORMATER; - -using namespace NLMISC; -using namespace std; -using namespace AITYPES; - -extern CVariable DefaultNpcAggroDist; -extern CVariable DefaultEscortRange; - -static bool VerboseLog=false; -#define LOG if (!VerboseLog) {} else nlinfo - -// 5 minute in ticks (10 Hz) -uint32 DEFAULT_RESPAWN_DELAY = 5*60*10; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupNpc // -////////////////////////////////////////////////////////////////////////////// - -uint32 CSpawnGroupNpc::_SlowUpdatePeriod = 10; -vector CSpawnGroupNpc::_SlowUpdateBuckets(_SlowUpdatePeriod); - -CSpawnGroupNpc::CSpawnGroupNpc(CPersistent& owner) -: CSpawnGroup(owner) -, _GroupInVision(false) -{ - sint32 const randomVal = (sint32)CTimeInterface::gameCycle()-CAIS::rand32(20); - _LastUpdate = (randomVal>=0)?randomVal:CTimeInterface::gameCycle(); - _LastBotUpdate = CTimeInterface::gameCycle(); - activityProfile().setAIProfile(new CGrpProfileNormal(this)); - _BotUpdateTimer.set((CAIS::rand32(40)+((intptr_t)this>>2))%20); // start with a random value. - resetSlowUpdateCycle(); - _DespawnBotsWhenNoMoreHandleTimerActive = false; -} - -void CSpawnGroupNpc::setSlowUpdatePeriod(uint32 ticks) -{ - // Check args - nlassert(ticks>0); - if (ticks==0) return; - // Save ticks number - _SlowUpdatePeriod = ticks; - // Reset cycles buckets - _SlowUpdateBuckets.clear(); - _SlowUpdateBuckets.resize(_SlowUpdatePeriod); - // For each group - FOREACH (itInstance, CCont, CAIS::instance().AIList()) - { - FOREACH (itManager, CCont, itInstance->managers()) - { - FOREACH (itGroup, CCont, itManager->groups()) - { - // Find the spawn - CGroup* group = *itGroup; - CSpawnGroup* spawnGroup = group->getSpawnObj(); - CSpawnGroupNpc* spawnGroupNpc = dynamic_cast(spawnGroup); - if (spawnGroupNpc!=NULL) - spawnGroupNpc->resetSlowUpdateCycle(); - } - } - } -} - -uint32 CSpawnGroupNpc::getSlowUpdatePeriod() -{ - return _SlowUpdatePeriod; -} - -void CSpawnGroupNpc::resetSlowUpdateCycle() -{ - nlassert(_SlowUpdateBuckets.size() == _SlowUpdatePeriod); - // Find the lowest bucket - vector::iterator it = std::min_element(_SlowUpdateBuckets.begin(), _SlowUpdateBuckets.end()); - // Assign it to the group - _SlowUpdateCycle = (uint32)(it - _SlowUpdateBuckets.begin()); - // Fill the bucket with the group - *it += bots().size(); -} - -void CSpawnGroupNpc::displaySlowUpdateBuckets() -{ - std::vector::iterator it, end=_SlowUpdateBuckets.end(); - for (it = _SlowUpdateBuckets.begin(); it!=end; ++it) - { - nlinfo("Bucket %d: %d", it-_SlowUpdateBuckets.begin(), *it); - } -} - -void CSpawnGroupNpc::noMoreHandle(uint32 nNbTickBeforeDespawn) -{ - _DespawnBotsWhenNoMoreHandleTimerActive = true; - _DespawnBotsWhenNoMoreHandleTimer.set(nNbTickBeforeDespawn); -} - -void CSpawnGroupNpc::handlePresent() -{ - _DespawnBotsWhenNoMoreHandleTimerActive = false; -} - -void CSpawnGroupNpc::sendInfoToEGS() const -{ - FOREACHC(itBot, CCont, bots()) - { - CBot const* bot = *itBot; - if (!bot->isSpawned()) - continue; - // :NOTE: As it can be called during CSpawnBotNpc dtor rely on dynamic cast to verify object is valid - CSpawnBotNpc const* spawn = dynamic_cast(bot->getSpawnObj()); - if (spawn) - spawn->sendInfoToEGS(); - } -} - -void CSpawnGroupNpc::update() -{ - H_AUTO(GrpNpcUpdate); - - ++AISStat::GrpTotalUpdCtr; - ++AISStat::GrpNpcUpdCtr; - - uint32 const Dt = CTimeInterface::gameCycle()-_LastUpdate; - bool const inFight = activityProfile().getAIProfileType()==FIGHT_NORMAL; - - uint32 updateTrigger; // in tick - - // use the lowest update time available - if (inFight) - { - updateTrigger = 0; - } - else if ( getPersistent().isRingGrp() ) - { - updateTrigger = 4; - } - else if (_GroupInVision) - { - updateTrigger = 10; - } - else - { - updateTrigger = 30; - } - - bool const haveToUpdateGroupBehaviour = (Dt>=updateTrigger); // every second. - - if (haveToUpdateGroupBehaviour) - { - H_AUTO(GrpNpcUpdateBehaviour); - // record the tick at which we ran this update (for future refference) - _LastUpdate = CTimeInterface::gameCycle(); - - checkDespawn(); - checkRespawn(); - getPersistent().updateStateInstance(); - } - - // bot update()s -------------------------------------------------- - { - if (haveToUpdateGroupBehaviour) - { - H_AUTO(GrpNpcUpdateBots); - _GroupInVision = false; - - FOREACH(first,CCont, bots()) - { - CSpawnBotNpc const* const bot = static_cast(*first)->getSpawn(); - if (!bot) - continue; - if (simulateBug(3)) - { - if (bot->isAlive()) - continue; - } - else // Normal behaviour - { - if (!bot->isAlive()) - continue; - } - if (!bot->havePlayersAround()) - continue; - - _GroupInVision = true; - break; - } - } - - // TODO : hack : remove this when the "can't reach and turn arround" debility is corrected - bool fastUpdate = _GroupInVision || inFight; - bool slowUpdate = (CTimeInterface::gameCycle()%_SlowUpdatePeriod)==_SlowUpdateCycle; - - if (fastUpdate || slowUpdate) - { - uint32 const botDt = CTimeInterface::gameCycle()-_LastBotUpdate; - _LastBotUpdate = CTimeInterface::gameCycle(); - - FOREACH(first, CCont, bots()) - { - CSpawnBotNpc* const bot = static_cast(*first)->getSpawn(); - if (bot && bot->isAlive()) - { - H_AUTO(GrpNpcUpdateBotsUpdate); - bot->update(botDt); - } - } - _BotUpdateTimer.set(10); - } - } - - if (haveToUpdateGroupBehaviour) - { - H_AUTO(GrpNpcUpdateGrpBehaviour); - if (!activityProfile().getAISpawnProfile().isNull()) // Check if we have a behaviour. - activityProfile().updateProfile(Dt); // If so, then update it ! -// this->CBotAggroOwner::update(Dt); - } - - if (_DespawnBotsWhenNoMoreHandleTimerActive) - { - if (_DespawnBotsWhenNoMoreHandleTimer.test()) - { - _DespawnBotsWhenNoMoreHandleTimerActive = false; - despawnBots(true); - } - } -} - -void CSpawnGroupNpc::stateChange(CAIState const* oldState, CAIState const* newState) -{ - // Find changing group profiles. - { - setProfileParameters(getPersistent().profileParameters()); - - IAIProfileFactory* moveProfile = newState->moveProfile(); - IAIProfileFactory* actProfile = newState->activityProfile(); - - mergeProfileParameters(newState->profileParameters()); - - FOREACHC(it, CCont, newState->profiles()) - { - if (!it->testCompatibility(getPersistent())) - continue; - - if (it->moveProfile()!= RYAI_GET_FACTORY(CGrpProfileNoChangeFactory)) - moveProfile = it->moveProfile(); - - if (it->activityProfile()!=RYAI_GET_FACTORY(CGrpProfileNoChangeFactory)) - actProfile = it->activityProfile(); - - mergeProfileParameters(it->profileParameters()); - break; - } - - breakable - { - if (oldState) - { - if (!newState->isPositional() && oldState->isPositional()) - { - // begin of punctual state - // need to backup the current profiles - _PunctualHoldActivityProfile = activityProfile(); - _PunctualHoldMovingProfile = movingProfile(); - - activityProfile() = CProfilePtr(); - movingProfile() = CProfilePtr(); - break; - } - - if (newState->isPositional() && !oldState->isPositional()) - { - // end of punctual state - // need to restore the backuped profile - activityProfile() = _PunctualHoldActivityProfile; - movingProfile() = _PunctualHoldMovingProfile; - - _PunctualHoldActivityProfile = CProfilePtr(); - _PunctualHoldMovingProfile = CProfilePtr(); - - // resume the profiles - activityProfile().getAISpawnProfile()->resumeProfile(); - movingProfile().getAISpawnProfile()->resumeProfile(); - break; - } - } - - // normal behavior, transition from positionnal to positionnal state - if (moveProfile!=RYAI_GET_FACTORY(CGrpProfileNoChangeFactory)) - setMoveProfileFromStateMachine(moveProfile); - - if (actProfile!=RYAI_GET_FACTORY(CGrpProfileNoChangeFactory)) - setActivityProfileFromStateMachine(actProfile); - - break; - } - } - - // iterate through bots changing their chat. - for (CCont::iterator it=bots().begin(), itEnd=bots().end();it!=itEnd;++it) - { - CBotNpc *const botNpc=static_cast(*it); - if (!botNpc->isSpawned()) - continue; - botNpc->getSpawn()->updateChat(newState); - } -} - -void CSpawnGroupNpc::spawnBots() -{ - FOREACH(itBot, CCont, bots()) - { - CBot* bot = *itBot; - if (!bot->isSpawned()) - bot->spawn(); - } -} - -void CSpawnGroupNpc::despawnBots(bool immediately) -{ - FOREACH(itBot, CCont, bots()) - { - CBot* const bot = *itBot; - if (!bot->isSpawned()) - continue; - - if (TheDataset.getOnlineTimestamp( bot->getSpawnObj()->dataSetRow()) >= CTickEventHandler::getGameCycle()) - nlwarning("Bots %s:%s spawn/despawn in the same tick ! despawn ignored", getPersistent().getName().c_str(), bot->getName().c_str()); - else - bot->despawnBot(); - } - if (getPersistent()._AutoDestroy) - getPersistent().getOwner()->groups().removeChildByIndex(getPersistent().getChildIndex()); -} - -CGroupNpc& CSpawnGroupNpc::getPersistent() const -{ - return static_cast(CSpawnGroup::getPersistent()); -} - -////////////////////////////////////////////////////////////////////////////// -// CGroupNpc // -////////////////////////////////////////////////////////////////////////////// - -CGroupNpc::CGroupNpc(CMgrNpc* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CGroup(mgr, denyFlags, aliasTree) -, CDynGrpBase() -, CPersistentStateInstance(*mgr->getStateMachine()) -{ - _BotsAreNamed = true; - - _PlayerAttackable = false; - _BotAttackable = false; - _AggroDist = 0; - _RingGrp = false; -} - -CGroupNpc::CGroupNpc(CMgrNpc* mgr, uint32 alias, std::string const& name, RYAI_MAP_CRUNCH::TAStarFlag denyFlags) -: CGroup(mgr, denyFlags, alias, name) -, CDynGrpBase() -, CPersistentStateInstance(*mgr->getStateMachine()) -{ - _BotsAreNamed = true; - - _PlayerAttackable = false; - _BotAttackable = false; - _AggroDist = 0; -} - -CGroupNpc::~CGroupNpc() -{ - // avoid re-deletion by despawn - _AutoDestroy = false; - if (isSpawned()) // to avoid bad CDbgPtr link interpretation - despawnGrp(); - - // clear all persistent state instance - while (!_PSIChilds.empty()) - { - _PSIChilds.back()->setParentStateInstance(NULL); - } - - _PSIChilds.clear(); -} - -std::string CGroupNpc::getOneLineInfoString() const -{ - return std::string("NPC Group '") + getName() + "'"; -} - -std::vector CGroupNpc::getMultiLineInfoString() const -{ - std::vector container; - std::vector strings; - - pushTitle(container, "CGroupNpc"); - strings = CGroup::getMultiLineInfoString(); - FOREACHC(itString, std::vector, strings) - pushEntry(container, *itString); - pushEntry(container, "faction=" + (faction().empty()?string(""):faction().toString())); - pushEntry(container, "friends=" + (friendFaction().empty()?string(""):friendFaction().toString())); - pushEntry(container, "ennemies=" + (ennemyFaction().empty()?string(""):ennemyFaction().toString())); - pushEntry(container, NLMISC::toString("attackable: player=%s bot=%s", _PlayerAttackable?"yes":"no", _BotAttackable?"yes":"no")); - pushEntry(container, "state=" + (getState()?getState()->getName():string(""))); - pushFooter(container); - - return container; -} - -CMgrNpc& CGroupNpc::mgr() const -{ - return *static_cast(getOwner()); -} - -void CGroupNpc::updateDependencies(CAIAliasDescriptionNode const& aliasTree, CAliasTreeOwner* aliasTreeOwner) -{ - switch(aliasTree.getType()) - { - case AITypeEvent: - { - CAIEventReaction* const eventPtr = NLMISC::safe_cast(mgr().getStateMachine()->eventReactions().getChildByAlias(aliasTree.getAlias())); - nlassert(eventPtr); - if (!eventPtr) - break; - eventPtr->setType(CAIEventReaction::FixedGroup); - eventPtr->setGroup(getAlias()); - break; - } - } -} - -IAliasCont* CGroupNpc::getAliasCont(TAIType type) -{ - switch(type) - { - case AITypeBot: - return &_Bots; - - case AITypeFolder: // Nothing .. - default: - return NULL; - } -} - -CAliasTreeOwner* CGroupNpc::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - CAliasTreeOwner* child = NULL; - - switch (aliasTree->getType()) - { - case AITypeOutpostBuilding: - case AITypeBot: - child = new CBotNpc(this, aliasTree); - break; - - case AITypeFolder: - default: - break; - } - - if (child!=NULL) - cont->addAliasChild(child); - return (child); -} - -CSmartPtr CGroupNpc::createSpawnGroup() -{ - return new CSpawnGroupNpc(*this); -} - -void CGroupNpc::serviceEvent (const CServiceEvent &info) -{ - CGroup::serviceEvent(info); - - // If the EGS crash - if ( (info.getServiceName() == "EGS") && (info.getEventType() == CServiceEvent::SERVICE_DOWN) ) - { - // If the Group of NPC has handles on itself - if (!_Handles.empty()) - { - // Remove all handles - _Handles.clear(); - // and despawn bots - if (getSpawnObj() != NULL) - { - if (getSpawnObj()->isGroupAlive()) // is there some bots spawned - { - getSpawnObj()->noMoreHandle(_DespawnTimeWhenNoMoreHandle); - } - } - } - } - - if ((info.getServiceName() == "EGS") && (info.getEventType() == CServiceEvent::SERVICE_UP)) - { - processStateEvent(getEventContainer().EventEGSUp); - } - -} - - -bool CGroupNpc::spawn () -{ - if (CGroup::spawn()) - { - setStartState(getStartState()); // stateInstance. - - // inform the EGS of our existence - simulate connection of EGS - serviceEvent (CServiceEvent(NLNET::TServiceId(0),std::string("EGS"),CServiceEvent::SERVICE_UP)); - - if (isAutoSpawn()) - { - CCont::iterator first(bots().begin()), last(bots().end()); - for (; first != last; ++first) - { - CBotNpc *bot = static_cast(*first); - // ok, we can spawn this bot - bot->spawn(); - } - } - return true; - } - return false; -} - -void CGroupNpc::despawnGrp() -{ - CGroup::despawnGrp(); -} - -void CGroupNpc::clearParameters() -{ - _PlayerAttackable = false; - _BotAttackable = false; - _RingGrp = false; - _AggroDist = DefaultNpcAggroDist; - setEscortTeamId(CTEAM::InvalidTeamId); - setEscortRange(DefaultEscortRange); - respawnTime() = (uint32) DEFAULT_RESPAWN_DELAY; - despawnTime() = (uint32) DEFAULT_RESPAWN_DELAY / 4; -} - -// Parse a paremeter for this group. -void CGroupNpc::addParameter(std::string const& parameter) -{ - static std::string ATTACKABLE("attackable"); - static std::string PLAYER_ATTACKABLE("player_attackable"); - static std::string BOT_ATTACKABLE("bot_attackable"); - static std::string BADGUY("bad guy"); - static std::string AGGRO_RANGE("aggro range"); - static std::string ESCORT_RANGE("escort range"); - static std::string RESPAWN_TIME("respawn time"); - static std::string DESPAWN_TIME("despawn time"); - static std::string RING("ring"); - static std::string DENIED_ASTAR_FLAGS("denied_astar_flags"); - - std::string key, tail; - - // force lowercase - std::string p = NLMISC::toLower(parameter); - AI_SHARE::stringToKeywordAndTail(p, key, tail); - - breakable - { - if (key == RING) - { - _RingGrp = true; - break; - } - if (key == BOT_ATTACKABLE) - { - _BotAttackable = true; - break; - } - - if (key == ATTACKABLE || key == PLAYER_ATTACKABLE) - { - // the bots are attackable ! - _PlayerAttackable = true; - if (!IsRingShard) // In Ring shard, BotAttackable means attackable by bot not vulnerable - { - // attackable implie vulnerable! - _BotAttackable = true; - } - break; - } - - if (key == BADGUY) - { - // the bots are bad guys! they will attack players in their aggro range. - if (!tail.empty()) - { - NLMISC::fromString(tail, _AggroDist); - // bad guy imply attackable! - _PlayerAttackable = true; - // bad guy imply vulnerable! - _BotAttackable = true; - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing agrodist !", parameter.c_str()); - } - break; - } - - if (key == AGGRO_RANGE) - { - if (!tail.empty()) - { - NLMISC::fromString(tail, _AggroDist); - - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing agrodist !", parameter.c_str()); - } - break; - } - - if (key == ESCORT_RANGE) - { - if (!tail.empty()) - { - float range = float(atof(tail.c_str())); - LOG("Setting range to %f", range); - setEscortRange(range); - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing escort range !", parameter.c_str()); - } - break; - } - - if (key == RESPAWN_TIME) - { - if (!tail.empty()) - { - uint32 respawntime = NLMISC::atoui(tail.c_str()); - // TODO:kxu: fix CAITimer! - if (respawntime > 0x7fffffff) - respawntime = 0x7fffffff; // AI timers do not treat properly delta times greater than the max signed int - LOG("Setting respawn time to %u", respawntime); - respawnTime()=respawntime; - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing respawn time !", parameter.c_str()); - } - break; - } - - if (key == DESPAWN_TIME) - { - if (!tail.empty()) - { - uint32 despawntime = NLMISC::atoui(tail.c_str()); - // TODO:kxu: fix CAITimer! - if (despawntime > 0x7fffffff) - despawntime = 0x7fffffff; // AI timers do not treat properly delta times greater than the max signed int - LOG("Setting despawn time to %u", despawntime); - despawnTime()=despawntime; - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing despawn time !", parameter.c_str()); - } - break; - } - - if (key == DENIED_ASTAR_FLAGS) - { - if (!tail.empty()) - { - RYAI_MAP_CRUNCH::TAStarFlag flags = RYAI_MAP_CRUNCH::Nothing; - vector sFlags; - NLMISC::splitString(tail, "|", sFlags); - FOREACHC(it, vector, sFlags) - { - flags = RYAI_MAP_CRUNCH::TAStarFlag( flags | RYAI_MAP_CRUNCH::toAStarFlag(*it) ); - } - - LOG("Setting denied AStar flags to (%s) = %u", tail.c_str(), flags); - _DenyFlags = flags; - } - else - { - nlwarning("GrpNpc::addParameter : in parameter '%s', missing denied AStar flags !", parameter.c_str()); - } - break; - } - - if (parameter.empty()) - break; - - nlwarning("CAIBotNpc::addParameter unknown parameter '%s'", parameter.c_str()); - } -} - -void CGroupNpc::addHpUpTrigger(float threshold, int eventId) -{ - _hpUpTriggers.insert(std::make_pair(threshold, eventId)); -} - -void CGroupNpc::delHpUpTrigger(float threshold, int eventId) -{ - CGroupNpc::THpTriggerList& hpTriggers = _hpUpTriggers; - CGroupNpc::THpTriggerList::iterator first, last, trigger; - first = hpTriggers.lower_bound(threshold); - last = hpTriggers.upper_bound(threshold); - - for (; first!=last; ++first) - { - if (first->second==eventId) - break; - } - if (first!=last) - hpTriggers.erase(first); -} - -void CGroupNpc::addHpDownTrigger(float threshold, int eventId) -{ - _hpDownTriggers.insert(std::make_pair(threshold, eventId)); -} - -void CGroupNpc::delHpDownTrigger(float threshold, int eventId) -{ - CGroupNpc::THpTriggerList& hpTriggers = _hpDownTriggers; - CGroupNpc::THpTriggerList::iterator first, last, trigger; - first = hpTriggers.lower_bound(threshold); - last = hpTriggers.upper_bound(threshold); - - for (; first!=last; ++first) - { - if (first->second==eventId) - break; - } - if (first!=last) - hpTriggers.erase(first); -} - -void CGroupNpc::addHpUpTrigger(float threshold, std::string cbFunc) -{ - _hpUpTriggers2.insert(std::make_pair(threshold, cbFunc)); -} - -void CGroupNpc::delHpUpTrigger(float threshold, std::string cbFunc) -{ - CGroupNpc::THpTriggerList2& hpTriggers = _hpUpTriggers2; - CGroupNpc::THpTriggerList2::iterator first, last, trigger; - first = hpTriggers.lower_bound(threshold); - last = hpTriggers.upper_bound(threshold); - - for (; first!=last; ++first) - { - if (first->second==cbFunc) - break; - } - if (first!=last) - hpTriggers.erase(first); -} - -void CGroupNpc::addHpDownTrigger(float threshold, std::string cbFunc) -{ - _hpDownTriggers2.insert(std::make_pair(threshold, cbFunc)); -} - -void CGroupNpc::delHpDownTrigger(float threshold, std::string cbFunc) -{ - CGroupNpc::THpTriggerList2& hpTriggers = _hpDownTriggers2; - CGroupNpc::THpTriggerList2::iterator first, last, trigger; - first = hpTriggers.lower_bound(threshold); - last = hpTriggers.upper_bound(threshold); - - for (; first!=last; ++first) - { - if (first->second==cbFunc) - break; - } - if (first!=last) - hpTriggers.erase(first); -} - -bool CGroupNpc::haveHpTriggers() -{ - return (_hpUpTriggers.size()+_hpDownTriggers.size()+_hpUpTriggers2.size()+_hpDownTriggers2.size())>0; -} - -void CGroupNpc::hpTriggerCb(float oldVal, float newVal) -{ - if (newVal>oldVal) - { - CGroupNpc::THpTriggerList::const_iterator first, last, trigger, triggerProcessed; - first = _hpUpTriggers.upper_bound(oldVal); - last = _hpUpTriggers.upper_bound(newVal); - for (trigger=first; trigger!=last;) - { - triggerProcessed = trigger; - ++trigger; - processStateEvent(getEventContainer().EventUserEvent[triggerProcessed->second]); - } - CGroupNpc::THpTriggerList2::const_iterator first2, last2, trigger2, triggerProcessed2; - first2 = _hpUpTriggers2.upper_bound(oldVal); - last2 = _hpUpTriggers2.upper_bound(newVal); - for (trigger2=first2; trigger2!=last2;) - { - triggerProcessed2 = trigger2; - ++trigger2; - callScriptCallBack(this, NLMISC::CStringMapper::map(triggerProcessed2->second)); - } - } - if (newValsecond]); - } - CGroupNpc::THpTriggerList2::const_iterator first2, last2, trigger2, triggerProcessed2; - first2 = _hpDownTriggers2.lower_bound(newVal); - last2 = _hpDownTriggers2.lower_bound(oldVal); - for (trigger2=first2; trigger2!=last2;) - { - triggerProcessed2 = trigger2; - ++trigger2; - callScriptCallBack(this, NLMISC::CStringMapper::map(triggerProcessed2->second)); - } - } -} - -void CGroupNpc::addNamedEntityListener(std::string const& name, std::string const& prop, int event) -{ - _namedEntityListeners.insert(std::make_pair(std::make_pair(name, prop), event)); - CNamedEntityManager::getInstance()->get(name).addListenerGroup(prop, this); -} - -void CGroupNpc::delNamedEntityListener(std::string const& name, std::string const& prop, int event) -{ - TNamedEntityListenerList::iterator first, last, listener; - listener = _namedEntityListeners.lower_bound(std::make_pair(name, prop)); - last = _namedEntityListeners.upper_bound(std::make_pair(name, prop)); - while (listener!=last) - { - if (listener->second==event) - { - _namedEntityListeners.erase(listener); - CNamedEntityManager::getInstance()->get(name).delListenerGroup(prop, this); - break; - } - ++listener; - } -} - -void CGroupNpc::addNamedEntityListener(std::string const& name, std::string const& prop, std::string functionName) -{ - _namedEntityListeners2.insert(std::make_pair(std::make_pair(name, prop), functionName)); - CNamedEntityManager::getInstance()->get(name).addListenerGroup(prop, this); -} - -void CGroupNpc::delNamedEntityListener(std::string const& name, std::string const& prop, std::string functionName) -{ - TNamedEntityListenerList2::iterator first, last, listener; - listener = _namedEntityListeners2.lower_bound(std::make_pair(name, prop)); - last = _namedEntityListeners2.upper_bound(std::make_pair(name, prop)); - while (listener!=last) - { - if (listener->second==functionName) - { - _namedEntityListeners2.erase(listener); - CNamedEntityManager::getInstance()->get(name).delListenerGroup(prop, this); - break; - } - ++listener; - } -} - -void CGroupNpc::namedEntityListenerCb(std::string const& name, std::string const& prop) -{ - TNamedEntityListenerList::iterator first, last, listener; - first = _namedEntityListeners.lower_bound(std::make_pair(name, prop)); - last = _namedEntityListeners.upper_bound(std::make_pair(name, prop)); - for (listener=first; listener!=last; ++listener) - { - processStateEvent(getEventContainer().EventUserEvent[listener->second]); - } - TNamedEntityListenerList2::iterator first2, last2, listener2; - first2 = _namedEntityListeners2.lower_bound(std::make_pair(name, prop)); - last2 = _namedEntityListeners2.upper_bound(std::make_pair(name, prop)); - std::queue listeners; - for (listener2=first2; listener2!=last2; ++listener2) - listeners.push(NLMISC::CStringMapper::map(listener2->second)); - while(!listeners.empty()) - { - callScriptCallBack(this, listeners.front()); - listeners.pop(); - } -} - -//-------------------------------------------------------------------- -// addHandle -//-------------------------------------------------------------------- -void CGroupNpc::addHandle(TDataSetRow playerRowId, uint32 missionAlias, uint32 DespawnTimeInTick) -{ - // If the group is not spawned -> spawn it - - // Save some states when adding first handle - if (_Handles.empty()) - { - _AutoSpawnWhenNoMoreHandle = isAutoSpawn(); - } - - setAutoSpawn(true); - // There is always a spawned object for group - if (getSpawnObj() != NULL) - { - if (! getSpawnObj()->isGroupAlive() ) // if no bots spawned - { - getSpawnObj()->spawnBots(); - } - getSpawnObj()->handlePresent(); - } - // Register the handle - SHandle h; - h.MissionAlias = missionAlias; - h.PlayerRowId = playerRowId; - - set::const_iterator it = _Handles.find(h); - - if (it != _Handles.end()) - { - nlwarning("CGroupNpc::addHandle handle already added player:%d missionAlias:%d", playerRowId.getIndex(), missionAlias); - } - else - { - _Handles.insert(h); - } - - _DespawnTimeWhenNoMoreHandle = DespawnTimeInTick; - - CHandledAIGroupSpawnedMsg msg; - msg.PlayerRowId = playerRowId; - msg.MissionAlias = missionAlias; - msg.GroupAlias = getAlias(); - msg.send("EGS"); -} - -//-------------------------------------------------------------------- -// delHandle -//-------------------------------------------------------------------- -void CGroupNpc::delHandle(TDataSetRow playerRowId, uint32 missionAlias) -{ - // Unregister the handle - SHandle h; - h.MissionAlias = missionAlias; - h.PlayerRowId = playerRowId; - - set::iterator it = _Handles.find(h); - if (it != _Handles.end()) - { - _Handles.erase(it); - } - else - { - // With the new queue_* generation system multiple handle_release can be done -> do not flood with this message - // nlwarning("CGroupNpc::delHandle handle not found player:%d missionAlias:%d", playerRowId.getIndex(), missionAlias); - } - - // If no more handle despawn the group and restore saved variables - if (_Handles.empty()) - { - if (getSpawnObj() != NULL) - { - if (getSpawnObj()->isGroupAlive()) // is there some bots spawned - { - getSpawnObj()->noMoreHandle(_DespawnTimeWhenNoMoreHandle); - } - } - setAutoSpawn(_AutoSpawnWhenNoMoreHandle); - } - - CHandledAIGroupDespawnedMsg msg; - msg.PlayerRowId = playerRowId; - msg.MissionAlias = missionAlias; - msg.GroupAlias = getAlias(); - msg.send("EGS"); -} - -//-------------------------------------------------------------------- -// the default display() -//-------------------------------------------------------------------- -std::string CSpawnGroupNpc::buildDebugString(uint idx) const -{ - if (idx == 0) - return "No debug info"; - return std::string(); -} - -std::string CGroupNpc::buildDebugString(uint idx) const -{ - - switch(idx) - { - case 0: return "-- CGroupNpc -----------------------------"; - case 1: { - std::string s; - if (!isSpawned()) - { - s += "id=" + getIndexString(); - s += " alias=" + getAliasString(); - s += " info="; - s += " name=" + getName(); - } - else - { - s += "id=" + getIndexString(); - s += " alias="+getAliasString(); - s += " info='" + getSpawnObj()->buildDebugString(0) + "'"; - s += " name="+getName(); - } - return s; - } - case 2: - return NLMISC::toString(": %s :", getAliasNode()->getName().c_str()) + buidStateInstanceDebugString(); - case 3: - return NLMISC::toString(" User Timers: %s %s %s %s", - userTimer(0).toString().c_str(), - userTimer(1).toString().c_str(), - userTimer(2).toString().c_str(), - userTimer(3).toString().c_str()); - case 4: - if (getEscortTeamId() != CTEAM::InvalidTeamId) - return NLMISC::toString(" Escorted by team %u", getEscortTeamId()); - else - return std::string(" Not escorted"); - case 5: return "----------------------------------------"; - } - return std::string(); -} - -void CGroupNpc::display(CStringWriter &stringWriter) const -{ -#ifdef NL_DEBUG - nlstopex(("not implemented")); -#endif -} - -CAIS::CCounter& CGroupNpc::getSpawnCounter() -{ - return CAIS::instance()._NpcBotCounter; -} - -void CGroupNpc::lastBotDespawned() -{ - // send message - processStateEvent(getEventContainer().EventLastBotDespawned); -} - -void CGroupNpc::firstBotSpawned() -{ - setFirstBotSpawned(); -} - -void CGroupNpc::setColour(uint8 colour) -{ - FOREACH(itBot, CCont, bots()) - { - CBotNpc* bot = static_cast(*itBot); - if (bot) - bot->setColour(colour); - } -} - -void CGroupNpc::setOutpostSide(OUTPOSTENUMS::TPVPSide side) -{ - FOREACH(itBot, CCont, bots()) - { - CBotNpc* bot = static_cast(*itBot); - if (bot) - bot->setOutpostSide(side); - } -} - -void CGroupNpc::setOutpostFactions(OUTPOSTENUMS::TPVPSide side) -{ - // Attack only the declared ennemies of the outpost - if (side == OUTPOSTENUMS::OutpostOwner) - { - // Bots factions - faction ().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str())); - friendFaction().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str())); - ennemyFaction().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str())); - // Players faction - ennemyFaction().addProperty(NLMISC::toString("outpost:%s:attacker", getAliasString().c_str())); - } - if (side == OUTPOSTENUMS::OutpostAttacker) - { - // Bots factions - faction ().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str())); - friendFaction().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str())); - ennemyFaction().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str())); - // Players faction - ennemyFaction().addProperty(NLMISC::toString("outpost:%s:defender", getAliasString().c_str())); - } -} - -void CGroupNpc::setFactionAttackableAbove(std::string faction, sint32 threshold, bool botAttackable) -{ - if (botAttackable) - _FactionAttackableAbove.insert(std::make_pair(faction, threshold)); - else - _FactionAttackableAbove.erase(std::make_pair(faction, threshold)); -} - -void CGroupNpc::setFactionAttackableBelow(std::string faction, sint32 threshold, bool botAttackable) -{ - if (botAttackable) - _FactionAttackableBelow.insert(std::make_pair(faction, threshold)); - else - _FactionAttackableBelow.erase(std::make_pair(faction, threshold)); -} - -bool CGroupNpc::isFactionAttackable(std::string faction, sint32 fame) -{ - TFactionAttackableSet::const_iterator it, itEnd; - for (it=_FactionAttackableAbove.begin(), itEnd=_FactionAttackableAbove.end(); it!=itEnd; ++it) - if (faction==it->first && fame>it->second) - return true; - for (it=_FactionAttackableBelow.begin(), itEnd=_FactionAttackableBelow.end(); it!=itEnd; ++it) - if (faction==it->first && famesecond) - return true; - return false; -} - -void CGroupNpc::stateChange(CAIState const* oldState, CAIState const* newState) -{ - if (isSpawned()) - getSpawnObj()->stateChange(oldState, newState); -} - -void CGroupNpc::setEvent(uint eventId) -{ - nlassert(eventId<10); - if (eventId >= 10) return; - processStateEvent(getEventContainer().EventUserEvent[eventId]); -} - -////////////////////////////////////////////////////////////////////////////// -// Commands // -////////////////////////////////////////////////////////////////////////////// - -//--------------------------------------------------------------------------------------- -// Control over verbose nature of logging -//--------------------------------------------------------------------------------------- - -NLMISC_COMMAND(verboseNPCGrp,"Turn on or off or check the state of verbose npc group logging","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (VerboseLog, args[0]); - - nlinfo("VerboseLogging is %s",VerboseLog?"ON":"OFF"); - return true; -} - -NLMISC_COMMAND(NpcGroupSlowUpdatePeriod, "Slow update period of the NPC groups","[]") -{ - if (args.size()==0 || args.size()==1) - { - if (args.size()==1) - { - uint32 ticks; - NLMISC::fromString(args[0], ticks); - if (ticks>0) - CSpawnGroupNpc::setSlowUpdatePeriod(ticks); - else - return false; - } - log.displayNL("Slow update period of the NPC groups is %d ticks", CSpawnGroupNpc::getSlowUpdatePeriod()); - return true; - } - return false; -} - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_grp_npc.h b/code/ryzom/server/src/ai_service/ai_grp_npc.h deleted file mode 100644 index 1f838584d..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_npc.h +++ /dev/null @@ -1,298 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_GRP_NPC_H -#define RYAI_GRP_NPC_H - -#include "ai_grp.h" -#include "timer.h" -#include "ai_vision.h" -#include "ai_keywords.h" -#include "state_instance.h" -#include "named_entity_manager.h" -#include "nel/misc/string_mapper.h" - -class CMgrNpc; -class CBotNpc; -class CSpawnBotNpc; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupNpc // -////////////////////////////////////////////////////////////////////////////// - -class CSpawnGroupNpc -: public NLMISC::CDbgRefCount -, public CSpawnGroup -{ -public: - CSpawnGroupNpc(CPersistent& owner); - - virtual ~CSpawnGroupNpc() { } - - CGroupNpc& getPersistent() const; - - virtual void spawnBots(); - virtual void despawnBots(bool immediately); - - void update(); - - void sendInfoToEGS() const; - - std::string buildDebugString(uint idx) const; - - void stateChange(CAIState const* oldState, CAIState const* newState); - - void botHaveDied(CBotNpc* bot); - void botHaveDespawn(CBotNpc* bot); - void botHaveSpawn(CBotNpc* bot); - -public: - void resetSlowUpdateCycle(); - static void setSlowUpdatePeriod(uint32 ticks); - static uint32 getSlowUpdatePeriod(); - static void displaySlowUpdateBuckets(); - - void noMoreHandle(uint32 nNbTickBeforeDespawn); - void handlePresent(); - -private: - bool _GroupInVision; - CAITimer _BotUpdateTimer; - uint32 _LastUpdate; // gamecycle at which update() last called - uint32 _LastBotUpdate; - uint32 _SlowUpdateCycle; - static uint32 _SlowUpdatePeriod; - static std::vector _SlowUpdateBuckets; - - bool _DespawnBotsWhenNoMoreHandleTimerActive; - CAITimer _DespawnBotsWhenNoMoreHandleTimer; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGroupNpc // -////////////////////////////////////////////////////////////////////////////// - -class CGroupNpc -: public NLMISC::CDbgRefCount -, public CGroup -, public CDynGrpBase -, public CPersistentStateInstance -{ -public: - typedef std::set > TFactionAttackableSet; - -public: - CGroupNpc(CMgrNpc* mgr, CAIAliasDescriptionNode* aliasTree, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - CGroupNpc(CMgrNpc* mgr, uint32 alias, std::string const& name, RYAI_MAP_CRUNCH::TAStarFlag denyFlags); - - virtual ~CGroupNpc(); - - /// @name CChild implementation - //@{ -// virtual std::string getIndexString() const; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; -// virtual std::string getFullName() const; - //@} - - CDynGrpBase* getGrpDynBase() { return this; } - - ////////////////////////////////////////////////////////////////////////// - // PersistentStateInstance - - CAliasTreeOwner* aliasTreeOwner() { return this; } - - void stateChange(CAIState const* oldState, CAIState const* newState); - - CGroup* getGroup() { return this; } - - ////////////////////////////////////////////////////////////////////////// - - virtual void lastBotDespawned(); - virtual void firstBotSpawned(); - - // debugging stuff - CDebugHistory* getDebugHistory() { return this; } - - CAIS::CCounter& getSpawnCounter(); - - RYZOMID::TTypeId getRyzomType() { return RYZOMID::npc; } - - NLMISC::CSmartPtr createSpawnGroup(); - - CSpawnGroupNpc* getSpawnObj() const { return NLMISC::type_cast(CGroup::getSpawnObj()); } - - CPersistentStateInstance* getPersistentStateInstance() { return this; } - - void setEvent(uint eventId); - - virtual void serviceEvent (const CServiceEvent &info); - - void init() { } - - void release() { } - - - // inheritted virtual interface ------------------------------------ - virtual bool spawn(); - virtual void despawnGrp(); - - virtual std::string buildDebugString(uint idx) const; - virtual void display(CStringWriter& stringWriter) const; - - void updateDependencies(CAIAliasDescriptionNode const& aliasTree, CAliasTreeOwner* aliasTreeOwner); - IAliasCont* getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree); - - // basic utilities ------------------------------------------------- - CMgrNpc& mgr() const; - - // management of the bot population -------------------------------- - // allocator for allocating new bot objects - CGroupNpc* newBot(); - - bool botsAreNamed() { return _BotsAreNamed; } - void setBotsAreNamedFlag() { _BotsAreNamed = true; } - void clrBotsAreNamedFlag() { _BotsAreNamed = false; } - - // Parameter management ------------------------------------- - void clearParameters(); - // Parse a paremeter for this group. - void addParameter(const std::string ¶meter); - - // set if the bots of the group are attackable by players - void setPlayerAttackable(bool playerAttackable) { _PlayerAttackable = playerAttackable; } - bool getPlayerAttackable() { return _PlayerAttackable; } - - // set if the bots of the group are attackable by other bots - void setBotAttackable(bool botAttackable) { _BotAttackable = botAttackable; } - bool getBotAttackable() { return _BotAttackable; } - - void setFactionAttackableAbove(std::string faction, sint32 threshold, bool botAttackable); - TFactionAttackableSet const& getFactionAttackableAbove() const { return _FactionAttackableAbove; } - void setFactionAttackableBelow(std::string faction, sint32 threshold, bool botAttackable); - TFactionAttackableSet const& getFactionAttackableBelow() const { return _FactionAttackableBelow; } - bool isFactionAttackable(std::string faction, sint32 fame); - - uint32 getAggroDist() { return _AggroDist; } - - uint32& despawnTime() { return _DespawnTime; } - uint32& respawnTime() { return _RespawnTime; } - - AITYPES::CPropertySetWithExtraList& faction() { return _faction; } - AITYPES::CPropertySetWithExtraList& ennemyFaction() { return _ennemyFaction; } - AITYPES::CPropertySetWithExtraList& friendFaction() { return _friendFaction; } - - AITYPES::CPropertySetWithExtraList const& faction() const { return _faction; } - AITYPES::CPropertySetWithExtraList const& ennemyFaction() const { return _ennemyFaction; } - AITYPES::CPropertySetWithExtraList const& friendFaction() const { return _friendFaction; } - -public: - void addHpUpTrigger(float threshold, int eventId); - void delHpUpTrigger(float threshold, int eventId); - void addHpUpTrigger(float threshold, std::string cbFunc); - void delHpUpTrigger(float threshold, std::string cbFunc); - - void addHpDownTrigger(float threshold, int eventId); - void delHpDownTrigger(float threshold, int eventId); - void addHpDownTrigger(float threshold, std::string cbFunc); - void delHpDownTrigger(float threshold, std::string cbFunc); - - bool haveHpTriggers(); - void hpTriggerCb(float oldVal, float newVal); - - void addNamedEntityListener(std::string const& name, std::string const& prop, int event); - void delNamedEntityListener(std::string const& name, std::string const& prop, int event); - void addNamedEntityListener(std::string const& name, std::string const& prop, std::string functionName); - void delNamedEntityListener(std::string const& name, std::string const& prop, std::string functionName); - void namedEntityListenerCb(std::string const& name, std::string const& prop); - - void addHandle(TDataSetRow playerRowId, uint32 missionAlias, uint32 DespawnTimeInTick); - void delHandle(TDataSetRow playerRowId, uint32 missionAlias); - - uint32 getTimerWhenNoMoreHandle(); - - void setSpawnZone(const CNpcZone *zone) { _SpawnZone = zone; } - const CNpcZone *getSpawnZone() const { return _SpawnZone; } - - void setColour(uint8 colour); - - void setOutpostSide(OUTPOSTENUMS::TPVPSide side); - void setOutpostFactions(OUTPOSTENUMS::TPVPSide side); - bool isRingGrp() const { return _RingGrp;} - -private: - /// group basics - bool _BotsAreNamed; // true if the bots in the group are explicitly placed in level editor tool - false otherwise - /// NPCs are attackable by player ? - bool _PlayerAttackable; - /// NPCs are attackable by npcs - bool _BotAttackable; - /// NPCs are attackable by players with fame for faction (string) above threshold (float) - TFactionAttackableSet _FactionAttackableAbove; - /// NPCs are attackable by players with fame for faction (string) below threshold (float) - TFactionAttackableSet _FactionAttackableBelow; - /// Aggro distance : any player passing at less this distance will be attacked - uint32 _AggroDist; - /// Respawn time in ticks - uint32 _RespawnTime; - /// Despawn time in ticks - uint32 _DespawnTime; - - - - AITYPES::CPropertySetWithExtraList _faction; - AITYPES::CPropertySetWithExtraList _ennemyFaction; - AITYPES::CPropertySetWithExtraList _friendFaction; - - typedef std::multimap THpTriggerList; - typedef std::multimap THpTriggerList2; - THpTriggerList _hpUpTriggers; - THpTriggerList _hpDownTriggers; - THpTriggerList2 _hpUpTriggers2; - THpTriggerList2 _hpDownTriggers2; - - typedef std::multimap, int> TNamedEntityListenerList; - TNamedEntityListenerList _namedEntityListeners; - typedef std::multimap, std::string> TNamedEntityListenerList2; - TNamedEntityListenerList2 _namedEntityListeners2; - - struct SHandle - { - TDataSetRow PlayerRowId; - uint32 MissionAlias; - - bool operator < (const SHandle &h) const - { - if (PlayerRowId < h.PlayerRowId) return true; - - if (PlayerRowId == h.PlayerRowId) - if (MissionAlias < h.MissionAlias) - return true; - - return false; - } - }; - - std::set _Handles; - uint32 _DespawnTimeWhenNoMoreHandle; - bool _AutoSpawnWhenNoMoreHandle; - NLMISC::CVirtualRefPtr _SpawnZone; - bool _RingGrp;//Ring rulez: like a override bandit profile - -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_grp_pet.cpp b/code/ryzom/server/src/ai_service/ai_grp_pet.cpp deleted file mode 100644 index 9e45c0d46..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_pet.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_grp_pet.h" -#include "owners.h" -#include "ai_share/ai_types.h" - -#include "ai_profile_pet.h" // for CAIPetProfileStand - -using namespace NLMISC; -using namespace AITYPES; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupPet // -////////////////////////////////////////////////////////////////////////////// - -void CSpawnGroupPet::update () -{ - FOREACH(it, CCont, bots()) - { - CBotPet* const botPet = safe_cast(*it); - if (!botPet->isSpawned() || botPet->haveToDespawn()) // must erase this bot. - getPersistent().bots().removeChildByIndex(botPet->getChildIndex()); - } - - CEntityId const& entityId = getPersistent().getPetOwner(); - CAIEntityPhysical* const petOwner = CAIS::instance().getEntityPhysical(CMirrors::DataSet->getDataSetRow(entityId)); - - // Quick hack to prevent of too much computing.. - if (petOwner) - { - double const distContDestToRealDest = petOwner->wpos().toAIVector().quickDistTo(_PathCont.getDestination()); - - if (distContDestToRealDest>4) // update only each 4 meters. - _PathCont.setDestination(petOwner->wpos()); - _IsPlayerSpawned = true; - } - else - { - if (_IsPlayerSpawned) - { - FOREACH(it, CCont, bots()) - { - CBotPet *const pet=safe_cast(*it); - if (pet->isSpawned()) - { - pet->getSpawn()->setAIProfile(new CAIPetProfileStand(pet->getSpawn())); - } - } - _IsPlayerSpawned = false; - } - } - - { - uint32 const newTime = CTimeInterface::gameCycle(); - uint32 const dt = newTime - _LastUpdate; - - FOREACH(it, CCont, bots()) - { - (safe_cast(*it))->update(dt, petOwner); - } - _LastUpdate = newTime; // record the tick at which we ran this update (for future refference) - } -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpPet // -////////////////////////////////////////////////////////////////////////////// - -CAIS::CCounter& CGrpPet::getSpawnCounter() -{ - return CAIS::instance()._PetBotCounter; -} diff --git a/code/ryzom/server/src/ai_service/ai_grp_pet.h b/code/ryzom/server/src/ai_service/ai_grp_pet.h deleted file mode 100644 index c51c7c6cd..000000000 --- a/code/ryzom/server/src/ai_service/ai_grp_pet.h +++ /dev/null @@ -1,152 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_GRP_PET_H -#define RYAI_GRP_PET_H -#include "ai_mgr_pet.h" -#include "ai_grp.h" -#include "time_interface.h" -#include "path_behaviors.h" -#include "service_dependencies.h" - -class CMgrPet; -class CPetOwner; - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupPet // -////////////////////////////////////////////////////////////////////////////// - -/// This is the base class for PET groups -class CSpawnGroupPet -: public CSpawnGroup -{ -public: - CSpawnGroupPet(CPersistent& owner) - : CSpawnGroup(owner) - , _PathCont(NLMISC::safe_cast(&owner)->getAStarFlag()) - { - _LastUpdate = CTimeInterface::gameCycle(); - _IsPlayerSpawned = true; - } - - CGrpPet& getPersistent() const; - - void spawnBots() { } - void despawnBots (bool immediately) { } - - void update(); - - CPathCont& getPathCont() { return _PathCont; } - - CAIVector const& getPos() const { return _PathCont.getDestination(); } - -private: - CPathCont _PathCont; // this path container is share by all player pets .. (thats accelerate our computing). - uint32 _LastUpdate; - bool _IsPlayerSpawned; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpPet // -////////////////////////////////////////////////////////////////////////////// - -class CGrpPet -: public CGroup -{ -public: - CGrpPet(CMgrPet* mgr, NLMISC::CEntityId const& owner, CAIAliasDescriptionNode* aliasTree = NULL); - - CDynGrpBase* getGrpDynBase() { return NULL; } - - RYZOMID::TTypeId getRyzomType() { return RYZOMID::pack_animal; } - - CAIS::CCounter& getSpawnCounter(); - - /// @name Service events - //@{ - void serviceUp(uint32 serviceId, std::string const& serviceName); - void serviceDown(uint32 serviceId, std::string const& serviceName); - //@} - - void init() { } - - void release() { } - - void setEvent(uint eventId); - - NLMISC::CSmartPtr createSpawnGroup(); - - CPersistentStateInstance* getPersistentStateInstance(); - - NLMISC::CEntityId const& getPetOwner() const { return _PetOwner; } - - CMgrPet& getPetManager() { return *(NLMISC::safe_cast(getOwner())); } - - CCont& bots() { return _Bots; } - - virtual std::string getOneLineInfoString() const { return std::string("Pet group '") + getName() + "'"; } - -private: - NLMISC::CEntityId const _PetOwner; -}; - -/****************************************************************************/ -/* Inlined methods */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupPet // -////////////////////////////////////////////////////////////////////////////// - -inline -CGrpPet& CSpawnGroupPet::getPersistent() const -{ - return static_cast(CSpawnGroup::getPersistent()); -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpPet // -////////////////////////////////////////////////////////////////////////////// - -inline -CGrpPet::CGrpPet(CMgrPet* mgr, NLMISC::CEntityId const& owner, CAIAliasDescriptionNode* aliasTree) -: CGroup(mgr, RYAI_MAP_CRUNCH::Nothing, aliasTree) -, _PetOwner(owner) -{ - _Bots.setChildSize(4); -} - -inline -void CGrpPet::setEvent(uint eventId) -{ - nlwarning("Can't set event on a CGrpPet object !"); -} - -inline -NLMISC::CSmartPtr CGrpPet::createSpawnGroup() -{ - return new CSpawnGroupPet(*this); -} - -inline -CPersistentStateInstance* CGrpPet::getPersistentStateInstance() -{ - // WE NEVER HAVE TO GO HERE AS PET ARE NOT DERIVED FROM STATE_INSTANCE STUFF ! - nldebug("State instance stuff called on a pet group"); - return (CPersistentStateInstance*)NULL; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_inline.h b/code/ryzom/server/src/ai_service/ai_inline.h deleted file mode 100644 index 8a3f3f026..000000000 --- a/code/ryzom/server/src/ai_service/ai_inline.h +++ /dev/null @@ -1,65 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AI_INLINE_H -#define RYAI_AI_INLINE_H - - -//------------------------------------------------------------------- -// Important boolean showing true when the singleton has been initialised -// and other pseudo-constants initialised at service init time - -/*inline bool CAIS::initialised() -{ - return _initialised; -} -*/ -//------------------------------------------------------------------- -// Interface to the random number generator -inline sint32 CAIS::randPlusMinus(uint16 mod) { return _random.randPlusMinus(mod); } -inline float CAIS::frand(double mod) { return _random.frand(mod); } -inline float CAIS::frandPlusMinus(double mod) { return _random.frandPlusMinus(mod); } - -inline uint32 CAIS::rand32() -{ - return ((uint32(_random.rand()))<<16)+uint32(_random.rand()); -} -inline uint32 CAIS::rand32(uint32 mod) -{ - if (mod==0) - return 0; - return rand32()%mod; -} -inline uint32 CAIS::rand16(uint32 mod) -{ - if (mod==0) - return 0; - return _random.rand()%mod; -} - -//------------------------------------------------------------------- -// Interface to the vision management matrices - -// read accessors for getting hold of the vision matrices -inline const CAIEntityMatrixIteratorTblRandom *CAIS::matrixIterator2x2() { return &_matrixIterator2x2; } -inline const CAIEntityMatrixIteratorTblRandom *CAIS::matrixIterator3x3() { return &_matrixIterator3x3; } - - -#endif - - diff --git a/code/ryzom/server/src/ai_service/ai_instance.cpp b/code/ryzom/server/src/ai_service/ai_instance.cpp deleted file mode 100644 index a4da91956..000000000 --- a/code/ryzom/server/src/ai_service/ai_instance.cpp +++ /dev/null @@ -1,1570 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "server_share/r2_vision.h" -#include "ai_instance.h" - -#include "ai_player.h" -#include "ai_grp_npc.h" -#include "ai_bot_fauna.h" -#include "ai_grp_fauna.h" -#include "ai_bot_easter_egg.h" - -#include "ai_instance_inline.h" - -#include "commands.h" -#include "messages.h" - -using namespace std; -using namespace NLMISC; -using namespace NLNET; -using namespace MULTI_LINE_FORMATER; - -CAIInstance::CAIInstance(CAIS* owner) -: CChild(owner) -{ - _PlayerManager = new CManagerPlayer(this); - _PetManager = static_cast(newMgr(AITYPES::MgrTypePet, 0, "Pet Manager", "MapName: Pet Manager", "")); - _EventNpcManager = static_cast(newMgr(AITYPES::MgrTypeNpc, 0, "Event NPCs Manager", "MapName: Event NPCs Manager", "")); - _EasterEggManager = static_cast(newMgr(AITYPES::MgrTypeNpc, 0, "Easter Eggs Manager", "MapName: Easter Eggs Manager", "")); - _SquadFamily = new COutpostSquadFamily(this, 0, "Squads"); -} - -CAIInstance::~CAIInstance() -{ - // delete managers - if (_PlayerManager != NULL) - { - delete _PlayerManager; - _PlayerManager = NULL; - } - _PetManager = NULL; - _EventNpcManager = NULL; - _Managers.clear(); - - // check if ref pointers were notified of the destruction - nlassert(_EasterEggGroup == NULL); - nlassert(_EasterEggManager == NULL); - - _SquadFamily = NULL; - _SquadVariantNameToGroupDesc.clear(); - - // delete continents - _Continents.clear(); -} - -static bool zoneHaveError = false; - -/// map of lastCreatedNpcGroup by player id -static std::map _PlayersLastCreatedNpcGroup; - -void CAIInstance::addZone(string const& zoneName, CNpcZone* zone) -{ -#if !FINAL_VERSION - TZoneList::iterator it = zoneList.find(CStringMapper::map(zoneName)); - if (it!=zoneList.end()) - { - nlwarning("this NpcZone have the same name than another: %s", zoneName.c_str()); - zoneHaveError = true; - } -#endif - zoneList[CStringMapper::map(zoneName)] = zone; -} - -void CAIInstance::removeZone(string const& zoneName, CNpcZone* zone) -{ - TZoneList::iterator it = zoneList.find(CStringMapper::map(zoneName)); - zoneList.erase(it); -} - -void CAIInstance::updateZoneTrigger(CBotPlayer* player) -{ - std::list zoneTriggerManager; - - FOREACH(it, CCont, _Managers) - { - std::string name = it->getName(); - uint32 size = (uint32)name.size(); - const uint32 extensionSize = 13; // strlen(".zone_trigger"); - if (size >= 13 && name.substr(size - extensionSize, extensionSize) == ".zone_trigger" ) - { - CMgrNpc* npcManager = dynamic_cast(*it); - if (npcManager && npcManager->getStateMachine()) - { - zoneTriggerManager.push_back(npcManager); - } - } - } - if ( zoneTriggerManager.empty() ) - { - return; - } - - uint64 whoSeesMe = CMirrors::whoSeesMe(player->dataSetRow()); - if (!R2_VISION::isEntityVisibleToPlayers(whoSeesMe)) - { - // The player is invisible, its a Dm / Gm: no zone event must be triggered - return; - } - - std::set insideZone; - std::vector enterZone; - std::vector leaveZone; - - FOREACH(it, std::list, zoneTriggerManager) - { - CMgrNpc* npcManager = *it; - CAliasCont& groups = npcManager->groups(); - - CAliasCont::iterator first2(groups.begin()), last2(groups.end()); - for ( ; first2 != last2 ; ++first2) - { - CAIState* startState = first2->getPersistentStateInstance()->getStartState(); - if (startState->isPositional()) - { - const CAIStatePositional* posit = dynamic_cast(startState); - if (posit) - { - CAIVector pos( player->pos() ); - bool inside = posit->contains(pos); - if (inside) - { - insideZone.insert(first2->getAlias()); - } - } - } - } - } - - player->updateInsideTriggerZones(insideZone, enterZone, leaveZone); - - - static NLMISC::TStringId nbPlayer = CStringMapper::map("NbPlayer"); - - FOREACH(zoneIt, std::vector, enterZone) - { - FOREACH(it, std::list, zoneTriggerManager) - { - CGroup* grp = (*it)->groups().getChildByAlias(*zoneIt); - if (grp) - { - - CGroupNpc* grpNpc = dynamic_cast(grp); - CPersistentStateInstance* sa = grpNpc->getPersistentStateInstance(); - if (sa) - { - sa->setLogicVar(nbPlayer, sa->getLogicVar(nbPlayer) + 1); - } - grpNpc->processStateEvent(grpNpc->getEventContainer().EventPlayerEnterTriggerZone); - } - } - } - - FOREACH(zoneIt, std::vector, leaveZone) - { - FOREACH(it, std::list, zoneTriggerManager) - { - CGroup* grp = (*it)->groups().getChildByAlias(*zoneIt); - if (grp) - { - CGroupNpc* grpNpc = dynamic_cast(grp); - CPersistentStateInstance* sa = grpNpc->getPersistentStateInstance(); - if (sa) - { - sa->setLogicVar(nbPlayer, sa->getLogicVar(nbPlayer) - 1); - } - grpNpc->processStateEvent(grpNpc->getEventContainer().EventPlayerLeaveTriggerZone); - } - } - } - -} - -CNpcZone* CAIInstance::getZone(TStringId zoneName) -{ - return zoneList[zoneName]; -} - -std::string CAIInstance::getManagerIndexString(CManager const* manager) const -{ - return getIndexString()+NLMISC::toString(":m%u", manager->getChildIndex()); -} - -void CAIInstance::initInstance(string const& continentName, uint32 instanceNumber) -{ - _ContinentName = continentName; - _InstanceNumber = instanceNumber; - - sendInstanceInfoToEGS(); - - if (!EGSHasMirrorReady) - return; - - // check all player in mirror to insert them in this instance. - TEntityIdToEntityIndexMap::const_iterator it, itEnd(TheDataset.entityEnd()); - for (it = TheDataset.entityBegin(); it!=itEnd; ++it) - { - if (it->first.getType()!=RYZOMID::player) - continue; - - TDataSetRow const row = TheDataset.getCurrentDataSetRow(it->second); - if (!row.isValid()) - continue; - - // this is a player, check the instance number - CMirrorPropValueRO playerInstance(TheDataset, row, DSPropertyAI_INSTANCE); - if (playerInstance != instanceNumber) - continue; - - // ok, add this player - getPlayerMgr()->addSpawnedPlayer(row, it->first); - } -} - -void CAIInstance::serviceEvent(CServiceEvent const& info) -{ - if (info.getServiceName() == "EGS") - sendInstanceInfoToEGS(); - - FOREACH(it, CCont, managers()) - it->serviceEvent(info); - - if (CMgrPet* petManager = getPetMgr()) - petManager->serviceEvent(info); - - if (_EventNpcManager) - _EventNpcManager->serviceEvent(info); - - FOREACH(first, CCont, continents()) - (*first)->serviceEvent(info); -} - -void CAIInstance::sendInstanceInfoToEGS() -{ - // send message to the EGS about this new instance - if (EGSHasMirrorReady) - { - CReportStaticAIInstanceMsg msg; - msg.InstanceNumber = _InstanceNumber; - msg.InstanceContinent = _ContinentName; - - msg.send("EGS"); - } -} - -bool CAIInstance::advanceUserTimer(uint32 nbTicks) -{ - // for each manager, look for a timer event - FOREACH(it, CCont, _Managers) - { - CGroup* grp = (*it)->getNextValidGroupChild(); - while (grp) - { - grp->getPersistentStateInstance()->advanceUserTimer(nbTicks); - grp=(*it)->getNextValidGroupChild(grp); // next group - } - } - return true; -} - -void CAIInstance::addGroupInfo(CGroup* grp) -{ - string const& name = grp->aliasTreeOwner()->getName(); - uint32 alias = grp->aliasTreeOwner()->getAlias(); - - if (!name.empty()) - _GroupFromNames[name].push_back(grp); - if (alias) - _GroupFromAlias[alias] = grp; -} - -void CAIInstance::removeGroupInfo(CGroup* grp, CAliasTreeOwner* grpAliasTreeOwner) -{ - string const& name = grpAliasTreeOwner->getName(); - uint32 alias = grpAliasTreeOwner->getAlias(); - - if (!name.empty()) - { - std::map< std::string, std::vector > >::iterator it=_GroupFromNames.find(name); - - // remove from name - if (it!=_GroupFromNames.end()) - { - std::vector > &v = it->second; // _GroupFromNames[name]; - std::vector >::iterator itGrp(find(v.begin(), v.end(), NLMISC::CDbgPtr(grp) )); - if (itGrp != v.end()) - v.erase(itGrp); - } - } - // remove from alias - if (alias) - _GroupFromAlias.erase(alias); -} - -CGroup* CAIInstance::findGroup(uint32 alias) -{ - std::map >::iterator it(_GroupFromAlias.find(alias)); - if (it != _GroupFromAlias.end()) - return it->second; - return NULL; -} - -void CAIInstance::findGroup(std::vector& result, std::string const& name) -{ - std::map > >::iterator it(_GroupFromNames.find(name)); - if (it != _GroupFromNames.end()) - result.insert(result.end(), it->second.begin(), it->second.end()); -} - -void CAIInstance::addMissionInfo(std::string const& missionName, uint32 alias) -{ - std::string const* otherName; - - while (true) - { - otherName = &findMissionName(alias); - if (otherName->empty()) - break; - nlwarning("Replacing mission name for alias %u from '%s' to '%s'", alias, otherName->c_str(), missionName.c_str()); - vector &aliases = _MissionToAlias[*otherName]; - aliases.erase(find(aliases.begin(), aliases.end(), alias)); - } - - vector& aliases = _MissionToAlias[missionName]; - if (std::find(aliases.begin(), aliases.end(), alias) == aliases.end()) - aliases.push_back(alias); -} - -std::string const& CAIInstance::findMissionName(uint32 alias) -{ - map >::iterator it, itEnd(_MissionToAlias.end()); - for (it=_MissionToAlias.begin(); it!=itEnd; ++it) - { - vector::iterator it2, itEnd2(it->second.end()); - for (it2=it->second.begin(); it2!=itEnd2; ++it2) - { - if (*it2 == alias) - return it->first; - } - } - static string emptyString; - return emptyString; -} - -void CAIInstance::update() -{ - // Call the player manager's updates - { - H_AUTO(PlayerMgrUpdate) - getPlayerMgr()->update(); - } - - // Call the managers' updates - { - H_AUTO(ManagersUpdate) - FOREACH(it, CCont, _Managers) - it->CManager::update(); - } - - // call continent's update - { - H_AUTO(ContinentsUpdate) - FOREACH(it, CCont, _Continents) - it->CContinent::update(); - } -} - -CManager* CAIInstance::tryToGetManager(char const* str) -{ - return dynamic_cast(tryToGetEntity(str, CAIS::AI_MANAGER)); -} - -CGroup* CAIInstance::tryToGetGroup(char const* str) -{ - return dynamic_cast(tryToGetEntity(str, CAIS::AI_GROUP)); -} - -// :TODO: Document that function -CAIEntity* CAIInstance::tryToGetEntity(char const* str, CAIS::TSearchType searchType) -{ - char ident[512]; - char* id = ident; - - strcpy(ident,str); - - char *mgr=NULL; - char *grp=NULL; - char *bot=NULL; - char lastChar; - CManager *mgrPtr=NULL; - CGroup *grpPtr=NULL; - CBot *botPtr=NULL; - uint32 localIndex = std::numeric_limits::max(); - - mgr = id; - while((*id!=':')&&(*id!=0)) id++; - lastChar = *id; - *id=0; - id++; - - localIndex=getInt64FromStr(mgr); - if (localIndex (mgrPtr); - - grp = id; - while((*id!=':')&&(*id!=0)) id++; - lastChar = *id; - *id=0; - id++; - - grpPtr = mgrPtr->getGroup(getInt64FromStr(grp)); - if (!grpPtr) - goto tryWithEntityId; - if ( lastChar==0 - || searchType==CAIS::AI_GROUP) - return dynamic_cast (grpPtr); - - bot = id; - while((*id!=':')&&(*id!=0)) id++; - lastChar = *id; - *id=0; - - botPtr = grpPtr->getBot(getInt64FromStr(bot)); - if (!botPtr) - goto tryWithEntityId; - if ( lastChar==0 - || searchType==CAIS::AI_BOT) - return dynamic_cast (botPtr); - - return NULL; - -tryWithEntityId: - - CEntityId entityId; - entityId.fromString(str); - - if (entityId.isUnknownId()) - return NULL; - - CCont::iterator instanceIt=CAIS::instance().AIList().begin(), instanceItEnd=CAIS::instance().AIList().end(); - - while (instanceIt!=instanceItEnd) - { - CAIInstance *instancePtr=*instanceIt; - - CCont::iterator it=instancePtr->managers().begin(), itEnd=instancePtr->managers().end(); - - while (it!=itEnd) - { - mgrPtr = *it; - - grpPtr = mgrPtr->getNextValidGroupChild (); - while (grpPtr) - { - botPtr = grpPtr->getNextValidBotChild(); - while (botPtr) - { - if (botPtr->isSpawned() && botPtr->getSpawnObj()->getEntityId() == entityId) -// if (botPtr->createEntityId()==entityId) - return dynamic_cast (botPtr); - botPtr = grpPtr->getNextValidBotChild (botPtr); - } - grpPtr=mgrPtr->getNextValidGroupChild (grpPtr); - } - ++it; - } - ++instanceIt; - } - - return NULL; -} - -//-------------------------------------------------------------------------- -// factory method newMgr() -//-------------------------------------------------------------------------- - -// factory for creating new managers and for adding them to the _Managers map -// asserts if the id is invalid (<0 or >1023) -// asserts if the id is already in use -CManager* CAIInstance::newMgr(AITYPES::TMgrType type, uint32 alias, std::string const& name, std::string const& mapName, std::string const& filename) -{ - - CManager* mgr = CManager::createManager(type, this, alias, name, "", filename); - // add the manager into the singleton's managers vector - if (mgr) - { - _Managers.addChild(mgr); - mgr->init (); - } - return mgr; -} - -bool CAIInstance::spawn() -{ - // Spawn instance managers - CCont::iterator itManager, itManagerEnd(_Managers.end()); - for (itManager=_Managers.begin(); itManager!=itManagerEnd; ++itManager) - { - CManager* manager = *itManager; - manager->spawn(); - } - // Spawn continents - CCont::iterator itContinent, itContinentEnd(continents().end()); - for (itContinent=continents().begin(); itContinent!=itContinentEnd; ++itContinent) - { - CContinent* continent = *itContinent; - continent->spawn(); - } - // We should check individual errors, but fake success here :) - return true; -} - -bool CAIInstance::despawn() -{ - // Despawn instance managers - CCont::iterator itManager, itManagerEnd(_Managers.end()); - for (itManager=_Managers.begin(); itManager!=itManagerEnd; ++itManager) - { - CManager* manager = *itManager; - manager->despawnMgr(); - } - // Despawn continents - CCont::iterator itContinent, itContinentEnd(_Continents.end()); - for (itContinent=_Continents.begin(); itContinent!=itContinentEnd; ++itContinent) - { - CContinent* continent = *itContinent; - continent->despawn(); - } - // We should check individual errors, but fake success here :) - return true; -} - -//---------------------------------------------------------------------------- -// deleteMgr() -//---------------------------------------------------------------------------- - -// erase a manager (free resources, free id, etc, etc -// asserts if the id is invalid (<0 or >1023) -// displays a warning and returns cleanly if the id is unused -void CAIInstance::deleteMgr(sint mgrId) -{ - _Managers.removeChildByIndex(mgrId); -} - -//---------------------------------------------------------------------------- -// Interface to kami management -//---------------------------------------------------------------------------- - -void CAIInstance::registerKamiDeposit(uint32 alias, CGroupNpc* grp) -{ - if (_KamiDeposits.find(alias) !=_KamiDeposits.end() && _KamiDeposits[alias]!=grp) - { - nlwarning("Failed to register Kami deposit '%s' with alias '%u' because alias already assigned to deposit '%s'", - (grp==NULL || grp->getAliasNode()==NULL) ? "NULL" : grp->getAliasNode()->fullName().c_str(), - alias, - (_KamiDeposits[alias]==NULL || _KamiDeposits[alias]->getAliasNode()==NULL)? "NULL": _KamiDeposits[alias]->getAliasNode()->fullName().c_str() - ); - return; - } - if (grp!=NULL) - _KamiDeposits[alias] = grp; - else - nlwarning("Attempt to assign Kami deposit alias '%u' to an inexistant group",alias); -} - -void CAIInstance::unregisterKamiDeposit(uint32 alias) -{ - if (_KamiDeposits.find(alias) !=_KamiDeposits.end()) - _KamiDeposits.erase(_KamiDeposits.find(alias)); -} - -//---------------------------------------------------------------------------- - -std::string CAIInstance::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":i%u", getChildIndex()); -} - -std::string CAIInstance::getOneLineInfoString() const -{ - return "AI instance number " + NLMISC::toString("%u", getInstanceNumber()) + ", continent '" + getContinentName() + "'"; -} - -std::vector CAIInstance::getMultiLineInfoString() const -{ - std::vector container; - - - pushTitle(container, "CAIInstance"); - pushEntry(container, "id=" + getIndexString()); - container.back() += " num=" + NLMISC::toString("%u", getInstanceNumber()); - container.back() += " continent=" + getContinentName(); - pushFooter(container); - - - return container; -} - -//---------------------------------------------------------------------------- - -#include "ai_bot_npc.h" -#include "ai_profile_npc.h" - -inline -static CAIVector randomPos(double dispersionRadius) -{ - if (dispersionRadius<=0.) - { - return CAIVector(0., 0.); - } - const uint32 maxLimit = std::numeric_limits::max() >> 1; - double rval = (double)CAIS::rand32(maxLimit)/(double)maxLimit; // [0-1[ - double r = dispersionRadius*sqrt(rval); - rval = (double)CAIS::rand32(maxLimit)/(double)maxLimit; // [0-1[ - double t = 2.0*NLMISC::Pi*rval; - double dx = cos(t)*r; - double dy = sin(t)*r; - return CAIVector(dx, dy); -} - -inline -static float randomAngle() -{ - uint32 const maxLimit = CAngle::PI*2; - float val = (float)CAIS::rand32(maxLimit); - return val; -} - -CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName, const std::string &look) -{ - if (!_EventNpcManager) - return NULL; - - AISHEETS::ICreatureCPtr sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId); - if (!sheet) - { - nlwarning("invalid sheet while creating event npc group"); - return NULL; - } - - // Create a group - CGroupNpc* grp = new CGroupNpc(_EventNpcManager, NULL, RYAI_MAP_CRUNCH::Nothing); - // Register it in the manager - _EventNpcManager->groups().addAliasChild(grp); - // Set the group parameters - grp->setAutoSpawn(false); - grp->setName(NLMISC::toString("event_group_%u", grp->getChildIndex())); - grp->clearParameters(); - grp->setPlayerAttackable(true); - grp->setBotAttackable(true); - - grp->autoDestroy(true); - - grp->clrBotsAreNamedFlag(); - - { - // build unnamed bot - for (uint i=0; ibots().addChild(new CBotNpc(grp, 0, botsName.empty() ? grp->getName():botsName), i); // Doub: 0 instead of getAlias()+i otherwise aliases are wrong - - CBotNpc* const bot = NLMISC::safe_cast(grp->bots()[i]); - - bot->setSheet(sheet); - if (!look.empty()) - bot->setClientSheet(look); - bot->equipmentInit(); - bot->initEnergy(/*groupEnergyCoef()*/0); - CAIVector rpos(pos); - if (dispersionRadius == 0) - { - nlinfo("Stucked !"); - bot->setStuck(true); - } - // Spawn all randomly except if only 1 bot - if (nbBots > 1) - { - RYAI_MAP_CRUNCH::CWorldMap const& worldMap = CWorldContainer::getWorldMap(); - RYAI_MAP_CRUNCH::CWorldPosition wp; - uint32 maxTries = 100; - do - { - rpos = pos; - rpos += randomPos(dispersionRadius); - --maxTries; - } - while (!worldMap.setWorldPosition(AITYPES::vp_auto, wp, rpos) && maxTries>0); - if (maxTries<=0) - rpos = pos; - } - - float angle = 0.f; - if (orientation < (NLMISC::Pi * 2.0) && orientation > (-NLMISC::Pi * 2.0)) - angle = (float)orientation; - else - angle = randomAngle(); - - bot->setStartPos(rpos.x().asDouble(),rpos.y().asDouble(), angle, AITYPES::vp_auto); - } - } - - grp->spawn(); - CSpawnGroupNpc* spawnGroup = grp->getSpawnObj(); - if (!spawnGroup) - { - // the spawning has failed, delete the useless object - nlwarning("Failed to spawn the event group"); - _EventNpcManager->groups().removeChildByIndex(grp->getChildIndex()); - return NULL; - } - - NLMISC::CSmartPtr destZone = NLMISC::CSmartPtr(new CNpcZonePlaceNoPrim()); - destZone->setPosAndRadius(AITYPES::vp_auto, CAIPos(pos, 0, 0), (uint32)(dispersionRadius*1000.)); - spawnGroup->movingProfile().setAIProfile(new CGrpProfileWanderNoPrim(spawnGroup, destZone)); - - if (spawnBots) - grp->getSpawnObj()->spawnBots(); - - return grp; -} - -CBotEasterEgg* CAIInstance::createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look) -{ - if (_EasterEggManager == NULL) - return NULL; - - if (_EasterEggGroup == NULL) - { - // create the easter egg group - CGroupNpc* grp = new CGroupNpc(_EasterEggManager, NULL, RYAI_MAP_CRUNCH::Nothing); - _EasterEggManager->groups().addAliasChild(grp); - - // set the group parameters - grp->setAutoSpawn(false); - grp->setName("easter_egg_group"); - grp->clearParameters(); - grp->setPlayerAttackable(true); - grp->setBotAttackable(true); // if false the bot will not be attackable by players... - grp->autoDestroy(false); - - // spawn the group - grp->spawn(); - - CSpawnGroupNpc* spawnGroup = grp->getSpawnObj(); - if (spawnGroup == NULL) - { - // the spawning has failed, delete the useless object - nlwarning("Failed to spawn the easter egg group"); - _EasterEggManager->groups().removeChildByIndex(grp->getChildIndex()); - return NULL; - } - - // easter eggs do not move - spawnGroup->movingProfile().setAIProfile(new CGrpProfileIdle(spawnGroup)); - - // keep a pointer on the easter egg group - _EasterEggGroup = grp; - } - nlassert(_EasterEggGroup != NULL); - - if (getEasterEgg(easterEggId) != NULL) - { - nlwarning("An easter egg with ID %u already exists in instance %u", easterEggId, getInstanceNumber()); - return NULL; - } - - AISHEETS::ICreatureCPtr sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId); - if (!sheet) - { - nlwarning("Invalid sheet '%s' while creating an easter egg", sheetId.toString().c_str()); - return NULL; - } - - // build the easter egg bot - CBotEasterEgg* bot = new CBotEasterEgg(_EasterEggGroup, 0, botName, easterEggId); - _EasterEggGroup->bots().addChild(bot); - - bot->setSheet(sheet); - if (!look.empty()) { bot->setClientSheet(look); } - bot->equipmentInit(); - bot->initEnergy(0); - bot->setStartPos(x, y, float(heading), AITYPES::vp_auto); - - bot->spawn(); - if (!bot->isSpawned()) - { - // the spawning has failed, delete the useless object - nlwarning("Failed to spawn the easter egg bot"); - _EasterEggGroup->bots().removeChildByIndex(bot->getChildIndex()); - return NULL; - } - - return bot; -} - -void CAIInstance::destroyEasterEgg(uint32 easterEggId) -{ - CBotEasterEgg* bot = getEasterEgg(easterEggId); - if (bot != NULL) - { - bot->despawnBot(); - _EasterEggGroup->bots().removeChildByIndex(bot->getChildIndex()); - } - else - { - nlwarning("Cannot destroy easter egg %u because not found", easterEggId); - } -} - -CBotEasterEgg* CAIInstance::getEasterEgg(uint32 easterEggId) -{ - if (_EasterEggGroup == NULL) - return NULL; - - FOREACH(itBot, CCont, _EasterEggGroup->bots()) - { - CBotEasterEgg* bot = dynamic_cast(*itBot); -#if !FINAL_VERSION - nlassert(bot != NULL); -#endif - if (bot != NULL && bot->getEasterEggId() == easterEggId) - return bot; - } - - return NULL; -} - -void cbEventCreateNpcGroup( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - uint32 messageVersion; - uint32 instanceNumber; - sint32 x; - sint32 y; - sint32 z; - sint32 orientation; - uint32 nbBots; - NLMISC::CSheetId sheetId; - CEntityId playerId; - double dispersionRadius; - bool spawnBots; - std::string botsName; - std::string look; - sint32 cell; - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(instanceNumber); - msgin.serial(playerId); - msgin.serial(x); - msgin.serial(y); - msgin.serial(z); - msgin.serial(orientation); - msgin.serial(nbBots); - msgin.serial(sheetId); - msgin.serial(dispersionRadius); - msgin.serial(spawnBots); - msgin.serial(botsName); - msgin.serial(look); - msgin.serial(cell); - CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber); - if (instance) - { - CGroupNpc* npcGroup = instance->eventCreateNpcGroup(nbBots, sheetId, CAIVector(((double)x)/1000.0, ((double)y)/1000.0), dispersionRadius, spawnBots, ((double)orientation)/1000.0, botsName, look); - if (npcGroup != NULL) - { - _PlayersLastCreatedNpcGroup[playerId] = npcGroup->getName(); - - FOREACH(botIt, CCont, npcGroup->bots()) - { - CSpawnBot* pbot = botIt->getSpawnObj(); - if (pbot!=NULL) - { - CEntityId id = pbot->getEntityId(); - float t = 0; - uint8 cont = 0; - uint8 one = 1; - NLMISC::TGameCycle tick = CTickEventHandler::getGameCycle() + 1; - CMessage msgout2("ENTITY_TELEPORTATION"); - msgout2.serial( id ); - msgout2.serial( x ); - msgout2.serial( y ); - msgout2.serial( z ); - msgout2.serial( t ); - msgout2.serial( tick ); - msgout2.serial( cont ); - msgout2.serial( cell ); - msgout2.serial( one ); - - sendMessageViaMirror("GPMS", msgout2); - } - } - } - } -} - -extern vector > scriptCommands2; - -void cbEventNpcGroupScript( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - uint32 messageVersion; - string botId; - uint32 nbString; - vector strings; - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(nbString); - - string eid; - string firstCommand; - msgin.serial(eid); // Player or boteid - msgin.serial(firstCommand); // Player or boteid - - if (firstCommand[0] == '(') // Old eventNpcGroupScript command : (boteid, commands...) - { - nlinfo("Event group script with %d strings :", nbString); - strings.resize(nbString); - strings[0] = eid; - nlinfo(" %d '%s'", 0, strings[0].c_str()); - strings[1] = firstCommand; - nlinfo(" %d '%s'", 1, strings[1].c_str()); - for (uint32 i=2; igetEntity(botEId); - CSpawnBotNpc* bot = dynamic_cast(entity); - if (!bot) - return; - if (!bot->getPersistent().getOwner()) - return; - - strings[0] = bot->getPersistent().getOwner()->getName(); - } - else - { - strings[0] = (string)groupname.replace("#last", _PlayersLastCreatedNpcGroup[playerId].c_str()); - } - nlinfo(" %d '%s'", 0, strings[0].c_str()); - for (uint32 i=1; i bots; - /// try to find the bot name - buildFilteredBotList(bots, botName); - if (bots.empty()) - { - nlwarning("No bot correspond to name %s", botName.c_str()); - return; - } - else - { - FOREACH(itBot, vector, bots) - { - CBot* bot = *itBot; - CBotFauna* botFauna = dynamic_cast(bot); - if (botFauna) - { - if (notHungryRadius>=0.f) - botFauna->setAggroRadiusNotHungry(notHungryRadius); - if (hungryRadius>=0.f) - botFauna->setAggroRadiusHungry(hungryRadius); - if (huntingRadius>=0.f) - botFauna->setAggroRadiusHunting(huntingRadius); - } - } - } -} - -void cbEventFaunaBotResetRadii( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - uint32 messageVersion; - string botName; - - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(botName); - - vector bots; - /// try to find the bot name - buildFilteredBotList(bots, botName); - if (bots.empty()) - { - nlwarning("No bot correspond to name %s", botName.c_str()); - return; - } - else - { - FOREACH(itBot, vector, bots) - { - CBot* bot = *itBot; - CBotFauna* botFauna = dynamic_cast(bot); - if (botFauna) - botFauna->resetAggroRadius(); - } - } -} - -void cbEventBotCanAggro( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - uint32 messageVersion; - string botName; - bool canAggro; - - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(botName); - msgin.serial(canAggro); - - vector bots; - /// try to find the bot name - buildFilteredBotList(bots, botName); - if (bots.empty()) - { - nlwarning("No bot correspond to name %s", botName.c_str()); - return; - } - else - { - FOREACH(itBot, vector, bots) - { - CBot* bot = *itBot; - if (bot) - { - CSpawnBot* spBot = bot->getSpawnObj(); - if (spBot) - spBot->setCanAggro(canAggro); - } - } - } -} - -void cbEventBotSheet( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - uint32 messageVersion; - string botName; - NLMISC::CSheetId sheetId; - bool autoSpawnDespawn; - string customName; - - msgin.serial(messageVersion); - nlassert(messageVersion==3); - msgin.serial(botName); - msgin.serial(sheetId); - msgin.serial(autoSpawnDespawn); - msgin.serial(customName); - - vector bots; - /// try to find the bot name - buildFilteredBotList(bots, botName); - if (bots.empty()) - { - nlwarning("No bot correspond to name %s", botName.c_str()); - return; - } - else - { - AISHEETS::ICreatureCPtr const sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId); - if (sheetId!=NLMISC::CSheetId::Unknown && !sheet.isNull()) - { - FOREACH(itBot, vector, bots) - { - CBot* bot = *itBot; - if (bot) - { - bot->setCustomName(customName); - bot->triggerSetSheet(sheet); - if (autoSpawnDespawn && !bot->isSpawned()) - bot->spawn(); - } - } - } - else if (autoSpawnDespawn) - { - FOREACH(itBot, vector, bots) - { - CBot* bot = *itBot; - if (bot && bot->isSpawned()) - bot->despawnBot(); - } - } - } -} - -extern vector > scriptCommandsBotById; - -void cbR2NpcBotScriptById(NLNET::CMessage& msgin, const std::string& serviceName, NLNET::TServiceId serviceId) -{ - uint32 messageVersion; - string botId; - uint32 nbString; - vector strings; - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(nbString); - strings.resize(nbString); - for (uint32 i=0; i > scriptCommandsGroupByName; - -void cbR2NpcGroupScriptByName(NLNET::CMessage& msgin, const std::string& serviceName, NLNET::TServiceId serviceId) -{ - uint32 messageVersion; - string botId; - uint32 nbString; - vector strings; - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(nbString); - strings.resize(nbString); - for (uint32 i=0; i TRegisteredServiceMap; - TRegisteredServiceMap _RegisteredServices; -}; - -CBotDespawnNotification* CBotDespawnNotification::_Instance = NULL; - -CBotDespawnNotification::CBotDespawnNotification() -{ -} - -CBotDespawnNotification* CBotDespawnNotification::getInstance() -{ - if (_Instance == NULL) - _Instance = new CBotDespawnNotification; - return _Instance; -} - -void CBotDespawnNotification::registerService(NLNET::TServiceId serviceId, CBot* bot, const NLMISC::CEntityId& botId) -{ - nlassert(bot != NULL); - - TRegisteredServiceMap::const_iterator first = _RegisteredServices.lower_bound(bot->getAlias()); - TRegisteredServiceMap::const_iterator last = _RegisteredServices.upper_bound(bot->getAlias()); - - if (first == last) - bot->attachObserver(this); - - CRegisteredService rs(serviceId, botId); - - for (; first != last; ++first) - { - if ((*first).second == rs) - break; - } - if (first == last) - _RegisteredServices.insert( make_pair(bot->getAlias(), rs) ); -} - -void CBotDespawnNotification::dump(CLog& log) const -{ - FOREACHC(it, TRegisteredServiceMap, _RegisteredServices) - { - const CRegisteredService& rs = (*it).second; - log.displayNL("BotAlias %s => ServiceId %hu, BotId %s", - LigoConfig.aliasToString((*it).first).c_str(), - rs.getServiceId().get(), - rs.getBotId().toString().c_str() - ); - } -} - -void CBotDespawnNotification::notifyBotDespawn(CBot* bot) -{ - nlassert(bot != NULL); - - // catch this event only once for current services registered for this bot - bot->detachObserver(this); - - TRegisteredServiceMap::iterator first = _RegisteredServices.lower_bound(bot->getAlias()); - TRegisteredServiceMap::iterator last = _RegisteredServices.upper_bound(bot->getAlias()); - if (first == last) - { - nlwarning("No service requested despawn notification for bot %s", - LigoConfig.aliasToString(bot->getAlias()).c_str() - ); - DEBUG_STOP; - return; - } - - // notify all services registered for this bot - while (first != last) - { - const CRegisteredService& rs = (*first).second; - CMessages::notifyBotDespawn(rs.getServiceId(), bot->getAlias(), rs.getBotId()); - - TRegisteredServiceMap::iterator tmp = first; - ++first; - _RegisteredServices.erase(tmp); - } -} - -void CBotDespawnNotification::notifyStopNpcControl(CBot* bot) -{ - nlassert(bot != NULL); - - // catch this event only once for current services registered for this bot - //bot->detachObserver(this); - - TRegisteredServiceMap::iterator first = _RegisteredServices.lower_bound(bot->getAlias()); - TRegisteredServiceMap::iterator last = _RegisteredServices.upper_bound(bot->getAlias()); - - - // notify all services registered for this bot - while (first != last) - { - const CRegisteredService& rs = (*first).second; - CMessages::notifyBotStopNpcControl(rs.getServiceId(), bot->getAlias(), rs.getBotId()); - - TRegisteredServiceMap::iterator tmp = first; - ++first; - // _RegisteredServices.erase(tmp); - } -} -void CBotDespawnNotification::notifyBotDeath(CBot* bot) -{ - nlassert(bot != NULL); - - // catch this event only once for current services registered for this bot - bot->detachObserver(this); - - TRegisteredServiceMap::iterator first = _RegisteredServices.lower_bound(bot->getAlias()); - TRegisteredServiceMap::iterator last = _RegisteredServices.upper_bound(bot->getAlias()); - if (first == last) - { - nlwarning("No service requested death notification for bot %s", - LigoConfig.aliasToString(bot->getAlias()).c_str() - ); - DEBUG_STOP; - return; - } - - // notify all services registered for this bot - while (first != last) - { - const CRegisteredService& rs = (*first).second; - CMessages::notifyBotDeath(rs.getServiceId(), bot->getAlias(), rs.getBotId()); - - TRegisteredServiceMap::iterator tmp = first; - ++first; - _RegisteredServices.erase(tmp); - } -} - - -void cbAskBotDespawnNotification(NLNET::CMessage& msgin, const std::string& serviceName, NLNET::TServiceId serviceId) -{ - uint32 messageVersion; - uint32 botAlias; - CEntityId botId; - - msgin.serial(messageVersion); - nlassert(messageVersion == 1); - msgin.serial(botAlias); - msgin.serial(botId); - - TDataSetRow botRowId = CMirrors::getDataSetRow(botId); - if (botRowId.isNull()) - { - CMessages::notifyBotDespawn(serviceId, botAlias, botId); - return; - } - - CAIEntityPhysical* entity = CAIS::instance().getEntityPhysical(botRowId); - if (entity == NULL) - { - CMessages::notifyBotDespawn(serviceId, botAlias, botId); - return; - } - -#if !FINAL_VERSION - nlassert(entity->getEntityId() == botId); -#endif - - CSpawnBot* bot = NULL; - switch (entity->getRyzomType()) - { - case RYZOMID::creature: - case RYZOMID::npc: - bot = NLMISC::safe_cast(entity); - break; - default: - break; - } - - // check if the bot has been replaced by another entity in mirror - if (bot == NULL || bot->getPersistent().getAlias() != botAlias) - { - CMessages::notifyBotDespawn(serviceId, botAlias, botId); - return; - } - - // register the service to be notified when the bot will despawn - CBotDespawnNotification::getInstance()->registerService(serviceId, &bot->getPersistent(), botId); -} - -void cbSpawnEasterEgg(NLNET::CMessage& msgin, const std::string& serviceName, NLNET::TServiceId serviceId) -{ - uint32 messageVersion; - uint32 instanceNumber; - uint32 easterEggId; - CSheetId sheetId; - string botName; - string look; - - sint32 x, y, z; - float heading; - - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(instanceNumber); - msgin.serial(easterEggId); - msgin.serial(sheetId); - msgin.serial(botName); - msgin.serial(look); - msgin.serial(x, y, z, heading); - - CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber); - if (instance != NULL) - { - CBotEasterEgg* bot = instance->createEasterEgg(easterEggId, sheetId, botName, float(x)/1000., float(y)/1000., float(z)/1000., heading, look ); - if (bot != NULL) - { - nlassert(bot->getSpawn() != NULL); - CEntityId botId = bot->getSpawn()->getEntityId(); - - NLNET::CMessage msgout("EASTER_EGG_SPAWNED"); - msgout.serial(botId); - msgout.serial(easterEggId); - sendMessageViaMirror(serviceId, msgout); - } - else - { - nlwarning("Cannot spawn easter egg %u!", easterEggId); - } - } - else - { - nlwarning("Cannot spawn easter egg %u, AI instance %u not found!", easterEggId, instanceNumber); - } -} - -void cbDespawnEasterEgg(NLNET::CMessage& msgin, const std::string& serviceName, NLNET::TServiceId serviceId) -{ - uint32 messageVersion; - uint32 instanceNumber; - uint32 easterEggId; - - msgin.serial(messageVersion); - nlassert(messageVersion==1); - msgin.serial(instanceNumber); - msgin.serial(easterEggId); - - CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber); - if (instance != NULL) - { - instance->destroyEasterEgg(easterEggId); - } -} - -NLMISC_COMMAND(simulateMsgAskBotDespawnNotification, "", " ") -{ - if (args.size() != 3) - return false; - - uint16 id; - NLMISC::fromString(args[0], id); - NLNET::TServiceId serviceId(id); - uint32 botAlias = LigoConfig.aliasFromString(args[1]); - CEntityId botId(args[2].c_str()); - - NLNET::CMessage msg("ASK_BOT_DESPAWN_NOTIFICATION"); - uint32 messageVersion = 1; - msg.serial(messageVersion, botAlias, botId); - msg.invert(); - cbAskBotDespawnNotification(msg, "FAKE", serviceId); - - return true; -} - -NLMISC_COMMAND(dumpBotDespawnNotification, "", "") -{ - if (args.size() != 0) - return false; - - CBotDespawnNotification::getInstance()->dump(log); - return true; -} - -NLMISC_COMMAND(simulateMsgSpawnEasterEgg, "", " ") -{ - if (args.size() != 7) - return false; - - uint16 id; - NLMISC::fromString(args[0], id); - NLNET::TServiceId serviceId(id); - uint32 instanceNumber; - NLMISC::fromString(args[1], instanceNumber); - uint32 easterEggId; - NLMISC::fromString(args[2], easterEggId); - CSheetId sheetId(args[3]); - string botName = args[4]; - sint32 x; - NLMISC::fromString(args[5], x); - sint32 y; - NLMISC::fromString(args[6], y); - sint32 z = 0; - sint32 heading = 0; - std::string look = ""; - - NLNET::CMessage msg("SPAWN_EASTER_EGG"); - uint32 messageVersion = 1; - msg.serial(messageVersion); - msg.serial(instanceNumber); - msg.serial(easterEggId); - msg.serial(sheetId); - msg.serial(botName); - msg.serial(look); - - msg.serial(x, y, z, heading); - msg.invert(); - cbSpawnEasterEgg(msg, "FAKE", serviceId); - - return true; -} - -NLMISC_COMMAND(simulateMsgDespawnEasterEgg, "", " ") -{ - if (args.size() != 3) - return false; - - uint16 id; - NLMISC::fromString(args[0], id); - NLNET::TServiceId serviceId(id); - uint32 instanceNumber; - NLMISC::fromString(args[1], instanceNumber); - uint32 easterEggId; - NLMISC::fromString(args[2], easterEggId); - - NLNET::CMessage msg("DESPAWN_EASTER_EGG"); - uint32 messageVersion = 1; - msg.serial(messageVersion); - msg.serial(instanceNumber); - msg.serial(easterEggId); - msg.invert(); - cbDespawnEasterEgg(msg, "FAKE", serviceId); - - return true; -} - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_instance.h b/code/ryzom/server/src/ai_service/ai_instance.h deleted file mode 100644 index 9f59129ce..000000000 --- a/code/ryzom/server/src/ai_service/ai_instance.h +++ /dev/null @@ -1,272 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//#include "ai_entity_id.h" // this must be BEFORE the RYAI_AI_H test - -#ifndef RYAI_AI_INSTANCE_H -#define RYAI_AI_INSTANCE_H - -#include "child_container.h" -#include "server_share/msg_ai_service.h" -#include "ai_entity_matrix.h" -#include "ai_entity.h" -#include "continent.h" -#include "ai_grp.h" -#include "service_dependencies.h" - -#include "sheets.h" - -class CBot; -class CGroup; -class CManager; - -template -class CAIEntityMatrix; -class CAIEntityMatrixIteratorTblRandom; -class CAIEntityMatrixIteratorTblLinear; - -class CAIEntityPhysical; -class CAIEntity; -class CMgrPet; -class CManagerPlayer; -class CGroupNpc; -class CPersistentOfPhysical; -class CManagerPlayer; -class CAIS; -class CContinent; -class CCell; -class COutpostSquadFamily; -class CBotPlayer; -class CBotEasterEgg; - -class CAIInstance -: public NLMISC::CDbgRefCount -, public NLMISC::CRefCount -, public CChild -, public CAIEntity -, public IManagerParent -, public CServiceEvent::CHandler -{ -public: - CAIInstance(CAIS* owner); - virtual ~CAIInstance(); - - typedef CHashMap, NLMISC::CStringIdHashMapTraits> TZoneList; - TZoneList zoneList; - void addZone(std::string const& zoneName, CNpcZone* zone); - void removeZone(std::string const& zoneName, CNpcZone* zone); - CNpcZone* getZone(NLMISC::TStringId zoneName); - // Trig Event if player in zone - void updateZoneTrigger(CBotPlayer* player); - - // overloads for IManagerParent virtuals - CAIInstance* getAIInstance() const { return const_cast(this); } - CCellZone* getCellZone() { return NULL; } - virtual std::string getIndexString() const; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - - std::string getManagerIndexString(CManager const* manager) const; - - void groupDead(CGroup* grp) { } - - void serviceEvent(CServiceEvent const& info); - - //------------------------------------------------------------------- - // classic init(), update() and release() - - // the update routine called once per tick - // this is the routine that calls the managers' updates - void update(); - - //------------------------------------------------------------------- - // managing the set of managers - - // factory for creating new managers and for adding them to the _managers map - CManager* newMgr(AITYPES::TMgrType type, uint32 alias, std::string const& name, std::string const& mapName, std::string const& filename); - - // a method that parse a supposed know type of manager:group:bot hierarchy and return the element as CAIEntity. - CManager* tryToGetManager(char const* str); - CGroup* tryToGetGroup(char const* str); - - CAIEntity* tryToGetEntity(char const* str, CAIS::TSearchType searchType); - - // erase a manager (free resources, free id, etc, etc - // asserts if the id is invalid (<0 or >1023) - // displays a warning and returns cleanly if the id is unused - void deleteMgr(sint mgrId); - - //------------------------------------------------------------------- - // the previous interfaces for searching the data structures for named objects are transfered in CAIEntityId - // as its one of their object behavior. a solution to build id directly was added. - CMgrPet* getPetMgr() { return _PetManager; } - CManagerPlayer* getPlayerMgr() { return _PlayerManager; } - - //------------------------------------------------------------------- - // Interface to kami management - void registerKamiDeposit(uint32 alias, CGroupNpc* grp); - void unregisterKamiDeposit(uint32 alias); - - //------------------------------------------------------------------- - // Interface to the vision management matrices - - // read accessors for getting hold of the vision matrices and their associated iterator tables - CAIEntityMatrix& playerMatrix() { return _PlayerMatrix; } - CAIEntityMatrix& botMatrix() { return _BotMatrix; } - - CAliasCont& managers() { return _Managers; } - - CCont& continents() { return _Continents; } - CCont const& continents() const { return _Continents; } - - // Methods to retreive location in the dynamic system. - CContinent* locateContinentForPos(CAIVector const& pos); - CRegion* locateRegionForPos(CAIVector const& pos); - CCellZone* locateCellZoneForPos(CAIVector const& pos); - CCell* locateCellForPos(CAIVector const& pos); - - - //------------------------------------------------------------------- - // Mission name/alias retreiver - /** Add a mission name and alias info. If alias is already mapped to a mission name, replace the mapping. - * Many alias can be mapped to the same name, but a name can only belong to one alias. - */ - void addMissionInfo(std::string const& missionName, uint32 alias); - /** Return all mission alias that have a given mission name. - * n log n search - */ - void findMissionAlias(std::vector& result, std::string const& missionName) - { - std::map >::iterator it(_MissionToAlias.find(missionName)); - if (it != _MissionToAlias.end()) - result.insert(result.end(), it->second.begin(), it->second.end()); - } - /** Return the name of the mission for a given alias. - * Return an empty string if no mission have this alias. - * This search is not optimized, linar time search ! - */ - std::string const& findMissionName(uint32 alias); - - //------------------------------------------------------------------- - // group name/alias retreiver - void addGroupInfo(CGroup* grp); - void removeGroupInfo(CGroup* grp, CAliasTreeOwner* grpAliasTreeOwner); - CGroup* findGroup(uint32 alias); - void findGroup(std::vector& result, std::string const& name); - - /// Time warp management. This method is called when time as warped more than 600ms - bool advanceUserTimer(uint32 nbTicks); - - bool spawn(); - bool despawn(); - - uint32 getInstanceNumber() const { return _InstanceNumber; } - std::string const& getContinentName() const { return _ContinentName; } - std::string& getContinentName() { return _ContinentName; } - - void initInstance(std::string const& continentName, uint32 instanceNumber); - - /// Main squad family accessor - COutpostSquadFamily *getSquadFamily() { return _SquadFamily; } - - /// Store mapping 'name:variant' -> squad to be used later by getSquadByVariantName() - void registerSquadVariant(const std::string& nameAndVariant, CGroupDesc *squad ) - { - if ( ! _SquadVariantNameToGroupDesc.insert( std::make_pair( NLMISC::toLower( nameAndVariant ), squad ) ).second ) - nlwarning( "Duplicate squad template / squad variant '%s'", nameAndVariant.c_str() ); - } - - /// Clear mapping 'name:variant' -> squad when it's not useful anymore - void clearSquadVariantNames() - { - _SquadVariantNameToGroupDesc.clear(); - } - - /// Get a squad by name:variant (works only during primitive parsing), or NULL if not found. Not case-sensitive. - CGroupDesc *getSquadByVariantName(const std::string& nameAndVariant) - { - std::map > >::iterator it = _SquadVariantNameToGroupDesc.find( NLMISC::toLower( nameAndVariant ) ); - if ( it != _SquadVariantNameToGroupDesc.end() ) - return (*it).second; - else - return NULL; - } - - CGroupNpc* eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName, const std::string &look); - - /// create a new easter egg - CBotEasterEgg* createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look); - /// destroy an easter egg - void destroyEasterEgg(uint32 easterEggId); - /// get an easter egg by ID - CBotEasterEgg* getEasterEgg(uint32 easterEggId); - -private: - void sendInstanceInfoToEGS(); - -private: - /// @name AI service hierarchy - //@{ - /// The set of continents - CCont _Continents; - /// the set of managers and the service's root alias description tree node - CAliasCont _Managers; - //@} - - /// The ai instance continent name (multi ai system) - std::string _ContinentName; - /// The ai instance number (multi ai system) - uint32 _InstanceNumber; - - CAIEntity* tryToGetEntity(char const* str); - - // we must share pets and players .. later :) - /// pet manager - CMgrPet* _PetManager; - /// player Manager. - CManagerPlayer* _PlayerManager; - /// event npc Manager. - CMgrNpc* _EventNpcManager; - /// easter egg manager - NLMISC::CRefPtr _EasterEggManager; - - /// easter egg group - NLMISC::CRefPtr _EasterEggGroup; - - /// map of kami groups by alias (for kami groups associated with deposits) - std::map _KamiDeposits; - - /// matrices used for vision generation and their associated iterator tables - CAIEntityMatrix _PlayerMatrix; - CAIEntityMatrix _BotMatrix; - - // Mission name to alias container. - std::map > _MissionToAlias; - - /// Group name and alias container. - std::map > > _GroupFromNames; - std::map > _GroupFromAlias; - - // Container for all the squad templates - NLMISC::CSmartPtr _SquadFamily; - - // Squad look-up (only valid during primitive parsing) - std::map< std::string, NLMISC::CSmartPtr< CGroupDesc > > _SquadVariantNameToGroupDesc; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_instance_inline.h b/code/ryzom/server/src/ai_service/ai_instance_inline.h deleted file mode 100644 index 31de00f7d..000000000 --- a/code/ryzom/server/src/ai_service/ai_instance_inline.h +++ /dev/null @@ -1,75 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_AI_INSTANCE_INLINE_H -#define RYAI_AI_INSTANCE_INLINE_H - -inline -CContinent* CAIInstance::locateContinentForPos(CAIVector const& pos) -{ - FOREACH(it, CCont, _Continents) - { - if (it->_BoundingBox.isInside(pos)) - return *it; - } - return NULL; -} - -inline -CRegion* CAIInstance::locateRegionForPos(CAIVector const& pos) -{ - CContinent* cont = locateContinentForPos(pos); - if (!cont) - return NULL; - FOREACH(it, CCont, cont->regions()) - { - if (it->_BoundingBox.isInside(pos)) - return *it; - } - return NULL; -} - -inline -CCellZone* CAIInstance::locateCellZoneForPos(CAIVector const& pos) -{ - CRegion* region = locateRegionForPos(pos); - if (!region) - return NULL; - FOREACH(it, CCont, region->cellZones()) - { - if (it->_BoundingBox.isInside(pos)) - return *it; - } - return NULL; -} - -inline -CCell* CAIInstance::locateCellForPos(CAIVector const& pos) -{ - CCellZone* cz = locateCellZoneForPos(pos); - if (!cz) - return NULL; - FOREACH(it, CCont, cz->cells()) - { - if (it->_BoundingBox.isInside(pos)) - return *it; - } - return NULL; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_keywords.cpp b/code/ryzom/server/src/ai_service/ai_keywords.cpp deleted file mode 100644 index ffd6d8a51..000000000 --- a/code/ryzom/server/src/ai_service/ai_keywords.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#include "stdpch.h" -#include "ai_keywords.h" -#include "nel/net/service.h" - -using namespace NLMISC; -using namespace NLNET; - -// singleton data instantiation - -CKeywordSet CAIKeywords::_botKeywords; -CKeywordSet CAIKeywords::_groupKeywords; -CKeywordSet CAIKeywords::_stateKeywords; - -void CAIKeywords::init() -{ - updateKeywordsFromCfg(); -} - -static void loadKeywordsFromCfg(const char *varName,CKeywordSet &wordSet) -{ - // get hold of the config file variable - CConfigFile::CVar *varPtr; - varPtr=IService::getInstance()->ConfigFile.getVarPtr(std::string(varName)); - if (!varPtr) - { - nlwarning("WARNING: Config file variable: %s not found",varName); - return; - } - - // add config file variable contents to keyword set - for (uint32 i=0;isize();++i) - wordSet.addKeywords(varPtr->asString(i)); -} - -void CAIKeywords::updateKeywordsFromCfg() -{ - loadKeywordsFromCfg("KeywordsGroupNpc",_groupKeywords); - loadKeywordsFromCfg("KeywordsBotNpc",_botKeywords); - loadKeywordsFromCfg("KeywordsStateNpc",_stateKeywords); -} - -void CAIKeywords::display() -{ - nlinfo ("bot keywords: %s",_botKeywords.toString().c_str()); - nlinfo ("group keywords: %s",_groupKeywords.toString().c_str()); - nlinfo ("state keywords: %s",_stateKeywords.toString().c_str()); -} - diff --git a/code/ryzom/server/src/ai_service/ai_keywords.h b/code/ryzom/server/src/ai_service/ai_keywords.h deleted file mode 100644 index 2ce141767..000000000 --- a/code/ryzom/server/src/ai_service/ai_keywords.h +++ /dev/null @@ -1,50 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef RYAI_KEYWORDS_H -#define RYAI_KEYWORDS_H - -#include "keyword.h" - -class CAIKeywords -{ -public: - static void init(); - static void updateKeywordsFromCfg(); - static void display(); - - static bool botMask(const std::string &word, CKeywordMask &result) { return _botKeywords.stringToMask(word, result); } - static bool groupMask(const std::string &word, CKeywordMask &result) { return _groupKeywords.stringToMask(word, result); } - static bool stateMask(const std::string &word, CKeywordMask &result) { return _stateKeywords.stringToMask(word, result); } - - static bool botFilter(const std::string &word, CKeywordFilter &result) { return _botKeywords.stringToFilter(word, result); } - static bool groupFilter(const std::string &word, CKeywordFilter &result) { return _groupKeywords.stringToFilter(word, result); } - static bool stateFilter(const std::string &word, CKeywordFilter &result) { return _stateKeywords.stringToFilter(word, result); } - -private: - static CKeywordSet _botKeywords; - static CKeywordSet _groupKeywords; - static CKeywordSet _stateKeywords; - -private: - // this is a singleton so prohibit construction - CAIKeywords(); -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_logic_action.h b/code/ryzom/server/src/ai_service/ai_logic_action.h deleted file mode 100644 index 8439246b2..000000000 --- a/code/ryzom/server/src/ai_service/ai_logic_action.h +++ /dev/null @@ -1,88 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_LOGIC_ACTION_H -#define RYAI_LOGIC_ACTION_H - -#include "alias_tree_owner.h" -#include "game_share/r2_basic_types.h" - -class IAIEvent; - -class CAIEventReaction; -class CGroupFamily; -class CGroup; -class CStateInstance; - -//--------------------------------------------------------------------------------- -// CAIEventReactionAction -//--------------------------------------------------------------------------------- -// this is the base class for action types that can be used to process events for -// teams and other entiites - -class IAILogicAction - : public NLMISC::CRefCount -{ -public: - typedef NLMISC::CSmartPtr TSmartPtr; - - // NOTE: ctor takes following form: - // CLASS(const std::vector &args, const std::vector &subActions) - - // note that actions are NOT responsible for deleting child actions - virtual ~IAILogicAction() - {} - - // this is the execute 'callback' for the action type. - // NOTE: This code should be fast and compact as it may be called very large numbers of times - // depending on the whim of the level designers - // returns true on success, false on failure - virtual bool executeAction (CStateInstance *entity,const IAIEvent *event)=0; - - virtual void addPropertyZone (CTmpPropertyZone::TSmartPtr zone) - {} - - // attach a group family to the action if it supports it (assert otherwise) - virtual void addGroupFamily(CGroupFamily *gf) { nlassert(0); } -}; - -// Code use by native functions and LogicAction -class CAILogicActionDssStartActHelper -{ -public: - static void dssStartAct(TSessionId sessionId, uint32 actId); -}; - -class CAILogicActionSitDownHelper -{ -public: - static void sitDown(CGroup* group); - static void standUp(CGroup* group); -}; - - -class CAILogicDynamicIfHelper -{ -public: - static void setConditionSuccess(bool value) {_ConditionSuccess = value;} - static bool getConditionSuccess() { return _ConditionSuccess;} -private: - static bool _ConditionSuccess; -}; -//--------------------------------------------------------------------------------- -#endif diff --git a/code/ryzom/server/src/ai_service/ai_map.h b/code/ryzom/server/src/ai_service/ai_map.h deleted file mode 100644 index 2d413d4fa..000000000 --- a/code/ryzom/server/src/ai_service/ai_map.h +++ /dev/null @@ -1,43 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -class CAIMap; - -#ifndef RYAI_MAP_H -#define RYAI_MAP_H - -#include "nel/misc/types_nl.h" -#include "ai_route.h" - -/* - This class implements the data set and related methods for a map. - Map data includes collision maps and so on. -*/ - - -class CAIMap -{ -public: - // a method for releasing self cleanly before destruction - void release() {} - - // the name of the map - std::string Name; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_messages.h b/code/ryzom/server/src/ai_service/ai_messages.h deleted file mode 100644 index 1f1c6e26f..000000000 --- a/code/ryzom/server/src/ai_service/ai_messages.h +++ /dev/null @@ -1,177 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_MESSAGES_H -#define RYAI_MESSAGES_H - -#include "nel/misc/types_nl.h" -#include "nel/misc/time_nl.h" -#include "nel/misc/sheet_id.h" -#include "nel/misc/entity_id.h" - -#include "nel/net/transport_class.h" - - -//---------------------------------------------------------------- -// Message sent by AIS to AIDS in reaction to AIDS's service up - -class CMsgAIServiceUp : public NLNET::CTransportClass -{ -public: - CMsgAIServiceUp(float processorAllocation,float ramAllocation) - { - _processorAllocation=processorAllocation; - _ramAllocation=ramAllocation; - } - - virtual void description () - { - className ("CMsgAIServiceUp"); - property ("_processorAllocation", PropFloat, 0.0f, _processorAllocation); - property ("_ramAllocation", PropFloat, 0.0f, _ramAllocation); - } - - virtual void callback (const std::string &name, NLNET::TServiceId id); - -protected: - float _processorAllocation; - float _ramAllocation; -}; - -//---------------------------------------------------------------- -// AIDS -> AIS: Load & start Managers - -class CMsgAIOpenMgrs : public NLNET::CTransportClass -{ -public: - CMsgAIOpenMgrs(uint16 idx,const std::string &name) - { - _idx.push_back(idx); - _name.push_back(name); - } - - void push_back(uint16 idx,constr std::string &name) - { - _idx.push_back(idx); - _name.push_back(name); - } - - virtual void description () - { - className ("CMsgAIOpenMgrs"); - propertyCont ("idx", PropUInt16, _idx); - propertyCont ("name", PropString, _name); - } - - virtual void callback (const std::string &name, NLNET::TServiceId id); - -protected: - std::vector _idx; - std::vector _name; -}; - - -//---------------------------------------------------------------- -// AIDS -> AIS: Reload Managers - -class CMsgAIReloadMgrs : public NLNET::CTransportClass -{ -public: - CMsgAIReloadMgrs(uint16 idx) - { - _idx.push_back(idx); - } - - void push_back(uint16 idx) - { - _idx.push_back(idx); - } - - virtual void description () - { - className ("CMsgAIReloadMgrs"); - propertyCont ("idx", PropUInt16, _idx); - } - - virtual void callback (const std::string &name, NLNET::TServiceId id); - -protected: - std::vector _idx; -}; - - -//---------------------------------------------------------------- -// AIDS -> AIS: Save, stop and unload Managers - -class CMsgAICloseMgrs : public NLNET::CTransportClass -{ -public: - CMsgAICloseMgrs(uint16 idx) - { - _idx.push_back(idx); - } - - void push_back(uint16 idx) - { - _idx.push_back(idx); - } - - virtual void description () - { - className ("CMsgAICloseMgrs"); - propertyCont ("idx", PropUInt16, _idx); - } - - virtual void callback (const std::string &name, NLNET::TServiceId id); - -protected: - std::vector _idx; -}; - - -//---------------------------------------------------------------- -// AIDS -> AIS: Save managers' backups - -class CMsgAIBackupMgrs : public NLNET::CTransportClass -{ -public: - CMsgAIBackupMgrs(uint16 idx) - { - _idx.push_back(idx); - } - - void push_back(uint16 idx) - { - _idx.push_back(idx); - } - - virtual void description () - { - className ("CMsgAIBackupMgrs"); - propertyCont ("idx", PropUInt16, _idx); - } - - virtual void callback (const std::string &name, NLNET::TServiceId id); - -protected: - std::vector _idx; -}; - - -#endif - diff --git a/code/ryzom/server/src/ai_service/ai_mgr.cpp b/code/ryzom/server/src/ai_service/ai_mgr.cpp deleted file mode 100644 index 5b8527af5..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_mgr.h" -#include "ai_mgr_fauna.h" -#include "ai_mgr_npc.h" -#include "ai_mgr_pet.h" -#include "owners.h" - -using namespace MULTI_LINE_FORMATER; - -CManager::CManager(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename) -: CAliasChild(parent, alias, name) -, CAliasTreeRoot(filename) -{ - _CurSpawnRing = 0; -} - -CManager::~CManager() -{ - release(); - _Groups.setChildSize(0); -} - -CManager* CManager::createManager(AITYPES::TMgrType type, IManagerParent* managerParent, uint32 alias, std::string const& name, std::string const& mapName, std::string const& filename) -{ - CManager* manager = NULL; - switch (type) - { - case AITYPES::MgrTypeFauna: manager = new CMgrFauna(managerParent, alias,name, filename); break; - case AITYPES::MgrTypeKami: manager = new CMgrNpc(managerParent, alias, name, filename); break; - case AITYPES::MgrTypeNpc: manager = new CMgrNpc(managerParent, alias, name, filename); break; - case AITYPES::MgrTypeKaravan: manager = new CMgrNpc(managerParent, alias,name, filename); break; - case AITYPES::MgrTypePet: manager = new CMgrPet(managerParent, alias,name, filename); break; - default: - nlwarning("CManager::createManager(): FAILED to instantiate manager due unmanaged type: %s", AITYPES::getName(type)); - break; - } - return manager; -} - -void CManager::update() -{ - if (_SpawnList.size()>0) - { - H_AUTO(MgrUpdateSpawnList) - // deal with the spawn list - // if there are bot groups waiting to be spawned then treat a few of them - for (uint count=0;!_SpawnList.empty() && count<_MaxSpawns;count++) - { - while (_SpawnList.size()>0) - { - _CurSpawnRing++; - if (_CurSpawnRing>=_SpawnList.size()) - _CurSpawnRing=0; - - if (!_SpawnList[_CurSpawnRing]->isSpawned()) - break; - - _SpawnList.erase(_SpawnList.begin()+_CurSpawnRing); // remove the group. - } - - if (_SpawnList.size()>0) - { - if (_SpawnList[_CurSpawnRing]->spawn()) - _SpawnList.erase(_SpawnList.begin()+_CurSpawnRing); // remove the group. - } - } - } - - if (groups().size()==0) - return; - - // we're going to run through the groups updating each one once every n ticks where n is - // determined by the 'getUpdatePriority()' mask - // note that 'getUpdatePriority()' needs to be renamed but it's late, I'm tired and I just need - // an unused variable to work with that already exists so that I don't have to go through a complete - // project recompile. - uint32 timeOffset = CTimeInterface::gameCycle(); - - { - H_AUTO(MgrUpdateSpawned); - int index = -1; - FOREACH(it, CCont, groups()) - { - ++index; - NLMISC::CSmartPtr persistent = *it; // To avoid destruction while executing .. - if (!persistent->isSpawned()) - continue; - - CSpawnGroup* const spawned = persistent->getSpawnObj(); - if (spawned->getUpdatePriority()==1) - ++AISStat::GrpFastUpdCtr; - if (spawned->getUpdatePriority()==31) - ++AISStat::GrpSlowUpdCtr; - if (((index+timeOffset)&spawned->getUpdatePriority())!=0) - continue; - - spawned->update(); - } - } -} - -CGroup* CManager::getNextValidGroupChild(CGroup* group) -{ - return _Groups.getNextValidChild(static_cast(group)); -} - -void CManager::serviceEvent(CServiceEvent const& info) -{ - FOREACH(it, CCont, groups()) - it->serviceEvent(info); -} - -void CManager::spawn() -{ - FOREACH(it, CCont, groups()) - _SpawnList.push_back(*it); - _MaxSpawns = (groups().size()+127)/(127+1); // the 127 and 128 are arbitrary ( D M ). -} - -void CManager::despawnMgr() -{ - FOREACH(it, CCont, groups()) - it->despawnGrp(); -} - -CGroup* CManager::getGroup(uint32 index) -{ - if (index>=groups().size()) - return NULL; - return groups()[index]; -} - -bool CManager::isEmpty() const -{ - for(uint k = 0; k < _Groups.size(); ++k) - { - if (_Groups[k] && _Groups[k]->getNextValidBotChild() != NULL) return false; - } - return true; -} - -std::string CManager::getIndexString() const -{ - return getOwner()->getManagerIndexString(this); -} - -std::string CManager::getOneLineInfoString() const -{ - return std::string("Manager '") + getName() + "'"; -} - -std::string CManager::getFullName() const -{ - return getName(); -} - -std::vector CManager::getMultiLineInfoString() const -{ - std::vector container; - - - pushTitle(container, "CManager"); - pushEntry(container, "id=" + getIndexString()); - container.back() += " type=" + std::string(AITYPES::getName(type())); - container.back() += " alias=" + getAliasString(); - container.back() += " name=" + getName(); - pushFooter(container); - - - return container; -} - -void CManager::release() -{ -} - -void CManager::addToSpawn(CGroup* group) -{ - for (size_t i=0; i<_SpawnList.size(); ++i) - { - if (_SpawnList[i].ptr()==group) - return; - } - _SpawnList.push_back(group); -} - -void CManager::removeFromSpawnList(CGroup const* group) -{ - for (size_t i=0; i<_SpawnList.size(); ++i) - { - if (_SpawnList[i]==group) - { - _SpawnList.erase(_SpawnList.begin()+i); // remove the group. - return; - } - } -} - -CAIInstance* CManager::getAIInstance() const -{ - return getOwner()->getAIInstance(); -} diff --git a/code/ryzom/server/src/ai_service/ai_mgr.h b/code/ryzom/server/src/ai_service/ai_mgr.h deleted file mode 100644 index 8dbcb2f11..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr.h +++ /dev/null @@ -1,112 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_AI_MGR_H -#define RYAI_AI_MGR_H - -#include "ai_entity.h" -#include "alias_tree_root.h" -#include "manager_parent.h" -#include "service_dependencies.h" - -extern NLLIGO::CLigoConfig LigoConfig; -class CSpawnGroup; -class CStateMachine; - -////////////////////////////////////////////////////////////////////////////// -// CManager // -////////////////////////////////////////////////////////////////////////////// - -class CManager -: public CAliasChild -, public NLMISC::CRefCount -, public CAliasTreeRoot -, public CServiceEvent::CHandler -, public CAIEntity -{ -public: - CManager(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename); - virtual ~CManager(); - - /// @name CChild implementation - //@{ - virtual std::string getIndexString() const; - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - virtual std::string getFullName() const; -// virtual std::string getName() const; - //@} - - /// @name CServiceEvent::CHandler implementation - //@{ - virtual void serviceEvent(CServiceEvent const& info); - //@} - - /// @name CAIEntity public implementation - //@{ - virtual CAIInstance* getAIInstance() const; - //@} - -public: - /// @name Virtual interface - //@{ - virtual void release(); - virtual void update(); - virtual AITYPES::TMgrType type() const = 0; - virtual void init() = 0; - virtual CStateMachine* getStateMachine() = 0; - virtual void spawn(); - virtual void despawnMgr(); - //@} - - /// @name Accessors - //@{ - CAliasCont& groups() { return _Groups; } - CAliasCont const& groups() const { return _Groups; } - CGroup* getGroup(uint32 index); - - bool isEmpty() const; - - CAliasTreeOwner* getAliasTreeOwner() { return this; } - - uint32 getAlias() const { return CAliasTreeOwner::getAlias(); } - std::string getMap() const { return _map; } - NLMISC::CEntityId getEntityId() { return _EntityId; } - //@} - - CGroup* getNextValidGroupChild(CGroup* group = NULL); - - void addToSpawn(CGroup* group); - void removeFromSpawnList(CGroup const* group); - - static CManager* createManager(AITYPES::TMgrType type, IManagerParent* managerParent, uint32 alias, std::string const& name, std::string const& mapName, std::string const& filename); - -protected: - /// @name AI service hierarchy - //@{ - CAliasCont _Groups; - //@} - - std::string _map; - -private: - NLMISC::CEntityId _EntityId; - uint32 _MaxSpawns; - std::vector > _SpawnList; - uint32 _CurSpawnRing; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp b/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp deleted file mode 100644 index b178cccff..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_fauna.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_mgr_fauna.h" -#include "ai_grp_fauna.h" -#include "timer.h" -#include "states.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -// Stuff used for management of log messages -static bool VerboseLog=false; -#define LOG if (!VerboseLog) {} else nlinfo - -////////////////////////////////////////////////////////////////////////////// -// Local globals // -////////////////////////////////////////////////////////////////////////////// - -static CAITimer VerboseMgrFaunaUpdateTimer; // for activating verbose debug info for short periods -static uint32 PlayersPerRegion = 0; // dummy variable for setting fake number of players per region - - -////////////////////////////////////////////////////////////////////////////// -// CMgrFauna // -////////////////////////////////////////////////////////////////////////////// - -CMgrFauna::CMgrFauna(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename) -: CManager(parent, alias, name, filename) -{ - registerEvents(); -} - -CMgrFauna::~CMgrFauna() -{ - _StateMachine.clearEventContainerContent(); - _Groups.clear(); -} - -void CMgrFauna::registerEvents() -{ - _StateMachine.registerEvents (); - - _StateMachine.addEvent( "destination_reached", EventDestinationReachedFirst ); - _StateMachine.addEvent( "destination_reached_first", EventDestinationReachedFirst ); - _StateMachine.addEvent( "destination_reached_all", EventDestinationReachedAll ); - _StateMachine.addEvent( "bot_killed", EventBotKilled ); - _StateMachine.addEvent( "group_eliminated", EventGrpEliminated ); -} - -void CMgrFauna::init() -{ - VerboseMgrFaunaUpdateTimer.set(0); -} - -void CMgrFauna::update() -{ - H_AUTO(MgrFaunaUpdate); - - ++AISStat::MgrTotalUpdCtr; - ++AISStat::MgrFaunaUpdCtr; - - CManager::update(); // general update call .. -} - -IAliasCont* CMgrFauna::getAliasCont(TAIType type) -{ - switch(type) - { - case AITypeGrp: - return &_Groups; - case AITypeEvent: - return &getStateMachine()->eventReactions(); - case AITypeState: - return &getStateMachine()->states(); - default: - return NULL; - } -} - -CAliasTreeOwner* CMgrFauna::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - CAliasTreeOwner* child = NULL; - - switch (aliasTree->getType()) - { - case AITypeGrp: - child = new CGrpFauna(this, aliasTree, WaterAndNogo); - break; - case AITypeEvent: - child = new CAIEventReaction(getStateMachine(), aliasTree); - break; - case AITypeState: - child = new CAIStatePositional(getStateMachine(), aliasTree); - break; - } - - cont->addAliasChild(child); - return child; -} - -std::string CMgrFauna::buildDebugString(uint idx) -{ - switch (idx) - { - case 0: - return CManager::getIndexString() + " " + getFullName() + NLMISC::toString(": %-25s ",getName().c_str()); - default: - break; - } - return std::string(); -} - -void CMgrFauna::display(CStringWriter& stringWriter) -{ - stringWriter.append(getFullName()); -} - -std::string CMgrFauna::getOneLineInfoString() const -{ - return std::string("Fauna manager '") + getName() + "'"; -} - -//---------------------------------------------------------------------------- -// Admin commands and variables -NLMISC_DYNVARIABLE(uint32, VerboseMgrUpdate, "Dump update priority heaps and lists of groups updated for next ticks") -{ - if (get) - *pointer = VerboseMgrFaunaUpdateTimer.timeRemaining(); - else - VerboseMgrFaunaUpdateTimer.set(*pointer); -} - -NLMISC_DYNVARIABLE(uint32, SimPlayersPerRegion, "Dump update priority heaps and lists of groups updated for next ticks") -{ - if (get) - *pointer = PlayersPerRegion; - else - PlayersPerRegion = *pointer; -} - -//---------------------------------------------------------------------------- -// Control over verbose nature of logging -NLMISC_COMMAND(verboseFaunaMgrLog,"Turn on or off or check the state of verbose manager activity logging","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (VerboseLog, args[0]); - - nlinfo("verboseLogging is %s",VerboseLog?"ON":"OFF"); - return true; -} diff --git a/code/ryzom/server/src/ai_service/ai_mgr_fauna.h b/code/ryzom/server/src/ai_service/ai_mgr_fauna.h deleted file mode 100644 index 70c30c3f0..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_fauna.h +++ /dev/null @@ -1,87 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_MGR_FAUNA_H -#define RYAI_MGR_FAUNA_H - -#include "ai_mgr.h" -#include "ai_place.h" -#include "event_manager.h" -#include "event_reaction_container.h" - -class CFauna; - -////////////////////////////////////////////////////////////////////////////// -// CMgrFauna // -////////////////////////////////////////////////////////////////////////////// - -/// This is the manager class for fauna (and fauna groups) -class CMgrFauna -: public CManager -{ -public: - CMgrFauna(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename); - virtual ~CMgrFauna(); - - CStateMachine* getStateMachine() { return &_StateMachine; } - - virtual std::string getOneLineInfoString() const; - - ////////////////////////////////////////////////////////////////////////// - // CStateMachine - - uint32 getAlias() const { return CManager::getAlias(); } - - CAIAliasDescriptionNode* getAliasNode() const { return CManager::getAliasNode(); } - - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Methods inherited from IManager. - void init(); - void update(); - void release() { CManager::release(); } - - AITYPES::TMgrType type() const { return AITYPES::MgrTypeFauna; } - // event managers -------------------------------------------------- - CAIEvent EventDestinationReachedFirst; - CAIEvent EventDestinationReachedAll; - CAIEvent EventBotKilled; - CAIEvent EventGrpEliminated; - - CStateMachine _StateMachine; - - void registerEvents(); - - ////////////////////////////////////////////////////////////////////////// - // Alias Tree related Methods. - - IAliasCont* getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree); - - /// @name CAIEntity public implementation - //@{ - virtual void display(CStringWriter& stringWriter); - //@} - -protected: - /// @name CAIEntity protected implementation - //@{ - virtual std::string buildDebugString(uint idx); - //@} -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_mgr_npc.cpp b/code/ryzom/server/src/ai_service/ai_mgr_npc.cpp deleted file mode 100644 index 5d2f381c0..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_npc.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_mgr_npc.h" -#include "ai_grp_npc.h" -#include "states.h" -#include "game_share/base_types.h" -#include "npc_description_msg.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -// Stuff used for management of log messages -static bool VerboseLog=false; -#define LOG if (!VerboseLog) {} else nlinfo - -////////////////////////////////////////////////////////////////////////////// -// CMgrNpc // -////////////////////////////////////////////////////////////////////////////// - -// instantiate the bot population -void CMgrNpc::spawn() -{ - nlinfo("--------------- spawn Npc manager: %s ----------------", getName().c_str() ); - CManager::spawn(); - - // inform the EGS of our existence - simulate connection of EGS - if (EGSHasMirrorReady) - serviceEvent(CServiceEvent(TServiceId(0), std::string("EGS"), CServiceEvent::SERVICE_UP)); -} - -// clear the bot population -void CMgrNpc::despawnMgr() -{ - nlinfo("-------------- despawn manager: %s --------------- ", getName().c_str()); - CManager::despawnMgr(); -} - -IAliasCont* CMgrNpc::getAliasCont(TAIType type) -{ - switch (type) - { - case AITypeNoGo: // not implemented. - return NULL; - case AITypeGrp: - return &_Groups; - case AITypeNpcStateRoute: - case AITypeNpcStateZone: - case AITypePunctualState: - case AITypeKamiDeposit: - case AITypeKaravanState: - case AITypeState: - return &getStateMachine()->states(); - case AITypeEvent: - return &getStateMachine()->eventReactions(); - case AITypeFolder: - default: - return NULL; - } -} - -CAliasTreeOwner* CMgrNpc::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - CAliasTreeOwner* child = NULL; - - switch (aliasTree->getType()) - { - case AITypeGrp: - child = new CGroupNpc(this, aliasTree, Nothing); - break; - case AITypeNpcStateRoute: - case AITypeNpcStateZone: - case AITypeKamiDeposit: - case AITypeKaravanState: - case AITypeState: - child = new CAIStatePositional(getStateMachine(), aliasTree); - break; - case AITypePunctualState: - child = new CAIStatePunctual(getStateMachine(), aliasTree); - break; - case AITypeEvent: - child = new CAIEventReaction(getStateMachine(), aliasTree); - break; - case AITypeNoGo: - case AITypeFolder: - break; - } - if (child) - cont->addAliasChild(child); - return child; -} - -std::string CMgrNpc::getOneLineInfoString() const -{ - return std::string("NPC manager '") + getName() + "'"; -} - -CMgrNpc::CMgrNpc(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename) -: CManager(parent, alias, name, filename) -{ - registerEvents(); -} - -CMgrNpc::~CMgrNpc() -{ - _StateMachine.clearEventContainerContent(); - _Groups.clear(); -} - -void CMgrNpc::update() -{ - ++AISStat::MgrTotalUpdCtr; - ++AISStat::MgrNpcUpdCtr; - CManager::update(); -} - -void CMgrNpc::registerEvents() -{ - _StateMachine.registerEvents(); - - _StateMachine.addEvent( "destination_reached", EventDestinationReachedFirst ); - _StateMachine.addEvent( "destination_reached_first", EventDestinationReachedFirst ); - _StateMachine.addEvent( "destination_reached_all", EventDestinationReachedAll ); - _StateMachine.addEvent( "bot_killed", EventBotKilled ); - _StateMachine.addEvent( "squad_leader_killed", EventSquadLeaderKilled ); - _StateMachine.addEvent( "group_eliminated", EventGrpEliminated ); -} - -std::vector CMgrNpc::getMultiLineInfoString() const -{ - using namespace MULTI_LINE_FORMATER; - std::vector container; - std::vector strings; - - - pushTitle(container, "CMgrNpc"); - strings = CManager::getMultiLineInfoString(); - FOREACHC(itString, std::vector, strings) - pushEntry(container, *itString); -// pushEntry(container, "state machine:"); - strings = _StateMachine.getMultiLineInfoString(); - FOREACHC(itString, std::vector, strings) - pushEntry(container, *itString); - pushFooter(container); - - - return container; -} - -// :KLUDGE: This method should be in event_reaction_container.cpp that doesn't exist -std::vector CStateMachine::getMultiLineInfoString() const -{ - using namespace MULTI_LINE_FORMATER; - std::vector container; - - - pushTitle(container, "CStateMachine"); - pushEntry(container, "States:"); - FOREACHC(itState, CCont, _states) - pushEntry(container, " - "+itState->getName()); - pushFooter(container); - - - return container; -} diff --git a/code/ryzom/server/src/ai_service/ai_mgr_npc.h b/code/ryzom/server/src/ai_service/ai_mgr_npc.h deleted file mode 100644 index 9d01d6206..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_npc.h +++ /dev/null @@ -1,82 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_MGR_NPC_H -#define RYAI_MGR_NPC_H - -#include "ai_mgr.h" -#include "event_manager.h" -#include "states.h" -#include "ai_variables.h" -#include "event_reaction_container.h" - -////////////////////////////////////////////////////////////////////////////// -// CMgrNpc // -////////////////////////////////////////////////////////////////////////////// - -/// This is the manager class for npc (and npc groups) -class CMgrNpc -: public CManager -{ -public: - CMgrNpc(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename); - virtual ~CMgrNpc(); - - void update(); - - CStateMachine* getStateMachine() { return &_StateMachine; } - - uint32 getAlias() const { return CManager::getAlias(); } - CAIAliasDescriptionNode* getAliasNode() const { return CManager::getAliasNode(); } - - virtual std::string getOneLineInfoString() const; - virtual std::vector getMultiLineInfoString() const; - - ////////////////////////////////////////////////////////////////////////// - - // Methods inherited from IManager. - void init() { } - void release() { } - - void serviceDown(uint32 sid, std::string const& name) { } - - AITYPES::TMgrType type() const { return AITYPES::MgrTypeNpc; } - - // instantiate the bot population - virtual void spawn(); - // clear the bot population - virtual void despawnMgr(); - - // event managers -------------------------------------------------- - CAIEvent EventDestinationReachedFirst; - CAIEvent EventDestinationReachedAll; - CAIEvent EventBotKilled; - CAIEvent EventSquadLeaderKilled; - CAIEvent EventGrpEliminated; - - virtual void registerEvents(); - - ////////////////////////////////////////////////////////////////////////// - // Alias Tree related Methods. - - IAliasCont* getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree); - - ////////////////////////////////////////////////////////////////////////// - CStateMachine _StateMachine; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_mgr_pet.cpp b/code/ryzom/server/src/ai_service/ai_mgr_pet.cpp deleted file mode 100644 index 0fe7019a3..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_pet.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_mgr_pet.h" -#include "time_interface.h" -#include "ai_grp_pet.h" -#include "ai_player.h" -#include "ai_mgr_npc.h" -#include "ai_bot_npc.h" -#include "server_share/animal_hunger.h" -#include "ai_profile_pet.h" - -using namespace NLMISC; -using namespace NLNET; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -/****************************************************************************/ -/* Methods definitions */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CMgrPet // -////////////////////////////////////////////////////////////////////////////// - -void CMgrPet::serviceEvent(CServiceEvent const& info) -{ - if (info.getServiceName()=="EGS" && info.getEventType()==CServiceEvent::SERVICE_DOWN) - { - despawnMgr(); // despawn all groups. - groups().setChildSize(0); // remove all groups. - _EntityIdToIndex.clear(); - } -} - -void CMgrPet::update() -{ - // call the update methods for all of the groups in the manager - uint32 const timeOffset = CTimeInterface::gameCycle(); - - FOREACH(it, CCont, groups()) - { - CGrpPet* const grpPet = NLMISC::safe_cast(*it); - - if (grpPet->isSpawned() && ((grpPet->getChildIndex()+timeOffset)&3)==1) - grpPet->getSpawnObj()->update(); - - if (grpPet->bots().isEmpty()) - grpPet->getPetManager().removePetGroup(grpPet->getPetOwner()); - } -} - -void CMgrPet::createPetGroup(CEntityId const& petOwnerId) -{ - nlassert(_EntityIdToIndex.find(petOwnerId)==_EntityIdToIndex.end()); - - CSmartPtr const petGroup = new CGrpPet(this, petOwnerId); - groups().addChild(petGroup); - _EntityIdToIndex.insert(std::make_pair(petOwnerId,petGroup->getChildIndex())); -} - -CGrpPet* CMgrPet::getPetGroup(CEntityId const& petOwnerId) -{ - CGrpPet* grp = NULL; - TEntityIdMapUint32::iterator const it = _EntityIdToIndex.find(petOwnerId); - - if (it!=_EntityIdToIndex.end()) - { - grp = NLMISC::type_cast(groups()[it->second]); - if (!grp) - _EntityIdToIndex.erase(it); - } - return grp; -} - -void CMgrPet::removePetGroup(NLMISC::CEntityId const& petOwnerId) -{ - TEntityIdMapUint32::iterator const it = _EntityIdToIndex.find(petOwnerId); - if (it==_EntityIdToIndex.end()) - return; - - groups().removeChildByIndex(it->second); - _EntityIdToIndex.erase(it); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotPet // -////////////////////////////////////////////////////////////////////////////// - -void CBotPet::changeOwner(NLMISC::CEntityId const& newOwner) -{ - if (newOwner==CEntityId::Unknown) - return; - - CMgrPet* const petMgr = getAIInstance()->getPetMgr(); - - CGrpPet* grp = petMgr->getPetGroup(newOwner); - - if (!grp) - { - petMgr->createPetGroup(newOwner); - grp = petMgr->getPetGroup(newOwner); - if (!grp) - return; - } - if (!grp->isSpawned()) - { - grp->spawn(); - if (!grp->isSpawned()) - return; - } - - // To Update. It s Ugly and the correct way to do that may be: - // a method call on the new player bot container giving the child and the new player as params. - // it reflects that to have a full autonomous architecture, with should have a container / owner relationship. - // This allow us more easy code to write but leads in more dependency or type casting as container should be template - // of owner or owner should derive of a base type (right way). - { - CGrpPet* const lastOwner = static_cast(getOwner()); - uint32 const lastIndex = getChildIndex(); - setOwner(grp); - if (isSpawned()) - getSpawnObj()->setSpawnGroup(grp->getSpawnObj()); - grp->bots().addChild(this); - lastOwner->bots().removeChildByIndex(lastIndex); - - // REmove Group if no more used .. - if (lastOwner->bots().size()==0) - lastOwner->getPetManager().removePetGroup(lastOwner->getPetOwner()); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CPetOwner // -////////////////////////////////////////////////////////////////////////////// - -CPetOwner::~CPetOwner() -{ - if (_petGroup.isNull()) - return; - - NLMISC::safe_cast(_petGroup->getOwner())->groups().removeChildByIndex(_petGroup->getChildIndex()); -} - -////////////////////////////////////////////////////////////////////////////// -// CPetSpawnMsgImp // -////////////////////////////////////////////////////////////////////////////// - -void CPetSpawnMsgImp::callback(std::string const& name, NLNET::TServiceId id) -{ - CAIInstance* aiInstance = NULL; - CPetSpawnConfirmationMsg confirmMsg; - - confirmMsg.CharacterMirrorRow = CharacterMirrorRow; - confirmMsg.PetIdx = PetIdx; - - switch(SpawnMode) - { - case NEAR_PLAYER: - case NEAR_POINT: - { - CAIInstance* const aiInstance = CAIS::instance().getAIInstance(AIInstanceId); // gets the AIInstance. - CEntityId const petOwnerId = CMirrors::getEntityId(CharacterMirrorRow); - - if (petOwnerId.isUnknownId() || !aiInstance) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::CHARATER_UNKNOWN; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlwarning("Unknow player"); -#endif - return; - } - - CGrpPet* petGrp = aiInstance->getPetMgr()->getPetGroup(petOwnerId); - if (!petGrp) - { - aiInstance->getPetMgr()->createPetGroup(petOwnerId); - petGrp = aiInstance->getPetMgr()->getPetGroup(petOwnerId); - } - - if (!petGrp) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlerror("Group must exist, perhaps Pet manager is not initialised or the player id is wrong."); -#else - nlwarning("Group must exist, perhaps Pet manager is not initialised or the player id is wrong."); -#endif - return; - } - - CBotPet* botPet = NULL; - if (PetIdxbots().size()) - botPet = static_cast(petGrp->bots()[PetIdx]); - - if (botPet && botPet->isSpawned()) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::PET_ALREADY_SPAWNED; - confirmMsg.send("EGS"); - return; - } - - if (!petGrp->isSpawned()) - petGrp->spawn(); - botPet = safe_cast(petGrp->bots().addChild(new CBotPet(petGrp),PetIdx)); - if (!botPet) // creation failed. - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; // the creation failed coz of an internal error. - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlerror("Pet cannot be created, perhaps memory problems."); -#else - nlwarning("Pet cannot be created, perhaps memory problems."); -#endif - return; - } - - // calc a valid spawn position. - { - CAIPos position; - CAIEntityPhysical const* const phys = CAIS::instance().getEntityPhysical(CMirrors::DataSet->getDataSetRow(petOwnerId)); - - // TSpawnMode - switch (SpawnMode) - { - case NEAR_PLAYER: - { - if (phys) - { - position = phys->pos(); - CAngle angle = phys->theta (); - double dist = 2 + (double)(botPet->getChildIndex()&3); - position.setX(position.x() - CAICoord(dist*angle.asVector2d().x)); - position.setY(position.y() - CAICoord(dist*angle.asVector2d().y)); - break; - } - else - { - nlwarning("Trying to spawn a pet near a player %s that is not in this aiinstance. try to use Coordinates instead (NEAR_POINT).", petOwnerId.toString().c_str()); - } - } - case NEAR_POINT: - position = CAIPos(Coordinate_X*0.001f, Coordinate_Y*0.001f, (sint32)(Coordinate_H*0.001f), Heading); - break; - } - - CWorldPosition spawnPos; - if (!CWorldContainer::calcNearestWPosFromPosAnRadius(position.h(), spawnPos, position, 16, 300, CWorldContainer::CPosValidatorDefault())) - { - // try with an auto vertical pos - if (!CWorldContainer::calcNearestWPosFromPosAnRadius(vp_auto, spawnPos, position, 16, 300, CWorldContainer::CPosValidatorDefault())) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlstopex(("Pet cannot be created, positionnal problem at %s", position.toString().c_str()) ); -#else - nlwarning("Pet cannot be created, positional problem at %s", position.toString().c_str() ); -#endif - return; - } - } - position = CAIPos(spawnPos.toAIVector(), spawnPos.getMetricHeight(), position.theta()); - botPet->setSpawnPos(position); - } - - AISHEETS::ICreatureCPtr const sheet = AISHEETS::CSheets::getInstance()->lookup(PetSheetId); - - if (!sheet) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; - confirmMsg.send("EGS"); - return; - } - - botPet->setSheet(sheet); - - if (!CustomName.empty()) - { - botPet->setCustomName(CustomName); - } - - if (!botPet->spawn()) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlassert("Pet cannot be created, perhaps memory or positional problems."); -#else - nlwarning("Pet cannot be created, perhaps memory or positional problems."); -#endif - return; - } - - if (!botPet->getSpawn()) - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; // the creation failed coz of an internal error. - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlerror("Pet cannot be created, perhaps memory problems."); -#else - nlwarning("Pet cannot be created, perhaps memory problems."); -#endif - return; - } - - botPet->getSpawn()->setAIProfile(new CAIPetProfileStand(botPet->getSpawn())); - - confirmMsg.PetMirrorRow = botPet->getSpawn()->dataSetRow(); - - if (!confirmMsg.PetMirrorRow.isValid()) // creation failed. - { - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlerror("Pet cannot be created, perhaps memory problems."); -#else - nlwarning("Pet cannot be created, perhaps memory problems."); -#endif - return; - } - - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::NO_ERROR_SPAWN; - confirmMsg.send("EGS"); - } - break; - default: - // not implemented .. - confirmMsg.SpawnError = CPetSpawnConfirmationMsg::NOT_IMPLEMENTED; - confirmMsg.send("EGS"); -#ifdef NL_DEBUG - nlerror("Unimplemented Message"); -#else - nlwarning("Unimplemented Message"); -#endif - return; - } -} - -////////////////////////////////////////////////////////////////////////////// -// CPetSetOwnerImp // -////////////////////////////////////////////////////////////////////////////// - -void CPetSetOwnerImp::callback(std::string const& name, NLNET::TServiceId id) -{ - CEntityId const& petOwner = CMirrors::getEntityId(OwnerMirrorRow); - - CSpawnBotPet* const petSpawnPtr = NLMISC::type_cast(CAIS::instance().getEntityPhysical(PetMirrorRow)); - if (!petSpawnPtr) - return; - - petSpawnPtr->getPersistent().changeOwner(petOwner); -} - -////////////////////////////////////////////////////////////////////////////// -// CPetCommandMsgImp // -////////////////////////////////////////////////////////////////////////////// - -void CPetCommandMsgImp::callback(std::string const& name, NLNET::TServiceId id) -{ - CAIEntityPhysical* petEntPtr = CAIS::instance().getEntityPhysical(PetMirrorRow); - if (!petEntPtr) - return; - - CSpawnBotPet* petSpawnPtr = NLMISC::type_cast(petEntPtr); - if (!petSpawnPtr) - return; - - CAIPos const position(Coordinate_X*0.001f, Coordinate_Y*0.001f, Coordinate_H, 0); - - switch (Command) - { - case STAND: - petSpawnPtr->setAIProfile(new CAIPetProfileStand(petSpawnPtr)); - break; - - case FOLLOW: - petSpawnPtr->setAIProfile(new CAIPetProfileFollowPlayer(petSpawnPtr, CharacterMirrorRow)); - break; - - case GOTO_POINT: - { - CAIPetProfileGotoPoint* const profile = new CAIPetProfileGotoPoint(petSpawnPtr, position, petSpawnPtr->getAStarFlag()); - - if (profile->isValid()) - petSpawnPtr->setAIProfile(profile); - else - CPetCommandConfirmationMsg(CPetCommandConfirmationMsg::POSITION_COLLISION_NOT_VALID, *this).send("EGS"); - } - break; - - case GOTO_POINT_DESPAWN: - { - CAIPetProfileGotoPoint* const profile = new CAIPetProfileGotoPoint(petSpawnPtr, position, petSpawnPtr->getAStarFlag(), true); - - if (profile->isValid()) - petSpawnPtr->setAIProfile(profile); - else - CPetCommandConfirmationMsg(CPetCommandConfirmationMsg::POSITION_COLLISION_NOT_VALID,*this).send("EGS"); - } - break; - - case LIBERATE: // not really implemented for now .. - petSpawnPtr->getPersistent().setDespawn(); - break; - - case DESPAWN: - petSpawnPtr->getPersistent().setDespawn(); - break; - default: - break; - } -}; diff --git a/code/ryzom/server/src/ai_service/ai_mgr_pet.h b/code/ryzom/server/src/ai_service/ai_mgr_pet.h deleted file mode 100644 index a6432a8ee..000000000 --- a/code/ryzom/server/src/ai_service/ai_mgr_pet.h +++ /dev/null @@ -1,106 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_MGR_PET_H -#define RYAI_MGR_PET_H - -#include "ai_mgr.h" -#include "ai_bot_pet.h" -#include "server_share/pet_interface_msg.h" - -class CPetOwner; - -typedef std::map TEntityIdMapUint32; - -////////////////////////////////////////////////////////////////////////////// -// CMgrPet // -////////////////////////////////////////////////////////////////////////////// - -/// This is the manager class for pets, pack animals and steeds -class CMgrPet -: public CManager -{ -public: - CMgrPet(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename) ; - - void init() { } - void update(); - void release() { } - - virtual void spawn() { CManager::spawn(); } - void despawnMgr() { CManager::despawnMgr(); } - - CStateMachine* getStateMachine() { return NULL; } - - void createPetGroup(NLMISC::CEntityId const& petOwnerId); - CGrpPet* getPetGroup(NLMISC::CEntityId const& petOwnerId); - void removePetGroup(NLMISC::CEntityId const& petOwnerId); - - AITYPES::TMgrType type() const { return AITYPES::MgrTypePet; } - - void serviceEvent(CServiceEvent const& info); - - virtual std::string getOneLineInfoString() const { return std::string("Pet manager '") + getName() + "'"; } - -private: - TEntityIdMapUint32 _EntityIdToIndex; -}; - -////////////////////////////////////////////////////////////////////////////// -// CPetSpawnMsgImp // -////////////////////////////////////////////////////////////////////////////// - -class CPetSpawnMsgImp -: public CPetSpawnMsg -{ - virtual void callback(std::string const& name, NLNET::TServiceId id); -}; - -////////////////////////////////////////////////////////////////////////////// -// CPetSetOwnerImp // -////////////////////////////////////////////////////////////////////////////// - -class CPetSetOwnerImp -: public CPetSetOwner -{ - virtual void callback(std::string const& name, NLNET::TServiceId id); -}; - -////////////////////////////////////////////////////////////////////////////// -// CPetCommandMsgImp // -////////////////////////////////////////////////////////////////////////////// - -class CPetCommandMsgImp -: public CPetCommandMsg -{ - virtual void callback(std::string const& name, NLNET::TServiceId id); -}; - -/****************************************************************************/ -/* Inlined methods */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CMgrPet // -////////////////////////////////////////////////////////////////////////////// - -inline -CMgrPet::CMgrPet(IManagerParent* parent, uint32 alias, std::string const& name, std::string const& filename) -: CManager(parent, alias, name, filename) -{ -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_outpost.cpp b/code/ryzom/server/src/ai_service/ai_outpost.cpp deleted file mode 100644 index bdbfd537b..000000000 --- a/code/ryzom/server/src/ai_service/ai_outpost.cpp +++ /dev/null @@ -1,1514 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_outpost.h" -#include "continent.h" -#include "ai_grp_npc.h" -#include "game_share/people.h" -#include "ai_profile_npc.h" - -#include "continent_inline.h" -#include "dyn_grp_inline.h" - -using namespace std; -using namespace NLMISC; -using namespace AITYPES; - - - -CFileDisplayer OutpostDisplayer("outposts.log"); -CLog OutpostDbgLog(CLog::LOG_DEBUG), OutpostInfLog(CLog::LOG_INFO), OutpostWrnLog(CLog::LOG_WARNING), OutpostErrLog(CLog::LOG_ERROR); - - -namespace OUTPOSTHELPERS { - -static std::map outpostFactions; - -bool isAttackingFaction(uint32 factionIndex, CAIEntityPhysical const* player) -{ - std::map::const_iterator it = outpostFactions.find(player->outpostAlias()); - return it!=outpostFactions.end() && it->second==factionIndex; -} - -} - -////////////////////////////////////////////////////////////////////////////// -// COutpost // -////////////////////////////////////////////////////////////////////////////// - -//std::set ChangedOutposts; -//COutpost::TOutpostIndex COutpost::_Outposts; - -COutpost::COutpost(CContinent* owner, uint32 alias, std::string const& name, std::string const& filename) -: CAliasChild(owner, alias, name) -, CAliasTreeRoot(filename) -, _OwnerAllianceId(InvalidAllianceId) -, _AttackerAllianceId(InvalidAllianceId) -, _State(OUTPOSTENUMS::UnknownOutpostState) - -{ - static bool logInitDone = false; - if ( ! logInitDone ) - { - OutpostDbgLog.addDisplayer( &OutpostDisplayer ); - OutpostInfLog.addDisplayer( &OutpostDisplayer ); - OutpostWrnLog.addDisplayer( &OutpostDisplayer ); - logInitDone = true; - } - - OUTPOST_DBG("Creating outpost %s' (%s)", name.c_str(), getAliasFullName().c_str()); - if (LogOutpostDebug) - OUTPOST_DBG("Creating outpost '%s'", getAliasFullName().c_str()); - - _OutpostName = getName(); - COutpostManager* manager = NULL; - // Create default squad manager - manager = new COutpostSquadManager(this, 0, "default_squad_manager", filename); - if (manager) - { - _Managers.addChild(manager); - manager->init(); - } - // Create default building manager - manager = new COutpostManager(this, 0, "default_building_manager", filename); - if (manager) - { - _Managers.addChild(manager); - manager->init(); - CGroupNpc* group = new CGroupNpc(manager, NULL, /*AStarFlag*/RYAI_MAP_CRUNCH::Nothing); - if (group) - { - manager->groups().addAliasChild(group); - group->setAutoSpawn(false); - group->setName("default_building_group"); - group->clearParameters(); - group->setPlayerAttackable(false); - group->setBotAttackable(false); - group->setBotsAreNamedFlag(); - } - } -} - -COutpost::~COutpost() -{ - if (LogOutpostDebug) - OUTPOST_DBG("Deleting outpost '%s'", getAliasFullName().c_str()); - - _SpawnZones.clear(); -} - -std::string COutpost::getOneLineInfoString() const -{ - return std::string("Outpost '") + getName() + "' " + getAliasString() + ", State=" + OUTPOSTENUMS::toString(_State); -} - -std::string COutpost::getFullName() const -{ - return std::string(getOwner()->getFullName() +":"+ getName()); -} - -std::string COutpost::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":o%u", getChildIndex()); -} -/* -std::string COutpost::getPlaceOwnerFullName() const -{ - return getFullName(); -} - -std::string COutpost::getPlaceOwnerIndexString() const -{ - return getIndexString(); -} -*/ -CAIInstance* COutpost::getAIInstance() const -{ - return getOwner()->getAIInstance(); -} - -std::string COutpost::getManagerIndexString(CManager const* manager) const -{ - return getIndexString()+NLMISC::toString(":m%u", manager->getChildIndex()); -} - -IAliasCont* COutpost::getAliasCont(TAIType type) -{ - switch (type) - { - case AITypeOutpostSquadFamily: - OUTPOST_WRN( "Obsolete squad family node under outpost %s", getName().c_str() ); - return NULL; - case AITypeOutpostSpawnZone: - return &_SpawnZones; - case AITypeManager: - return &_Managers; - case AITypeOutpostManager: - return &_Managers; - case AITypeOutpostBuilding: - return getBuildingGroup()->getAliasCont(AITypeBot); - default: - return NULL; - } - -} - -CAliasTreeOwner* COutpost::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - if (!cont) - return NULL; - - CAliasTreeOwner* child = NULL; - - switch(aliasTree->getType()) - { - // create the child and adds it to the corresponding position. - case AITypeOutpostSpawnZone: - child = new COutpostSpawnZone(this, aliasTree); - break; - case AITypeManager: - child = new COutpostSquadManager(this, aliasTree->getAlias(), aliasTree->getName()); - break; - case AITypeOutpostManager: - child = new COutpostSquadManager(this, aliasTree->getAlias(), aliasTree->getName()); - break; - case AITypeOutpostBuilding: - return getBuildingGroup()->createChild(cont, aliasTree); - } - - if (child) - cont->addAliasChild(child); - return child; -} - -CGroup* COutpost::getBuildingGroup() -{ - COutpostManager* manager = _Managers.getChildByName("default_building_manager"); - return manager->groups().getChildByName("default_building_group"); -} - -void COutpost::setTribe(const std::string &tribeName) -{ - // The tribe is only populated by the NPCs of the squads - _Tribe = tribeName; - if (LogOutpostDebug) - OUTPOST_DBG("setting tribe '%s' in '%s' as owner for outpost '%s'", - tribeName.c_str(), - getOwner()->getName().c_str(), - getAliasFullName().c_str()); -} - -void COutpost::setOwnerAlliance( TAllianceId ownerAllianceId ) -{ - if (_OwnerAllianceId!=ownerAllianceId) - { - // if the old owner was a tribe - if (_OwnerAllianceId==InvalidAllianceId) - { - triggerSpecialEvent(OUTPOSTENUMS::TribeOwnershipEnd); - OUTPOSTHELPERS::outpostFactions.erase(getAlias()); - } - else - triggerSpecialEvent(OUTPOSTENUMS::GuildOwnershipEnd); - } - std::swap(_OwnerAllianceId, ownerAllianceId); // 'ownerAllianceId' contains old owner alliance id - if (_OwnerAllianceId!=ownerAllianceId) - { - triggerSpecialEvent(OUTPOSTENUMS::OwnerChanged); - // if the new owner is a tribe - if (_OwnerAllianceId==InvalidAllianceId) - { - OUTPOSTHELPERS::outpostFactions.insert(make_pair(getAlias(), CStaticFames::getInstance().getFactionIndex(_Tribe))); - triggerSpecialEvent(OUTPOSTENUMS::TribeOwnershipBegin); - } - else - triggerSpecialEvent(OUTPOSTENUMS::GuildOwnershipBegin); - } -} - -void COutpost::setAttackerAlliance( TAllianceId attackerAllianceId ) -{ - std::swap(_AttackerAllianceId, attackerAllianceId); // 'attackerAllianceId' contains old attacker alliance id - if (_AttackerAllianceId!=attackerAllianceId) - { - triggerSpecialEvent(OUTPOSTENUMS::AttackerChanged); - } - - // Update the enemies of the current squads of the outpost - FOREACH( im, CAliasCont, _Managers ) - im->setEnemies( _AttackerAllianceId ); -} - -void COutpost::setState( OUTPOSTENUMS::TOutpostState state ) -{ - if (_State!=state) - { - if (_State==OUTPOSTENUMS::Peace) - triggerSpecialEvent(OUTPOSTENUMS::PeaceStateEnd); - } - std::swap(_State, state); // 'state' contains old _State - if (_State!=state) - { - triggerSpecialEvent(OUTPOSTENUMS::StateChanged); - if (_State==OUTPOSTENUMS::Peace) - triggerSpecialEvent(OUTPOSTENUMS::PeaceStateBegin); - } -} - -void COutpost::update() -{ -// FOREACH(it, CAliasCont, _SquadFamilies) it->update(); -// FOREACH(it, CAliasCont, _SpawnZones) it->update(); - FOREACH(it, CAliasCont, _Managers) it->update(); -} - -void COutpost::addZone(COutpostSpawnZone* zone) -{ -#if !FINAL_VERSION - if (_ZoneList.find(NLMISC::CStringMapper::map(zone->getName()))!=_ZoneList.end()) - OUTPOST_WRN("this OutpostSpawnZone have the same name than another: %s", zone->getName().c_str()); -#endif - _ZoneList[NLMISC::CStringMapper::map(zone->getName())] = zone; -} - -void COutpost::removeZone(COutpostSpawnZone* zone) -{ - _ZoneList.erase(NLMISC::CStringMapper::map(zone->getName())); -} - -COutpostSpawnZone* COutpost::getZone(NLMISC::TStringId zoneName) -{ - return _ZoneList[zoneName]; -} - -void COutpost::serviceEvent(CServiceEvent const& info) -{ - if (info.getServiceName()=="EGS" && info.getEventType()==CServiceEvent::SERVICE_DOWN) - { - // Delete all the squad groups - COutpostManager* manager = _Managers.getChildByName("default_squad_manager"); - if (manager) - manager->groups().clear(); - } - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - manager->serviceEvent(info); - } -} - -bool COutpost::spawn() -{ - // Spawn outpost managers - CCont::iterator itManager, itManagerEnd(_Managers.end()); - for (itManager=_Managers.begin(); itManager!=itManagerEnd; ++itManager) - { - COutpostManager* manager = *itManager; - manager->spawn(); - } - // We should check individual errors, but fake success here :) - return true; -} - -bool COutpost::despawn() -{ - // Despawn instance managers - CCont::iterator itManager, itManagerEnd(_Managers.end()); - for (itManager=_Managers.begin(); itManager!=itManagerEnd; ++itManager) - { - COutpostManager* manager = *itManager; - manager->despawnMgr(); - } - // We should check individual errors, but fake success here :) - return true; -} - -//----------------------------------------------------------------------------- -std::string COutpost::getStateName() const -{ - return OUTPOSTENUMS::toString(_State); -} - -////////////////////////////////////////////////////////////////////////////// -// COutpostSquadFamily // -////////////////////////////////////////////////////////////////////////////// - -IAliasCont* COutpostSquadFamily::getAliasCont(TAIType type) -{ - switch (type) - { - case AITypeGroupTemplate: - case AITypeGroupTemplateMultiLevel: - return &_GroupDescs; - default: - return NULL; - } - -} - -CAliasTreeOwner* COutpostSquadFamily::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ - if (!cont) - return NULL; - - CAliasTreeOwner* child = NULL; - - switch (aliasTree->getType()) - { - case AITypeSquadTemplateVariant: - child = new CGroupDesc(this, aliasTree->getAlias(), aliasTree->getParent()->getName()+":"+aliasTree->getName()); - break; - case AITypeGroupTemplate: - case AITypeGroupTemplateMultiLevel: - child = new CGroupDesc(this, aliasTree->getAlias(), aliasTree->getName()); - break; - } - - if (child) - cont->addAliasChild(child); - return child; -} - -std::string COutpostSquadFamily::getFullName() const -{ -// return std::string(getOwner()->getFullName() +":"+ getName()); - return getName(); -} - -std::string COutpostSquadFamily::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":sf%u", getChildIndex()); -} - -////////////////////////////////////////////////////////////////////////////// -// CGroupDesc // -////////////////////////////////////////////////////////////////////////////// - -template <> size_t const CGroupDesc::_MultiLevelSheetCount = 20; - -////////////////////////////////////////////////////////////////////////////// -// CBotDesc // -////////////////////////////////////////////////////////////////////////////// - -template <> size_t const CBotDesc::_MultiLevelSheetCount = 20; - -////////////////////////////////////////////////////////////////////////////// -// COutpostSpawnZone // -////////////////////////////////////////////////////////////////////////////// - -COutpostSpawnZone::COutpostSpawnZone(COutpost* owner, CAIAliasDescriptionNode* adn) -: CAIPlaceXYR(owner, adn) -{ - owner->addZone(this); -} - -COutpostSpawnZone::~COutpostSpawnZone() -{ - static_cast(getOwner())->removeZone(this); -} - -std::string COutpostSpawnZone::getFullName() const -{ - return std::string(getOwner()->getFullName() +":"+ getName()); -} - -std::string COutpostSpawnZone::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex()); -} - -////////////////////////////////////////////////////////////////////////////// -// COutpostManager // -////////////////////////////////////////////////////////////////////////////// - -COutpostManager::COutpostManager(COutpost* parent, uint32 alias, std::string const& name, std::string const& filename) -: CMgrNpc(parent, alias, name, filename) -, _AutoSpawn(false) -{ - registerEvents(); -} - -COutpostManager::~COutpostManager() -{ - unregisterEvents(); // need be called otherwise the state manager will be unhappy when the CAIEvent objects are destroyed -} - -std::string COutpostManager::getOneLineInfoString() const -{ - return std::string("Outpost manager '") + getName() + "'"; -} - -void COutpostManager::update() -{ - CMgrNpc::update(); -} - -IAliasCont* COutpostManager::getAliasCont(TAIType type) -{ -// IAliasCont* cont = NULL; -// switch (type) -// { -// default: -// break; -// } -// if (cont) -// return cont; -// else - return CMgrNpc::getAliasCont(type); -} - -CAliasTreeOwner* COutpostManager::createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree) -{ -// CAliasTreeOwner* child = NULL; -// switch (aliasTree->getType()) -// { -// default: -// break; -// } -// if (child) -// cont->addAliasChild(child); -// if (child) -// return child; -// else - return CMgrNpc::createChild(cont, aliasTree); -} - -void COutpostManager::registerEvents() -{ - _StateMachine.addEvent( "outpost_peace_state_begin", EventOutpostPeaceStateBegin ); - _StateMachine.addEvent( "outpost_peace_state_end", EventOutpostPeaceStateEnd ); - _StateMachine.addEvent( "outpost_tribe_ownership_begin", EventOutpostTribeOwnershipBegin ); - _StateMachine.addEvent( "outpost_tribe_ownership_end", EventOutpostTribeOwnershipEnd ); - _StateMachine.addEvent( "outpost_guild_ownership_begin", EventOutpostGuildOwnershipBegin ); - _StateMachine.addEvent( "outpost_guild_ownership_end", EventOutpostGuildOwnershipEnd ); - _StateMachine.addEvent( "outpost_owner_changed", EventOutpostOwnerChanged ); - _StateMachine.addEvent( "outpost_attacker_changed", EventOutpostAttackerChanged ); - _StateMachine.addEvent( "outpost_state_changed", EventOutpostStateChanged ); -} - -void COutpostManager::unregisterEvents() -{ - _StateMachine.delEvent( "outpost_peace_state_begin" ); - _StateMachine.delEvent( "outpost_peace_state_end" ); - _StateMachine.delEvent( "outpost_tribe_ownership_begin" ); - _StateMachine.delEvent( "outpost_tribe_ownership_end" ); - _StateMachine.delEvent( "outpost_guild_ownership_begin" ); - _StateMachine.delEvent( "outpost_guild_ownership_end" ); - _StateMachine.delEvent( "outpost_owner_changed" ); - _StateMachine.delEvent( "outpost_attacker_changed" ); - _StateMachine.delEvent( "outpost_state_changed" ); -} - -void COutpostManager::autoSpawnBegin() -{ - if (!_AutoSpawn) - return; - FOREACH(itGroup, CCont, groups()) - { - CGroupNpc* group = static_cast(*itGroup); - if (group) - { - CSpawnGroupNpc* spawn = group->getSpawnObj(); - if (spawn) - spawn->spawnBots(); - } - } -} - -void COutpostManager::autoSpawnEnd() -{ - if (!_AutoSpawn) - return; - FOREACH(itGroup, CCont, groups()) - { - CGroupNpc* group = static_cast(*itGroup); - if (group) - { - CSpawnGroupNpc* spawn = group->getSpawnObj(); - if (spawn) - spawn->despawnBots(1); - } - } -} - -void COutpostManager::setEnemies( TAllianceId attackerAllianceId ) -{ - FOREACH( ig, CAliasCont, _Groups ) - { - // Attack only the declared ennemies of the outpost - CGroupNpc *grp = static_cast(*ig); - grp->ennemyFaction().clearExtra(); - grp->ennemyFaction().addExtraProperty(attackerAllianceId); - } -} - -////////////////////////////////////////////////////////////////////////////// -// COutpostSquadManager // -////////////////////////////////////////////////////////////////////////////// - -COutpostSquadManager::COutpostSquadManager(COutpost* parent, uint32 alias, std::string const& name, std::string const& filename) -: COutpostManager(parent, alias, name, filename) -{ - // Create init state - CAIState* state = new CAIStatePositional(getStateMachine(), 0, "outpost_squad_init"); - IAIProfileFactory* aiProfile = lookupAIGrpProfile("squad"); - state->setActivityProfile(aiProfile); - getStateMachine()->states().addChild(state); - - CAIEventDescription eventDescription; - CAIEventActionNode::TSmartPtr eventAction; - CAIEventReaction* event; - - // Create event handler for start of state - eventDescription.EventType = "start_of_state"; -// eventDescription.StateKeywords.push_back(""); -// eventDescription.NamedStates.push_back(""); -// eventDescription.GroupKeywords.push_back(""); -// eventDescription.NamedGroups.push_back(""); - - // Create event action - eventAction = new CAIEventActionNode; - eventAction->Action = "code"; - eventAction->Weight = 1; - eventAction->Args.push_back("print(\"CREATING A SQUAD\");"); -// eventAction->Args.push_back("()setFactionProp(\"faction\", \"foo\");"); -// eventAction->Args.push_back("()setFactionProp(\"ennemyFaction\", \"bar\");"); -// eventAction->Args.push_back("()setFactionProp(\"friendFaction\", \"baf\");"); - eventAction->Args.push_back("()setHealer(1);"); - - // Register event action - eventDescription.Action = eventAction; - eventAction = NULL; - - // Register event handler - event = new CAIEventReaction(getStateMachine(), 0, eventDescription.EventType); - event->processEventDescription(&eventDescription, getStateMachine()); - getStateMachine()->eventReactions().addChild(event); - event = NULL; - - // Create event handler for group death - eventDescription.EventType = "group_eliminated"; -// eventDescription.StateKeywords.push_back(""); -// eventDescription.NamedStates.push_back(""); -// eventDescription.GroupKeywords.push_back(""); -// eventDescription.NamedGroups.push_back(""); - - // Create event action - eventAction = new CAIEventActionNode; - eventAction->Action = "outpost_report_squad_death"; - eventAction->Weight = 1; -// eventAction->Args.push_back(""); - - // Register event action - eventDescription.Action = eventAction; - eventAction = NULL; - - // Register event handler - event = new CAIEventReaction(getStateMachine(), 0, eventDescription.EventType); - event->processEventDescription(&eventDescription, getStateMachine()); - getStateMachine()->eventReactions().addChild(event); - event = NULL; - - // Create event handler for bot death - eventDescription.EventType = "bot_killed"; -// eventDescription.StateKeywords.push_back(""); -// eventDescription.NamedStates.push_back(""); -// eventDescription.GroupKeywords.push_back(""); -// eventDescription.NamedGroups.push_back(""); - - // Create event action - eventAction = new CAIEventActionNode; - eventAction->Action = "outpost_send_squad_status"; - eventAction->Weight = 1; -// eventAction->Args.push_back(""); - - // Register event action - eventDescription.Action = eventAction; - eventAction = NULL; - - // Register event handler - event = new CAIEventReaction(getStateMachine(), 0, eventDescription.EventType); - event->processEventDescription(&eventDescription, getStateMachine()); - getStateMachine()->eventReactions().addChild(event); - event = NULL; - - // Create event handler for bot death - eventDescription.EventType = "squad_leader_killed"; -// eventDescription.StateKeywords.push_back(""); -// eventDescription.NamedStates.push_back(""); -// eventDescription.GroupKeywords.push_back(""); -// eventDescription.NamedGroups.push_back(""); - - // Create event action - eventAction = new CAIEventActionNode; - eventAction->Action = "multi_actions"; - eventAction->Weight = 1; - eventAction->Children.resize(2); - eventAction->Children[0] = new CAIEventActionNode; - eventAction->Children[0]->Action = "outpost_report_squad_leader_death"; - eventAction->Children[0]->Weight = 1; -// eventAction->Children[0]->Args.push_back(""); - eventAction->Children[1] = new CAIEventActionNode; - eventAction->Children[1]->Action = "code"; - eventAction->Children[1]->Weight = 1; - eventAction->Children[1]->Args.push_back("()setAutoSpawn(0);"); -#ifdef NL_DEBUG - eventAction->Children[1]->Args.push_back("print(\"INFINITE RESPAWN TIME FOR SQUAD\");"); -#endif - - // Register event action - eventDescription.Action = eventAction; - eventAction = NULL; - - // Register event handler - event = new CAIEventReaction(getStateMachine(), 0, eventDescription.EventType); - event->processEventDescription(&eventDescription, getStateMachine()); - getStateMachine()->eventReactions().addChild(event); - event = NULL; -} - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -void COutpost::createSquad(string const& dynGroupName, string const& stateMachineName, string const& initialStateName, string const& zoneName, uint32 spawnOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side) -{ - IManagerParent* const managerParent = getOwner()->getOwner(); - CAIInstance* const aiInstance = dynamic_cast(managerParent); - if (!aiInstance) - return; - - COutpostSpawnZone const* spawnZone = getZone(CStringMapper::map(zoneName)); - if (!spawnZone) - { - OUTPOST_WRN("newNpcChildGroup failed : spawnZone Not Found ! for StateMachine : %s", stateMachineName.c_str()); - return; - } - - CGroupDesc const* groupDesc = NULL; - - FOREACH(itGroupDesc, CSquadLinks, _SquadLinks) - { - if ((*itGroupDesc).second->getName()==dynGroupName) - { - groupDesc = (*itGroupDesc).second; - goto groupFound; - } - } -groupFound: - if (!groupDesc) - { - OUTPOST_WRN("createSquad failed: No Group Found"); - return; - } - - // Find the state machine as a manager - CManager* manager = NULL; - FOREACH(itCont, CCont, aiInstance->managers()) - { - if (itCont->getName()==stateMachineName) - { - manager = *itCont; - break; - } - } - if (!manager) - { - FOREACH(itCont, CCont, managers()) - { - if (itCont->getName()==stateMachineName) - { - manager = *itCont; - break; - } - } - } - if (!manager) - { - OUTPOST_WRN("createSquad failed : Unknown stateMachine %s", stateMachineName.c_str()); - return; - } - // Find the state machine as a npc manager - COutpostSquadManager* outpostManager = dynamic_cast(manager); - if (!outpostManager) - { - OUTPOST_WRN("createSquad failed : Not an outpost state machine !: ", stateMachineName.c_str()); - return; - } - createSquad(groupDesc, outpostManager, initialStateName, spawnZone, spawnOrder, respawTimeGC, side); -} - -void COutpost::createSquad(uint32 dynGroupAlias, uint32 zoneAlias, uint32 spawnOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side) -{ - IManagerParent* const managerParent = getOwner()->getOwner(); - CAIInstance* const aiInstance = dynamic_cast(managerParent); - if (!aiInstance) - return; - - COutpostSpawnZone const* spawnZone = spawnZones().getChildByAlias(zoneAlias); - if (!spawnZone) - { - OUTPOST_WRN("createSquad failed: spawn zone %s not found", LigoConfig.aliasToString(zoneAlias).c_str()); - return; - } - - CGroupDesc const* groupDesc = NULL; - - // Find the group template. - // :TODO: Replace it with a faster map access. - groupDesc = getSquad( dynGroupAlias ); - if (!groupDesc) - { - OUTPOST_WRN("createSquad failed: group %s not found", LigoConfig.aliasToString(dynGroupAlias).c_str()); - return; - } - - // Find the state machine as a manager - COutpostSquadManager* manager = dynamic_cast(managers().getChildByName("default_squad_manager")); - if (!manager) - { - OUTPOST_WRN("createSquad failed: default state machine not found! (<- this is a code bug)"); - return; - } - createSquad(groupDesc, manager, "", spawnZone, spawnOrder, respawTimeGC, side); -} - -void COutpost::createSquad(CGroupDesc const* groupDesc, COutpostSquadManager* manager, string const& initialStateName, COutpostSpawnZone const* spawnZone, uint32 createOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side) -{ - OUTPOST_DBG("Creating a squad"); - CAIVector const& spawnPosition = spawnZone->midPos(); - sint32 baseLevel = -1; - double dispersionRadius = spawnZone->getRadius(); - // Save the creator state - bool const savePlayerAttackable = groupDesc->getGDPlayerAttackable(); - bool const saveBotAttackable = groupDesc->getGDBotAttackable(); - // PlayerAttackable must be false as it it sent to the EGS in BotDescriptionMessage to set the - // property 'Attackable'. Squads are not attackable unless a player is in war with the owner of - // the outpost (using botchatprogram instead of the property 'Attackable'). - // BotAttackable must be true, otherwise the EGS sets it as invulnerable (not attackable). - groupDesc->setGDPlayerAttackable(false); - groupDesc->setGDBotAttackable(true); - // Create the group - CGroupNpc* const grp = groupDesc->createNpcGroup(manager, spawnPosition, dispersionRadius, baseLevel, false); - // Restore the creator state - groupDesc->setGDPlayerAttackable(savePlayerAttackable); - groupDesc->setGDBotAttackable(saveBotAttackable); - // Verify that the group was created - if (!grp) - { - OUTPOST_WRN("createSquad failed: group %s cannot spawn", LigoConfig.aliasToString(groupDesc->getAlias()).c_str()); - return; - } - // Set the new group parameters - // Let the EGS destroys squads explicitely because when a group is destroyed in the AIS its groupId can be reused - // and 2 squads would have the same groupId in the EGS (it asserts) - grp->autoDestroy(false); - grp->setAutoSpawn(true); - // grp->getPersistentStateInstance()->setParentStateInstance(entity->getPersistentStateInstance()); - grp->initDynGrp(groupDesc, NULL); - // Set color - uint8 color = (uint8)(grp->getChildIndex() % 8); - grp->setColour(color); - // Get the state machine - CStateMachine const* stateMachine = manager->getStateMachine(); -#if !FINAL_VERSION - // Verify that we have a state in the state machine - if (stateMachine->cstStates().size()==0) - nlerror("no state defined for StateMachine in Manager %s", manager->getFullName().c_str()); -#endif - // Set the group in that state - CAIState* initialState = NULL; - if (!initialStateName.empty()) - { - // FOREACH(itState, CCont, stateMachine->states()) - for (size_t i=0; icstStates().size(); ++i) - { - CAIState* state = stateMachine->cstStates()[(uint32)i]; - if (state->getName()==initialStateName) - initialState = state; - } - } - if (initialState==NULL) - initialState = stateMachine->cstStates()[0]; // sets the first state (must exist!). - grp->setStartState(initialState); - - // Do not assist friends because it would lead to exploits - /*if ( _OwnerGuild != InvalidGuildId ) - { - //grp->faction().addExtraProperty(_OwnerGuild); // TODO: set the GuildId for the squad npcs? - //grp->friendFaction().addExtraProperty(_OwnerGuild); // will be defended by the squad - } - else - { - // A tribe owns the outpost and all players are ennemies - // CPropertyId tribeFaction(CGrpProfileFaction::fameFactionToScriptFaction(_OwnerTribe)); - //grp->faction().addProperty(tribeFaction); - //grp->friendFaction().addProperty(tribeFaction); // will be defended by the squad - //grp->ennemyFaction().addProperty(CPropertyId("Player")); - }*/ - - // Set guild id of members of the squad (for the tribe case, these *are* the tribe as well) - // This was removed because CBotNpc::spawn() now uses getOwner()->getOwner()->getOwner() to access the outpsot - /*FOREACH(ib, CAliasCont, grp->bots()) - { - CBotNpc *bot = static_cast(*ib); - bot->setOwnerOutpost(this); - }*/ - - grp->setOutpostSide(side); - grp->setOutpostFactions(side); - - grp->_AggroRange = 25; - grp->_UpdateNbTicks = 10; - grp->respawnTime() = respawTimeGC; - - grp->updateStateInstance(); // Directly call his first state (to retrieve associated params). - - if (createOrder!=0) - { - COutpostSquadCreatedMsg params; - params.Outpost = this->getAlias(); - params.CreateOrder = createOrder; - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //params.GroupId = reinterpret_cast(grp); - params.GroupId = (uint32)(size_t)(void*)grp; - sendOutpostMessage("OUTPOST_SQUAD_CREATED", params); - } - - OUTPOST_DBG( "Outpost %s: squad created defending 0x%x against 0x%x, respawnTime=%u gc", getName().c_str(), _OwnerAllianceId, _AttackerAllianceId, respawTimeGC ); -} - -void COutpost::spawnSquad(uint32 groupId) -{ - OUTPOST_DBG( "Outpost %s: Spawning squad 0x%08x", getName().c_str(), groupId ); - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - FOREACH(itGroup, CAliasCont, manager->groups()) - { - CGroup* group = *itGroup; - CGroupNpc* groupNpc = static_cast(group); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 thisGroupId = reinterpret_cast(groupNpc); - uint32 thisGroupId = (uint32)(size_t)(void*)groupNpc; - if (groupId==thisGroupId) - { - group->getSpawnObj()->spawnBots(); - COutpostSquadSpawnedMsg params; - params.Outpost = this->getAlias(); - params.GroupId = groupId; - sendOutpostMessage("OUTPOST_SQUAD_SPAWNED", params); - OUTPOST_DBG( "\t\tSpawned" ); - return; - } - } - } - OUTPOST_WRN("No squad to spawn with group id 0x%08x. Valid group ids are:", groupId); - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - FOREACH(itGroup, CAliasCont, manager->groups()) - { - CGroup* group = *itGroup; - CGroupNpc* groupNpc = static_cast(group); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 thisGroupId = reinterpret_cast(groupNpc); - uint32 thisGroupId = (uint32)(size_t)(void*)groupNpc; - OUTPOST_WRN("- 0x%08x", thisGroupId); - } - } -} - -void COutpost::despawnSquad(uint32 groupId) -{ - OUTPOST_DBG( "Outpost %s: Despawning squad 0x%08x", getName().c_str(), groupId ); - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - FOREACH(itGroup, CAliasCont, manager->groups()) - { - CGroup* group = *itGroup; - CGroupNpc* groupNpc = static_cast(group); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 thisGroupId = reinterpret_cast(groupNpc); - uint32 thisGroupId = (uint32)(size_t)(void*)groupNpc; - if (groupId==thisGroupId) - { - group->despawnBots(); - COutpostSquadDespawnedMsg params; - params.Outpost = this->getAlias(); - params.GroupId = groupId; - sendOutpostMessage("OUTPOST_SQUAD_DESPAWNED", params); - return; - } - } - } - OUTPOST_WRN("No squad to despawn"); -} - -void COutpost::deleteSquad(uint32 groupId) -{ - OUTPOST_DBG( "Outpost %s: deleting squad 0x%08x", getName().c_str(), groupId ); - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - FOREACH(itGroup, CAliasCont, manager->groups()) - { - CGroup* group = *itGroup; - CGroupNpc* groupNpc = static_cast(group); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 thisGroupId = reinterpret_cast(groupNpc); - uint32 thisGroupId = (uint32)(size_t)(void*)groupNpc; - if (groupId==thisGroupId) - { - manager->groups().removeChildByIndex(group->getChildIndex()); - // No message here since this is called by squad destructor in EGS - return; - } - } - } - OUTPOST_WRN("No squad to delete"); -} - -void COutpost::sendOutpostSquadStatus(CGroupNpc* group) -{ - uint32 alias = this->getAlias(); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 groupId = reinterpret_cast(group); - uint32 groupId = (uint32)(size_t)(void*)group; - bool groupAlive = false; - bool leaderAlive = group->getSquadLeader()!=NULL; - uint32 botCount = 0; - // Persistent status - // Spawn dependent status - CSpawnGroup* spawnGroup = group->getSpawnObj(); - if (spawnGroup) - { - groupAlive = spawnGroup->isGroupAlive(); - } - NLNET::CMessage msgout("OUTPOST_SQUAD_STATUS"); - msgout.serial(alias); - msgout.serial(groupId); - msgout.serial(groupAlive); - msgout.serial(leaderAlive); - msgout.serial(botCount); - sendMessageViaMirror("EGS", msgout); -} - -void COutpost::squadLeaderDied(CGroupNpc* group) -{ - uint32 alias = this->getAlias(); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 groupId = reinterpret_cast(group); - uint32 groupId = (uint32)(size_t)(void*)group; - NLNET::CMessage msgout("OUTPOST_SQUAD_LEADER_DIED"); - msgout.serial(alias); - msgout.serial(groupId); - sendMessageViaMirror("EGS", msgout); -} - -void COutpost::squadDied(CGroupNpc* group) -{ - uint32 alias = this->getAlias(); - // Bug #847: Just downcast the pointer to make the groupId, the collision in 64b is negligible - //uint32 groupId = reinterpret_cast(group); - uint32 groupId = (uint32)(size_t)(void*)group; - NLNET::CMessage msgout("OUTPOST_SQUAD_DIED"); - msgout.serial(alias); - msgout.serial(groupId); - sendMessageViaMirror("EGS", msgout); -} - -void COutpost::triggerSpecialEvent(OUTPOSTENUMS::TSpecialOutpostEvent eventId) -{ - // Managers handlers - FOREACH(itManager, CCont, _Managers) - { - COutpostManager* manager = *itManager; - if (manager) - { - CAIEvent* event = NULL; - switch (eventId) - { - case OUTPOSTENUMS::PeaceStateBegin: event = &manager->EventOutpostPeaceStateBegin; break; - case OUTPOSTENUMS::PeaceStateEnd: event = &manager->EventOutpostPeaceStateEnd; break; - case OUTPOSTENUMS::TribeOwnershipBegin: event = &manager->EventOutpostTribeOwnershipBegin; break; - case OUTPOSTENUMS::TribeOwnershipEnd: event = &manager->EventOutpostTribeOwnershipEnd; break; - case OUTPOSTENUMS::GuildOwnershipBegin: event = &manager->EventOutpostGuildOwnershipBegin; break; - case OUTPOSTENUMS::GuildOwnershipEnd: event = &manager->EventOutpostGuildOwnershipEnd; break; - case OUTPOSTENUMS::OwnerChanged: event = &manager->EventOutpostOwnerChanged; break; - case OUTPOSTENUMS::AttackerChanged: event = &manager->EventOutpostAttackerChanged; break; - case OUTPOSTENUMS::StateChanged: event = &manager->EventOutpostStateChanged; break; - } - if (event) - { - FOREACH(itGroup, CCont, manager->groups()) - { - CGroupNpc* group = static_cast(*itGroup); - if (group) - group->processStateEvent(*event); - } - } - } - } - // Special handlers - switch (eventId) - { - case OUTPOSTENUMS::TribeOwnershipBegin: - { - FOREACH(itManager, CCont, _Managers) - { - COutpostManager* manager = *itManager; - if (manager) - manager->autoSpawnBegin(); - } - break; - } - case OUTPOSTENUMS::TribeOwnershipEnd: - { - FOREACH(itManager, CCont, _Managers) - { - COutpostManager* manager = *itManager; - if (manager) - manager->autoSpawnEnd(); - } - break; - } - } -} - -void COutpost::setBuildingBotSheet(uint32 buildingAlias, NLMISC::CSheetId sheetId, bool autoSpawnDespawn, const std::string & customName) -{ - CBot * bot = getBuildingBotByAlias(buildingAlias); - if (bot == NULL) - { - OUTPOST_WRN( "cannot find building bot %s", LigoConfig.aliasToString( buildingAlias ).c_str() ); - return; - } - - AISHEETS::ICreatureCPtr const sheet = AISHEETS::CSheets::getInstance()->lookup(sheetId); - if (sheetId!=NLMISC::CSheetId::Unknown && !sheet.isNull()) - { - bot->setCustomName(customName); - bot->triggerSetSheet(sheet); - if (autoSpawnDespawn && !bot->isSpawned()) - bot->spawn(); - } - else - { - if (autoSpawnDespawn && bot->isSpawned()) - bot->despawnBot(); - } -} - -void COutpost::despawnAllSquads() -{ - FOREACH(itManager, CAliasCont, _Managers) - { - COutpostManager* manager = *itManager; - COutpostSquadManager* sqManager = dynamic_cast(manager); - if (sqManager) - { - FOREACH(itGroup, CAliasCont, sqManager->groups()) - { - CGroup* group = *itGroup; - group->despawnBots(); - } - } - } -} - -template -void COutpost::sendOutpostMessage(std::string const& msgName, T& paramStruct) -{ - NLNET::CMessage msgout(msgName); - msgout.serial(paramStruct); - sendMessageViaMirror(std::string("EGS"), msgout); -} - -////////////////////////////////////////////////////////////////////////////// -// Commands // -////////////////////////////////////////////////////////////////////////////// - -NLMISC_COMMAND(displayOutposts, "list the available outpost", "") -{ - if (args.size() > 0) - return false; - - uint32 instanceNumber = std::numeric_limits::max(); - for (uint i=0; icontinents().size(); ++i) - { - CContinent *const continent = aii->continents()[i]; - if ( !continent - || ( !continentName.empty() - && continentName!=continent->getName())) - continue; - - log.displayNL("Outposts in continent '%s':", continent->getName().c_str()); - for (uint j=0; joutposts().size(); ++j) - { - COutpost const* outpost = continent->outposts()[j]; - if (!outpost) - continue; - - log.displayNL(" %s", outpost->getOneLineInfoString().c_str()); - log.displayNL(" - %d group descs", outpost->squadLinks().size()); - for (COutpost::CSquadLinks::const_iterator isl=outpost->squadLinks().begin(); isl!=outpost->squadLinks().end(); ++isl ) - { - CGroupDesc const* gd = (*isl).second; - if (!gd) - continue; - - log.displayNL(" Group desc '%s' %s", gd->getName().c_str(), gd->getAliasString().c_str()); - } - - log.displayNL(" - %d spawn zones", outpost->spawnZones().size()); - for (uint j=0; jspawnZones().size(); ++j) - { - COutpostSpawnZone const* sz = outpost->spawnZones()[j]; - if (!sz) - continue; - - log.displayNL(" SpawnZone '%s' %s (%s)", sz->getName().c_str(), sz->getAliasString().c_str(), sz->midPos().toString().c_str()); - } - log.displayNL(" - %d state machines", outpost->managers().size()); - for (uint j=0; jmanagers().size(); ++j) - { - COutpostManager* manager = outpost->managers()[j]; - if (!manager) - continue; - - log.displayNL(" State machine '%s' %s", manager->getName().c_str(), manager->getAliasString().c_str()); - log.displayNL(" - %d states", manager->getStateMachine()->states().size()); - for (uint j=0; jgetStateMachine()->states().size(); ++j) - { - CAIState const* state = manager->getStateMachine()->states()[j]; - if (!state) - continue; - - log.displayNL(" State '%s' %s", state->getName().c_str(), state->getAliasString().c_str()); - } - log.displayNL(" - %d groups", manager->groups().size()); - for (uint j=0; jgroups().size(); ++j) - { - CGroup const* group = manager->groups()[j]; - if (group) - { - log.displayNL(" Group '%s' %s", group->getName().c_str(), group->getAliasString().c_str()); - log.displayNL(" - %d bots", group->bots().size()); - for (uint k=0; kbots().size(); ++k) - { - CBot const* bot = group->bots()[k]; - if (bot) - log.displayNL(" Bot '%s' %s", bot->getName().c_str(), bot->getAliasString().c_str()); - else - log.displayNL(" Bot "); - } - } - else - log.displayNL(" Group "); - } - } - } - - } - } - return true; -} - -// outpostSpawnSquad 1 fyros outpost group machine zone - -NLMISC_COMMAND(outpostSpawnSquad, "Spawns a squad in an outpost", " [=5*60]") -{ - if (args.size() != 6) - return false; - - uint32 instanceNumber = std::numeric_limits::max(); - fromString(args[0], instanceNumber); - string continentName = args[1]; - string outpostName = args[2]; - string dynGroupName = args[3]; - string stateMachineName = args[4]; - string zoneName = args[5]; - uint32 respawnTimeGC = 5*60*10; - if ( args.size() > 6 ) - { - NLMISC::fromString(args[6], respawnTimeGC); - respawnTimeGC *= 10; - } - - for (size_t i=0; i<5; ++i) - if (args[i]=="") - return false; - - bool done = false; - bool instanceFound = false; - bool continentFound = false; - bool outpostFound = false; - if (instanceNumbercontinents().size() && !done; ++i) - { - CContinent* const continent = aiinstance->continents()[i]; - if (!continent || continentName!=continent->getName()) - continue; - continentFound = true; - for (uint j=0; joutposts().size() && !done; ++j) - { - COutpost* const outpost = continent->outposts()[j]; - if (!outpost || outpostName!=outpost->getName()) - continue; - outpostFound = true; - outpost->createSquad(dynGroupName, stateMachineName, "", zoneName, 0, respawnTimeGC, OUTPOSTENUMS::UnknownPVPSide); - done = true; - } - } - } - } - if (!done) - { - OUTPOST_WRN("Could not spawn a new squad"); - log.displayNL("Could not spawn a new squad"); - if (!instanceFound) - log.displayNL( "Instance not found" ); - if (!continentFound) - log.displayNL( "Continent not found" ); - if (!outpostFound) - log.displayNL( "Outpost not found" ); - } - return true; -} - - -/* - * Return the outpost corresponding to the alias, or NULL if not found (with a nlwarning) - */ -COutpost* COutpost::getOutpostByAlias( TAIAlias outpostAlias ) -{ - bool instanceFound = false; - bool continentFound = false; - bool outpostFound = false; - for (uint i=0; icontinents().size(); ++i) - { - CContinent* const continent = aiinstance->continents()[i]; - if (!continent) - continue; - continentFound = true; - for (uint j=0; joutposts().size(); ++j) - { - COutpost* outpost = continent->outposts()[j]; - if (!outpost || outpostAlias!=outpost->getAlias()) - continue; - return outpost; - } - } - } - } - if (!instanceFound) - OUTPOST_WRN( "Instance not found" ); - if (!continentFound) - OUTPOST_WRN( "Continent not found" ); - if (!outpostFound) - OUTPOST_WRN( "Outpost %s not found", LigoConfig.aliasToString( outpostAlias ).c_str() ); - return NULL; -} - -/* -void outpostCreateSquad(uint32 outpostAlias, uint32 dynGroupAlias, uint32 zoneAlias, uint32 spawnOrder) -{ - COutpost *outpost = COutpost::getOutpostByAlias( outpostAlias ); - if ( outpost ) - outpost->createSquad(dynGroupAlias, zoneAlias, spawnOrder); -} - -void outpostSpawnSquad(uint32 outpostAlias, uint32 groupId) -{ - COutpost *outpost = COutpost::getOutpostByAlias( outpostAlias ); - if ( outpost ) - outpost->spawnSquad(groupId); -} - -void outpostDespawnSquad(uint32 outpostAlias, uint32 groupId) -{ - COutpost *outpost = COutpost::getOutpostByAlias( outpostAlias ); - if ( outpost ) - outpost->despawnSquad(groupId); -} - -void outpostDeleteSquad(uint32 outpostAlias, uint32 groupId) -{ - COutpost *outpost = COutpost::getOutpostByAlias( outpostAlias ); - if ( outpost ) - outpost->deleteSquad(groupId); -} - -void outpostDespawnAllSquads(uint32 outpostAlias) -{ - COutpost *outpost = COutpost::getOutpostByAlias( outpostAlias ); - if ( outpost ) - outpost->despawnAllSquads(); -} -*/ - -NLMISC_COMMAND(outpostAliasSpawnSquad, "Spawns a squad in an outpost (respawn time = 5 min)", " ") -{ - if (args.size()!=3) - return false; - - for (size_t i=0; i<3; ++i) - if (args[i]=="") - return false; - - uint32 outpostAlias = LigoConfig.aliasFromString(args[0]); - uint32 dynGroupAlias = LigoConfig.aliasFromString(args[1]); - uint32 zoneAlias = LigoConfig.aliasFromString(args[2]); - string stateMachineName = "default_squad_manager"; - - COutpost *outpost = COutpost::getOutpostByAlias(outpostAlias); - if (outpost) - outpost->createSquad(dynGroupAlias, zoneAlias, 0, 5*60*10, OUTPOSTENUMS::UnknownPVPSide); - - return true; -} - -CBot* COutpost::getBuildingBotByAlias(TAIAlias alias) -{ - CGroup* group = getBuildingGroup(); - if (group) - return group->bots().getChildByAlias(alias); - else - return NULL; -} - -NLMISC_COMMAND(outpostSetBuildingBotSheet, "Set the sheet of an outpost building", " ") -{ - if (args.size()!=3) - return false; - - for (size_t i=0; i<3; ++i) - if (args[i]=="") - return false; - - uint32 outpostAlias = LigoConfig.aliasFromString(args[0]); - uint32 buildingAlias = LigoConfig.aliasFromString(args[1]); - NLMISC::CSheetId buildingBotSheet = NLMISC::CSheetId(args[2]);; - - COutpost* outpost = COutpost::getOutpostByAlias(outpostAlias); - if (outpost) - outpost->setBuildingBotSheet(buildingAlias, buildingBotSheet, true, ""); - - return true; -} - - -// Call this macro, then do the code that will must done only if the outpost is found in this instance -// The data you have access to after this macro: -// - COutpost *outpost -// - msgStruct params; -#define IF_GET_OUTPOST_FOR_MSG( msgStruct ) \ - msgStruct params; \ - msgin.serial( params ); \ - COutpost *outpost = COutpost::getOutpostByAlias( params.Outpost ); \ -if ( outpost ) - - -void cbOutpostCreateSquad( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostCreateSquadMsg ) - outpost->createSquad(params.Group, params.Zone, params.CreateOrder, params.RespawnTimeS*10, params.Side); -} - -void cbOutpostSpawnSquad( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostSpawnSquadMsg ) - outpost->spawnSquad(params.GroupId); -} - -void cbOutpostDespawnSquad( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostDespawnSquadMsg ) - outpost->despawnSquad(params.GroupId); -} - -void cbOutpostDeleteSquad( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostDeleteSquadMsg ) - outpost->deleteSquad(params.GroupId); -} - -void cbOutpostDespawnAllSquads( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostDespawnAllSquadsMsg ) - outpost->despawnAllSquads(); -} - -void cbOutpostSetOwner( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( CSetOutpostOwner ) - outpost->setOwnerAlliance( params.Owner ); -} - -void cbOutpostSetAttacker( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( CSetOutpostAttacker ) - outpost->setAttackerAlliance( params.Attacker ); -} - -void cbOutpostSetState( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostSetStateMsg ) - outpost->setState( params.State ); -} - -void cbOutpostEvent( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostEventMsg ) - outpost->triggerSpecialEvent(params.Event); -} - -void cbOutpostSetBuildingBotSheet( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) -{ - IF_GET_OUTPOST_FOR_MSG( COutpostSetBuildingBotSheetMsg ) - outpost->setBuildingBotSheet(params.Building, params.SheetId, params.AutoSpawnDespawn, params.CustomName); -} - - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_outpost.h b/code/ryzom/server/src/ai_service/ai_outpost.h deleted file mode 100644 index a05b16274..000000000 --- a/code/ryzom/server/src/ai_service/ai_outpost.h +++ /dev/null @@ -1,353 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -#ifndef AI_OUTPOST_H -#define AI_OUTPOST_H - -#include "nel/misc/variable.h" -#include "child_container.h" -#include "alias_tree_root.h" -#include "game_share/zc_shard_common.h" -#include "service_dependencies.h" -#include "state_instance.h" -#include "manager_parent.h" -#include "event_reaction_container.h" -#include "ai_place_patat.h" - -class CContinent; -class CCellZone; -class COutpostSquadFamily; -class COutpostManager; -class COutpostSquadManager; -template -class CGroupDesc; -template -class CBotDesc; -class COutpostGroup; -class COutpostSpawnZone; - -extern NLMISC::CVariable LogOutpostDebug; - -////////////////////////////////////////////////////////////////////////////// -// Helpers functions // -////////////////////////////////////////////////////////////////////////////// - -namespace OUTPOSTHELPERS { - -extern uint32 getEntityOutpost(CAIEntityPhysical const* entity); -extern bool isAttackingFaction(uint32 factionIndex, CAIEntityPhysical const* player); - -} - -#define RYAI_DEBUG_OUTPOSTS 1 - -#ifdef RYAI_DEBUG_OUTPOSTS - -#define OUTPOST_DBG nldebug -#define OUTPOST_INF nlinfo -#define OUTPOST_WRN nlwarning -#define OUTPOST_ERR nlerror - -#else - -extern NLMISC::CLog OutpostDbgLog, OutpostInfLog, OutpostWrnLog, OutpostErrLog; -#define OUTPOST_DBG OutpostDbgLog.setPosition( __LINE__, __FILE__, __FUNCTION__ ), OutpostDbgLog.displayNL -#define OUTPOST_INF OutpostInfLog.setPosition( __LINE__, __FILE__, __FUNCTION__ ), OutpostInfLog.displayNL -#define OUTPOST_WRN OutpostWrnLog.setPosition( __LINE__, __FILE__, __FUNCTION__ ), OutpostWrnLog.displayNL -#define OUTPOST_ERR OutpostErrLog.setPosition( __LINE__, __FILE__, __FUNCTION__ ), OutpostErrLog.displayNL - -#endif - -////////////////////////////////////////////////////////////////////////////// -// COutpost // -////////////////////////////////////////////////////////////////////////////// - -class COutpost -: public NLMISC::CDbgRefCount -, public CAliasChild -, public NLMISC::CRefCount -, public CAliasTreeRoot -, public CPlaceOwner -, public IManagerParent -{ -public: - - typedef std::map< TAIAlias, NLMISC::CSmartPtr > > CSquadLinks; - - /// Return the outpost corresponding to the alias, or NULL if not found (with a nlwarning) - static COutpost* getOutpostByAlias(TAIAlias outpostAlias); - - COutpost(CContinent* owner, uint32 alias, std::string const& name, std::string const& filename); - virtual ~COutpost(); - - /// @name CChild implementation - //@{ - virtual std::string getIndexString() const; - virtual std::string getOneLineInfoString() const; -// virtual std::vector getMultiLineInfoString() const; - virtual std::string getFullName() const; - // virtual std::string getName() const; - //@} - - /// @name IManagerParent implementation - //@{ - virtual CAIInstance* getAIInstance() const; - virtual CCellZone* getCellZone() { return NULL; } -// virtual std::string getIndexString() const = 0; - virtual std::string getManagerIndexString(CManager const* manager) const; - virtual void groupDead(CGroup* grp) { } - //@} - - /// @name Children containers accessors - //@{ - CAliasCont& spawnZones() { return _SpawnZones; } - CAliasCont const& spawnZones() const { return _SpawnZones; } - CAliasCont& managers() { return _Managers; } - CAliasCont const& managers() const { return _Managers; } - //@} - - /// @name Outpost zone - //@{ - NLMISC::CSmartPtr const& getShape() const { return _Shape; } - void setShape(NLMISC::CSmartPtr const& shape) { _Shape = shape; } - //@} - - /// Returns the group containing building bots - CGroup* getBuildingGroup(); - /// Returns the building bot with the specified alias - CBot* getBuildingBotByAlias(TAIAlias alias); - - /// Set the tribe that can own the outpost when no guild owns it - void setTribe(std::string const& tribeName); - - std::string const& getTribe() const { return _Tribe; } - - /// Return the guild defending the outpost, or InvalidGuildId - TAllianceId getOwnerAlliance() const { return _OwnerAllianceId; } - - /// Assign the outpost to a guild (defender) or to a tribe with InvalidAllianceId. - void setOwnerAlliance( TAllianceId ownerAllianceId ); - - /// Set the attacker guilds (opponent and its allies) of the outpost - void setAttackerAlliance( TAllianceId attackerAllianceId ); - - /// Set the EGS state of the outpost - void setState( OUTPOSTENUMS::TOutpostState state ); - - /// Manages service event (typically service ups and downs) - void serviceEvent(CServiceEvent const& info); - - std::string const& getOutpostName() const { return _OutpostName; } - - /// Called regularly at low frequency by continent update - void update(); - - void addZone(COutpostSpawnZone* zone); - void removeZone(COutpostSpawnZone* zone); - COutpostSpawnZone* getZone(NLMISC::TStringId zoneName); - - void createSquad(CGroupDesc const* groupDesc, COutpostSquadManager* manager, std::string const& initialStateName, COutpostSpawnZone const* spawnZone, uint32 spawnOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side); - void createSquad(std::string const& dynGroupName, std::string const& stateMachineName, std::string const& initialStateName, std::string const& zoneName, uint32 spawnOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side); - void createSquad(uint32 dynGroupAlias, uint32 zoneAlias, uint32 spawnOrder, uint32 respawTimeGC, OUTPOSTENUMS::TPVPSide side); - void spawnSquad(uint32 groupId); - void despawnSquad(uint32 groupId); - void deleteSquad(uint32 groupId); - void despawnAllSquads(); - void sendOutpostSquadStatus(CGroupNpc* group); - void squadLeaderDied(CGroupNpc* group); - void squadDied(CGroupNpc* group); - - void triggerSpecialEvent(OUTPOSTENUMS::TSpecialOutpostEvent eventId); - - void setBuildingBotSheet(uint32 buildingAlias, NLMISC::CSheetId sheetId, bool autoSpawnDespawn, const std::string & customName); - - bool spawn(); - bool despawn(); - - /// returns the state of the outpost - std::string getStateName() const; - - /// return true if the outpost is owned by a guild, not by a tribe - bool isBelongingToAGuild() const { return (_OwnerAllianceId!=InvalidAllianceId); } - - // add a link to a squad that can be created/spawned in the outpost - void addSquadLink( TAIAlias alias, CGroupDesc *squad ) - { - _SquadLinks.insert( std::make_pair( alias, squad ) ); - } - - /// get a squad that can be created/spawned in the outpost - CGroupDesc *getSquad( TAIAlias alias ) - { - CSquadLinks::iterator it=_SquadLinks.find( alias ); - if ( it != _SquadLinks.end() ) - return (*it).second; - else - return NULL; - } - - const CSquadLinks& squadLinks() const { return _SquadLinks; } - -private: - IAliasCont *getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner *createChild(IAliasCont *cont, CAIAliasDescriptionNode *aliasTree); - template - void sendOutpostMessage(std::string const& msgName, T& paramStruct); - -private: - /// @name AI service hierarchy - //@{ - CAliasCont _SpawnZones; - CAliasCont _Managers; - //@} - - /// Links to the squad group descs - CSquadLinks _SquadLinks; - - /// The guild or the tribe that control the outpost. Can be InvalidAllianceId if tribe alliance id not known yet. - TAllianceId _OwnerAllianceId; - - /// The guild that wants to control the outpost (if any). Can be InvalidAllianceId (peace time). - TAllianceId _AttackerAllianceId; - - /// current state of the outpost - OUTPOSTENUMS::TOutpostState _State; - - /// The tribe that controls this outpost when no guild owns it - std::string _Tribe; - - /// Name of the outpost - std::string _OutpostName; - - // Zone map to retrieve a spawn zone based on its name - typedef std::map > TZoneList; - TZoneList _ZoneList; - - /// The polygon surounding the outpost -// CShape _Shape; - NLMISC::CSmartPtr _Shape; -}; - -////////////////////////////////////////////////////////////////////////////// -// COutpostSquadFamily // -////////////////////////////////////////////////////////////////////////////// - -class COutpostSquadFamily -: public NLMISC::CDbgRefCount -, public NLMISC::CRefCount -, public CAliasChild -{ -public: - COutpostSquadFamily(CAIInstance* owner, uint32 alias, std::string const& name) - : CAliasChild(owner, alias, name) - { - } - virtual ~COutpostSquadFamily() - { - _GroupDescs.clear(); - } - - CAliasCont >& groupDescs() { return _GroupDescs; } - CAliasCont > const& groupDescs() const { return _GroupDescs; } - - virtual std::string getFullName() const; - virtual std::string getIndexString() const; - -//private: - IAliasCont *getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner *createChild(IAliasCont *cont, CAIAliasDescriptionNode *aliasTree); - -private: - /// These are only references to the group descs that are created when reading the squad template primitive - CAliasCont< CGroupDesc > _GroupDescs; -}; - -////////////////////////////////////////////////////////////////////////////// -// COutpostSpawnZone // -////////////////////////////////////////////////////////////////////////////// - -/// Zone for outpost activity -class COutpostSpawnZone -: public NLMISC::CDbgRefCount -, public CAIPlaceXYR -{ -public: - COutpostSpawnZone(COutpost* owner, CAIAliasDescriptionNode* adn); - ~COutpostSpawnZone(); - - virtual std::string getFullName() const; - virtual std::string getIndexString() const; -}; - -////////////////////////////////////////////////////////////////////////////// -// COutpostManager // -// This is a container of bot groups, // -// This is *not* a singleton manager as it is in the EGS. // -////////////////////////////////////////////////////////////////////////////// - -class COutpostManager -: public CMgrNpc -{ -public: - COutpostManager(COutpost* parent, uint32 alias, std::string const& name, std::string const& filename = std::string()); - virtual ~COutpostManager(); - - void update(); - - IAliasCont* getAliasCont(AITYPES::TAIType type); - CAliasTreeOwner* createChild(IAliasCont* cont, CAIAliasDescriptionNode* aliasTree); - virtual std::string getOneLineInfoString() const; - - /// Change the list of enemies of the squad (attackers of the outpost) - void setEnemies( TAllianceId attackerAllianceId ); - - CAIEvent EventOutpostPeaceStateEnd; - CAIEvent EventOutpostPeaceStateBegin; - CAIEvent EventOutpostTribeOwnershipBegin; - CAIEvent EventOutpostTribeOwnershipEnd; - CAIEvent EventOutpostGuildOwnershipBegin; - CAIEvent EventOutpostGuildOwnershipEnd; - CAIEvent EventOutpostOwnerChanged; - CAIEvent EventOutpostAttackerChanged; - CAIEvent EventOutpostStateChanged; - - virtual void registerEvents(); - virtual void unregisterEvents(); - - void setAutoSpawn(bool autoSpawn) { _AutoSpawn = autoSpawn; } - void autoSpawnBegin(); - void autoSpawnEnd(); - -private: - bool _AutoSpawn; -}; - -////////////////////////////////////////////////////////////////////////////// -// COutpostManager // -////////////////////////////////////////////////////////////////////////////// -/// This class derives from COutpostManager and adds a state machine for -/// squads. -class COutpostSquadManager -: public COutpostManager -{ -public: - COutpostSquadManager(COutpost* parent, uint32 alias, std::string const& name, std::string const& filename = std::string()); -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_outpost_actions.cpp b/code/ryzom/server/src/ai_service/ai_outpost_actions.cpp deleted file mode 100644 index 25513ea06..000000000 --- a/code/ryzom/server/src/ai_service/ai_outpost_actions.cpp +++ /dev/null @@ -1,825 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - - -//---------------------------------------------------------------------------- - -#include "stdpch.h" -#include "ais_actions.h" -#include "ai_outpost.h" -#include "continent.h" -#include "continent_inline.h" - - -using namespace NLMISC; -using namespace NLNET; -using namespace std; -using namespace CAISActionEnums; - - -extern CAIInstance *currentInstance; - -DEFINE_ACTION(ContextGlobal,SQD_TMPL) -{ - nlassertex(currentInstance != NULL, ("No AIInstance created !")); - CWorkPtr::aiInstance(currentInstance); - CAIInstance *aii = CWorkPtr::aiInstance(); - - CAIAliasDescriptionNode *aliasTree; - string filename; - if (!getArgs(args, name(), aliasTree, filename)) - return; - - CContextStack::setContext(ContextSquadTemplate); -} - -DEFINE_ACTION(ContextSquadTemplate,SQD_T_V) -{ - string templateName, variantTag; - if ( !getArgs(args, name(), templateName, variantTag)) - return; - - CAIInstance *aii = CWorkPtr::aiInstance(); - CWorkPtr::squadVariantName(templateName + ":" + variantTag); - - CContextStack::setContext(ContextSquadTemplateVariant); -} - -DEFINE_ACTION(ContextOutpostGroupDesc,IDTREE_F) -{ - // IDTREE "flat": instead of browsing nodes, we build tree from the argument vector - - if (!CWorkPtr::groupDesc()) - return; - - // read the bot sheet vector from the argument list - vector botSheets( args.size() ); - for ( uint i=0; i!=args.size(); ++i ) - { - args[i].get( botSheets[i] ); - - // Remove .creature suffix if present - string::size_type p = botSheets[i].find( ".creature" ); - if ( p != string::npos ) - botSheets[i].erase( p ); - } - if ( botSheets.empty() ) - { - OUTPOST_WRN( "No bot sheets specified in %s => no squad", CWorkPtr::groupDesc()->getFullName().c_str() ); - return; - } - - // build the bot nodes - CAliasTreeOwner *owner = dynamic_cast(CWorkPtr::groupDesc()); - if ( ! owner ) - { - OUTPOST_WRN( "Invalid squad group desc %s", CWorkPtr::groupDesc()->getFullName().c_str() ); - return; - } - - owner->pushCurrentOwnerList(); - for ( uint j=0; j!=botSheets.size(); ++j ) - { - CAliasTreeOwner* childOwner = NULL; - IAliasCont* cont = NULL; - - // we try to get a valid IAliasCont for this type - if ( ! owner->getCont( childOwner, cont, AITYPES::AITypeSquadTemplateMember ) ) - break; - - // create a bot desc object (with alias 0) - CAliasTreeOwner* child = NULL; - CSmartPtr fakeNode = new CAIAliasDescriptionNode( /*NLMISC::toString( "tm%u", j )*/botSheets[j], 0, AITYPES::AITypeSquadTemplateMember, NULL ); - child = childOwner->createChild( cont, fakeNode ); - if ( ! child ) - { - OUTPOST_WRN( "Can't create child %s of squad template variant %s", botSheets[j].c_str(), owner->getName().c_str() ); - } - else - { - CBotDesc* botDesc = dynamic_cast< CBotDesc* >(child); - nlassert( botDesc ); - botDesc->setSheet( botSheets[j] ); - botDesc->setUseSheetBotName(true); - } - } - owner->popCurrentOwnerList(); -} - -DEFINE_ACTION(ContextGlobal,OUTPOST) -{ - nlassertex(currentInstance != NULL, ("No AIInstance created !")); - CWorkPtr::aiInstance(currentInstance); - CAIInstance *aii = CWorkPtr::aiInstance(); - - CAIAliasDescriptionNode *aliasTree; - string contName, mapName, filename, familyName; - if (!getArgs(args, name(), aliasTree, contName, filename, familyName)) - return; - - if (!CWorkPtr::continent()) - return; - - // see whether the region is already created - COutpost *outpost = CWorkPtr::continent()->outposts().getChildByAlias(aliasTree->getAlias()); - - // not found so create it - if (!outpost) - { - outpost = new COutpost(CWorkPtr::continent(), aliasTree->getAlias(), aliasTree->getName(), filename); - - CWorkPtr::continent()->outposts().addAliasChild(outpost); - CWorkPtr::outpost(outpost); - } - else - { - outpost->registerForFile(filename); - } - - // set the owner tribe - CWorkPtr::outpost()->setTribe(familyName); - - CContextStack::setContext(ContextOutpost); - -} - -DEFINE_ACTION(ContextOutpost,OUTP_SQD) -{ - CAIInstance *aii = CWorkPtr::aiInstance(); - COutpost *outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - set squads; - string variantTag; - - // read the variant tag (first element of vector) - nlassert( ! args.empty() ); - args[0].get( variantTag ); - - // read the squads (skip first element of vector; avoid duplicates) - for ( uint i=1; i!=args.size(); ++i ) - { - string s; - args[i].get( s ); - squads.insert( s ); - } - - // link outpost to squads - for ( set::const_iterator its=squads.begin(); its!=squads.end(); ++its ) - { - string variantName = (*its); - if ( variantName.find( ':' ) == string::npos ) // the leveldesigner can specify which variant he wants - variantName += ":" + variantTag; - CGroupDesc *groupDesc = aii->getSquadByVariantName( variantName ); - if ( groupDesc ) - outpost->addSquadLink( groupDesc->getAlias(), groupDesc ); - else - OUTPOST_WRN( "Can't find squad %s for outpost %s", variantName.c_str(), outpost->getName().c_str() ); - } -} - -DEFINE_ACTION(ContextOutpost,IDTREE) -{ - // set the id tree for the region (results in creation or update of region's object tree) - // args: aliasTree - - if (!CWorkPtr::outpost()) - return; - - // read the alias tree from the argument list - CAIAliasDescriptionNode *aliasTree; - if (!getArgs(args, name(),aliasTree)) - return; - - - // have the manager update it's structure from the id tree - nlinfo("ACTION IDTREE: Applying new tree to outpost[%u]: '%s'%s in continent '%s'", - CWorkPtr::outpost()->getChildIndex(), - CWorkPtr::outpost()->getName().c_str(), - CWorkPtr::outpost()->getAliasString().c_str(), - CWorkPtr::outpost()->getOwner()->getName().c_str() - ); - - if (aliasTree && CWorkPtr::outpost()) - CWorkPtr::outpost()->updateAliasTree(*aliasTree); -} - -DEFINE_ACTION(ContextOutpost,OUTPOGEO) -{ - COutpost* outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - std::vector points; - for (uint i=0; i<(args.size()-1); i+=2) - { - double x, y; - args[i].get(x); - args[i+1].get(y); - points.push_back(CAIVector(x, y)); - } - NLMISC::CSmartPtr shape = NLMISC::CSmartPtr(new CAIPlaceOutpost(outpost)); - shape->setPatat(AITYPES::vp_auto, points); - shape->setOutpostAlias(outpost->getAlias()); - outpost->setShape(shape); -} - -DEFINE_ACTION(ContextOutpost,SPWNZONE) -{ - COutpost* outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - float x, y, r; - uint32 verticalPos; - // read the alias tree from the argument list - CAIAliasDescriptionNode* aliasTree; - if (!getArgs(args, name(), aliasTree, x, y, r, verticalPos)) - return; - - // see whether the region is already loaded - COutpostSpawnZone* spawnZone = outpost->spawnZones().getChildByAlias(aliasTree->getAlias()); - if (!spawnZone) - return; - - spawnZone->setPosAndRadius((AITYPES::TVerticalPos)verticalPos, CAIPos(x, y, 0, 0.f), uint32(r*1000)); -} - -DEFINE_ACTION(ContextOutpost,BUILDING) -{ -/****************************************************************************/ - /* - COutpost* outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - float x, y, theta; - uint32 verticalPos; - // read the alias tree from the argument list - CAIAliasDescriptionNode* aliasTree; - if (!getArgs(args, name(), aliasTree, x, y, theta, verticalPos)) - return; - - // see whether the region is already loaded - COutpostSpawnZone* spawnZone = outpost->spawnZones().getChildByAlias(aliasTree->getAlias()); - if (!spawnZone) - return; - - spawnZone->setPosAndRadius((AITYPES::TVerticalPos)verticalPos, CAIPos(x, y, 0, 0.f), uint32(r*1000)); - */ -/****************************************************************************/ - COutpost* outpost = CWorkPtr::outpost(); - if (!outpost) - return; - CGroup* grp = outpost->getBuildingGroup(); - if (!grp) - return; - - uint32 alias; - if (!getArgs(args, name(), alias)) - return; - -// LOG("Outpost Building: group: %s, bot: %u", grp->getFullName().c_str(), alias); - - // set workptr::bot to this bot - CWorkPtr::bot(grp->bots().getChildByAlias(alias)); //lookupBotInGrpNpc(alias)); - if (!CWorkPtr::botNpc()) - { - nlwarning("Failed to select bot %s as not found in group: %s", - LigoConfig.aliasToString(alias).c_str(), - CWorkPtr::grpNpc()->getName().c_str()); - return; - } - /* - if (!(CWorkPtr::botNpc()->getChat().isNull())) - { - CWorkPtr::botNpc()->getChat()->clearMissions(); - } - */ - // set workptr state to this state - CContextStack::setContext(ContextNpcBot); -} -/* -DEFINE_ACTION(ContextOutpost,PLACE) -{ - COutpost *outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - float x,y; - - if (!getArgs(args,name(), x, y)) - return; - - outpost->setPosition(CAIVector(x, y)); -} -*/ -/* -DEFINE_ACTION(ContextOutpost,CHARGE) -{ - COutpost *outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - // read the alias tree from the argument list - CAIAliasDescriptionNode *aliasTree; - string civilisation; - if (!getArgs(args, name(), aliasTree, civilisation)) - return; - - // see whether the outpost charge is already loaded - COutpostCharge *charge = outpost->charges().getChildByAlias(aliasTree->getAlias()); - if (!charge) - return; - - charge->setCivilisation(civilisation); - - CWorkPtr::outpostCharge(charge); - CContextStack::setContext(ContextOutpostCharge); -} -*/ -/* -DEFINE_ACTION(ContextOutpost,CHGPARM) -{ - COutpostCharge *charge = CWorkPtr::outpostCharge(); - if (!charge) - return; - - vector params; - for (uint i=0; args.size(); ++i) - { - string s; - args[i].get(s); - params.push_back(s); - } - - charge->setParams(params); -} -*/ -/*DEFINE_ACTION(ContextOutpost,SQUADFAM) -{ - COutpost *outpost = CWorkPtr::outpost(); - if (!outpost) - return; - - CAIAliasDescriptionNode *aliasTree; - if (!getArgs(args, name(), aliasTree)) - return; - - COutpostSquadFamily* squadFamily = outpost->squadFamilies().getChildByAlias(aliasTree->getAlias()); - if (!squadFamily) - return; - - CWorkPtr::outpostSquadFamily(squadFamily); - CContextStack::setContext(ContextOutpostSquadFamily); -}*/ - -static void DoMgrAction( - std::vector const& args, - AITYPES::TMgrType type, - CAISActionEnums::TContext context) -{ -// nlassertex(currentInstance != NULL, ("No AIInstance created !")); -// CAIInstance* aiInstance = currentInstance; -// CWorkPtr::aiInstance(aiInstance); // set the current AIInstance. - COutpost* outpost = CWorkPtr::outpost(); - - // get hold of the manager's slot id - note that managers are identified by slot and not by alias! - uint32 alias; - std::string name, mapName, filename; - bool manualSpawn = true; - if (type==AITYPES::MgrTypeOutpost) - { - if (!getArgs(args, "MANAGER", alias, name, mapName, filename, manualSpawn)) - return; - } - else - { - if (!getArgs(args, "MANAGER", alias, name, mapName, filename)) - return; - } - - // see whether the manager is already loaded - COutpostManager* mgr = static_cast(outpost->managers().getChildByAlias(alias)); - - // not found so look for a free slot - nlassert(mgr); -// outpost->newMgr(type, alias, name, mapName, filename); - mgr->registerForFile(filename); - mgr->setAutoSpawn(!manualSpawn); - - mgr = outpost->managers().getChildByAlias(alias); - - // setup the working manager pointer and exit - CWorkPtr::mgr(mgr); - if (mgr) - CWorkPtr::eventReactionContainer(mgr->getStateMachine()); - else - CWorkPtr::eventReactionContainer(NULL); - - // push the manager context onto the context stack - CContextStack::setContext(context); -} - - -DEFINE_ACTION(ContextOutpost,MGRNPC) -{ - DoMgrAction(args, AITYPES::MgrTypeNpc, CAISActionEnums::ContextNpcMgr); -} - -DEFINE_ACTION(ContextOutpost,MGROUTPO) -{ - DoMgrAction(args, AITYPES::MgrTypeOutpost, CAISActionEnums::ContextNpcMgr); -} - -/* -DEFINE_ACTION(ContextOutpostSquadFamily,IDTREE) -{ - // set the id tree for the region (results in creation or update of region's object tree) - // args: aliasTree - - if (!CWorkPtr::outpostSquadFamily()) - return; - - // read the alias tree from the argument list - CAIAliasDescriptionNode *aliasTree; - if (!getArgs(args, name(),aliasTree)) - return; - - - // have the manager update it's structure from the id tree - nlinfo("ACTION IDTREE: Applying new tree to outpost[%u]: '%s'%s in continent '%s'", - CWorkPtr::outpostSquadFamily()->getChildIndex(), - CWorkPtr::outpostSquadFamily()->getName().c_str(), - CWorkPtr::outpostSquadFamily()->getAliasString().c_str(), - CWorkPtr::outpostSquadFamily()->getOwner()->getName().c_str() - ); - - if (aliasTree && CWorkPtr::outpostSquadFamily()) - CWorkPtr::outpostSquadFamily()->updateAliasTree(*aliasTree); -} -*/ -DEFINE_ACTION(ContextSquadTemplateVariant,GRPTMPL) -{ - CAIInstance *aii = CWorkPtr::aiInstance(); - COutpostSquadFamily* const squadFamily = aii->getSquadFamily(); - if (!squadFamily) - return; - - string grpFamily; // Ignored - uint32 botCount; - bool countMultipliedBySheet; - bool multiLevel; - - // read the alias tree from the argument list - CAIAliasDescriptionNode* aliasTree; - if (!getArgs(args, name(), aliasTree, grpFamily, botCount, countMultipliedBySheet, multiLevel)) - return; - - IAliasCont *aliasCont = squadFamily->getAliasCont( AITYPES::AITypeGroupTemplate ); - CAliasTreeOwner *child = squadFamily->createChild( aliasCont, aliasTree ); - CGroupDesc *groupDesc = (dynamic_cast*>(child)); - if (!groupDesc) - return; - - aii->registerSquadVariant( CWorkPtr::squadVariantName(), groupDesc ); - CWorkPtr::groupDesc( groupDesc ); - - groupDesc->setBaseBotCount(botCount); - groupDesc->setCountMultiplierFlag(countMultipliedBySheet); - groupDesc->setMultiLevel(multiLevel); - - CContextStack::setContext(ContextOutpostGroupDesc); -} - -////////////////////////////////////////////////////////////////////////////// -// ContextGroupDesc actions instances // -////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////////////////////////////////////////////// -// ContextGroupDesc actions // -////////////////////////////////////////////////////////////////////////////// - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_SHEE,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - string lookSheet; - - if (!getArgs(args,name(), lookSheet)) - return; - - if (!groupDesc->setSheet(lookSheet)) - { - groupDesc->getOwner()->groupDescs().removeChildByIndex(groupDesc->getChildIndex()); - CWorkPtr::groupDesc(NULL); - return; - } -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_LVLD,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - sint32 levelDelta; - - if (!getArgs(args,name(), levelDelta)) - return; - - groupDesc->setLevelDelta(levelDelta); -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_SEAS,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - bool seasons[4]; - - if (!getArgs(args,name(), seasons[0], seasons[1], seasons[2], seasons[3])) - return; - - groupDesc->setSeasonFlags(seasons); -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_ACT,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - uint32 spawnType; - if (!getArgs(args, name(), spawnType)) - return; - - groupDesc->setSpawnType((AITYPES::TSpawnType)spawnType); -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_APRM,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - for (size_t i=0; iproperties().addProperty(AITYPES::CPropertyId::create(property)); - } -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_NRG,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - uint32 weight[4]; - - if (!getArgs(args,name(), weight[0], weight[1], weight[2], weight[3])) - return; - - groupDesc->setWeightLevels(weight); -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_EQUI,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - groupDesc->botEquipment().clear(); - - for (size_t i=0; ibotEquipment().push_back(equip); - } -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_GPRM,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - for (size_t i=0; iproperties().addProperty(param); - else // unreconized param, leace it for the group instance - groupDesc->grpParameters().push_back(param); - } -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,BOTTMPL,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - string lookSheet; - bool multiLevel; - - // read the alias tree from the argument list - CAIAliasDescriptionNode* aliasTree; - if (!getArgs(args, name(), aliasTree, lookSheet, multiLevel)) - return; - - // see whether the region is already loaded - CBotDesc* botDesc = groupDesc->botDescs().getChildByAlias(aliasTree->getAlias()); - if (!botDesc) - return; - - botDesc->setMultiLevel(multiLevel); - botDesc->setSheet(lookSheet); - - CWorkPtr::botDesc(botDesc); - CContextStack::setContext(ContextOutpostBotDesc); -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostBotDesc,BT_EQUI,FamilyT) -{ - CBotDesc* botDesc = static_cast*>(CWorkPtr::botDesc()); - if (!botDesc) - return; - - for (size_t i=0; iequipement().push_back(equip); - } -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostBotDesc,BT_LVLD,FamilyT) -{ - CBotDesc* botDesc = static_cast*>(CWorkPtr::botDesc()); - if (!botDesc) - return; - - sint32 levelDelta; - - if (!getArgs(args,name(), levelDelta)) - return; - - botDesc->setLevelDelta(levelDelta); -} - - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_GNRJ,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - uint32 energyValue; - - if (!getArgs(args,name(), energyValue)) - return; -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,POPVER,FamilyT) -{ - // add a population version for a group - // args: uint32 alias, string spawn_type, uint weight, (string sheet, uint32 count)+ - - if(!CWorkPtr::groupDesc()) - return; - - const uint32 fixedArgsCount = 0; - if (args.size()lookup(sheetId); - if (!sheetPtr) - { - nlwarning("POPVER Add Record Invalid sheet: %s", sheet.c_str()); - continue; - } - static_cast*>(CWorkPtr::groupDesc())->populationRecords().push_back(CPopulationRecord(sheetPtr, count)); - } - -} - -/// :KLUDGE: This code is copied from continent_inline.h. Update both if you -/// make a modification. -// scales bot energy .. to match with group's one. -DEFINE_ACTION_TEMPLATE1(ContextOutpostGroupDesc,GT_END,FamilyT) -{ - CGroupDesc* groupDesc = static_cast*>(CWorkPtr::groupDesc()); - if (!groupDesc) - return; - - if (!groupDesc->isMultiLevel()) - { - uint32 totalEnergyValue = groupDesc->calcTotalEnergyValue(); - if (totalEnergyValue) - { - double coef = (double)groupDesc->groupEnergyValue()/(double)totalEnergyValue; - groupDesc->setGroupEnergyCoef((float)coef); - } - else - { - nlwarning("exists some empty template groups"); - } - } -} - -// O for outpost -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_SHEE,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_LVLD,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_SEAS,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_ACT, O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_APRM,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_NRG, O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_EQUI,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_GPRM,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,BOTTMPL,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostBotDesc,BT_EQUI,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostBotDesc,BT_LVLD,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_GNRJ,O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,POPVER, O,COutpostSquadFamily); -DEFINE_ACTION_TEMPLATE1_INSTANCE(ContextOutpostGroupDesc,GT_END, O,COutpostSquadFamily); - diff --git a/code/ryzom/server/src/ai_service/ai_place.cpp b/code/ryzom/server/src/ai_service/ai_place.cpp deleted file mode 100644 index e000fc4d5..000000000 --- a/code/ryzom/server/src/ai_service/ai_place.cpp +++ /dev/null @@ -1,429 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - -#include "stdpch.h" -#include "ai_place.h" -#include "ai_place_xyr.h" -#include "ai_place_patat.h" -#include "ai_instance.h" -#include "ai_grp_fauna.h" // TODO nico : try to get rid of that dependency - -////////////////////////////////////////////////////////////////////////////// -// CAIPlace // -////////////////////////////////////////////////////////////////////////////// - -std::string CAIPlace::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":%u", getChildIndex()); -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYR // -////////////////////////////////////////////////////////////////////////////// - -bool CAIPlaceXYR::atPlace(CAIEntityPhysical const* entity) const -{ - return atPlace(entity->pos()); -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYRFauna // -////////////////////////////////////////////////////////////////////////////// -std::string CAIPlaceXYRFauna::getOneLineInfoString() const -{ - std::string result = NLMISC::toString("Name = %s; Active : %s, index = %d ", getFullName().c_str(), getActive() ? "on" : "off", (int) getIndex()); - if (getFlag(FLAG_SPAWN)) result +="spawn "; - if (getFlag(FLAG_EAT)) result +="food "; - if (getFlag(FLAG_REST)) result +="rest "; - if (getTimeDriven()) result += NLMISC::toString(" TIME_DRIVEN : days=%s; time=%s", getDayInterval().c_str(), getTimeInterval().c_str()); - return result; -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceFastXYR // -////////////////////////////////////////////////////////////////////////////// - -bool CAIPlaceFastXYR::atPlace(CAIEntityPhysical const* entity) const -{ - return atPlace(entity->pos()); -} - -void CAIPlaceFastXYR::display(CStringWriter& stringWriter) const -{ - stringWriter.append("XYR: ("+_Pos.x().toString() - +" " - +_Pos.y().toString() - +" "+NLMISC::toString(_Pos.h()) - +") Radius " - +NLMISC::toString(_Radius) - +" " - +getName()); -} - -uint CFaunaGenericPlace::setupFromOldName(const std::string &name) -{ - uint32 stayTime; - uint placeIndex = std::numeric_limits::max(); - // depending on place name setup eat/ rest/ sleep pointers - if (NLMISC::nlstricmp(name,"spawn")==0) - { - placeIndex = CGrpFauna::SPAWN_PLACE; - setIndex(0); - setReachNext(true); - setFlag(FLAG_SPAWN, true); - stayTime = CGrpFauna::refTimer(CGrpFauna::CORPSE_TIME); - } - else - if (NLMISC::nlstricmp(name,"food")==0) - { - placeIndex = CGrpFauna::EAT_PLACE; - setIndex(1); - setReachNext(true); - setFlag(FLAG_EAT, true); - stayTime = CGrpFauna::refTimer(CGrpFauna::EAT_TIME); - } - else - if (NLMISC::nlstricmp(name,"rest")==0) - { - placeIndex = CGrpFauna::REST_PLACE; - setIndex(2); - std::vector arcs(1); - arcs[0] = 1; // can reach place 1 from place 2 - setArcs(arcs); - setFlag(FLAG_REST, true); - stayTime = CGrpFauna::refTimer(CGrpFauna::REST_TIME); - } - else - { - nlwarning("Unknown fauna place type"); - nlassert(0); - } - stayTime *= FAUNA_BEHAVIOR_GLOBAL_SCALE; - setMinStayTime(stayTime); - setMaxStayTime(stayTime); - return placeIndex; -} - -bool CFaunaGenericPlace::getActive() const -{ - if (!_TimeDriven) return _Active; - // NB : INDICES FOR DAYS are expected to start at 1!! - extern bool FAUNA_GRAPH_USES_DEBUG_TIME; - const CRyzomTime &rt = FAUNA_GRAPH_USES_DEBUG_TIME ? CTimeInterface::getRyzomDebugTime() : CTimeInterface::getRyzomTime(); - std::vector dayIntervals; - NLMISC::explode(_DayInterval, std::string(","), dayIntervals, true); - std::string season = EGSPD::CSeason::toString(rt.getRyzomSeason()); - std::string month = MONTH::toString((MONTH::EMonth) rt.getRyzomMonth()); - std::string weekday = WEEKDAY::toString((WEEKDAY::EWeekDay) rt.getRyzomDay()); - bool found = false; - for (uint k = 0; k < dayIntervals.size(); ++k) - { - bool goodToken = false; - if (NLMISC::nlstricmp(dayIntervals[k], "always") == 0) - { - found = true; - break; - } - if (NLMISC::nlstricmp(dayIntervals[k], season) == 0) - { - found = true; - break; - } - if (EGSPD::CSeason::fromString(season) != EGSPD::CSeason::Unknown) - { - goodToken = true; - } - if (NLMISC::nlstricmp(dayIntervals[k], month) == 0) - { - found = true; - break; - } - if (MONTH::toMonth(dayIntervals[k]) != MONTH::UNKNOWN) - { - goodToken = true; - } - if (NLMISC::nlstricmp(dayIntervals[k], weekday) == 0) - { - found = true; - break; - } - if (WEEKDAY::toWeekDay(dayIntervals[k]) != WEEKDAY::UNKNOWN) - { - goodToken = true; - } - // see if this is a n interval - int startDay, endDay; - if (sscanf(dayIntervals[k].c_str(), "%d-%d", &startDay, &endDay) == 2) - { - goodToken = true; - if ((int) (rt.getRyzomDay() + 1) >= startDay && (int) (rt.getRyzomDay() + 1) <= endDay) - { - found = true; - break; - } - } - // see if this is a single day - int day; - if (sscanf(dayIntervals[k].c_str(), "%d", &day) == 1) - { - goodToken = true; - if ((int) (rt.getRyzomDay() + 1) == day) - { - found = true; - break; - } - } - if (!goodToken) - { - nlwarning("Unknwon time interval token : %s", dayIntervals[k].c_str()); - } - } - if (!found) return false; - // test against time interval - // If no interval is given then assume whole day - if (_TimeInterval.empty()) return true; - std::vector timeIntervals; - NLMISC::explode(_TimeInterval, std::string(","), timeIntervals, true); - for (uint k = 0; k < dayIntervals.size(); ++k) - { - uint startHour, endHour; - if (sscanf(timeIntervals[k].c_str(), "%d-%d", &startHour, &endHour) == 2) - { - if (startHour > endHour) - { - // reversed interval - if (rt.getRyzomTime() >= startHour || rt.getRyzomTime() <= endHour) - { - return true; - } - } - else - { - if (rt.getRyzomTime() >= startHour && rt.getRyzomTime() <= endHour) - { - return true; - } - } - } - else - { - nlwarning("Unknwon time interval token : %s", timeIntervals[k].c_str()); - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceShape // -////////////////////////////////////////////////////////////////////////////// - -CAIPlaceShape::CAIPlaceShape(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription, bool warnOnInvalidPosition) -: CAIPlace(owner, aliasDescription), _Shape(!warnOnInvalidPosition) -{ - _Shape.calcRandomPos(_MidPos); - CWorldContainer::getWorldMap().setWorldPosition(AITYPES::vp_auto, _WorldValidPos, _MidPos); - _Shape.calcRandomPos(_MidPos); -} - -bool CAIPlaceShape::atPlace(CAIVector const& pos) const -{ - return _Shape.contains(pos); -} - -bool CAIPlaceShape::atPlace(const CAIVectorMirror &pos) const -{ - return _Shape.contains(pos); -} - -bool CAIPlaceShape::atPlace(CAIEntityPhysical const* entity) const -{ - return atPlace(entity->pos()); -} - -CAIPos const& CAIPlaceShape::midPos() const -{ - return _MidPos; -} - -RYAI_MAP_CRUNCH::CWorldPosition const& CAIPlaceShape::worldValidPos() const -{ - return _WorldValidPos; -} - -float CAIPlaceShape::getRadius() const -{ - // :TODO: Compute a real radius here. - return 20.f; -} - -AITYPES::TVerticalPos CAIPlaceShape::getVerticalPos() const -{ - return _Shape.getVerticalPos(); -} - -void CAIPlaceShape::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const -{ - CAIPos aiPos; - _Shape.calcRandomPos(aiPos); - CWorldContainer::getWorldMap().setWorldPosition(AITYPES::vp_auto, pos, aiPos); -} - -bool CAIPlaceShape::calcRandomPos(CAIPos& pos) const -{ - return _Shape.calcRandomPos(pos); -} - -bool CAIPlaceShape::setPatat(AITYPES::TVerticalPos verticalPos, std::vector const& points) -{ - return _Shape.setPatat(verticalPos, points); -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceIntersect // -////////////////////////////////////////////////////////////////////////////// - -CAIPlaceIntersect::CAIPlaceIntersect(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription) -: CAIPlace(owner, aliasDescription) -{ -} - -bool CAIPlaceIntersect::atPlace(CAIVector const& pos) const -{ - if (_Place1 && _Place2) - return _Place1->atPlace(pos) && _Place2->atPlace(pos); - if (_Place1) - return _Place1->atPlace(pos); - if (_Place2) - return _Place2->atPlace(pos); - return false; -} - -bool CAIPlaceIntersect::atPlace(const CAIVectorMirror &pos) const -{ - if (_Place1 && _Place2) - return _Place1->atPlace(pos) && _Place2->atPlace(pos); - if (_Place1) - return _Place1->atPlace(pos); - if (_Place2) - return _Place2->atPlace(pos); - return true; -} - -bool CAIPlaceIntersect::atPlace(CAIEntityPhysical const* pos) const -{ - if (_Place1 && _Place2) - return _Place1->atPlace(pos) && _Place2->atPlace(pos); - if (_Place1) - return _Place1->atPlace(pos); - if (_Place2) - return _Place2->atPlace(pos); - return true; -} - -CAIPos const& CAIPlaceIntersect::midPos() const -{ - nlassert(_Place1 || _Place2); - if (_Place1) - return _Place1->midPos(); - if (_Place2) - return _Place2->midPos(); - return _DummyMidPos; -} - -RYAI_MAP_CRUNCH::CWorldPosition const& CAIPlaceIntersect::worldValidPos() const -{ - nlassert(_Place1 || _Place2); - if (_Place1) - return _Place1->worldValidPos(); - if (_Place2) - return _Place2->worldValidPos(); - return _DummyValidPos; -} - -float CAIPlaceIntersect::getRadius() const -{ - nlassert(_Place1 || _Place2); - if (_Place1) - return _Place1->getRadius(); - if (_Place2) - return _Place2->getRadius(); - return 0.f; -} - -AITYPES::TVerticalPos CAIPlaceIntersect::getVerticalPos() const -{ - nlassert(_Place1 || _Place2); - if (_Place1) - return _Place1->getVerticalPos(); - if (_Place2) - return _Place2->getVerticalPos(); - return AITYPES::vp_auto; -} - -void CAIPlaceIntersect::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const -{ - nlassert(_Place1 || _Place2); - if (_Place1) - _Place1->getRandomPos(pos); - if (_Place2) - _Place2->getRandomPos(pos); -} - -bool CAIPlaceIntersect::calcRandomPos(CAIPos& pos) const -{ -// if (_Place1 && _Place1->calcRandomPos(pos)) -// return true; -// if (_Place2 && _Place2->calcRandomPos(pos)) -// return true; - return false; -} - -void CAIPlaceIntersect::setPlace1(NLMISC::CSmartPtr const& place) -{ - _Place1 = place; -} - -void CAIPlaceIntersect::setPlace2(NLMISC::CSmartPtr const& place) -{ - _Place2 = place; -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceOutpost // -////////////////////////////////////////////////////////////////////////////// - -CAIPlaceOutpost::CAIPlaceOutpost(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription) -: CAIPlaceShape(owner, aliasDescription,false) -, _OutpostAlias(0) -{ -} - -bool CAIPlaceOutpost::atPlace(CAIEntityPhysical const* entity) const -{ - if (_OutpostAlias!=0) - { - CMirrorPropValueRO entityInOutpostAlias(TheDataset, entity->dataSetRow(), DSPropertyIN_OUTPOST_ZONE_ALIAS); - return (entityInOutpostAlias == _OutpostAlias); - } - return CAIPlaceShape::atPlace(entity); -} - -void CAIPlaceOutpost::setOutpostAlias(uint32 outpostAlias) -{ - _OutpostAlias = outpostAlias; -} - diff --git a/code/ryzom/server/src/ai_service/ai_place.h b/code/ryzom/server/src/ai_service/ai_place.h deleted file mode 100644 index 593cd1c11..000000000 --- a/code/ryzom/server/src/ai_service/ai_place.h +++ /dev/null @@ -1,176 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//class CAIPlace; - -#ifndef RYAI_PLACE_H -#define RYAI_PLACE_H - -#include "nel/misc/variable.h" -#include "ai_route.h" -#include "ai_share/world_map.h" -#include "world_container.h" -#include "ai.h" - -class CPlaceOwner; - -// come from config file -//extern uint32 RandomPosMaxRetry; -extern NLMISC::CVariable RandomPosMaxRetry; -//extern bool LogAcceptablePos; -extern NLMISC::CVariable LogAcceptablePos; - -const uint32 MAX_PLACE_RANDOM_POS = 64; - -/** Base class for random generated pos inside a place. - * NB : this class as no idea of the place geometry it - * only store random valid position. - */ -class CPlaceRandomPos - :public NLMISC::CDbgRefCount -{ -public: - - CPlaceRandomPos() - { - _MaxPlacesFound = 0; - _VerticalPos = AITYPES::vp_auto; - } - - void setVerticalPos(AITYPES::TVerticalPos verticalPos) - { - _VerticalPos = verticalPos; - } - - AITYPES::TVerticalPos getVerticalPos() const - { - return _VerticalPos; - } - - - uint getRandomPosCount() const - { - return _MaxPlacesFound; - } - - // return a random position within the place - void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const - { -#ifdef NL_DEBUG - nlassert(_MaxPlacesFound>0); -#endif - pos=_PosList[CAIS::rand16(_MaxPlacesFound)]; - } - - void buildRandomPos(const RYAI_MAP_CRUNCH::CWorldPosition &validPos, float radius) - { - _MaxPlacesFound = 0; - - RYAI_MAP_CRUNCH::CWorldPosition worldValidPos; - - if (!CWorldContainer::calcNearestWPosFromPosAnRadius (_VerticalPos, worldValidPos, validPos, radius, 1000, CWorldContainer::CPosValidatorDefault())) - { - if (LogAcceptablePos) - nlwarning("Unvalid place (no collision free position found) at %d %d", validPos.toAIVector().x().asInt(), validPos.toAIVector().y().asInt()); - } - - uint maxTries= RandomPosMaxRetry; - nlassert(MAX_PLACE_RANDOM_POS>0); - _MaxPlacesFound = 0; - _PosList[_MaxPlacesFound] = worldValidPos; - _MaxPlacesFound++; - - while (_MaxPlacesFound, - public CAliasChild, - public virtual NLMISC::CVirtualRefCount -{ -public: - // ctor & dtor - CAIPlace(CPlaceOwner* owner, CAIAliasDescriptionNode *aliasDescription) - : CAliasChild(owner,aliasDescription) - { - } - - virtual ~CAIPlace() - { - } - - std::string getIndexString() const; - - /// @name Abstract interface - //@{ - /// Test whether a position is 'at the place' - virtual bool atPlace(const CAIVector &pos) const = 0; - /// Test whether a position is 'at the place' - virtual bool atPlace(const CAIVectorMirror &pos) const = 0; - /// Test whether an entity is 'at the place' - virtual bool atPlace(CAIEntityPhysical const* entity) const = 0; - /// Return the position of the middle of the place - virtual const CAIPos &midPos() const = 0; - - /// Return a valid world position in the place. - virtual const RYAI_MAP_CRUNCH::CWorldPosition &worldValidPos() const = 0; - - /// Return the outer radius of the place - virtual float getRadius() const = 0; - - virtual void display(CStringWriter &stringWriter) const = 0; - - virtual AITYPES::TVerticalPos getVerticalPos() const = 0; - virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition &pos) const = 0; - //@} - - virtual std::string getOneLineInfoString() const { return ""; } -}; - - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_place_patat.h b/code/ryzom/server/src/ai_service/ai_place_patat.h deleted file mode 100644 index 64f5a21be..000000000 --- a/code/ryzom/server/src/ai_service/ai_place_patat.h +++ /dev/null @@ -1,145 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_PLACE_SHAPE_H -#define RYAI_PLACE_SHAPE_H - -#include "nel/misc/types_nl.h" -#include "ai_place.h" -#include "states.h" - -//#include "ai_place.h" -//#include "ai.h" -//#include "world_container.h" -//#include "nel/misc/variable.h" - -// used to allow object to handle places. -/* -class CPlaceOwner -{ -public: - virtual std::string getFullName() const = 0; - virtual std::string getIndexString() const = 0; -}; -*/ - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceShape // -////////////////////////////////////////////////////////////////////////////// - -/// This class implements places defined by a shape -class CAIPlaceShape -: public CAIPlace -, public CPlaceRandomPos -{ -public: - CAIPlaceShape(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL, bool warnOnInvalidPosition=false); - - /// @name CAIPlace implementation - //@{ - virtual bool atPlace(CAIVector const& pos) const; - virtual bool atPlace(const CAIVectorMirror &pos) const; - virtual bool atPlace(CAIEntityPhysical const* entity) const; - virtual CAIPos const& midPos() const; - virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const; - virtual float getRadius() const; - virtual void display(CStringWriter& stringWriter) const { } - virtual AITYPES::TVerticalPos getVerticalPos() const; - virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const; - //@} - - /// @name CPlaceRandomPos implementation - //@{ - virtual bool calcRandomPos(CAIPos& pos) const; - //@} - - bool setPatat(AITYPES::TVerticalPos verticalPos, std::vector const& points); - -private: - RYAI_MAP_CRUNCH::CWorldPosition _WorldValidPos; - CAIPos _MidPos; - - CShape _Shape; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceShape // -////////////////////////////////////////////////////////////////////////////// - -/// This class implements places defined by an outpost (it takes into account delays) -class CAIPlaceOutpost -: public CAIPlaceShape -{ -public: - CAIPlaceOutpost(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL); - - /// @name CAIPlace implementation - //@{ - virtual bool atPlace(CAIEntityPhysical const* entity) const; - //@} - - void setOutpostAlias(uint32 outpostAlias); - -private: - uint32 _OutpostAlias; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceIntersect // -////////////////////////////////////////////////////////////////////////////// - -// :KLUDGE: Intersection is not respected for some methods (and anyway a NULL -// intersection is theorically possible, although empty place is not allowed -// by CAIPlace interface specification. -class CAIPlaceIntersect -: public CAIPlace -, public CPlaceRandomPos -{ -public: - CAIPlaceIntersect(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL); - - /// @name CAIPlace implementation - //@{ - virtual bool atPlace(CAIVector const& pos) const; - virtual bool atPlace(const CAIVectorMirror &pos) const; - virtual bool atPlace(CAIEntityPhysical const* entity) const; - virtual CAIPos const& midPos() const; - virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const; - virtual float getRadius() const; - virtual void display(CStringWriter& stringWriter) const { } - virtual AITYPES::TVerticalPos getVerticalPos() const; - virtual void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const; - //@} - - /// @name CPlaceRandomPos implementation - //@{ - virtual bool calcRandomPos(CAIPos& pos) const; - //@} - - void setPlace1(NLMISC::CSmartPtr const& place); - void setPlace2(NLMISC::CSmartPtr const& place); - -private: - NLMISC::CSmartPtr _Place1; - NLMISC::CSmartPtr _Place2; - // :TODO: Make _DummyMidPos and _DummyValidPos static as soon as there's a cpp file for this class. - /*static */CAIPos _DummyMidPos; - /*static */RYAI_MAP_CRUNCH::CWorldPosition _DummyValidPos; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_place_xyr.h b/code/ryzom/server/src/ai_service/ai_place_xyr.h deleted file mode 100644 index 10200599e..000000000 --- a/code/ryzom/server/src/ai_service/ai_place_xyr.h +++ /dev/null @@ -1,412 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_PLACE_XYR_H -#define RYAI_PLACE_XYR_H - -#include "ai_place.h" -#include "ai.h" -#include "world_container.h" -#include "nel/misc/variable.h" - -extern NLMISC::CVariable LogAcceptablePos; - - -// used to allow object to handle places. -class CPlaceOwner -{ -public: - virtual std::string getFullName() const = 0; - virtual std::string getIndexString() const = 0; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYR // -////////////////////////////////////////////////////////////////////////////// - -/// This class implements places defined by a point and radius -class CAIPlaceXYR -: public CAIPlace -, public CPlaceRandomPos -{ -public: - CAIPlaceXYR(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL); - - /// @name CAIPlace implementation - //@{ - virtual bool atPlace(CAIVector const& pos) const; - virtual bool atPlace(CAIVectorMirror const& pos) const; - virtual bool atPlace(CAIEntityPhysical const* entity) const; - virtual CAIPos const& midPos() const { return _pos; } - - virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const { return _worldValidPos; } - - virtual float getRadius() const { return _radius; } - - virtual void display(CStringWriter& stringWriter) const; - - AITYPES::TVerticalPos getVerticalPos() const; - void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const; - //@} - - /// radius in mm - void setPosAndRadius(AITYPES::TVerticalPos verticalPos, CAIPos const& pos, uint32 radius); - - CAIPlaceXYR& operator =(CAIPlaceXYR const& other); - - std::string getFullName() const { return std::string(getOwner()->getFullName() +":"+ getName()); } - -private: - bool calcRandomPos(CAIPos& pos) const; - - RYAI_MAP_CRUNCH::CWorldPosition _worldValidPos; - CAIPos _pos; - float _radius; -}; - -// base class for fauna places -class CFaunaGenericPlace -{ -public: - enum - { - INVALID_PLACE = INT_MAX - }; - enum TFlag - { - FLAG_SPAWN = 0, - FLAG_EAT, - FLAG_REST, - FLAG_COUNT - }; - // ctor - CFaunaGenericPlace(); - // activities flags - void setFlag(TFlag flag, bool on) { nlassert(flag < FLAG_COUNT); _Flags[flag] = on; } - bool getFlag(TFlag flag) const { nlassert(flag < FLAG_COUNT); return _Flags[flag]; } - void setMinStayTime(uint32 numTicks) { _MinStayTime = numTicks; } - void setMaxStayTime(uint32 numTicks) { _MaxStayTime = numTicks; } - uint32 getMinStayTime() const { return _MinStayTime; } - uint32 getMaxStayTime() const { return _MaxStayTime; } - // index in graph - void setIndex(sint32 index) { _Index = index; } - sint32 getIndex() const { return _Index; } - void setArcs(const std::vector &arcs) { _Arcs = arcs; } - const std::vector &getArcs() const { return _Arcs; } - void setReachNext(bool enabled) { _ReachNext = enabled; } - bool getReachNext() const { return _ReachNext; } - void setActive(bool active) { nlassert(!_TimeDriven); _Active = active; } - // See if that place is active in the fauna graph - // If place is season driven then current time is tested against valid interval - // to see if the place is activated. - // Otherwise the 'active' field is returns - bool getActive() const; - void setTimeDriven(bool timeDriven) { _TimeDriven = timeDriven; } - bool getTimeDriven() const { return _TimeDriven; } - // - void setDayInterval(const std::string &dayInterval) { _DayInterval = dayInterval; } - const std::string &getDayInterval() const { return _DayInterval; } - void setTimeInterval(const std::string &TimeInterval) { _TimeInterval = TimeInterval; } - const std::string &getTimeInterval() const { return _TimeInterval; } - // backward compatibility : setup parameter from the zone name ("spawn, food, or rest") - uint setupFromOldName(const std::string &name); - // -private: - bool _Active; - bool _TimeDriven; - std::string _TimeInterval; - std::string _DayInterval; - bool _Flags[FLAG_COUNT]; - uint32 _MinStayTime; // min stay time in this place (in ticks) - uint32 _MaxStayTime; // man stay time in this place (in ticks) - sint32 _Index; - std::vector _Arcs; - bool _ReachNext; // if arcs where not given, say if next greater index is reachable -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYRFauna // -////////////////////////////////////////////////////////////////////////////// -class CAIPlaceXYRFauna : public CAIPlaceXYR, - public CFaunaGenericPlace -{ -public: - CAIPlaceXYRFauna(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL); - virtual std::string getOneLineInfoString() const; - std::string getFullName() const { return std::string(getOwner()->getFullName() +":"+ getName()); } -}; - - - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceFastXYR // -////////////////////////////////////////////////////////////////////////////// - -/// This class implements places defined by a point and radius -class CAIPlaceFastXYR -: public CAIPlace -//, public CPlaceRandomPos -{ -public: - CAIPlaceFastXYR(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription = NULL); - - /// @name CAIPlace implementation - //@{ - virtual bool atPlace(CAIVector const& pos) const; - virtual bool atPlace(CAIVectorMirror const& pos) const; - virtual bool atPlace(CAIEntityPhysical const* entity) const; - virtual CAIPos const& midPos() const { return _Pos; } - - virtual RYAI_MAP_CRUNCH::CWorldPosition const& worldValidPos() const; - - virtual float getRadius() const { return _Radius; } - - virtual void display(CStringWriter& stringWriter) const; - - AITYPES::TVerticalPos getVerticalPos() const; - void getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const; - //@} - - /// radius in mm - void setPosAndRadius(AITYPES::TVerticalPos verticalPos, CAIPos const& pos, uint32 radius); - - CAIPlaceFastXYR& operator =(CAIPlaceFastXYR const& other); - -private: - bool calcRandomPos(CAIPos& pos) const; - - CAIPos _Pos; - AITYPES::TVerticalPos _VerticalPos; - float _Radius; - - mutable bool _WorldPosInitialized; - mutable RYAI_MAP_CRUNCH::CWorldPosition _WorldValidPos; -}; - -/****************************************************************************/ -/* Inlined methods */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYR // -////////////////////////////////////////////////////////////////////////////// - -inline -CAIPlaceXYR::CAIPlaceXYR(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription) -: CAIPlace(owner, aliasDescription) -{ -} - -inline -bool CAIPlaceXYR::atPlace(CAIVector const& pos) const -{ - return (pos-_pos).sqrnorm() <= ((double)_radius*(double)_radius); -} - -inline -bool CAIPlaceXYR::atPlace(CAIVectorMirror const& pos) const -{ - return (pos-_pos).sqrnorm() <= ((double)_radius*(double)_radius); -} - -inline -void CAIPlaceXYR::setPosAndRadius(AITYPES::TVerticalPos verticalPos, CAIPos const& pos, uint32 radius) -{ - _VerticalPos = verticalPos; - _pos = pos; - _radius = float(radius)/1000.0f; -#ifdef NL_DEBUG - nlassert(_radius > 0); - nlassert(pos.x()!=0||pos.y()!=0); -#endif - if (pos.x()==0 && pos.y()==0) - { - nlwarning("Null place Position for %s", getAliasFullName().c_str()); - } - - if (!CWorldContainer::calcNearestWPosFromPosAnRadius(_VerticalPos, _worldValidPos, _pos, _radius, 1000, CWorldContainer::CPosValidatorDefault())) - { - if (LogAcceptablePos) - nlwarning("Unvalid place (no collision free position found) at %d %d ", _pos.x().asInt(), _pos.y().asInt()); - } - - buildRandomPos(_worldValidPos, _radius); -} - -inline -CAIPlaceXYR& CAIPlaceXYR::operator =(CAIPlaceXYR const& other) -{ - _worldValidPos = other._worldValidPos; - _pos = other._pos; - _radius = other._radius; - - CPlaceRandomPos::operator =(other); - return *this; -} - -inline -AITYPES::TVerticalPos CAIPlaceXYR::getVerticalPos() const -{ - return CPlaceRandomPos::getVerticalPos(); -} - -inline -void CAIPlaceXYR::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& pos) const -{ - CPlaceRandomPos::getRandomPos(pos); -} - -inline -bool CAIPlaceXYR::calcRandomPos(CAIPos& pos) const -{ - double dx, dy; - double const r = (double)_radius; - double const rSquare = r * r; - do - { - dx = CAIS::frandPlusMinus(r); - dy = CAIS::frandPlusMinus(r); - } - while (dx*dx+dy*dy > rSquare); - - pos.setX(_pos.x()+dx); - pos.setY(_pos.y()+dy); - pos.setH(_pos.h()); - pos.setTheta(pos.angleTo(_pos)+CAngle(NLMISC::Pi/2)); - - return true; -} - - -//////////////////////// -// CFaunaGenericPlace // -//////////////////////// -inline -CFaunaGenericPlace::CFaunaGenericPlace() -{ - - _ReachNext = false; - _Index = 0; - _MinStayTime = _MaxStayTime = 100; - std::fill(_Flags, _Flags + FLAG_COUNT, false); - _Active = true; - _TimeDriven = false; -} - - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceXYRFauna // -////////////////////////////////////////////////////////////////////////////// - -inline -CAIPlaceXYRFauna::CAIPlaceXYRFauna(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription) -: CAIPlaceXYR(owner, aliasDescription) -{ -} - - -////////////////////////////////////////////////////////////////////////////// -// CAIPlaceFastXYR // -////////////////////////////////////////////////////////////////////////////// - -inline -CAIPlaceFastXYR::CAIPlaceFastXYR(CPlaceOwner* owner, CAIAliasDescriptionNode* aliasDescription) -: CAIPlace(owner, aliasDescription) -{ -} - -inline -bool CAIPlaceFastXYR::atPlace(CAIVector const& pos) const -{ - return (float)((pos-_Pos).sqrnorm()) <= (_Radius*_Radius); -} - -inline -bool CAIPlaceFastXYR::atPlace(CAIVectorMirror const& pos) const -{ - return (float)((pos-_Pos).sqrnorm()) <= ((double)_Radius*(double)_Radius); -} - -inline -void CAIPlaceFastXYR::setPosAndRadius(AITYPES::TVerticalPos verticalPos, CAIPos const& pos, uint32 radius) -{ -#ifdef NL_DEBUG - nlassert(radius > 0); - nlassert(pos.x()!=0||pos.y()!=0); -#endif - _VerticalPos = verticalPos; - _Pos = pos; - _Radius = (float)radius / 1000.0f; -} - -inline -CAIPlaceFastXYR& CAIPlaceFastXYR::operator =(CAIPlaceFastXYR const& other) -{ - _VerticalPos = other._VerticalPos; - _Pos = other._Pos; - _Radius = other._Radius; - - return *this; -} - -inline -AITYPES::TVerticalPos CAIPlaceFastXYR::getVerticalPos() const -{ - return _VerticalPos; -} - -inline -void CAIPlaceFastXYR::getRandomPos(RYAI_MAP_CRUNCH::CWorldPosition& wpos) const -{ - CAIPos pos; - if (calcRandomPos(pos)) - { - CWorldContainer::getWorldMap().setWorldPosition(_VerticalPos, wpos, pos); - } -} - -inline -bool CAIPlaceFastXYR::calcRandomPos(CAIPos& pos) const -{ - double dx, dy; - double const r = (double)_Radius; - double const rSquare = r * r; - do - { - dx = CAIS::frandPlusMinus(r); - dy = CAIS::frandPlusMinus(r); - } - while (dx*dx+dy*dy > rSquare); - - pos.setX(_Pos.x()+dx); - pos.setY(_Pos.y()+dy); - pos.setH(_Pos.h()); - pos.setTheta(pos.angleTo(_Pos)+CAngle(NLMISC::Pi/2)); - - return true; -} - -inline -RYAI_MAP_CRUNCH::CWorldPosition const& CAIPlaceFastXYR::worldValidPos() const -{ - if (!_WorldPosInitialized) - _WorldPosInitialized = CWorldContainer::getWorldMap().setWorldPosition(_VerticalPos, _WorldValidPos, _Pos); - return _WorldValidPos; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_player.cpp b/code/ryzom/server/src/ai_service/ai_player.cpp deleted file mode 100644 index 3870cfa60..000000000 --- a/code/ryzom/server/src/ai_service/ai_player.cpp +++ /dev/null @@ -1,465 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "ai_player.h" -#include "ai_bot_fauna.h" -#include "ai_bot_npc.h" - -using namespace MULTI_LINE_FORMATER; - - -////////////////////////////////////////////////////////////////////////////// -// CBotPlayer // -////////////////////////////////////////////////////////////////////////////// - -CBotPlayer::CBotPlayer(CManagerPlayer* owner, TDataSetRow const& DataSetRow, NLMISC::CEntityId const& id, uint32 level) -: CChild(owner) -, CAIEntityPhysical(static_cast(*this), DataSetRow, id, 0.5f, level, RYAI_MAP_CRUNCH::Nothing) -, _CurrentTeamId(CTEAM::InvalidTeamId) -, _FollowMode(false) -, _Aggroable(true) -{ -#ifdef NL_DEBUG - nlassert(owner->playerList().find(dataSetRow())==owner->playerList().end()); -#endif - owner->playerList().insert(std::make_pair(dataSetRow(), this)); - NLMISC::CSheetId sheetId = CMirrors::sheet(DataSetRow); - _Sheet = AISHEETS::CSheets::getInstance()->lookupRaceStats(sheetId); -} - -CBotPlayer::~CBotPlayer() -{ - getOwner()->playerList().erase(dataSetRow()); - if (isSpawned()) - { - despawnBot(); - } -} - -std::string CBotPlayer::getIndexString() const -{ - return getOwner()->getIndexString()+NLMISC::toString(":p%u", getChildIndex()); -} - -std::string CBotPlayer::getEntityIdString() const -{ - return getEntityId().toString() ; -} - -std::string CBotPlayer::getOneLineInfoString() const -{ - return std::string("Player '") + getEntityId().toString() + "'"; -} - -std::vector CBotPlayer::getMultiLineInfoString() const -{ - std::vector container; - - - pushTitle(container, "CBotPlayer"); - pushEntry(container, "id=" + getIndexString()); - container.back() += " eid=" + getEntityIdString(); - container.back() += " teamid=" + NLMISC::toString("%u", _CurrentTeamId); - pushFooter(container); - - - return container; -} - -void CBotPlayer::processEvent(CCombatInterface::CEvent const& event) -{ - // if heal happends, dispatch aggro on targetters. - if (event._nature==ACTNATURE::CURATIVE_MAGIC && event._weight>=0) - { - float aggro = -event._weight; - if (aggro>-0.5f) - aggro = -0.5f; - else if (aggro<-1.f) - aggro = -1.f; - - CAIEntityPhysical const* const targetBot = CAIS::instance().getEntityPhysical(event._targetRow); - - if (targetBot) - { - CAIEntityPhysical* targeter = targetBot->firstTargeter(); - while (targeter) - { - if (targeter->dataSetRow()!=event._originatorRow) - { - switch (targeter->getRyzomType()) - { - case RYZOMID::creature: - { - CSpawnBotFauna* const fauna = NLMISC::safe_cast(targeter); - fauna->addAggroFor(event._originatorRow, aggro, true); - } - break; - case RYZOMID::npc: - { - CSpawnBotNpc* const npc = NLMISC::safe_cast(targeter); - npc->addAggroFor(event._originatorRow, aggro, true); - } - break; - default: - break; - } - } - targeter = targeter->nextTargeter(); - } - } - } -} - -void CBotPlayer::updatePos() -{ - RYAI_MAP_CRUNCH::CWorldPosition wpos; - if (!CWorldContainer::getWorldMap().setWorldPosition(pos().h(), wpos,CAIVector(pos()))) - { - _PlayerPosIsInvalid = true; - return; - } - _PlayerPosIsInvalid = false; - setWPos(wpos); - linkEntityToMatrix(this->pos(),getOwner()->getOwner()->playerMatrix()); - - if (wpos.getFlags()&RYAI_MAP_CRUNCH::Water) - setActionFlags(RYZOMACTIONFLAGS::InWater); - else - removeActionFlags(RYZOMACTIONFLAGS::InWater); -} - -CAIPos CBotPlayer::aipos() const -{ - if (_PlayerPosIsInvalid) - return CAIPos(wpos().toAIVector(), wpos().h(), 0); // This is last valid position on AI collision map - else - return CAIPos(pos()); -} - -void CBotPlayer::update() -{ - updatePos(); -} - -CAIInstance* CBotPlayer::getAIInstance() const -{ - return getOwner()->getAIInstance(); -} - -bool CBotPlayer::spawn() -{ - setSpawn(this); - return true; -} - -void CBotPlayer::despawnBot() -{ - setSpawn(NULL); -} - -bool CBotPlayer::isUnReachable() const -{ - // _PlayerPosIsInvalid does not reflect the fact that the player is unreachable - // _PlayerPosIsInvalid is true when player is in delta between PACS and WorldMap - // collisions, and is reachable in those cases if the bot is near - if (useOldUnreachable) - { - return _PlayerPosIsInvalid; - } - else - { - return false; - } -} - -bool CBotPlayer::setPos(CAIPos const& pos) -{ -#ifdef NL_DEBUG - nlassert(1==0); -#endif - return true; -} - -float CBotPlayer::walkSpeed() const -{ - nlerror("Non-virtual overriden function walkSpeed in CBotPlayer"); - return 3.f/10.f; -} - -float CBotPlayer::runSpeed() const -{ - nlerror("Non-virtual overriden function runSpeed in CBotPlayer"); - return 6.f/10.f; -} - -bool CBotPlayer::isAggressive() const -{ - MBEHAV::TMode const mode = getMode(); - return mode==MBEHAV::COMBAT_FLOAT || mode==MBEHAV::COMBAT; -} - -void CBotPlayer::addAggroer(TDataSetRow const& row) -{ -#if !FINAL_VERSION - for (sint32 i=(sint32)_AggroerList.size()-1;i>=0;i--) - nlassert(_AggroerList[i]!=row); -#endif - _AggroerList.push_back(row); -} - -void CBotPlayer::removeAggroer(TDataSetRow const& row) -{ - for (sint32 i=(sint32)_AggroerList.size()-1;i>=0;i--) - { - if (_AggroerList[i]==row) - { - _AggroerList.at(i)=_AggroerList.back(); - _AggroerList.pop_back(); - break; - } - } -} - -void CBotPlayer::updateInsideTriggerZones(const std::set& newInsideTriggerZone, std::vector& onEnterZone, std::vector& onLeaveZone) -{ - std::set::const_iterator firstInside(_InsideTriggerZones.begin()), lastInside( _InsideTriggerZones.end()); - std::set::const_iterator firstNewInside(newInsideTriggerZone.begin()), lastNewInside( newInsideTriggerZone.end()); - - std::set_difference(firstInside, lastInside, firstNewInside, lastNewInside, std::back_inserter(onLeaveZone)); - std::set_difference(firstNewInside, lastNewInside, firstInside, lastInside, std::back_inserter(onEnterZone)); - - _InsideTriggerZones = newInsideTriggerZone; -} - -////////////////////////////////////////////////////////////////////////////// -// CManagerPlayer // -////////////////////////////////////////////////////////////////////////////// - -CManagerPlayer::~CManagerPlayer() -{ - TPlayerMap::iterator it = _spawnedPlayers.begin(); - while (it != _spawnedPlayers.end()) - { - CBotPlayer* player = (*it).second; - - // a CBotPlayer object removes itself from _spawnedPlayers at destruction - // increment the iterator before it becomes invalid - ++it; - player->despawnBot(); - removeChildByIndex(player->getChildIndex()); - // now the player object is destroyed - } -} - -void CManagerPlayer::update() -{ - FOREACH(it, TPlayerMap, _spawnedPlayers) - { - it->second->CBotPlayer::update(); - } -} - -void CManagerPlayer::addSpawnedPlayer(TDataSetRow const& dataSetRow, NLMISC::CEntityId const& id) -{ - CBotPlayer* player = new CBotPlayer(this,dataSetRow,id,1); // :TODO: default player level calculation (skill & hp ?). - addChild(player); - player->spawn(); - - player->linkToWorldMap(player, player->pos(), getOwner()->playerMatrix()); - player->updatePos(); - - // update team id and composition - CMirrorPropValueRO value( *CMirrors::DataSet, dataSetRow, DSPropertyTEAM_ID ); - player->setCurrentTeamId(value()); - if (value() != CTEAM::InvalidTeamId) - { - _teams[value()].insert(dataSetRow); - } -} - -void CManagerPlayer::removeDespawnedPlayer(TDataSetRow const& dataSetRow) -{ - // Remove player from Manager. - TPlayerMap::iterator it = _spawnedPlayers.find(dataSetRow); - if (it==_spawnedPlayers.end()) - { - // need to log some warning - nlwarning("Player Despawn Error"); - #ifdef NL_DEBUG - nlerror("Player Despawn Error"); - #endif - return; - } - else - { - CBotPlayer* const player = (*it).second; - - // update team composition - if (player->getCurrentTeamId() != CTEAM::InvalidTeamId) - { - CHashMap >::iterator it(_teams.find(player->getCurrentTeamId())); - if (it != _teams.end()) - { - it->second.erase(dataSetRow); - if (it->second.empty()) - _teams.erase(it); - } - } - player->despawnBot(); - removeChildByIndex(player->getChildIndex()); - } -} - -void CManagerPlayer::updatePlayerTeam(TDataSetRow const& dataSetRow) -{ - TPlayerMap::iterator it(_spawnedPlayers.find(dataSetRow)); - if (it!=_spawnedPlayers.end()) - { - uint16 const oldTeam = it->second->getCurrentTeamId(); - if (oldTeam!=CTEAM::InvalidTeamId) - { - CHashMap >::iterator it(_teams.find(oldTeam)); - if (it != _teams.end()) - { - it->second.erase(dataSetRow); - if (it->second.empty()) - _teams.erase(it); - } - } - // update team id and composition - CMirrorPropValueRO value(*CMirrors::DataSet, dataSetRow, DSPropertyTEAM_ID); - it->second->setCurrentTeamId(value()); - if (value() != CTEAM::InvalidTeamId) - { - _teams[value()].insert(dataSetRow); - } - } - else - { - nlwarning("CManagerPlayer::updatePlayerTeam : dataSetRow %u, can't find spawned player !", dataSetRow.getIndex()); - } -} - -// This static data is just to have a ref return type anytime, bad habit. -std::set CManagerPlayer::emptySet; - -std::set const& CManagerPlayer::getPlayerTeam(TDataSetRow const& playerRow) -{ - TPlayerMap::iterator it(_spawnedPlayers.find(playerRow)); - - if (it != _spawnedPlayers.end()) - { - uint16 const teamId = it->second->getCurrentTeamId(); - return getPlayerTeam(teamId); - } - else - { - nlwarning("CManagerPlayer::getPlayerTeam can't find player from dataset %u", playerRow.getIndex()); - return emptySet; - } -} - -std::set const& CManagerPlayer::getPlayerTeam(uint16 teamId) -{ - if (teamId == CTEAM::InvalidTeamId) - { - return emptySet; - } - else - { - TTeamMap::iterator itTeam = _teams.find(teamId); - if (itTeam != _teams.end()) - { - return itTeam->second; - } - else - { - nlwarning("CManagerPlayer::getPlayerTeam : no player in team %u", teamId); - return emptySet; - } - } -} - -void CManagerPlayer::getTeamIds(std::vector& teamIds) -{ - FOREACH(itTeam, TTeamMap, _teams) - { - teamIds.push_back(itTeam->first); - } -} - -void CBotPlayer::forgotAggroForAggroer() -{ - - for (sint32 i=(sint32)_AggroerList.size()-1; i>=0; --i) - { - CAIEntityPhysical* const phys = CAIS::instance().getEntityPhysical(_AggroerList[i]); - if (!phys) - continue; - CBotAggroOwner* aggroOwner = NULL; - - switch(phys->getRyzomType()) - { - case RYZOMID::creature: - aggroOwner = NLMISC::safe_cast(NLMISC::safe_cast(phys)); - break; - case RYZOMID::npc: - aggroOwner = NLMISC::safe_cast(NLMISC::safe_cast(phys)); - break; - } - if (!aggroOwner) - continue; - aggroOwner->forgetAggroFor(dataSetRow()); - } -} - -bool CBotPlayer::useOldUnreachable = false; - -NLMISC_COMMAND(playerUseOldUnreachable, "Old unreachable state computing is used","") -{ - if(args.size()>1) return false; - if(args.size()==1) StrToBool(CBotPlayer::useOldUnreachable, args[0]); - log.displayNL("playerUseOldUnreachable is %s", CBotPlayer::useOldUnreachable?"true":"false"); - return true; -} - -sint32 CBotPlayer::getFame(std::string const& faction, bool modulated, bool returnUnknownValue) const -{ - sint32 fame = CAIEntityPhysical::getFame(faction, modulated, true); - if (fame==NO_FAME) - { - fame = CStaticFames::getInstance().getStaticFame(_Sheet->Race(), faction); - } - if (!returnUnknownValue && fame==NO_FAME) - fame = 0; - return fame; -} - -sint32 CBotPlayer::getFameIndexed(uint32 factionIndex, bool modulated, bool returnUnknownValue) const -{ - sint32 fame = CAIEntityPhysical::getFameIndexed(factionIndex, modulated, true); - if (fame==NO_FAME) - { - uint32 playerFaction = CStaticFames::getInstance().getFactionIndex(_Sheet->Race()); - fame = CStaticFames::getInstance().getStaticFameIndexed(playerFaction, factionIndex); - } - if (!returnUnknownValue && fame==NO_FAME) - fame = 0; - return fame; -} diff --git a/code/ryzom/server/src/ai_service/ai_player.h b/code/ryzom/server/src/ai_service/ai_player.h deleted file mode 100644 index 69bd14ffc..000000000 --- a/code/ryzom/server/src/ai_service/ai_player.h +++ /dev/null @@ -1,187 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef AI_PLAYER_H -#define AI_PLAYER_H - -#include "ai_share/ai_coord.h" -#include "nel/misc/sheet_id.h" -#include "ai.h" -#include "ai_bot.h" -#include "owners.h" - -class CFauna; - - - -#ifdef NL_OS_WINDOWS -#pragma warning (disable : 4355) -#endif // NL_OS_WINDOWS - -////////////////////////////////////////////////////////////////////////////// -// CBotPlayer // -////////////////////////////////////////////////////////////////////////////// - -// Player is considered as both a persistent and a spawned entity (philosophycally, the spawning process is part of the client). -class CBotPlayer -: public NLMISC::CDbgRefCount -, public CChild -, public CPetOwner -, public CAIEntityPhysical -, public CPersistentOfPhysical -{ -public: - CBotPlayer(CManagerPlayer* owner, TDataSetRow const& dataSetRow, NLMISC::CEntityId const& id, uint32 level); - virtual ~CBotPlayer(); - - /// @name CChild implementation - //@{ - virtual std::string getIndexString() const; - virtual std::string getEntityIdString() const; - virtual std::string getOneLineInfoString() const; - std::vector getMultiLineInfoString() const; - //@} - - CAIInstance* getAIInstance() const; - - void setAggroable(bool aggroable = true) { _Aggroable = aggroable; } - bool isAggroable() const { return _Aggroable; } - - // player are always attackable (this is a IA point of view, it mean that IA can attack player) - virtual bool isBotAttackable() const { return true; } - - virtual bool spawn(); - void despawnBot(); - - void update(); - - // update the pos and link of player (if the position is valid, otherwise, no move are done) - // perhaps should we invalidate the player worldPosition. (!?). - void updatePos(); - virtual CAIPos aipos() const; - - void setTarget(CAIEntityPhysical* target) { CTargetable::setTarget(target); } - void setVisualTarget(CAIEntityPhysical* target) { CTargetable::setVisualTarget(target); } - - bool isUnReachable() const; - - bool setPos(CAIPos const& pos); - - float walkSpeed() const; - float runSpeed() const; - - CAIEntityPhysical& getPhysical() { return *this; } - - virtual RYZOMID::TTypeId getRyzomType() const { return RYZOMID::player; } - - bool isAggressive() const; - - void processEvent(const CCombatInterface::CEvent &); - - uint16 getCurrentTeamId() const { return _CurrentTeamId;} - void setCurrentTeamId(uint16 teamId) { _CurrentTeamId = teamId;} - - bool getFollowMode() const { return _FollowMode; } - void setFollowMode(bool followMode) { _FollowMode = followMode; } - - void addAggroer(TDataSetRow const& row); - - void removeAggroer(TDataSetRow const& row); - - void forgotAggroForAggroer(); - /// Updates the reference to zone in which the player is that can trigger event (on enter, on leave) - void updateInsideTriggerZones(const std::set& newInsideTriggerZone, std::vector& onEnterZone, std::vector& onLeaveZone); - - virtual sint32 getFame(std::string const& faction, bool modulated = false, bool returnUnknowValue = false) const; - virtual sint32 getFameIndexed(uint32 factionIndex, bool modulated = false, bool returnUnknowValue = false) const; - -public: - static bool useOldUnreachable; - -private: - uint16 _CurrentTeamId; - bool _FollowMode; - bool _PlayerPosIsInvalid; - bool _Aggroable; - std::vector _AggroerList; - std::set _InsideTriggerZones; - AISHEETS::IRaceStatsCPtr _Sheet; -}; - -////////////////////////////////////////////////////////////////////////////// -// CManagerPlayer // -////////////////////////////////////////////////////////////////////////////// - -class CManagerPlayer -: public CCont -, public CChild -{ -public: - typedef CHashMap, TDataSetRow::CHashCode> TPlayerMap; - -public: - CManagerPlayer(CAIInstance* owner) - : CChild(owner) - { - } - - virtual ~CManagerPlayer(); - - CAIInstance* getAIInstance() const - { - return getOwner(); - } - - void addSpawnedPlayer(TDataSetRow const& dataSetRow, NLMISC::CEntityId const& id); - // Strict mean that the player MUST be in this manager (otherwise, the function log a warning) - void removeDespawnedPlayer(TDataSetRow const& dataSetRow); - /// Called when the team id value from mirror change. - void updatePlayerTeam(TDataSetRow const& dataSetRow); - - // update the manager. - void update(); - - /// Return a set of player in the same team of the indicated player - std::set const& getPlayerTeam(TDataSetRow const& playerRow); - /// Return a set of player in the specified team - std::set const& getPlayerTeam(uint16 teamId); - - /// Debug feature, build a set of currently active team. - void getTeamIds(std::vector& teamIds); - - std::string getIndexString() const - { - return getOwner()->getIndexString()+NLMISC::toString(":players"); - } - - TPlayerMap& playerList() - { - return _spawnedPlayers; - } - -private: - TPlayerMap _spawnedPlayers; // hum .. still useful ? - /// Team composition. - typedef CHashMap > TTeamMap; - TTeamMap _teams; - -private: - static std::set emptySet; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_pos.h b/code/ryzom/server/src/ai_service/ai_pos.h deleted file mode 100644 index 1867bbefa..000000000 --- a/code/ryzom/server/src/ai_service/ai_pos.h +++ /dev/null @@ -1,135 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -class CAIPos; - -#ifndef RYAI_POS_H -#define RYAI_POS_H - -#include "ai_share/ai_vector.h" -#include "ai_vector_mirror.h" - -class CAIPosMirror; - - -//---------------------------------------------------------------------------- -// The class -//---------------------------------------------------------------------------- - -/** This class is an extension of CAIVector with an added height and -orientation information. - -This class as an additionnal sint32 h field and a CAngle theta field. The -height unit is 1 meter length (and thus there is no precision smaller than 1 -meter), and the orientation (see CAngle) is on the horizontal XY plane. - -*/ -class CAIPos -: public CAIVector -{ -public: - CAIPos() : CAIVector(0., 0.), _h(0), _theta(0.f) { } - CAIPos(CAIPos const& pos) : CAIVector(pos), _h(pos._h), _theta(pos._theta) { } - - explicit CAIPos(CAIVector const& xy, sint32 h, float theta) : CAIVector(xy), _h(h), _theta(theta) { } - explicit CAIPos(CAIVector const& xy, sint32 h, CAngle const& theta) : CAIVector(xy), _h(h), _theta(theta) { } - - CAIPos(CAIPosMirror const& pos); - explicit CAIPos(CAIVectorMirror const& xy, sint32 h, float theta); - explicit CAIPos(CAIVectorMirror const& xy, sint32 h, CAngle const& theta); - template - explicit CAIPos(C x, C y, sint32 h, float theta) : CAIVector(x, y), _h(h), _theta(theta) { } - template - explicit CAIPos(C x, C y, sint32 h, CAngle theta) :CAIVector(x, y), _h(h), _theta(theta) { } - - std::string toString() const - { - return NLMISC::toString("(%9s,%9s,%d) %3d\"",x().toString().c_str(),y().toString().c_str(),h(),theta().asDegrees()); - } - - inline bool operator==(const CAIPos &other) const { return CAIVector::operator==(other) && other.h()==h(); } - inline bool operator!=(const CAIPos &other) const { return CAIVector::operator!=(other) || other.h()!=h(); } - inline bool operator==(const CAIPosMirror &other) const; - inline bool operator!=(const CAIPosMirror &other) const; - - inline bool operator==(const CAIVectorMirror &other) const { return CAIVector::operator==(other); } - inline bool operator!=(const CAIVectorMirror &other) const { return CAIVector::operator!=(other); } - - - inline const CAIPos &operator= (const CAIPos &other) { setX(other.x()); setY(other.y()); _h=other._h; _theta=other._theta; return *this; } - inline const CAIPos &operator= (const CAIPosMirror &other); /* { setX(other.x()); setY(other.y()); _h=other.h(); _theta=other.theta(); return *this; }*/ - - template inline const CAIPos &operator+=(const V &v) { CAIVector::operator +=(v); return *this; } - template inline const CAIPos &operator-=(const V &v) { CAIVector::operator -=(v); return *this; } - - template inline const CAIPos operator+(const V &v) const { CAIPos p(*this); return p+=v; } - template inline const CAIPos operator-(const V &v) const { CAIPos p(*this); return p-=v; } - - inline const sint32 &h() const { return _h; } - inline const CAngle &theta() const { return _theta; } - - template inline void setH(const C &h) { _h=h; } - template inline void setTheta(const C &theta) { _theta=theta; } - -private: - sint32 _h; - CAngle _theta; -}; - -//-------------------------------------------------------------------------- -// The inlines -//-------------------------------------------------------------------------- - -#include "ai_pos_mirror.h" - - -inline const CAIPos &CAIPos::operator= (const CAIPosMirror &other) -{ - setX(other.x()); - setY(other.y()); - _h=other.h(); - _theta=other.theta(); - return *this; -} - - -inline CAIPos::CAIPos(const CAIPosMirror &pos): -CAIVector(pos.x(),pos.y()), _h(pos.h()), _theta(pos.theta()) -{ -} - -inline CAIPos::CAIPos(const CAIVectorMirror &xy, sint32 h, float theta): - CAIVector(xy.x(),xy.y()), _h(h), _theta(theta) -{ -} - -inline CAIPos::CAIPos(const CAIVectorMirror &xy, sint32 h, const CAngle &theta): - CAIVector(xy.x(),xy.y()), _h(h), _theta(theta) -{ -} - -inline bool CAIPos::operator==(const CAIPosMirror &other) const -{ - return (other.x()==x()) && (other.y()==y()) && other.h()==h(); -} - -inline bool CAIPos::operator!=(const CAIPosMirror &other) const -{ - return !(*this == other); -} -#endif diff --git a/code/ryzom/server/src/ai_service/ai_pos_mirror.h b/code/ryzom/server/src/ai_service/ai_pos_mirror.h deleted file mode 100644 index d4909c8b6..000000000 --- a/code/ryzom/server/src/ai_service/ai_pos_mirror.h +++ /dev/null @@ -1,83 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef RYAI_POS_MIRROR_H -#define RYAI_POS_MIRROR_H - -//#include "ai.h" -#include "ai_vector_mirror.h" - - -class CAngle; -class CAIPos; -class CAIVector; - -//---------------------------------------------------------------------------- -// The class -//---------------------------------------------------------------------------- - -/** A position based on CAIPos with components in the mirror shared memory. - - - -*/ - -class CAIPosMirror: public CAIVectorMirror -{ -public: - // ctor - inline CAIPosMirror(const TDataSetRow& entityIndex=TDataSetRow()); - inline std::string toString() const; - - // == and != operators - inline bool operator==(const CAIPos &other) const; - inline bool operator!=(const CAIPos &other) const; - - inline bool operator==(const CAIPosMirror &other) const; - inline bool operator!=(const CAIPosMirror &other) const; - - // = operator - inline const CAIPosMirror &operator=(const CAIPos &other); - - // += and -= operators - template inline const CAIPosMirror &operator+=(const C &v); - template inline const CAIPosMirror &operator-=(const C &v); - - // * and / operators - inline const CAIPos operator* (double d) const; - inline const CAIPos operator/ (double d) const; - - // + and - operators - inline CAIPos operator+ (const NLMISC::CVector2d &v) const; - template inline CAIPos operator+ (const C &v) const; - template inline CAIPos operator- (const C &v) const; - - inline const sint32 &h() const; - inline CAngle theta() const; - template inline void setH(C h); - template inline void setTheta(C theta); - -private: - CMirrorPropValue _h; - CMirrorPropValue _theta; -}; - -#include "ai_pos_mirror_inline.h" - -#endif - diff --git a/code/ryzom/server/src/ai_service/ai_pos_mirror_inline.h b/code/ryzom/server/src/ai_service/ai_pos_mirror_inline.h deleted file mode 100644 index 4185adafa..000000000 --- a/code/ryzom/server/src/ai_service/ai_pos_mirror_inline.h +++ /dev/null @@ -1,218 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -class CAIPosMirror; - -#ifndef RYAI_POS_MIRROR_INLINE_H -#define RYAI_POS_MIRROR_INLINE_H - -/* -#include "nel/misc/types_nl.h" -#include "nel/misc/vector_2d.h" -#include "ai_share/ai_vector.h" -#include "ai_share/angle.h" -#include "ai_vector_mirror.h" - -#include -#include -#include - -class CAIPos; -*/ -//-------------------------------------------------------------------------- -// The inlines -//-------------------------------------------------------------------------- - -#include "ai_pos.h" - -// ctor -inline CAIPosMirror::CAIPosMirror(const TDataSetRow& entityIndex): - CAIVectorMirror(entityIndex), - _h( *CMirrors::DataSet, entityIndex, DSPropertyPOSZ ), - _theta( *CMirrors::DataSet, entityIndex, DSPropertyORIENTATION ) - {} - -// toString for debugging... -inline std::string CAIPosMirror::toString() const -{ - return NLMISC::toString("(%9s,%9s,%d) %3d\"",x().toString().c_str(),(y()).toString().c_str(),h(),theta().asDegrees()); -} - - -// == and != operators -inline bool CAIPosMirror::operator==(const CAIPos &other) const -{ - return other.x()==x() && other.y()==y() && other.h()==h(); -} - -inline bool CAIPosMirror::operator!=(const CAIPos &other) const -{ - return !(*this == other); -} - - -inline bool CAIPosMirror::operator==(const CAIPosMirror &other) const -{ - return other.x()==x() && other.y()==y() && other.h()==h(); -} - -inline bool CAIPosMirror::operator!=(const CAIPosMirror &other) const -{ - return !(*this == other); -} - - -// = operator -inline const CAIPosMirror &CAIPosMirror::operator= (const CAIPos &other) -{ - setX(other.x()); setY(other.y()); setH(other.h()); setTheta(other.theta()); return *this; -} - -// += and -= operators -template -inline const CAIPosMirror &CAIPosMirror::operator+=(const C &v) -{ - setX(x()+v.x()); setY(y()+v.y()); return *this; -} - -template -inline const CAIPosMirror &CAIPosMirror::operator-=(const C &v) -{ - setX(x()-v.x()); setY(y()-v.y()); return *this; -} - - -// * and / operators -inline const CAIPos CAIPosMirror::operator* (double d) const -{ - return CAIPos(CAIVectorMirror::operator*(d),h(),theta()); -} - -inline const CAIPos CAIPosMirror::operator/ (double d) const -{ - return CAIPos(CAIVectorMirror::operator/(d),h(),theta()); -} - - -// + and - operators -template -inline CAIPos CAIPosMirror::operator+ (const C &v) const -{ - return CAIPos(*this)+v; -} - -template -inline CAIPos CAIPosMirror::operator- (const C &v) const -{ - return CAIPos(*this)-v; -} - -inline const sint32 &CAIPosMirror::h() const -{ - return _h(); -} - -inline CAngle CAIPosMirror::theta() const -{ - return (CAngle)_theta(); -} - - -template inline void CAIPosMirror::setH(C h) -{ - _h=(TYPE_POSZ)h; -} - -template inline void CAIPosMirror::setTheta(C theta) -{ - _theta=((CAngle)theta).asRadians(); -} - - -// a few handy utility methods SLOW!!!!!!!!! -inline CAngle CAIVectorMirror::angleTo(const CAIPos &dest) const -{ - return (dest-CAIVector(*this)).asAngle(); -} - -inline double CAIVectorMirror::distTo(const CAIPos &dest) const -{ - return (dest-CAIVector(*this)).norm(); -} - -inline double CAIVectorMirror::distSqTo(const CAIPos &dest) const -{ - return (dest-CAIVector(*this)).sqrnorm(); -} - -inline double CAIVectorMirror::quickDistTo(const CAIPos &dest) const -{ - double dx=fabs((dest.x()-x()).asDouble()), dy=fabs((dest.y()-y()).asDouble()); - return (dx>dy)? (dx+dy/2): (dy+dx/2); -} - - -inline CAngle CAIVectorMirror::angleTo(const CAIVector &dest) const -{ - return (dest-CAIVector(*this)).asAngle(); -} - -inline double CAIVectorMirror::distTo(const CAIVector &dest) const -{ - return (dest-CAIVector(*this)).norm(); -} - -inline double CAIVectorMirror::distSqTo(const CAIVector &dest) const -{ - return (dest-CAIVector(*this)).sqrnorm(); -} - -inline double CAIVectorMirror::quickDistTo(const CAIVector &dest) const -{ - double dx=fabs((dest.x()-x()).asDouble()), dy=fabs((dest.y()-y()).asDouble()); - return (dx>dy)? (dx+dy/2): (dy+dx/2); -} - - -inline CAngle CAIVectorMirror::angleTo(const CAIVectorMirror &dest) const -{ - return CAngle(atan2((dest.y()-y()).asDouble(),(dest.x()-x()).asDouble())); -} - -inline double CAIVectorMirror::distTo(const CAIVectorMirror &dest) const -{ - return (dest-*this).norm(); -} - -inline double CAIVectorMirror::distSqTo(const CAIVectorMirror &dest) const -{ - return (dest-*this).sqrnorm(); -} - -inline double CAIVectorMirror::quickDistTo(const CAIVectorMirror &dest) const -{ - double dx=fabs((dest.x()-x()).asDouble()), dy=fabs((dest.y()-y()).asDouble()); return (dx>dy)? (dx+dy/2): (dy+dx/2); -} - -inline CAIVectorMirror::operator CAIVector() const -{ - return CAIVector(*this); -} - -#endif - diff --git a/code/ryzom/server/src/ai_service/ai_profile_fauna.cpp b/code/ryzom/server/src/ai_service/ai_profile_fauna.cpp deleted file mode 100644 index 354cccdfc..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_fauna.cpp +++ /dev/null @@ -1,948 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#include "stdpch.h" -#include "ai_profile_fauna.h" - -#include "ai_bot_fauna.h" -#include "ai_grp_fauna.h" -#include "ai_mgr_fauna.h" - -//- Compact logging facilities ----------------------------------------------- - -CFaunaProfileFloodLogger CWanderFaunaProfile::_FloodLogger(600); -CFaunaProfileFloodLogger CGrazeFaunaProfile::_FloodLogger(600); -CFaunaProfileFloodLogger CRestFaunaProfile::_FloodLogger(600); - -//- Profile factories singletons --------------------------------------------- - -CPlanteIdleFaunaProfileFactory PlanteIdleFaunaProfileFactory; -CWanderFaunaProfileFactory WanderFaunaProfileFactory; -CGrazeFaunaProfileFactory GrazeFaunaProfileFactory; -CRestFaunaProfileFactory RestFaunaProfileFactory; -CFightFaunaProfileFactory FightFaunaProfileFactory; -CCorpseFaunaProfileFactory CorpseFaunaProfileFactory; -CEatCorpseFaunaProfileFactory EatCorpseFaunaProfileFactory; -CCuriosityFaunaProfileFactory CuriosityFaunaProfileFactory; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightFauna // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFightFauna -: public CBotProfileFight -{ -public: - CBotProfileFightFauna(CProfileOwner* owner, CAIEntityPhysical* ennemy); - - virtual std::string getOneLineInfoString() const { return NLMISC::toString("fight fauna bot profile"); } - - void noMoreTarget(); - - void eventBeginFight(); - void eventTargetKilled(); -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHealFauna // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileHealFauna -: public CBotProfileHeal -{ -public: - CBotProfileHealFauna(TDataSetRow const& row, CProfileOwner* owner); - - virtual std::string getOneLineInfoString() const { return NLMISC::toString("heal fauna bot profile"); } - - void noMoreTarget(); - -// void eventBeginFight(); -// void eventTargetKilled(); -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFightFauna // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileReturnAfterFightFauna -: public CBotProfileReturnAfterFight -, public IMouvementMagnetOwner -{ -public: - CBotProfileReturnAfterFightFauna(CProfileOwner* owner); - ~CBotProfileReturnAfterFightFauna(); - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual std::string getOneLineInfoString() const { return NLMISC::toString("return_after_fight fauna bot profile"); } - - virtual NLMISC::CSmartPtr const& getMovementMagnet() const { return _MovementMagnet; } - -private: - NLMISC::CSmartPtr _MovementMagnet; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightFauna // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileFightFauna::CBotProfileFightFauna(CProfileOwner* owner, CAIEntityPhysical* ennemy) -: CBotProfileFight(owner, ennemy) -{ -} - -void CBotProfileFightFauna::noMoreTarget() -{ - static_cast(_Bot.ptr())->setDefaultComportment(); -} - -void CBotProfileFightFauna::eventBeginFight() -{ - CSpawnBotFauna* spawnable= NLMISC::safe_cast(_Bot.ptr()); - CGrpFauna &grpFauna = static_cast(*spawnable->getPersistent().getOwner()); - grpFauna.processStateEvent(grpFauna.getEventContainer().EventBotBeginFight); -} - -void CBotProfileFightFauna::eventTargetKilled() -{ - CSpawnBotFauna* spawnable= NLMISC::safe_cast(_Bot.ptr()); - CGrpFauna *grpFauna = static_cast(spawnable->getPersistent().getOwner()); - grpFauna->processStateEvent(grpFauna->getEventContainer().EventBotTargetKilled); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHealFauna // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileHealFauna::CBotProfileHealFauna(TDataSetRow const& row, CProfileOwner* owner) -: CBotProfileHeal(row, owner) -{ -} - -void CBotProfileHealFauna::noMoreTarget() -{ - static_cast(_Bot.ptr())->setDefaultComportment(); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFightFauna // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileReturnAfterFightFauna::CBotProfileReturnAfterFightFauna(CProfileOwner* owner) -: CBotProfileReturnAfterFight(owner) -{ - CSpawnBotFauna* bot = NLMISC::safe_cast(owner); - RYAI_MAP_CRUNCH::TAStarFlag denyFlags = bot->getAStarFlag(); - _MovementMagnet = NLMISC::CSmartPtr(new CReturnMovementMagnet(bot->getReturnPos(), *bot, bot->getAStarFlag())); -} - -CBotProfileReturnAfterFightFauna::~CBotProfileReturnAfterFightFauna() -{ -} - -void CBotProfileReturnAfterFightFauna::beginProfile() -{ -// PROFILE_LOG("bot_fauna", "return_after_fight", "begin", ""); - CBotProfileReturnAfterFight::beginProfile(); - _Bot->ignoreReturnAggro(true); -} - -void CBotProfileReturnAfterFightFauna::endProfile() -{ -// PROFILE_LOG("bot_fauna", "return_after_fight", "end", ""); - _Bot->ignoreReturnAggro(false); - CBotProfileReturnAfterFight::endProfile(); -} - -void CBotProfileReturnAfterFightFauna::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CBotProfileReturnAfterFightFaunaUpdate); - CBotProfileReturnAfterFight::updateProfile(ticksSinceLastUpdate); - _MovementMagnet->update(0, ticksSinceLastUpdate); -} - -////////////////////////////////////////////////////////////////////////////// -// CSpawnBotFauna // -////////////////////////////////////////////////////////////////////////////// - -void CSpawnBotFauna::doFight(CAIEntityPhysical* ennemy) -{ -#ifdef NL_DEBUG - nlassert(ennemy); -#endif - setAIProfile(new CBotProfileFightFauna(this, ennemy)); -} - -void CSpawnBotFauna::setDefaultComportment() -{ - - if (getPersistent().getRyzomType()==RYZOMID::flora) - setAIProfile(this, &PlanteIdleFaunaProfileFactory, false); - else - setAIProfile(this, &WanderFaunaProfileFactory, false); -} - -void CSpawnGroupFauna::setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy) -{ - bot->setAIProfile(new CBotProfileFightFauna(bot, ennemy)); -} - -void CSpawnGroupFauna::setHeal(CSpawnBot* bot, CAIEntityPhysical* target) -{ - bot->setAIProfile(new CBotProfileHealFauna(target->dataSetRow(), bot)); -} - -void CSpawnGroupFauna::setNoFight(CSpawnBot* bot) -{ - if (!bot->getTarget().isNULL()) - bot->setTarget(NULL); - if ( bot->getAIProfileType()==AITYPES::BOT_FLEE - || bot->getAIProfileType()==AITYPES::BOT_FIGHT - || bot->getAIProfileType()==AITYPES::BOT_HEAL - || bot->getAIProfileType()==AITYPES::BOT_RETURN_AFTER_FIGHT ) - { - static_cast(bot)->setDefaultComportment(); - } -} - -void CSpawnGroupFauna::setFlee(CSpawnBot* bot, CAIVector& fleeVect) -{ - bot->setMoveDecalage(fleeVect); - if (bot->getAIProfileType()!=AITYPES::BOT_FLEE) - { - bot->setAIProfile(new CBotProfileFlee(bot)); - } -} - -void CSpawnGroupFauna::setReturnAfterFight(CSpawnBot* bot) -{ - if (bot->getAIProfileType()!=AITYPES::BOT_RETURN_AFTER_FIGHT) - { - bot->setAIProfile(new CBotProfileReturnAfterFightFauna(bot)); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CPlanteIdleFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CPlanteIdleFaunaProfile::CPlanteIdleFaunaProfile(CProfileOwner* owner) -: CAIBaseProfile() -, _Bot(NLMISC::safe_cast(owner)) -{ -} - -void CPlanteIdleFaunaProfile::beginProfile() -{ - _Bot->setMode(MBEHAV::NORMAL); -} - -void CPlanteIdleFaunaProfile::endProfile() -{ -} - -void CPlanteIdleFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ -} - -std::string CPlanteIdleFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("plante_idle fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CAIFaunaActivityBaseSpawnProfile // -////////////////////////////////////////////////////////////////////////////// - -CAIFaunaActivityBaseSpawnProfile::CAIFaunaActivityBaseSpawnProfile(CProfileOwner* owner) -: CAIBaseProfile() -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _OutOfMagnet(false) -{ -} - -NLMISC::CSmartPtr const& CAIFaunaActivityBaseSpawnProfile::getMovementMagnet() const -{ - return _MovementMagnet; -} - -////////////////////////////////////////////////////////////////////////////// -// CWanderFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CWanderFaunaProfile::CWanderFaunaProfile(CProfileOwner* owner) -: CAIFaunaActivityBaseSpawnProfile(owner) -, _Bot(NLMISC::safe_cast(owner)) -{ - _DenyFlags = _Bot->getAStarFlag(); - _MovementMagnet = new CMovementMagnet(*_Bot, _DenyFlags); -} - -void CWanderFaunaProfile::beginProfile() -{ - _Bot->setMode(MBEHAV::NORMAL); - _OutOfMagnet=false; -} - -void CWanderFaunaProfile::endProfile() -{ -} - -void CWanderFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(WanderFaunaProfileUpdate) - CFollowPathContext fpcWanderFaunaProfileUpdate("WanderFaunaProfileUpdate"); - - // calculate distance from bot position to magnet point (used in all the different processes) - _magnetDistSq=_Bot->pos().distSqTo(_Bot->spawnGrp().magnetPos()); - double grpMagnetRadiusFar=_Bot->spawnGrp().magnetRadiusFar(); - if (_magnetDistSq>(grpMagnetRadiusFar*grpMagnetRadiusFar)) - { - _Bot->setMode( MBEHAV::NORMAL ); - - if (!_OutOfMagnet) - { - _PathPos._Angle=_Bot->theta(); - _OutOfMagnet=true; - _MovementMagnet=NULL; - } - - if (_Bot->canMove()) - { - const float dist=_Bot->walkSpeed()*ticksSinceLastUpdate; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _Bot->spawnGrp().getPathCont(), - dist, - dist*0.71f, - 0.5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - CFollowPath::TFollowReason lastReason = CFollowPath::getInstance()->lastReason(); - RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason lastFIASPReason = CFollowPath::getInstance()->lastFIASPReason(); -#ifdef COMPACT_POS_WARNINGS - int logTick = CTimeInterface::gameCycle(); - std::string error = _Bot->spawnGrp().getPathCont().getDestPos().toString() + " " + CFollowPath::toString(lastReason, lastFIASPReason); - ++_FloodLogger.logPositions[error]; - if ((logTick-_FloodLogger.logLastTick)>_FloodLogger.logPeriod) // Log errors every minute // :TODO: Put that in a config thing - { - if (!_FloodLogger.logPositions.empty()) - { - nlwarning("bots cannot reach their groups while wandering, positions are:"); - FOREACH(it, CFaunaProfileFloodLogger::TLogPositions, _FloodLogger.logPositions) - { - nlwarning(" - %s: %d times", it->first.c_str(), it->second); - } - _FloodLogger.logPositions.clear(); - } - _FloodLogger.logLastTick = logTick; - } -#else - nlwarning("Problem with a bot that cannot reach its group from %s to %s %s", _Bot->pos().toString().c_str(), _Bot->spawnGrp().getPathCont().getDestination().toString().c_str(), CFollowPath::toString(lastReason, lastFIASPReason).c_str()); -#endif - } - - } - return; - } - - _OutOfMagnet=false; - if (_MovementMagnet.isNull()) - _MovementMagnet=new CMovementMagnet(*_Bot,_DenyFlags); - _MovementMagnet->update(30, ticksSinceLastUpdate); -} - -std::string CWanderFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("wander fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CGrazeFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CGrazeFaunaProfile::CGrazeFaunaProfile(CProfileOwner* owner) -: CAIFaunaActivityBaseSpawnProfile(owner) -, _ArrivedInZone(false) -, _Bot(NLMISC::safe_cast(owner)) -{ - _DenyFlags=_Bot->getAStarFlag(); -} - -void CGrazeFaunaProfile::beginProfile() -{ - _ArrivedInZone=false; - _OutOfMagnet=false; - _Bot->setCycleState(CFaunaActivity::CycleStateHungry); - _CycleTimerBaseTime=_Bot->spawnGrp().getCurrentCycleTime()>>2; // 4 steps. (sorry, its hard coded) - _CycleTimer.set(_CycleTimerBaseTime+CAIS::rand16(_CycleTimerBaseTime/4)); -} - -void CGrazeFaunaProfile::endProfile() -{ -} - -void CGrazeFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrazeFaunaProfileUpdate) - CFollowPathContext fpcGrazeFaunaProfileUpdate("GrazeFaunaProfileUpdate"); - - // calculate distance from bot position to magnet point (used in all the different processes) - _magnetDistSq=_Bot->pos().distSqTo(_Bot->spawnGrp().magnetPos()); - - if (!_ArrivedInZone) - { - float grpMagnetRadiusFar=_Bot->spawnGrp().magnetRadiusFar(); - if (_magnetDistSq>(grpMagnetRadiusFar*grpMagnetRadiusFar)) - { - _Bot->setMode( MBEHAV::NORMAL ); - - if (!_OutOfMagnet) - { - _OutOfMagnet=true; - _PathPos._Angle=_Bot->theta(); - } - - if (_Bot->canMove()) - { - float dist = _Bot->walkSpeed()*ticksSinceLastUpdate; - CFollowPath::TFollowStatus status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _Bot->spawnGrp().getPathCont(), - dist, - dist*.71f, - .5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - CFollowPath::TFollowReason lastReason = CFollowPath::getInstance()->lastReason(); - RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason lastFIASPReason = CFollowPath::getInstance()->lastFIASPReason(); -#ifdef COMPACT_POS_WARNINGS - int logTick = CTimeInterface::gameCycle(); - std::string error = _Bot->spawnGrp().getPathCont().getDestPos().toString() + " " + CFollowPath::toString(lastReason, lastFIASPReason); - ++_FloodLogger.logPositions[error]; - if ((logTick-_FloodLogger.logLastTick)>_FloodLogger.logPeriod) // Log errors every minute // :TODO: Put that in a config thing - { - if (!_FloodLogger.logPositions.empty()) - { - nlwarning("bots cannot reach their groups while grazing, positions are:"); - FOREACH(it, CFaunaProfileFloodLogger::TLogPositions, _FloodLogger.logPositions) - { - nlwarning(" - %s: %d times", it->first.c_str(), it->second); - } - _FloodLogger.logPositions.clear(); - } - _FloodLogger.logLastTick = logTick; - } -#else - nlwarning("Follow No Path from %s to %s %s", _Bot->pos().toString().c_str(), _Bot->spawnGrp().getPathCont().getDestPos().toString().c_str(), CFollowPath::toString(lastReason, lastFIASPReason).c_str()); -// _Bot->spawnGrp().addBotToDespawnAndRespawnTime(&_Bot->getPersistent(),1,3000); -#endif - } - return; - } - } - else - { - _Bot->VisualTargetTimer().set(0); - _ArrivedInZone=true; - _MovementMagnet=new CMovementMagnet(*_Bot,_DenyFlags); - } - } - - if (_MovementMagnet.isNull()) - _MovementMagnet=new CMovementMagnet(*_Bot,_DenyFlags); - - if (_OutOfMagnet) - { - _MovementMagnet->setBotAngle(); - _OutOfMagnet=false; - } - - // increase cycle state when needed. - if (_CycleTimer.test()) - { - _Bot->setCycleState((CFaunaActivity::TCycleState)(_Bot->cycleState()+1)); - if (_Bot->cycleState()>CFaunaActivity::CycleStateDigesting) - _Bot->setCycleState(CFaunaActivity::CycleStateDigesting); - _CycleTimer.set(_CycleTimerBaseTime+CAIS::rand16(_CycleTimerBaseTime/4)); - } - - switch (_Bot->cycleState()) - { - case CFaunaActivity::CycleStateHungry: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*30, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateVeryHungry: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*60, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateStarving: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*120, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateDigesting: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*30, ticksSinceLastUpdate); - break; - } - - // && _state==0 ) // means wait in movementmagnet. - const float grpMagnetRadiusNear=_Bot->spawnGrp().magnetRadiusNear(); - if ( _magnetDistSq<=(grpMagnetRadiusNear*grpMagnetRadiusNear) - && _MovementMagnet->getMovementType()==CMovementMagnet::Movement_Anim) - { - if (_Bot->getPersistent().grp().getType()==AITYPES::FaunaTypePredator) - { - _Bot->setMode(MBEHAV::ALERT); - } - else - { - _Bot->setMode(MBEHAV::EAT); - } - } - else - { - if ( _Bot->cycleState()==CFaunaActivity::CycleStateHungry - || _Bot->cycleState()==CFaunaActivity::CycleStateDigesting) - { - _Bot->setMode(MBEHAV::NORMAL); - } - else - { - _Bot->setMode(MBEHAV::HUNGRY); - } - } -} - -std::string CGrazeFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("graze fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CRestFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CRestFaunaProfile::CRestFaunaProfile(CProfileOwner* owner) -: CAIFaunaActivityBaseSpawnProfile(owner) -, _ArrivedInZone(false) -, _Bot(NLMISC::safe_cast(owner)) -{ - _DenyFlags=_Bot->getAStarFlag(); -} - -void CRestFaunaProfile::beginProfile() -{ - _ArrivedInZone=false; - _Bot->setCycleState(CFaunaActivity::CycleStateTired); - _CycleTimerBaseTime=_Bot->spawnGrp().getCurrentCycleTime()>>2; // 4 steps. (sorry, its hard coded) - _CycleTimer.set(_CycleTimerBaseTime+CAIS::rand16(_CycleTimerBaseTime/4)); - _OutOfMagnet=false; -} - -void CRestFaunaProfile::endProfile() -{ - _Bot->setHungry (); -} - -void CRestFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(RestFaunaProfileUpdate) - CFollowPathContext fpcRestFaunaProfileUpdate("RestFaunaProfileUpdate"); - - // calculate distance from bot position to magnet point (used in all the different processes) - _magnetDistSq=_Bot->pos().distSqTo(_Bot->spawnGrp().magnetPos()); - - if (!_ArrivedInZone) - { - float grpMagnetRadiusFar=_Bot->spawnGrp().magnetRadiusFar(); - if (_magnetDistSq>(grpMagnetRadiusFar*grpMagnetRadiusFar)) - { - if (!_OutOfMagnet) - { - _PathPos._Angle=_Bot->theta(); - _OutOfMagnet=true; - } - _Bot->setMode( MBEHAV::NORMAL ); - if (_Bot->canMove()) - { - const float dist=_Bot->walkSpeed()*ticksSinceLastUpdate; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _Bot->spawnGrp().getPathCont(), - dist, - dist*.71f, - .5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - CFollowPath::TFollowReason lastReason = CFollowPath::getInstance()->lastReason(); - RYAI_MAP_CRUNCH::CWorldMap::TFindInsideAStarPathReason lastFIASPReason = CFollowPath::getInstance()->lastFIASPReason(); -#ifdef COMPACT_POS_WARNINGS - int logTick = CTimeInterface::gameCycle(); - std::string error = _Bot->spawnGrp().getPathCont().getDestPos().toString() + " " + CFollowPath::toString(lastReason, lastFIASPReason); - ++_FloodLogger.logPositions[error]; - if ((logTick-_FloodLogger.logLastTick)>_FloodLogger.logPeriod) // Log errors every minute // :TODO: Put that in a config thing - { - if (!_FloodLogger.logPositions.empty()) - { - nlwarning("bots cannot reach their groups, positions are:"); - FOREACH(it, CFaunaProfileFloodLogger::TLogPositions, _FloodLogger.logPositions) - { - nlwarning(" - %s: %d times", it->first.c_str(), it->second); - } - _FloodLogger.logPositions.clear(); - } - _FloodLogger.logLastTick = logTick; - } -#else - nlwarning("bot cannot reach its group from %s to %s %s", _Bot->pos().toString().c_str(), _Bot->spawnGrp().getPathCont().getDestPos().toString().c_str(), CFollowPath::toString(lastReason, lastFIASPReason).c_str()); -#endif - } - } - return; - } - else - { - _Bot->VisualTargetTimer().set(0); - _ArrivedInZone=true; - _MovementMagnet=new CMovementMagnet(*_Bot, _DenyFlags); - } - } - - if (_MovementMagnet.isNull()) - _MovementMagnet=new CMovementMagnet(*_Bot, _DenyFlags); - - if (_OutOfMagnet) - { - _MovementMagnet->setBotAngle(); - _OutOfMagnet=false; - } - - // increase cycle state when needed. - if (_CycleTimer.test()) - { - _Bot->setCycleState((CFaunaActivity::TCycleState)(_Bot->cycleState()+1)); - if (_Bot->cycleState()>CFaunaActivity::CycleStateShaking) - _Bot->setCycleState(CFaunaActivity::CycleStateShaking); - _CycleTimer.set(_CycleTimerBaseTime+CAIS::rand16(_CycleTimerBaseTime/4)); - } - - switch(_Bot->cycleState()) - { - case CFaunaActivity::CycleStateTired: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*80, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateVeryTired: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*120, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateExhausted: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*200, ticksSinceLastUpdate); - break; - case CFaunaActivity::CycleStateShaking: - _MovementMagnet->update(FAUNA_BEHAVIOR_GLOBAL_SCALE*80, ticksSinceLastUpdate); - break; - } - - const float grpMagnetRadiusNear=_Bot->spawnGrp().magnetRadiusNear(); - if ( _magnetDistSq<=(grpMagnetRadiusNear*grpMagnetRadiusNear) - && _MovementMagnet->getMovementType()==CMovementMagnet::Movement_Anim) - { - _Bot->setMode(MBEHAV::REST); - } - else - { - _Bot->setMode(MBEHAV::NORMAL); - } -} - -std::string CRestFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("rest fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CEatCorpseFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CEatCorpseFaunaProfile::CEatCorpseFaunaProfile(CProfileOwner* owner, TDataSetRow const& corpse, RYAI_MAP_CRUNCH::TAStarFlag flag) -: CAIBaseProfile() -, _Bot(NLMISC::safe_cast(owner)) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _eated(corpse) -, _atGoodDist(false) -, _PathCont(flag) -{ - CAIEntityPhysical const* const entity = CAIS::instance().getEntityPhysical(_eated); - if (entity) - _PathCont.setDestination(AITYPES::vp_auto, CAIVector(entity->pos())); -} - -void CEatCorpseFaunaProfile::beginProfile() -{ -#ifdef NL_DEBUG - nlassert(_Bot->canMove ()); -#endif -} - -void CEatCorpseFaunaProfile::endProfile() -{ - CAIEntityPhysical *const entity=CAIS::instance().getEntityPhysical(_eated); - - if (entity) - { - CSpawnBotFauna const* const botFauna = NLMISC::safe_cast(entity); - IAIProfile* const profile = botFauna->getAIProfile(); - - if (_Bot) - { - float pieceOffood=_Bot->radius()*(1.f/3.f); - - if (pieceOffood>=entity->food()) - { - pieceOffood=entity->food(); - entity->food()=0; - } - else - { - entity->food()-=pieceOffood; - } - - _Bot->hungry()-=pieceOffood; - if (_Bot->food()<0) - _Bot->food()=0; - } - - if ( profile - && profile->getAIProfileType()==AITYPES::ACTIVITY_CORPSE) - { - CCorpseFaunaProfile *const corpseProfile=NLMISC::safe_cast(profile); - corpseProfile->setEater(false); - corpseProfile->setEated(_Bot->food()==0); - } - } -} - -void CEatCorpseFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(EatCorpseFaunaProfileUpdate) - CFollowPathContext fpcEatCorpseFaunaProfileUpdate("EatCorpseFaunaProfileUpdate"); - - CAIEntityPhysical *const entity=CAIS::instance().getEntityPhysical(_eated); - - if (entity) - { - _Bot->setTarget(entity); - - if ( !_atGoodDist - && _Bot->canMove()) - { - float dist=(float) entity->pos().quickDistTo(_Bot->pos()); - if (dist>0.5f) // 0.5f far - { - if (!_Bot->canMove()) - { - return; - } - - float moveDist=_Bot->runSpeed()*ticksSinceLastUpdate; - if (moveDist>dist*0.25f) // do go too far .. - { - moveDist=dist*0.25f; - } - - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _PathCont, - moveDist, - moveDist*.5f, - .3f); - - if (status==CFollowPath::FOLLOW_NO_PATH) - { - _Bot->setDefaultComportment(); // .. gives the control to its group. - return; - } - - if (status!=CFollowPath::FOLLOW_ARRIVED) - { - return; - } - } - - _atGoodDist=true; - _Bot->setTheta(_Bot->pos().angleTo(entity->pos())); - _Bot->setMode(MBEHAV::EAT); - _eatTimer.set(100); // ten seconds to eat a corpse (vorace!). - - - const CSpawnBotFauna *const botFauna=NLMISC::safe_cast(entity); - IAIProfile* const profile = botFauna->getAIProfile(); - if ( profile - && profile->getAIProfileType()==AITYPES::ACTIVITY_CORPSE) - { - CCorpseFaunaProfile *corpseProfile=NLMISC::safe_cast(profile); - corpseProfile->setEater(true); - } - return; - } - else - { - if (!_eatTimer.test()) // did he finished to eat the corpse ? - return; - } - } - _Bot->setDefaultComportment(); // .. gives the control to its group. -} - -std::string CEatCorpseFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("eat_corpse fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CCuriosityFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CCuriosityFaunaProfile::CCuriosityFaunaProfile(CProfileOwner* owner, TDataSetRow const& player, RYAI_MAP_CRUNCH::TAStarFlag flag) -: CAIBaseProfile() -, _Bot(NLMISC::safe_cast(owner)) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _player(player) -, _atGoodDist(false) -, _Flag(flag) -, _PathCont(flag) -{ -#ifdef NL_DEBUG - nlassert(owner); -#endif -} - -void CCuriosityFaunaProfile::beginProfile() -{ -#ifdef NL_DEBUG - nlassert(_Bot->canMove ()); -#endif - _curiosityTimer.set(100+CAIS::rand32(100)); // i give you 10 to 20 sec of my time - _addCuriosityTime=30+CAIS::rand32(30); // 3 to 6 seconds to say hello. - _Bot->setMode(MBEHAV::NORMAL); - _TooFar=true; -} - -void CCuriosityFaunaProfile::endProfile() -{ - _Bot->timeBeforeNextCuriosity().set((CAIS::rand32(120)+120)*10*3); // consider every 2 to 4 minutes; - _Bot->setVisualTarget(NULL); -} - -void CCuriosityFaunaProfile::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CuriosityFaunaProfileUpdate) - CFollowPathContext fpcCuriosityFaunaProfileUpdate("CuriosityFaunaProfileUpdate"); - - if (_curiosityTimer.test()) - { - _Bot->setDefaultComportment(); // .. gives the control to its group. - return; - } - - CAIEntityPhysical *const entity=CAIS::instance().getEntityPhysical(_player); - - if (entity) - { - - if ( !entity->wpos().isValid() - || (entity->wpos().getFlags()&_Flag)!=0 // we don't want to follow player there .. - || !entity->isAlive()) - { - _Bot->setDefaultComportment(); // .. gives the control to its group. - return; - } - - _Bot->setVisualTarget(entity); - - float dist=(float) entity->pos().quickDistTo(_Bot->pos()); - if (dist>(1.f+getDistBetWeen (*_Bot, *entity)) ) // 1.f too far - { - _TooFar=true; - - if (!_Bot->canMove()) - { - return; - } - - _PathCont.setDestination(AITYPES::vp_auto, CAIVector(entity->pos())); - - float speedCoef=1.f/(dist*0.1f+1.f); - float moveDist=(speedCoef*_Bot->walkSpeed()+(1.f-speedCoef)*_Bot->runSpeed())*ticksSinceLastUpdate; - if (moveDist>dist*0.5f) // do go too far .. - { - moveDist=dist*0.5f; - } - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _PathCont, - moveDist, - moveDist*.5f, - .3f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - _Bot->setDefaultComportment(); - } - return; - } - - if (_TooFar) // just arrived ? - { - _Bot->setTheta(_Bot->pos().angleTo(entity->pos())); - _Bot->setMode(MBEHAV::ALERT); - - _curiosityTimer.set((uint32)(_curiosityTimer.timeRemaining()*0.5f+_addCuriosityTime)); // ten seconds to say hello (cute!). - _TooFar=false; - } - - } -} - -std::string CCuriosityFaunaProfile::getOneLineInfoString() const -{ - return NLMISC::toString("curiosity fauna profile"); -} - -////////////////////////////////////////////////////////////////////////////// -// CCorpseFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -CCorpseFaunaProfile::CCorpseFaunaProfile(CProfileOwner* owner) -: CAIBaseProfile() -, _Bot(NLMISC::safe_cast(owner)) -, _HaveEater(false) -, _Eated(false) -{ -} - -inline -void CCorpseFaunaProfile::beginProfile() -{ - _Bot->setTarget(NULL); - _Bot->setMode(MBEHAV::DEATH); -} - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_profile_fauna.h b/code/ryzom/server/src/ai_service/ai_profile_fauna.h deleted file mode 100644 index e85f2b709..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_fauna.h +++ /dev/null @@ -1,372 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -/** - * This file defines the classes: - * - CPlanteIdleFaunaProfile - * - CStaticPlanteIdleFaunaProfile - * - CAIFaunaActivityBaseSpawnProfile - * - CWanderFaunaProfile - * - CStaticWanderFaunaProfile - * - CGrazeFaunaProfile - * - CStaticGrazeFaunaProfile - * - CRestFaunaProfile - * - CStaticRestFaunaProfile - * - CStaticFightFaunaProfile - * - CCorpseFaunaProfileFactory - * - CEatCorpseFaunaProfile - * - CStaticEatCorpseFaunaProfile - * - CCuriosityFaunaProfile - * - CStaticCuriosityFaunaProfile - */ - -#ifndef AI_PROFILE_FAUNA_H -#define AI_PROFILE_FAUNA_H - -#include "profile.h" // for CAIBaseProfile -#include "path_behaviors.h" // for CPathPosition -#include "ai_bot_fauna.h" // for CCorpseFaunaProfile -#include "ai_grp_fauna.h" -#include "ai_mgr_fauna.h" - -class CSpawnBotFauna; -class CMovementMagnet; - -// --------------------------------------------------------------------------- -// Debug defines -// --------------------------------------------------------------------------- -// COMPACT_POS_WARNINGS compress flooding warnings concerning path problems. -// Positions where the problems occures are stored and displayed and cleared -// every minute. -// :TODO: /!\ As it cannot be tested without long-time run with several -// players the following define can be commented to restore previous behavior. -#define COMPACT_POS_WARNINGS 1 - -class CFaunaProfileFloodLogger -{ -public: - typedef std::map TLogPositions; - -public: - CFaunaProfileFloodLogger(int period) - : logLastTick(0) - , logPeriod(period) - { - } - -public: - TLogPositions logPositions; - int logLastTick; - int logPeriod; -}; - -////////////////////////////////////////////////////////////////////////////// -// CPlanteIdleFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CPlanteIdleFaunaProfile -: public CAIBaseProfile -{ -public: - CPlanteIdleFaunaProfile(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_PLANTIDLE; } - virtual std::string getOneLineInfoString() const; - //@} - -protected: - CSpawnBotFauna* _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIFaunaActivityBaseSpawnProfile // -////////////////////////////////////////////////////////////////////////////// - -class CAIFaunaActivityBaseSpawnProfile -: public CAIBaseProfile -, public IMouvementMagnetOwner -{ -public: - CAIFaunaActivityBaseSpawnProfile(CProfileOwner* owner); - - virtual NLMISC::CSmartPtr const& getMovementMagnet() const; - -protected: - NLMISC::CSmartPtr _MovementMagnet; - CPathPosition _PathPos; - bool _OutOfMagnet; -}; - -////////////////////////////////////////////////////////////////////////////// -// CWanderFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CWanderFaunaProfile -: public CAIFaunaActivityBaseSpawnProfile -{ -public: - CWanderFaunaProfile(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_WANDERING; } - virtual std::string getOneLineInfoString() const; - //@} - -protected: - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - CSpawnBotFauna* _Bot; - double _magnetDistSq; ///< square distance from bot to his magnet at last move - static CFaunaProfileFloodLogger _FloodLogger; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrazeFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CGrazeFaunaProfile -: public CAIFaunaActivityBaseSpawnProfile -{ -public: - CGrazeFaunaProfile(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_GRAZING; } - virtual std::string getOneLineInfoString() const; - //@} - -protected: - CSpawnBotFauna* _Bot; -private: - CAITimer _CycleTimer; - uint _CycleTimerBaseTime; - bool _ArrivedInZone; - double _magnetDistSq; ///< square distance from bot to his magnet at last move - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - static CFaunaProfileFloodLogger _FloodLogger; -}; - -////////////////////////////////////////////////////////////////////////////// -// CRestFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CRestFaunaProfile -: public CAIFaunaActivityBaseSpawnProfile -{ -public: - CRestFaunaProfile(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_RESTING; } - virtual std::string getOneLineInfoString() const; - //@} - -protected: - CSpawnBotFauna* _Bot; -private: - CAITimer _CycleTimer; - uint _CycleTimerBaseTime; - bool _ArrivedInZone; - double _magnetDistSq; // square distance from bot to his magnet at last move - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; - static CFaunaProfileFloodLogger _FloodLogger; -}; - -////////////////////////////////////////////////////////////////////////////// -// CEatCorpseFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CEatCorpseFaunaProfile -: public CAIBaseProfile -{ -public: - CEatCorpseFaunaProfile(CProfileOwner* owner, TDataSetRow const& corpse, RYAI_MAP_CRUNCH::TAStarFlag flag); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_EAT_CORPSE; } - virtual std::string getOneLineInfoString() const; - //@} - - TDataSetRow _eated; -protected: - CSpawnBotFauna* _Bot; -private: - bool _atGoodDist; - CAITimer _eatTimer; - CPathPosition _PathPos; - CPathCont _PathCont; -}; - -////////////////////////////////////////////////////////////////////////////// -// CCuriosityFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CCuriosityFaunaProfile -: public CAIBaseProfile -{ -public: - CCuriosityFaunaProfile(CProfileOwner* owner, TDataSetRow const& player, RYAI_MAP_CRUNCH::TAStarFlag flag); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_CURIOSITY; } - virtual std::string getOneLineInfoString() const; - //@} - - TDataSetRow _player; -protected: - CSpawnBotFauna* _Bot; -private: - bool _atGoodDist; - CAITimer _curiosityTimer; - CPathPosition _PathPos; - CPathCont _PathCont; - uint32 _addCuriosityTime; - bool _TooFar; - RYAI_MAP_CRUNCH::TAStarFlag _Flag; -}; - -////////////////////////////////////////////////////////////////////////////// -// CCorpseFaunaProfile // -////////////////////////////////////////////////////////////////////////////// - -class CCorpseFaunaProfile -: public CAIBaseProfile -{ -public: - CCorpseFaunaProfile(CProfileOwner* owner); - - virtual void beginProfile(); - - virtual void endProfile() { } - - virtual void updateProfile(uint ticksSinceLastUpdate) { } - - virtual std::string getOneLineInfoString() const { return NLMISC::toString("corpse fauna profile"); } - - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_CORPSE; } - - bool eated() const { return _Eated; } - void setEated(bool eated) { _Eated = eated; } - - void setEater(bool eater) { _HaveEater = eater; } - bool haveEater() const { return _HaveEater; } - -protected: - CSpawnBotFauna* _Bot; - -private: - bool _HaveEater; - bool _Eated; -}; - -/****************************************************************************/ -/* Profile factories */ -/****************************************************************************/ - -//- Simple profile factories ------------------------------------------------- - -// CPlanteIdleFaunaProfileFactory -typedef CAIGenericProfileFactory CPlanteIdleFaunaProfileFactory; - -// CWanderFaunaProfileFactory -typedef CAIGenericProfileFactory CWanderFaunaProfileFactory; - -// CGrazeFaunaProfileFactory -typedef CAIGenericProfileFactory CGrazeFaunaProfileFactory; - -// CRestFaunaProfileFactory -typedef CAIGenericProfileFactory CRestFaunaProfileFactory; - -// CCorpseFaunaProfileFactory -typedef CAIGenericProfileFactory CCorpseFaunaProfileFactory; - -//- Complex profile factories ------------------------------------------------ - -// CStaticFightFaunaProfile -class CFightFaunaProfileFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { - return NULL; - } -}; - -// CStaticEatCorpseFaunaProfile -class CEatCorpseFaunaProfileFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { - #ifdef NL_DEBUG - nlassert(false); - #endif - return NULL; - } -}; - -// CStaticCuriosityFaunaProfile -class CCuriosityFaunaProfileFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { -#ifdef NL_DEBUG - nlassert(false); -#endif - return NULL; - } -}; - -//- Profile factories singletons --------------------------------------------- - -extern CPlanteIdleFaunaProfileFactory PlanteIdleFaunaProfileFactory; -extern CWanderFaunaProfileFactory WanderFaunaProfileFactory; -extern CGrazeFaunaProfileFactory GrazeFaunaProfileFactory; -extern CRestFaunaProfileFactory RestFaunaProfileFactory; -extern CFightFaunaProfileFactory FightFaunaProfileFactory; -extern CCorpseFaunaProfileFactory CorpseFaunaProfileFactory; -extern CEatCorpseFaunaProfileFactory EatCorpseFaunaProfileFactory; -extern CCuriosityFaunaProfileFactory CuriosityFaunaProfileFactory; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_profile_fauna_inline.h b/code/ryzom/server/src/ai_service/ai_profile_fauna_inline.h deleted file mode 100644 index 0cd9a9aca..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_fauna_inline.h +++ /dev/null @@ -1,22 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef AI_PROFILE_FAUNA_INLINE_H -#define AI_PROFILE_FAUNA_INLINE_H - -// This file is now obsolete - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_profile_npc.cpp b/code/ryzom/server/src/ai_service/ai_profile_npc.cpp deleted file mode 100644 index 73c0bddcb..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_npc.cpp +++ /dev/null @@ -1,4720 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "profile.h" -#include "ai_bot_npc.h" -#include "ai_grp_npc.h" -#include "ai_mgr_npc.h" -#include "ai_grp_fauna.h" - -#include "ai_bot_fauna.h" - -#include "states.h" -#include "path_behaviors.h" -#include "ai_aggro.h" -#include "ai_player.h" -#include "ai_generic_fight.h" -#include "ai_profile_npc.h" -#include "group_profile.h" - -extern bool simulateBug(int bugId); - -#include "dyn_grp_inline.h" - -using namespace std; -using namespace RYAI_MAP_CRUNCH; -using namespace NLMISC; -using namespace NLNET; -using namespace AITYPES; - -// Global configuration variables -extern CVariable DefaultWanderMinTimer; -extern CVariable DefaultWanderMaxTimer; -extern CVariable FameForGuardAttack; -extern CVariable FameForGuardHelp; - -// Stuff used for management of log messages -bool ai_profile_npc_VerboseLog = false; - -void ai_profile_npc_LOG(std::string const& type, std::string const& profile, std::string const& step, std::string const& object) -{ - static size_t maxType = 0; - static size_t maxProfile = 0; - static size_t maxStep = 0; - static size_t maxObject = 0; - if (ai_profile_npc_VerboseLog) - { - maxType = std::max(maxType, type.length()); - maxProfile = std::max(maxProfile, profile.length()); - maxStep = std::max(maxStep, step.length()); - maxObject = std::max(maxObject, object.length()); - std::string log = "profile"; - log += " " + type + std::string(maxType - type.length(), ' '); - log += " " + profile + std::string(maxProfile - profile.length(), ' '); - log += " " + step + std::string(maxStep - step.length(), ' '); - log += " " + object + std::string(maxObject - object.length(), ' '); - nlinfo("%s", log.c_str()); - } -} -#define PROFILE_LOG(type,profile,step,object) ai_profile_npc_LOG(type,profile,step,object) - -#define LOG if (!ai_profile_npc_VerboseLog) {} else nlinfo - -NLMISC_COMMAND(verboseAIProfiles,"Turn on or off or check the state of verbose ai profile info logging","") -{ - if(args.size()>1) - return false; - - if(args.size()==1) - StrToBool (ai_profile_npc_VerboseLog, args[0]); - - nlinfo("VerboseLogging is %s",ai_profile_npc_VerboseLog?"ON":"OFF"); - return true; -} - -/****************************************************************************/ -/* Local classes */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightNpc // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFightNpc -: public CBotProfileFight -{ -public: - CBotProfileFightNpc(CProfileOwner* owner, CAIEntityPhysical* ennemy); - virtual ~CBotProfileFightNpc(); - - virtual std::string getOneLineInfoString() const { return "fight npc bot profile"; } - - void noMoreTarget(); - - void eventBeginFight(); - void eventTargetKilled(); -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHealNpc // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileHealNpc -: public CBotProfileHeal -, public IAIEntityPhysicalHealer -{ -public: - CBotProfileHealNpc(CAIEntityPhysical* target, CProfileOwner* owner); - virtual ~CBotProfileHealNpc(); - - virtual std::string getOneLineInfoString() const { return "heal npc bot profile"; } - - void noMoreTarget(); - - virtual void healerAdded(CAIEntityPhysical* entity); - virtual void healerRemoved(CAIEntityPhysical* entity); - -// void eventBeginFight(); -// void eventTargetKilled(); -private: - CAIEntityPhysical* _Target; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFightNpc // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileReturnAfterFightNpc -: public CBotProfileReturnAfterFight -{ -public: - CBotProfileReturnAfterFightNpc(CSpawnBotNpc* owner); - ~CBotProfileReturnAfterFightNpc(); - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual std::string getOneLineInfoString() const; - -// virtual NLMISC::CSmartPtr const& getMovementMagnet() const { return _MovementMagnet; } - -private: - CPathCont _PathCont; - NLMISC::CSmartPtr _MoveProfile; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileTribu // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileTribu : public CGrpProfileNormal -{ -public: - CGrpProfileTribu(CProfileOwner *owner); - virtual ~CGrpProfileTribu(); - - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - - virtual std::string getOneLineInfoString() const; - - virtual TProfiles getAIProfileType() const { return ACTIVITY_TRIBU; } - -private: - CAIVector _CenterPos; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileStandOnVertices // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileStandAtStartPoint -: public CMoveProfile -{ -public: - CGrpProfileStandAtStartPoint(CProfileOwner* owner); - virtual ~CGrpProfileStandAtStartPoint(); - - class CBotPositionner : public CRefCount - { - public: - CBotPositionner(RYAI_MAP_CRUNCH::TAStarFlag flags); - CBotPositionner(TVerticalPos verticalPos, CAIPos position, RYAI_MAP_CRUNCH::TAStarFlag flag); - virtual ~CBotPositionner(); - void setBotAtDest(bool atDest = true); - bool isBotAtDest() const; - - CPathCont _PathCont; - CAIPos _Position; - TVerticalPos _VerticalPos; - private: - bool _BotAtDest; - }; - - CPathCont* getPathCont(CBot const* bot); - - virtual void beginProfile(); - void resumeProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - - void addBot(CBot* bot); - void removeBot(CBot* bot); - - void setCurrentValidPos(); - - virtual TProfiles getAIProfileType() const { return MOVE_STAND_ON_VERTICES; } - virtual std::string getOneLineInfoString() const; - -private: - typedef std::map > TNpcBotPositionnerMap; - - TNpcBotPositionnerMap _NpcList; - bool _Finished; -}; - -/****************************************************************************/ -/* Local profile factories */ -/****************************************************************************/ - -//- Simple profile factories (based on generic factory) ---------------------- - -// CGrpProfileFightFactory -typedef CAIGenericProfileFactory CGrpProfileFightFactory; - -// CGrpProfileTribuFactory -typedef CAIGenericProfileFactory CGrpProfileTribuFactory; - -// CGrpProfileIdleFactory -typedef CAIGenericProfileFactory CGrpProfileIdleFactory; - -// CGrpProfileStandAtStartPointFactory -typedef CAIGenericProfileFactory CGrpProfileStandAtStartPointFactory; - -//- Singleton profiles (stateless ones) -------------------------------------- -extern CGrpProfileFightFactory GrpProfileFightFactory; - -/****************************************************************************/ -/* Implementations */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CSpawnGroupNpc // -////////////////////////////////////////////////////////////////////////////// - -void CSpawnGroupNpc::botHaveDied(CBotNpc* bot) -{ - // check bot profile type and update group profile bot list. - if (fightProfile().getAIProfile()) - { - CSlaveProfile* const profile = NLMISC::type_cast(fightProfile().getAIProfile()); - if (profile) - profile->removeBot(bot); - } - if (movingProfile().getAIProfile()) - { - CSlaveProfile* const profile = NLMISC::type_cast(movingProfile().getAIProfile()); - if (profile) - profile->removeBot(bot); - } - - { - CSpawnBotNpc* const spawn = bot->getSpawn(); - if (spawn) - spawn->setAIProfile(BotProfileStandAtPosFactory.createAIProfile(spawn)); - } -} - -void CSpawnGroupNpc::botHaveDespawn(CBotNpc* bot) -{ - CSpawnGroupNpc::botHaveDied(bot); -} - -void CSpawnGroupNpc::botHaveSpawn(CBotNpc* bot) -{ - if (movingProfile().getAIProfile()) - { - NLMISC::safe_cast(movingProfile().getAIProfile())->addBot(bot); - } - if (fightProfile().getAIProfile()) - { - NLMISC::safe_cast(fightProfile().getAIProfile())->addBot(bot); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFightNpc // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileFightNpc::CBotProfileFightNpc(CProfileOwner* owner, CAIEntityPhysical* ennemy) -: CBotProfileFight(owner, ennemy) -{ - PROFILE_LOG("bot", "fight_npc", "ctor", ""); -} - -CBotProfileFightNpc::~CBotProfileFightNpc() -{ - PROFILE_LOG("bot", "fight_npc", "dtor", ""); -} - -void CBotProfileFightNpc::noMoreTarget() -{ - _Bot->setAIProfile(BotProfileStandAtPosFactory.createAIProfile(_Bot.ptr())); -} - -void CBotProfileFightNpc::eventBeginFight() -{ - TempSpeaker = _Bot; - CSpawnBotNpc* spawnable = NLMISC::safe_cast(_Bot.ptr()); - CGroupNpc* grpNpc = static_cast(spawnable->getPersistent().getOwner()); - grpNpc->processStateEvent(grpNpc->getEventContainer().EventBotBeginFight); - TempSpeaker = NULL; -} -void CBotProfileFightNpc::eventTargetKilled() -{ - TempSpeaker = _Bot; - CSpawnBotNpc* spawnable= NLMISC::safe_cast(_Bot.ptr()); - CGroupNpc* grpNpc = static_cast(spawnable->getPersistent().getOwner()); - grpNpc->processStateEvent(grpNpc->getEventContainer().EventBotTargetKilled); - TempSpeaker = NULL; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileHealNpc // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileHealNpc::CBotProfileHealNpc(CAIEntityPhysical* target, CProfileOwner* owner) -: CBotProfileHeal(target->dataSetRow(), owner) -, _Target(target) -{ - PROFILE_LOG("bot", "heal_npc", "ctor", ""); - if (_Target) - _Target->addHealer(this); -} - -CBotProfileHealNpc::~CBotProfileHealNpc() -{ - PROFILE_LOG("bot", "heal_npc", "dtor", ""); - if (_Target) - _Target->delHealer(this); -} - -void CBotProfileHealNpc::healerAdded(CAIEntityPhysical* entity) -{ -} - -void CBotProfileHealNpc::healerRemoved(CAIEntityPhysical* entity) -{ - if (_Target == entity) - _Target = NULL; -} - -void CBotProfileHealNpc::noMoreTarget() -{ - _Bot->setAIProfile(BotProfileStandAtPosFactory.createAIProfile(_Bot.ptr())); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileReturnAfterFightNpc // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileReturnAfterFightNpc::CBotProfileReturnAfterFightNpc(CSpawnBotNpc* owner) -: CBotProfileReturnAfterFight(owner) -, _PathCont(owner->getPersistent().getOwner()->getAStarFlag()) -{ - PROFILE_LOG("bot_npc", "return_after_fight", "ctor", ""); -// CSpawnBotNpc* bot = NLMISC::safe_cast(owner); -// RYAI_MAP_CRUNCH::TAStarFlag denyFlags = bot->getAStarFlag(); - _PathCont.setDestination(owner->getReturnPos()); - _MoveProfile = NLMISC::CSmartPtr(new CBotProfileFollowPos(&_PathCont, owner)); -} - -CBotProfileReturnAfterFightNpc::~CBotProfileReturnAfterFightNpc() -{ - PROFILE_LOG("bot_npc", "return_after_fight", "dtor", ""); -} - -void CBotProfileReturnAfterFightNpc::beginProfile() -{ - PROFILE_LOG("bot_npc", "return_after_fight", "begin", ""); - CBotProfileReturnAfterFight::beginProfile(); - _Bot->ignoreReturnAggro(true); - _MoveProfile->beginProfile(); -} - -void CBotProfileReturnAfterFightNpc::endProfile() -{ - PROFILE_LOG("bot_npc", "return_after_fight", "end", ""); - _MoveProfile->endProfile(); - _Bot->ignoreReturnAggro(false); - CBotProfileReturnAfterFight::endProfile(); -} - -void CBotProfileReturnAfterFightNpc::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CBotProfileReturnAfterFightFaunaUpdate); - CBotProfileReturnAfterFight::updateProfile(ticksSinceLastUpdate); - _MoveProfile->updateProfile(ticksSinceLastUpdate); -} - -std::string CBotProfileReturnAfterFightNpc::getOneLineInfoString() const -{ - std::string info = "return_after_fight npc bot profile"; - info += " ("; - info += _MoveProfile?_MoveProfile->getOneLineInfoString():std::string(""); - info += ")"; - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFight // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileFight::CGrpProfileFight(CProfileOwner *owner) -: CFightProfile(owner) -, CFightOrganizer() -, _WasRunning(false) -{ - PROFILE_LOG("group", "fight", "ctor", ""); -} - -CGrpProfileFight::~CGrpProfileFight() -{ - PROFILE_LOG("group", "fight", "dtor", ""); - for (CCont::iterator it=_Grp->bots().begin(), itEnd=_Grp->bots().end();it!=itEnd;++it) - { - CBot *bot=*it; - removeBot (bot); - } -} - -void CGrpProfileFight::beginProfile() -{ - PROFILE_LOG("group", "fight", "begin", ""); - if (_Grp->getPersistent().getGrpDynBase() != /*(CDynGrpBase*)*/NULL - && !_Grp->getPersistent().getGrpDynBase()->getFamilyBehavior().isNULL()) - { - // this is a dynamic bots groups, activate assist between groups - _CheckAround.set(CHECK_AROUND_PERIOD); - } - - _HaveEnnemy=true; - for (CCont::iterator it=_Grp->getPersistent().bots().begin(), itEnd=_Grp->getPersistent().bots().end();it!=itEnd;++it) - { - addBot (*it); - } - _WasRunning = _Grp->checkProfileParameter("running"); - if (!_WasRunning) - _Grp->addProfileParameter("running", "", 0.f); -} - -void CGrpProfileFight::endProfile() -{ - PROFILE_LOG("group", "fight", "end", ""); - if (!_WasRunning) - _Grp->removeProfileParameter("running"); -} - -void CGrpProfileFight::addBot(CBot* bot) -{ - vector::iterator it = find(_NpcList.begin(), _NpcList.end(), bot); - if (it==_NpcList.end()) - _NpcList.push_back(bot); -} - -void CGrpProfileFight::removeBot(CBot* bot) -{ - vector::iterator it = find(_NpcList.begin(), _NpcList.end(), bot); - if (it!=_NpcList.end()) - _NpcList.erase(it); -} - -void CGrpProfileFight::setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy) -{ - bot->setAIProfile(new CBotProfileFightNpc(bot, ennemy)); -} - -void CGrpProfileFight::setHeal(CSpawnBot* bot, CAIEntityPhysical* target) -{ - bot->setAIProfile(new CBotProfileHealNpc(target, bot)); -} - -void CGrpProfileFight::setNoFight(CSpawnBot* bot) -{ - if (!bot->getTarget().isNULL()) - bot->setTarget(NULL); - if ( bot->getAIProfileType()==BOT_FLEE - || bot->getAIProfileType()==BOT_FIGHT - || bot->getAIProfileType()==BOT_HEAL - || bot->getAIProfileType()==BOT_RETURN_AFTER_FIGHT ) - { - bot->setAIProfile(new CBotProfileStandAtPos(bot)); - } -} - -void CGrpProfileFight::setFlee(CSpawnBot* bot, CAIVector& fleeVect) -{ - bot->setMoveDecalage(fleeVect); - if (bot->getAIProfileType()!=BOT_FLEE) - { - bot->setAIProfile(new CBotProfileFlee(bot)); - } -} - -void CGrpProfileFight::setReturnAfterFight(CSpawnBot* bot) -{ - if (bot->getAIProfileType()!=BOT_RETURN_AFTER_FIGHT) - { - bot->setAIProfile(new CBotProfileReturnAfterFightNpc(NLMISC::safe_cast(bot))); - } -} - -bool CGrpProfileFight::stillHaveEnnemy() const -{ - return _HaveEnnemy; -} - -void CGrpProfileFight::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpFightProfileUpdate); - CFollowPathContext fpcGrpFightProfileUpdate("GrpFightProfileUpdate"); - - // check if some bots died or are despawned. - - for(uint i = 0; i < _NpcList.size();) - { - CSpawnBot *spawnBot=_NpcList[i]->getSpawnObj(); - if ( !spawnBot - || !spawnBot->isAlive()) - { - _NpcList.erase(_NpcList.begin()+i); - continue; - } - i++; - } - reorganize(_NpcList.begin(), _NpcList.end()); - - // check groups around - if (_CheckAround.test()) - { - _CheckAround.set(CHECK_AROUND_PERIOD); - - FOREACH(itBot, vector, _NpcList) - { - CBot* pBot = *itBot; - if (pBot) - { - CSpawnBot* bot = pBot->getSpawnObj(); - if (bot) - bot->propagateAggro(); - } - } - } -} - -std::string CGrpProfileFight::getOneLineInfoString() const -{ - return "fight profile"; -} - -std::vector& CGrpProfileFight::npcList() -{ - return _NpcList; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileNormal // -////////////////////////////////////////////////////////////////////////////// - -void CGrpProfileNormal::beginProfile() -{ - PROFILE_LOG("group", "normal", "begin", ""); - _GroupFighting=false; -} - -void CGrpProfileNormal::endProfile() -{ - PROFILE_LOG("group", "normal", "end", ""); - setGroupFighting(false); -} - -void CGrpProfileNormal::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpNormalProfileUpdate); - CFollowPathContext fpcGrpNormalProfileUpdate("GrpNormalProfileUpdate"); - - if (_GroupFighting) - { - if (!_Grp->fightProfile().getAIProfile()) - _Grp->fightProfile().setAIProfile(new CGrpProfileFight(_Grp)); - - _Grp->fightProfile().mayUpdateProfile(ticksSinceLastUpdate); - - CFightProfile* profile = NLMISC::safe_cast(_Grp->fightProfile().getAIProfile()); - if (!profile->stillHaveEnnemy ()) - { - // :TODO: Verify if it's needed to erase bots aggro too/instead -// _Grp->clearAggroList(); // this erase all agro. - - setGroupFighting(false); - _Grp->fightProfile().setAIProfile(NULL); - - CSlaveProfile* moveProfile = NLMISC::type_cast(_Grp->movingProfile().getAIProfile()); - if (moveProfile) - moveProfile->resumeProfile(); - } - } - else - { - if (_Grp->haveAggroOrReturnPlace()) - { - if(_Grp->isGroupAlive()) - { - // set the fighting comportment. - if (!_Grp->fightProfile().getAIProfile()) - // _Grp->fightProfile().setAIProfile(new CGrpProfileFight(_Grp)); - _Grp->fightProfile().setAIProfile(_Grp.ptr(), &GrpProfileFightFactory, false); - - setGroupFighting(true); - } - } - else - { - _Grp->movingProfile().mayUpdateProfile(ticksSinceLastUpdate); - } - } -} - -std::string CGrpProfileNormal::getOneLineInfoString() const -{ - std::string info = "normal profile"; - info += " group_fighting=" + NLMISC::toString(_GroupFighting); - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileBandit // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileBandit::CGrpProfileBandit(CProfileOwner *owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "bandit", "ctor", ""); -} - -CGrpProfileBandit::~CGrpProfileBandit() -{ - PROFILE_LOG("group", "bandit", "dtor", ""); -} - -void CGrpProfileBandit::beginProfile() -{ - PROFILE_LOG("group", "bandit", "begin", ""); - CGrpProfileNormal::beginProfile(); - - - CGroupNpc &persGrp=_Grp->getPersistent(); - - if (persGrp.isRingGrp()) - { - _AggroRange = persGrp.getAggroDist(); - } - else - { - // look for aggro range parameter or set a default value - float aggroRangeFloat = 0.f; - - if (!_Grp->getProfileParameter("aggro range", aggroRangeFloat)) - _AggroRange =static_cast( CGrpProfileBanditFactory::getDefaultBanditAggroRange() ); - else - _AggroRange = static_cast(aggroRangeFloat); - - bool resendInfo = false; - - - if (!persGrp.getPlayerAttackable ()) - { - persGrp.setPlayerAttackable (true); - resendInfo = true; - } - if (!persGrp.getBotAttackable ()) - { - persGrp.setBotAttackable (true); - resendInfo = true; - } - if (resendInfo) - _Grp->sendInfoToEGS (); - } - - -} - -void CGrpProfileBandit::endProfile() -{ - PROFILE_LOG("group", "bandit", "end", ""); - CGrpProfileNormal::endProfile(); -} - -void CGrpProfileBandit::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpBanditProfileUpdate); - CFollowPathContext fpcGrpBanditProfileUpdate("GrpBanditProfileUpdate"); - - CAIVision BanditVision; - - breakable - { - CAIVector centerPos; - if (!_Grp->calcCenterPos(centerPos)) // true if there's some bots in the group. - break; - _Grp->setCenterPos(centerPos); - - uint32 playerRadius=uint(_AggroRange); - uint32 botRadius=uint(_AggroRange); - uint32 groupPlayerRadius=playerRadius*2; - uint32 groupBotRadius=botRadius*2; - - uint32 minRadius=playerRadius>botRadius?botRadius:playerRadius; - - CFightProfile* fightProfile=static_cast(_Grp->fightProfile().getAIProfile()); - - if (fightProfile) - { - CAIVision localBanditVision; - - for (vector::iterator it=fightProfile->npcList().begin(), itEnd=fightProfile->npcList().end();it!=itEnd;++it) - { - CBot *bot=(*it); - CSpawnBot *spawnBot=bot->getSpawnObj(); - - if (!spawnBot) - continue; - - double distToCenter=centerPos.quickDistTo(spawnBot->pos()); - if (distToCenter>minRadius) // (minRadius*2) - minRadius - { - const CAIVector spawnBotPos(spawnBot->pos()); - // bot vision update. - localBanditVision.updateBotsAndPlayers(spawnBot->getAIInstance(), spawnBotPos, playerRadius, botRadius); - - // bandits don't like guards nor escorted people - { - const std::vector > &bots = localBanditVision.bots(); - std::vector >::const_iterator first(bots.begin()), last(bots.end()); - for (; first != last; ++first) - { - CAIEntityPhysical *ep = (*first)->getSpawnObj(); - if ( ep - && ep->getRyzomType()==RYZOMID::npc - && ep->isAlive()) - { - CSpawnBotNpc *botNpc = NLMISC::safe_cast(ep); - - if ( botNpc->spawnGrp().activityProfile().getAIProfileType() == ACTIVITY_GUARD - || botNpc->spawnGrp().activityProfile().getAIProfileType() == ACTIVITY_GUARD_ESCORTED - || botNpc->spawnGrp().activityProfile().getAIProfileType() == ACTIVITY_ESCORTED ) - { - spawnBot->setAggroMinimumFor(ep->dataSetRow(), 0.8f, false); - } - } - } - } - - // bandits don't like players. - { - const std::vector > &players = localBanditVision.players(); - std::vector >::const_iterator first(players.begin()), last(players.end()); - for (; first != last; ++first) - { - CPersistentOfPhysical *player = (*first); - CAIEntityPhysical *ep = player->getSpawnObj(); - if ( ep - && ep->isAlive() - && ep->currentHitPoints()>0.f) - { - const CRootCell *const rootCell=ep->wpos().getRootCell(); - if ( rootCell - && rootCell->getFlag()!=0 ) // Safe Zone ? - continue; - - spawnBot->setAggroMinimumFor(ep->dataSetRow(), 0.5f, false); - } - } - } - } - } - } - // group vision update. - BanditVision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), centerPos, playerRadius, botRadius); - } - - CGrpProfileNormal::updateProfile(ticksSinceLastUpdate); - - // check if we are in war and if some bot are waiting for a bus. - if (_GroupFighting) - { - // check if some bots are not fighting. - for (CCont::iterator it=_Grp->getPersistent().bots().begin(), itEnd=_Grp->getPersistent().bots().end();it!=itEnd;++it) - { - CBot* bot=*it; - CSpawnBot *spawnBot=bot->getSpawnObj(); - if ( spawnBot - && spawnBot->isAlive() - && spawnBot->getAIProfileType()==BOT_STAND_AT_POS) - { - // :KLUDGE: We verify here that we have a moving profile, to prevent some crashes - // :TODO: Remove that check and make sure a group always have a moving profile (even if none is defined in primitives) - if (_Grp->movingProfile().getAIProfile()) - { - CMoveProfile *moveProf=NLMISC::safe_cast(_Grp->movingProfile().getAIProfile()); - moveProf->resumeBot(bot); - } - } - } - } - - // bandits don't like guards nor escorted people - { - const std::vector > &bots = BanditVision.bots(); - std::vector >::const_iterator first(bots.begin()), last(bots.end()); - for (; first != last; ++first) - { - CAIEntityPhysical *const ep = (*first)->getSpawnObj(); - if ( !ep - || ep->getRyzomType()!=RYZOMID::npc - || !ep->isAlive()) - continue; - - const CSpawnBot *const bot = NLMISC::safe_cast(ep); - - const TProfiles profileType=bot->spawnGrp().activityProfile().getAIProfileType(); - if ( profileType != ACTIVITY_GUARD - && profileType != ACTIVITY_GUARD_ESCORTED - && profileType != ACTIVITY_ESCORTED ) - continue; - - _Grp->setAggroMinimumFor(ep->dataSetRow(), 0.8f, false); - } - } - - // bandits don't like players. - { - const std::vector > &players = BanditVision.players(); - - std::vector >::const_iterator first(players.begin()), last(players.end()); - for (; first != last; ++first) - { - CPersistentOfPhysical*const player = (*first); - CAIEntityPhysical*const ep = player->getSpawnObj(); - - if ( ep - && ep->isAlive() - && ep->currentHitPoints()>0.f) // not in safe zone. - { - const CRootCell *const rootCell=ep->wpos().getRootCell(); - if ( rootCell - && rootCell->getFlag()!=0 ) // Safe Zone ? - continue; - - _Grp->setAggroMinimumFor(ep->dataSetRow(), 0.5f, false); - } - } - } -} - -std::string CGrpProfileBandit::getOneLineInfoString() const -{ - std::string info = "bandit profile"; - info += " aggro_range=" + NLMISC::toString(_AggroRange); - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGuard // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileGuard::CGrpProfileGuard(CProfileOwner *owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "guard", "ctor", ""); -} - -CGrpProfileGuard::~CGrpProfileGuard() -{ - PROFILE_LOG("group", "guard", "dtor", ""); -} - -void CGrpProfileGuard::beginProfile() -{ - PROFILE_LOG("group", "guard", "begin", ""); - CGrpProfileNormal::beginProfile(); - CGroupNpc &persGrp=_Grp->getPersistent(); - - if (persGrp.isRingGrp()) - { - _AggroRange = persGrp.getAggroDist(); - } - else - { - _AggroRange = 25; - } -} - -void CGrpProfileGuard::endProfile() -{ - PROFILE_LOG("group", "guard", "end", ""); - CGrpProfileNormal::endProfile(); -} - -void CGrpProfileGuard::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpGuardProfileUpdate); - CFollowPathContext fpcGrpGuardProfileUpdate("GrpGuardProfileUpdate"); - - CAIVision GuardVision; - const uint32 aggroSize=uint32(_AggroRange); - - TTicks startVisionTime = CTime::getPerformanceTime(); - - { - H_AUTO(GrpGuardProfileVision); - CAIVector centerPos; - if (_Grp->calcCenterPos(centerPos)) // true if there's some bots in the group. - { - _Grp->setCenterPos(centerPos); - if (!_GroupFighting) - _CenterPos=_Grp->getCenterPos(); - GuardVision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), _CenterPos, aggroSize, aggroSize); - } - } - - TTicks endVisionTime = CTime::getPerformanceTime(); - - static uint32 s_maxBotsVisible = 0; - static double s_maxBotsVisionTime = 0.0; - - uint32 numBotsVisible = (uint32)GuardVision.bots().size(); - double deltaVisionTime = CTime::ticksToSecond(endVisionTime-startVisionTime); - bool bTellUs = false; - if( s_maxBotsVisible < numBotsVisible ) - { - s_maxBotsVisible = numBotsVisible; - bTellUs = true; - } - - if( s_maxBotsVisionTime < deltaVisionTime ) - { - s_maxBotsVisionTime = deltaVisionTime; - bTellUs = true; - } - - if( bTellUs ) - { - nldebug( "==> max bots visible is now %u", s_maxBotsVisible ); - nldebug( "vision time: %.2f", (float)(deltaVisionTime * 1000.0) ); - } - - uint32 factionIndex=CStaticFames::INVALID_FACTION_INDEX; - sint32 fameForGuardAttack = FameForGuardAttack; - { - H_AUTO(GrpGuardProfileFaction); - CAliasCont &bots = _Grp->getPersistent().bots(); - if (!bots.size() != 0 && bots.begin() != bots.end()) - { - CBot* bot = *(bots.begin()); - if (bot != NULL) - { - factionIndex=bot->getSheet()->FactionIndex(); - if (bot->getSheet()->FameForGuardAttack() != AISHEETS::ICreature::InvalidFameForGuardAttack) - fameForGuardAttack = bot->getSheet()->FameForGuardAttack(); - -/* if (factionIndex == CStaticFames::INVALID_FACTION_INDEX) - { - nlwarning("Bot sheet '%s' have invalid faction index (guard profile)", bot->getSheet()->SheetId().toString().c_str()); - } -*/ - } - } - } - - string s; - float f = 0.f; - if (_Grp->getProfileParameter("faction", s) && !s.empty()) - { - factionIndex = CStaticFames::getInstance().getFactionIndex(s); - } - if (_Grp->getProfileParameter("fame_for_guard_attack", f)) - { - fameForGuardAttack = (sint32)f; - } - - CGrpProfileNormal::updateProfile(ticksSinceLastUpdate); - - // check if we are in war and if some bot are waiting for a bus. - if (_GroupFighting) - { - H_AUTO(GrpGuardProfileFighting); - const CAIVector centerPos(_Grp->getCenterPos()); - - // check if some bots are not fighting. - for (CCont::iterator it=_Grp->getPersistent().bots().begin(), itEnd=_Grp->getPersistent().bots().end();it!=itEnd;++it) - { - const CBot*const bot=*it; - CSpawnBot *const spawnBot=bot->getSpawnObj(); - if ( spawnBot - && spawnBot->isAlive()) - { - switch(spawnBot->getAIProfileType()) - { - case BOT_STAND_AT_POS: - { - CMoveProfile*const moveProf=NLMISC::type_cast(_Grp->movingProfile().getAIProfile()); - if (moveProf) - moveProf->resumeBot(bot); - } - break; - case BOT_FIGHT: - { - // This system is now managed by CBotAggroOwner itself - /* - const CAIEntityPhysical*const target=spawnBot->getTarget(); - if (target) - { - // if target is out of range, then forget the aggro. - if (centerPos.quickDistTo(target->pos())>50) - { - spawnBot->forgetAggroFor(target->dataSetRow()); - _Grp->forgetAggroFor(target->dataSetRow()); - } - } - */ - } - break; - default: - break; - } - } - } - } - - // guards don't like bandits. - { - H_AUTO(GrpGuardProfileBandits); - const std::vector > &bots = GuardVision.bots(); - std::vector >::const_iterator first(bots.begin()), last(bots.end()); - for (; first != last; ++first) - { - const CAIEntityPhysical *const ep = (*first)->getSpawnObj(); - if (ep->isAlive()) - { - switch (ep->getRyzomType()) - { - case RYZOMID::npc: - { - const CSpawnBotNpc *const botNpc = NLMISC::safe_cast(ep); - - if (botNpc->spawnGrp().activityProfile().getAIProfileType() == ACTIVITY_BANDIT) - { - if (_CenterPos.quickDistTo(botNpc->pos())setAggroMinimumFor(ep->dataSetRow(), 0.5f, false); - } - } - } - break; - case RYZOMID::creature: - { - const CSpawnBotFauna *const botFauna = NLMISC::safe_cast(ep); - - if (botFauna->getPersistent().faunaType()==FaunaTypePredator) - { - if (_CenterPos.quickDistTo(botFauna->pos())setAggroMinimumFor(ep->dataSetRow(), 0.5f, false); - } - } - } - break; - default: - break; - } - } - } - } - - // guards don't like bots that attack players. - { - H_AUTO(GrpGuardProfileAttack); - const std::vector > &players = GuardVision.players(); - LOG("%u players in group vision with aggrosize %d", players.size(), aggroSize); - - const CAIVector ¢erPos=_Grp->getCenterPos(); - - std::vector >::const_iterator first(players.begin()), last(players.end()); - for (; first != last; ++first) - { - const CPersistentOfPhysical *const player = (*first); - CAIEntityPhysical *const ep = player->getSpawnObj(); - if ( !ep - || !ep->isAlive() - || ep->currentHitPoints()<=0.f - || ep->wpos().toAIVector().quickDistTo(centerPos)>aggroSize) - continue; - - // check Fame before choosing what to do .. - sint32 const fame = ep->getFameIndexed(factionIndex); - - // if player is kos attack him (only if bot is attackable by player) - if ((_Grp->getPersistent().getPlayerAttackable() || (factionIndex!=CStaticFames::INVALID_FACTION_INDEX && _Grp->getPersistent().isFactionAttackable(CStaticFames::getInstance().getFactionName(factionIndex), fame))) && ((factionIndex!=CStaticFames::INVALID_FACTION_INDEX && famesetAggroMinimumFor(ep->dataSetRow(), 1.f, false); - continue; - } - - // check if player is attacked and assist him). - CAIEntityPhysical const* phys = ep->firstTargeter(); - while (phys) - { - switch(phys->getRyzomType()) - { - case RYZOMID::player: - break; - case RYZOMID::npc: - { - const CSpawnBotNpc *const botNpc=dynamic_cast(phys); - if ( botNpc - && botNpc->getPersistent().getGroup().getSpawnObj()->activityProfile().getAIProfileType() == ACTIVITY_GUARD) - { - break; - } - - // guard don't attack npc of the same faction, rather, they attack the player ! - if (factionIndex != CStaticFames::INVALID_FACTION_INDEX && botNpc->getPersistent().getSheet()->FactionIndex() == factionIndex) - { - // the guard attack the player ! - _Grp->setAggroMinimumFor(ep->dataSetRow(), 1.f, false); - break; - } - } - default: - // guard defend only player with a not too bad fame - if (fame >= FameForGuardHelp && !OUTPOSTHELPERS::isAttackingFaction(factionIndex, ep)) - _Grp->setAggroMinimumFor(phys->dataSetRow(), 1.f, false); - break; - } - phys = phys->nextTargeter(); - } - } - } -} - -std::string CGrpProfileGuard::getOneLineInfoString() const -{ - return "guard profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileTribu // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileTribu::CGrpProfileTribu(CProfileOwner *owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "tribe", "ctor", ""); -} - -CGrpProfileTribu::~CGrpProfileTribu() -{ - PROFILE_LOG("group", "tribe", "dtor", ""); -} - -void CGrpProfileTribu::beginProfile() -{ - PROFILE_LOG("group", "tribe", "begin", ""); - CGrpProfileNormal::beginProfile(); -} - -void CGrpProfileTribu::endProfile() -{ - PROFILE_LOG("group", "tribe", "end", ""); - CGrpProfileNormal::endProfile(); -} - -void CGrpProfileTribu::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpTribuProfileUpdate); - CFollowPathContext fpcGrpTribuProfileUpdate("GrpTribuProfileUpdate"); - - CAIVision TribuVision; - const uint32 aggroSize=40; - - breakable - { - CAIVector centerPos; - if (!_Grp->calcCenterPos(centerPos)) // true if there's some bots in the group. - break; - - _Grp->setCenterPos(centerPos); - if (!_GroupFighting) - _CenterPos=_Grp->getCenterPos(); - TribuVision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), _CenterPos, aggroSize, aggroSize); - } - - uint32 factionIndex=CStaticFames::INVALID_FACTION_INDEX; - { - CBotNpc* bot = static_cast(*_Grp->getPersistent().bots().begin()); - factionIndex = bot->getSheet()->FactionIndex(); - } - - CGrpProfileNormal::updateProfile(ticksSinceLastUpdate); - - // check if we are in war and if some bot are waiting for a bus. - if (_GroupFighting) - { - CAIVector centerPos(_Grp->getCenterPos()); - - // check if some bots are not fighting. - for (CCont::iterator it=_Grp->getPersistent().bots().begin(), itEnd=_Grp->getPersistent().bots().end();it!=itEnd;++it) - { - const CBot*const bot=*it; - CSpawnBot *const spawnBot=bot->getSpawnObj(); - if ( !spawnBot - || !spawnBot->isAlive()) - continue; - - switch(spawnBot->getAIProfileType()) - { - case BOT_STAND_AT_POS: - { - CMoveProfile *moveProf=NLMISC::safe_cast(_Grp->movingProfile().getAIProfile()); - moveProf->resumeBot(bot); - } - break; - case BOT_FIGHT: - { - // This system is managed by CBotAggroOwner now - /* - const CAIEntityPhysical *const target=spawnBot->getTarget(); - if (!target) - break; - - // if target is out of range, then forget the aggro. - if (centerPos.quickDistTo(target->pos())<=50) - break; - - spawnBot->forgetAggroFor(target->dataSetRow()); - _Grp->forgetAggroFor(target->dataSetRow()); - */ - } - break; - default: - break; - } - } - } - - // Tribus don't like players with bad fame. - { - const std::vector > &players = TribuVision.players(); - - LOG("%u players in group vision", players.size()); - - std::vector >::const_iterator first(players.begin()), last(players.end()); - for (; first != last; ++first) - { - CPersistentOfPhysical *const player = (*first); - CAIEntityPhysical *const ep = player->getSpawnObj(); - if ( !ep - || !ep->isAlive() - || ep->currentHitPoints()<=0.f) - continue; - - const CRootCell *const rootCell=ep->wpos().getRootCell(); - if ( rootCell - && rootCell->getFlag()!=0 ) // Safe Zone ? - continue; - - // check Fame before choosing what to do .. - sint32 const fame = ep->getFameIndexed(factionIndex); - - // check if player is attacked. - if (fame<-10000 || OUTPOSTHELPERS::isAttackingFaction(factionIndex, ep)) - { - _Grp->setAggroMinimumFor(ep->dataSetRow(), 1.f, false); - } - } - } -} - -std::string CGrpProfileTribu::getOneLineInfoString() const -{ - return "tribu profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFollowRoute // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileGoToPoint::CGrpProfileGoToPoint(CProfileOwner *owner, RYAI_MAP_CRUNCH::CWorldPosition const& startPos, RYAI_MAP_CRUNCH::CWorldPosition const& endPos, bool dontSendEvent) -: CMoveProfile(owner) -, _StartPos(startPos) -, _EndPos(endPos) -, _PathCont(NLMISC::safe_cast(owner)->getPersistent().getAStarFlag()) -, _DontSendEvent(dontSendEvent) -{ - PROFILE_LOG("group", "go_to_point", "ctor", ""); - _GlobalOrient.setX(1); - _GlobalOrient.setY(0); - _FollowForward=true; - _ValidPosInit=false; - _StopNpc = false; -} - -void CGrpProfileGoToPoint::setDirection(bool forward) -{ - if ( _FollowForward==forward - && _ValidPosInit ) - return; - - _ValidPosInit=true; - _FollowForward=forward; -} - -void CGrpProfileGoToPoint::beginProfile() -{ - PROFILE_LOG("group", "go_to_point", "begin", ""); - _ProfileTerminated = false; - CMoveProfile::beginProfile(); - - setCurrentDestination(_EndPos); // * -} - -void CGrpProfileGoToPoint::stateChangeProfile() -{ - setCurrentDestination(_EndPos); // * - - // set a stand at pos profile on every bots - FOREACH(it, CAliasCont, _Grp->bots()) - { - CSpawnBot *sb = (*it)->getSpawnObj(); - if (sb) - sb->setAIProfile(new CBotProfileStandAtPos(sb)); - } - - resumeProfile(); -} - -void CGrpProfileGoToPoint::endProfile() -{ - PROFILE_LOG("group", "go_to_point", "end", ""); -} - -void CGrpProfileGoToPoint::resumeProfile() -{ - PROFILE_LOG("group", "go_to_point", "resume", ""); - FOREACH(it, TBotFollowerMap, _NpcList) - { - const CBot *const bot=it->first; - CSpawnBot *const sbot=bot->getSpawnObj(); - if (!sbot) - continue; - - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - break; - default: // push the correct comportment. - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - break; - } - - } - setCurrentDestination(_EndPos); -} - -void CGrpProfileGoToPoint::addBot(CBot* bot) -{ - _NpcList[bot] = CBotFollower(); - - CSpawnBot *sbot=bot->getSpawnObj(); - if (sbot) - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - - _MustCalcRatios = true; -} - -void CGrpProfileGoToPoint::removeBot(CBot* bot) -{ - TBotFollowerMap::iterator it=_NpcList.find(bot); - - if (it==_NpcList.end()) - return; - - CSpawnBotNpc *const spawnBot=NLMISC::safe_cast(bot)->getSpawn(); - if (spawnBot) - spawnBot->setAIProfile(BotProfileStandAtPosFactory.createAIProfile(spawnBot)); - - _NpcList.erase (it); - _MustCalcRatios = true; -} - -void CGrpProfileGoToPoint::setCurrentDestination(RYAI_MAP_CRUNCH::CWorldPosition const& dest) -{ - _PathCont.setDestination(dest); - - FOREACH(it, TBotFollowerMap, _NpcList) - it->second.setBotAtDest(false); -} - -void CGrpProfileGoToPoint::calcRatios() -{ - _MustCalcRatios = false; - - // loop to compute max speeds - _MaxRunSpeed = FLT_MAX; - _MaxWalkSpeed = FLT_MAX; - FOREACH(it, TBotFollowerMap, _NpcList) - { - CBot *bot = it->first; //static_cast(_Grp->bots()[botFollower.getIndex()]); - CSpawnBot *sbot = bot->getSpawnObj(); - if ( !sbot - || !sbot->isAlive()) - continue; - - _MaxRunSpeed = std::min(sbot->runSpeed(), _MaxRunSpeed); - _MaxWalkSpeed = std::min(sbot->walkSpeed(), _MaxWalkSpeed); - } - - - if (_Shape!=SHAPE_RECTANGLE) - return; - - const uint32 nbbots=(uint32)_NpcList.size(); - - _NbRange = (uint32) sqrt(_Ratio*nbbots); - if (_NbRange==0) - _NbRange=1; - _NbLines = nbbots/_NbRange; - _NbBotInNormalShape = _NbLines*_NbRange; - _Rest = nbbots-_NbBotInNormalShape; - - _Cx=(double(_NbRange)-1.0)*0.5; - _Cy=(double(_NbLines)-1.0)*0.5; - _Cy=(_Cy*_NbBotInNormalShape+double(_NbLines)*_Rest)/double(nbbots); -} - -void CGrpProfileGoToPoint::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CGrpGoToPointProfileUpdate); - CFollowPathContext fpcCGrpGoToPointProfileUpdate("CGrpGoToPointProfileUpdate"); - - CMoveProfile::updateProfile(ticksSinceLastUpdate); - - CSpawnGroupNpc *NpcGrp=NLMISC::safe_cast(_Grp.ptr()); - CGroupNpc &persGrp=NpcGrp->getPersistent(); - - CAIVector groupPosition = NpcGrp->getCenterPos(); - CAIVector perpGlobalOrient; - NpcGrp->calcCenterPos(groupPosition); - - uint32 nbAtDest=0; - uint32 nbNewAtDest=0; - - uint32 botIndex=0; - uint32 xIndex=0; - uint32 yIndex=0; - - double dx=0; - double dy=0; - - - if (_Shape==SHAPE_RECTANGLE) - { - perpGlobalOrient.setX(-_GlobalOrient.y()); - perpGlobalOrient.setY(_GlobalOrient.x()); - } - - ////////////////////////////////////////////////////////////////////////// - // Calcs the correct gravity grid position (must be done only when bot are removed or add to the group. - if (_MustCalcRatios) - calcRatios (); - - - FOREACH(it, TBotFollowerMap, _NpcList) - { - CBotFollower &botFollower=it->second; - if (botFollower.isBotAtDest()) - { - nbAtDest++; - continue; - } - - CBot *bot=it->first; - CSpawnBot *sbot=bot->getSpawnObj(); - if ( !sbot - || !sbot->isAlive()) - continue; - - // verify if the bot has a correct profile and if he reached the destination position. - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - { - if (_ProfileTerminated) - { - // remove the profile - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - } - else - { - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - - // flag the sub profile to stop the npc - prof->setStop(_StopNpc); - if (!_StopNpc) - { - if (prof->_Status==CFollowPath::FOLLOW_ARRIVED) - { - botFollower.setBotAtDest(); - nbNewAtDest++; - nbAtDest++; - } - else - { - // update speeds - prof->setMaxSpeeds(_MaxWalkSpeed, _MaxRunSpeed); - } - } - } - } - break; - default: // push the correct comportment. - { - if (!_ProfileTerminated) - { - sbot->setAIProfile(new CBotProfileFollowPos(&_PathCont, sbot)); - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - // update speeds - prof->setMaxSpeeds(_MaxWalkSpeed, _MaxRunSpeed); - } - } - break; - } - - if (_Shape==SHAPE_RECTANGLE) - { - NLMISC::CVector2d dir=sbot->theta().asVector2d(); - dx+=dir.x; - dy+=dir.y; - - // 4 rows - CAIVector idealPos=groupPosition; - if (botIndex>=_NbBotInNormalShape) - { - idealPos += perpGlobalOrient * (_XSize*(_Cx-double(xIndex)-(_NbRange-_Rest)*0.5)); - } - else - { - idealPos += perpGlobalOrient * (_XSize*(_Cx-double(xIndex))); - } - - idealPos+=_GlobalOrient*(_YSize*(_Cy-(double)yIndex)); - idealPos-=CAIVector(sbot->pos()); - - botIndex++; - xIndex++; - if (xIndex>=_NbRange) - { - xIndex=0; - yIndex++; - } - sbot->setMoveDecalage(idealPos); - } - } - - if (_Shape==SHAPE_RECTANGLE) - { - _GlobalOrient.setX(dx/botIndex); - _GlobalOrient.setY(dy/botIndex); - } - - // first to arrived ? - if (nbAtDest>0 && !_ProfileTerminated) - { - if (!_DontSendEvent) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedFirst); - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedAll); - } - _ProfileTerminated = true; - } -} - -CGrpProfileGoToPoint::~CGrpProfileGoToPoint() -{ - for (CCont::iterator it=_Grp->bots().begin(), itEnd=_Grp->bots().end();it!=itEnd;++it) - removeBot(*it); -} - -CGrpProfileGoToPoint::CBotFollower::CBotFollower() -: _BotAtDest(false) -{ -} - -CGrpProfileGoToPoint::CBotFollower::~CBotFollower() -{ -} - -void CGrpProfileGoToPoint::CBotFollower::setBotAtDest(bool atDest) -{ - _BotAtDest = atDest; -} - -const bool& CGrpProfileGoToPoint::CBotFollower::isBotAtDest() const -{ - return _BotAtDest; -} - -bool CGrpProfileGoToPoint::getDirection() -{ - return _FollowForward; -} - - -CPathCont* CGrpProfileGoToPoint::getPathCont(CBot const* bot) -{ - return &_PathCont; -} - -std::string CGrpProfileGoToPoint::getOneLineInfoString() const -{ - std::string info = "go_to_point profile"; - info += " stop_npc=" + NLMISC::toString(_StopNpc); - return info; -} - -bool CGrpProfileGoToPoint::profileTerminated() const -{ - return _ProfileTerminated; -} - -void CGrpProfileGoToPoint::stopNpc(bool stop) -{ - _StopNpc = stop; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGoToPoint // -////////////////////////////////////////////////////////////////////////////// - -//RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileGoToPoint, "goto_point"); - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFollowRoute // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileFollowRoute::CGrpProfileFollowRoute(CProfileOwner *owner) -: CMoveProfile(owner) -, _PathCont(NLMISC::safe_cast(owner)->getPersistent().getAStarFlag()) -, _DontSendEvent(false) -{ - PROFILE_LOG("group", "follow_route", "ctor", ""); - _GlobalOrient.setX(1); - _GlobalOrient.setY(0); - _FollowForward = true; - _StopNpc = false; - - CGroupNpc &grp=*safe_cast(&_Grp->getPersistent()); - if (grp.getState()) - { - const CAIState *const state = grp.getCAIState(); - if (state->isPositional()) - { - const CAIStatePositional *const statePositionnal=static_cast(state); - _Geometry=&statePositionnal->shape().getGeometry(); - _GeometryComeFromState = true; - _VerticalPos=statePositionnal->shape().getVerticalPos(); - return; - } - } - _GeometryComeFromState = false; - _Geometry = NULL; - _VerticalPos = TVerticalPos(); - _GeomIndex = 0; -#ifdef NL_DEBUG - nlassert(true==false); // Cannot use this constructor outside machine state context. -#endif -} - - -CGrpProfileFollowRoute::CGrpProfileFollowRoute(CProfileOwner *owner,const std::vector &geometry,const TVerticalPos &verticalPos, bool dontSendEvent) -: CMoveProfile(owner) -, _PathCont(NLMISC::safe_cast(owner)->getPersistent().getAStarFlag()) -, _GeometryComeFromState(false) -, _Geometry(&geometry) -, _VerticalPos(verticalPos) -, _DontSendEvent(dontSendEvent) -{ - PROFILE_LOG("group", "follow_route", "ctor2", ""); - _GlobalOrient.setX(1); - _GlobalOrient.setY(0); - _FollowForward=true; - _ValidPosInit=false; - _GeomIndex=0; - _StopNpc = false; -} - -void CGrpProfileFollowRoute::setDirection(bool forward) -{ - if ( _FollowForward==forward - && _ValidPosInit ) - return; - - _ValidPosInit=true; - _FollowForward=forward; -#ifdef NL_DEBUG - nlassert(_Geometry); -#endif - setCurrentValidPos(_VerticalPos); -} - -void CGrpProfileFollowRoute::beginProfile() -{ - PROFILE_LOG("group", "follow_route", "begin", ""); - _ProfileTerminated = false; - CMoveProfile::beginProfile(); - - if (_GeometryComeFromState) - assignGeometryFromState(); -} - -void CGrpProfileFollowRoute::assignGeometryFromState() -{ - _ProfileTerminated = false; - - // default value initialization. - std::string shape; - _Shape = SHAPE_NOTHING; - _XSize = 1; - _YSize = 1; - _Ratio = 1; - - if (_Grp->getProfileParameter("shape", shape) - && shape=="rectangle") - { - _Shape = SHAPE_RECTANGLE; - } - - _Grp->getProfileParameter("ratio", _Ratio); - _Grp->getProfileParameter("xsize", _XSize); - _Grp->getProfileParameter("ysize", _YSize); - - _GeomIndex=0; - { - CGroup &persGrp=NLMISC::safe_cast(_Grp.ptr())->getPersistent(); - // R2_PRIMITIVE_LAXITY - if (IsRingShard.get()) - { - nlassertex(_Geometry, ("CGrpProfileFollowRoute : NULL geometry data for group '%s'", persGrp.getFullName().c_str())); - if (_Geometry->empty()) - { - nlwarning("CGrpProfileFollowRoute : missing geometry data for group '%s'", persGrp.getFullName().c_str()); - } - } - else - { - nlassertex(_Geometry && _Geometry->size()>0, ("CGrpProfileFollowRoute : missing geometry data for group '%s'", persGrp.getFullName().c_str())); - } - } - - CSpawnGroupNpc *grp = static_cast(static_cast(_Grp)); - CGroupNpc &pgrp = grp->getPersistent(); - const CAIState *const state = pgrp.getActiveState(); - - if ( !state - || !state->isPositional()) - return; - - const CAIStatePositional *const sp = static_cast(state); - if (!sp->shape().hasPoints() && (_GeometryComeFromState)) - { - nlwarning("Error, no position in state '%s'%s", - sp->getAliasFullName().c_str(), - sp->getAliasString().c_str()); - } - else - { - _Geometry = &(sp->shape().getGeometry()); - _GeometryComeFromState = true; - _MustCalcRatios = true; - } - - setCurrentValidPos (_VerticalPos); // static_cast(_Grp.ptr())->getPersistent().getGeometryVerticalPos(), geometry); -} - -void CGrpProfileFollowRoute::stateChangeProfile() -{ - assignGeometryFromState(); - - // set a stand at pos profile on every bots - FOREACH(it, CAliasCont, _Grp->bots()) - { - CSpawnBot *sb = (*it)->getSpawnObj(); - if (sb) - sb->setAIProfile(new CBotProfileStandAtPos(sb)); - } - // Reset stop flag to false - stopNpc(false); - - resumeProfile(); -} - -void CGrpProfileFollowRoute::endProfile() -{ - PROFILE_LOG("group", "follow_route", "end", ""); -} - -void CGrpProfileFollowRoute::resumeProfile() -{ - PROFILE_LOG("group", "follow_route", "resume", ""); - FOREACH(it, TBotFollowerMap, _NpcList) - { - const CBot *const bot=it->first; - CSpawnBot *const sbot=bot->getSpawnObj(); - if (!sbot) - continue; - - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - break; - default: // push the correct comportment. - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - break; - } - - } -// setCurrentValidPos (NLMISC::safe_cast(NLMISC::safe_cast(_Grp)->getPersistent().getCAIState())); -#ifdef NL_DEBUG - nlassert(_Geometry); -#endif - setCurrentValidPos (_VerticalPos); -} - -void CGrpProfileFollowRoute::addBot (CBot *bot) -{ - _NpcList[bot]=CBotFollower(); - - CSpawnBot *sbot=bot->getSpawnObj(); - if (sbot) - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - - _MustCalcRatios = true; -} - -void CGrpProfileFollowRoute::removeBot (CBot *bot) -{ - TBotFollowerMap::iterator it=_NpcList.find(bot); - - if (it==_NpcList.end()) - return; - - CSpawnBotNpc *const spawnBot=NLMISC::safe_cast(bot)->getSpawn(); - if (spawnBot) - spawnBot->setAIProfile(BotProfileStandAtPosFactory.createAIProfile(spawnBot)); - - _NpcList.erase (it); - _MustCalcRatios = true; -} - -void CGrpProfileFollowRoute::setCurrentValidPos (TVerticalPos verticalPos) -{ - if (_Geometry->size()>0) - { -#if !FINAL_VERSION - nlassert(_Geometry!=NULL); -#endif - size_t index = getDirection()?_GeomIndex:(_Geometry->size()-_GeomIndex-1); -#if !FINAL_VERSION - nlassert(index < _Geometry->size()); -#endif - _PathCont.setDestination (verticalPos, (*_Geometry)[index]); - } - - FOREACH(it, TBotFollowerMap, _NpcList) - it->second.setBotAtDest(false); -} - -void CGrpProfileFollowRoute::calcRatios () -{ - _MustCalcRatios = false; - - // loop to compute max speeds - _MaxRunSpeed = FLT_MAX; - _MaxWalkSpeed = FLT_MAX; - FOREACH(it, TBotFollowerMap, _NpcList) - { - CBot *bot = it->first; //static_cast(_Grp->bots()[botFollower.getIndex()]); - CSpawnBot *sbot = bot->getSpawnObj(); - if ( !sbot - || !sbot->isAlive()) - continue; - - _MaxRunSpeed = std::min(sbot->runSpeed(), _MaxRunSpeed); - _MaxWalkSpeed = std::min(sbot->walkSpeed(), _MaxWalkSpeed); - } - - - if (_Shape!=SHAPE_RECTANGLE) - return; - - const uint32 nbbots=(uint32)_NpcList.size(); - - _NbRange = (uint32) sqrt(_Ratio*nbbots); - if (_NbRange==0) - _NbRange=1; - _NbLines = nbbots/_NbRange; - _NbBotInNormalShape = _NbLines*_NbRange; - _Rest = nbbots-_NbBotInNormalShape; - - _Cx=(double(_NbRange)-1.0)*0.5; - _Cy=(double(_NbLines)-1.0)*0.5; - _Cy=(_Cy*_NbBotInNormalShape+double(_NbLines)*_Rest)/double(nbbots); -} - -void CGrpProfileFollowRoute::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpFollowRouteProfileUpdate); - CFollowPathContext fpcGrpFollowRouteProfileUpdate("GrpFollowRouteProfileUpdate"); - - CMoveProfile::updateProfile(ticksSinceLastUpdate); - - CSpawnGroupNpc *NpcGrp=NLMISC::safe_cast(_Grp.ptr()); - CGroupNpc &persGrp=NpcGrp->getPersistent(); - - CAIVector groupPosition = NpcGrp->getCenterPos(); - CAIVector perpGlobalOrient; - NpcGrp->calcCenterPos(groupPosition); - - uint32 nbAtDest=0; - uint32 nbNewAtDest=0; - - uint32 botIndex=0; - uint32 xIndex=0; - uint32 yIndex=0; - - double dx=0; - double dy=0; - - // R2_PRIMITIVE_LAXITY - if (IsRingShard.get()) - { - if (!_ProfileTerminated && _Geometry->empty()) - _ProfileTerminated = true; - } - - if (_Shape==SHAPE_RECTANGLE) - { - perpGlobalOrient.setX(-_GlobalOrient.y()); - perpGlobalOrient.setY(_GlobalOrient.x()); - } - - ////////////////////////////////////////////////////////////////////////// - // Calcs the correct gravity grid position (must be done only when bot are removed or add to the group. - if (_MustCalcRatios) - calcRatios (); - - - FOREACH(it, TBotFollowerMap, _NpcList) - { - CBotFollower &botFollower=it->second; - if (botFollower.isBotAtDest()) - { - nbAtDest++; - continue; - } - - CBot *bot=it->first; - CSpawnBot *sbot=bot->getSpawnObj(); - if ( !sbot - || !sbot->isAlive()) - continue; - - // verify if the bot has a correct profile and if he reached the destination position. - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - { - if (_ProfileTerminated) - { - // remove the profile - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - } - else - { - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - - // flag the sub profile to stop the npc - prof->setStop(_StopNpc); - if (!_StopNpc) - { - if (prof->_Status==CFollowPath::FOLLOW_ARRIVED) - { - botFollower.setBotAtDest(); - nbNewAtDest++; - if (simulateBug(2)) - { - /* Following statement was missing */ - } - else - { - nbAtDest++; - } - } - else - { - // update speeds - prof->setMaxSpeeds(_MaxWalkSpeed, _MaxRunSpeed); - } - } - } - } - break; - default: // push the correct comportment. - { - if (!_ProfileTerminated) - { - sbot->setAIProfile(new CBotProfileFollowPos(&_PathCont, sbot)); - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - // update speeds - prof->setMaxSpeeds(_MaxWalkSpeed, _MaxRunSpeed); - } - } - break; - } - - if (_Shape==SHAPE_RECTANGLE) - { - NLMISC::CVector2d dir=sbot->theta().asVector2d(); - dx+=dir.x; - dy+=dir.y; - - // 4 rows - CAIVector idealPos=groupPosition; - if (botIndex>=_NbBotInNormalShape) - { - idealPos += perpGlobalOrient * (_XSize*(_Cx-double(xIndex)-(_NbRange-_Rest)*0.5)); - } - else - { - idealPos += perpGlobalOrient * (_XSize*(_Cx-double(xIndex))); - } - - idealPos+=_GlobalOrient*(_YSize*(_Cy-(double)yIndex)); - idealPos-=CAIVector(sbot->pos()); - - botIndex++; - xIndex++; - if (xIndex>=_NbRange) - { - xIndex=0; - yIndex++; - } - sbot->setMoveDecalage(idealPos); - } - } - - if (_Shape==SHAPE_RECTANGLE) - { - _GlobalOrient.setX(dx/botIndex); - _GlobalOrient.setY(dy/botIndex); - } - - // first to arrived ? - if (nbAtDest>0 && !_ProfileTerminated) - { - // oh la la (la, let 's go dancing).. - _GeomIndex++; -#ifdef NL_DEBUG - nlassert(_Geometry); -#endif - - if (_GeomIndex>=_Geometry->size()) // we reach the end. - { - _GeomIndex=0; - - if (!_DontSendEvent) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedFirst); - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedAll); - } - _ProfileTerminated = true; - } - else - { - setCurrentValidPos(_VerticalPos); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileStandOnVertices // -////////////////////////////////////////////////////////////////////////////// - -CPathCont* CGrpProfileStandOnVertices::getPathCont(CBot const* bot) -{ - TNpcBotPositionnerMap::const_iterator it=_NpcList.find(bot); - if (it==_NpcList.end()) - return NULL; - return &it->second->_PathCont; -} - -void CGrpProfileStandOnVertices::beginProfile() -{ - PROFILE_LOG("group", "stand_on_vertices", "begin", ""); - CMoveProfile::beginProfile(); - CSpawnGroupNpc *NpcGrp=NLMISC::safe_cast(_Grp.ptr()); - - CAIStatePositional *grpState=NLMISC::safe_cast(NpcGrp->getPersistent().getCAIState()); - - if ( !grpState - || grpState->shape().numPoints() == 0 - || !grpState->isPositional()) - { - if (grpState) - nlwarning("CGrpProfileStandOnVertices::beginProfile : grpState without valid points %s for group %s", grpState->getAliasFullName().c_str(), NpcGrp->getPersistent().getFullName().c_str()); - else - nlwarning("CGrpProfileStandOnVertices::beginProfile : invalid no grpState for group %s", NpcGrp->getPersistent().getFullName().c_str()); - } - setCurrentValidPos (grpState); - _Finished=false; -} - -void CGrpProfileStandOnVertices::setCurrentValidPos(CAIStatePositional *grpState) -{ - for (TNpcBotPositionnerMap::iterator it=_NpcList.begin(), itEnd=_NpcList.end();it!=itEnd;++it) - { - CBotPositionner *botPos=(*it).second; - botPos->setBotAtDest(false); - botPos->_PathCont.setDestination(grpState->shape().getVerticalPos(), *grpState->shape().point(botPos->_GeomIndex)); - } -} - -void CGrpProfileStandOnVertices::resumeProfile() -{ - PROFILE_LOG("group", "stand_on_vertices", "resume", ""); - for (TNpcBotPositionnerMap::iterator it=_NpcList.begin(), itEnd=_NpcList.end();it!=itEnd;++it) - { - const CBot*const bot=(*it).first; - CSpawnBot *sbot=bot->getSpawnObj(); - if (!sbot) - continue; - - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - break; - default: // push the correct behaviour - { - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - } - break; - } - - } - - CSpawnGroupNpc *NpcGrp=NLMISC::safe_cast(_Grp.ptr()); - CAIStatePositional *grpState=NLMISC::safe_cast(NpcGrp->getPersistent().getCAIState()); - nlassert( grpState->shape().numPoints()>0 - && grpState - && grpState->isPositional()); - setCurrentValidPos (grpState); - _Finished=false; -} - -void CGrpProfileStandOnVertices::addBot (CBot *bot) -{ - CGroupNpc& grp=NLMISC::safe_cast(bot)->grp(); -#ifdef NL_DEBUG - nlassert(grp.getSpawnObj()); -#endif - - CAIStatePositional *grpState=NLMISC::safe_cast(grp.getCAIState()); - - CSpawnBot *const sbot=bot->getSpawnObj(); - - if ( grpState->shape().numPoints() < 1 ) - { - nlwarning("CGrpProfileStandOnVertices : group state '%s'%s: no vertice !", grpState->getAliasFullName().c_str(), grpState->getAliasString().c_str()); - return; - } - - if (sbot) - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - - _NpcList[bot]=new CBotPositionner (bot->getChildIndex()%grpState->shape().numPoints(), bot->getGroup().getAStarFlag()); -} - -void CGrpProfileStandOnVertices::removeBot (CBot *bot) -{ - TNpcBotPositionnerMap::iterator it=_NpcList.find(bot); - if (it!=_NpcList.end()) - { - CSpawnBotNpc *spawnBot=NLMISC::safe_cast(bot)->getSpawn(); - if (spawnBot) - spawnBot->setAIProfile(new CBotProfileStandAtPos(spawnBot)); - - _NpcList.erase (it); - } - -} - -void CGrpProfileStandOnVertices::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpStandProfileUpdate); - CFollowPathContext fpcGrpStandProfileUpdate("GrpStandProfileUpdate"); - - CMoveProfile::updateProfile(ticksSinceLastUpdate); - - CGroupNpc &persGrp=NLMISC::safe_cast(_Grp.ptr())->getPersistent(); - CAIStatePositional *grpState=static_cast(persGrp.getCAIState()); - - uint32 nbAtDest=0; - uint32 nbNewAtDest=0; - - for (TNpcBotPositionnerMap::iterator it=_NpcList.begin(), itEnd=_NpcList.end();it!=itEnd;++it) - { - CBotPositionner *botPos=(*it).second; - if (!botPos->isBotAtDest()) - { - const CBot*const bot=(*it).first; - CSpawnBot *sbot=bot->getSpawnObj(); - if ( sbot - && sbot->isAlive()) - { - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - { - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - - if (prof->_Status==CFollowPath::FOLLOW_ARRIVED) - { - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - botPos->setBotAtDest(); - nbNewAtDest++; - if (simulateBug(2)) - { - /* Following statement was missing */ - } - else - { - nbAtDest++; - } - } - } - break; - default: // push the correct comportment. - { - sbot->setAIProfile(new CBotProfileFollowPos(&botPos->_PathCont, sbot)); - } - break; - } - } - } - else - { - nbAtDest++; - } - } - - // first to arrived ? - if ( nbNewAtDest==nbAtDest - && nbAtDest>0 ) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedFirst); - } - - // all arrived ? - if ( nbAtDest==_NpcList.size() - && !_Finished ) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedAll); - _Finished=true; - } -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFollowPlayer // -////////////////////////////////////////////////////////////////////////////// -CGrpProfileFollowPlayer::CGrpProfileFollowPlayer(CProfileOwner* owner, TDataSetRow const& playerRow, uint32 dispersionRadius) -: CMoveProfile(owner) -, _PlayerRow(playerRow) -, _DispersionRadius(dispersionRadius) -, _PathPos(CAngle(0)) -, _PathCont(NLMISC::safe_cast(owner)->getAStarFlag()) -{ - PROFILE_LOG("group", "follow player", "ctor", ""); - _Status = CFollowPath::FOLLOWING; -} - -bool CGrpProfileFollowPlayer::destinationReach() const -{ - return _Status == CFollowPath::FOLLOW_ARRIVED - || _Status==CFollowPath::FOLLOW_NO_PATH; -} - -void CGrpProfileFollowPlayer::beginProfile() -{ - _Status = CFollowPath::FOLLOWING; -} - -// TODO: this doesn't work very well at all... -void CGrpProfileFollowPlayer::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(CGrpProfileFollowPlayerUpdate); - CFollowPathContext fpcGrpFollowPlayerUpdate("CGrpProfileFollowPlayerUpdate"); - - // check all bot to see if there need to move - CSpawnGroupNpc* grp = static_cast(static_cast(_Grp)); - CGroupNpc &pgrp = grp->getPersistent(); - - CBotPlayer* plrPtr = dynamic_cast(CAIS::instance().getEntityPhysical(_PlayerRow)); - - if ( ! plrPtr) { - nlwarning("CGrpProfileFollowPlayer: No valid player position to follow"); - return; - } - - _PathCont.setDestination(plrPtr->wpos()); - _PathPos._Angle = plrPtr->theta(); - - for (uint i = 0; i < pgrp.bots().size(); ++i) - { - CBotNpc* bot = static_cast(pgrp.bots()[i]); - if (!bot) - continue; - - // check current bot state - CSpawnBotNpc *sbot = bot->getSpawn(); - if (!sbot) - continue; - - // Need to wait for a correct position before moving? - CAIVector const& dest = _PathCont.getDestination(); - if (dest.x()==0 || dest.y()==0) - return; - - static const std::string runParameter("running"); - float dist; - if (sbot->getPersistent().getOwner()->getSpawnObj()->checkProfileParameter(runParameter)) - dist = sbot->runSpeed()*ticksSinceLastUpdate; - else - dist = sbot->walkSpeed()*ticksSinceLastUpdate; - - // Move - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - sbot, - _PathPos, - _PathCont, - dist, - 0.f, - 0.5f); - - if (status==CFollowPath::FOLLOW_NO_PATH) - { - nlwarning("Problem with following player"); - } - - - } -} - - - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileIdle // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileIdle::CGrpProfileIdle(CProfileOwner* owner) -: CMoveProfile(owner) -{ - PROFILE_LOG("group", "idle", "ctor", ""); -} - -CGrpProfileIdle::~CGrpProfileIdle() -{ - PROFILE_LOG("group", "idle", "dtor", ""); - FOREACH(it, CCont, _Grp->bots()) - { - CBot* bot = *it; - removeBot(bot); - } -} - -CGrpProfileIdle::CBotPositionner::CBotPositionner() -{ -} - -CGrpProfileIdle::CBotPositionner::~CBotPositionner() -{ -} - -void CGrpProfileIdle::beginProfile() -{ - PROFILE_LOG("group", "idle", "begin", ""); - CMoveProfile::beginProfile(); -} - -CPathCont* CGrpProfileIdle::getPathCont(CBot const* bot) -{ - return NULL; -} - -void CGrpProfileIdle::resumeProfile() -{ - PROFILE_LOG("group", "idle", "resume", ""); - typedef std::map TCont; - FOREACH(it, TCont, _NpcList) - { - CBot* bot = (*it).first; - CSpawnBot* sbot = bot->getSpawnObj(); - if (sbot) - { - switch (sbot->getAIProfileType()) - { - case BOT_STAND_AT_POS: - break; - default: // push the correct comportment. - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - break; - } - } - } -} - -void CGrpProfileIdle::addBot(CBot* bot) -{ -#ifdef NL_DEBUG - CGroupNpc& grp=NLMISC::safe_cast(bot)->grp(); - nlassert(grp.getSpawnObj()); -#endif - _NpcList[bot]=CBotPositionner (); - CSpawnBot *sbot=bot->getSpawnObj(); - if (sbot) - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); -} - -void CGrpProfileIdle::removeBot(CBot* bot) -{ - std::map::iterator it=_NpcList.find(bot); - if (it!=_NpcList.end()) - { - _NpcList.erase (it); - } - -} - -void CGrpProfileIdle::endProfile() -{ - PROFILE_LOG("group", "idle", "end", ""); -} - -void CGrpProfileIdle::updateProfile(uint ticksSinceLastUpdate) -{ - CMoveProfile::updateProfile(ticksSinceLastUpdate); -} - -std::string CGrpProfileIdle::getOneLineInfoString() const -{ - return "idle profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileWander // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileWander::CGrpProfileWander(CProfileOwner* owner, CNpcZone const* npcZone) -: CMoveProfile(owner) -, _Social(false) -, _NpcZone(npcZone) -{ - PROFILE_LOG("group", "wander", "ctor", ""); - _BotStandProfileType = BOT_STAND_AT_POS; - _BotStandProfileFactory = &BotProfileStandAtPosFactory; - _RandomPos=&npcZone->getPlaceRandomPos(); -} - -CGrpProfileWander::CGrpProfileWander(CProfileOwner* owner) -: CMoveProfile(owner) -, _Social(false) -{ - PROFILE_LOG("group", "wander", "ctor2", ""); - affectZoneFromStateMachine(); -#if !FINAL_VERSION - // R2_PRIMITIVE_LAXITY - if (!IsRingShard.get()) - { - nlassert(!_RandomPos.isNULL()); - } -#endif - - // default to stand apt pos profile - _BotStandProfileType = BOT_STAND_AT_POS; - _BotStandProfileFactory = &BotProfileStandAtPosFactory; -} - -CGrpProfileWander::~CGrpProfileWander() -{ - PROFILE_LOG("group", "wander", "dtor", ""); -} - -void CGrpProfileWander::stateChangeProfile() -{ - affectZoneFromStateMachine(); - resetDestinationReachedData(); -} - -void CGrpProfileWander::affectZoneFromStateMachine() -{ - CSpawnGroupNpc* grp = static_cast(static_cast(_Grp)); - CGroupNpc& pgrp = grp->getPersistent(); - CAIState const* const state = pgrp.getActiveState(); - - if ( !state - || !state->isPositional()) - return; - - CAIStatePositional const* const sp = static_cast(state); - if (!sp->shape().hasPoints()) - { - if (sp->getAliasNode()) - nlwarning("Error, no position in state %s", sp->getAliasNode()->fullName().c_str()); - else - nlwarning("Error, no position in state %s", sp->getName().c_str()); - } - if (sp->shape().hasPatat()) - _RandomPos=&(sp->shape()); -} - -void CGrpProfileWander::resetDestinationReachedData() -{ - _DestinationReachedFirst = false; - _DestinationReachedAll = false; - std::fill(_NpcDestinationReached.begin(), _NpcDestinationReached.end(), false); -} - -void CGrpProfileWander::setBotStandProfile(TProfiles botStandProfileType, IAIProfileFactory *botStandProfileFactory) -{ - _BotStandProfileType = botStandProfileType; - _BotStandProfileFactory = botStandProfileFactory; -} - -void CGrpProfileWander::beginProfile() -{ - PROFILE_LOG("group", "wander", "begin", ""); - CMoveProfile::beginProfile(); - - CSpawnGroupNpc *grp = static_cast(static_cast(_Grp)); - - if (grp->checkProfileParameter("forage")) - { - _BotStandProfileType = BOT_FORAGE; - _BotStandProfileFactory = &BotProfileForageFactory; - } - else if (grp->checkProfileParameter("social")) - { - _Social = true; - } - - _NpcDestinationReached.resize( grp->getPersistent().bots().size()); - resetDestinationReachedData(); - -} - -void CGrpProfileWander::addBot(CBot* bot) -{ - CSpawnBot *const spawnBot=bot->getSpawnObj(); - if (!spawnBot) - return; - - if (_BotStandProfileType == BOT_FORAGE) - { - // special case, only set the forage activity and let the bot live there life - spawnBot->setAIProfile(_BotStandProfileFactory->createAIProfile(spawnBot)); - return; - } - - CBotProfileStandAtPos* const profile = new CBotProfileStandAtPos(spawnBot); -#ifdef NL_DEBUG - nlassert(profile!=NULL); -#endif - spawnBot->setAIProfile(profile); -} -void CGrpProfileWander::removeBot(CBot* bot) -{ -} -CPathCont* CGrpProfileWander::getPathCont(CBot const* bot) -{ - return NULL; -} - -void CGrpProfileWander::endProfile() -{ - PROFILE_LOG("group", "wander", "end", ""); -} - -void CGrpProfileWander::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpWanderProfileUpdate); - CFollowPathContext fpcGrpWanderProfileUpdate("GrpWanderProfileUpdate"); - - if (_BotStandProfileType == BOT_FORAGE) - { - // special case, only set the forage activity and let the bot live there life - return; - } - - // check all bot to see if there need to move - CSpawnGroupNpc* grp = static_cast(static_cast(_Grp)); - CGroupNpc &pgrp = grp->getPersistent(); - bool aNpcHasReachDestination = false; - for (uint i=0; i(pgrp.bots()[i]); - if (!bot) - continue; - - // check current bot state - CSpawnBotNpc *sbot = bot->getSpawn(); - if (!sbot) - continue; - - IAIProfile *profile = sbot->getAIProfile(); - - if (!profile) - { - // init a profile on the bot - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - continue; - } - - if (profile->getAIProfileType() == BOT_MOVE_TO) - { - // check if we are arrived - CBotProfileMoveTo* mt = static_cast(profile); - if (mt->destinationReach()) - { - if (!_DestinationReachedAll) - { - - uint32 npcSize = (uint32)pgrp.bots().size(); - uint32 reachedSize = (uint32)_NpcDestinationReached.size(); - if (reachedSize!= npcSize) - { - _NpcDestinationReached.resize(npcSize); - // invalid the vector a new bot has arrived - if (npcSize>reachedSize){ std::fill(_NpcDestinationReached.begin(), _NpcDestinationReached.end(), false); } - } - - if ( !_NpcDestinationReached[i]) - { - _NpcDestinationReached[i] = true; - aNpcHasReachDestination = true; - } - - } - - // look arround for interesting target - CAIVision vision; - vision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), CAIVector(sbot->pos()), 10, 10); - - CPersistentOfPhysical *target = NULL; - - if (!vision.players().empty()) - { - // there are some player near, look at one if it is not behin us - uint index = CAIS::rand16((uint32)vision.players().size()); - CAngle angle(CAngle::pi()); - - while (index < vision.players().size() && !target) - { - CPersistentOfPhysical *pop = vision.players()[index++]; - - angle = sbot->pos().angleTo(pop->getSpawnObj()->pos()); - - if (angle < CAngle::pi()/2 && angle > CAngle::pi()/-2) - { - target = pop; - break; - } - } - } - if (!target && !vision.bots().empty()) - { - // there are some bots near, look at one if it is not behin us - uint index = CAIS::rand16((uint32)vision.bots().size()); - CAngle angle(CAngle::pi()); - - while (index < vision.bots().size() && !target) - { - CPersistentOfPhysical *pop = vision.bots()[index++]; - - angle = sbot->pos().angleTo(pop->getSpawnObj()->pos()); - - if (angle < CAngle::pi()/2 && angle > CAngle::pi()/-2) - { - target = pop; - break; - } - } - } - // set the visual target - if (target && target->isSpawned()) - sbot->setVisualTarget(target->getSpawnObj()); - else - sbot->setVisualTarget(NULL); - - // now, set the idle activity with a random timer - - sbot->setAIProfile(_BotStandProfileFactory->createAIProfile(sbot)); - CBotProfileWanderBase *wbs = safe_cast(sbot->getAIProfile()); - if (wbs) - { - float waitMin; - float waitMax; - static string waitMinStr("wait min"); - static string waitMaxStr("wait max"); - if (grp->getProfileParameter(waitMinStr, waitMin)) - { - if (!grp->getProfileParameter(waitMaxStr, waitMax)) - waitMax = waitMin; - else - waitMax = waitMax > waitMin ? waitMax : waitMin; - } - else - { - waitMin = float(DefaultWanderMinTimer); - waitMax = float(DefaultWanderMaxTimer); - } - wbs->setTimer(uint32(waitMin+CAIS::rand32(uint32(waitMax-waitMin)))); - } - } - continue; - } - - if (profile->getAIProfileType()==_BotStandProfileType) - { - const CBotProfileWanderBase*const wbs = static_cast(sbot->getAIProfile()); -#ifdef NL_DEBUG - nlassert(wbs); -#endif - if (!wbs->testTimer()) - continue; - } - -#ifdef NL_DEBUG - nlassert(_RandomPos != NULL && _RandomPos->getRandomPosCount() != 0); -#endif - // R2_PRIMITIVE_LAXITY - // for a Ring shard stop here and only do a warning to avoid asserting later - // primitives generated by players may be incorrect and should not crash the service - if (IsRingShard.get()) - { - if ( _RandomPos == NULL - || _RandomPos->getRandomPosCount() == 0) - { - string stateName = "NULL state!"; - CAIState const* const state = pgrp.getActiveState(); - if (state != NULL) - stateName = state->getAliasFullName(); - nlwarning("No valid wander position for state '%s'", stateName.c_str()); - return; - } - } - - // time out, move to another point in the geometry - RYAI_MAP_CRUNCH::CWorldPosition wp; - - if (_Social && CAIS::rand32(3) == 0) - { - // this time, we try to reach an npc in the neighbour - //TODO : implemente this behavior - } - else - { - // standard random move - _RandomPos->getRandomPos(wp); - } - CBotProfileMoveTo* mts = new CBotProfileMoveTo(_RandomPos->getVerticalPos(), wp, sbot); - sbot->setAIProfile(mts); - - } - - if (aNpcHasReachDestination && !_DestinationReachedAll) - { - - if (!_DestinationReachedFirst) - { - _DestinationReachedFirst = true; - pgrp.processStateEvent(pgrp.mgr().EventDestinationReachedFirst); - } - - uint32 first=0, last=(uint32)_NpcDestinationReached.size(); - for ( ; first != last && _NpcDestinationReached[first]; ++first) {} - - if (first == last) - { - _DestinationReachedAll = true; - pgrp.processStateEvent(pgrp.mgr().EventDestinationReachedAll); - } - } -} - -std::string CGrpProfileWander::getOneLineInfoString() const -{ - return "wander group profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileWanderNoPrim // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileWanderNoPrim::CGrpProfileWanderNoPrim(CProfileOwner* owner, NLMISC::CSmartPtr const& npcZone) -: CMoveProfile(owner) -, _Social(false) -, _NpcZone(npcZone) -{ - PROFILE_LOG("group", "wander", "ctor", ""); - _BotStandProfileType = BOT_STAND_AT_POS; - _BotStandProfileFactory = &BotProfileStandAtPosFactory; -// _RandomPos = &npcZone->getPlaceRandomPos(); -} -/* -CGrpProfileWanderNoPrim::CGrpProfileWanderNoPrim(CProfileOwner* owner) -: CMoveProfile(owner) -, _Social(false) -{ - PROFILE_LOG("group", "wander", "ctor2", ""); - affectZoneFromStateMachine(); -#if !FINAL_VERSION - nlassert(!_RandomPos.isNULL()); -#endif - - // default to stand apt pos profile - _BotStandProfileType = BOT_STAND_AT_POS; - _BotStandProfileFactory = &BotProfileStandAtPosFactory; -} -*/ -void CGrpProfileWanderNoPrim::stateChangeProfile() -{ -// affectZoneFromStateMachine(); -// resetDestinationReachedData(); -} -/* -void CGrpProfileWanderNoPrim::affectZoneFromStateMachine() -{ - CSpawnGroupNpc* grp = static_cast(static_cast(_Grp)); - CGroupNpc& pgrp = grp->getPersistent(); - CAIState const* const state = pgrp.getActiveState(); - - if ( !state - || !state->isPositional()) - return; - - CAIStatePositional const* const sp = static_cast(state); - if (!sp->shape().hasPoints()) - { - if (sp->getAliasNode()) - nlwarning("Error, no position in state %s", sp->getAliasNode()->fullName().c_str()); - else - nlwarning("Error, no position in state %s", sp->getName().c_str()); - } - if (sp->shape().hasPatat()) - _RandomPos=&(sp->shape()); -} -*/ - -CGrpProfileWanderNoPrim::~CGrpProfileWanderNoPrim() -{ - PROFILE_LOG("group", "wander", "dtor", ""); -} - -void CGrpProfileWanderNoPrim::setBotStandProfile(TProfiles botStandProfileType, IAIProfileFactory *botStandProfileFactory) -{ - _BotStandProfileType = botStandProfileType; - _BotStandProfileFactory = botStandProfileFactory; -} - -void CGrpProfileWanderNoPrim::beginProfile() -{ - PROFILE_LOG("group", "wander", "begin", ""); - CMoveProfile::beginProfile(); - - CSpawnGroupNpc *grp = static_cast(static_cast(_Grp)); - - if (grp->checkProfileParameter("forage")) - { - _BotStandProfileType = BOT_FORAGE; - _BotStandProfileFactory = &BotProfileForageFactory; - } - else if (grp->checkProfileParameter("social")) - { - _Social = true; - } -} - -void CGrpProfileWanderNoPrim::addBot(CBot* bot) -{ - CSpawnBot *const spawnBot=bot->getSpawnObj(); - if (!spawnBot) - return; - - if (_BotStandProfileType == BOT_FORAGE) - { - // special case, only set the forage activity and let the bot live there life - spawnBot->setAIProfile(_BotStandProfileFactory->createAIProfile(spawnBot)); - return; - } - - CBotProfileStandAtPos* const profile = new CBotProfileStandAtPos(spawnBot); -#ifdef NL_DEBUG - nlassert(profile!=NULL); -#endif - spawnBot->setAIProfile(profile); -} -void CGrpProfileWanderNoPrim::removeBot(CBot* bot) -{ -} -CPathCont* CGrpProfileWanderNoPrim::getPathCont(CBot const* bot) -{ - return NULL; -} - -void CGrpProfileWanderNoPrim::endProfile() -{ - PROFILE_LOG("group", "wander", "end", ""); -} - -void CGrpProfileWanderNoPrim::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpWanderProfileUpdate); - CFollowPathContext fpcGrpWanderProfileUpdate("GrpWanderProfileUpdate"); - - if (_BotStandProfileType == BOT_FORAGE) - { - // special case, only set the forage activity and let the bot live there life - return; - } - - // check all bot to see if there need to move - CSpawnGroupNpc* grp = static_cast(static_cast(_Grp)); - CGroupNpc &pgrp = grp->getPersistent(); - - for (uint i=0; i(pgrp.bots()[i]); - if (!bot) - continue; - - // check current bot state - CSpawnBotNpc *sbot = bot->getSpawn(); - if (!sbot) - continue; - - IAIProfile *profile = sbot->getAIProfile(); - - if (!profile) - { - // init a profile on the bot - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - continue; - } - - if (profile->getAIProfileType() == BOT_MOVE_TO) - { - // check if we are arrived - CBotProfileMoveTo* mt = static_cast(profile); - if (mt->destinationReach()) - { - // look arround for interesting target - CAIVision vision; - vision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), CAIVector(sbot->pos()), 10, 10); - - CPersistentOfPhysical *target = NULL; - - if (!vision.players().empty()) - { - // there are some player near, look at one if it is not behin us - uint index = CAIS::rand16((uint32)vision.players().size()); - CAngle angle(CAngle::pi()); - - while (index < vision.players().size() && !target) - { - CPersistentOfPhysical *pop = vision.players()[index++]; - - angle = sbot->pos().angleTo(pop->getSpawnObj()->pos()); - - if (angle < CAngle::pi()/2 && angle > CAngle::pi()/-2) - { - target = pop; - break; - } - } - } - if (!target && !vision.bots().empty()) - { - // there are some bots near, look at one if it is not behin us - uint index = CAIS::rand16((uint32)vision.bots().size()); - CAngle angle(CAngle::pi()); - - while (index < vision.bots().size() && !target) - { - CPersistentOfPhysical *pop = vision.bots()[index++]; - - angle = sbot->pos().angleTo(pop->getSpawnObj()->pos()); - - if (angle < CAngle::pi()/2 && angle > CAngle::pi()/-2) - { - target = pop; - break; - } - } - } - // set the visual target - if (target && target->isSpawned()) - sbot->setVisualTarget(target->getSpawnObj()); - else - sbot->setVisualTarget(NULL); - - // now, set the idle activity with a random timer - - sbot->setAIProfile(_BotStandProfileFactory->createAIProfile(sbot)); - CBotProfileWanderBase *wbs = safe_cast(sbot->getAIProfile()); - if (wbs) - { - float waitMin; - float waitMax; - static string waitMinStr("wait min"); - static string waitMaxStr("wait max"); - if (grp->getProfileParameter(waitMinStr, waitMin)) - { - if (!grp->getProfileParameter(waitMaxStr, waitMax)) - waitMax = waitMin; - else - waitMax = waitMax > waitMin ? waitMax : waitMin; - } - else - { - waitMin = float(DefaultWanderMinTimer); - waitMax = float(DefaultWanderMaxTimer); - } - wbs->setTimer(uint32(waitMin+CAIS::rand32(uint32(waitMax-waitMin)))); - } - } - continue; - } - - if (profile->getAIProfileType()==_BotStandProfileType) - { - const CBotProfileWanderBase*const wbs = static_cast(sbot->getAIProfile()); -#ifdef NL_DEBUG - nlassert(wbs); -#endif - if (!wbs->testTimer()) - continue; - } - -#ifdef NL_DEBUG - nlassert(_NpcZone->getRandomPosCount()); -#endif - // time out, move to another point in the geometry - RYAI_MAP_CRUNCH::CWorldPosition wp; - - if (_Social && CAIS::rand32(3) == 0) - { - // this time, we try to reach an npc in the neighbour - //TODO : implemente this behavior - } - else - { - // standard random move - _NpcZone->getRandomPos(wp); - } - CBotProfileMoveTo* mts = new CBotProfileMoveTo(_NpcZone->getVerticalPos(), wp, sbot); - sbot->setAIProfile(mts); - } -} - -std::string CGrpProfileWanderNoPrim::getOneLineInfoString() const -{ - return "wander group profile (without primitive)"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileStandOnVertices // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileStandAtStartPoint::CGrpProfileStandAtStartPoint(CProfileOwner* owner) -: CMoveProfile(owner) -{ - PROFILE_LOG("group", "stand_at_start_point", "ctor", ""); -} - -CGrpProfileStandAtStartPoint::~CGrpProfileStandAtStartPoint() -{ - PROFILE_LOG("group", "stand_at_start_point", "dtor", ""); - for (CCont::iterator it=_Grp->bots().begin(), itEnd=_Grp->bots().end();it!=itEnd;++it) - { - CBot *bot=*it; - removeBot (bot); - } -} - -CGrpProfileStandAtStartPoint::CBotPositionner::CBotPositionner(RYAI_MAP_CRUNCH::TAStarFlag flags) -: _PathCont(flags) -{ -} - -CGrpProfileStandAtStartPoint::CBotPositionner::CBotPositionner(TVerticalPos verticalPos, CAIPos position, RYAI_MAP_CRUNCH::TAStarFlag flag) -: _PathCont(flag) -, _Position(position) -, _VerticalPos(verticalPos) -, _BotAtDest(false) -{ - _PathCont.setDestination(verticalPos, position); -} - -CGrpProfileStandAtStartPoint::CBotPositionner::~CBotPositionner() -{ -} - -inline -void CGrpProfileStandAtStartPoint::CBotPositionner::setBotAtDest(bool atDest) -{ - _BotAtDest = atDest; -} - -inline -bool CGrpProfileStandAtStartPoint::CBotPositionner::isBotAtDest() const -{ - return _BotAtDest; -} - -CPathCont* CGrpProfileStandAtStartPoint::getPathCont(CBot const* bot) -{ - TNpcBotPositionnerMap::const_iterator it = _NpcList.find(bot); - if (it==_NpcList.end()) - return NULL; - return &it->second->_PathCont; -} - -void CGrpProfileStandAtStartPoint::beginProfile() -{ - PROFILE_LOG("group", "stand_at_start_point", "begin", ""); - CMoveProfile::beginProfile(); - - setCurrentValidPos(); - _Finished = false; -} - -void CGrpProfileStandAtStartPoint::resumeProfile() -{ - PROFILE_LOG("group", "stand_at_start_point", "resume", ""); - for (TNpcBotPositionnerMap::iterator it=_NpcList.begin(), itEnd=_NpcList.end();it!=itEnd;++it) - { - const CBot*const bot=(*it).first; - CSpawnBot *sbot=bot->getSpawnObj(); - if (!sbot) - continue; - - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - break; - default: // push the correct comportment. - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - break; - } - - } - - setCurrentValidPos(); - _Finished = false; -} - -void CGrpProfileStandAtStartPoint::addBot(CBot* bot) -{ - CBotNpc* botNpc = NLMISC::safe_cast(bot); - - CGroupNpc& grp = botNpc->grp(); -#ifdef NL_DEBUG - nlassert(grp.getSpawnObj()); -#endif - CAIStatePositional *grpState=NLMISC::safe_cast(grp.getCAIState()); - _NpcList[bot]=new CBotPositionner (botNpc->getStartVerticalPos(), botNpc->getStartPos(), botNpc->getGroup().getAStarFlag()); - - CSpawnBot *const sbot=bot->getSpawnObj(); - if (sbot) - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); -} - -void CGrpProfileStandAtStartPoint::removeBot(CBot* bot) -{ - TNpcBotPositionnerMap::iterator it=_NpcList.find(bot); - - if (it==_NpcList.end()) - return; - - CSpawnBotNpc* const spawnBot = NLMISC::safe_cast(bot)->getSpawn(); - if (spawnBot) - spawnBot->setAIProfile(new CBotProfileStandAtPos(spawnBot)); - _NpcList.erase (it); -} - -void CGrpProfileStandAtStartPoint::setCurrentValidPos() -{ - FOREACH(it, TNpcBotPositionnerMap, _NpcList) - { - CBotPositionner *botPos=(*it).second; - botPos->setBotAtDest(false); - botPos->_PathCont.setDestination(botPos->_VerticalPos, botPos->_Position); - } - -} - -void CGrpProfileStandAtStartPoint::endProfile() -{ - PROFILE_LOG("group", "stand_at_start_point", "end", ""); -} - -void CGrpProfileStandAtStartPoint::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpStandStartPointProfileUpdate); - CFollowPathContext fpcGrpStandStartPointProfileUpdate("GrpStandStartPointProfileUpdate"); - - CMoveProfile::updateProfile(ticksSinceLastUpdate); - - CGroupNpc &persGrp=NLMISC::safe_cast(_Grp.ptr())->getPersistent(); - CAIStatePositional *grpState=static_cast(persGrp.getCAIState()); - - uint32 nbAtDest=0; - uint32 nbNewAtDest=0; - - for (TNpcBotPositionnerMap::iterator it=_NpcList.begin(), itEnd=_NpcList.end();it!=itEnd;++it) - { - CBotPositionner*const botPos=(*it).second; - if (botPos->isBotAtDest()) - { - nbAtDest++; - continue; - } - - const CBot*const bot=(*it).first; - CSpawnBot *sbot=bot->getSpawnObj(); - if ( !sbot - || !sbot->isAlive()) - continue; - - switch (sbot->getAIProfileType()) - { - case BOT_FOLLOW_POS: - { - CBotProfileFollowPos* prof = NLMISC::safe_cast(sbot->getAIProfile()); - - if (prof->_Status==CFollowPath::FOLLOW_ARRIVED) - { - sbot->setTheta(botPos->_Position.theta()); - sbot->setAIProfile(new CBotProfileStandAtPos(sbot)); - botPos->setBotAtDest(); - nbNewAtDest++; - if (simulateBug(2)) - { - /* Following statement was missing */ - } - else - { - nbAtDest++; - } - } - - } - break; - default: // push the correct comportment. - { - sbot->setAIProfile(new CBotProfileFollowPos(&botPos->_PathCont, sbot)); - } - break; - } - - } - - // first to arrived ? - if ( nbNewAtDest==nbAtDest - && nbAtDest>0 ) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedFirst); - } - - // all arrived ? - if ( nbAtDest==_NpcList.size() - && !_Finished ) - { - persGrp.processStateEvent(persGrp.mgr().EventDestinationReachedAll); - _Finished=true; - } -} - -std::string CGrpProfileStandAtStartPoint::getOneLineInfoString() const -{ - std::string info = "stand_at_start_point group profile"; - info += " finished=" + NLMISC::toString(_Finished); - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileEscorted // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileEscorted::CGrpProfileEscorted(CProfileOwner *owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "escorted", "ctor", ""); -} - -CGrpProfileEscorted::~CGrpProfileEscorted() -{ - PROFILE_LOG("group", "escorted", "dtor", ""); -} - -void CGrpProfileEscorted::beginProfile() -{ - PROFILE_LOG("group", "escorted", "begin", ""); - CGrpProfileNormal::beginProfile(); - _EscortTeamInRange = false; -} - -void CGrpProfileEscorted::endProfile() -{ - PROFILE_LOG("group", "escorted", "end", ""); - if (_Grp->movingProfile().getAIProfileType() == AITYPES::MOVE_FOLLOW_ROUTE) - { - CGrpProfileFollowRoute* prof = NLMISC::safe_cast(_Grp->movingProfile().getAIProfile()); - if (prof) - prof->stopNpc(false); - } -} - -void CGrpProfileEscorted::stateChangeProfile() -{ - CGrpProfileNormal::beginProfile(); -} - -void CGrpProfileEscorted::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpEscortedProfileUpdate); - CFollowPathContext fpcGrpEscortedProfileUpdate("GrpEscortedProfileUpdate"); - - const uint32 ESCORT_RANGE_DELTA = 3; - CGroupNpc &GrpRef = _Grp->getPersistent(); - const uint16 teamId = GrpRef.getEscortTeamId(); - - if (teamId == CTEAM::InvalidTeamId) - { - // no escort team assigned, can't move! - _EscortTeamInRange = false; - return; - } - - // we need to have some member of the escort team in range to allow movement - // look arround for an escort member - CAIVector centerPos; - bool escortAway = true; - bool escortBack = false; - float escortRange=GrpRef.getEscortRange(); - double distAway = escortRange+ESCORT_RANGE_DELTA; - double distBack = escortRange-ESCORT_RANGE_DELTA; - // square the dist to speedup test - distAway *= distAway; - distBack *= distBack; - if (_Grp->calcCenterPos(centerPos)) // true if there's some bots in the group. - { - CAIVision vision; - - // group vision update. - vision.updateBotsAndPlayers(_Grp->getPersistent().getAIInstance(), centerPos, uint(escortRange+ESCORT_RANGE_DELTA), 0); - - if (vision.players().empty()) - { - // no player, no need to check, the escort is away ! - escortAway = true; - } - else - { - // loop on each player until we know if escort is away or back - vector >::const_iterator first(vision.players().begin()), last(vision.players().end()); - for (;first != last && (escortAway || !escortBack); ++first) - { - CBotPlayer *player = safe_cast((*first).ptr()); // (CPersistentOfPhysical*) - if (player->isAlive()) - { - if (CMirrors::getTeamId(player->getSpawnObj()->dataSetRow()) == teamId) - { - // on of our escort girl ;) - // check the distance - double sqrDist = (centerPos - player->getSpawnObj()->pos()).sqrnorm(); - if (sqrDist < distBack) - { - escortBack = true; - // the escort is back - } - if (sqrDist < distAway) - { - escortAway = false; - // the escort is not away - } - } - } - } - } - } - - if (_EscortTeamInRange) - { - if (escortAway) - { - // switch to 'wait for escort' mode and send event 'escort away' - _EscortTeamInRange = false; - GrpRef.processStateEvent(GrpRef.mgr().getStateMachine()->EventEscortAway); - } - } - else - { - if (escortBack) - { - // switch to 'escort in range' mode and send event 'escort back' - _EscortTeamInRange = true; - GrpRef.processStateEvent(GrpRef.mgr().getStateMachine()->EventEscortBack); - } - } - - if (_GroupFighting) - { - if (!_Grp->fightProfile().getAIProfile()) - _Grp->fightProfile().setAIProfile(_Grp.ptr(), &GrpProfileFightFactory, false); - - _Grp->fightProfile().mayUpdateProfile(ticksSinceLastUpdate); - - CFightProfile* profile = NLMISC::safe_cast(_Grp->fightProfile().getAIProfile()); - if (!profile->stillHaveEnnemy()) - { - // :TODO: Verify if it's needed to erase bots aggro too/instead -// _Grp->clearAggroList(); // this erase all aggro. - setGroupFighting (false); - - _Grp->fightProfile().setAIProfile(NULL); - (NLMISC::safe_cast(_Grp->movingProfile().getAIProfile()))->resumeProfile (); - } - } - else - { - if (!_Grp->checkProfileParameter("defenceless")) - { - if (_Grp->haveAggroOrReturnPlace()) - { - if(_Grp->isGroupAlive()) - { - // set the fighting comportment. - if (!_Grp->fightProfile().getAIProfile()) - _Grp->fightProfile().setAIProfile(_Grp.ptr(), &GrpProfileFightFactory, false); - - setGroupFighting(true); - } - } - } - } - - if (_Grp->movingProfile().getAIProfileType() == AITYPES::MOVE_FOLLOW_ROUTE && !_GroupFighting) - { - CGrpProfileFollowRoute* prof = NLMISC::safe_cast(_Grp->movingProfile().getAIProfile()); - - if (prof) - { - prof->stopNpc(!_EscortTeamInRange); - _Grp->movingProfile().mayUpdateProfile(ticksSinceLastUpdate); - } - } -} - -std::string CGrpProfileEscorted::getOneLineInfoString() const -{ - std::string info = "escorted profile"; - info += " escort_team_in_range=" + NLMISC::toString(_EscortTeamInRange); - uint16 teamId = _Grp->getPersistent().getEscortTeamId(); - info += " team_id=" + (teamId==CTEAM::InvalidTeamId)?"InvalidTeamId":NLMISC::toString(teamId); - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGuardEscorted // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileGuardEscorted::CGrpProfileGuardEscorted(CProfileOwner *owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "guard_escorted", "ctor", ""); - _GuardProfile = new CGrpProfileGuard(owner); - _EscortedProfile = new CGrpProfileEscorted(owner); -} - -CGrpProfileGuardEscorted::~CGrpProfileGuardEscorted() -{ - PROFILE_LOG("group", "guard_escorted", "dtor", ""); -} - -void CGrpProfileGuardEscorted::beginProfile() -{ - PROFILE_LOG("group", "guard_escorted", "begin", ""); - CGrpProfileNormal::beginProfile(); - - _GuardProfile->beginProfile(); - _EscortedProfile->beginProfile(); -} - -void CGrpProfileGuardEscorted::endProfile() -{ - PROFILE_LOG("group", "guard_escorted", "end", ""); - _EscortedProfile->endProfile(); - _GuardProfile->endProfile(); -} - -void CGrpProfileGuardEscorted::stateChangeProfile() -{ - CGrpProfileNormal::beginProfile(); - _EscortedProfile->stateChangeProfile(); - _GuardProfile->stateChangeProfile(); -} - -void CGrpProfileGuardEscorted::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(GrpEscortedGuardProfileUpdate); - CFollowPathContext fpcGrpEscortedGuardProfileUpdate("GrpEscortedGuardProfileUpdate"); - - _GuardProfile->updateProfile(ticksSinceLastUpdate); - if (!_EscortedProfile->isGroupFighting()) - _EscortedProfile->updateProfile(ticksSinceLastUpdate); -} - -std::string CGrpProfileGuardEscorted::getOneLineInfoString() const -{ - std::string info = "guard_escorted profile"; - info += " ("; - info += _GuardProfile?_GuardProfile->getOneLineInfoString():std::string(""); - info += ") ("; - info += _EscortedProfile?_EscortedProfile->getOneLineInfoString():std::string(""); - info += ")"; - return info; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileSquad // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileSquad::CGrpProfileSquad(CProfileOwner* const owner) -: CGrpProfileFaction(owner) -{ - PROFILE_LOG("group", "squad", "ctor", ""); -} - -CGrpProfileSquad::~CGrpProfileSquad() -{ - PROFILE_LOG("group", "squad", "dtor", ""); -} - -void CGrpProfileSquad::beginProfile() -{ - PROFILE_LOG("group", "squad", "begin", ""); - CGrpProfileFaction::beginProfile(); - CGroupNpc& thisGrpNpc = _Grp->getPersistent(); - - // Set aggro parameters - thisGrpNpc._AggroRange = 25; - thisGrpNpc._UpdateNbTicks = 10; -} - -string CGrpProfileSquad::getOneLineInfoString() const -{ - return "squad profile"; -} - -void CGrpProfileSquad::aggroEntity(CAIEntityPhysical const* entity) -{ -// COutpost* outpost = getDefendedOutpost(); -// if (!outpost || outpost->getShape()->atPlace(CAIVector(entity->pos()))) - _Grp->setAggroMinimumFor(entity->dataSetRow(), 0.5f, false); -} - -NLMISC::CSmartPtr CGrpProfileSquad::buildFirstHitPlace(TDataSetRow const& aggroBot) -{ - COutpost* outpost = getDefendedOutpost(); - if (outpost) - return &*(outpost->getShape()); - else - return NULL; -} -/* -void CGrpProfileSquad::aggroEntity(CAIEntityPhysical const* entity) -{ - COutpost* outpost = getDefendedOutpost(); - if (outpost) - { - // Check that the (player) entity is in the outpost zone (according to the rules of the EGS with timers) - CMirrorPropValueRO entityInOutpostAlias(TheDataset, entity->dataSetRow(), DSPropertyIN_OUTPOST_ZONE_ALIAS); - if (entityInOutpostAlias != outpost->getAlias()) - return; - } - _Grp->setBotAggroMinimum(entity->dataSetRow(), -0.5f); -} -*/ -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFaction // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileFaction::CGrpProfileFaction(CProfileOwner* const owner) -: CGrpProfileNormal(owner) -{ - PROFILE_LOG("group", "faction", "ctor", ""); - bNoAssist = false; -} - -CGrpProfileFaction::~CGrpProfileFaction() -{ - PROFILE_LOG("group", "faction", "dtor", ""); -} - -void CGrpProfileFaction::beginProfile() -{ - PROFILE_LOG("group", "faction", "begin", ""); -} - -void CGrpProfileFaction::endProfile() -{ - PROFILE_LOG("group", "faction", "end", ""); -} - -AITYPES::CPropertySet CGrpProfileFaction::_FameFactions; - -void CGrpProfileFaction::initFameFactions() -{ - static bool inited = false; - if (!inited) - { - inited = true; - std::map factionTranslator; - std::vector const& factionNames = CStaticFames::getInstance().getFactionNames(); - std::vector::const_iterator it, end=factionNames.end(); - for (it=factionNames.begin(); it!=end; ++it) - { - std::string fameFaction = CStringMapper::unmap(*it); - std::string scriptFaction = fameFactionToScriptFaction(fameFaction); - factionTranslator.insert(std::make_pair(scriptFaction, *it)); - _FameFactions.addProperty(scriptFaction); - } - _FameFactions.addProperty(CPropertyId("Player")); -#ifdef NL_DEBUG_FACTION_NAME_CONVERTER - nldebug("Testing script faction name converters"); - std::string names[][2] = { - { "matis", "FamousMatis" }, - { "fyros", "FamousFyros" }, - { "tryker", "FamousTryker" }, - { "zorai", "FamousZorai" }, - { "kami", "FamousKami" }, - { "black_kami", "FamousBlackKami" }, - { "karavan", "FamousKaravan" }, - { "white_karavan", "FamousWhiteKaravan" }, - { "tribe_ancient_dryads", "FamousTribeAncientDryads" }, - { "tribe_antikamis", "FamousTribeAntikamis" }, - { "tribe_barkers", "FamousTribeBarkers" }, - { "tribe_beachcombers", "FamousTribeBeachcombers" }, - { "tribe_black_circle", "FamousTribeBlackCircle" }, - { "tribe_cholorogoos", "FamousTribeCholorogoos" }, - { "tribe_cockroaches", "FamousTribeCockroaches" }, - { "tribe_company_of_the_eternal_tree", "FamousTribeCompanyOfTheEternalTree" }, - { "tribe_corsair", "FamousTribeCorsair" }, - { "tribe_cute", "FamousTribeCute" }, - { "tribe_darkening_sap", "FamousTribeDarkeningSap" }, - { "tribe_dune_riders", "FamousTribeDuneRiders" }, - { "tribe_ecowarriors", "FamousTribeEcowarriors" }, - { "tribe_firebrands", "FamousTribeFirebrands" }, - { "tribe_first_deserter", "FamousTribeFirstDeserter" }, - { "tribe_frahar", "FamousTribeFrahar" }, - { "tribe_frahar_hunters", "FamousTribeFraharHunters" }, - { "tribe_gibbay", "FamousTribeGibbay" }, - { "tribe_goo_heads", "FamousTribeGooHeads" }, - { "tribe_green_seed", "FamousTribeGreenSeed" }, - { "tribe_hamazans_of_the_dead_seed", "FamousTribeHamazansOfTheDeadSeed" }, - { "tribe_icon_workshipers", "FamousTribeIconWorkshipers" }, - { "tribe_keepers", "FamousTribeKeepers" }, - { "tribe_kitin_gatheres", "FamousTribeKitinGatheres" }, - { "tribe_lagoon_brothers", "FamousTribeLagoonBrothers" }, - { "tribe_lawless", "FamousTribeLawless" }, - { "tribe_leviers", "FamousTribeLeviers" }, - { "tribe_master_of_the_goo", "FamousTribeMasterOfTheGoo" }, - { "tribe_matisian_border_guards", "FamousTribeMatisianBorderGuards" }, - { "tribe_night_turners", "FamousTribeNightTurners" }, - { "tribe_oasis_diggers", "FamousTribeOasisDiggers" }, - { "tribe_pyromancers", "FamousTribePyromancers" }, - { "tribe_recoverers", "FamousTribeRecoverers" }, - { "tribe_renegades", "FamousTribeRenegades" }, - { "tribe_restorers", "FamousTribeRestorers" }, - { "tribe_root_tappers", "FamousTribeRootTappers" }, - { "tribe_sacred_sap", "FamousTribeSacredSap" }, - { "tribe_sap_gleaners", "FamousTribeSapGleaners" }, - { "tribe_sap_slaves", "FamousTribeSapSlaves" }, - { "tribe_scorchers", "FamousTribeScorchers" }, - { "tribe_shadow_runners", "FamousTribeShadowRunners" }, - { "tribe_siblings_of_the_weeds", "FamousTribeSiblingsOfTheWeeds" }, - { "tribe_silt_sculptors", "FamousTribeSiltSculptors" }, - { "tribe_slavers", "FamousTribeSlavers" }, - { "tribe_smuglers", "FamousTribeSmuglers" }, - { "tribe_the_arid_matis", "FamousTribeTheAridMatis" }, - { "tribe_the_kuilde", "FamousTribeTheKuilde" }, - { "tribe_the_slash_and_burn", "FamousTribeTheSlashAndBurn" }, - { "tribe_tutors", "FamousTribeTutors" }, - { "tribe_water_breakers", "FamousTribeWaterBreakers" }, - { "tribe_woven_bridles", "FamousTribeWovenBridles" } - }; - size_t size = sizeof(names)/sizeof(names[0]); - for (size_t i=0; i %s", names[i][0].c_str(), fameFactionToScriptFaction(names[i][0]).c_str()); - nlassert( names[i][1] == fameFactionToScriptFaction(names[i][0]) ); - nldebug("%s -> %s", names[i][1].c_str(), scriptFactionToFameFaction(names[i][1]).c_str()); - nlassert( names[i][0] == scriptFactionToFameFaction(names[i][1]) ); - } -#endif - } -} - -bool CGrpProfileFaction::entityHavePartOfFactions(CAIEntityPhysical const* entity, AITYPES::CPropertySetWithExtraList const& factions) -{ - H_AUTO(CGrpProfileFaction_entityHavePartOfFactions); - switch (entity->getRyzomType()) - { - case RYZOMID::player: - { - // Test Player - if (factions.have(AITYPES::CPropertyId("Player"))) - { - // nldebug("Entity has faction Player"); - return true; - } - // Test if the entity is involved in an outpost war - if (entity->outpostAlias()!=0) - { - if (factions.have(NLMISC::toString("outpost:%s:%s", LigoConfig.aliasToString(entity->outpostAlias()).c_str(), entity->outpostSide()?"attacker":"defender"))) - return true; - } - // Test entity fame value - std::set factionsSet = factions.properties(); - std::set::const_iterator it, end = factionsSet.end(); - for (it=factionsSet.begin(); it!=end; ++it) - { - string factionInfos = CStringMapper::unmap(*it); - string fameFaction = scriptFactionToFameFaction(factionInfos); - // sint32 fame = CFameInterface::getInstance().getFameOrCivilisationFame(entity->getEntityId(), CStringMapper::map(fameFaction)); - sint32 const fame = entity->getFame(fameFaction); - sint32 const value = scriptFactionToFameFactionValue(factionInfos); - bool gt = scriptFactionToFameFactionGreaterThan(factionInfos); - if ((fame != NO_FAME && gt && fame > value) || - (fame != NO_FAME && !gt && fame < value)) - { - // nldebug("Entity has faction %s", CStringMapper::unmap(*it).c_str()); - return true; - } - } - return false; - } - case RYZOMID::npc: - { - CSpawnBotNpc const* const sbnEntity = NLMISC::safe_cast(entity); - CGroupNpc *const gnEntityGroup = NLMISC::safe_cast(&sbnEntity->getPersistent().getGroup()); - return gnEntityGroup->faction().containsPartOfStrict(factions); - } - case RYZOMID::creature: - { - CSpawnBotFauna const* const sbnEntity = NLMISC::safe_cast(entity); - CGrpFauna* const gnEntityGroup = NLMISC::safe_cast(&sbnEntity->getPersistent().getGroup()); - return gnEntityGroup->faction().containsPartOfStrict(factions); - } - default: - { - return false; - } - } -} - -std::string CGrpProfileFaction::scriptFactionToFameFaction(std::string name) -{ - if (name.find("Famous")!=0) - return name; - std::string ret = ""; - for (size_t i=6; i='A' && name[i]<='Z') - ret += name[i]-'A'+'a'; - else if (name[i]>='A' && name[i]<='Z') - { - ret += "_"; - ret += name[i]-'A'+'a'; - } - else if (name[i] == '>' || name[i] == '<') - { - return ret; - } - else - { - ret += name[i]; - } - } - return ret; -} - -bool CGrpProfileFaction::scriptFactionToFameFactionGreaterThan(string name) -{ - if (name.find("<") != string::npos) - return false; - - return true; -} - -sint32 CGrpProfileFaction::scriptFactionToFameFactionValue(string name) -{ - size_t start = name.find(">"); - if (start == string::npos) - { - start = name.find("<"); - if (start == string::npos) - return 0; - } - - sint32 value; - NLMISC::fromString(name.substr(start+1), value); - return value*6000; -} - -std::string CGrpProfileFaction::fameFactionToScriptFaction(std::string name) -{ - std::string ret = "Famous"; - for (size_t i=0; i='a' && name[i]<='z') - ret += name[i]-'a'+'A'; - else if (name[i]=='_' && name[i+1]>='a' && name[i+1]<='z') - ret += name[++i]-'a'+'A'; - else - ret += name[i]; - } - return ret; -} - -void CGrpProfileFaction::aggroEntity(CAIEntityPhysical const* entity) -{ - _Grp->setAggroMinimumFor(entity->dataSetRow(), 0.5f, false); -} - -void CGrpProfileFaction::checkTargetsAround() -{ - if (!_checkTargetTimer.test()) - return; - - CGroupNpc& thisGrpNpc = _Grp->getPersistent(); - - _checkTargetTimer.set(thisGrpNpc._UpdateNbTicks+CAIS::rand16(2)); // every _UpdateNbTicks+1 seconds. - - initFameFactions(); - CPropertySetWithExtraList const& thisFaction = thisGrpNpc.faction(); - CPropertySetWithExtraList const& thisFriendFactions = thisGrpNpc.friendFaction(); - CPropertySetWithExtraList const& thisEnnemyFactions = thisGrpNpc.ennemyFaction(); - - // We don't assist or attack players if our friends/ennemies are not in factions - bool const assistPlayers = (thisFriendFactions.containsPartOfStrictFilter("Famous*") || thisFriendFactions.have(AITYPES::CPropertyId("Player"))); - bool const assistBots = !thisFriendFactions.empty() && !bNoAssist; - bool const attackPlayers = (!thisEnnemyFactions.extraSetEmpty()) || thisEnnemyFactions.containsPartOfStrictFilter("Famous*") || thisEnnemyFactions.have(AITYPES::CPropertyId("Player")) || thisEnnemyFactions.containsPartOfStrictFilter("outpost:*"); - bool const attackBots = !thisEnnemyFactions.empty(); - - CAIVision Vision; - breakable - { - CAIVector centerPos; - if (!_Grp->calcCenterPos(centerPos)) // true if there's some bots in the group. - break; - - const uint32 playerRadius=(uint32)(assistPlayers||attackPlayers?thisGrpNpc._AggroRange:0); - const uint32 botRadius=(uint32)(assistBots||attackBots?thisGrpNpc._AggroRange:0); - - Vision.updateBotsAndPlayers(thisGrpNpc.getAIInstance(), centerPos, playerRadius, botRadius); - } - - // Assist players - if (assistPlayers) - { - // For each player - FOREACHC (itAssisted, std::vector >, Vision.players()) - { - // Get assisted entity - CPersistentOfPhysical const* const popAssisted = (*itAssisted); - CAIEntityPhysical* const epAssisted = popAssisted->getSpawnObj(); - // If entity is not alive skip it - if (!epAssisted || !epAssisted->isAlive() || epAssisted->currentHitPoints()<=0.f) - continue; - // If entity is not a friend skip it - if (!entityHavePartOfFactions(epAssisted, thisFriendFactions)) - continue; - // For each targeter of the assisted entity - CAIEntityPhysical const* epAttacker = epAssisted->firstTargeter(); - while (epAttacker) - { - // If attacker is not in our faction attack him - if (!entityHavePartOfFactions(epAttacker, thisFaction)) - aggroEntity(epAttacker); - epAttacker = epAttacker->nextTargeter(); - } - } - } - // Assist bots - if (assistBots) - { - FOREACHC (itAssisted, std::vector >, Vision.bots()) - { - // Get assisted entity - const CPersistentOfPhysical *const popAssisted = (*itAssisted); - CAIEntityPhysical *const epAssisted = popAssisted->getSpawnObj(); - // If entity is not alive skip it - if (!epAssisted || !epAssisted->isAlive() || epAssisted->currentHitPoints()<=0.f) - continue; - // If entity is not a npc skip it - if (epAssisted->getRyzomType()!=RYZOMID::npc) - continue; - // If entity is not a friend skip it - if (!entityHavePartOfFactions(epAssisted, thisFriendFactions)) - continue; - // For each targeter of the assisted entity - CAIEntityPhysical const* epAttacker = epAssisted->firstTargeter(); - while (epAttacker) - { - // If attacker is not in our faction attack him - if (!entityHavePartOfFactions(epAttacker, thisFaction)) - { - const CSpawnBot * spwBot = dynamic_cast(epAssisted); - if(spwBot) - { - if (spwBot->haveAggroWithEntity(epAttacker->dataSetRow())) - aggroEntity(epAttacker); - } - } - epAttacker = epAttacker->nextTargeter(); - } - } - } - // Attack players - if (attackPlayers) - { - FOREACHC (itAttacked, TPersistentList, Vision.players()) - { - // Get attacked entity - CPersistentOfPhysical const* const popAttacked = (*itAttacked); - CAIEntityPhysical const* const epAttacked = popAttacked->getSpawnObj(); - // If entity is not alive skip it - if (!epAttacked || !epAttacked->isAlive() || epAttacked->currentHitPoints()<=0.f) - continue; - // If entity is not an ennemy skip it - if (!entityHavePartOfFactions(epAttacked, thisEnnemyFactions)) - continue; - // If entity is a friend skip it - if (entityHavePartOfFactions(epAttacked, thisFriendFactions)) - continue; - // If entity is in our faction skip it - if (entityHavePartOfFactions(epAttacked, thisFaction)) - continue; - // If player is in safe zone skip it - CRootCell const* const rootCell = epAttacked->wpos().getRootCell(); - if (rootCell && rootCell->getFlag()!=0) // Safe Zone ? - continue; - // Attack the rest - aggroEntity(epAttacked); - } - } - // Attack bots - if (attackBots) - { - FOREACHC (itAttacked, TPersistentList, Vision.bots()) - { - // Get attacked entity - CPersistentOfPhysical const* const popAttacked = (*itAttacked); - CAIEntityPhysical const* const epAttacked = popAttacked->getSpawnObj(); - // If entity is not alive skip it - if (!epAttacked || !epAttacked->isAlive() || epAttacked->currentHitPoints()<=0.f) - continue; - // If entity is not an ennemy skip it - if (!entityHavePartOfFactions(epAttacked, thisEnnemyFactions)) - continue; - // If entity is a friend skip it - if (entityHavePartOfFactions(epAttacked, thisFriendFactions)) - continue; - // If entity is in our faction skip it - if (entityHavePartOfFactions(epAttacked, thisFaction)) - continue; - // Attack the rest - aggroEntity(epAttacked); - } - } -} - -void CGrpProfileFaction::updateProfile(uint ticksSinceLastUpdate) -{ - checkTargetsAround (); - CGrpProfileNormal::updateProfile(ticksSinceLastUpdate); -} - -string CGrpProfileFaction::getOneLineInfoString() const -{ - return "faction profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// Profile factories implementation // -////////////////////////////////////////////////////////////////////////////// - -//- Singleton profiles (stateless ones) -------------------------------------- - -CBotProfileStandAtPosFactory BotProfileStandAtPosFactory; -CBotProfileForageFactory BotProfileForageFactory; -CGrpProfileFightFactory GrpProfileFightFactory; - -//- Factory registering ------------------------------------------------------ - -// CGrpProfileGuardFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileGuardFactory, "guard"); - -// CGrpProfileTribuFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileTribuFactory, "tribu"); - -// CGrpProfileIdleFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileIdleFactory, "idle"); - -// CGrpProfileStandAtStartPointFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileStandAtStartPointFactory, "stand_on_start_point"); - -// CGrpProfileEscortedFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileEscortedFactory, "escorted"); - -// CGrpProfileGuardEscorted Factory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileGuardEscortedFactory, "guard_escorted"); - -// CGrpProfileSquadFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileSquadFactory, "squad"); - -// CGrpProfileFactionFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileFactionFactory, "faction"); - -// CGrpProfileStandOnVerticesFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileStandOnVerticesFactory, "stand_on_vertices"); - -// CGrpProfileWanderFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileWanderFactory, "wander"); - -// CGrpProfileNormalFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileNormalFactory, "normal"); - -// CGrpProfileFollowRouteFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileFollowRouteFactory, "follow_route"); - -// CGrpProfileNoChangeFactory -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileNoChangeFactory, "no_change"); - -// CGrpProfileBanditFactory -NLMISC::CSmartPtr CGrpProfileBanditFactory::createAIProfile(CProfileOwner* owner) -{ - LOG("bandit group profile factory create"); - static bool firstCall = true; - if (firstCall) - { - CConfigFile::CVar *v = IService::getInstance()->ConfigFile.getVarPtr("DefaultBanditAggroRange"); - if (v) - _DefaultAggroRange = v->asFloat(); - else - _DefaultAggroRange = 15.0f; - } - - return new CGrpProfileBandit(owner); -} -float CGrpProfileBanditFactory::getDefaultBanditAggroRange() -{ - return _DefaultAggroRange; -} -float CGrpProfileBanditFactory::_DefaultAggroRange; -RYAI_REGISTER_PROFILE_FACTORY(CGrpProfileBanditFactory, "bandit"); - -// Global profile factory stuff. This should be put in some profile.cpp since it's common with fauna profiles. -IAIProfileFactory* lookupAIGrpProfile(const char *name) -{ - IAIProfileFactory *ret = CAiFactoryIndirect::instance().getFactory(std::string(name)); - if (!ret) - nlwarning("Can't find activity '%s', returning NULL", name); - return ret; -} -RYAI_IMPLEMENT_FACTORY_INDIRECT(IAIProfileFactory, std::string); - -//***************************************************************************/ -/* Below that line is magical ununderstandable stuff */ -//***************************************************************************/ - -float getDistBetWeen(CAIEntityPhysical& creat1, CAIEntityPhysical& creat2) -{ -// coz player position is not updated really 'goodly' as it can be in a invalid ai map position. - float angTo = (creat1.pos().angleTo(creat2.pos())).asRadians(); - - return creat1.getCollisionDist(angTo) + creat2.getCollisionDist(-angTo); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileMoveTo // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileMoveTo::CBotProfileMoveTo(AITYPES::TVerticalPos verticalPos, RYAI_MAP_CRUNCH::CWorldPosition const& dest, CProfileOwner* owner) -: CAIBaseProfile() -, _VerticalPos(verticalPos) -, _Dest(dest) -, _PathCont(NLMISC::safe_cast(owner)->getAStarFlag()) -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _Bot(NLMISC::safe_cast(owner)) -{ - PROFILE_LOG("bot", "move_to", "ctor", ""); -#ifdef NL_DEBUG_PTR - _Bot.setData(this); -#endif -#if !FINAL_VERSION - nlassert(dest.x()!=0 || dest.y()!=0); -#endif -} - -void CBotProfileMoveTo::beginProfile() -{ - PROFILE_LOG("bot", "move_to", "begin", ""); - _LastPos = CAIVector(_Bot->pos()); - _PathCont.setDestination(_VerticalPos, _Dest); - _Status = CFollowPath::FOLLOWING; -} - -void CBotProfileMoveTo::endProfile() -{ - PROFILE_LOG("bot", "move_to", "end", ""); -} - -void CBotProfileMoveTo::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(BotMoveToProfileUpdate); - CFollowPathContext fpcBotMoveToProfileUpdate("BotMoveToProfileUpdate"); - - if (!_Bot->canMove()) - return; - - if (_Status != CFollowPath::FOLLOW_ARRIVED) - { - static const std::string runParameter("running"); - float dist; - if (_Bot->getPersistent().getOwner()->getSpawnObj()->checkProfileParameter(runParameter)) - dist =_Bot->runSpeed()*ticksSinceLastUpdate; - else - dist =_Bot->walkSpeed()*ticksSinceLastUpdate; - - _Status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - _PathCont, - dist, - 0.f, - .5f); - if (_Status==CFollowPath::FOLLOW_NO_PATH) - { - // get a base pointer to allow virtual call to work - - nlwarning("Follow No Path : %s", _Bot->getPersistent().getOneLineInfoString().c_str()); - } - } -} - -bool CBotProfileMoveTo::destinationReach() const -{ - return _Status == CFollowPath::FOLLOW_ARRIVED - || _Status==CFollowPath::FOLLOW_NO_PATH; -} - -std::string CBotProfileMoveTo::getOneLineInfoString() const -{ - return "move_to bot profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFollowPos // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileFollowPos::CBotProfileFollowPos(CBotProfileFollowPos const& other) -: CAIBaseProfile() -, _PathPos(const_cast(other)._PathPos._Angle) // Just to debug... -, _Bot(const_cast(other)._Bot) -, _PathCont(const_cast(other)._PathCont) -, _MaxWalkSpeed(FLT_MAX) -, _MaxRunSpeed(FLT_MAX) -, _Stop(false) -{ - PROFILE_LOG("bot", "follow_pos", "ctor", ""); -#ifdef NL_DEBUG_PTR - _Bot.setData(this); -#endif -} - -CBotProfileFollowPos::CBotProfileFollowPos(CPathCont* pathCont, CProfileOwner* owner) -: CAIBaseProfile() -, _PathPos(NLMISC::safe_cast(owner)->theta()) -, _Bot(NLMISC::safe_cast(owner)) -, _PathCont(pathCont) -, _MaxWalkSpeed(FLT_MAX) -, _MaxRunSpeed(FLT_MAX) -, _Stop(false) -{ - PROFILE_LOG("bot", "follow_pos", "ctor", ""); -#ifdef NL_DEBUG - nlassert(pathCont); -#endif -} - -void CBotProfileFollowPos::beginProfile() -{ - PROFILE_LOG("bot", "follow_pos", "begin", ""); - _Status = CFollowPath::FOLLOWING; -} - -void CBotProfileFollowPos::endProfile() -{ - PROFILE_LOG("bot", "follow_pos", "end", ""); -} - -void CBotProfileFollowPos::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(BotFollowPosProfileUpdate); - CFollowPathContext fpcBotFollowPosProfileUpdate("BotFollowPosProfileUpdate"); - - if (!_Bot->canMove() || _Stop) - return; - - static const std::string runParameter("running"); - float dist; - float speed; - if (_Bot->getPersistent().getOwner()->getSpawnObj()->checkProfileParameter(runParameter)) - speed = std::min(_Bot->runSpeed(), _MaxRunSpeed); - else - speed = std::min(_Bot->walkSpeed(), _MaxWalkSpeed); - - dist = speed*ticksSinceLastUpdate; - - CPathCont &pathContRef=*_PathCont; - if (_Status!=CFollowPath::FOLLOW_NO_PATH) - { - _Status = CFollowPath::getInstance()->followPath( - _Bot, - _PathPos, - pathContRef, - dist, - 0, - .5f); - } - if (_Status==CFollowPath::FOLLOW_NO_PATH) - { - // R2_PRIMITIVE_LAXITY - if (!IsRingShard.get()) - { - nlwarning("Follow No Path for '%s'%s", - _Bot->getPersistent().getAliasFullName().c_str(), - _Bot->getPersistent().getAliasString().c_str()); - } - } -} - -std::string CBotProfileFollowPos::getOneLineInfoString() const -{ - std::string info = "follow_pos bot profile"; - info += " stop=" + NLMISC::toString(_Stop); - info += " max_walk_speed=" + NLMISC::toString(_MaxWalkSpeed); - info += " max_run_speed=" + NLMISC::toString(_MaxRunSpeed); - return info; -} - -void CBotProfileFollowPos::setMaxSpeeds(float walkSpeed, float runSpeed) -{ - _MaxWalkSpeed = walkSpeed; - _MaxRunSpeed = runSpeed; -} - -void CBotProfileFollowPos::setStop(bool stop) -{ - _Stop = stop; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileWanderBase // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileWanderBase::CBotProfileWanderBase() -: CAIBaseProfile() -{ - PROFILE_LOG("bot", "wander_base", "ctor", ""); -} - -void CBotProfileWanderBase::setTimer(uint32 ticks) -{ - _Timer.set(ticks); -} - -bool CBotProfileWanderBase::testTimer() const -{ - return _Timer.test(); -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileStandAtPos // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileStandAtPos::CBotProfileStandAtPos(CProfileOwner* owner) -: CBotProfileWanderBase() -, _Bot(NLMISC::safe_cast(owner)) -{ - PROFILE_LOG("bot", "stand_at_pos", "ctor", ""); -#ifdef NL_DEBUG_PTR - _Bot.setData(this); -#endif -} - -void CBotProfileStandAtPos::beginProfile() -{ - PROFILE_LOG("bot", "stand_at_pos", "begin", ""); -} - -void CBotProfileStandAtPos::endProfile() -{ - PROFILE_LOG("bot", "stand_at_pos", "end", ""); -} - -void CBotProfileStandAtPos::updateProfile(uint ticksSinceLastUpdate) -{ -} - -std::string CBotProfileStandAtPos::getOneLineInfoString() const -{ - return "stand_at_pos bot profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileForage // -////////////////////////////////////////////////////////////////////////////// - -CBotProfileForage::CBotProfileForage(CProfileOwner* owner) -: CBotProfileWanderBase() -, _Bot(NLMISC::safe_cast(owner)) -, _TemporarySheetUsed(false) -{ - PROFILE_LOG("bot", "forage", "ctor", ""); -#ifdef NL_DEBUG_PTR - _Bot.setData(this); -#endif - _OldSheet = 0; -} - -CBotProfileForage::~CBotProfileForage() -{ - PROFILE_LOG("bot", "forage", "dtor", ""); -#ifdef NL_DEBUG - nlassert(_TemporarySheetUsed==false); -#endif - if (_TemporarySheetUsed) - { - setOldSheet(); // if this leads to a virtual pure call somewhere, - // try to ask profileOwner to flush its profile in Bot dtor, - // which is a proper way to delete objects. - } -} - -void CBotProfileForage::beginProfile() -{ - PROFILE_LOG("bot", "forage", "begin", ""); - // begin first forage in 3-10 second - _ForageTimer.set(30+CAIS::rand32(70)); - - static const NLMISC::CSheetId forageTool("itforage.sitem"); - /* - AISHEETS::ICreature *cs = new AISHEETS::CCreature(*_Bot->getPersistent().getSheet()); - _OldSheet = _Bot->getPersistent().getSheet(); - cs->LeftItem = NLMISC::CSheetId(); - cs->RightItem = forageTool; - _Bot->getPersistent().setSheet(cs); - _Bot->getPersistent().sendVPA(); - _TemporarySheetUsed = true; - */ - nlerror("This profile has been broken (above block commented), it shouldn't be used"); - - // begin propecting - _Bot->setBehaviour(MBEHAV::PROSPECTING); -} - -void CBotProfileForage::endProfile() -{ - PROFILE_LOG("bot", "forage", "end", ""); - // stop foraging if needed - if (_Bot->getBehaviour() == MBEHAV::EXTRACTING) - _Bot->setBehaviour(MBEHAV::EXTRACTING_END); - else if (_Bot->getBehaviour() == MBEHAV::PROSPECTING) - _Bot->setBehaviour(MBEHAV::PROSPECTING_END); - /* - setOldSheet(); - */ - nlerror("This profile has been broken (above block commented), it shouldn't be used"); -} - -void CBotProfileForage::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(BotForageProfileUpdate); - CFollowPathContext fpcBotForageProfileUpdate("BotForageProfileUpdate"); - - if (_ForageTimer.test()) - { - // somethink to do :) - if (_Bot->getBehaviour() != MBEHAV::EXTRACTING) - { - // do a little turn - CAngle a = _Bot->theta(); - CAngle newAngle(CAIS::randPlusMinus(CAngle::PI/4)); - _Bot->setTheta(a+newAngle); - - // begin foraging - _Bot->setBehaviour(MBEHAV::EXTRACTING); - - // forage for 10 to 15 sec - _ForageTimer.set(100+CAIS::rand32(50)); - } - else if (_Bot->getBehaviour() == MBEHAV::EXTRACTING) - { - // end foraging - _Bot->setBehaviour(MBEHAV::PROSPECTING); - - // wait 20-30s before next forage - _ForageTimer.set(250+CAIS::rand32(50)); - } - } -} - -void CBotProfileForage::setOldSheet() -{ - AISHEETS::ICreatureCPtr cs = _Bot->getPersistent().getSheet(); - _Bot->getPersistent().setSheet(_OldSheet); - _Bot->getPersistent().sendVPA(); - _TemporarySheetUsed = false; -// delete const_cast(cs); - nlerror("This profile has been broken (above line commented), it shouldn't be used"); -} - -std::string CBotProfileForage::getOneLineInfoString() const -{ - return "forage bot profile"; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileNormal // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileNormal::CGrpProfileNormal(CProfileOwner* owner) -: _Grp(NLMISC::safe_cast(owner)) -//, _GroupFighting(false) // :KLUDGE: Replaced by a bug simulation -{ - PROFILE_LOG("group", "normal", "ctor", ""); - // This should be part of init list, but can't do conditionnal init - if (simulateBug(7)) - { - /* Following statement was missing in initialization list. */ - } - else - { - _GroupFighting = false; - } -} - -bool CGrpProfileNormal::isGroupFighting() const -{ - return _GroupFighting; -} - -void CGrpProfileNormal::setGroupFighting(bool groupFighting) -{ - if (_GroupFighting!=groupFighting) - { - _GroupFighting=groupFighting; - - CGroupNpc &grp=_Grp->getPersistent(); - if (groupFighting) - grp.processStateEvent(grp.getEventContainer().EventGroupBeginFight); - else - grp.processStateEvent(grp.getEventContainer().EventGroupEndFight); - } -} - -////////////////////////////////////////////////////////////////////////////// -// CSlaveProfile // -////////////////////////////////////////////////////////////////////////////// - -CSlaveProfile::CSlaveProfile(CProfileOwner* owner) -: _Grp(NLMISC::safe_cast(owner)) -{ - PROFILE_LOG("base", "slave", "ctor", ""); -} - -void CSlaveProfile::beginProfile() -{ - PROFILE_LOG("base", "slave", "begin", ""); - FOREACH(itBot, CCont, _Grp->bots()) - { - CBot* bot = *itBot; - CSpawnBot* spawnBot = bot->getSpawnObj(); - if (!spawnBot || !spawnBot->isAlive()) - continue; - addBot(bot); - } -} - -void CSlaveProfile::updateProfile(uint ticksSinceLastUpdate) -{ -} - -////////////////////////////////////////////////////////////////////////////// -// CMoveProfile // -////////////////////////////////////////////////////////////////////////////// - -CMoveProfile::CMoveProfile(CProfileOwner* owner) -: CSlaveProfile(owner) -, _MaxRunSpeed(FLT_MAX) -, _MaxWalkSpeed(FLT_MAX) -{ - PROFILE_LOG("base", "move", "ctor", ""); -} - -void CMoveProfile::resumeBot(CBot const* bot) -{ - CSpawnBot* spawnBot = bot->getSpawnObj(); - if (!spawnBot) - return; - - CPathCont* pathCont = getPathCont(bot); - if (!pathCont) - return; - - spawnBot->setAIProfile(new CBotProfileFollowPos(pathCont, spawnBot)); -} - -////////////////////////////////////////////////////////////////////////////// -// CFightProfile // -////////////////////////////////////////////////////////////////////////////// - -CFightProfile::CFightProfile(CProfileOwner* owner) -: CSlaveProfile(owner) -{ - PROFILE_LOG("base", "fight", "ctor", ""); -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFollowRoute // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileFollowRoute::~CGrpProfileFollowRoute() -{ - PROFILE_LOG("group", "follow_route", "dtor", ""); - FOREACH(itBot, CCont, _Grp->bots()) - removeBot(*itBot); -} - -CGrpProfileFollowRoute::CBotFollower::CBotFollower() -: _BotAtDest(false) -{ -} - -CGrpProfileFollowRoute::CBotFollower::~CBotFollower() -{ -} - -void CGrpProfileFollowRoute::CBotFollower::setBotAtDest(bool atDest) -{ - _BotAtDest = atDest; -} - -const bool& CGrpProfileFollowRoute::CBotFollower::isBotAtDest() const -{ - return _BotAtDest; -} - -bool CGrpProfileFollowRoute::getDirection() -{ - return _FollowForward; -} - - -CPathCont* CGrpProfileFollowRoute::getPathCont(CBot const* bot) -{ - return &_PathCont; -} - -std::string CGrpProfileFollowRoute::getOneLineInfoString() const -{ - std::string info = "follow_route group profile"; - info += " stop_npc=" + NLMISC::toString(_StopNpc); - return info; -} - -bool CGrpProfileFollowRoute::profileTerminated() const -{ - return _ProfileTerminated; -} - -void CGrpProfileFollowRoute::stopNpc(bool stop) -{ - _StopNpc = stop; -} - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileStandOnVertices // -////////////////////////////////////////////////////////////////////////////// - -CGrpProfileStandOnVertices::CBotPositionner::CBotPositionner(RYAI_MAP_CRUNCH::TAStarFlag flags) -: _PathCont(flags) -{ -} - -CGrpProfileStandOnVertices::CBotPositionner::CBotPositionner(uint32 geomIndex, RYAI_MAP_CRUNCH::TAStarFlag flags) -: _PathCont(flags) -, _GeomIndex(geomIndex) -, _BotAtDest(false) -{ -} - -void CGrpProfileStandOnVertices::CBotPositionner::setBotAtDest(bool atDest) -{ - _BotAtDest=atDest; -} - -bool CGrpProfileStandOnVertices::CBotPositionner::isBotAtDest() const -{ - return _BotAtDest; -} - -CGrpProfileStandOnVertices::CGrpProfileStandOnVertices(CProfileOwner* owner) -: CMoveProfile(owner) -, _DenyFlags(NLMISC::safe_cast(owner)->getPersistent().getAStarFlag()) -{ - PROFILE_LOG("group", "stand_on_vertices", "ctor", ""); -} - -CGrpProfileStandOnVertices::~CGrpProfileStandOnVertices() -{ - PROFILE_LOG("group", "stand_on_vertices", "dtor", ""); - for (CCont::iterator it=_Grp->bots().begin(), itEnd=_Grp->bots().end();it!=itEnd;++it) - { - removeBot(*it); - } -} - -void CGrpProfileStandOnVertices::endProfile() -{ - PROFILE_LOG("group", "stand_on_vertices", "end", ""); -} - -std::string CGrpProfileStandOnVertices::getOneLineInfoString() const -{ - std::string info = "stand_on_vertices group profile"; - info += " finished=" + NLMISC::toString(_Finished); - return info; -} - - -//- Complex profile factories ------------------------------------------------ - -// CBotProfileMoveToFactory (with specialization) -typedef CAIGenericProfileFactory CBotProfileMoveToFactory; -template <> -NLMISC::CSmartPtr CAIGenericProfileFactory::createAIProfile(CProfileOwner* owner) -{ - nlerror("This profile factory (CBotProfileMoveToFactory) can't be used"); - return NULL; -} - -// CBotProfileFollowPosFactory (with specialization) -typedef CAIGenericProfileFactory CBotProfileFollowPosFactory; -template <> -NLMISC::CSmartPtr CAIGenericProfileFactory::createAIProfile(CProfileOwner* owner) -{ - nlerror("This profile factory (CBotProfileFollowPosFactory) can't be used"); - return NULL; -} - -#include "event_reaction_include.h" diff --git a/code/ryzom/server/src/ai_service/ai_profile_npc.h b/code/ryzom/server/src/ai_service/ai_profile_npc.h deleted file mode 100644 index bd4993662..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_npc.h +++ /dev/null @@ -1,1007 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -#ifndef AI_PROFILE_NPC_H -#define AI_PROFILE_NPC_H - -#include "profile.h" -#include "ai_bot_npc.h" -#include "ai_grp_npc.h" -#include "ai_generic_fight.h" - -extern bool simulateBug(int bugId); - -// Forard declarations -class CSpawnGroupNpc; - -////////////////////////////////////////////////////////////////////////////// -// Free variables and functions // -////////////////////////////////////////////////////////////////////////////// - -extern bool ai_profile_npc_VerboseLog; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileMoveTo // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileMoveTo -: public CAIBaseProfile -, public NLMISC::IDbgPtrData -{ -public: - CBotProfileMoveTo(AITYPES::TVerticalPos verticalPos, RYAI_MAP_CRUNCH::CWorldPosition const& dest, CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::BOT_MOVE_TO; } - virtual std::string getOneLineInfoString() const; - //@} - - bool destinationReach() const; - - CFollowPath::TFollowStatus _Status; - AITYPES::TVerticalPos _VerticalPos; - RYAI_MAP_CRUNCH::CWorldPosition _Dest; - CPathCont _PathCont; - CPathPosition _PathPos; - CAIVector _LastPos; - -protected: - NLMISC::CDbgPtr _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileFollowPos // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileFollowPos -: public CAIBaseProfile -, public NLMISC::IDbgPtrData -{ -public: - CBotProfileFollowPos(CPathCont* pathCont, CProfileOwner* owner); - CBotProfileFollowPos(CBotProfileFollowPos const& other); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_FOLLOW_POS; } - virtual std::string getOneLineInfoString() const; - //@} - - void setMaxSpeeds(float walkSpeed, float runSpeed); - void setStop(bool stop); - - CFollowPath::TFollowStatus _Status; - CPathPosition _PathPos; - -protected: - NLMISC::CDbgPtr _Bot; - -private: - NLMISC::CDbgPtr _PathCont; - - // maximum speed to use (for group with different creatures) - float _MaxWalkSpeed; - float _MaxRunSpeed; - - // flag to stop temporary stop the movement - bool _Stop; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileWanderBase // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileWanderBase -: public CAIBaseProfile -{ -public: - CBotProfileWanderBase(); - - void setTimer(uint32 ticks); - bool testTimer() const; - -protected: - CAITimer _Timer; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileStandAtPos // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileStandAtPos -: public CBotProfileWanderBase -, public NLMISC::IDbgPtrData -{ -public: - CBotProfileStandAtPos(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_STAND_AT_POS; } - virtual std::string getOneLineInfoString() const; - //@} - -protected: - NLMISC::CDbgPtr _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CBotProfileForage // -////////////////////////////////////////////////////////////////////////////// - -class CBotProfileForage -: public CBotProfileWanderBase -, public NLMISC::IDbgPtrData -{ -public: - CBotProfileForage(CProfileOwner* owner); - virtual ~CBotProfileForage(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::BOT_FORAGE; } - virtual std::string getOneLineInfoString() const; - //@} - - void setOldSheet(); - -protected: - NLMISC::CDbgPtr _Bot; - - CAITimer _ForageTimer; - AISHEETS::ICreatureCPtr _OldSheet; - bool _TemporarySheetUsed; -}; - -////////////////////////////////////////////////////////////////////////////// -// CActivityProfile // -////////////////////////////////////////////////////////////////////////////// - -class CActivityProfile -: public CAIBaseProfile -{ -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileNormal // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileNormal -: public CActivityProfile -{ -public: - CGrpProfileNormal(CProfileOwner* owner); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::ACTIVITY_NORMAL; } - virtual std::string getOneLineInfoString() const; - //@} - - bool isGroupFighting() const; - void setGroupFighting(bool groupFighting); - -protected: - NLMISC::CDbgPtr _Grp; - bool _GroupFighting; -}; - -////////////////////////////////////////////////////////////////////////////// -// CSlaveProfile // -////////////////////////////////////////////////////////////////////////////// -// :TODO: Understand following comment, and act accordingly -// every bot add or remove must be done from a spawn/despawn/die event (and not this way!) - -class CSlaveProfile -: public CAIBaseProfile -{ -public: - CSlaveProfile(CProfileOwner* owner); - - /// @name IAIProfile partial implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - //@} - - virtual void addBot(CBot* bot) = 0; - virtual void removeBot(CBot* bot) = 0; - -protected: - NLMISC::CDbgPtr _Grp; -}; - -////////////////////////////////////////////////////////////////////////////// -// CMoveProfile // -////////////////////////////////////////////////////////////////////////////// - -class CMoveProfile -: public CSlaveProfile -{ -public: - CMoveProfile(CProfileOwner* owner) ; - - virtual CPathCont* getPathCont(CBot const* bot) = 0; - - virtual void resumeBot(CBot const* bot); - -protected: - float _MaxRunSpeed; - float _MaxWalkSpeed; -}; - -////////////////////////////////////////////////////////////////////////////// -// CFightProfile // -////////////////////////////////////////////////////////////////////////////// - -class CFightProfile -: public CSlaveProfile -{ -public: - CFightProfile(CProfileOwner* owner); - - virtual std::vector& npcList() = 0; - virtual bool stillHaveEnnemy() const = 0; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGoToPoint // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileGoToPoint -: public CMoveProfile -{ -public: - /// @name Constructors, destructor - //@{ - CGrpProfileGoToPoint(CProfileOwner* owner, RYAI_MAP_CRUNCH::CWorldPosition const& startPos, RYAI_MAP_CRUNCH::CWorldPosition const& endPos, bool dontSendEvent = false); - virtual ~CGrpProfileGoToPoint(); - //@} - - enum TShapeType - { - SHAPE_NOTHING, - SHAPE_RECTANGLE, - }; - class CBotFollower - { - public: - CBotFollower(); - virtual ~CBotFollower(); - void setBotAtDest(bool atDest = true); - const bool& isBotAtDest() const; - - private: - bool _BotAtDest; - }; - - /// @name CMoveProfile implementation - //@{ - virtual CPathCont* getPathCont(CBot const* bot); - //@} - - /// @name CSlaveProfile implementation - //@{ - virtual void addBot(CBot* bot); - virtual void removeBot(CBot* bot); - //@} - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_GOTO_POINT; } - virtual std::string getOneLineInfoString() const; - virtual void stateChangeProfile(); - virtual void resumeProfile(); - //@} - - bool profileTerminated() const; - -protected: - void setDirection(bool forward); - bool getDirection(); - - - void setCurrentDestination(RYAI_MAP_CRUNCH::CWorldPosition const& dest); - - void calcRatios(); - - void stopNpc(bool stop); - -private: - void assignGeometryFromState(); - - typedef std::map TBotFollowerMap; - TBotFollowerMap _NpcList; - - bool _ValidPosInit; - bool _FollowForward; - bool _ProfileTerminated; - bool _MustCalcRatios; - TShapeType _Shape; - RYAI_MAP_CRUNCH::CWorldPosition _StartPos; - RYAI_MAP_CRUNCH::CWorldPosition _EndPos; - - /// flag to temporary stop the bots - bool _StopNpc; - - // rectangle shape related vars. - float _XSize; - float _YSize; - float _Ratio; - double _Cx, _Cy; - uint32 _NbRange; - uint32 _NbLines; - uint32 _NbBotInNormalShape; - uint32 _Rest; - - uint32 _GeomIndex; - CPathCont _PathCont; - CAIVector _GlobalOrient; - - AITYPES::TVerticalPos _VerticalPos; - bool _DontSendEvent; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFollowRoute // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileFollowRoute -: public CMoveProfile -{ -public: - CGrpProfileFollowRoute(CProfileOwner* owner, std::vector const& geometry, AITYPES::TVerticalPos const& verticalPos, bool dontSendEvent = false); - CGrpProfileFollowRoute(CProfileOwner* owner); - - virtual ~CGrpProfileFollowRoute(); - - enum TShapeType - { - SHAPE_NOTHING, - SHAPE_RECTANGLE, - }; - - class CBotFollower - { - public: - CBotFollower(); - virtual ~CBotFollower(); - void setBotAtDest(bool atDest = true); - const bool& isBotAtDest() const; - - private: - bool _BotAtDest; - }; - - void setDirection(bool forward); - bool getDirection(); - - void resumeProfile(); - - CPathCont* getPathCont(CBot const* bot); - - void addBot(CBot* bot); - void removeBot(CBot* bot); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_FOLLOW_ROUTE; } - virtual std::string getOneLineInfoString() const; - //@} - - bool profileTerminated() const; - - void setCurrentValidPos(AITYPES::TVerticalPos verticalPos); - - void calcRatios(); - - virtual void stateChangeProfile(); - - void stopNpc(bool stop); - -private: - void assignGeometryFromState(); - - typedef std::map TBotFollowerMap; - TBotFollowerMap _NpcList; - - bool _ValidPosInit; - bool _FollowForward; - bool _ProfileTerminated; - bool _MustCalcRatios; - TShapeType _Shape; - - /// flag to temporary stop the bots - bool _StopNpc; - - // rectangle shape related vars. - float _XSize; - float _YSize; - float _Ratio; - double _Cx, _Cy; - uint32 _NbRange; - uint32 _NbLines; - uint32 _NbBotInNormalShape; - uint32 _Rest; - - uint32 _GeomIndex; - CPathCont _PathCont; - CAIVector _GlobalOrient; - - bool _GeometryComeFromState; - std::vector const* _Geometry; - AITYPES::TVerticalPos _VerticalPos; - bool _DontSendEvent; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileStandOnVertices // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileStandOnVertices -: public CMoveProfile -{ -public: - // utility class - class CBotPositionner : public NLMISC::CRefCount - { - public: - CBotPositionner(RYAI_MAP_CRUNCH::TAStarFlag flags); - CBotPositionner(uint32 geomIndex, RYAI_MAP_CRUNCH::TAStarFlag flags); - void setBotAtDest(bool atDest = true); - bool isBotAtDest() const; - - CPathCont _PathCont; - uint32 _GeomIndex; - private: - bool _BotAtDest; - }; - - CGrpProfileStandOnVertices(CProfileOwner* owner); - ~CGrpProfileStandOnVertices(); - - CPathCont *getPathCont (const CBot *bot); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_STAND_ON_VERTICES; } - virtual std::string getOneLineInfoString() const; - //@} - void resumeProfile(); - - void setCurrentValidPos (CAIStatePositional *grpState); - - void addBot(CBot* bot); - void removeBot(CBot* bot); - -private: - typedef std::map > TNpcBotPositionnerMap; - TNpcBotPositionnerMap _NpcList; - bool _Finished; - RYAI_MAP_CRUNCH::TAStarFlag _DenyFlags; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileWander // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileWander -: public CMoveProfile -{ -public: - CGrpProfileWander(CProfileOwner* owner); - CGrpProfileWander(CProfileOwner* owner, CNpcZone const* const npcZone); - virtual ~CGrpProfileWander(); - - void setBotStandProfile(AITYPES::TProfiles botStandProfileType, IAIProfileFactory* botStandProfileFactory); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_WANDER; } - virtual std::string getOneLineInfoString() const; - //@} - - void addBot (CBot* bot); - void removeBot (CBot* bot); - CPathCont* getPathCont (CBot const* bot); - - void stateChangeProfile(); - - void affectZoneFromStateMachine(); - void resetDestinationReachedData(); - - void setTimer(uint32 ticks) { _Timer.set(ticks); } - bool testTimer() const { return _Timer.test(); } - - CNpcZone const* currentZone() const { return _NpcZone; } - -private: - - /// the profile type to apply to bot standing between two deplacement - AITYPES::TProfiles _BotStandProfileType; - /// the profile factory to apply to bot standing between two deplacement - IAIProfileFactory*_BotStandProfileFactory; - /// a flag to force social interaction for the bots - bool _Social; - - NLMISC::CstCDbgPtr _RandomPos; - NLMISC::CSmartPtr _NpcZone; - std::vector _NpcDestinationReached; - bool _DestinationReachedAll; - bool _DestinationReachedFirst; - - CAITimer _Timer; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileWanderNoPrim // -////////////////////////////////////////////////////////////////////////////// - -/// This profile shouldn't require data primitive for wander zone -class CGrpProfileWanderNoPrim -: public CMoveProfile -{ -public: -// CGrpProfileWanderNoPrim(CProfileOwner* owner); - CGrpProfileWanderNoPrim(CProfileOwner* owner, NLMISC::CSmartPtr const& npcZone); - virtual ~CGrpProfileWanderNoPrim(); - - void setBotStandProfile(AITYPES::TProfiles botStandProfileType, IAIProfileFactory* botStandProfileFactory); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_WANDER; } - virtual std::string getOneLineInfoString() const; - //@} - - void addBot (CBot* bot); - void removeBot (CBot* bot); - CPathCont* getPathCont (CBot const* bot); - - void stateChangeProfile(); - -// void affectZoneFromStateMachine(); - - void setTimer(uint32 ticks) { _Timer.set(ticks); } - bool testTimer() const { return _Timer.test(); } - -// CNpcZone const* currentZone() const { return _NpcZone; } - -private: - - /// the profile type to apply to bot standing between two deplacement - AITYPES::TProfiles _BotStandProfileType; - /// the profile factory to apply to bot standing between two deplacement - IAIProfileFactory*_BotStandProfileFactory; - /// a flag to force social interaction for the bots - bool _Social; - -// NLMISC::CstCDbgPtr _RandomPos; - NLMISC::CSmartPtr _NpcZone; - - CAITimer _Timer; -}; - -class CGrpProfileFollowPlayer : -public CMoveProfile -{ -public: - CGrpProfileFollowPlayer(CProfileOwner* owner, TDataSetRow const& playerRow, uint32 dispersionRadius); - virtual ~CGrpProfileFollowPlayer() {} - - void setBotStandProfile(AITYPES::TProfiles botStandProfileType, IAIProfileFactory* botStandProfileFactory); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile() {} - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_FOLLOW_POS; } - virtual std::string getOneLineInfoString() const { return std::string("follow_player group profile"); } - //@} - - void stateChangeProfile() {} - bool destinationReach() const; - - void addBot (CBot* bot) {} - void removeBot (CBot* bot) {} - CPathCont* getPathCont (CBot const* bot) { return NULL; }; - - -protected: -private: - /// the profile type to apply to bot standing between two deplacement - AITYPES::TProfiles _BotStandProfileType; - /// the profile factory to apply to bot standing between two deplacement - IAIProfileFactory*_BotStandProfileFactory; - - CFollowPath::TFollowStatus _Status; - CPathPosition _PathPos; - CPathCont _PathCont; - CAIVector _LastPos; - - TDataSetRow _PlayerRow; - uint32 _DispersionRadius; -}; - - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileIdle // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileIdle -: public CMoveProfile -{ -public: - CGrpProfileIdle(CProfileOwner* owner); - virtual ~CGrpProfileIdle(); - - class CBotPositionner - { - public: - CBotPositionner(); - virtual ~CBotPositionner(); - }; - - CPathCont* getPathCont(CBot const* bot); - virtual void beginProfile(); - void resumeProfile(); - virtual void endProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - - void addBot(CBot* bot); - void removeBot(CBot* bot); - - virtual std::string getOneLineInfoString() const; - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::MOVE_IDLE; } - -private: - typedef std::map TNpcBotPositionnerMap; - TNpcBotPositionnerMap _NpcList; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileBandit // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileBandit -: public CGrpProfileNormal -{ -public: - CGrpProfileBandit(CProfileOwner* owner); - virtual ~CGrpProfileBandit(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::ACTIVITY_BANDIT; } - virtual std::string getOneLineInfoString() const; - //@} - -private: - uint32 _AggroRange; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileEscorted // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileEscorted -: public CGrpProfileNormal -{ -public: - CGrpProfileEscorted(CProfileOwner* owner); - virtual ~CGrpProfileEscorted(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType () const { return AITYPES::ACTIVITY_ESCORTED; } - virtual std::string getOneLineInfoString() const; - //@} - - void stateChangeProfile(); - -protected: - bool _EscortTeamInRange; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGuard // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileGuard -: public CGrpProfileNormal -{ -public: - CGrpProfileGuard(CProfileOwner* owner); - virtual ~CGrpProfileGuard(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_GUARD; } - virtual std::string getOneLineInfoString() const; - //@} - -private: - CAIVector _CenterPos; - uint32 _AggroRange; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileGuardEscorted // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileGuardEscorted -: public CGrpProfileNormal -{ -public: - CGrpProfileGuardEscorted(CProfileOwner* owner); - virtual ~CGrpProfileGuardEscorted(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_GUARD_ESCORTED; } - virtual std::string getOneLineInfoString() const; - //@} - - void stateChangeProfile(); - -protected: - NLMISC::CSmartPtr _GuardProfile; - NLMISC::CSmartPtr _EscortedProfile; -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFaction // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileFaction -: public CGrpProfileNormal -{ -public: - CGrpProfileFaction(CProfileOwner* owner); - virtual ~CGrpProfileFaction(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_FACTION; } - virtual std::string getOneLineInfoString() const; - //@} - - virtual void aggroEntity(CAIEntityPhysical const* entity); - void checkTargetsAround(); - void noAssist() { bNoAssist = true; } - - static std::string scriptFactionToFameFaction(std::string name); - static std::string fameFactionToScriptFaction(std::string name); - - static bool scriptFactionToFameFactionGreaterThan(std::string name); - static sint32 scriptFactionToFameFactionValue(std::string name); - - -private: - CAITimer _checkTargetTimer; - bool bNoAssist; - -private: - static AITYPES::CPropertySet _FameFactions; - static void initFameFactions(); - static bool entityHavePartOfFactions(CAIEntityPhysical const* entity, AITYPES::CPropertySetWithExtraList const& factions); -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileSquad // -// The Manager Parent of the Manager of this Grp class is COutpost // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileSquad -: public CGrpProfileFaction -{ -public: - CGrpProfileSquad(CProfileOwner* owner); - virtual ~CGrpProfileSquad(); - - /// @name IAIProfile implementation - //@{ - virtual void beginProfile(); - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::ACTIVITY_SQUAD; } - virtual std::string getOneLineInfoString() const; - //@} - - virtual void aggroEntity(CAIEntityPhysical const* entity); - - NLMISC::CSmartPtr buildFirstHitPlace(TDataSetRow const& aggroBot); - -protected: - - /// Return the outpost to which the squad belongs, or NULL if not found - COutpost* getDefendedOutpost() { return dynamic_cast(_Grp->getPersistent().getOwner()->getOwner()); } -}; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileFight // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileFight -: public CFightProfile -, public CFightOrganizer -{ - // TODO : set this parameters thrue the group, no hardcode them - enum - { - - CHECK_AROUND_PERIOD = 50, ///< Check every 5s - CHECK_AROUND_RADIUS = 60, ///< Check 60 meters around - }; -public: - CGrpProfileFight(CProfileOwner *owner); - virtual ~CGrpProfileFight(); - - virtual void beginProfile(); - void endProfile(); - - void addBot (CBot *bot); - void removeBot (CBot *bot); - - ////////////////////////////////////////////////////////////////////////// - /// @name CFightOrganizer - //@{ - virtual void setFight(CSpawnBot* bot, CAIEntityPhysical* ennemy); - virtual void setHeal(CSpawnBot* bot, CAIEntityPhysical* target); - virtual void setNoFight(CSpawnBot* bot); - virtual void setFlee(CSpawnBot* bot, CAIVector& fleeVect); - virtual void setReturnAfterFight(CSpawnBot* bot); - //@} - - bool stillHaveEnnemy () const; - - virtual void updateProfile(uint ticksSinceLastUpdate); - - virtual std::string getOneLineInfoString() const; - - virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::FIGHT_NORMAL; } - - std::vector &npcList(); - -private: - std::vector _NpcList; - /// A timer to check the friend groups around and set their aggro list if they are not fighting - CAITimer _CheckAround; - bool _WasRunning; -}; - -/****************************************************************************/ -/* Profile factories */ -/****************************************************************************/ - -//- Simple profile factories (based on generic factory) ---------------------- - -// CBotProfileStandAtPos -typedef CAIGenericProfileFactory CBotProfileStandAtPosFactory; - -// CBotProfileForage -typedef CAIGenericProfileFactory CBotProfileForageFactory; - -// CGrpProfileNormal -typedef CAIGenericProfileFactory CGrpProfileNormalFactory; - -// CGrpProfileFollowRoute -typedef CAIGenericProfileFactory CGrpProfileFollowRouteFactory; - -// CGrpProfileWander -typedef CAIGenericProfileFactory CGrpProfileWanderFactory; - -// CGrpProfileGuardFactory -typedef CAIGenericProfileFactory CGrpProfileGuardFactory; - -// CGrpProfileEscortedFactory -typedef CAIGenericProfileFactory CGrpProfileEscortedFactory; - -// CGrpProfileGuardEscortedFactory -typedef CAIGenericProfileFactory CGrpProfileGuardEscortedFactory; - -// CGrpProfileFactionFactory -typedef CAIGenericProfileFactory CGrpProfileFactionFactory; - -// CGrpProfileSquadFactory -typedef CAIGenericProfileFactory CGrpProfileSquadFactory; - -// CGrpProfileStandOnVerticesFactory -typedef CAIGenericProfileFactory CGrpProfileStandOnVerticesFactory; - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileNoChange // -////////////////////////////////////////////////////////////////////////////// - -/// No change special profile -class CGrpProfileNoChangeFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner) - { - return NULL; - } -}; -RYAI_DECLARE_PROFILE_FACTORY(CGrpProfileNoChangeFactory); - -////////////////////////////////////////////////////////////////////////////// -// CGrpProfileBanditFactory // -////////////////////////////////////////////////////////////////////////////// - -class CGrpProfileBanditFactory -: public IAIProfileFactory -{ -public: - NLMISC::CSmartPtr createAIProfile(CProfileOwner* owner); - static float getDefaultBanditAggroRange(); -private: - static float _DefaultAggroRange; -}; - -//- Singleton profiles (stateless ones) -------------------------------------- - -extern CBotProfileStandAtPosFactory BotProfileStandAtPosFactory; -extern CBotProfileForageFactory BotProfileForageFactory; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_profile_pet.cpp b/code/ryzom/server/src/ai_service/ai_profile_pet.cpp deleted file mode 100644 index 87bce52cc..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_pet.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_profile_pet.h" - -#include "ai_bot_pet.h" // for CSpawnBotPet -#include "ai_grp_pet.h" // for CSpawnGroupPet -#include "server_share/animal_hunger.h" // for CSpeedLimit - -using namespace NLMISC; -using namespace NLNET; -using namespace RYAI_MAP_CRUNCH; -using namespace AITYPES; - -/****************************************************************************/ -/* Local classes */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CTopoPosValidator // -////////////////////////////////////////////////////////////////////////////// - -class CTopoPosValidator -: public CWorldContainer::CPosValidator -{ -public: - CTopoPosValidator(CWorldPosition const& startPos, TAStarFlag denyFlags); - bool check(CWorldPosition const& wpos) const; - -private: - CWorldPosition _StartPos; - TAStarFlag _DenyFlags; -}; - -/****************************************************************************/ -/* Methods definitions */ -/****************************************************************************/ - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileStand // -////////////////////////////////////////////////////////////////////////////// - -CAIPetProfileStand::CAIPetProfileStand(CSpawnBotPet* bot) -: CAIBaseProfile() -, _Bot(bot) -{ -#ifndef NL_DEBUG - nlassert(bot); -#endif -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileFollowPlayer // -////////////////////////////////////////////////////////////////////////////// - -CAIPetProfileFollowPlayer::CAIPetProfileFollowPlayer(CSpawnBotPet* bot, TDataSetRow const& playerRow) -: CAIBaseProfile() -, _Bot(bot) -, _PlayerRow(playerRow) -{ -} - -void CAIPetProfileFollowPlayer::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(PetFollowPlayer); - - // Is the pet stucked by something? - if (!_Bot->canMove()) - return; - - // Need to wait for a correct position before moving? - CAIVector const& dest = _Bot->spawnGrp().getPathCont().getDestination(); - if (dest.x()==0 || dest.y()==0) - return; - - CPathCont& pathCont = _Bot->spawnGrp().getPathCont(); - if ((pathCont.getDestination()-_Bot->wpos().toAIVector()).quickNorm()>6.f) // follow only if > 6 meters. - { - // Handle the hunger of the animal - CSpeedLimit speedLimit( TheDataset, _Bot->dataSetRow() ); - float speedToUse = speedLimit.getSpeedLimit( _Bot->walkSpeed(), _Bot->runSpeed() ); - - // Move - float const dist = speedToUse * ticksSinceLastUpdate; - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _Bot->pathPos(), - pathCont, - dist, - 0, - .5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - nlwarning("problem with pet following behavior and ground properties like (Water, Nogo)"); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileGotoPoint // -////////////////////////////////////////////////////////////////////////////// - -CAIPetProfileGotoPoint::CAIPetProfileGotoPoint(CSpawnBotPet* bot, CAIPos const& position, TAStarFlag denyFlags, bool despawn) -: CAIBaseProfile() -, _Bot(bot) -, _Pos(position) -, _Despawn(despawn) -, _Valid(false) -, _PathCont(denyFlags) -{ -#ifndef NL_DEBUG - nlassert(bot); -#endif - CTopoPosValidator const posValidator(bot->wpos(), denyFlags); - - CWorldPosition gotoPos; - if (!CWorldContainer::calcNearestWPosFromPosAnRadius(vp_auto, gotoPos, _Pos, 16, 300, posValidator)) - { -#ifdef NL_DEBUG - nldebug("position problem CAIPetProfileGotoPoint"); -#endif - return; - } - _Pos.setXY(gotoPos.toAIVector()); - _PathCont.setDestination((TVerticalPos)position.h(), _Pos); - _Valid = true; -} - -void CAIPetProfileGotoPoint::updateProfile(uint ticksSinceLastUpdate) -{ - H_AUTO(PetGotoPoint); - if (!_Bot->canMove()) - return; - - CAIVector botPos = _Bot->wpos().toAIVector(); - float dist = _Bot->runSpeed() * ticksSinceLastUpdate; - - if ((_PathCont.getDestination()-botPos).quickNorm()>3.f) // follow only if > 6 meters. - { - CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath( - _Bot, - _Bot->pathPos(), - _PathCont, - dist, - 0.f, - .5f); - if (status==CFollowPath::FOLLOW_NO_PATH) - { - nlwarning("PetGotoPoint problem with destination properties (Water, Nogo)"); - } - } - botPos -= _Bot->wpos().toAIVector(); - - if (botPos.quickNorm()<(dist*0.1)) - { - if (_Despawn) - { - _Bot->getPersistent().setDespawn(); - return; - } - _Bot->setAIProfile(new CAIPetProfileStand(_Bot)); - return; - } -} - -TProfiles CAIPetProfileGotoPoint::getAIProfileType() const -{ - if (_Despawn) - return PET_GOTO_AND_DESPAWN; - else - return PET_GOTO; -} - -////////////////////////////////////////////////////////////////////////////// -// CTopoPosValidator // -////////////////////////////////////////////////////////////////////////////// - -CTopoPosValidator::CTopoPosValidator(CWorldPosition const& startPos, TAStarFlag denyFlags) -: _StartPos(startPos) -, _DenyFlags(denyFlags) -{ -} - -bool CTopoPosValidator::check(CWorldPosition const& wpos) const -{ - CCompatibleResult res; - areCompatiblesWithoutStartRestriction(_StartPos, wpos, _DenyFlags, res, true); - return res.isValid(); -} diff --git a/code/ryzom/server/src/ai_service/ai_profile_pet.h b/code/ryzom/server/src/ai_service/ai_profile_pet.h deleted file mode 100644 index 58c5f258f..000000000 --- a/code/ryzom/server/src/ai_service/ai_profile_pet.h +++ /dev/null @@ -1,107 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef RYAI_PROFILE_PET_H -#define RYAI_PROFILE_PET_H - -#include "profile.h" // for CAIBaseProfile -#include "ai_share/ai_types.h" // for TProfiles -#include "ai_pos.h" // for CAIPos -#include "ai_share/world_map.h" // for TAStarFlag -#include "path_behaviors.h" // for CPathCont - -class CSpawnBotPet; -/* -#include "ai_mgr.h" -#include "ai_bot_pet.h" -#include "server_share/pet_interface_msg.h" -*/ - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileStand // -////////////////////////////////////////////////////////////////////////////// - -class CAIPetProfileStand -: public CAIBaseProfile -{ -public: - CAIPetProfileStand(CSpawnBotPet* bot); - - virtual void beginProfile() { } - virtual void updateProfile(uint ticksSinceLastUpdate) { } - virtual void endProfile() { } - - virtual std::string getOneLineInfoString() const { return std::string("stand pet profile"); } - - AITYPES::TProfiles getAIProfileType() const { return AITYPES::PET_STAND; } - -private: - NLMISC::CDbgPtr _Bot; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileFollowPlayer // -////////////////////////////////////////////////////////////////////////////// - -class CAIPetProfileFollowPlayer -: public CAIBaseProfile -{ -public: - CAIPetProfileFollowPlayer(CSpawnBotPet* bot, TDataSetRow const& playerRow); - - virtual void beginProfile() { } - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile() { } - - virtual std::string getOneLineInfoString() const { return std::string("follow_player pet profile"); } - - AITYPES::TProfiles getAIProfileType() const { return AITYPES::PET_FOLLOW; } - -protected: -private: - NLMISC::CDbgPtr _Bot; - TDataSetRow _PlayerRow; -}; - -////////////////////////////////////////////////////////////////////////////// -// CAIPetProfileGotoPoint // -////////////////////////////////////////////////////////////////////////////// - -class CAIPetProfileGotoPoint -: public CAIBaseProfile -{ -public: - CAIPetProfileGotoPoint(CSpawnBotPet* bot, CAIPos const& position, RYAI_MAP_CRUNCH::TAStarFlag denyFlags, bool despawn = false); - - bool isValid() const { return _Valid; } - - virtual void beginProfile() { } - virtual void updateProfile(uint ticksSinceLastUpdate); - virtual void endProfile() { } - - virtual std::string getOneLineInfoString() const { return std::string("goto_point pet profile"); } - - AITYPES::TProfiles getAIProfileType() const; - -private: - NLMISC::CDbgPtr _Bot; - CPathCont _PathCont; - CAIVector _Pos; - bool const _Despawn; - bool _Valid; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_route.h b/code/ryzom/server/src/ai_service/ai_route.h deleted file mode 100644 index 6ad8bc423..000000000 --- a/code/ryzom/server/src/ai_service/ai_route.h +++ /dev/null @@ -1,47 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -//class CAIRoute; - -#ifndef RYAI_ROUTE_H -#define RYAI_ROUTE_H - -//#include "nel/misc/types_nl.h" -#include "ai_share/ai_coord.h" -#include "ai_pos.h" - -/* - This is the virtual base class for abstracting pathfinding algorithms - Routes are generaly spawned by CAIPlace classes (the 'place' is the destination) -*/ - - -class CAIRoute -{ -public: - virtual ~CAIRoute() {} - // get direction vector from current coordinate - virtual double getDirection(CAIPos currentCoord)=0; - - // have we arrived at the destination - // - dist defines the distance that the entity moves/ tick - // returns true if distance from currentCoord to dest <= dist - virtual bool haveArrived(CAIPos currentCoord,uint dist)=0; -}; - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_route_beeline.h b/code/ryzom/server/src/ai_service/ai_route_beeline.h deleted file mode 100644 index 47aba6527..000000000 --- a/code/ryzom/server/src/ai_service/ai_route_beeline.h +++ /dev/null @@ -1,66 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - - - -class CAIRouteBeeline; - -#ifndef RYAI_ROUTE_BEELINE_H -#define RYAI_ROUTE_BEELINE_H - -#include "nel/misc/types_nl.h" -#include "ai_route.h" - -/* - This class implements beeline routes towards points - it is the most - basic form of pathfinding imaginable -*/ - - -class CAIRouteBeeline: public CAIRoute -{ -public: - // ctors and dtors ------------------------------------------------- - CAIRouteBeeline(CAIPos destination) - { - _destination=destination; - } - -public: - // respecting the inheritted interface ----------------------------- - - virtual double getDirection(CAIPos currentCoord); - virtual bool haveArrived(CAIPos currentCoord,uint dist); - -private: - CAIPos _destination; -}; - - -//---------------------------------------------------------------------- -// methods - -double CAIRouteBeeline::getDirection(CAIPos currentCoord) -{ - return currentCoord.directionTo(_destination); -} - -double CAIRouteBeeline::haveArrived(CAIPos currentCoord,uint dist) -{ - return currentCoord.distTo(_destination)<=dist; -} - -#endif diff --git a/code/ryzom/server/src/ai_service/ai_script_comp.cpp b/code/ryzom/server/src/ai_service/ai_script_comp.cpp deleted file mode 100644 index 69c4c9bab..000000000 --- a/code/ryzom/server/src/ai_service/ai_script_comp.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#include "stdpch.h" -#include "ai_generic_fight.h" -#include "ai_script_comp.h" -#include "server_share/msg_brick_service.h" - -using namespace std; -using namespace NLMISC; - -// renvoie le bout de la string jusqu'au prochain ',' en respectant les priorités des parenthèses. -void explodeSubStrings(const std::string &str, vector &strings, sint32 parenthesis=0) -{ - const std::string separators("(),"); - string::size_type current=0; - string::size_type nextCurrent=current; - strings.clear(); - - nextCurrent=str.find_first_of(separators.c_str(), current); - while (nextCurrent!=std::string::npos) - { - switch(str.at(nextCurrent)) - { - case '(': - parenthesis++; - if (parenthesis==0) - { - current=nextCurrent+1; - } - break; - case ')': - if (parenthesis==0) - { - strings.push_back(str.substr(current, nextCurrent-current)); - current=nextCurrent+1; - } - parenthesis--; - break; - case ',': - if (parenthesis==0) - { - strings.push_back(str.substr(current, nextCurrent-current)); - current=nextCurrent+1; - } - break; - default: - break; - } - nextCurrent=str.find_first_of(separators.c_str(), nextCurrent+1); - } - -} - - - -////////////////////////////////////////////////////////////////////////// -// Select Filter - -bool CFightSelectFilter::update (CSpawnBot &bot) const -{ - return _CustomComp->update(bot); -// nlassert("a filter is not designed to be updated"); -} - -std::string CFightSelectFilter::toString() const -{ - return "SELECT("+_Param+","+_CustomComp->toString()+")"; -} - - - -CFightScriptComp *CFightSelectFilterReader::create (const std::string &inStr) -{ - std::vector params; - explodeSubStrings(inStr, params, -1); - - if (params.size()!=2) - throw ReadFightActionException("SELECT Needs 2 Params: ,"); - - CSmartPtr scriptComp; - try - { - scriptComp=createScriptComp(params[1]); - } - catch (const ReadFightActionException &ex) - { - throw ReadFightActionException("cannot create sub ScriptComp : "+std::string(ex.what())); - } - return new CFightSelectFilter(scriptComp, params[0]); -} - - -////////////////////////////////////////////////////////////////////////// -// Once - - -class CFightOnce - :public CFightScriptComp -{ -public: - CFightOnce(CFightScriptComp *customComp) - :_CustomComp(customComp) - { - nlassert(customComp); // the creature is hitting, we cannot do anything .. - } - - virtual ~CFightOnce() - {} - bool update (CSpawnBot &bot) const - { - uint32 dummy; - if (bot.getProp((size_t)this,dummy)) // check if we already go there (for once). - return true; - - if (!_CustomComp->update(bot)) - return false; - - bot.setProp((size_t)this,1); - return true; - } - - string toString() const - { - return "ONCE("+_CustomComp->toString()+")"; - } - -protected: -private: - NLMISC::CSmartPtr _CustomComp; -}; - - -class CFightOnceReader - :public CFightScriptCompReader -{ -public: - CFightOnceReader() {} - virtual ~CFightOnceReader() {} - - CFightScriptComp *create (const std::string &inStr) - { - vector params; - explodeSubStrings(inStr, params, -1); - - if (params.size()!=1) - throw ReadFightActionException("ONCE Needs 1 Param: "); - - CSmartPtr scriptComp; - try - { - scriptComp=createScriptComp(params[0]); - } - catch (const ReadFightActionException &ex) - { - throw ReadFightActionException("cannot create sub ScriptComp : "+string(ex.what())); - } - return new CFightOnce(scriptComp); - } - std::string getName () const - { - return std::string("ONCE"); - } - -}; - - - -////////////////////////////////////////////////////////////////////////// -// Timed Filter - - -class CFightTimedFilter - :public CFightScriptComp -{ -public: - CFightTimedFilter(CFightScriptComp *customComp, uint32 deltaTime) - :_CustomComp(customComp) - ,_DeltaTime(deltaTime) - { - nlassert(customComp); // the creature is hitting, we cannot do anything .. - } - - virtual ~CFightTimedFilter() - {} - bool update (CSpawnBot &bot) const - { - uint32 decTime=0; - if (bot.getProp((size_t)this, decTime)) - if (CTimeInterface::gameCycle()update(bot)) - return false; - - bot.setProp((size_t)this, CTimeInterface::gameCycle()+(uint32)_DeltaTime); - return true; - } - - string toString() const - { - return "EVERY_SEC("+NLMISC::toString(_DeltaTime/10)+","+_CustomComp->toString()+")"; - } - -protected: -private: - NLMISC::CSmartPtr _CustomComp; - uint32 _DeltaTime; -}; - - -class CFightTimedFilterReader - :public CFightScriptCompReader -{ -public: - CFightTimedFilterReader() {} - virtual ~CFightTimedFilterReader() {} - - CFightScriptComp *create (const std::string &inStr) - { - vector params; - explodeSubStrings(inStr, params, -1); - - if (params.size()!=2) - throw ReadFightActionException("EVERY_SEC Needs 2 Params: