www.pudn.com > GameEngine_src.rar > CMagic.cpp


// CMagicSprite.cpp: implementation of the CMagicSprite class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "CAliveSprite.h" 
#include "CMagic.h" 
#include "normal.h" 
#include "CMap.h" 
#include "CMagicFactory.h" 
#include "CHero.h" 
#include  
#include  
 
 
extern CMap				theMap; 
extern CMagicFactory	theMagicFactory; 
extern CHero			theHero; 
extern PEASYAUDIO		g_pEasyAudio; 
 
//****************************************CMagic************************************************ 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CMagic::CMagic() 
{ 
	m_pSound = NULL; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CMagic::~CMagic() 
{ 
	Free(); 
} 
 
////////////////////////////////////////////////////////////////////// 
//初始化 
//mfh:MGC文件的文件头 
//pES:脚本在内存中的位置 
//indexOfEPG:载入时EPG的索引 
////////////////////////////////////////////////////////////////////// 
bool CMagic::Init( const MAGIC_FILE_HEADER &mfh, char *pES ) 
{ 
	m_MagicID		= mfh.mgcID; 
	m_Interval		= mfh.mgcInterval; 
	m_MagicDistance = mfh.mgcDistance; 
	m_Mana			= mfh.mgcMana; 
	m_CmdOnEffect	= mfh.mgcCmdOnEffect; 
	m_CmdOnEffect2	= mfh.mgcCmdOnEffect2; 
	m_SpellState	= mfh.mgcSpellState; 
	m_MagicArea		= mfh.mgcArea; 
 
	m_CmdPool.LoadESFromMemory( pES, 0 ); 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CMagic::LoadMagicFile( char *filename ) 
{ 
	FILE *fp = fopen( filename, "rb" ); 
	if ( fp == NULL ) 
		return false; 
	 
	MAGIC_FILE_HEADER mfh; 
	fread( &mfh, sizeof(mfh), 1, fp ); 
	if ( mfh.mgcFileType != MGC_FILE ) 
	{ 
		fclose(fp); 
		return false; 
	} 
 
	m_MagicID		= mfh.mgcID; 
	m_MagicDistance = mfh.mgcDistance; 
	m_Mana			= mfh.mgcMana; 
	m_CmdOnEffect	= mfh.mgcCmdOnEffect; 
	m_CmdOnEffect2	= mfh.mgcCmdOnEffect2; 
	m_SpellState	= mfh.mgcSpellState; 
	m_MagicArea		= mfh.mgcArea; 
 
	m_CmdPool.LoadESFromFile( fp, sizeof(MAGIC_FILE_HEADER) ); 
 
	fclose(fp); 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::Free() 
{ 
	m_MagicEPG.Free(); 
	if ( m_pSound ) 
		g_pEasyAudio->DeleteSoundBuffer( m_pSound ); 
 
	m_CmdPool.Free(); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::OnHeroSpell( CAliveSprite *pMagician, CAliveSprite *pTarget, const POINT &p ) 
{ 
	m_SpellPoint = p; 
	theMagicFactory.SetCurMagic( this ); 
	theMagicFactory.SetMagician( pMagician ); 
	theMagicFactory.SetTarget( pTarget ); 
	pMagician->SetState( m_SpellState ); 
	m_CmdPool.RunCmdAll();			//运行施法时的脚本 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::OnSpell( CAliveSprite *pMagician, CAliveSprite *pTarget ) 
{ 
	m_SpellPoint = pTarget->GetBasePoint(); 
	theMagicFactory.SetCurMagic( this ); 
	theMagicFactory.SetMagician( pMagician ); 
	theMagicFactory.SetTarget( pTarget ); 
	m_CmdPool.RunCmdAll();			//运行施法时的脚本 
 
	if ( pMagician->SetState( m_SpellState ) == false ) 
	{ 
		SPRITE_STATE state = ( m_SpellState == SS_SPELL ? SS_MELEE : SS_SPELL ); 
		pMagician->SetState( state ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::OnEffect( CAliveSprite *pMagician, CAliveSprite *pTarget ) 
{ 
	theMagicFactory.SetCurMagic( this ); 
	theMagicFactory.SetMagician( pMagician ); 
	theMagicFactory.SetTarget( pTarget ); 
	theMagicFactory.SetSpellPoint( m_SpellPoint ); 
	m_CmdPool.RunCmd( m_CmdOnEffect ); 
	if ( m_pSound ) m_pSound->Play(); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::OnHeroEffect( CAliveSprite *pMagician, CAliveSprite *pTarget ) 
{ 
	theMagicFactory.SetCurMagic( this ); 
	theMagicFactory.SetMagician( pMagician ); 
 
	if ( m_MagicArea == MA_SELF ) 
		pTarget = pMagician; 
 
	theMagicFactory.SetTarget( pTarget ); 
	theMagicFactory.SetSpellPoint( m_SpellPoint ); 
	m_CmdPool.RunCmd( m_CmdOnEffect ); 
	if ( m_pSound ) m_pSound->Play(); 
} 
  
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagic::OnEffect2( CAliveSprite *pMagician, CAliveSprite *pTarget ) 
{ 
	theMagicFactory.SetCurMagic( this ); 
	theMagicFactory.SetMagician( pMagician ); 
	theMagicFactory.SetTarget( pTarget ); 
	m_CmdPool.RunCmd( m_CmdOnEffect2 ); 
} 
 
//*****************************************CMagicSprite****************************************** 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CMagicSprite::CMagicSprite() 
{ 
 
} 
 
CMagicSprite::~CMagicSprite() 
{ 
 
} 
 
 
////////////////////////////////////////////////////////////////////// 
//初始化 
//life 为魔法精灵的存活时间 
//direction 为施法者施法时的方向,仅对地上魔法有用 
////////////////////////////////////////////////////////////////////// 
bool CMagicSprite::Init( CMagic *pMagic, const POINT &base, int direction, SPRITE_TYPE SpriteType, int life, 
						 CAliveSprite *magician, CAliveSprite *target, int damage ) 
{ 
	m_pMagic = pMagic; 
	m_cur_pg = pMagic->GetMagicEPG(); 
	m_BasePoint = base; 
 
	if ( pMagic->IsTarget() ) 
	{ 
		GetNextPoint( direction, m_BasePoint );		//为地上魔法计算实际位置(沿方向前进一个位置) 
		m_direction = direction; 
	} 
 
	m_SpriteType = SpriteType; 
	m_EndTime = life + timeGetTime(); 
	m_pMagician = magician; 
	m_pTarget = target; 
	m_damage = damage; 
	CalcPriority(); 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CMagicSprite::UpdateSprite() 
{ 
	unsigned int ThisTick = timeGetTime(); 
	bool bNextFrame = false; 
 
	if ( ThisTick - m_LastTick > m_cur_pg->GetDelayTime() ) 
	{ 
		bNextFrame = true; 
		m_LastTick = ThisTick; 
	} 
	else 
	{ 
		if ( m_EndTime < ThisTick ) 
		{ 
			theMagicFactory.DeleteMagicSprite( this ); 
			return false; 
		} 
		goto _exit; 
	} 
 
	if ( m_pMagic->IsTarget() )	//地上魔法会跟踪目标 
	{ 
		m_direction = CalcDirection( m_BasePoint, m_pTarget->GetBasePoint() ); 
 
		if ( m_Frame == m_cur_pg->GetLastFrame() )	//如果到了移位帧(最后一帧) 
		{ 
			if ( m_pTarget->IsAlive() ) 
			{ 
				POINT next; 
				GetNextPoint( m_direction, next ); 
				if ( theMap.IsCellNull( next.y / CELL_HEIGHT, next.x / CELL_WIDTH ) ) 
				{ 
					theMagicFactory.DeleteMagicSprite( this );	//如果超出地图范围,死亡 
					return false; 
				} 
				 
				m_BasePoint = next; 
				CalcPriority(); 
			} 
			else						//如果目标已死亡,魔法精灵也死亡 
			{ 
				theMagicFactory.DeleteMagicSprite( this ); 
				return false; 
			} 
		} 
		else							//如果非移位帧,则判断是否击中目标 
		{ 
			if ( m_BasePoint.x == m_pTarget->GetBasePoint().x  
				&& m_BasePoint.y == m_pTarget->GetBasePoint().y ) 
			{ 
				theMagicFactory.SetMagicDamage( m_damage ); 
				m_pMagic->OnEffect2( m_pMagician, m_pTarget ); 
				theMagicFactory.DeleteMagicSprite( this ); 
				return false; 
			} 
		} 
	} 
	else if ( m_SpriteType == ST_MAGE_3 )	//如果是天空魔法 
	{ 
		if ( m_Frame == m_cur_pg->GetLastFrame() )	//如果到了最后一帧 
		{ 
			EffectHelp(); 
			theMagicFactory.DeleteMagicSprite( this ); 
			return false; 
		} 
	} 
	else if ( m_SpriteType == ST_MAGE_2 || m_SpriteType == ST_MAGE_1 ) 
	{ 
		EffectHelp(); 
	} 
	 
_exit: 
 
	if ( m_pMagic->IsTarget() ) 
		m_CurFrame = m_cur_pg->UpdateAliveSprite( bNextFrame, m_Frame, m_direction, m_BasePoint, m_RenderPoint, m_Rect ); 
	else  
		m_CurFrame = m_cur_pg->UpdateMagicSprite( bNextFrame, m_Frame, m_BasePoint, m_RenderPoint, m_Rect ); 
 
	return true; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagicSprite::DrawSprite() 
{ 
	m_cur_pg->DrawFrame( m_CurFrame, m_RenderPoint.x, m_RenderPoint.y ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CMagicSprite::EffectHelp() 
{ 
	RECT rc, rcOut; 
	rc.left = m_BasePoint.x; 
	rc.top	= m_BasePoint.y; 
	rc.right= rc.left + CELL_WIDTH; 
	rc.bottom=rc.top + CELL_HEIGHT; 
	 
	int add = 0; 
	if ( m_pMagic->GetMagicArea() == MA_CELL_9 ) 
		add = 1; 
	else if ( m_pMagic->GetMagicArea() == MA_CELL_25 ) 
		add = 2; 
	 
	int add_x = add * CELL_WIDTH; 
	int add_y = add * CELL_HEIGHT; 
	 
	rc.left -= add_x; 
	rc.right+= add_x; 
	rc.top -= add_y; 
	rc.bottom+=add_y; 
	 
	if ( m_pMagician->GetSpriteType() == ST_MONSTER ) 
	{ 
		if ( theHero.GetBasePoint().x >= rc.left && theHero.GetBasePoint().y < rc.right ) 
		{ 
			if ( theHero.GetBasePoint().y >= rc.top && theHero.GetBasePoint().y < rc.bottom ) 
			{ 
				theMagicFactory.SetMagicDamage( m_damage ); 
				m_pMagic->OnEffect2( m_pMagician, &theHero ); 
			} 
		} 
	} 
	else if ( m_pMagician->GetSpriteType() == ST_HERO ) 
	{ 
		theMap.GetVisibleTile( rc, rcOut ); 
		for ( int i = rcOut.top; i <= rcOut.bottom; ++i ) 
		{ 
			for ( int j = rcOut.left; j <= rcOut.right; ++j ) 
			{ 
				CPool &pool = theMap.GetTilePointer( i, j )->m_APool; 
				for ( pool.Begin(); pool.IsNotNull(); pool.MoveNext() ) 
				{ 
					CBaseSprite *sprite = *(pool.GetCur()); 
					if ( sprite->GetSpriteType() >= ST_MONSTER ) 
					{ 
						if ( sprite->GetBasePoint().x >= rc.left && sprite->GetBasePoint().x < rc.right ) 
						{ 
							if ( sprite->GetBasePoint().y >= rc.top && sprite->GetBasePoint().y < rc.bottom ) 
							{ 
								theMagicFactory.SetMagicDamage( m_damage ); 
								m_pMagic->OnEffect2( m_pMagician, (CAliveSprite *)sprite ); 
							} 
						} 
					} 
				} 
			} 
		} 
	} 
}