/*
**	Command & Conquer Renegade(tm)
**	Copyright 2025 Electronic Arts Inc.
**
**	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, either version 3 of the License, or
**	(at your option) any later version.
**
**	This program is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**	GNU General Public License for more details.
**
**	You should have received a copy of the GNU General Public License
**	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*********************************************************************************************** 
 ***                            Confidential - Westwood Studios                              *** 
 *********************************************************************************************** 
 *                                                                                             * 
 *                 Project Name : Commando                                                     * 
 *                                                                                             * 
 *                     $Archive:: /Commando/Code/Combat/soldierobserver.h                     $* 
 *                                                                                             * 
 *                      $Author:: Byon_g                                                      $* 
 *                                                                                             * 
 *                     $Modtime:: 11/29/01 11:03a                                             $* 
 *                                                                                             * 
 *                    $Revision:: 44                                                          $* 
 *                                                                                             * 
 *---------------------------------------------------------------------------------------------* 
 * Functions:                                                                                  * 
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#ifndef	SOLDIEROBSERVER_H
#define	SOLDIEROBSERVER_H

#include "always.h"
#include "persistentgameobjobserver.h"
#include "vector3.h"
#include "gameobjref.h"
#include "cover.h"
#include "wwstring.h"
#include "actionparams.h"

class		SoldierGameObj;
class		PhysicalGameObj;

class	SoldierObserverClass : public PersistentGameObjObserverClass
{
public:
	SoldierObserverClass(void);
	virtual	~SoldierObserverClass(void);

	virtual const char * Get_Name( void )						{ return "Innate Soldier"; }

	// PersistClass interface
	virtual const PersistFactoryClass& Get_Factory(void) const;
	virtual bool Save(ChunkSaveClass &csave);
	virtual bool Load(ChunkLoadClass &cload);

	// GameObjObserverClass interface
	virtual void Attach(GameObject* obj);
	virtual void Detach(GameObject* obj);

	virtual	void	Created( GameObject * obj );
	virtual	void	Destroyed( GameObject * obj );
	virtual	void	Killed( GameObject * obj, GameObject * killer );
	virtual	void	Damaged( GameObject * obj, GameObject * damager, float amount );
	virtual	void	Custom( GameObject * obj, int type, int param, GameObject * sender );
	virtual	void	Sound_Heard( GameObject * obj, const CombatSound & sound );
	virtual	void	Enemy_Seen( GameObject * obj, GameObject * enemy );
	virtual	void	Action_Complete( GameObject * obj, int action_id, ActionCompleteReason complete_reason );
	virtual	void	Timer_Expired( GameObject * obj, int timer_id );
	virtual	void	Animation_Complete( GameObject * obj, const char * animation_name ) {}
	virtual	void	Poked( GameObject * obj, GameObject * poker );
	virtual	void	Entered( GameObject * obj, GameObject * enterer ) {}		
	virtual	void	Exited( GameObject * obj, GameObject * exiter ) {}		

	// State access
	void		Reset_Conversation_Timer( void );

	void		Set_Home_Location( const Vector3& location, float radius )	{ HomeLocation = location; HomeRadius = radius; }

	void		Set_Aggressiveness( float aggressiveness )		{	Aggressiveness = aggressiveness; }
	void		Set_Take_Cover_Probability( float probability )	{	TakeCoverProbability = probability; }
	void		Set_Is_Stationary( bool stationary )				{	IsStationary = stationary; }

	void		Get_Information( StringClass & string );

	typedef enum {
		SOLDIER_AI_RELAXED_IDLE = 0,	
		SOLDIER_AI_ALERT_IDLE,	
		SOLDIER_AI_FOOTSTEPS_HEARD,
		SOLDIER_AI_BULLET_HEARD,
		SOLDIER_AI_GUNSHOT_HEARD,
		SOLDIER_AI_ENEMY_SEEN,
		NUM_SOLDIER_AI_STATES,
		SOLDIER_AI_CONDITIONAL_IDLE = 100,	
	} SoldierAIStates;

	bool Set_State( SoldierGameObj * soldier, int state, const Vector3& location = Vector3(0,0,0), GameObject* enemy = NULL);

private:
	int		State;					// Current State
	float		StateTimer;				// Time spent in this state

	Vector3	HomeLocation;			// Location to stay centered around
	float		HomeRadius;				// Radius to stay within

	Vector3	AlertPosition;
	float		ActionTimer;	// Used to make us change actions periodically
	GameObjReference EnemyObject;
	bool		CoveredAttack;
	CoverEntryClass * CoverPosition;
	float		ConversationTimer;
	bool		IsAlerted;

	float		Aggressiveness;
	float		TakeCoverProbability;
	bool		IsStationary;

	StringClass	SubStateString;

	int		LastEvent;
	int		LastWeaponIndex;

	/*
	** Innate AI States
	*/
	void State_Changed( SoldierGameObj * soldier );
	void Notify_Neighbors_Sound( SoldierGameObj * soldier, const CombatSound & sound );
	void Notify_Neighbors_Enemy( SoldierGameObj * soldier, GameObject * enemy );

	/*
	** Innate AI State Actions
	*/
	void Think( SoldierGameObj * soldier, bool is_new_state = false );
	void State_Act( SoldierGameObj* soldier, bool is_new_state = false );
	void State_Act_Idle( SoldierGameObj * soldier );
	void State_Act_Footsteps_Heard( SoldierGameObj * soldier );
	void State_Act_Bullet_Heard( SoldierGameObj * soldier, bool is_new_state );
	void State_Act_Gunshot_Heard( SoldierGameObj * soldier );
	void State_Act_Attack( SoldierGameObj * soldier );

	/*
	** Innate AI Actions
	*/
	void Action_Reset( SoldierGameObj * soldier );
	void Action_Face_Location( SoldierGameObj * soldier, const Vector3 & location, SoldierAIState ai_state, bool crouched = false );
	void Action_Goto_Location( SoldierGameObj * soldier, const Vector3 & location, SoldierAIState ai_state, float speed = 1.0f, float distance = 1.0f, bool crouched = false );
	void Action_Goto_Location_Facing( SoldierGameObj * soldier, const Vector3 & location, SoldierAIState ai_state, const Vector3 & facing_pos, float speed = 1.0f, float distance = 1.0f, bool crouched = false );
	void Action_Attack_Object( SoldierGameObj * soldier, PhysicalGameObj * enemy, float range, bool kneel, const Vector3 & move_location, float arrived_distance );
	void Action_Dive( SoldierGameObj * soldier, const Vector3 & location );
	void Stay_Within_Home( SoldierGameObj * soldier, Vector3 * location, float * distance );
	bool Take_Cover( SoldierGameObj * soldier, bool force_face = false, const Vector3 & face_pos = Vector3(0,0,0) );
	void Look_Random( SoldierGameObj * soldier, float duration );


	/*
	** Innate AI Cover Positions
	*/
	void	Release_Cover_Position( void );

};

#endif	// SOLDIEROBSERVER_H
