📄 cbother.cpp
字号:
/////////////////
// CBOther.cpp : v0020
// v0010 : Mar.21.1997
// v0020 : May.16.1997, add stone, fixed some bugs
// written by : Liu Gang
// Compiler : Visual C++ 4.2
// Copyright : WayAhead Software Co.Ltd. 1996-1997
/////////////////
// implementation file
// 弓箭,火,滚木,擂石,投石,血迹,爆炸,火攻,(雨,雪)等的数据结构
#include "stdafx.h"
#include "CBOther.h"
#include "Assert.h"
// only used by OTHER_Hit()
#include "CBMap.h"
#include "CBGame.h"
#include "CBCtrl.h"
#include "CBMouse.h"
#include "CBEYEs.h"
#include "CBData.h"
#include "CBMini.h" // MINI_SetBlink()
//added by tian yue
#include "tbnbase.h"
// LHJ
#include "Cbprompt.h"
// LHJ
// globals
/////////////////
struct OTHER_STRUCT OTHER[OTHER_MAX];
int OTHER_nCounter = 0;
#define OTHER_HUOGONG_RAND 300
/////////////////
// externals
/////////////////
extern POINT DRAW_ptScreenOffset; // defined in CBDraw.cpp
extern int CTRL_nHitCounter; // defined in CBCtrl.cpp
extern RECT DRAW_rcScreen; // defined in CBDraw.cpp
extern int CB_Counter;
// 判断如果单元生命小于0,对该单元下达删除命令
// 但只有当动画显示完全后,才真正调用CTRL_UNIT_Detroy()删除它
extern void RUN_UNIT_ToDie( struct UNIT_STRUCT *pUnit );
// defined in CBRunOT.cpp
// 受伤音效
// nX, nY : 位置
// nFile : 单元文件号
extern void RUN_SOUND_Wounded( int nX, int nY, int nFile );
// defined in CBRunOT.cpp
// 用于音效,每隔一定时间该开关打开,当屏幕以外的我方单元(部队/建筑)
// 受到攻击时,由画外音提醒游戏者We are under attack!
// nX, nY : 被攻击单元位置坐标
// nFile : 被攻击单元文件号
extern void RUN_SOUND_UnderAttack( int nX, int nY, int nFile );
// defined in CBCTRl.cpp, debug for do not die
extern BOOL CTRL_bDebugDie;
/////////////////
/////////////////
// initialize
void OTHER_InitOther()
{
OTHER_nCounter = 0;
memset( OTHER, 0, sizeof(OTHER_STRUCT)*OTHER_MAX );
}
/////////////////
/////////////////
//
#define OTHER_MOUSE_MAX 20
// 把数据设置到数组中
// pOther : source structure
// return : index in array, -1 if failed
int OTHER_CreateData( struct OTHER_STRUCT *pOther )
{
BOOL bSuccess = FALSE;
for( int i=0; i<OTHER_MAX-OTHER_MOUSE_MAX; i++ )
{
if( OTHER[i].nType == OTHER_TYPE_NONE )
{
bSuccess = TRUE; break;
}
}
if( bSuccess == TRUE )
{
memcpy( &OTHER[i], pOther, sizeof( OTHER_STRUCT ) );
OTHER[i].ptCur.x = OTHER[i].ptBegin.x,
OTHER[i].ptCur.y = OTHER[i].ptBegin.y;
OTHER_nCounter++;
#ifdef _DEBUG
// OutputDebugString( "OTHER_CreateData() Message:" );
// OutputString( OTHER_nCounter, "\n" );
#endif
/*
if( pOther->nType == OTHER_TYPE_HUOGONG )
{
char temp[128];
wsprintf( temp, "//---------------%d------------------//\n", CB_Counter );
WriteLogFile( "Net.log", temp );
WriteErrorFile( "Net.log", i );
}
*/
return i;
}
else return -1;
}
// 把数据设置到数组中
// 专门为鼠标设置,Dec.8.1997
// pOther : source structure
// return : index in array, -1 if failed
int OTHER_CreateDataEx( struct OTHER_STRUCT *pOther )
{
BOOL bSuccess = FALSE;
for( int i=OTHER_MAX-1; i>=OTHER_MAX-OTHER_MOUSE_MAX; i-- )
{
if( OTHER[i].nType == OTHER_TYPE_NONE )
{
bSuccess = TRUE; break;
}
}
if( bSuccess == TRUE )
{
memcpy( &OTHER[i], pOther, sizeof( OTHER_STRUCT ) );
OTHER[i].ptCur.x = OTHER[i].ptBegin.x,
OTHER[i].ptCur.y = OTHER[i].ptBegin.y;
OTHER_nCounter++;
#ifdef _DEBUG
// OutputDebugString( "OTHER_CreateData() Message:" );
// OutputString( OTHER_nCounter, "\n" );
#endif
/*
if( pOther->nType == OTHER_TYPE_HUOGONG )
{
char temp[128];
wsprintf( temp, "//---------------%d------------------//\n", CB_Counter );
WriteLogFile( "Net.log", temp );
WriteErrorFile( "Net.log", i );
}
*/
return i;
}
else return -1;
}
// 从数组中删除该内容,与CreateData对应
// nIndex : index in OTHER array
void OTHER_DestroyData( int nIndex )
{
#ifdef _DEBUG
if( nIndex < 0 )
{
OutputDebugString( "OTHER_DestroyData Error: index is less than 0!\n" );
return;
}
#endif
struct OTHER_STRUCT *pOther = &OTHER[nIndex];
#ifdef _DEBUG
if( pOther->nType == OTHER_TYPE_NONE )
OutputDebugString( "OTHER_DestroyData Warning: has been cleared!\n" );
#endif
OTHER_nCounter--;
memset( pOther, 0, sizeof( OTHER_STRUCT ) );
}
// 初始化结构
// pOther : source structure
void OTHER_ClearData( struct OTHER_STRUCT *pOther )
{
memset( pOther, 0, sizeof( OTHER_STRUCT ) );
}
/////////////////
/////////////////
// 移动该内容
// index : index in array
// return : TRUE if hit
BOOL OTHER_Move( int nIndex )
{
#ifdef _DEBUG
if( nIndex < 0 )
{
OutputDebugString( "OTHER_Move Error: index is less than 0!\n" );
return FALSE;
}
#endif
struct OTHER_STRUCT *pOther = &OTHER[nIndex];
switch( pOther->nType )
{
case OTHER_TYPE_FIRE:
// 对于火,要不断燃烧,直到从外部把它删除
if( pOther->nCounter>=pOther->nDelay )
{
pOther->nCounter = 0;
Assert( pOther->nMaxFrame );
pOther->nFrame = (pOther->nFrame+1)%pOther->nMaxFrame;
}
pOther->nCounter++;
break;
case OTHER_TYPE_ARROW:
// 对于弓箭,到达目的地后,删除自己
if( pOther->nCounter >= pOther->nDelay )
{ // 到达目的地了
OTHER_HitArrow( nIndex );
OTHER_DestroyData( nIndex );
}
else
{
pOther->nCounter += pOther->nSpeed;
pOther->ptCur.x = pOther->ptBegin.x + (int)(pOther->nCounter*pOther->fCos);
pOther->ptCur.y = pOther->ptBegin.y + (int)(pOther->nCounter*pOther->fSin);
}
break;
case OTHER_TYPE_GUNMU:
case OTHER_TYPE_STONE:
// 对于投石,到达目的地后,删除自己
if( pOther->nCounter >= pOther->nDelay )
{ // 到达目的地了
OTHER_HitStone( nIndex );
OTHER_DestroyData( nIndex );
}
else
{
pOther->nCounter += pOther->nSpeed;
pOther->ptCur.x = pOther->ptBegin.x + (int)(pOther->nCounter*pOther->fCos);
pOther->ptCur.y = pOther->ptBegin.y + (int)(pOther->nCounter*pOther->fSin);
}
break;
case OTHER_TYPE_BLOOD:
// 对于DOWN型,在动画帧结束后要删除本个体
case OTHER_TYPE_BOMB:
// 对于爆炸,在动画帧结束后要删除本个体
case OTHER_TYPE_MOUSE:
// 对于鼠标,在动画帧结束后要删除本个体
if( pOther->nCounter >= pOther->nDelay )
{
pOther->nFrame++;
pOther->nCounter = 0;
if( pOther->nFrame >= pOther->nMaxFrame )
{
pOther->nFrame = 0;
//OTHER_Hit( nIndex );
OTHER_DestroyData( nIndex );
return TRUE;
}
}
pOther->nCounter++;
break;
case OTHER_TYPE_HUOGONG:
// Dec.6.1997, Liu Gang
// 对于火攻,持续动画,并在一定时间后删除自己
if( pOther->nCounter>=pOther->nDelay )
{
pOther->nCounter = 0;
Assert( pOther->nMaxFrame );
pOther->nFrame = (pOther->nFrame+1)%pOther->nMaxFrame;
OTHER_HUOGONG_Hit( nIndex );
}
pOther->nCounter++;
pOther->nSpeed++;
if( pOther->nSpeed == (pOther->nTargetID>>1) )
{
if( OTHER_HUOGONG_Hit( nIndex ) == TRUE )
{
// 增加了火攻的持续时间,Aug 29, 1997
if( pOther->nOwnerID < 2 )
pOther->nOwnerID+=2;
}
// 时间超过一半时,再生一些火
// 生产的代数,为0时不生产
// 生产的个数,1到9个
WORD codeG = MAP_GetGroundData( 0, pOther->ptEnd.x, pOther->ptEnd.y );
int nNum = 4;
if( codeG != MAP_DATA_NONE )
{ // 如果是麦田树林则火放得大一些
struct MAP_GROUND_CODE_STRUCT stctG;
MAP_GroundDeCode( codeG, &stctG );
if( stctG.nAttr != MAP_SPECIAL_NONE && stctG.nAttr < 4 )
{
nNum = 8;
// 增加了火攻的持续时间,Aug 29, 1997
// pOther->nOwnerID++;
}
}
OTHER_HUOGONG_Set( pOther->ptEnd.x, pOther->ptEnd.y, pOther->nTargetID, pOther->nOwnerID-1, nNum );
}
if( pOther->nSpeed >= pOther->nTargetID )
{ // 超时删除
OTHER_HUOGONG_Die( nIndex );
OTHER_DestroyData( nIndex );
}
break;
}
return FALSE;
}
// 得到在屏幕上的矩形
// ptScreenOff : offset of screen relative to the whole map
// nIndex : index in array
// return : rectangle on screen
RECT OTHER_GetRect( POINT ptScreenOff, int nIndex )
{
RECT rect={0,0,0,0};
#ifdef _DEBUG
if( nIndex < 0 )
{
OutputDebugString( "OTHER_GetRect Error: index is less than 0!\n" );
return rect;
}
#endif
struct OTHER_STRUCT *pOther = &OTHER[nIndex];
rect.left = pOther->ptCur.x - ptScreenOff.x,
rect.top = pOther->ptCur.y - ptScreenOff.y;
rect.right = rect.left + pOther->szItem.cx,
rect.bottom = rect.top + pOther->szItem.cy;
return rect;
}
// 到达目的地后,对该点上的单元造成损失
// nIndex : index in array
// return : TRUE if hit someone
BOOL OTHER_HitStone( int nIndex )
{
struct OTHER_STRUCT *pOther;
struct UNIT_STRUCT *pUnit, *pU; //分别是中石的人和投石的人
#ifdef _DEBUG
if( nIndex < 0 )
{
OutputDebugString( "OTHER_HitStone Error: index is less than 0!\n" );
return FALSE;
}
#endif
pOther = &OTHER[nIndex];
// 设置爆炸效果
struct OTHER_STRUCT otherBomb;
OTHER_ClearData( &otherBomb );
otherBomb.nFile = 2;
otherBomb.nType = OTHER_TYPE_BOMB;
otherBomb.nDelay = 5; //RUN_TIMEDELAY_BOMB
otherBomb.ptBegin.x = pOther->ptCur.x-23; // 偏移量
otherBomb.ptBegin.y = pOther->ptCur.y-32;
otherBomb.szItem.cx = MAP_Lib.Other[otherBomb.nFile].szItem.cx;
otherBomb.szItem.cy = MAP_Lib.Other[otherBomb.nFile].szItem.cy;
for( int i=0; i<4; i++ )
{
otherBomb.nCol[i] = i;
}
otherBomb.nMaxFrame = 4;
OTHER_CreateData( &otherBomb );
// 在目的地坐标上寻找牺牲者
pUnit = MAP_GetUnit( pOther->ptEnd.x, pOther->ptEnd.y );
// July 31. 1997, Liu Gang
if( pUnit && EYE_IfUnitIsDead( pUnit ) ) return FALSE;
if( pUnit && !EYE_IfUnitIsDead( pUnit ) )
{
// 计算攻击效果
//--------------------攻击计算--------------------
int nHit, nDefend;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -