⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cbctrls.cpp

📁 赤壁之战(游戏原码)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////
// CBCtrlS.cpp	:	<< chibi >> global contral data structure
// v0014		:	Feb.16.1997,devided from CBCTRL.cpp
// v0020		:	Mar.29.1997,add most controls
// written by	:	Liu Gang
// Compiler		:	Visual C++ 4.2
// Copyright	:	WayAhead Co.Ltd.		1996-1997
/////////////////
// 此文件包含游戏对控制结构(命令,状态,步,帧)的处理
#include "stdafx.h"
#include "Assert.h"

#include "CBCTRL.h"
#include "CBShadow.h"
#include "CBMini.h"
#include "CBDATA.h"

#include "CBEyes.h"
//////////////////////
// Dong hai, 行军算法
#include "March_n.h"
extern	BYTE		MARCH_TrackForward[NUMBER_OF_TRACK];//此数组为用来存储最后由行军轨迹求出的行军路线的方向变化
extern short		MARCH_Track[NUMBER_OF_TRACK][3];//此数组为用来存储最后的行军轨迹的数组

//////////////////////
// LHJ
#include "marco.h"		// BUTTON_UP BUTTON_DISABLE
#include "interfac.h"	// FACE_SetNumberButtonState(int number, int state);
#include "cbprompt.h"	// FACE_UpdateExperience(), FACE_UpdateSoldierNumber()
// LHJ
//////////////////////

//////////////////////
// externals
extern int MAP_nLocationNum[4];						// defined in CBMap.cpp
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX];	// defined in CBMap.cpp
extern int MAP_nDrawNum[4];							// defined in CBMap.cpp
//////////////////////

//////////////////////
// local functions
// 在刚刚创建单元后,使用此函数对该单元赋给属性值
void CTRL_SetUnitAttribute( struct UNIT_STRUCT *pUnit );
//////////////////////

//////////////////////
// 状态处理
// Status
//////////////////////
// check each unit if should change Status
void CTRL_STATUS_Main()
{
	for( int i=0; i<GAME_PLAYER_MAX; i++ )
	{
#ifdef	_DEBUG
		int nCounter=0;
#endif
		for( int j=0; j<PLAYER_UNIT_MAX; j++ )
		{
			if( GAME.Players[i].Unit[j].nType != MAP_UNIT_TYPE_NONE )
			{
				CTRL_STATUS_Change( &GAME.Players[i].Unit[j] );
#ifdef	_DEBUG
				nCounter++;
#endif
			}
		}
#ifdef	_DEBUG
		if( GAME.Players[i].wUnitCounter!= nCounter )
			OutputDebugString( "CTRL_STATUS_Main Error(0): Unit number check error!\n" );
#endif
	}
}

// change the Status of the unit
// pUnit	:	the unit to be changed to
inline void CTRL_STATUS_Change( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit->nType != MAP_UNIT_TYPE_NONE );

	// 死亡时不响应任何命令
	if( EYE_IfUnitIsDead( pUnit ) )	return;	// has dead

#ifdef	_DEBUG
		// 是否要从建筑里出来
		if( pUnit->nHasShadow == 0 )
		{
			Assert( pUnit->Status.bIRQ == TRUE );
			pUnit->Status.bIRQ = TRUE;
		}
#endif

	if( pUnit->Task.nTaskID == QUXIAO )	return;	// no command at all

////////////////////////////
	// 清除Bug!!!
	// 必须当单元完成一个“步”操作后,才能接收新的命令
	if( pUnit->Draw.ptOff.x != 0 || pUnit->Draw.ptOff.y != 0 )
		return;
