AI_Actor.h

Go to the documentation of this file.
00001 #ifndef AI_ACTOR_H
00002 #define AI_ACTOR_H
00003 
00004 #include "utils/AI_Array.h"
00005 #include "AI_Obstacle.h"
00006 #include "AI_AStar.h"
00007 #include "AI_StateMachine.h"
00008 #include "AI_State.h"
00009 #include "AI_NavigationMesh.h"
00010 
00011 
00114 class AI_Actor : public AI_Obstacle
00115 {
00116 //*** Embedded
00117 public:
00119     enum ACT { 
00120         NONE,   
00121         WAIT,   
00122         WALK,   
00123         WANDER, 
00124         TURN,   
00125         ATTACK, 
00126         DEATH   
00127     };
00128 
00129 
00131     enum FEEDBACK {
00132         ATTACK_FINISHED = (1<<0),   
00133         HIT = (1<<1)                
00134     };
00135 
00137     enum ENEMY_TYPE {
00138         ET_HERO,            
00139         ET_OTHER_CLANS,     
00140         ET_CLAN             
00141     };
00142 
00146     class StateMachineSession : public AI_StateMachine::Session
00147     {
00148     private:
00150         AI_Actor *m_ptr_actor;
00152         AI_Ref<AI_Actor> m_ref_heard_enemy;
00154         float m_f_time_elapsed;
00156         float m_f_time_plan;
00157 
00158     public:
00159         StateMachineSession();
00160 
00161         void setActor(AI_Actor *ptr_actor);
00162         void setHeardEnemy(AI_Actor *ptr_actor);
00163 
00164         AI_Actor *getActor(void);
00165         AI_Actor *getHeardEnemy(void);
00166 
00167         void setTimePlan(const float f_time);
00168         const float getTimePlan(void);
00169         void resetTime(void);
00170         void addTime(const float f_time);
00171         const float getTime(void);
00172     };
00173 
00174 
00178     class StateAct : public AI_State
00179     {
00180     private:
00181         ACT m_act;
00182 
00183     public:
00184         StateAct(ACT i_act, ai_index i_index_out);
00185         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00186         virtual bool isInterrupt( void ) const;
00187     };
00188 
00189 
00193     class StateStop : public AI_State
00194     {
00195     public:
00196         StateStop (ai_index i_index_out);
00197         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00198         virtual bool isInterrupt( void ) const;
00199     };
00200 
00201 
00205     class StateChase : public AI_State
00206     {
00207     public:
00208         StateChase (ai_index i_index_out);
00209         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00210         virtual bool isInterrupt( void ) const;
00211     };
00212 
00213 
00217     class StateAttack : public AI_State
00218     {
00219     public:
00220         StateAttack (ai_index i_index_out);
00221         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00222         virtual bool isInterrupt( void ) const;
00223     };
00224 
00225 
00229     class StateWander : public AI_State
00230     {
00231     public:
00232         StateWander (ai_index i_index_out);
00233         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00234         virtual bool isInterrupt( void ) const;
00235     };
00236 
00237 
00243     class StateIsSee : public AI_State
00244     {
00245     private:
00246         bool m_b_invisible; 
00247 
00248     public:
00249         StateIsSee (ai_index i_index_true, ai_index i_index_false, bool b_invisible = false);
00250         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00251         virtual bool isInterrupt( void ) const;
00252 
00253     private:
00254         const bool isSee(AI_Actor *ptr_actor_this, AI_Actor *ptr_actor_other) const;
00255     };
00256 
00257 
00264     class StateIsHear : public AI_State
00265     {
00266     public:
00267         StateIsHear (ai_index i_index_true, ai_index i_index_false);
00268         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00269         virtual bool isInterrupt( void ) const;
00270 
00271     private:
00272         const bool isHear(AI_Actor *ptr_actor_this, AI_Actor *ptr_actor_other, AI_Actor::StateMachineSession *ptr_session) const;
00273     };
00274 
00275 
00279     class StateIsAccessible : public AI_State
00280     {
00281     private:
00282         float m_f_pane_size;
00283         float m_f_two_pane_size;
00284         float m_f_three_pane_size;
00285         float m_f_four_pane_size;
00286 
00287     public:
00288         StateIsAccessible (ai_index i_index_true, ai_index i_index_false);
00289         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00290         virtual bool isInterrupt( void ) const;
00291     
00292     private:
00293         float convertWidthToPanes(const float f_width);
00294         void setPaneSize(const float f_pane_size);
00295     };
00296 
00297 
00301     class StateIsTouch : public AI_State
00302     {
00303     public:
00304         StateIsTouch (ai_index i_index_true, ai_index i_index_false);
00305         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00306         virtual bool isInterrupt( void ) const;
00307     };
00308 
00309 
00313     class StateIsInOptimum : public AI_State
00314     {
00315     public:
00316         StateIsInOptimum (ai_index i_index_true, ai_index i_index_false);
00317         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00318         virtual bool isInterrupt( void ) const;
00319     };
00320 
00321 
00325     class StateIsFeedback : public AI_State
00326     {
00327     private:
00328         FEEDBACK m_feedback;
00329 
00330     public:
00331         StateIsFeedback (FEEDBACK dw_feedback, ai_index i_index_true, ai_index i_index_false);
00332         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00333         virtual bool isInterrupt( void ) const;
00334     };
00335 
00336 
00340     class StateIsInRange : public AI_State
00341     {
00342     public:
00343         StateIsInRange (ai_index i_index_true, ai_index i_index_false);
00344         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00345         virtual bool isInterrupt( void ) const;
00346     };
00347 
00348 
00352     class StateIsAct : public AI_State
00353     {
00354     public:
00355         typedef enum ACTOR {
00356             ME,
00357             ENEMY,
00358             CHASED
00359         };
00360 
00361     private:
00362         AI_Actor::ACT m_act;
00363         ACTOR m_actor;
00364 
00365     public:
00366         StateIsAct (AI_Actor::ACT act, AI_Actor::StateIsAct::ACTOR actor, ai_index i_index_true, ai_index i_index_false);
00367         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00368         virtual bool isInterrupt( void ) const;
00369     };
00370 
00374     class StateTimePlan : public AI_State
00375     {
00376     public:
00377         float m_f_time_min;
00378         float m_f_time_max;
00379 
00380     public:
00381         StateTimePlan (float f_time, ai_index i_index_true);
00382         StateTimePlan (float f_time_min, float f_time_max, ai_index i_index_true);
00383         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00384         virtual bool isInterrupt( void ) const;
00385     };
00386 
00390     class StateIsTimePlan : public AI_State
00391     {
00392     public:
00393         StateIsTimePlan (ai_index i_index_true, ai_index i_index_false);
00394         virtual ai_index step(AI_StateMachine::Session *ptr_session);
00395         virtual bool isInterrupt( void ) const;
00396     };
00397 
00398 
00400     typedef AI_Array<AI_Actor*> ActorArray;
00402     typedef ActorArray::iterator ActorArrayIt;
00403 
00404 //*** Attributes
00405 private:
00406     //*** General
00408     AI_Ref<AI_Actor> m_ref_actor_chased;
00410     AI_Ref<AI_Actor> m_ref_actor_enemy;
00412     AI_Ref<AI_Actor> m_ref_actor_attacker;
00414     ai_dword m_dw_feedback;
00416     AgentArray m_arr_near_agents;
00418     ObstacleArray m_arr_near_obstacles;
00420     ActorArray m_arr_near_actors;
00422     AgentArray m_arr_near_items;
00424     ActorArray m_arr_near_enemies;
00426     float m_f_near_agents_distance;
00428     ai_dword m_dw_db_version;
00429 
00430     //*** Orientation in space
00432     AI_Vector3 m_v_dest;
00434     AI_Vector3 m_v_dest_prev;
00436     AI_NavigationMesh::Session m_session_navmesh;
00438     AI_Array<AI_Vector3> m_arr_way;
00440     AI_Vector3 m_v_pivot;
00442     AI_Vector2 m_v_feeler_tip;
00444     float m_f_feeler_length;
00446     float m_f_pivot_distance;
00448     int m_i_actual_way_point;
00450     float m_f_fov;
00452     float m_f_turn_direction;
00454     float m_f_wall_evasive_direction;
00456     float m_f_desired_angle;
00458     float m_f_wander_deviation;
00460     double m_d_dest_check_period;
00462     AI_Vector3 m_v_segment_direction;
00464     float m_f_way_length;
00465 
00466     //*** Behaviour
00468     int m_i_act;
00470     int m_i_act_next;
00472     AI_StateMachine *m_ptr_state_machine;
00474     StateMachineSession m_session_state_machine;
00476     AI_Vector3 m_v_walk_direction;
00477 
00478     //*** Characteristic
00480     double m_d_reflex;
00482     float m_f_linear_velocity;
00484     float m_f_angular_velocity;
00486     float m_f_sight;
00488     float m_f_earshot;
00490     float m_f_range;
00492     float m_f_optimal_dist;
00494     float m_f_chase_dist;
00496     int m_i_clan;
00498     int m_i_enemy_clan;
00500     ENEMY_TYPE m_enemy_type;
00501 
00502     //*** Timestamps
00504     double m_d_time_state_machine;
00506     double m_d_time_near_agents;
00508     double m_d_time_dest_check;
00509 
00510     double m_d_time_sleep;
00511     double m_d_time_sleep_plan;
00512 double m_d_time_touch;
00513 
00514     //flags
00515     struct {
00517         bool m_b_ai_enable : 1;
00519         bool m_b_new_near_obstacles : 1;
00521         bool m_b_new_near_actors : 1;
00523         bool m_b_new_near_items : 1;
00525         bool m_b_new_near_enemies : 1;
00527         bool m_b_on_path : 1;
00529         bool m_b_heading_pivot : 1;
00531         bool m_b_replan_path : 1;
00533         bool m_b_attack_finished : 1;
00535         bool m_b_sleep : 1;
00537         bool m_b_visible : 1;
00539         bool m_b_noise : 1;
00541         bool m_b_fixed_feeler_length : 1;
00543         bool m_b_fixed_pivot_distance : 1;
00545         bool m_b_untouchable : 1;
00546     };
00547 
00548 public:
00549     //*** Constructors & destructors
00550     AI_Actor(void);
00551     ~AI_Actor(void);
00552 
00553     //*** General
00554     void trigger( double d_time );
00555     void setLockedChased( AI_Actor *ptr_actor );
00556     AI_Actor *getLockedChased( void );
00557     void setLockedEnemy( AI_Actor *ptr_actor );
00558     void setAttacker( AI_Actor *ptr_attacker );
00559     AI_Actor *getLockedEnemy( void );
00560     AI_Actor *getAttacker( void );
00561     bool updateNearAgents( const float f_distance );
00562     AgentArray &getNearAgents( const float f_distance );
00563     ActorArray &getNearActors( const float f_distance );
00564     ObstacleArray &getNearObstacles( const float f_distance );
00565     ActorArray &getNearEnemies( const float f_distance );
00566     const bool isEnemy( AI_Actor *ptr_actor );
00567     virtual void setEnable( const bool b_enable );
00568 
00569     //*** Orientation in space
00570     const AI_Vector3 &getDestination( void );
00571     AI_NavigationMesh::Session &getNavmeshSession( void );
00572     void clearWay( void );
00573     int getWaySize( void ) const;
00574     AI_Vector3 &getWayPoint( int i ) const;
00575     const bool isTouch( AI_Obstacle *ptr_agent_other, const float f_tolerance ) const;
00576     const bool isCollision( AI_Obstacle *ptr_obstacle, const double d_time ) const;
00577     const AI_Vector3 &getWalkDirection( void ) const;
00578     const AI_Vector3 &getWalkWayPoint( void ) const;
00579     const AI_Vector2 &getFeelerTip( void ) const;
00580     const AI_Vector3 &getPivot( void ) const;
00581     const float getTurnDirection( void ) const;
00582     const float getDesiredAngle( void ) const;
00583     const float getWayLength( void );
00584     bool isOnSurface(void);
00585     bool getNearestSurfacePosition(AI_Vector3 &v_nearest_position);
00586 
00587     //*** Behaviour
00588     void setAIEnable (bool b_ai = true);
00589     bool isAIEnable (void) const;
00590     void setStateMachine( AI_StateMachine *ptr_state_machine );
00591     AI_StateMachine *getStateMachine( void );
00592     AI_StateMachine::Session &getStateMachineSession( void );
00593     void setAct(int i_act);
00594     int getAct(void) const;
00595     const AI_Actor *getAttackTarget( void );
00596     const bool isSleeping(void) const;
00597     void setFeelerLength(bool b_fixed, float f_length = -1);
00598     void setPivotDistance(bool b_fixed, float f_distance = -1);
00599     const float getFeelerLength(void) const;
00600     const float getPivotDistance(void) const;
00601 
00602     //*** Characteristics
00603     void setRefex( const double d_reflex );
00604     void setLinearVelocity( const float f_linear_velocity );
00605     void setAngularVelocity( const float f_angular_velocity );
00606     void setClan( const int i_clan );
00607     void setEnemyClan( const int i_clan );
00608     void setEnemyType( const ENEMY_TYPE type );
00609     void setSight( const float f_sight );
00610     void setEarshot( const float f_earshot );
00611     void setFOV( const float f_fov );
00612     void setRange( const float f_range );
00613     void setOptimalDistance( const float f_dist );
00614     void setChaseDistance( const float f_dist );
00615     virtual void setWidth( const float f_width );
00616     void setVisible( const bool b );
00617     void setNoise( const bool b );
00618     void setUntouchable( const bool b );
00619     const float getAngularVelocity( void ) const;
00620 
00621     const double getReflex( void ) const;
00622     const float getLinearVelocity( void ) const;
00623     const int getClan( void ) const;
00624     const int getEnemyClan( void ) const;
00625     const ENEMY_TYPE getEnemyType( void ) const;
00626     const float getSight( void ) const;
00627     const float getEarshot( void ) const;
00628     const float getFOV( void ) const;
00629     const float getRange( void ) const;
00630     const float getOptimalDistance( void ) const;
00631     const float getChaseDistance( void ) const;
00632     const bool isVisible(void) const;
00633     const bool isNoise(void) const;
00634     const bool isUntouchable(void) const;
00635 
00636     //*** Commands
00637     void walkTo(const AI_Vector3 &v_dest);
00638     void wander( void );
00639     void turnTo(const float f_angle);
00640     void chaseActor(AI_Actor *ptr_actor);
00641     void attack(AI_Actor *ptr_actor);
00642     void stop(void);
00643     void die(void);
00644     void reset(void);
00645 
00646     //*** Feedback
00647     void sendFeedback(FEEDBACK dw_feedback);
00648     bool checkFeedback(ai_dword dw_feedback);
00649     void clearFeedback(ai_dword dw_feedback);
00650     void flushFeedback(void);
00651 
00652 protected:
00653     void updateWait( const double d_time );
00654     void updateWalkDirection( const double d_time );
00655     void updateWandering( const double d_time );
00656     void updateOrientation( const double d_time );
00657     void updateAttack( const double d_time );
00658     bool findWay( void );
00659     void updatePivot( const double d_time );
00660     void updateFeeler( void );
00661     void updateDestination( const double d_time );
00662     AI_Obstacle *findNearestObstacle( const double d_time, float &f_obstacle_distance );
00663     float findNearestWall( float &f_wall_distance );
00664     const bool findInitialWay( void );
00665     void avoidObstacle( AI_Obstacle *ptr_obstacle, const double d_time );
00666     void avoidWall( const float f_dir, const double d_time );
00667     void goBackToPath( const double d_time );
00668     void doJink( const float f_evasive_angle );
00669     bool isDesiredAngle( const double d_time );
00670     void updateSteeringLengths( void );
00671     void makeDesiredAngleFromDirection( AI_Vector3 &v_direction );
00672     void makeTurnDirection( void );
00673     void changeWayPoint( void );
00674     bool isFinishReached(const double d_time, AI_Obstacle *ptr_obstacle, const bool b_obstruct_dest );
00675     void makePositionPrediction( AI_Vector3 &v_position, const double d_time ) const;
00676     void sleep( const double d_time );
00677     const bool detectDeadWayWall( const float f_walk_evasive_direction, const float f_wall_distance );
00678     const bool detectDeadWayObstacle( const double d_time, AI_Obstacle *ptr_obstacle, const float f_obstacle_distance );
00679     const bool detectDeadWayFarFromPath( void );
00680     AI_Obstacle *checkObstacleWhileWalking( AI_Obstacle *ptr_obstacle, const float f_obstacle_distance, bool &b_obstruct_dest );
00681 };
00682 
00683 
00684 inline
00685 AI_Actor::StateAct::StateAct(ACT i_act, ai_index i_index_out)
00686 {
00687     m_act = i_act;
00688     m_i_true_state = i_index_out;
00689 }
00690 
00691 
00692 inline
00693 AI_Actor::StateStop::StateStop (ai_index i_index_out)
00694 {
00695     m_i_true_state = i_index_out;
00696 }
00697 
00698 
00699 inline
00700 AI_Actor::StateChase::StateChase (ai_index i_index_out)
00701 {
00702     m_i_true_state = i_index_out;
00703 }
00704 
00705 
00706 inline
00707 AI_Actor::StateAttack::StateAttack (ai_index i_index_out)
00708 {
00709     m_i_true_state = i_index_out;
00710 }
00711 
00712 
00713 inline
00714 AI_Actor::StateWander::StateWander (ai_index i_index_out)
00715 {
00716     m_i_true_state = i_index_out;
00717 }
00718 
00719 
00720 inline
00721 AI_Actor::StateIsSee::StateIsSee (ai_index i_index_true, ai_index i_index_false, bool b_invisible)
00722 {
00723     m_b_invisible = b_invisible;
00724     m_i_true_state = i_index_true;
00725     m_i_false_state = i_index_false;
00726 }
00727 
00728 
00729 inline
00730 AI_Actor::StateIsHear::StateIsHear (ai_index i_index_true, ai_index i_index_false)
00731 {
00732     m_i_true_state = i_index_true;
00733     m_i_false_state = i_index_false;
00734 }
00735 
00736 
00737 inline
00738 AI_Actor::StateIsAccessible::StateIsAccessible (ai_index i_index_true, ai_index i_index_false)
00739 {
00740     m_i_true_state = i_index_true;
00741     m_i_false_state = i_index_false;
00742 }
00743 
00744 
00745 inline
00746 AI_Actor::StateIsTouch::StateIsTouch (ai_index i_index_true, ai_index i_index_false)
00747 {
00748     m_i_true_state = i_index_true;
00749     m_i_false_state = i_index_false;
00750 }
00751 
00752 
00753 inline
00754 AI_Actor::StateIsInOptimum::StateIsInOptimum (ai_index i_index_true, ai_index i_index_false)
00755 {
00756     m_i_true_state = i_index_true;
00757     m_i_false_state = i_index_false;
00758 }
00759 
00760 
00761 inline
00762 AI_Actor::StateIsFeedback::StateIsFeedback (FEEDBACK dw_feedback, ai_index i_index_true, ai_index i_index_false)
00763 {
00764     m_feedback = dw_feedback;
00765     m_i_true_state = i_index_true;
00766     m_i_false_state = i_index_false;
00767 }
00768 
00769 
00770 inline
00771 AI_Actor::StateIsInRange::StateIsInRange (ai_index i_index_true, ai_index i_index_false)
00772 {
00773     m_i_true_state = i_index_true;
00774     m_i_false_state = i_index_false;
00775 }
00776 
00777 
00778 inline
00779 AI_Actor::StateIsAct::StateIsAct (AI_Actor::ACT act, AI_Actor::StateIsAct::ACTOR actor, ai_index i_index_true, ai_index i_index_false)
00780 {
00781     m_i_true_state = i_index_true;
00782     m_i_false_state = i_index_false;
00783     m_act = act;
00784     m_actor = actor;
00785 }
00786 
00787 
00788 inline
00789 AI_Actor::StateTimePlan::StateTimePlan (float f_time, ai_index i_index_true)
00790 {
00791     m_i_true_state = i_index_true;
00792     m_f_time_min = m_f_time_max = f_time;
00793 }
00794 
00795 
00796 inline
00797 AI_Actor::StateTimePlan::StateTimePlan (float f_time_min, float f_time_max, ai_index i_index_true)
00798 {
00799     m_i_true_state = i_index_true;
00800     m_f_time_min = f_time_min;
00801     m_f_time_max = f_time_max;
00802 }
00803 
00804 
00805 inline
00806 AI_Actor::StateIsTimePlan::StateIsTimePlan (ai_index i_index_true, ai_index i_index_false)
00807 {
00808     m_i_true_state = i_index_true;
00809     m_i_false_state = i_index_false;
00810 }
00811 
00812 
00813 inline
00814 AI_Actor::StateMachineSession::StateMachineSession() :
00815     m_f_time_elapsed(0),
00816     m_f_time_plan(-1.0f)
00817 {
00818 }
00819 
00820 
00821 inline
00822 void AI_Actor::StateMachineSession::setActor(AI_Actor *ptr_actor)
00823 {
00824     m_ptr_actor = ptr_actor;
00825 }
00826 
00827 
00828 inline
00829 AI_Actor *AI_Actor::StateMachineSession::getActor(void)
00830 {
00831     return m_ptr_actor;
00832 }
00833 
00834 
00835 inline
00836 void AI_Actor::StateMachineSession::setHeardEnemy(AI_Actor *ptr_actor)
00837 {
00838     m_ref_heard_enemy = ptr_actor;
00839 }
00840 
00841 
00842 inline
00843 AI_Actor *AI_Actor::StateMachineSession::getHeardEnemy(void)
00844 {
00845     return m_ref_heard_enemy.get_unsafe();
00846 }
00847 
00848 
00849 inline
00850 void AI_Actor::StateMachineSession::setTimePlan(const float f_time)
00851 {
00852     m_f_time_plan = f_time;
00853 }
00854 
00855 
00856 inline
00857 const float AI_Actor::StateMachineSession::getTimePlan(void)
00858 {
00859     return m_f_time_plan;
00860 }
00861 
00862 
00863 inline
00864 void AI_Actor::StateMachineSession::resetTime(void)
00865 {
00866     m_f_time_elapsed = 0;
00867 }
00868 
00869 
00870 inline
00871 void AI_Actor::StateMachineSession::addTime(const float f_time)
00872 {
00873     m_f_time_elapsed += f_time;
00874 }
00875 
00876 
00877 inline
00878 const float AI_Actor::StateMachineSession::getTime(void)
00879 {
00880     return m_f_time_elapsed;
00881 }
00882 
00883 
00884 inline
00885 bool AI_Actor::StateAct::isInterrupt( void ) const
00886 {
00887     return true;
00888 }
00889 
00890 
00891 inline
00892 bool AI_Actor::StateStop::isInterrupt( void ) const
00893 {
00894     return true;
00895 }
00896 
00897 
00898 inline
00899 bool AI_Actor::StateChase::isInterrupt( void ) const
00900 {
00901     return true;
00902 }
00903 
00904 
00905 inline
00906 bool AI_Actor::StateAttack::isInterrupt( void ) const
00907 {
00908     return true;
00909 }
00910 
00911 
00912 inline
00913 bool AI_Actor::StateWander::isInterrupt( void ) const
00914 {
00915     return true;
00916 }
00917 
00918 
00919 inline
00920 bool AI_Actor::StateIsSee::isInterrupt( void ) const
00921 {
00922     return false;
00923 }
00924 
00925 
00926 inline
00927 bool AI_Actor::StateIsHear::isInterrupt( void ) const
00928 {
00929     return false;
00930 }
00931 
00932 
00933 inline
00934 bool AI_Actor::StateIsAccessible::isInterrupt( void ) const
00935 {
00936     return false;
00937 }
00938 
00939 
00940 inline
00941 bool AI_Actor::StateIsTouch::isInterrupt( void ) const
00942 {
00943     return false;
00944 }
00945 
00946 
00947 inline
00948 bool AI_Actor::StateIsInOptimum::isInterrupt( void ) const
00949 {
00950     return false;
00951 }
00952 
00953 
00954 inline
00955 bool AI_Actor::StateIsFeedback::isInterrupt( void ) const
00956 {
00957     return false;
00958 }
00959 
00960 
00961 inline
00962 bool AI_Actor::StateIsInRange::isInterrupt( void ) const
00963 {
00964     return false;
00965 }
00966 
00967 
00968 inline
00969 bool AI_Actor::StateIsAct::isInterrupt( void ) const
00970 {
00971     return false;
00972 }
00973 
00974 
00975 inline
00976 bool AI_Actor::StateTimePlan::isInterrupt( void ) const
00977 {
00978     return false;
00979 }
00980 
00981 
00982 inline
00983 bool AI_Actor::StateIsTimePlan::isInterrupt( void ) const
00984 {
00985     return false;
00986 }
00987 
00988 
00993 inline
00994 const AI_Vector3 &AI_Actor::getDestination( void )
00995 {
00996     return m_v_dest;
00997 }
00998 
00999 
01002 inline
01003 AI_NavigationMesh::Session &AI_Actor::getNavmeshSession( void )
01004 {
01005     return m_session_navmesh;
01006 }
01007 
01008 
01011 inline
01012 AI_Vector3 &AI_Actor::getWayPoint( int i ) const
01013 {
01014     return m_arr_way[i];
01015 }
01016 
01017 
01020 inline
01021 void AI_Actor::clearWay( void )
01022 {
01023     m_arr_way.Reset();
01024 }
01025 
01026 
01029 inline
01030 int AI_Actor::getWaySize( void ) const
01031 {
01032     return m_arr_way.Size();
01033 }
01034 
01035 
01038 inline
01039 const float AI_Actor::getWayLength( void )
01040 {
01041     if ( !m_f_way_length )
01042     {
01043         for (int i=1; i<m_arr_way.Size(); i++)
01044             m_f_way_length += (m_arr_way[i-1]-m_arr_way[i]).len();
01045     }
01046     return m_f_way_length;
01047 }
01048 
01049 
01052 inline
01053 void AI_Actor::setLockedChased( AI_Actor *ptr_actor )
01054 {
01055     m_ref_actor_chased = ptr_actor;
01056 }
01057 
01058 
01061 inline
01062 void AI_Actor::setLockedEnemy( AI_Actor *ptr_actor )
01063 {
01064     m_ref_actor_enemy = ptr_actor;
01065 }
01066 
01067 
01070 inline
01071 void AI_Actor::setAttacker( AI_Actor *ptr_attacker )
01072 {
01073     m_ref_actor_attacker = ptr_attacker;
01074 }
01075 
01076 
01079 inline
01080 AI_Actor *AI_Actor::getLockedChased( void )
01081 {
01082     return m_ref_actor_chased.get_unsafe();
01083 }
01084 
01085 
01088 inline
01089 AI_Actor *AI_Actor::getLockedEnemy( void )
01090 {
01091     if ( m_ref_actor_enemy.isvalid() && !isEnemy( m_ref_actor_enemy.get_unsafe() ) )
01092         m_ref_actor_enemy.invalidate();
01093 
01094     return m_ref_actor_enemy.get_unsafe();
01095 }
01096 
01097 
01100 inline
01101 AI_Actor *AI_Actor::getAttacker( void )
01102 {
01103     return m_ref_actor_attacker.get_unsafe();
01104 }
01105 
01106 
01109 inline
01110 void AI_Actor::setAIEnable (bool b_ai /*= true*/)
01111 {
01112     m_b_ai_enable = b_ai;
01113 }
01114 
01115 
01118 inline
01119 bool AI_Actor::isAIEnable (void) const
01120 {
01121     return ( m_b_ai_enable && m_ptr_state_machine );
01122 }
01123 
01124 
01127 inline
01128 void AI_Actor::setStateMachine( AI_StateMachine *ptr_state_machine )
01129 {
01130     m_ptr_state_machine = ptr_state_machine;
01131 }
01132 
01133 
01136 inline
01137 AI_StateMachine *AI_Actor::getStateMachine( void )
01138 {
01139     return m_ptr_state_machine;
01140 }
01141 
01142 
01145 inline
01146 AI_StateMachine::Session &AI_Actor::getStateMachineSession( void )
01147 {
01148     return m_session_state_machine;
01149 }
01150 
01151 
01154 inline
01155 void AI_Actor::setAct(int i_act)
01156 {
01157     m_i_act = i_act;
01158 }
01159 
01160 
01163 inline
01164 int AI_Actor::getAct(void) const
01165 {
01166     return m_i_act;
01167 }
01168 
01169 
01172 inline
01173 const AI_Vector3 &AI_Actor::getWalkDirection( void ) const
01174 {
01175     return m_v_walk_direction;
01176 }
01177 
01178 
01183 inline
01184 const AI_Vector3 &AI_Actor::getWalkWayPoint( void ) const
01185 {
01186     return getWayPoint(m_i_actual_way_point); 
01187 }
01188 
01189 
01192 inline
01193 void AI_Actor::setRefex( const double d_reflex )
01194 {
01195     m_d_reflex = d_reflex;
01196     m_d_time_state_machine = m_d_reflex;
01197 }
01198 
01199 
01202 inline
01203 const double AI_Actor::getReflex( void ) const
01204 {
01205     return m_d_reflex;
01206 }
01207 
01208 
01211 inline
01212 void AI_Actor::setLinearVelocity( const float f_linear_velocity )
01213 {
01214     m_f_linear_velocity = f_linear_velocity;
01215     updateSteeringLengths();
01216 }
01217 
01218 
01221 inline
01222 void AI_Actor::setAngularVelocity( const float f_angular_velocity )
01223 {
01224     m_f_angular_velocity = f_angular_velocity;
01225 }
01226 
01227 
01230 inline
01231 const float AI_Actor::getAngularVelocity( void ) const
01232 {
01233     return m_f_angular_velocity;
01234 }
01235 
01236 
01239 inline
01240 const float AI_Actor::getLinearVelocity( void ) const
01241 {
01242     return m_f_linear_velocity;
01243 }
01244 
01245 
01251 inline
01252 void AI_Actor::walkTo(const AI_Vector3 &v_dest)
01253 {
01254     //if ( !(getAct()==WALK || m_b_sleep || (getAct()==TURN && m_i_act_next==WALK) ) )
01255     if ( !(getAct()==WALK || (m_b_sleep && m_i_act_next==WALK) || (getAct()==TURN && m_i_act_next==WALK) ) )
01256     {
01257         stop();
01258 
01259         setAct( TURN );
01260         m_i_act_next = WALK;
01261 
01262         m_v_dest = m_v_dest_prev = v_dest;
01263         m_b_replan_path = true;
01264     }
01265     else if ( getLockedChased() )
01266     {
01267         m_v_dest = m_v_dest_prev = v_dest;
01268         m_b_replan_path = true;
01269     }
01270 
01271     m_v_dest = v_dest;
01272     setLockedChased( NULL );
01273 }
01274 
01275 
01281 inline
01282 void AI_Actor::turnTo(const float f_angle)
01283 {
01284     if ( !(getAct()==TURN && m_i_act_next==NONE) )
01285     {
01286         stop();
01287         setAct(TURN);
01288         m_f_desired_angle = f_angle;
01289     }
01290 }
01291 
01292 
01295 inline
01296 void AI_Actor::setSight( const float f_sight )
01297 {
01298     m_f_sight = f_sight;
01299 }
01300 
01301 
01304 inline
01305 const float AI_Actor::getSight( void ) const
01306 {
01307     return m_f_sight;
01308 }
01309 
01310 
01313 inline
01314 void AI_Actor::setEarshot( const float f_earshot )
01315 {
01316     m_f_earshot = f_earshot;
01317 }
01318 
01319 
01322 inline
01323 const float AI_Actor::getEarshot( void ) const
01324 {
01325     return m_f_earshot;
01326 }
01327 
01328 
01331 inline
01332 void AI_Actor::sendFeedback(FEEDBACK dw_feedback)
01333 {
01334     m_dw_feedback |= dw_feedback;
01335 
01336     if ( dw_feedback & ATTACK_FINISHED )
01337     {
01338         m_b_attack_finished = true;
01339     }
01340 }
01341 
01342 
01345 inline
01346 bool AI_Actor::checkFeedback(ai_dword dw_feedback)
01347 {
01348     return ((m_dw_feedback & dw_feedback)==dw_feedback) ? true : false;
01349 }
01350 
01351 
01354 inline
01355 void AI_Actor::clearFeedback(ai_dword dw_feedback)
01356 {
01357     m_dw_feedback &= ~dw_feedback;
01358 }
01359 
01360 
01363 inline
01364 void AI_Actor::flushFeedback(void)
01365 {
01366     m_dw_feedback = 0;
01367 }
01368 
01369 
01372 inline
01373 void AI_Actor::setFOV( const float f_fov )
01374 {
01375     m_f_fov = f_fov;
01376 }
01377 
01378 
01381 inline
01382 const float AI_Actor::getFOV( void ) const
01383 {
01384     return m_f_fov;
01385 }
01386 
01387 
01390 inline
01391 void AI_Actor::setRange( const float f_range )
01392 {
01393     m_f_range = f_range;
01394 }
01395 
01396 
01399 inline
01400 const float AI_Actor::getRange( void ) const
01401 {
01402     return m_f_range;
01403 }
01404 
01405 
01408 inline
01409 void AI_Actor::setOptimalDistance( const float f_dist )
01410 {
01411     m_f_optimal_dist = f_dist;
01412 }
01413 
01414 
01417 inline
01418 void AI_Actor::setChaseDistance( const float f_dist )
01419 {
01420     m_f_chase_dist = f_dist;
01421 }
01422 
01423 
01426 inline
01427 const float AI_Actor::getOptimalDistance( void ) const
01428 {
01429     return m_f_optimal_dist;
01430 }
01431 
01432 
01435 inline
01436 const float AI_Actor::getChaseDistance( void ) const
01437 {
01438     return m_f_chase_dist;
01439 }
01440 
01441 
01446 inline
01447 void AI_Actor::die(void)
01448 {
01449     stop();
01450     setAct( DEATH );
01451 }
01452 
01453 
01458 inline
01459 void AI_Actor::makePositionPrediction( AI_Vector3 &v_position, const double d_time ) const
01460 {
01461     if ( d_time && getAct()==WALK )
01462     {
01463         AI_Vector3 v_dir( m_v_walk_direction );
01464         v_dir.norm();
01465 
01466         v_position = getPosition() + v_dir * (float)d_time * m_f_linear_velocity;
01467     }
01468     else
01469     {
01470         v_position = getPosition();
01471     }
01472 }
01473 
01474 
01477 inline
01478 const bool AI_Actor::isTouch( AI_Obstacle *ptr_obstacle, const float f_tolerance ) const
01479 {
01480     AI_Vector3 v_dist = ptr_obstacle->getPosition() - getPosition();
01481     v_dist.y = 0;
01482     float f_dist = v_dist.len();
01483 
01484     float f_touch = getWidth() + ptr_obstacle->getWidth() + f_tolerance;
01485 
01486     return ( f_dist <= f_touch );
01487 }
01488 
01489 
01494 inline
01495 const bool AI_Actor::isCollision( AI_Obstacle *ptr_obstacle, const double d_time ) const
01496 {
01497     //*** Predict actor's position
01498     AI_Vector3 v_position;
01499     makePositionPrediction( v_position, d_time );
01500 
01501     //*** Predict obstacle position
01502     AI_Vector3 v_other_position;
01503     if ( ptr_obstacle->getType()==ACTOR )
01504     {
01505         ((AI_Actor*)ptr_obstacle)->makePositionPrediction( v_other_position, d_time );
01506     }
01507     else
01508     {
01509         v_other_position = ptr_obstacle->getPosition();
01510     }
01511 
01512     //*** Test if obstacles in predicted positions will touch
01513     return ai_isInRange( v_position, v_other_position, getWidth() + ptr_obstacle->getWidth() );
01514 
01515     //AI_Vector3 v_dist = v_other_position - v_position;
01516     //v_dist.y = 0;
01517     //float f_dist = v_dist.len();
01518 
01519     //float f_touch = getWidth() + ptr_obstacle->getWidth();
01520 
01521     //return ( f_dist <= f_touch );
01522 }
01523 
01524 
01527 inline
01528 const AI_Vector2 &AI_Actor::getFeelerTip( void ) const
01529 {
01530     return m_v_feeler_tip;
01531 }
01532 
01533 
01536 inline
01537 const AI_Vector3 &AI_Actor::getPivot( void ) const
01538 {
01539     return m_v_pivot;
01540 }
01541 
01542 
01548 inline
01549 void AI_Actor::avoidWall( const float f_dir, const double d_time )
01550 {
01551     doJink( m_f_angular_velocity * (float)d_time * f_dir );
01552 
01553     m_b_on_path = false;
01554     m_b_heading_pivot = false;
01555 }
01556 
01557 
01560 inline
01561 void AI_Actor::doJink( const float f_evasive_angle )
01562 {
01563     AI_Quaternion q;
01564     q.set_rotate_y( f_evasive_angle );
01565 
01566     m_v_walk_direction = q.rotate( m_v_walk_direction );
01567 }
01568 
01569 
01572 inline
01573 void AI_Actor::updateSteeringLengths( void )
01574 {
01575     if (!m_b_fixed_feeler_length)
01576         m_f_feeler_length = AI_PIVOT_MAX_LEADING * m_f_linear_velocity + m_f_width;
01577     
01578     if (!m_b_fixed_pivot_distance)
01579         m_f_pivot_distance = AI_PIVOT_MAX_DISTANCE * m_f_linear_velocity + m_f_width;
01580 }
01581 
01582 
01585 inline
01586 void AI_Actor::makeDesiredAngleFromDirection( AI_Vector3 &v_direction )
01587 {
01588     v_direction.y = 0;
01589     v_direction.norm();
01590 
01591     m_f_desired_angle = ai_acos( v_direction.x );
01592     if ( v_direction.z > 0.0f )
01593         m_f_desired_angle = AI_2PI - m_f_desired_angle; //flip angle
01594 }
01595 
01596 
01599 inline
01600 void AI_Actor::makeTurnDirection( void )
01601 {
01602     if (m_f_desired_angle > m_v_orientation.y)
01603     {
01604         if ( (m_f_desired_angle - m_v_orientation.y) < AI_PI )
01605             m_f_turn_direction = 1.0f;
01606         else
01607             m_f_turn_direction = -1.0f;
01608     }
01609     else
01610     {
01611         if ( (m_v_orientation.y - m_f_desired_angle) < AI_PI )
01612             m_f_turn_direction = -1.0f;
01613         else
01614             m_f_turn_direction = 1.0f;
01615     }
01616 }
01617 
01618 
01626 inline
01627 const float AI_Actor::getTurnDirection( void ) const
01628 {
01629     return m_f_turn_direction;
01630 }
01631 
01632 
01635 inline
01636 void AI_Actor::changeWayPoint( void )
01637 {
01638     m_i_actual_way_point++;
01639                         
01640     m_v_segment_direction = getWayPoint(m_i_actual_way_point) - getWayPoint(m_i_actual_way_point-1);
01641     m_v_segment_direction.norm();
01642 }
01643 
01644 
01649 inline
01650 bool AI_Actor::isDesiredAngle( const double d_time )
01651 {
01652     return ( abs(m_f_desired_angle - m_v_orientation.y) <= m_f_angular_velocity * (float)d_time );
01653 }
01654 
01655 
01658 inline
01659 void AI_Actor::stop( void )
01660 {
01661     setAct(WAIT);
01662     m_i_act_next = NONE;
01663 
01664     m_f_turn_direction = 0;
01665     m_b_sleep = false;
01666     m_b_attack_finished = false;
01667     m_b_replan_path = false;
01668 }
01669 
01670 
01675 inline
01676 void AI_Actor::sleep( const double d_time )
01677 {
01678     stop();
01679     
01680     m_b_sleep = true;
01681     m_d_time_sleep_plan = d_time;
01682     m_d_time_sleep = 0;
01683 }
01684 
01685 
01691 inline
01692 void AI_Actor::reset( void )
01693 {
01694     stop();
01695     m_session_state_machine.reset();
01696     m_d_time_state_machine = m_d_reflex;
01697 }
01698 
01699 
01702 inline
01703 void AI_Actor::setClan( const int i_clan )
01704 {
01705     if ( getEnemyType()==ET_OTHER_CLANS )
01706     {   m_ref_actor_enemy.invalidate();
01707         m_b_new_near_enemies = true;
01708     }
01709 
01710     m_i_clan = i_clan;
01711 }
01712 
01713 
01718 inline
01719 void AI_Actor::setEnemyClan( const int i_clan )
01720 {
01721     if ( getEnemyType()==ET_CLAN && m_i_enemy_clan!=i_clan )
01722     {   m_ref_actor_enemy.invalidate();
01723         m_b_new_near_enemies = true;
01724     }
01725 
01726     m_i_enemy_clan = i_clan;
01727 }
01728 
01729 
01732 inline
01733 const int AI_Actor::getClan( void ) const
01734 {
01735     return m_i_clan;
01736 }
01737 
01738 
01741 inline
01742 const int AI_Actor::getEnemyClan( void ) const
01743 {
01744     return m_i_enemy_clan;
01745 }
01746 
01747 
01750 inline
01751 void AI_Actor::setVisible( const bool b )
01752 {
01753     m_b_visible = b;
01754 }
01755 
01756 
01759 inline
01760 void AI_Actor::setNoise( const bool b )
01761 {
01762     m_b_noise = b;
01763 }
01764 
01765 
01768 inline
01769 const bool AI_Actor::isVisible(void) const
01770 {
01771     return m_b_visible;
01772 }
01773 
01774 
01777 inline
01778 const bool AI_Actor::isNoise(void) const
01779 {
01780     return m_b_noise;
01781 }
01782 
01783 
01786 inline
01787 void AI_Actor::setEnemyType( const AI_Actor::ENEMY_TYPE type )
01788 {
01789     if ( m_enemy_type!=type && type!=ET_HERO )
01790         m_b_new_near_enemies = true;
01791 
01792     m_enemy_type = type;
01793 
01794 
01795 }
01796 
01797 
01800 inline
01801 const AI_Actor::ENEMY_TYPE AI_Actor::getEnemyType( void ) const
01802 {
01803     return m_enemy_type;
01804 }
01805 
01806 
01816 inline
01817 AI_Agent::AgentArray &AI_Actor::getNearAgents( const float f_distance )
01818 {
01819     updateNearAgents( f_distance );
01820     return m_arr_near_agents;
01821 }
01822 
01823 
01826 inline
01827 const bool AI_Actor::isSleeping(void) const
01828 {
01829     return m_b_sleep;
01830 }
01831 
01832 
01835 inline
01836 const float AI_Actor::getDesiredAngle( void ) const
01837 {
01838     return m_f_desired_angle;
01839 }
01840 
01841 
01846 inline
01847 void AI_Actor::setFeelerLength(bool b_fixed, float f_length)
01848 {
01849     m_b_fixed_feeler_length = b_fixed;
01850     if (f_length>=0)
01851         m_f_feeler_length = f_length;
01852 }
01853 
01854 
01859 inline
01860 void AI_Actor::setPivotDistance(bool b_fixed, float f_distance)
01861 {
01862     m_b_fixed_pivot_distance = b_fixed;
01863     if (f_distance>=0)
01864         m_f_pivot_distance = f_distance;
01865 }
01866 
01867 
01870 inline
01871 const float AI_Actor::getFeelerLength(void) const
01872 {
01873     return m_f_feeler_length;
01874 }
01875 
01876 
01879 inline
01880 const float AI_Actor::getPivotDistance(void) const
01881 {
01882     return m_f_pivot_distance;
01883 }
01884 
01885 
01888 inline
01889 void AI_Actor::setUntouchable( const bool b )
01890 {
01891     m_b_untouchable = b;
01892 }
01893 
01894 
01897 inline
01898 const bool AI_Actor::isUntouchable(void) const
01899 {
01900     return m_b_untouchable;
01901 }
01902 
01903 
01904 #endif