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
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
00405 private:
00406
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
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
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
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
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
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
00550 AI_Actor(void);
00551 ~AI_Actor(void);
00552
00553
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
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
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
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
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
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 )
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
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
01498 AI_Vector3 v_position;
01499 makePositionPrediction( v_position, d_time );
01500
01501
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
01513 return ai_isInRange( v_position, v_other_position, getWidth() + ptr_obstacle->getWidth() );
01514
01515
01516
01517
01518
01519
01520
01521
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;
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