📄 console.cpp
字号:
CloseHandle(hfile);
hfile = NULL;
}
}
#endif
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void ConsoleNet::CreateAICmd() {
TANKCMD *pcmd = m_pCmd+m_nLocal+1;
for ( int i=0; i<DEFAINUM; i++ ) {
if ( m_ppTanks[m_nLocal+1+i]->GetStat() & OBJSTAT_LIVE )
*(pcmd+i) = m_ppAiGen[i].Generator( NULL, 0 );
}
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void ConsoleNet::GameMain() {
static int counter = 0;
static DWORD start_time = 0, last_get;
static DWORD frame_start = 0;
DWORD end_time;
if ( m_dwStatus == CONSTAT_ENDGAME )
return ;
// Peek and process messages
if ( !NetList.IsEmpty() )
MsgProcessor( &NetList );
// Waiting
if ( m_dwStatus < CONSTAT_WAITMORE ) {
// TODO: here we should set a time-out event,
// and display like this, " Now, connecting... "
return ;
} else if ( m_dwStatus == CONSTAT_WAITBEGIN ) {
last_get = timeGetTime();
return ;
} else if ( m_dwStatus == CONSTAT_WAITPLAYER ) {
if ( bFresh ) {
cmdbuf = uiCurrentCmd;
firebuf = bFired;
bFresh = false;
}
if ( bRecvCmd ) {
last_get = timeGetTime();
m_dwStatus = CONSTAT_RUNNING;
} else {
end_time = timeGetTime();
if( end_time - last_get > WAITTIMEOUT ) {
// TODO: Record the lag
// m_dwStatus = CONSTAT_WAITERROR;
DebugOutput( 1, "Wait error!" );
m_dwStatus = CONSTAT_WAITERROR;
}
return ;
}
}
// FPS control, 1000/x in theory
// x = 20, 30 fps
while ( timeGetTime() - frame_start < 30 );
frame_start = timeGetTime();
// Running
if ( m_dwStatus == CONSTAT_RUNNING ) {
// Excute commands
BulletsProc(); // 1- Excute bullets earlier than tanks
#ifdef _DEBUG_CMDOUTPUT
char temp[4];
DebugOutput( 1, "*****Last Get:*****" );
for ( int i=0; i<DEFTANKNUM; i++ ) {
itoa(m_pCmd[i].cmd,temp,10);
DebugOutput( 2, temp, "\t" );
}
DebugOutput( 1, "\r\n" );
#endif
TanksProc(); // 2- Excute tanks
FoodProc(); // 3- Excute food
// Exchange command messages
m_pCmd[m_nLocal].cmd = cmdbuf;
m_pCmd[m_nLocal].fire = firebuf;
bFresh = true;
CreateAICmd();
#ifdef _DEBUG_CMDOUTPUT
DebugOutput( 1, "*****Generate:*****" );
for ( int k=m_nLocal; k<m_nLocal+DEFAINUM+1; k++ ) {
itoa(m_pCmd[k].cmd,temp,10);
DebugOutput( 2, temp, "\t" );
}
#endif
SendCmdMsg( &m_pCmd[m_nLocal], DEFAINUM+1, m_nLocal ); // home-0, enemy-5
// wait next message
m_dwStatus = CONSTAT_WAITPLAYER;
m_nMsgCounter = 0;
ZeroMemory( m_pMsgFlag,sizeof(bool)*m_nPlayers);
bRecvCmd = false;
}
// The app-window is not activated, skip refresh screen
if ( !g_bActive )
return ;
// Animations, frame roller
RollBlockObjects( m_pRiver, m_nNumRiver );
// Redraw land layer
Display.Clear(0); // level ground
Display.Blt(0,0,pMapSolid->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);
// objects layer
BlitBullets( m_ppBullets, DEFTANKNUM );
BlitTanks( m_ppTanks, DEFTANKNUM );
BlitBases( m_ppBases, 2 );
// Redraw grass layer, level trees
Display.Blt(0,0,pMapGrass->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);
BlitFood();
// FPS display
counter++;
end_time = timeGetTime();
if ( end_time - start_time >= 1000 ) {
start_time = end_time;
itoa( counter, fps+5, 10 );
counter = 0;
}
pText->DrawText( NULL, " ", 5, 5, RGB(0,0,0), RGB(0,0,0) );
pText->DrawText( NULL, fps, 5, 5, RGB(0,0,0), RGB(255,0,0) );
Display.Blt(0,0,pText->GetDDrawSurface(), NULL, 0);
// Flip
Display.Present();
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
int ConsoleNet::BulletsProc()
{
RECT rt_mobile;
POINT step, pt_block;
DWORD overland;
int hit_blt, hit_tk, hit_block, hit_base;
POINT ptChanged[4];
for ( int i=0; i<DEFTANKNUM; i++ )
{
// Create bullet
if ( m_pCmd[i].fire && !(m_ppTanks[i]->HaveBullet()) ) {
m_ppBullets[i]->CreateBullet( m_ppTanks[i] );
pFire->Play();
}
else if ( m_ppBullets[i]->GetStat() == OBJSTAT_CADAVER )
continue;
// Collision test
if ( m_ppBullets[i]->GetStat() & OBJSTAT_LIVE )
{
// Set coltest parameters
step = m_ppBullets[i]->GetDirectionUnit();
rt_mobile = m_ppBullets[i]->GetNextRect();
// Collistion test of bases
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases, 2, -1,
m_ppBullets[i]->m_uiTeamType, true, hit_base );
// Collistion test of bullets
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
m_ppBullets[i]->m_uiTeamType, true, hit_blt );
// Collistion test of bullets and tanks
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
m_ppBullets[i]->m_uiTeamType, true, hit_tk );
pt_block.x = rt_mobile.left;
pt_block.y = rt_mobile.top;
// Collistion test of tanks and blocks
overland = 0;
hit_block = 4; // don't need to remove blocks
MapInfo.ColRToB( pt_block, WIDTH_16, step, COL_IRON,
overland, COL_BRICK, ptChanged, hit_block );
// Reset and render map
int level;
RECT *prc = new RECT;
for( int j=0; j<hit_block; j++ ) {
MapInfo.BlockLocator( ptChanged[j].x, ptChanged[j].y, prc, level );
// if ( level == LAYER_GROUND )
pddsSolid->BltFast( ptChanged[j].x<<5, ptChanged[j].y<<5, pddsRes, prc, 0 );
// else if ( level == LAYER_TREE )
// pddsGrass->BltFast( ptChanged[i].x<<5, ptChanged[i].y<<5, pddsRes, prc, 0 );
}
// Boom and destroy
m_ppBullets[i]->SetPos( pt_block.x, pt_block.y );
if ( pt_block.x != rt_mobile.left || pt_block.y != rt_mobile.top ||
hit_block > 0 ) {
m_ppBullets[i]->NextStat();
} else if ( hit_tk >= 0 ) {
m_ppBullets[i]->Hit( m_ppTanks[hit_tk] );
} else if ( hit_blt >= 0 ) {
m_ppBullets[i]->Hit( m_ppBullets[hit_blt] );
} else if ( hit_base >= 0 ) {
if ( !( m_ppBases[hit_base]->m_ptyBlood.Minus( m_ppBullets[i]->GetAttack() ) ) )
SendMsg( NETMSGTK_TEAMVICTORY, &hit_base, sizeof(int) );
m_ppBullets[i]->NextStat();
}
}
else
m_ppBullets[i]->NextStat();
}
return 0;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
int ConsoleNet::TanksProc()
{
RECT rt_mobile;
POINT step, pt_block;
int hit_blt, hit_tk, hit_block, hit_base;
DWORD overland, blockland;
bool movetest;
for ( int i=0; i<DEFTANKNUM; i++ )
{
if ( m_ppTanks[i]->GetStat() & OBJSTAT_CADAVER )
continue;
if ( m_ppTanks[i]->GetStat() & OBJSTAT_DIE ) {
m_ppTanks[i]->NextStat();
pBoom->Play();
continue;
}
// Convert direction
if ( m_ppTanks[i]->IsHomeTeam() ^ m_bHomeTeam )
m_pCmd[i].cmd = 5 - m_pCmd[i].cmd;
// Direction command to excute,
if ( m_ppTanks[i]->m_uiIceDir != DIR_NONE ) // still sliding
{
movetest = true;
// if on ice, modify slide speed each time
if ( m_pCmd[i].cmd > DIR_NONE && m_pCmd[i].cmd < DIR_MAX ) {
// After all, reset main direction
m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;
// Affect the speed by direction
if ( m_ppTanks[i]->m_uiIceDir == m_pCmd[i].cmd ) { // speed up
if ( m_ppTanks[i]->m_nIceStep < MAXSPEEDONICE-2 )
m_ppTanks[i]->m_nIceStep += 2;
else
m_ppTanks[i]->m_nIceStep = MAXSPEEDONICE;
} else {
if ( m_ppTanks[i]->m_uiIceDir == 5 - m_pCmd[i].cmd ) // opposite
m_ppTanks[i]->m_nIceStep -= 4;
else // others, no effect
m_ppTanks[i]->m_nIceStep -= 2;
if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
movetest = false;
m_ppTanks[i]->m_uiIceDir = DIR_NONE;
}
}
} else { // natural friction
m_ppTanks[i]->m_nIceStep -= 2;
if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
movetest = false;
m_ppTanks[i]->m_uiIceDir = DIR_NONE;
}
}
// Set coltest parameters
step = m_ppTanks[i]->GetDirUnitOnIce();
rt_mobile = m_ppTanks[i]->GetNextRectOnIce();
}
// Test command to see if it's none
else if ( m_pCmd[i].cmd == DIR_NONE || m_pCmd[i].cmd == DIR_MAX )
continue;
else if ( m_ppTanks[i]->m_uiDirection == m_pCmd[i].cmd ) // move forward
{
// Set moving animation flag
m_ppTanks[i]->m_bMoving = true;
movetest = true;
// Set coltest parameters
step = m_ppTanks[i]->GetDirectionUnit();
rt_mobile = m_ppTanks[i]->GetNextRect();
}
else // just turn around
{
movetest = false;
bool dirtest = true;
int residue;
// Count a integer step
rt_mobile = m_ppTanks[i]->GetRect();
step = m_ppTanks[i]->GetDirectionUnit();
if ( step.y != 0 ) {
residue = m_ppTanks[i]->GetTop() % DEFTURNSTEP;
if ( residue == 0 )
dirtest = false;
else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) { // down
residue = DEFTURNSTEP - residue;
rt_mobile.top += residue;
rt_mobile.bottom += residue;
} else { // up
rt_mobile.top -= residue;
rt_mobile.bottom -= residue;
}
} else if ( step.x != 0 ) {
residue = m_ppTanks[i]->GetLeft() % DEFTURNSTEP;
if ( residue == 0 )
dirtest = false;
else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) { // right
residue = DEFTURNSTEP - residue;
rt_mobile.left += residue;
rt_mobile.right += residue;
} else { // left
rt_mobile.left -= residue;
rt_mobile.right -= residue;
}
}
// Test if it can move
if ( dirtest ) {
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
m_ppTanks[i]->m_uiTeamType, false, hit_tk );
if ( hit_tk < 0 )
m_ppTanks[i]->SetPos( rt_mobile.left, rt_mobile.top );
}
// change direction
m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;
}
// Move collision test
if ( movetest ) {
// Collistion test of bases
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases,
2, -1, 0, false, hit_base );
// Collistion test of bullets
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
m_ppTanks[i]->m_uiTeamType, true, hit_blt );
// Collistion test of tanks
MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
m_ppTanks[i]->m_uiTeamType, false, hit_tk );
// Collistion test of tanks and blocks
pt_block.x = rt_mobile.left;
pt_block.y = rt_mobile.top;
overland = COL_ICE;
blockland = COL_BRICK|COL_IRON;
if ( !(m_ppTanks[i]->m_dwEquip & EQUIP_SHIP) )
blockland |= COL_RIVER;
hit_block = 0; // don't need to remove blocks
MapInfo.ColRToB( pt_block, WIDTH_32, step, blockland,
overland, 0, NULL, hit_block );
// Set ice flag
if ( overland & COL_ICE ) {
m_ppTanks[i]->m_bOnIce = true;
if ( m_ppTanks[i]->m_uiIceDir == DIR_NONE ) {
m_ppTanks[i]->m_nIceStep = m_ppTanks[i]->GetStep();
m_ppTanks[i]->m_uiIceDir = m_ppTanks[i]->m_uiDirection;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -