Planeshift

npcbehave.h

Go to the documentation of this file.
00001 /*
00002 * npcbehave.h
00003 *
00004 * Copyright (C) 2003 Atomic Blue ([email protected], http://www.atomicblue.org)
00005 *
00006 *
00007 * This program is free software; you can redistribute it and/or
00008 * modify it under the terms of the GNU General Public License
00009 * as published by the Free Software Foundation (version 2 of the License)
00010 * This program is distributed in the hope that it will be useful,
00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 * GNU General Public License for more details.
00014 * You should have received a copy of the GNU General Public License
00015 * along with this program; if not, write to the Free Software
00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 *
00018 */
00019 
00020 /* This file holds definitions for ALL global variables in the planeshift
00021 * server, normally you should move global variables into the psServer class
00022 */
00023 #ifndef __NPCBEHAVE_H__
00024 #define __NPCBEHAVE_H__
00025 //=============================================================================
00026 // Crystal Space Includes
00027 //=============================================================================
00028 #include <csgeom/matrix3.h>
00029 #include <csutil/array.h>
00030 #include <iutil/document.h>
00031 
00032 struct iSector;
00033 
00034 //=============================================================================
00035 // Library Includes
00036 //=============================================================================
00037 #include "util/eventmanager.h"
00038 #include "util/gameevent.h"
00039 #include "util/consoleout.h"
00040 #include "util/pspath.h"
00041 
00042 //=============================================================================
00043 // Local Includes
00044 //=============================================================================
00045 #include "perceptions.h"
00046 #include "walkpoly.h"
00047 #include "npcoperations.h"
00048 
00053 class ScriptOperation;
00054 class Perception;
00055 class Reaction;
00056 class Behavior;
00057 class NPC;
00058 class EventManager;
00059 class BehaviorSet;
00060 class Waypoint;
00061 
00069 class BehaviorSet
00070 {
00071 protected:
00072     csPDelArray<Behavior>  behaviors; 
00073     Behavior*              active;    
00074 
00075 public:
00078     BehaviorSet();
00079 
00090     bool Add(Behavior* behavior);
00091 
00099     Behavior* Find(const char* name);
00100 
00109     void DeepCopy(BehaviorSet &other);
00110 
00119     void ClearState(NPC* npc);
00120 
00129     void UpdateNeeds(float delta, NPC* npc);
00130 
00135     Behavior* Schedule(NPC* npc);
00136 
00145     void Advance(csTicks delta, NPC* npc);
00146 
00154     void Execute(NPC* npc, bool forceRunScript);
00155 
00163     void Interrupt(NPC* npc);
00164 
00167     Behavior* GetCurrentBehavior()
00168     {
00169         return active;
00170     }
00171 
00176     void DumpBehaviorList(csString &output, NPC* npc);
00177 
00182     csString InfoBehaviors(NPC* npc);
00183 
00186     float GetHighestNeed(NPC* npc);
00187 
00188 };
00189 
00190 
00197 class NPCType
00198 {
00199 protected:
00200     NPC*                  npc;       
00201     csString              name;      
00202     csPDelArray<Reaction> reactions; 
00203     BehaviorSet           behaviors; 
00204     float                 ang_vel;   
00205 
00206 
00207     float                 vel;       
00208 
00209 
00210     ScriptOperation::VelSource             velSource; 
00211 
00212     csString              collisionPerception;   
00213     csString              outOfBoundsPerception; 
00214     csString              inBoundsPerception;    
00215     csString              fallingPerception;     
00216 
00217 public:
00218     NPCType();
00219     NPCType(NPCType &other, NPC* npc);
00220 
00221     ~NPCType();
00222     void DeepCopy(NPCType &other);
00223     void ClearState(NPC* npc);
00224 
00225     bool Load(iDocumentNode* node);
00226     bool Load(iResultRow &node);
00227     const char* GetName()
00228     {
00229         return name.GetDataSafe();
00230     }
00231 
00239     Behavior* Find(const char* name)
00240     {
00241         return behaviors.Find(name);
00242     }
00243 
00244     void Advance(csTicks delta, NPC* npc);
00245     void Interrupt(NPC* npc);
00246     void FirePerception(NPC* npc,Perception* pcpt);
00247 
00248     void DumpBehaviorList(csString &output, NPC* npc)
00249     {
00250         behaviors.DumpBehaviorList(output, npc);
00251     }
00252     csString InfoBehaviors(NPC* npc)
00253     {
00254         return behaviors.InfoBehaviors(npc);
00255     }
00256 
00261     csString InfoReactions(NPC* npc);
00262 
00267     void DumpReactionList(csString &output, NPC* npc);
00268 
00269     Behavior* GetCurrentBehavior()
00270     {
00271         return behaviors.GetCurrentBehavior();
00272     }
00273 
00278     float GetHighestNeed(NPC* npc);
00279 
00284     float GetAngularVelocity(NPC* npc);
00285 
00290     float GetVelocity(NPC* npc);
00291 
00294     void SetVelSource(ScriptOperation::VelSource velSource, float vel);
00295 
00298     const csString &GetCollisionPerception() const;
00299 
00304     const csString &GetOutOfBoundsPerception() const;
00305 
00310     const csString &GetInBoundsPerception() const;
00311 
00314     const csString &GetFallingPerception() const;
00315 
00316 
00317 private:
00322     void AddReaction(Reaction* reaction);
00323 
00328     void InsertReaction(Reaction* reaction);
00329 };
00330 
00331 
00340 class Behavior
00341 {
00342 public:
00343     // Used to indicate the result of the RunScript operation of a behavior.
00344     enum BehaviorResult
00345     {
00346         BEHAVIOR_NOT_COMPLETED,       
00347         BEHAVIOR_COMPLETED,           
00348         BEHAVIOR_WILL_COMPLETE_LATER, 
00349         BEHAVIOR_FAILED               
00350     };
00351 protected:
00352     csString name;                      
00353 
00354     csPDelArray<ScriptOperation> sequence; 
00355     size_t   current_step;              
00356     size_t   stepCount;                 
00357     bool     loop;                      
00358     bool     isActive;                  
00359     bool     is_applicable_when_dead;
00360     float    need_decay_rate;           
00361     float    need_growth_rate;          
00362     float    completion_decay;          
00363     float    init_need;                 
00364     bool     resume_after_interrupt;    
00365     csString interruptPerception;       
00366 
00367     float    current_need;              
00368     float    new_need;                  
00369 
00370     bool     interrupted;               
00371 
00372     bool     minLimitValid;             
00373     float    minLimit;                  
00374     bool     maxLimitValid;             
00375     float    maxLimit;                  
00376     csString failurePerception;         
00377 
00378 public:
00379 
00380     Behavior();
00381     Behavior(const char* n);
00382     Behavior(Behavior &other);
00383 
00384     virtual ~Behavior() { };
00385 
00386     const char* GetName()
00387     {
00388         return name;
00389     }
00390 
00391     void DeepCopy(Behavior &other);
00392     bool Load(iDocumentNode* node);
00393 
00394     bool LoadScript(iDocumentNode* node,bool top_level=true);
00395 
00396     void UpdateNeed(float delta, NPC* npc);
00397     BehaviorResult Advance(float delta, NPC* npc);
00398     float CurrentNeed()
00399     {
00400         return current_need;
00401     }
00402     float NewNeed()
00403     {
00404         return new_need;
00405     }
00406 
00416     void  CommitAdvance();
00417 
00428     void ApplyNeedDelta(NPC* npc, float deltaDesire);
00429 
00430 
00442     void ApplyNeedAbsolute(NPC* npc, float absoluteDesire);
00443 
00444     void SetIsActive(bool flag)
00445     {
00446         isActive = flag;
00447     }
00448 
00455     bool IsActive()
00456     {
00457         return isActive;
00458     }
00459 
00460     void SetCurrentStep(int step);
00461     size_t GetCurrentStep()
00462     {
00463         return current_step;
00464     }
00465     size_t GetLastStep()
00466     {
00467         return sequence.GetSize();
00468     }
00469     void ResetNeed()
00470     {
00471         current_need = new_need = init_need;
00472     }
00473 
00474     bool ApplicableToNPCState(NPC* npc);
00475     void DoCompletionDecay(NPC* npc);
00478     void StartScript(NPC* npc);
00481     void OperationCompleted(NPC* npc);
00484     void OperationFailed(NPC* npc);
00485     void SetStartStep();
00486     void InterruptScript(NPC* npc);
00487     bool IsInterrupted()
00488     {
00489         return interrupted;
00490     }
00491     void ClearInterrupted()
00492     {
00493         interrupted = false;
00494     }
00495     Behavior* SetCompletionDecay(float completion_decay)
00496     {
00497         this->completion_decay = completion_decay;
00498         return this;
00499     }
00500 
00501     inline bool operator==(const Behavior &other)
00502     {
00503         return (current_need == other.current_need &&
00504                 name == other.name);
00505     }
00506     bool operator<(Behavior &other)
00507     {
00508         if(current_need > other.current_need)
00509             return true;
00510         if(current_need < other.current_need)
00511             return false;
00512         if(strcmp(name,other.name)>0)
00513             return true;
00514         return false;
00515     }
00516 
00517     // For testing purposes only.
00518 
00519     Behavior* SetDecay(float need_decay_rate)
00520     {
00521         this->need_decay_rate = need_decay_rate;
00522         return this;
00523     }
00524     Behavior* SetGrowth(float need_growth_rate)
00525     {
00526         this->need_growth_rate = need_growth_rate;
00527         return this;
00528     }
00529     Behavior* SetInitial(float init_need)
00530     {
00531         this->init_need = init_need;
00532         return this;
00533     }
00534 
00539     void Failure(NPC* npc, ScriptOperation* op);
00540 };
00541 
00542 class psGameObject
00543 {
00544 public:
00552     static void GetPosition(gemNPCObject* object, csVector3 &pos, float &yrot, iSector* &sector);
00553 
00560     static void GetPosition(gemNPCObject* object, csVector3 &pos, iSector* &sector);
00561 
00562     static void SetPosition(gemNPCObject* objecty, const csVector3 &pos, iSector* = NULL);
00563     static void SetRotationAngle(gemNPCObject* object, float angle);
00564     static void GetRotationAngle(gemNPCObject* object, float &yrot)
00565     {
00566         csVector3 pos;
00567         iSector* sector;
00568         GetPosition(object,pos,yrot,sector);
00569     }
00573     static float CalculateIncidentAngle(const csVector3 &pos, const csVector3 &dest);
00574 
00575     // Clamp the angle within 0 to 2*PI
00576     static void ClampRadians(float &target_angle);
00577 
00578     // Normalize angle within -PI to PI
00579     static void NormalizeRadians(float &target_angle);
00580 
00581     static csVector3 DisplaceTargetPos(const iSector* mySector, const csVector3 &myPos,
00582                                        const iSector* targetSector, const csVector3 &targetPos,
00583                                        float offset);
00584     static csVector3 DisplaceTargetPos(const iSector* mySector, const csVector3 &myPos,
00585                                        const iSector* targetSector, const csVector3 &targetPos,
00586                                        float offset, float angle);
00587 
00588     static float Calc2DDistance(const csVector3 &a, const csVector3 &b);
00589 
00598     static csString ReplaceNPCVariables(NPC* npc, const csString &object);
00599 
00608     static bool ReplaceNPCVariablesBool(NPC* npc, const csString &object);
00609 
00610 };
00611 
00614 #endif
00615