📄 cbgame.cpp
字号:
/////////////////
// CBGame.cpp : 《赤壁》全局数据结构
// CBGame.cpp : << chibi >> global data structure
//
// v0011 : Oct.18.1996
// v0012 : Nov.28.1996
// v0013 : Feb.5.1997, changed setunitdata() part in GAME_ReadMedFile()
// add function GAME_ReadMedHeader()
// v0020 : Feb.28.1997, add function named DATA_ReadDATAFile()
//
// v0030 : May.2.1997, add save&load file, read&write option file functions
// v0031 : May.14.1997, add some values in main structure: nBuildType, nMusicID
//
// 编写 : 刘刚
// 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 <stdio.h>
#include "Assert.h"
#include "CBGame.h"
#include "CBMap.h"
#include "CBEyes.h"
#include "CBMini.h"
#ifdef _GAME_
#include "CBData.h"
#include "CBDraw.h"
#include "CBCtrl.h"
#include "CBOther.h"
#include "CBMouse.h"
#include "CBShadow.h"
#include "CBeyes.h"
#include "CBEvent.h"
#include "CBRun.h"
// TY
#include "Temperor.h"
// LWC
#include "l_save.h" // GAME_Save(), GAME_Load()
#include "l_scan.h"
// LHJ
#include "cbprompt.h" // PROMPT_BLOCK
#include "marco.h" // BUTTON_UP BUTTON_DISABLE
#include "interfac.h" // FACE_SetNumberButtonState()
#include "interfa1.h" // FACE_ShowCommandUnit()
// end
#include "ddcompo.h"
#include "mciapi.h"
#include "dsapi.h"
#endif
///////////
// 全局量
//DH
// 网络,Nov.4.1997, LG & LHJ
BOOL GAME_bNetwork=FALSE;
BOOL GAME_bNetPlayerOK[GAME_PLAYER_MAX];// 确认连接完成
//DH
// Nov.7.1997
// CBData.cpp
extern BOOL MUSIC_bEnable; // 是否播放CD
extern BOOL EFFECT_bEnable; // 是否播放音效
// Nov.9.1997
// CbCtrl.cpp
// 指示任务队列的尾端位置
// points to the Task List's tail
extern int CTRL_nTaskTail[GAME_PLAYER_MAX];
// 指向下一个有效命令的位置
extern int CTRL_nTaskHead[GAME_PLAYER_MAX];
struct GAME_STRUCT GAME;
// 缺省时的保存数据的代号
int GAME_nSlot = 99;
// Nov.7.1997
// 游戏是豪华版时用来区分A盘和B盘
// 是0则不区分,是1为A盘,是2为B盘
int GAME_nDisk = 0;
// Nov.7.1997
// 计算得到存盘文件名
void GAME_MakeSaveName( int nSlot, LPCTSTR tail, LPSTR filename );
char GAME_strSetupDirectory[_MAX_PATH]; // 游戏安装路径
BOOL GAME_bBegin = FALSE;
BOOL GAME_bDebugStage = FALSE;
struct GAME_TIME_STRUCT GAME_Time;
SYSTEMTIME TimeSub( SYSTEMTIME time1, SYSTEMTIME time2 );
///////////
#define GAME_INIT_GOLD 20000
#define GAME_INIT_FOOD 10000
#define GAME_INIT_WOOD 10000
#define GAME_INIT_IRON 10000
///////////
// 外部量
// 保存地形图素数据
extern WORD MAP_wGroundData[MAP_DATA_THICK][MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 保存单元图素数据
extern WORD MAP_wUnitData[MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 保存区域数据
extern WORD MAP_wRegionData[MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// defined in CBCtrl.cpp
// mouse hit result
// 命令的主体的计数器
extern int CTRL_nHitCounter;
// contains the units player want to send command to
// 命令的主体
// 只有nID有用
extern struct CTRL_TASK_STRUCT CTRL_hitSrc[CTRL_TASK_LIST_MAX-1];
// the target unit
// 命令的客体,命令的内容也存放在此
extern struct CTRL_TASK_STRUCT CTRL_hitDest;
// 战场的调色板
extern CDDPalette palMain; // defiend in CbMain.cpp
// LHJ
// declared in CBprompt.cpp
// the current prompt block
extern struct PROMPT_BLOCK FACE_CURRENT_PROMPT_BLOCK;
// declared in Interfa1.cpp
// to store these value for the command unit when save and load
extern int FACE_CurrentCommandUnitID;
extern DWORD FACE_CurrentCommandUnitFlag;
// LHJ
///////////
// 用来保存当前的命令组
extern struct CTRL_TASK_SAVE_CMDUNIT CTRL_TASK_saveCmdUnit; // defined in CBCtrl.cpp
// 是否自动运行所有君主的策略
extern BOOL RUN_bAUTO; // declared in CBRun.cpp
///////////
// declared in CBRun.cpp, location function
// 当前状态是ZUJIAN或JIARU时调用
void RUN_GroupUnit( struct UNIT_STRUCT *pUnit );
///////////
///////////
// 初始化
void GAME_InitGame()
{
memset( &GAME, 0, sizeof(struct GAME_STRUCT ) );
for( int i=0; i< GAME_PLAYER_MAX; i++ )
{
//设置部队数组为空
memset( GAME.Players[i].wGroup, MAP_DATA_NONE, sizeof( WORD)*PLAYER_GROUP_MAX );
}
}
void GAME_InitGamePlayers()
{
for( int i=0; i< GAME_PLAYER_MAX; i++ )
{
memset( &GAME.Players[i], 0, sizeof(struct PLAYER_STRUCT ) );
//设置部队数组为空
memset( GAME.Players[i].wGroup, MAP_DATA_NONE, sizeof( WORD)*PLAYER_GROUP_MAX );
}
}
///////////
///////////
// 读取各种设置数据文件
// hwnd : window to receive error message
// return : TRUE if successful
BOOL GAME_ReadCBSetFile( HWND hwnd )
{
char fname[65];
#ifdef _MAP_COMPRESS_
strcpy( fname, "CB.set" );
#else
strcpy( fname, "CB.set" );
#endif
FILE * fp = fopen( fname, "rb" );
if( !fp )
{
ErrorMessage( hwnd, GAME_ERROR_ID+0,"Cannot open Chi Bi set file: ", fname );
return FALSE;
}
// read item size
fscanf( fp, "%d,%d,", &MAP_Lib.szItem.cx, &MAP_Lib.szItem.cy );
if( MAP_Lib.szItem.cx>MAP_ITEM_WIDTH || MAP_Lib.szItem.cy>MAP_ITEM_HEIGHT )
{
ErrorMessage( hwnd, GAME_ERROR_ID+1, "Map item is too large, change setup again." );
MAP_Lib.szItem.cx = MAP_ITEM_WIDTH, MAP_Lib.szItem.cy = MAP_ITEM_WIDTH;
}
// read item heights
fscanf(fp,"%d,%d,%d,%d\n",&MAP_Lib.nHeight[0],&MAP_Lib.nHeight[1],&MAP_Lib.nHeight[2],&MAP_Lib.nHeight[3]);
// read game options
// 运行速度
// 滚屏速度
// 音效的音量大小,range from 0 to -5000,1时关闭
// 音乐的音量大小,range from 0 to -5000,1时关闭
// AVI的开关
// fscanf(fp,"%d,%d,%d,%d,%d\n",
// &GAME.nSpeed, &GAME.nSpeedScroll, &GAME.nVolume, &GAME.nVolumeCD, &GAME.bFightEnabled );
// read path of each kind of data file
char file[_MAX_PATH];
fscanf(fp,"%s\n", GAME.strPathMED );
fscanf(fp,"%s\n", GAME.strPathDAT );
fscanf(fp,"%s\n", GAME.strPathBMP );
fscanf(fp,"%s\n", GAME.strPathAVI );
fscanf(fp,"%s\n", GAME.strPathWAV );
// read ground map item data file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadGroundFile( hwnd, file, GAME.strPathDAT, GAME.strPathBMP ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(0): read ground file error!\n" );
return FALSE;
}
// read unit map item data file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadUnitFile( hwnd, file, GAME.strPathDAT, GAME.strPathBMP ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(1): read Unit file error!\n" );
return FALSE;
}
// read special ground data file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadSpecFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(2): read special file error!\n" );
return FALSE;
}
// read senser file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadSenserFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(3): read senser file error!\n" );
return FALSE;
}
// read BTL initialization file name
// in order to be compatible with MapEditer, cannot read med file directly
fscanf( fp, "%s\n", GAME.strNameBTL );
// read Animation data file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadAniSeqFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(4): read animation sequency file error!\n" );
return FALSE;
}
// read animation data file extensional
fscanf( fp, "%s\n", file );
if( !::MAP_ReadAniSeqFileEx( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(8): read animation sequency extension file error!\n" );
return FALSE;
}
// read wave data file
fscanf( fp, "%s\n", file );
if( !::DATA_ReadWAVEFile( hwnd, file, GAME.strPathDAT, GAME.strPathWAV ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(11): read wave file error!\n" );
return FALSE;
}
// read game option data file
fscanf( fp, "%s\n", GAME.strNameOPT );
if( !GAME_ReadOptionFile( hwnd, GAME.strNameOPT, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(12): read game option error!\n" );
return FALSE;
}
// read others file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadOtherFile( hwnd, file, GAME.strPathDAT, GAME.strPathBMP ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(9): read cover file error!\n" );
return FALSE;
}
// read Cover data file
fscanf( fp, "%s\n", file );
if( !::DRAW_ReadCoverFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(5): read cover file error!\n" );
return FALSE;
}
// read mini map data file
fscanf( fp, "%s\n", file );
if( !::MAP_ReadMiniFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(6): read minimap file error!\n" );
return FALSE;
}
// read data file
fscanf( fp, "%s\n", file );
if( !::DATA_ReadDATAFile( hwnd, file, GAME.strPathDAT ) )
{
OutputDebugString( "GAME_ReadCBSetFile Error(7): read data file error!\n" );
return FALSE;
}
// read if debug each stage
fscanf( fp, "%d\n", &GAME_bDebugStage );
fclose( fp );
return TRUE;
} // end of GAME_ReadCBSetFile()
///////////
///////////
// 读取战场初始化数据文件
// hwnd : window to receive error message
// nBattle : battle number
// filename : battle field data file name
// path : battle field data file path
// return : TRUE if successful
BOOL GAME_ReadBTLFile( HWND hwnd, int nBattle, LPCTSTR filename, LPCTSTR path )
{
char fname[65];
// FILE * fp;
int i, j, k;
int nNum, nNum2, nNum3, nNum4, nNum5, nNum6;
CScan_read FSCAN;
if( path != 0 )
{
strcpy( fname, path );
strcat( fname, filename );
}
else strcpy( fname, filename );
FSCAN.scan_open (fname);
/*
fp = fopen( fname, "rt" );
if( !fp )
{
ErrorMessage( hwnd, GAME_ERROR_ID+2,"Cannot open Med file: ", fname );
return FALSE;
}
*/
// if( GAME.nMe == 3 ) // 曹操
// nBattle += 17;
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d\n", &nNum ));
//fscanf( fp, "%d\n", &nNum );
Assert( nBattle < nNum );
if( nBattle >= nNum )
{
ErrorMessage( hwnd, GAME_ERROR_ID+4,"battle ID is out of range! ", fname );
return FALSE;
}
// 预读前面的数据,无用
int nTemp;
char strTemp[65];
for( i=0; i<nBattle; i++ )
{
// 读取本关ID和君主数,本关背景音乐ID
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,%d,%d\n", &nNum2, &nNum3, &nTemp ));
//fscanf( fp, "%d,%d,%d\n", &nNum2, &nNum3, &nTemp );
// 读取战场图文件和AVI文件名
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%s %s\n", &strTemp, strTemp ));
//fscanf( fp, "%s %s\n", &strTemp, strTemp );
for( j=0; j<nNum3; j++ )
{
// 读取君主的ID,战场类型,技术级别
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,", &nNum4 ));
//fscanf( fp, "%d,", &nNum4 );
// nThink: 0为陆战,1为水战,2为无基地
// nTechLvl:
// nBuildType: 0为城内建筑,1为城外建筑
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,%d,%d\n",
&nTemp, &nTemp, &nTemp ));
//fscanf( fp, "%d,%d,%d\n",
// &nTemp, &nTemp, &nTemp );
// 读取初始资源,钱,粮,木,铁
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d, %d, %d, %d\n",
&nTemp, &nTemp, &nTemp, &nTemp ));
//fscanf( fp, "%d, %d, %d, %d\n",
// &nTemp, &nTemp, &nTemp, &nTemp );
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d, ", &nNum5 ));
//fscanf( fp, "%d, ", &nNum5 );
for( k=0; k<nNum5; k++ )
{
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,", &nNum6 ));
//fscanf( fp, "%d,", &nNum6 );
}
for( k=0; k<nNum5; k++ )
{
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,", &nNum6 ));
//fscanf( fp, "%d,", &nNum6 );
}
}
}
// 读取本关ID和君主数,本关背景音乐ID
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,%d,%d\n", &nNum2, &nNum3, &GAME.nMusicID ));
if( GAME_nDisk != 0 )
{
GAME.nMusicID=getrandom( 3, 15 );//背景音乐ID,可以给随机数
}
//fscanf( fp, "%d,%d,%d\n", &nNum2, &nNum3, &GAME.nMusicID );
Assert( nNum2 == i );
GAME.nID = nNum2;
// 读取战场图文件和AVI文件名
char strAVI[_MAX_FNAME];
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%s %s\n", GAME.strNameMED, strAVI ));
strcpy( GAME.strNameAVI, GAME_strSetupDirectory );
strcat( GAME.strNameAVI, "\\avi\\" );
strcat( GAME.strNameAVI, strAVI );
//fscanf( fp, "%s %s\n", GAME.strNameMED, GAME.strNameAVI );
for( j=0; j<nNum3; j++ )
{
// 读取君主的ID,战场类型,技术级别
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,", &nNum4 ));
//fscanf( fp, "%d,", &nNum4 );
int nPlayer = 0;
if(GAME_bNetwork==2)
{nPlayer = 1;}
if( j==nPlayer )
{
GAME.nMe = nNum4;
GAME.Players[nNum4].nType = PLAYER_TYPE_HUMAN;
}
else
{
GAME.Players[nNum4].nType = PLAYER_TYPE_COMPUTER;
}
// nThink: 0为陆战,1为水战,2为无基地
// nTechLvl:
// nBuildType: 0为城内建筑,1为城外建筑
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d,%d,%d\n",
&GAME.Players[nNum4].nThink,
&GAME.Players[nNum4].nTechLvl,
&GAME.Players[nNum4].nBuildType ));
/*
fscanf( fp, "%d,%d,%d\n",
&GAME.Players[nNum4].nThink,
&GAME.Players[nNum4].nTechLvl,
&GAME.Players[nNum4].nBuildType );
*/
GAME.Players[nNum4].nID=nNum4;
// 读取初始资源,钱,粮,木,铁
FSCAN.l_scan (sscanf (FSCAN.expand_buf,"%d, %d, %d, %d\n",
&GAME.Players[nNum4].nGold,
&GAME.Players[nNum4].nFood,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -