📄 cbctrl.cpp
字号:
/////////////////
// CBCtrl.cpp : 《赤壁》全局控制数据结构
// CBCtrl.cpp : << chibi >> global contral data structure
//
// v0010 : Oct.3.1996
// v0011 : Oct.18.1996
// v0012 : Jan.25.1997
// v0013 : Feb.5.1997
// v0020 : Mar.29.1997, add most controls
// v0021 : Apr.2.1997, add deploy asserts
// v0030 : May.16.1997, add Block(), OpenDoor(), etc. changed a lot
// v0031 : Sep.11.1997, changed a lot
//
// 编写 : 刘刚
// written by : Liu Gang
//
// 编译器 : Visual C++ 4.2
// Compiler : Visual C++ 4.2
//
// 版权 : 北京前导软件有限公司 1996-1997
// Copyright : WayAhead Co.Ltd. 1996-1997
/////////////////
// 此文件包含游戏的控制结构(命令,状态,帧)的产生,以及对任务缓冲区队列的操作
#include "stdafx.h"
#include "CBCtrl.h"
#ifndef _CTRL_DEBUG
#include "Assert.h"
#include "CBMap.h"
#include "CBData.h"
#include "CBGame.h" // 使用GAME.Me用来判断是否是游戏者
#include "CBMouse.h"
#include "CbEyes.h" // 检测函数
#include "CBShadow.h" // SHADOW_IfEnabled()
//#include "CBRun.h" // RUN_CREATE_IfEnoughMoney()
#include "CBRDelay.h"
#include "DDCompo.h"
// LHJ
#include "marco.h"
#include "interfa1.h"
#include "interfac.h"
#include "cbprompt.h"
// LHJ
// TY
#include "TbnBase.h"
#include "Temperor.h"
// TY
#include "CBBuild.h"
#include "CBRDelay.h" // defines
#include "CBOther.h"
#include "CBDraw.h" // DRAW_JumpScreen()
#endif
// debug only
#include <stdio.h>
//////////////////////
// externals
// defined in CBDraw.cpp
extern RECT DRAW_rcScreen; // defined in CBDraw.cpp
extern POINT DRAW_ptScreenOffset; // defined in CBDraw.cpp
extern int MAP_nLocationNum[4]; // defined in CBMap.cpp
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX]; // defined in CBMap.cpp
// defined in CBDraw.cpp
// 被选中为目的地的单元,要闪烁显示它的边界
extern int DRAW_BLINK_nCounter;
extern int DRAW_BLINK_nDelay;
extern BOOL DRAW_BLINK_bDraw;
extern WORD DRAW_BLINK_nID;
extern int DRAW_BLINK_nSave;
//////////////////////
//////////////////////
// defines
#define CTRL_TIMEDELAY_COMMAND 200 // 两个右键命令的间隔时间(毫秒)
#define CTRL_TIMEDELAY_MOUSE 2 // 目标右键点击后所遗留下来的痕迹
//////////////////////
//////////////////////
// 命令处理流水线,关于命令流水线的所有函数都是本文件内部的
// 全局量
// 指示任务队列的尾端位置
// points to the Task List's tail
int CTRL_nTaskTail[GAME_PLAYER_MAX]={0,0,0,0,0};
// 指向下一个有效命令的位置
int CTRL_nTaskHead[GAME_PLAYER_MAX]={0,0,0,0,0};
// First demension: 0-4 are the Waiting List of player 0-4
// 第一个下标:0-4代表游戏者0-4的等待队列
struct CTRL_TASK_STRUCT CTRL_TaskList[GAME_PLAYER_MAX][CTRL_TASK_LIST_MAX+CTRL_TASK_LIST_MAX];
// 用来保存当前的命令组
struct CTRL_TASK_SAVE_CMDUNIT CTRL_TASK_saveCmdUnit;
//////////////////////
// local functions
// get contents from Task List
// nPlayer : player's ID, 0-4 are player 0-4
// pTask : the Task you got
// return vlaue : TRUE if get one
extern BOOL CTRL_TASK_LIST_Peek( int nPlayer, struct CTRL_TASK_STRUCT *pTask ); // 取得任务返回真
// store contents to Task List
// nPlayer : player's ID, 0-4 are player 0-4
// pTask : the Task you want to send
// return vlaue : TRUE if there is room for the Task
extern BOOL CTRL_TASK_LIST_Send( int nPlayer, CONST struct CTRL_TASK_STRUCT *pTask ); // 发送任务返回真
extern BOOL CTRL_TASK_LIST_SendEx( int nPlayer, CONST struct CTRL_TASK_STRUCT *pTask, int nIndex ,int nTail);
// copy list
// nFrom : ID for Task List to copy from
// nTo : ID for Task List to copy to
extern void CTRL_TASK_LIST_Copy( int bTo, int nFrom );
// clear list
// nList : number of list to cleared
extern void CTRL_TASK_LIST_Clear( int nList );
//////////////////////
//////////////////////
// 鼠标痕迹
void CTRL_MOUSE_Clip( int nX, int nY );
//////////////////////
//////////////////////
// 音效
// 选中某个单元后
// nFile : 单元的文件号
void CTRL_SOUND_select( int nFile );
// 对某个单元下达命令后
// nFile : 单元的文件号
void CTRL_SOUND_doIt( int nFile );
//////////////////////
//////////////////////
// 调试命令用
BOOL CTRL_bDebugCommand = FALSE;
BOOL CTRL_bDebugDie = FALSE;
//////////////////////
///////////////////////////////////Donghai//////////////////////////////////////
#include "network.h"
extern BYTE DP_SendMessageBuff[BUFFER_MAX_BYTE];
extern int DP_NetworkInterface(int Action, HWND MainWndHandle);
int CB_SendTaskMessage(int nPlayer, CONST struct CTRL_TASK_STRUCT *pTask);
extern int CB_Counter;
///////////////////////////////////Donghai//////////////////////////////////////
//////////////////////
// 任务处理
//////////////////////
// get contents from Task List
// nPlayer : player's ID, 1-4 are player 1-4, 0 is my Waiting List
// pTask : the Task you got
// return value : TRUE if get one
inline BOOL CTRL_TASK_LIST_Peek( int nPlayer, struct CTRL_TASK_STRUCT *pTask )
{
// 判断队列是否是空的
if( CTRL_nTaskTail[nPlayer] == CTRL_nTaskHead[nPlayer] )
return FALSE;
int nHead = CTRL_nTaskHead[nPlayer];
struct CTRL_TASK_STRUCT *pTaskSrc = &CTRL_TaskList[nPlayer][nHead];
//Assert( pTaskSrc->nTaskID != QUXIAO );
// 从任务队列中读取
CTRL_TASK_Copy( pTask, pTaskSrc );
// 从队列中删除
CTRL_TASK_Clear( pTaskSrc );
// 头指针移动
nHead++;
if( nHead == CTRL_TASK_LIST_MAX )
{
nHead = 0;
}
CTRL_nTaskHead[nPlayer] = nHead;
return TRUE;
}
// store contents to Task List
// nPlayer : player's ID, 1-4 are player 1-4, 0 is my Waiting List
// pTask : the Task you want to send
// return vlaue : TRUE if there is room for the Task
inline BOOL CTRL_TASK_LIST_Send( int nPlayer, CONST struct CTRL_TASK_STRUCT *pTask )
{
// 队列尾指针移动
int nTail = CTRL_nTaskTail[nPlayer];
nTail++;
if( nTail == CTRL_TASK_LIST_MAX )
nTail = 0;
// 判断队列是否已满
if( nTail == CTRL_nTaskHead[nPlayer] )
return FALSE;
// 存储任务到队列中
struct CTRL_TASK_STRUCT *pTaskDest = &CTRL_TaskList[nPlayer][CTRL_nTaskTail[nPlayer]];
CTRL_TASK_Copy( pTaskDest, pTask );
CTRL_nTaskTail[nPlayer]=nTail;
return TRUE;
}
// store contents to Task List
// nPlayer : player's ID, 1-4 are player 1-4, 0 is my Waiting List
// pTask : the Task you want to send
// return vlaue : TRUE if there is room for the Task
inline BOOL CTRL_TASK_LIST_SendEx( int nPlayer, CONST struct CTRL_TASK_STRUCT *pTask, int nIndex ,int nTail)
{
// 存储任务到队列中
struct CTRL_TASK_STRUCT *pTaskDest = &CTRL_TaskList[nPlayer][nIndex];
CTRL_TASK_Copy( pTaskDest, pTask );
CTRL_nTaskTail[nPlayer]=nTail;
/////////////////////////////Donghai/////////////////////////////
// char test32[255];
// wsprintf((char *)test32,"================================%d!!!================================\n",CB_Counter);
// WriteLogFile("Test_Sendex.log",(char *)test32);
/////////////////////////////Donghai/////////////////////////////
return TRUE;
}
// copy
// nFrom : ID for Task List to copy from
// nTo : ID for Task List to copy to
inline void CTRL_TASK_LIST_Copy( int nTo, int nFrom )
{
memcpy( CTRL_TaskList[nTo], CTRL_TaskList[nFrom], sizeof(struct CTRL_TASK_STRUCT)*CTRL_TASK_LIST_MAX );
}
// clear list
// nList : number of list to cleared
inline void CTRL_TASK_LIST_Clear( int nList )
{
memset( CTRL_TaskList[nList], 0, sizeof(struct CTRL_TASK_STRUCT)*CTRL_TASK_LIST_MAX );
}
//////////////////////
//////////////////////
// 命令的产生
#ifdef _DEBUG
// 当调用CTRL_TASK_LIST_Send()时,即对任务队列进行读操作时,
// 一定不要进行写操作。保证在处理命令时的同步性。
// 当调用CTRL_TASK_Main()时,该Flag标志为真,
// 当调用CTRL_TASK_LIST_Send()时,判断该标志量。
BOOL CTRL_TASK_Reading = FALSE;
#endif // _DEBUG
// mouse hit result
// 命令的主体的计数器
int CTRL_nHitCounter=0;
// contains the units player want to send command to
// 命令的主体
// 只有nID有用
struct CTRL_TASK_STRUCT CTRL_hitSrc[CTRL_TASK_LIST_MAX-1];
// the target unit
// 命令的客体,命令的内容也存放在此
struct CTRL_TASK_STRUCT CTRL_hitDest;
// Set Task from Task List to unit
// task : Task to be set
void CTRL_TASK_SetToUnit( struct CTRL_TASK_STRUCT task );
//////////////////////
//////////////////////
// get soldier number that focus on
// 得到处于焦点状态的士兵的数量
// return : soldier number, in person
int CTRL_GetFocusSoldierNumber()
{
// 得到士兵数
int nCount=0;
for( int i=0; i< CTRL_nHitCounter; i++ )
{
Assert( CTRL_hitSrc[i].nID != MAP_DATA_NONE );
struct UNIT_STRUCT *pUnit = MAP_GetUnit( CTRL_hitSrc[i].nID );
// 极少出现的现象,士兵已经准备死亡,可是还没有从选中数组中清空
if( EYE_IfUnitIsDead( pUnit ) )
break;
// if( pUnit == NULL )
// WriteLogFile( "Test.log", "CTRL_GetFocusSoldierNumber()\n" );
Assert( pUnit );
Assert( pUnit->nType != 0 );
if( EYE_IfUnitIsSoldier( pUnit ) )
nCount += pUnit->nLife;
Assert( nCount >= 0 && nCount <= 99999 );
}
return nCount;
}
// clear assembling parameters
// 清除CTRL_hitSrc的内容
// bForce : 强迫清除所有内容
// bForce : 为真时,强迫清空任务队列中的所有结点;
// 否则,只有该任务不完整时才会被清空。
void CTRL_TASK_ClearAssembleSrc( BOOL bForce /*=FALSE*/ )
{
// clear Focus to units, clear hittest source objects
int nCounter = CTRL_nHitCounter;
for( int i=0; i< nCounter; i++ )
{
if( CTRL_hitSrc[i].bDone && !bForce ) continue;
Assert( CTRL_hitSrc[i].nID != MAP_DATA_NONE );
struct UNIT_STRUCT *pUnit = MAP_GetUnit( CTRL_hitSrc[i].nID );
Assert(pUnit);
pUnit->Draw.bUpdate = FALSE; // 去掉选中框
// clear source objects
CTRL_TASK_Clear( &CTRL_hitSrc[i] );
CTRL_nHitCounter --;
}
// clear build drawings
if( BUILD_IfEnable() )
BUILD_Enable( FALSE );
// CTRL_TASK_saveCmdUnit.Cmd = COMMANDUNIT_NONE;
// CTRL_TASK_saveCmdUnit.Ex = 0xFFFFFFFF;
// CTRL_TASK_saveCmdUnit.Busy = 0;
#ifdef _DEBUG
if( bForce ) Assert( CTRL_nHitCounter == 0 );
#endif
}
void CTRL_TASK_ClearAssembleDest()
{
// clear command
// clear hittest destination object and command
CTRL_TASK_Clear( &CTRL_hitDest );
// reset command unit array
/* if( CTRL_TASK_saveCmdUnit.Busy == 1 )
{
FACE_ShowCommandUnit( COMMANDUNIT_CANCEL, 0xFFFF ); // clear command sets
}
else
{
FACE_ShowCommandUnit( CTRL_TASK_saveCmdUnit.Cmd, CTRL_TASK_saveCmdUnit.Ex ); // clear command sets
}
*/
// 重新设置鼠标光标形状
MOUSE_SetState( MOUSE_STATE_NONE );
}
// 设置建筑的命令组
//void CTRL_TASK_BuildCommand( int nFile )
void CTRL_TASK_BuildCommand( struct UNIT_STRUCT *pUnit )
{
Assert( EYE_IfUnitIsBuild( pUnit ) );
switch( pUnit->Draw.nFile )
{
case 0: // 帅帐1
CTRL_TASK_saveCmdUnit.Cmd = COMMANDUNIT_CHAO_MAINBUILDING;
// 基本配置
CTRL_TASK_saveCmdUnit.Ex = 0x0001;
//if( GAME.Players[GAME.nMe].nGrade[PLAYER_GRADE_MAIN] == 0
if( pUnit->Build.dwUpgrade[0] == 0
&& GAME.Players[GAME.nMe].nTechLvl >= 2
&& BuildPoint[GAME.nMe][MUCAICHANG].hPos == CBTRUE
&& BuildPoint[GAME.nMe][WUQICHANG].hPos == CBTRUE )
{ // 当前等级是0,最高等级大于1,有木材场,有武器场
CTRL_TASK_saveCmdUnit.Ex = 0x0003; //0011
}
//else if( GAME.Players[GAME.nMe].nGrade[PLAYER_GRADE_MAIN] == 1
else if( pUnit->Build.dwUpgrade[0] == 1
&& GAME.Players[GAME.nMe].nTechLvl >= 3
&& BuildPoint[GAME.nMe][QIBINGSUO].hPos == CBTRUE
&& BuildPoint[GAME.nMe][CHEBINGSUO].hPos == CBTRUE )
{ // 当前等级是1,最高等级大于2,有骑兵所,有车兵所
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -