//@STATE=嶌惉拞
//@DESCRIPTION ---------------------------------------------------------------
// ZK02.cpp: ZK02 僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
//	棜楌丗
// $Log: ZK02.cpp,v $
// Revision 1.1  2001/10/28 21:40:37  fujiwara
// DLL偵暘妱
//
// Revision 1.4  2001/07/09 20:30:10  fujiwara
// 椺奜張棟偺慻傒崬傒
//
// Revision 1.3  2001/07/01 21:30:34  fujiwara
// 儊儌儕儕乕僋僠僃僢僋尒捈偟
//
// Revision 1.2  2001/07/01 01:03:45  fujiwara
// const 偺尒捈偟
// 攝抲僄僨傿僞偼搑拞宱夁
//
// Revision 1.1  2001/06/10 21:16:12  fujiwara
// 嶨嫑僉儍儔俀捛壛
//
//@DESCRIPTION_END -----------------------------------------------------------
//@AUTHOR=S.F.
// Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////
#pragma warning( disable : 4786 )	//STL偺寈崘奜偟

// 儊儌儕乕儕乕僋専弌梡
#include "sfdebug.h"

#include <string>
#include <vector>
#include <memory>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <map>

#include "stdio.h"
#include "math.h"

#include "exception.h"
#include "singleton.h"
#include "system.h"
#include "console.h"
#include "input.h"
#include "sound.h"

#include "Obj.h"
#include "Obj2D.h"
#include "Obj3D.h"
#include "Obj3DL.h"
#include "ObjRectangle.h"
#include "ObjQuadrangle.h"

#include "Background.h"
#include "Scene.h"
#include "main.h"

#include "character.h"
#include "Hit.h"
#include "MyShip.h"
#include "Game.h"
#include "Enemys.h"
#include "Armys.h"
#include "AbstractEnemy.h"
#include "EnemyBullets.h"
#include "DispositionControl.h"
#include "Effects.h"
#include "Explosion.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "ZK02.h"
#include "EB01.h"

using namespace sf::application;
using namespace sf::application::enemy;
using namespace sf::system;

sf::system::console::sprite::PSprite ZK02::mspSprite;


const sf::system::console::sprite::Info ZK02::msSpriteInfo = 
{
	"media\\ZK02.png",0.0f,0.0f,64.0f,64.0f,0xff000000,console::sprite::SPRITE2D
};

const int ZK02::SCORE = 20;

// 僐儞僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
ZK02::ZK02()
{
}// ZK02()

// 僨僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
ZK02::~ZK02()
{
	Enemys::instance()->clear(index());
}// ~ZK02()


// 弶婜壔 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::initialize(void)
{
	// 摉傝敾掕 
	mHitRect.offsetTop(-20.0f);
	mHitRect.offsetBottom(20.0f);
	mHitRect.offsetLeft(-20.0f);
	mHitRect.offsetRight(20.0f);

	mHitRect.isChecking(true);
	mHitRect.characterPtr(this);
	direction(Util::calcDirection(x(),y(),game()->player()->x(),game()->player()->y()));
	
 	mDeltaTime = sf::system::instance()->deltaTime();
	mDeltaTimeRev = 1.0f / mDeltaTime;
	speed(8.0f * mDeltaTime + (rand() & 0x7) + game()->currentDifficulty());

	mDx = cosf(direction());
	mDy = sinf(direction());
	
	// Body 晹暘 
	mObj.index(0);

	if(!mspSprite.get())
		load();

	mObj.sprite(mspSprite.get());
	
	mObj.z(z() + (float)index() * 0.0001f );
	mObj.x(x());
	mObj.y(y());

	mObj.visibility(true);
	mObj.color(0xffffffff);
	mObj.drawMode(sf::system::console::DRAW_TRANS);
	mObj.angle(direction());

	// Light晹暘
	mObjLight.z(z() + (float)index() * 0.0001f - 0.00001f);
	mObjLight.x(x());
	mObjLight.y(y());
	
	life(2);

	initLight();
	
	mbHit = false;
	mState = APPROACH;
	mAccel = 0.3f * mDeltaTime;

}// initialize()

// 僥僋僗僠儍偺儘乕僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::load(void){
	using namespace sf::system::console::sprite;
	if(!mspSprite.get()){
		sf::system::console::sprite::PSprite ptemp(sf::system::instance()->console()->createSprite(&msSpriteInfo)); 
		mspSprite = ptemp;
	}
	Bullets::instance()->load(Bullets::EB01);
	AbstractEnemy::loadLight();
}// load()

// 僥僋僗僠儍偺傾儞儘乕僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::unload(void){
	using namespace sf::system::console::sprite;
	PSprite ptmp(NULL);
	mspSprite = ptmp;
}// unload()

// 揋偺摦嶌 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::move()
{
	using namespace sf::application;


	switch(mState){
	case APPROACH:
		approach();
		break;
	case SHOOT:
		shoot();
		break;
	case ESCAPE:
		escape();
		break;
	case DEAD:
		if(!--mDirCount){
			delete this;
			return;
		}
		mObj.x(x());
		mObj.y(y());
		return ;
	}

	// 抏偵偁偨偭偨偐偳偆偐偺敾掕
	if(mbHit)
	{
		mObj.color(0xffff8080);
		mObj.drawMode(sf::system::console::DRAW_ADD);
		mbHit = false;
	} else {
		mObj.drawMode(sf::system::console::DRAW_TRANS);
		mObj.color(0xffffffff);
	}


	// 夋柺徚嫀敾掕
	if(Util::checkArea(x(),y(),64.0f,64.0f))
		delete this;
}//move()


// 僾儗僀儎乕偵愙嬤 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::approach(void){

	float dir_player = Util::calcDirection(x(),y(),game()->player()->x(),game()->player()->y());
	float dir = fabs(direction() - dir_player);
		
	if(dir > sf::system::PI)
		dir = 2.0f * sf::system::PI - dir;
		
	if(dir > 0.08f)
	{

		dir = direction() - dir_player;
			
		if(dir < 0.0f) dir = dir + 2.0f * sf::system::PI;
			
		if(dir > sf::system::PI) 
			mDirSpeed = 0.04f;
		else
			mDirSpeed = -0.04f;
	
		direction(direction() + mDirSpeed);
			
		if(direction() < 0.0f)
			direction(2.0f * sf::system::PI + direction());
	
		if(direction() > 2.0f * sf::system::PI)
			direction(direction() - 2.0f * sf::system::PI);

		mObj.angle(direction());
		
		mDx = cosf(direction());
		mDy = sinf(direction());
	

	} 

	y(y() + mDy * speed());
	x(x() + mDx * speed());
	
	mObj.x(x());
	mObj.y(y());

	mObjLight.x(x() + cosf(direction()) * -8.0f );
	mObjLight.y(y() + sinf(direction()) * -8.0f );

	moveLight();

	speed(speed() - mAccel);

	if(speed() < 0.0f){
		speed(0.0f);
		mState = SHOOT;
		mAnimCount = 0.0f;
	}
	

}// approach()

// 僾儗僀儎乕曽岦傪岦偒丄抏傪敪幩偡傞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::shoot(void){
	

	mAnimCount += 0.2f;

	if(mAnimCount <= 3.0f){
		mObj.index((int)mAnimCount);

	} else {
		if(mAnimCount > 4.0f){
			float tx = x() + 8.0f * cosf(direction());
			float ty = y() + 8.0f * sinf(direction());
			EB01 *peb = (EB01 *)Bullets::instance()->create(Bullets::EB01,tx,ty,z() + 0.01f,game());
			peb->direction(direction());
			mbShoot = true;
			mState = ESCAPE;
			mDirSpeed = (x() < (float)(console::viewport::X + console::viewport::WIDTH / 2))?-0.08f:0.08f;
			mDirCount = 0.0f;
			mAnimCount = 3.0f;
			mObj.index((int)mAnimCount);
			return;
		}
	}

	float dir_player = Util::calcDirection(x(),y(),game()->player()->x(),game()->player()->y());
	float dir = fabs(direction() - dir_player);
		
	if(dir > sf::system::PI)
		dir = 2.0f * sf::system::PI - dir;
		
	if(dir > 0.08f)
	{

		dir = direction() - dir_player;
			
		if(dir < 0.0f) dir = dir + 2.0f * sf::system::PI;
			
		if(dir > sf::system::PI) 
			mDirSpeed = 0.04f;
		else
			mDirSpeed = -0.04f;
	
		direction(direction() + mDirSpeed);
			
		if(direction() < 0.0f)
			direction(2.0f * sf::system::PI + direction());
	
		if(direction() > 2.0f * sf::system::PI)
			direction(direction() - 2.0f * sf::system::PI);

		mObj.angle(direction());
		
		mDx = cosf(direction());
		mDy = sinf(direction());
	

	}

	mObj.x(x());
	mObj.y(y());

	mObjLight.x(x() + cosf(direction()) * -8.0f );
	mObjLight.y(y() + sinf(direction()) * -8.0f );
	moveLight();

}// shoot()

// 棧扙偡傞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::escape(void)
{
	if(mAnimCount > 0.0f){
		mAnimCount -= 0.2f;
		mObj.index((int)mAnimCount);
	}

	if(mDirCount < sf::system::PI){
		mDirCount += mDirSpeed > 0 ? mDirSpeed:-mDirSpeed;
		direction(direction() + mDirSpeed);
		speed(speed() + 0.1f);
		mDx = cosf(direction());
		mDy = sinf(direction());
	}
	
	mObj.angle(direction());

	x(x() + mDx * speed());
	y(y() + mDy * speed());

	mObj.x(x());
	mObj.y(y());

	mObjLight.x(x() + cosf(direction()) * -8.0f );
	mObjLight.y(y() + sinf(direction()) * -8.0f );
	moveLight();

}// escape()

// 抏偵偁偨偭偨偲偒偺張棟 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::hit(Character * const pDest)
{
	if(pDest->life()){
		life(life() - pDest->life());
		if(life() < 0) {
			y(y() + mDy * speed());
			x(x() + mDx * speed());


			mHitRect.isChecking(false);
			mbHit = true;
			die();
		} else {
			mbHit = true;
		}
	}
};

// 揋偺惗惉 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
sf::application::Character * const ZK02::create(float x,float y ,float z,sf::application::scene::Game * const pGame,int index)
{
	ZK02 * ptemp = new ZK02;
	ptemp->x(x);
	ptemp->y(y);
	ptemp->z(z);
	ptemp->index(index);
	ptemp->game(pGame);
	ptemp->initialize();
	return ptemp;
;}// create

//丂巰傫偩偲偒偺張棟  亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::die(void)
{
	effect::Explosion *pExp = (effect::Explosion*)effect::Effects::instance()->create(effect::Effects::EXPLOSION,x(),y(),0.1f,game(),this);
	if(pExp){
		pExp->scaling(1.5f);
	}
	mDirCount = 4;
	mState = DEAD;
	game()->score(game()->score() + SCORE);

};// die()

//  慡敋敪僀儀儞僩 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void ZK02::allBomb(void)
{
	die();
}// allBomb()