/* * npcclient.h * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __NPCCLIENT_H__ #define __NPCCLIENT_H__ #include #include #include #include #include #include "net/pstypes.h" #include "engine/celbase.h" #include "util/prb.h" #include "util/growarray.h" #include "util/psconst.h" #include "util/serverconsole.h" struct iObjectRegistry; struct iDocumentNode; struct iConfigManager; struct iCollideSystem; class psDatabase; class MsgHandler; class psNetConnection; class EventManager; class NetworkManager; class NPCType; class NPC; class gemNPCActor; class gemNPCObject; struct iCelEntity; struct iVFS; class Perception; class PathManager; class psWorld; class Location; class LocationType; class Waypoint; class psPFMaps; class psTribe; /** * The main NPC Client class holding references to important superclient objects */ class psNPCClient : public CelBase, public iCommandCatcher { public: psNPCClient(); /** * Cleans up all allocated memory and removes all the players from the world. */ ~psNPCClient(); /** * Initialize the superclient. * Starts a thread for the Network, Message Handler. Also * binds the status socket for the network. */ bool Initialize(iObjectRegistry* object_reg,const char *host, const char *user, const char *pass, int port); /** * Just make iObjectRegistry available to other classes. */ iObjectRegistry *GetObjectReg() { return objreg; } /** Returns a random number. * * @return Returns a random number between 0.0 and 1.0. */ float GetRandom() { return randomGen.Get(); } /** Returns a random number with a limit. * * @return Returns a random number between 0 and limit. */ uint32 GetRandom(uint32 limit) { return randomGen.Get(limit); } /** * Load and starts an optional script file that sets * up the server. After that it jumps into the * server console's main loop, accepting commands from the user. */ int MainLoop (); virtual void CatchCommand(const char *cmd); /** * If a world is ready and loaded this returns true. */ bool IsReady(); /** * This does 1 AI calc per NPC, 1 AI calc per Tribe then returns. */ void Tick(); /** * Load a map into a region. This is a copy of code * from entitymanager->CreateRoom(). */ bool LoadMap(const char *mapfile); iCelEntity* FindActor( const char* name ); /** * This function handles the searching for the specified region name * so that other functions can refer to the region directly. */ LocationType *FindRegion(const char *regname); /** * This function handles the searching for the specified location type * so that other functions can refer to the location type directly. */ LocationType *FindLocation(const char *locname); /** * This function handles the searching for the specified object * type and basically does the work for the script command. */ Location *FindLocation(const char *loctype, const char *name); /** * This function handles the searching for the specified object * type and basically does the work for the script command. */ Location *FindNearestLocation(const char *loctype, csVector3& pos, iSector* sector, float range = -1, float *found_range = NULL); /** * This function handles the searching for the specified object * type and basically does the work for the script command. */ Location *FindRandomLocation(const char *loctype, csVector3& pos, iSector* sector, float range = -1, float *found_range = NULL); /** * This iterates over all waypoints and finds the nearest one. * There is probably a more efficient structure to accomplish this. */ Waypoint *FindNearestWaypoint(csVector3& v, iSector* sector, float range = -1, float * found_range = NULL); /** * This iterates over all waypoints and finds the nearest one. * There is probably a more efficient structure to accomplish this. */ Waypoint *FindRandomWaypoint(csVector3& v, iSector* sector, float range = -1, float * found_range = NULL); /** * This iterates over all waypoints and finds the one with the given id. * There is probably a more efficient structure to accomplish this. */ Waypoint *FindWaypoint(int id); /** * This iterates over all waypoints and finds the one with the given name. * There is probably a more efficient structure to accomplish this. */ Waypoint *FindWaypoint(const char * name); /** * Find the shortest path between waypoint start and stop. */ csList FindWaypointPath(Waypoint * start, Waypoint * end); /** * This function handles the searching for the specified NPCType name * so that other NPCTypes can subclass an existing one. */ NPCType *FindNPCType(const char *npctype_name); /** * Returns the network handler so script ops can invoke the network. */ NetworkManager *GetNetworkMgr() { return network; } /** * Returns the network handler so script ops can invoke the network. */ psNetConnection *GetNetConnection() { return connection; } /** * Sends a perception to a specified NPC, or broadcasts to all npcs, or to all within a range of a position. * * @param npc The npc to percept or NULL it all NPCs is to be percepted. If NPC is null max_range can be set to null to broadast to all or both * base_pos and base_sector has to be set to broadcast only to items within the given range. */ void TriggerEvent(NPC *npc,Perception *pcpt,float max_range=0,csVector3 *base_pos=NULL, iSector *base_sector=NULL); EventManager *GetEventMgr() { return eventmanager; } /** * Disconnect from server nicely, before quitting. */ void Disconnect(); /** * SetEntityPos finds the given ID entity, and updates * its position in mesh and linmove. */ void SetEntityPos(PS_ID id, csVector3& pos, iSector* sector); /** * Find the NPC* attached to the entity with the specified ID */ NPC *FindNPC(PS_ID entid); NPC *FindNPC(const char *name); /** * Get the spline path list. */ PathManager *GetPathManager() { return pathmgr; } /** * List all NPCs matching pattern to console. */ void ListAllNPCs(char *pattern); /** * Find one npc and print its current state info. */ bool DumpNPC(char *pattern); /** * List all known entities on superclient. */ void ListAllEntities(char *pattern, bool onlyCharacters = false); /** * List all tribes matching pattern to console. */ void ListTribes(char *pattern); /** * List all waypoints matching pattern to console. */ void ListWaypoints(char *pattern); /** * List all locations matching pattern to console. */ void ListLocations(char *pattern); /** * Special handling for death notifications from the server * is required, to stop behavior scripting, delete hate lists, * etc. */ void HandleDeath(NPC *who); /** * This is called when a human player dies, enabling NPCs * to find out and react accordingly. */ void HandlePlayerDeath(PS_ID who); /** * This function removes any associations if the entity to * be removed is an NPC managed by this superclient, then * calls the normal CelBase RemoveItem function. */ //bool RemoveItem(iCelEntity *item); void Add( gemNPCObject* object ); void Remove ( unsigned id ); void RemoveAll(); gemNPCObject *FindCharacterID(int char_id); gemNPCObject *FindEntityID(unsigned entityID); /** * Loop through every tribe and check if this npc is a member. */ void CheckAttachTribes( NPC* npc); void AttachNPC( gemNPCActor* actor, uint8_t DRcounter ); iCelEntity* FindEntity( uint32_t id ); iCollideSystem *GetCollDetSys() { return cdsys; } NPC* FindAttachedNPC(iCelEntity *entity); NPC *ReadSingleNPC(int char_id); NPC *FindNPC(int character_id); psPFMaps * GetMaps() { return PFMaps; } psWorld * GetWorld() { return world; } iEngine * GetEngine() { return engine; } protected: bool ReadNPCsFromDatabase(); bool LoadNPCTypes(const char *xmlfile); bool LoadNPCDefinitions(const char *xmlfile); public: bool ImportNPCDefinitions(const char *xmlfile); protected: bool ImportLocations(iDocumentNode *topNode); bool ImportWaypoints(iDocumentNode *topNode); bool LoadLocations(); bool LoadWaypoints(); /** Load Tribes from db */ bool LoadTribes(); // Fns to get NPC* from iCelEntity* void AttachNPC(iCelEntity *entity, NPC *npc); void UnattachNPC(iCelEntity *entity, NPC *npc); /** * Find all items that are close to NPC's and percept the * NPC. */ void PerceptProximityItems(); psNetConnection *connection; iObjectRegistry* objreg; csRef engine; csRef configmanager; csRef msghandler; EventManager *eventmanager; NetworkManager *network; PathManager *pathmgr; psDatabase *database; csRef vfs; BinaryRBTree npctypes; BinaryRBTree loctypes; BinaryRBTree waypoints; csArray npcs; csArray npcsDeferred; csArray tribes; csHash npc_entities; csArray objects; csRef cdsys; psWorld *world; psPFMaps *PFMaps; /// Counter used to start events at every nth client tick unsigned int tick_counter; csRandomGen randomGen; }; #endif