/*!
* @file Creature.h
* @brief ゲーム中のクリーチャーと付随要素のプロトタイプ
* @date 2013/12/11
* @author Deskull
* 2013 Sikabane Works.
*/

#pragma once

#include "stdafx.h"
#include "BaseStatusTable.h"
#include "Coordinates.h"
#include "Discipline.h"
#include "Effect.h"
#include "Floor.h"
#include "Item.h"
#include "GameElement.h"
#include "SavingTable.h"
#include "Species.h"

BOOST_CLASS_VERSION(Creature, 1);

namespace Deeangband
{

	/*!
	* @class Creature
	* @brief クリーチャーのクラス
	*/
	class Creature : public GameElement
	{
	private:

		static SOUL soulLevel[CREATURE_MAX_LEVEL]; //!< 必要ソウルレベルテーブル

		NAME name;      //!< クリーチャーの名前
		HP currentHp;     //!< 現在のHP
		HP maxHp;         //!< 現在の最大HP
		MP currentMp;     //!< 現在のMP
		MP maxMp;         //!< 現在の最大MP
		MP maxMaxMp;      //!< 本来の最大MP
		SOUL currentSoul; //!< 現在のソウル値
		SOUL maxSoul;     //!< ソウル最大到達値

		HEIGHT height;    //!< 身長
		HEIGHT weight;    //!< 体重

		FEED currentFeed; //!< 現在滋養値
		FEED maxFeed;     //!< 最大滋養値

		Discipline currentDiscipilne; //!< 現在の修養値
		LEVEL divineLevel;            //!< 神性レベル

		BaseStatusTable currentStatus; //!< 現在のステータス
		BaseStatusTable maxStatus;     //!< 通常のステータス
		BaseStatusTable maxMaxStatus;  //!< 限界のステータス

		SavingTable savings; //!< セービング

		ID floorID;           //!< 現在いるフロアID
		Coordinates position; //!< 現座標
		std::vector<Item> itemList;  //!< 所持アイテムリスト
		std::map<TAG, SKILL_EXP> skillExpList; //!< スキル経験値リスト

		char symbol;       //!< シンボルキャラ
		Color symbolColor; //!< シンボルカラー
		ID tileID;         //!< タイルID

		ID campID; //!< 所属陣営ID

		TURN turn; //!< 生存総ターン数

		HP hpTable[CREATURE_MAX_LEVEL]; //!< ヒットダイスに基づき生成されたレベル毎の基本HP

		/*!
		* @brief クリーチャー死亡時の処理を行う
		* @return なし
		*/
		void Creature::die(void);

		/*!
		* @brief クリーチャーの現HPを増減させる
		* @param amount 増減HP量
		* @return なし
		*/
		void Creature::calcHP(HP amount);

		/*!
		* @brief クリーチャーの現MPを増減させる
		* @param amount 増減MP量
		* @return なし
		*/
		void Creature::calcMP(MP amount);

		/*!
		* @brief クリーチャーの現HPを設定する
		* @param amount 設定HP量
		* @return なし
		*/
		void Creature::setHP(HP amount);

		/*!
		* @brief クリーチャーの現MPを設定する
		* @param amount 設定HP量
		* @return なし
		*/
		void Creature::setMP(MP amount);

		/*!
		* @brief クリーチャーを所定フロアの所定座標に移動する
		* @param floorID 移動先フロアID
		* @param x 移動先x座標
		* @param y 移動先y座標
		* @return 移動できなかった場合のエラーID
		*/
		int Creature::move(ID floorID, int x, int y);

		/*!
		* @brief クリーチャーを所定フロアの所定座標に移動する
		* @param floorID 移動先フロアID
		* @param coord 移動先座標
		* @return 移動できなかった場合のエラーID
		*/
		int Creature::move(ID floorID, Coordinates coord);

		/*!
		* @brief クリーチャーのレベル毎基本HPを再計算する
		* @return なし
		*/
		void Creature::calcHPTable(void);

		friend class boost::serialization::access;

		/*!
		* @brief クラスのシリアライズ化を設定する
		* @param archive アーカイブ化するクラスのアドレス
		* @param version データバージョン
		* @return XMLSerializeテンプレート
		*/
		template<class Archive> void serialize(Archive &archive, const unsigned int version) 
		{
			if(version >= 0)
			{
				archive & BOOST_SERIALIZATION_NVP(name);
				archive & BOOST_SERIALIZATION_NVP(currentHp);
				archive & BOOST_SERIALIZATION_NVP(maxHp);
				archive & BOOST_SERIALIZATION_NVP(hpTable);
				archive & BOOST_SERIALIZATION_NVP(currentMp);
				archive & BOOST_SERIALIZATION_NVP(maxMp);
				archive & BOOST_SERIALIZATION_NVP(maxMaxMp);
				archive & BOOST_SERIALIZATION_NVP(currentSoul);
				archive & BOOST_SERIALIZATION_NVP(maxSoul);
				archive & BOOST_SERIALIZATION_NVP(currentStatus);
				archive & BOOST_SERIALIZATION_NVP(maxStatus);
				archive & BOOST_SERIALIZATION_NVP(maxMaxStatus);
				archive & BOOST_SERIALIZATION_NVP(height);
				archive & BOOST_SERIALIZATION_NVP(weight);
				archive & BOOST_SERIALIZATION_NVP(currentFeed);
				archive & BOOST_SERIALIZATION_NVP(maxFeed);
				archive & BOOST_SERIALIZATION_NVP(savings);
				archive & BOOST_SERIALIZATION_NVP(floorID);
				archive & BOOST_SERIALIZATION_NVP(position);
				archive & BOOST_SERIALIZATION_NVP(itemList);
			}
		}

	public:

		/*! 
		* @brief Creatureクラスコンストラクタ(GameElementメンバ対応)
		* @param speciesPtr 生成元となるクリーチャー種別
		* @param id GameElementのID
		* @param tag GameElementのタグ
		* @param gameWorld 所属元gameWorld参照ポインタ
		*/
		Creature::Creature(Species *speciesPtr, ID id, TAG tag, GameWorld *gameWorld);

		/*! 
		* @brief Creatureクラスコンストラクタ(GameElementメンバ対応)
		* @param id GameElementのID
		* @param tag GameElementのタグ
		* @param gameWorld 所属元gameWorld参照ポインタ
		*/
		Creature::Creature(ID id, TAG tag, GameWorld *gameWorld);

		/*! 
		* @brief Creatureクラスコンストラクタ
		*/
		Creature::Creature(void);

		/*! 
		* @brief Creatureクラスデストラクタ
		*/
		Creature::~Creature(void);

		/*! 
		* @brief クリーチャー種別に基づきクリーチャーを生成する
		*/
		void Creature::SetSpeciesData(Species *speciesPtr);

		/*! 
		* @brief ダミーデータによる初期化
		* @return なし
		*/
		void Creature::SetDammyData(void);

		/*!
		* @brief クリーチャーの名前を返す
		* @return クリーチャー名
		*/
		NAME Creature::GetName(void);

		/*!
		* @brief クリーチャーが生存している状態かを返す
		* @return 生存しているならばtrueを返す
		*/
		bool Creature::IsAlive(void);

		/*!
		* @brief 受けた属性効果を処理する
		* @param effectPtr
		* @param amount
		*/
		bool Creature::TakeEffect(Effect* effectPtr, POWER amount);

		/*! 
		* @brief クリーチャーの現レベルを返す
		* @return クリーチャーの現レベル
		*/
		LEVEL Creature::GetLevel(void);

		/*!
		* @brief クリーチャーの現HPを返す
		* @return クリーチャーの現HP
		*/
		HP Creature::GetCurHP(void);

		/*!
		* @brief クリーチャーの現最大HPを返す
		* @return クリーチャーの現最大HP
		*/
		HP Creature::GetMaxHP(void);

		/*!
		* @brief クリーチャーの通常最大HPを返す
		* @return クリーチャーの通常最大HP
		*/
		HP Creature::GetNorMaxHP(void);

		/*!
		* @brief クリーチャーの現MPを返す
		* @return クリーチャーの現MP
		*/
		MP Creature::GetCurMP(void);

		/*!
		* @brief クリーチャーの現最大MPを返す
		* @return クリーチャーの現最大MP
		*/
		MP Creature::GetMaxMP(void);

		/*!
		* @brief クリーチャーの通常最大MPを返す
		* @return クリーチャーの通常最大MP
		*/
		MP Creature::GetNorMaxMP(void);

		/*!
		* @brief クリーチャーの現装甲セービング値を返す
		* @return クリーチャーの現装甲セービング値
		*/
		AC Creature::GetArmorSaving(void);

		/*!
		* @brief クリーチャーの現回避セービング値を返す
		* @return クリーチャーの現回避セービング値
		*/
		EV Creature::GetEvasionSaving(void);