////////////////////////////

	// new command
	// 新命令,TASK的nTaskID不为QUXIAO,bDone为TRUE
	if( pUnit->Task.bDone )
	{
		Assert( pUnit->Draw.ptOff.x == 0 || pUnit->Draw.ptOff.y == 0 );
#ifdef	_DEBUG_OFFSET_
		if( pUnit->Draw.ptOff.x != 0 || pUnit->Draw.ptOff.y != 0 )
		{
//			WriteLogFile( "off.log", "change0\n" );
		}
#endif //_DEBUG_OFFSET_

		// 对某些旧命令要有一些结束的操作
		if( pUnit->Status.nTaskID == GONGJI )
		{
			Assert( pUnit->Status.nTaskIDEx == 2 );
			Assert( pUnit->Status.nParam1 != MAP_DATA_NONE );
			struct UNIT_STRUCT *pU = MAP_GetUnit( pUnit->Status.nParam1 );
			Assert( pU );
			pU->nIDAttackMe = MAP_DATA_NONE;
		}
		pUnit->nIDAttackMe = MAP_DATA_NONE;

		if( pUnit->Status.nTaskID == YUNSONG
			&& pUnit->Status.nTaskIDEx == 1
			&& EYE_IfUnitIsWorker( pUnit ) 
			&& pUnit->Status.bDone == FALSE )
		{
			int nDir;
			nDir = pUnit->Draw.nDir;
			int bOdd = pUnit->Draw.nY&1;
			int nX = pUnit->Draw.nX + MAP_ptSenser[bOdd][0][nDir].x;
			int nY = pUnit->Draw.nY + MAP_ptSenser[bOdd][0][nDir].y;
			WORD codeG = MAP_GetGroundData( pUnit->Draw.nLayer, nX, nY );
			if( codeG != MAP_DATA_NONE )
			{
				struct MAP_GROUND_CODE_STRUCT stctG;
				MAP_GroundDeCode( codeG, &stctG );
				Assert( stctG.nAttr != MAP_SPECIAL_NONE );
				Assert( stctG.nAttr == pUnit->Soldier.nResType+4 );	// 碰巧
				stctG.nAttr -= 4;	// 设置为采集完
				codeG = MAP_GroundEnCode( stctG );
				MAP_SetGroundData( pUnit->Draw.nLayer, nX, nY, codeG );
			}
		}

		if( pUnit->Status.nTaskID == MFU )
		{
			CTRL_SetSTG( &pUnit->Draw, MAIFU, FALSE );
		}

		// 对于已经打开的门,则不再执行此命令
		// Aug.8, 1997, Liu Gang
		if( pUnit->Status.nTaskID == KAIMEN 
			&& pUnit->nCounter != 0 )
		{
			pUnit->Task.bDone = FALSE;
			// 计数器不能为0
			//pUnit->nCounter = 0;
			return;
		}

//		OutputDebugString( "CTRL_TASK : New Command: " );
//		OutputString( pUnit->Task.nID, "," );
//		OutputString( pUnit->Task.nTaskID, "," );
//		OutputString( pUnit->Task.nTaskIDEx, "\n" );
		// set TASK to "doing"
		// 设置完毕状态后,bDone为FALSE
		pUnit->Task.bDone = FALSE;
		pUnit->nCounter = 0;

		// 运送任务,但是此时该单元已经携带有资源了
		if( pUnit->Task.nTaskID == YUNSONG
			&& EYE_IfUnitIsWorker( pUnit ) 
			&& pUnit->Soldier.nResource > 0 )
		{
			// 设置该士兵为回送的任务
			struct CTRL_TASK_STRUCT Task;
			CTRL_TASK_Clear( &Task );
			Task.nID = pUnit->nID;
			// 目的地是所带资源的家
			Task.nParam1 = TY_FindNearHome(pUnit->Draw.nPlayer,pUnit->Draw.nX, pUnit->Draw.nY, pUnit->Soldier.nResType);
			if( Task.nParam1 == MAP_DATA_NONE )
			{	// 如果没有老家,则结束命令
				Task.nTaskID = JIESHU;
			}
			else
			{
				Task.nTaskID = HUISONG;
				Task.nTaskIDEx = 2;	// MOUSE_HITRESULT_UNIT
				Task.nTaskIDEx2 = pUnit->Task.nTaskIDEx2;	// 保存资源类型
				if( pUnit->Task.nTaskIDEx == 1 )	// MOUSE_HITRESULT_GROUND
				{
					Task.nParam2 = pUnit->Task.nParam1;		// 原来资源的位置Z
					Task.nParam3 = pUnit->Task.nParam2;		// 原来资源的位置X
					Task.nParam4 = pUnit->Task.nParam3;		// 原来资源的位置Y
				}
				else
				{
					Task.nParam4 = pUnit->Task.nParam1;		// 保存原来的资源建筑ID
				}
				Assert( Task.nParam1 != MAP_DATA_NONE );
			}
			Task.bDone = TRUE;
			CTRL_TASK_DeployByComputer( pUnit->Draw.nPlayer, &Task );
			return;
		}

		if( (pUnit->Task.nTaskID == XIULI
			|| (pUnit->Task.nTaskID == YIDONG && pUnit->Task.nTaskIDEx == 2) )
			&& EYE_IfUnitIsWorker( pUnit ) 
			&& pUnit->Soldier.nResType != QXZIYUAN
			&& pUnit->Soldier.nResource > 0 )
		{	// 把工人任务变为回送
			struct UNIT_STRUCT *pU = MAP_GetUnit( pUnit->Task.nParam1 );
			Assert( pU );
			if( !EYE_IfUnitIsDead( pU ) 
				&& EYE_IfUnitIsBuild( pU ) && (pU->Draw.nPlayer == pUnit->Draw.nPlayer) )
			{
				int nRes = EYE_GetUResHome( pU );
				if( nRes == pUnit->Soldier.nResType || nRes == SUOYOUZY 
					|| (nRes == MAITIAN && pUnit->Soldier.nResType == LIANGCANG) ) 
				{
					struct CTRL_TASK_STRUCT Task;
					CTRL_TASK_Clear( &Task );
					Task.nID = pUnit->nID;
					Task.nTaskID = HUISONG;
					Task.nTaskIDEx = 2;
					Task.nTaskIDEx2 = pUnit->Soldier.nResType;	// 保存资源类型
					if( pUnit->Soldier.nResType == 0 
						|| pUnit->Soldier.nResType == 1 )
					{	// 地形类型资源
						Task.nParam2 = pUnit->Draw.nLayer;
						Task.nParam3 = pUnit->Draw.nX;
						Task.nParam4 = pUnit->Draw.nY;
					}
					else
					{	// 建筑类型资源
						Task.nParam4 = MAP_DATA_NONE;
					}
					Task.nParam1 = pUnit->Task.nParam1;		// 目的单元ID
					Assert( Task.nParam1 != MAP_DATA_NONE );
					Task.bDone = TRUE;

					// 发送
					CTRL_TASK_DeployByComputer( pUnit->Draw.nPlayer, &Task );
					return;
				}
			}
		}

		// set status to unit
		CTRL_TASK_Copy( &pUnit->Status, &pUnit->Task );

		// change status if needed
		// 对于多状态任务,设置其第一状态为移动
//		if( pUnit->Status.nTaskID == JIANZAO )	// 建造
//			pUnit->Status.nTaskIDEx = 1; //MOUSE_HITRESULT_GROUND,设置目的地类型

		if( pUnit->Status.nTaskID == XIULI )	// 修理
			Assert( pUnit->Status.nTaskIDEx == 2 );
//			pUnit->Status.nTaskIDEx = 2; //MOUSE_HITRESULT_GROUND,设置目的地类型

		// 卸载,当nTaskIDEx2为0时,要先移动后卸载
		if( pUnit->Status.nTaskID == XIEZAI 
			&& pUnit->Status.nTaskIDEx2 == 0 )
		{
			pUnit->Status.nTaskID = YIDONG;
		}
		if( pUnit->Status.nTaskID == YUNZAI
			&& !(EYE_IfUnitIsTransport( pUnit ) 
				&& pUnit->Status.nTaskIDEx2 == 1) )
		{
			pUnit->Status.nTaskID = YIDONG;
		}

		if( !EYE_IfUnitIsBuild( pUnit ) )
		{
			switch( pUnit->Status.nTaskID )
			{
			case	JIANZAO:	// 建造
			case	GONGJI:		// 攻击
			case	YUNSONG:	// 运送
			case	XIULI:		// 修理
			//case	ZHENXING:	// 阵型
			//case	DANTIAO:	// 单挑
			case	HUISONG:	// 回送
				pUnit->Status.nTaskID = YIDONG;
				break;
			}
		}

		// 设置动画帧状态
		if( pUnit->Status.nTaskID == YIDONG
			&& EYE_IfUnitIsWorker( pUnit ) 
			&& pUnit->Soldier.nResource > 0 )
		{
			if( pUnit->Soldier.nResType == SHULIN )	// 树林
			{
				pUnit->Draw.nState = pUnit->Draw.nDir+
					MAP_Lib.AniSeq[pUnit->Draw.nFile].nEventBegin[3];
			}
			else if( pUnit->Soldier.nResType == MAITIAN		// 麦田
				|| pUnit->Soldier.nResType == LIANGCANG )	// 粮仓
			{
				pUnit->Draw.nState = pUnit->Draw.nDir+
					MAP_Lib.AniSeq[pUnit->Draw.nFile].nEventBegin[5];
			}
			else if( pUnit->Soldier.nResType == TIEKUANG )	// 铁矿
			{
				pUnit->Draw.nState = pUnit->Draw.nDir+
					MAP_Lib.AniSeq[pUnit->Draw.nFile].nEventBegin[4];
			}
			else	// 一般状态
			{
				pUnit->Draw.nState = pUnit->Draw.nDir;
			}
		}
		else	pUnit->Draw.nState = pUnit->Draw.nDir;
		if( !EYE_IfUnitIsBuild( pUnit ) )
		{
			pUnit->Draw.nFrame = 1;
			pUnit->Draw.nCol = MAP_Lib.AniSeq[pUnit->Draw.nFile].nAniSeq[pUnit->Draw.nState][pUnit->Draw.nFrame]+
				MAP_Lib.AniSeq[pUnit->Draw.nFile].nOffset;
			pUnit->Draw.nRow = 0;
		}
		// 对于移动状态,行军算法
		if( pUnit->Status.nTaskID == YIDONG )
		{
			int nEndx, nEndy, nEndZ;
			WORD codeG;

			Assert( pUnit->Status.nParam2 <= MAP_Lib.szNum.cx );	// 层号
			Assert( pUnit->Status.nParam3 <= MAP_Lib.szNum.cy );	// 层号

			// 如果目的地和出发点一样,则状态结束,不结构化
			if( pUnit->Draw.nX == pUnit->Status.nParam2 && pUnit->Draw.nY == pUnit->Status.nParam3 )
			{
				pUnit->Status.bDone = TRUE;
				return;
			}

			BOOL bShouldDuSe = TRUE;	// 当目的地到达不了时是否设置堵塞标志
			if( pUnit->Status.nTaskIDEx == 1 )	// hit ground
			{
				POINT ptNew = MAP_FindRegion( pUnit->Status.nParam1, pUnit->Status.nParam2,pUnit->Status.nParam3, MAP_Lib.Unit[pUnit->Draw.nFile].nItems[0], pUnit->nID );
				//Assert( ptNew.x!=-1 && ptNew.y!=-1 );
				if( ptNew.x == -1 || ptNew.y == -1 )
				{
					ptNew.x = pUnit->Status.nParam2,
					ptNew.y = pUnit->Status.nParam3;
					bShouldDuSe = FALSE;// 如果没在附近找到可以到达的目的地,则不设置预堵塞
				}
				nEndZ = pUnit->Status.nParam1;
				nEndx = ptNew.x,
				nEndy = ptNew.y;

				// 修改层号
				for(;;)
				{	

					codeG = MAP_GetGroundData( nEndZ, nEndx, nEndy );
					if( codeG != MAP_DATA_NONE )
						break;
					if( nEndZ == 0 && codeG == MAP_DATA_NONE )
					{
						Assert(0);
						break;
					}
					nEndZ--;
				}
			}
			else if( pUnit->Status.nTaskIDEx == 2 )	//hit unit
			{
				Assert( pUnit->Status.nParam1 != MAP_DATA_NONE );
				struct UNIT_STRUCT *pUnitE = MAP_GetUnit( pUnit->Status.nParam1 );
				POINT ptNew = MAP_FindRegion( pUnitE->Draw.nLayer, pUnitE->Draw.nX, pUnitE->Draw.nY, MAP_Lib.Unit[pUnit->Draw.nFile].nItems[0], pUnit->nID );
				//Assert( ptNew.x!=-1 && ptNew.y!=-1 );
				if( ptNew.x == -1 )
				{
					ptNew.x = pUnit->Status.nParam2,
					ptNew.y = pUnit->Status.nParam3;
					bShouldDuSe = FALSE;// 如果没在附近找到可以到达的目的地,则不设置预堵塞
				}
				nEndZ = pUnitE->Draw.nLayer;
				nEndx = ptNew.x, 
				nEndy = ptNew.y;

				// 修改层号
				for(;;)
				{	
					codeG = MAP_GetGroundData( nEndZ, nEndx, nEndy );
					if( codeG != MAP_DATA_NONE )
						break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -