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 ); } } } } } } } }