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

📄 message.cpp

📁 圣剑英雄传源码适合初学C语言者如细心阅读完定有收获!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//********************************************
//	消息处理 相关函数
//  创建于2000年5月8日
//********************************************
#include <windows.h>
#include <stdio.h>
#include "gamelib\goldpoint.h"
#include "interface\interface.h"
#include "fight\fight.h"
#include "menu\title.h"
#include "main.h"
#include "events.h"
#include "talk.h"
#include "map.h"
#include "role.h"
#include "npc.h"
#include "script.h"
#include "message.h"

//初始化
CMessage::CMessage()
{
	ClearAllMessage();				//清空
	m_bMessageRunning=false;		//没有消息在运行
}

//清除所有消息
void CMessage::ClearAllMessage()
{
	m_nStartId=m_nEndId=0;			//头尾指针
}

//消息队列是否为空
bool CMessage::IsEmpty()
{
	if( m_nStartId==m_nEndId )
		return true;
	else 
		return false;
}

//加入一条消息
void CMessage::PutMessage(stMessage Message)
{
	m_stMsg[m_nEndId]=Message;		//加入到数组中
	m_nEndId++;						//尾指针加1
	if( m_nEndId >= MAX_MSG )
		m_nEndId=0;					//循环
}

//加入一条消息
void CMessage::PutMessage(enum MESSAGE Class, int p1, int p2, int p3, char *str1, char *str2, char *str3)
{
	//设置结构
	m_stMsg[m_nEndId].msg=Class;
	m_stMsg[m_nEndId].Param1=p1;
	m_stMsg[m_nEndId].Param2=p2;
	m_stMsg[m_nEndId].Param3=p3;
	m_stMsg[m_nEndId].String1=str1;
	m_stMsg[m_nEndId].String2=str2;
	m_stMsg[m_nEndId].String3=str3;
	
	m_nEndId++;
	if( m_nEndId >= MAX_MSG )
		m_nEndId=0;
}

//获得一条消息类型
enum MESSAGE CMessage::GetMessage(int Id)
{
	if( Id==-1 ) 
		Id=m_nStartId;	//缺省消息

	if( Id < 0 || Id >= MAX_MSG ) 
		return MSG_NULL;

	if( m_nEndId==Id ) 
		return MSG_NULL;	//消息队列为空

	return m_stMsg[Id].msg;
}

//删除一条消息
void CMessage::DeleteMessage(int Id)
{
	if( Id==-1 ) 
		Id=m_nStartId;	//缺省消息

	if( Id < 0 || Id >= MAX_MSG ) 
		return;

	if( m_nEndId==Id ) 
		return;		//消息队列为空

	//释放字符串变量
	_FREE( m_stMsg[Id].String1 );
	_FREE( m_stMsg[Id].String2 );
	_FREE( m_stMsg[Id].String3 );

	m_nStartId++;				//头指针向后移动一个
	if( m_nStartId>=MAX_MSG )
		m_nStartId=0;
}

//执行
void CMessage::Run()
{
	//-----------------------///////////////////////
	//Message.RunMessage();	//   处理当前消息	 //
	//---------------------///////////////////////

	//-----------------------//////////////////////
	//Message.BackMessage();// 上条消息结束处理 //
	//---------------------//////////////////////

	// 如果SetPlayState(0)就连续执行消息,一直执行到SetPlayState(1)为止
	do
	{
		if( m_nStartId == m_nEndId ) 
			return;	//消息队列为空

		RunMessage();		//执行一个消息
		BackMessage();		//结束一个消息
	}
	while( g_ePlayState == PS_Null && m_nStartId != m_nEndId );		//连续执行
}

//执行一条消息
bool CMessage::RunMessage(int Id)
{
	if( m_bMessageRunning ) 
		return false;			//有消息正在执行

	if( Id==-1 ) 
		Id=m_nStartId;						//缺省消息

	if( Id < 0 || Id >= MAX_MSG ) 
		return false;		//消息越界

	switch( m_stMsg[Id].msg )
	{
	case MSG_BREAK:
		return true;
	case MSG_BREAKSCRIPT:	//继续执行脚本
		{
			for(int i=Script.RecursionLevel; i>=0; i--)
			{
				//接着上次暂停的地方执行,如果有遇到暂停或者脚本完成就退出
				if( Script.Run( Script.RecursionFile[i], "",
						Script.RecursionPoint[i] ) == CScript::SR_RECURSION )
					break;
			}
		}
		break;

	case MSG_SETVARIABLE:	//设置脚本变量的值
		Script.SetValue( m_stMsg[Id].String1, m_stMsg[Id].Param1 );
		break;

	case MSG_SETPLAYSTATE:	//设置运行状态
		g_ePlayState=(enum ePLAYSTATE)m_stMsg[Id].Param1;
		break;

	case MSG_SETDISPLAYSTATE:	//设置显示状态
		g_eDisplayState=(enum eDISPLAYSTATE)m_stMsg[Id].Param1;
		break;

	case MSG_BACKTOTITLE:	//回游戏主菜单
		Title.DoMenu(lpDDSBack);
		break;

	case MSG_TEXTTITLE:		//显示字幕
		Events.TextTitle( m_stMsg[Id].String1, m_stMsg[Id].String2 );
		break;

	case MSG_FIGHT:			//战斗
		{
			FadeIn(2, 20, RGB16(255,255,255));		//屏幕变白
			//敌人名字
			if( strcmp(m_stMsg[Id].String1, "")==0 ) 
				m_stMsg[Id].String1=NULL;
			if( strcmp(m_stMsg[Id].String2, "")==0 ) 
				m_stMsg[Id].String2=NULL;
			if( strcmp(m_stMsg[Id].String3, "")==0 ) 
				m_stMsg[Id].String3=NULL;

			//主角数据
			stRolePropertiy *rps[3];
			if( m_stMsg[Id].Param1 == ERROR_DATA )	//没有指定主角,就全部上
			{
				rps[0]=&role[0].Propertiy;
				if( RoleNum >1 ) 
					rps[1]=&role[1].Propertiy;
				else rps[1]=NULL;

				if( RoleNum >2 ) 
					rps[2]=&role[2].Propertiy;
				else rps[2]=NULL;
			}
			else
			{										//只上指定的主角
				if (m_stMsg[Id].Param1 != -1 ) 
					rps[0]=&role[m_stMsg[Id].Param1].Propertiy;
				else rps[0]=NULL;

				if( m_stMsg[Id].Param2 != -1 && m_stMsg[Id].Param2 != ERROR_DATA ) 
					rps[1]=&role[m_stMsg[Id].Param2].Propertiy;
				else rps[1]=NULL;

				if( m_stMsg[Id].Param3 != -1 && m_stMsg[Id].Param3 != ERROR_DATA ) 
					rps[2]=&role[m_stMsg[Id].Param3].Propertiy;
				else rps[2]=NULL;
			}

			Fight.bLeave=false;			//不能逃跑
			//只支持三个敌人,2位置不会有人
			Fight.Start("ini\\fight\\background1.ini", rps[0], rps[1], rps[2], 
				m_stMsg[Id].String1, NULL, m_stMsg[Id].String2, m_stMsg[Id].String3);

			FadeOut(2);
		}
		break;

	case MSG_ENABLEFIGHT:	//是否踩地雷
		Fight.bRandomFight=m_stMsg[Id].Param1;
		break;

	case MSG_BOSSFIGHT:	//是否踩地雷
		Fight.SetBossFight(m_stMsg[Id].Param1);
		break;

	//-----------------------------------------------------------

	case MSG_LOADMAP:		//读入地图
		map.LoadMap( m_stMsg[Id].String1 );
		break;

	case MSG_SAVEMAP:		//存储地图
		map.SaveMap( m_stMsg[Id].String1 );
		break;

	case MSG_ADDMAPHOOK:	//添加地图陷阱
		map.AddHook( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].String1);
		break;

	case MSG_SETMAPHOOK:	//设置地图陷阱
		map.SetHook( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].Param3);
		break;

	case MSG_SETMAPCELL:	//设置地图某格
		{
			int n1=(int)m_stMsg[Id].String1;
			int n2=(int)m_stMsg[Id].String2;
			map.SetCell( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].Param3, n1, n2);
			m_stMsg[Id].String1=NULL;
			m_stMsg[Id].String2=NULL;
		}
		break;

	case MSG_SETMAPBLOCK:	//设置地图阻挡
		map.SetBlock( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].Param3 );
		break;

	case MSG_SETMAPLEVEL:	//设置地图层次
		{
			int n1=(int)m_stMsg[Id].String1;
			map.SetLevel( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].Param3, n1 );
			m_stMsg[Id].String1=NULL;
		}
		break;

	case MSG_CENTERMAP:		//设置地图中心点
		map.CenterMap( m_stMsg[Id].Param1, m_stMsg[Id].Param2 );
		break;

	case MSG_SCROLLMAPTO:	//卷动地图到某点
		bControl=false;
		m_bMessageRunning=true;		//等到地图卷动到位了才执行下一条消息

		if( m_stMsg[Id].Param3==ERROR_DATA ) //没有指定节奏
			m_stMsg[Id].Param3=8;

		map.ScrollTo( m_stMsg[Id].Param1, m_stMsg[Id].Param2, m_stMsg[Id].Param3 );
		break;
	
	case MSG_LOADNPC:		//读取地图的NPC
		map.LoadIniNpcList( m_stMsg[Id].String1 );
		break;