		/*!
		* @brief クリーチャーの現意思セービング値を返す
		* @return クリーチャーの現意思セービング値
		*/
		VO Creature::GetVolitionSaving(void);

		/*!
		* @brief クリーチャーの現在位置を返す
		* @return クリーチャー現在位置を示すCoordinates
		*/
		Coordinates *Creature::getCorrdinates(void);

		/*!
		* @brief クリーチャーの所持品リストを返す
		* @return クリーチャー所持品リストマップ
		*/
		std::vector<Item> *Creature::getItemList(void);

		/*!
		* @brief クリーチャーの現ソウル値を返す
		* @return クリーチャーの現ソウル値
		*/
		SOUL Creature::GetCurrentSoul(void);

		/*!
		* @brief クリーチャーのソウル最大到達値を返す
		* @return クリーチャーのソウル最大到達値
		*/
		SOUL Creature::GetMaxSoul(void);

		/*!
		* @brief クリーチャーの現基礎能力値を返す
		* @param stat 取得したい基礎能力値ID
		* @return 基礎能力値の現在値
		*/
		BASE_STATUS Creature::GetCurrentStatus(CREATURE_STATUS stat);

		/*!
		* @brief クリーチャーの平常基礎能力値を返す
		* @param stat 取得したい平常能力値ID
		* @return 基礎能力値の平常値
		*/
		BASE_STATUS Creature::GetMaxStatus(CREATURE_STATUS stat);

		/*!
		* @brief クリーチャーの限界基礎能力値を返す
		* @param stat 取得したい限界能力値ID
		* @return 基礎能力値の限界値
		*/
		BASE_STATUS Creature::GetMaxMAXStatus(CREATURE_STATUS stat);

		/*!
		* @brief クリーチャーの現在修養値を返す
		* @param typ 取得したい現在修養値のID
		* @return 現在修養値
		*/
		int Creature::GetDiscipilnePoint(DISCIPLINE_TYPE typ);

		/*!
		* @brief クリーチャーの現在修養ランクを返す
		* @param typ 取得したい現在修養ランクのID
		* @return 現在修養ランク
		*/
		int Creature::GetDiscipilneRank(DISCIPLINE_TYPE typ);

		/*!
		* @brief クリーチャーの身長を返す
		* @return 身長
		*/
		HEIGHT Creature::GetHeight(void);

		/*!
		* @brief クリーチャーの体重を返す
		* @return 体重
		*/
		WEIGHT Creature::GetWeight(void);

		/*!
		* @brief クリーチャーの体格値を返す
		* @return 体格値
		*/
		BODY_SIZE Creature::GetSize(void);

		/*!
		* @brief ソウル値の新規加算処理
		* @param plus 新規加算ソウル量
		* @return なし
		*/
		void Creature::GainSoul(SOUL plus);

		/*!
		* @brief ソウル値の喪失処理
		* @param amount 喪失ソウル量
		* @return なし
		*/
		void Creature::LostSoul(SOUL amount);

		/*!
		* @brief クリーチャーの神性レベルを返す
		* @return 神性レベル
		*/
		LEVEL Creature::GetDivineLevel(void);

		/*!
		* @brief 現在滋養値を返す
		* @return 現在滋養値
		*/
		FEED Creature::GetCurrentFeedPoint(void);

		/*!
		* @brief 最大滋養値を返す
		* @return 最大滋養値
		*/
		FEED Creature::GetMaxFeedPoint(void);

		/*!
		* @brief クリーチャーのターン時更新定期処理を行う
		* @return なし
		*/
		void Creature::TurnProcess(void);

		/*!
		* @brief クリーチャーのゲーム時間更新定期処理を行う
		* @return なし
		*/
		void Creature::TimeProcess(void);

		/*!
		* @brief クリーチャーの経過総ターン数を返す
		* @return 総ターン数
		*/
		TURN Creature::GetTurn(void);

		/*! 
		* @brief クリーチャー種別のスキル基本経験値を返す
		* @param tag 取得したいスキルのタグ
		* @return 該当スキルの基本経験値、全くの未経験ならば0を返す
		*/
		SKILL_EXP Creature::GetSkillExp(TAG tag);

		/*!
		* @brief クリーチャーの所属陣営IDを返す
		* @return 所属陣営ID
		*/
		ID Creature::GetCampID(void);

		/*!
		* @brief XMLシリアライズによるゲームデータ保存処理
		* @return なし
		*/
		void Creature::XMLSave(std::string filename);

	};

}