//------------------------ROLE------------------------------------

	case MSG_TALK:			//对话消息
		talk.Talk(lpDDSBackGround, m_stMsg[Id].String1);	//对话
		break;

	case MSG_SAY:			//说一句话
		talk.Say(lpDDSBackGround, m_stMsg[Id].String1, m_stMsg[Id].String2, 
					m_stMsg[Id].Param1);
		break;

	case MSG_TALKDIR:		//调整主角和npc对话时的方向
		{
			int px=role[0].State.X;
			int py=role[0].State.Y;
			int nx=map.m_vNpc[m_stMsg[Id].Param1]->State.X;
			int ny=map.m_vNpc[m_stMsg[Id].Param1]->State.Y;
			if( abs(px-nx) >= abs(py-ny) )	//横向
			{
				if( px < nx )	//主角在左边
				{
					role[0].State.CurrentDir=3;
					map.m_vNpc[m_stMsg[Id].Param1]->State.CurrentDir=1;
				}
				else			//主角在右边
				{
					role[0].State.CurrentDir=1;
					map.m_vNpc[m_stMsg[Id].Param1]->State.CurrentDir=3;
				}
			}
			else	//纵向
			{
				if( py < ny )	//主角在上边
				{
					role[0].State.CurrentDir=0;
					map.m_vNpc[m_stMsg[Id].Param1]->State.CurrentDir=2;
				}
				else			//主角在下边
				{
					role[0].State.CurrentDir=2;
					map.m_vNpc[m_stMsg[Id].Param1]->State.CurrentDir=0;
				}
			}		//运行脚本
			Script.Run(m_stMsg[Id].String1);
			Message.PutMessage( MSG_SETNPCACTIVE, m_stMsg[Id].Param2,m_stMsg[Id].Param1, 1);		//npc恢复活动
		}
		break;
	
	case MSG_MOVE:			//行走消息
		bControl=false;
		m_bMessageRunning=true;			//主角到位才接着执行
		if(m_stMsg[Id].Param3)
		{
			map.Cell[m_stMsg[Id].Param1+m_stMsg[Id].Param2*map.Width].Block =1;
			role[0].MoveTo(m_stMsg[Id].Param1*CellWidth, m_stMsg[Id].Param2*CellHeight);
			map.Cell[m_stMsg[Id].Param1+m_stMsg[Id].Param2*map.Width].Block =0;
		}
		else
			role[0].MoveTo(m_stMsg[Id].Param1*CellWidth, m_stMsg[Id].Param2*CellHeight);
		break;

	case MSG_MOVEDIRECTTO:		//朝一个方向移动
		{
			bControl = false;
			m_bMessageRunning=true;
			int x = role[0].State.X*CellWidth;
			int y = role[0].State.Y*CellHeight;
			switch(m_stMsg[Id].Param1)		//根据方向算出目的点
			{
			case 0:
				y += m_stMsg[Id].Param2*CellHeight;
				break;
			case 1:
				x -= m_stMsg[Id].Param2*CellWidth;
				break;
			case 2:
				y -= m_stMsg[Id].Param2*CellHeight;
				break;
			case 3:
				x += m_stMsg[Id].Param2*CellWidth;
				break;
			default:
				return false;
			}

			role[0].MoveTo(x,y);
			break;
		}
	case MSG_SETDIR:		//设置人物方向
		role[0].State.CurrentDir=m_stMsg[Id].Param1;
		break;

	case MSG_SETPOSITION:	//设置人物位置
		if( m_stMsg[Id].Param3 != ERROR_DATA )		//清除原位置的阻挡关系
			map.Block[map.Width*role[0].State.Y+role[0].State.X]=0;
		role[0].bMoving = false;
		role[0].State.x=role[0].State.oldx=m_stMsg[Id].Param1*CellWidth+CellWidth/2;
		role[0].State.y=role[0].State.oldy=m_stMsg[Id].Param2*CellHeight+CellHeight/2;
		//取主角的格子坐标
		role[0].State.X=role[0].State.oldX=_grid_x(role[0].State.x);
		role[0].State.Y=role[0].State.oldY=_grid_y(role[0].State.y);
		//设置新的当前步状态
		role[0].State.CurrentStep = 0;
		//设置新的阻挡关系
		map.Block[map.Width*role[0].State.Y+role[0].State.X]=1;
		break;

	case MSG_CENTERPLAYER:	//以主角为地图中心

⌨️ 快捷键说明

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