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

📄 client.cpp

📁 改工程是一个基于select模型实现的MUD游戏
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(nRet==SOCKET_ERROR)
	{
		cout<<"CreateRole::recv()failed!"<<endl;
		return;
	}

	if(strcmp(szRet,"CR OK")==0)
	{
		cout<<"角色数据初始化成功!"<<endl;
		cout<<"赶快开始你的大侠之旅把……"<<endl;
	}

	if(strcmp(szRet,"CR ERR")==0)
	{
		cout<<"你的注册资料被服务器拒绝!请核实你的资料"<<endl;
		return;
	}

}


/**
获取角色数据,地图数据
*/
bool initGameCondition(SOCKET sock)
{
	bool bResult=false;
	int nRet=0;

	//获取角色初始化信息部分
	//------------------------------begin-----------------------------
	SCommand scom;
	scom.CommandID=CMD_GETROLEINFO;
	scom.DataSize=0;

	nRet=send(sock,(char*)&scom,sizeof(scom),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"发送数据失败,请检查网络!"<<endl;
	}

	//接受数据大小
	int datasize;
	nRet=recv(sock,(char*)&datasize,sizeof(datasize),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"接受角色信息数据失败!"<<endl;
	}

	nRet=recv(sock,(char*)&g_player,datasize,0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"接受角色信息数据失败!"<<endl;
	}
	else
	{
		cout<<"获取角色信息数据成功!"<<endl;
		bResult=true;
	}

	//---------------------------------end------------------------------



	//获取在线玩家列表
	bResult=GetOnlineRoleList(sock);

	//获取HM上限
	SetHMTop(sock);

	return bResult;
}



void SetHMTop(SOCKET sock)
{
	
	char lv[3];
	memset(lv,0,3);
	SCommand scom;
	scom.CommandID=CMD_GETLEVELINFO;
	

	itoa(g_player.level,lv,10);

	scom.DataSize=(int)strlen(lv);

	int nRet=send(sock,(char*)&scom,sizeof(scom),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"SetHMTop()发送数据失败,请检查网络!"<<endl;
		return;
	}

	nRet=send(sock,lv,(int)strlen(lv),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"SetHMTop()发送数据失败,请检查网络!"<<endl;
		return;
	}


	LevelInfo lvi;
	memset(&lvi,0,sizeof(lvi));

	nRet=recv(sock,(char*)&lvi,sizeof(lvi),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"SetHMTop()接收数据失败,请检查网络!"<<endl;
		return;
	}


	hpTop=lvi.hp;
	mpTop=lvi.mp;

}


//获取在线玩家数据
bool GetOnlineRoleList(SOCKET sock)
{
	int nRet;
	bool bRet=false;
	SCommand scom;
	scom.CommandID=CMD_GETOLLIST;
	scom.DataSize=0;

	nRet=send(sock,(char*)&scom,sizeof(scom),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"发送数据失败,请检查网络!"<<endl;
	}


	//接收在线玩家个数
	int olnum;
	nRet=recv(sock,(char*)&olnum,sizeof(olnum),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"接受在线玩家数据出错!"<<endl;
	}


	int recvnum=0;
	OnLineList tempOLR;
	g_OnLineRoles.clear();
	while(recvnum<olnum)//减去玩家本身
	{
		nRet=recv(sock,(char*)&tempOLR,sizeof(tempOLR),0);
		{
			if(nRet==SOCKET_ERROR)
			{
				cout<<"接收在线玩家数据出错,请检查网络!"<<endl;
				break;
			}
			g_OnLineRoles.push_back(tempOLR);
			recvnum++;
		}
	}

	//如果全部正确接收所有数据
	if(recvnum==olnum)
	{
		cout<<"在线玩家数据已更新!"<<endl;
		bRet=true;
	}

	return bRet;
}

//游戏事件
void CreateGameEvent(SOCKET sock)
{
	srand(timeGetTime());
	int random=rand()%100;
	if(random<5)
	{
		//获得宝物事件
		GetTreasureEvent(sock);
	}
	if(random>=5&&random<50)
	{
		//遇敌事件
		MeetEnemyEvent(sock);
	}
	if(random>=50)
	{
		//一般描述事件
		DefaultEvent(sock);
	}

}


//获得宝物事件,概率为5%
void GetTreasureEvent(SOCKET sock)
{
	srand(timeGetTime());
	int item=rand()%5;
	
	bool welldone=false;

	ColorTextOut("[系统]由于你的人品爆发,你获得了传说中的宝物!",false);
	cout<<endl;

	int i=0;
	for(;i<OBJECTNUM;i++)
	{
		if(g_player.ownObject[i].ownObjectName=="null")
		{
			g_player.ownObject[i].ownObjectName=spEquip[item];
			g_player.ownObject[i].num=1;
			welldone=true;
			break;
		}
	}

	if(!welldone)
	{
		ColorTextOut("很遗憾,由于你身上没有足够的空间来存放,失去了得到传说中的宝物",false);
		return;			
	}


	char noticeInfo[256];
	memset(noticeInfo,0,256);

	sprintf(noticeInfo,"%s人品爆发,获得了传说中的宝物——%s",g_player.nickName,spEquip[item]);

	SCommand scom;
	scom.CommandID=CMD_NOTICE;
	scom.DataSize=(int)strlen(noticeInfo);


	//宝物通知
	int nRet=send(sock,(char*)&scom,sizeof(scom),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"GetTreasureEvent()发送数据失败,请检查网络!"<<endl;
		return;
	}

	nRet=send(sock,(char*)noticeInfo,(int)strlen(noticeInfo),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"GetTreasureEvent()发送数据失败,请检查网络!"<<endl;
		return;
	}


	//玩家数据保存
	updateNewDS updata;
	memset(&updata,0,sizeof(updata));

	sprintf(updata.op,"objectname%d objectnum%d",i+1,i+1);
	strcpy(updata.item,g_player.ownObject[i].ownObjectName.c_str());
	updata.num=1;
	updata.opType=DBOP_TYPE_ALL;



	scom.CommandID=CMD_UPDATE;
	scom.DataSize=sizeof(updata);


	nRet=send(sock,(char*)&scom,sizeof(scom),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"GetTreasureEvent()发送数据失败,请检查网络!"<<endl;
		return;
	}


	nRet=send(sock,(char*)&updata,sizeof(updata),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"GetTreasureEvent()发送数据失败,请检查网络!"<<endl;
		return;
	}


	char res[20];
	memset(res,0,20);

	nRet=recv(sock,res,sizeof(res),0);
	if(nRet==SOCKET_ERROR)
	{
		cout<<"GetTreasureEvent()接收数据失败,请检查网络!"<<endl;
		return;
	}


	if(strcmp(res,"UP OK")==0)
	{
		cout<<"每张地图都有可能获得传说中的宝物哦!"<<endl;
	}

}


//遇敌事件,概率为45%
//
//战斗准备阶段:1,获取怪物数据,2,获取玩家的综合数据(本系统采用基本属性和装备属性分离保存机制)
//战斗逻辑:根据双方的敏捷值,判断出手先后,采用死斗模式,怪物有简单AI,
//战斗结束阶段:经验值增加->等级增加->属性值增加(基本属性及新技能),金钱增加,没有装备掉落
//
void MeetEnemyEvent(SOCKET sock)
{	
	monster mon;
	int totalAK=0,totalDF=0,totalCT=0;//综合伤害值,防御值,敏捷值

	CalculateRoleInfo(sock,totalAK,totalDF,totalCT);

	if(!GetMonsterInfo(sock,mon))
	{
		cout<<"从服务器端读取怪物数据失败"<<endl;
		return;
	}

	//遇怪通知
	ColorTextOut("[系统]",false);
	cout<<"在"<<map[g_player.pos[0]][g_player.pos[1]]<<"遇到了"<<mon.monsterName<<endl;



	vector<skill> sklib;//技能库信息
	vector<Myobject> mdlib;//药品库信息


	//统计拥有技能,以获取技能参数
	for(int i=0;i<SKILLNUM;i++)
	{
		skill tempsk;
		memset(&tempsk,0,sizeof(tempsk));
		if(g_player.ownSkill[i]!="null")
		{
			GetSkillParamByString(sock,g_player.ownSkill[i],tempsk);
			sklib.push_back(tempsk);
		}
	}

	int temphp=0;//掉血量

	int hpindex=-1;//hp药品索引
	int mpindex=-1;//mp药品索引

	
	//准备药品库
	for(int i=0;i<OBJECTNUM;i++)
	{
		Myobject mobj;
		memset(&mobj,0,sizeof(mobj));
		if(GetObjectInfo(sock,g_player.ownObject[i].ownObjectName,mobj))
		{
			if(mobj.moType==OT_HP)
			{
				mdlib.push_back(mobj);
				hpindex=i;
			}
			else if(mobj.moType==OT_MP)
			{
				mdlib.push_back(mobj);
				mpindex=i;
			}
		}
	}

	ColorTextOut("[系统]进入战斗模式",false);
	cout<<endl;
	while(true)
	{
		//怪物AI所需-------	
		srand(timeGetTime());
		int mprob=rand()%100;
		//-----------------

		
		
		char in='0';//输入
		int choice=0;//转换
		
		if(g_player.celerity>=mon.ct)//玩家先出手
		{
			PL:cout<<"*************技能攻击**************"<<endl;
			
			for(int index=0;index<SKILLNUM;index++)//显示技能
			{
				if(g_player.ownSkill[index]!="null")
					cout<<"["<<index<<"] "<<g_player.ownSkill[index]<<"  ";
				else cout<<"["<<index<<"] "<<"还未学习"<<"  ";
				if(index%3==0) cout<<endl;//换行
			}
			cout<<endl;
			cout<<"*******你可以使用的辅助药品********"<<endl;
			for(UINT i=0;i<mdlib.size();i++)
			{
				cout<<"["<<SKILLNUM+i<<"]"<<mdlib[i].objectName<<"  "<<"数量:"<<(mdlib[i].moType==OT_HP?(g_player.ownObject[hpindex].num):(g_player.ownObject[mpindex].num))<<endl;
			}
			cout<<endl;
			cout<<"请输入你的要使用的技能,其他任意字符键普通攻击"<<endl;
			while(true)//防止误操作
			{
				cin>>in;
				if(in>'9'||in<'0')
				{
					//cout<<"输入非法,请输入0-9"<<endl;
					//continue;
					goto WL;
				}

				choice=in-'0';
				if(g_player.ownSkill[choice]!="null")
					break;
				else cout<<"你还没有学习该项技能,赶紧修炼把!"<<endl;
						
			}


			if(choice<7)//使用技能
			{
				if(g_player.mp-sklib[i].needmp>0)
				{
					cout<<"你使出了一招——";
					ColorTextOut(g_player.ownSkill[choice].c_str(),false);
					cout<<endl;
					if((sklib[choice].damage-mon.defence)>0)//怪物防御太高了
						temphp=sklib[choice].damage-mon.defence;
					else temphp=1;//至少一点血
					cout<<mon.monsterName<<"耗去了"<<temphp<<"滴血"<<endl;
					

					//状态修改
					mon.hp-=temphp;
					g_player.mp-=sklib[choice].needmp;

					if(mon.hp<=0)//战斗胜利
					{

						g_player.exp+=mon.hasexp;
						g_player.money+=mon.hasmoney;

						ColorTextOut("[系统]你获得了",false);
						cout<<mon.hasexp<<"点经验和"<<mon.hasmoney<<"两银子"<<endl;

						//退出战斗
						break;
					}else//怪物没死,怪物攻击
					{
						goto GW;

					}
				}
				else
				{
					cout<<"你的魔法值不够了,使用物理攻击!"<<endl;
					goto WL;
				}
			}
			else if(choice<9)//使用药品
			{
				int whatuse=choice-SKILLNUM;//获得使用物品序号
				if(mdlib[whatuse].moType==OT_HP)
				{
					if(g_player.ownObject[hpindex].num-1>0)
					{
						g_player.hp+=mdlib[whatuse].value;
						g_player.ownObject[hpindex].num--;
					}
				}
				else
				{
					if(g_player.ownObject[mpindex].num-1>0)
					{
						g_player.mp+=mdlib[whatuse].value;
						g_player.ownObject[mpindex].num--;
					}
				}

				goto GW;

			}
			else//使用物理攻击
			{
				WL:if((g_player.attack-mon.defence)>0)
					temphp=g_player.attack-mon.defence;
				else temphp=1;

				mon.hp-=temphp;
			

				if(mon.hp<=0)//战斗胜利
				{
					g_player.exp+=mon.hasexp;
					g_player.money+=mon.hasmoney;

					//奖励提示:
					ColorTextOut("[系统]你获得了",false);
					cout<<mon.hasexp<<"点经验和"<<mon.hasmoney<<"两银子"<<endl;
					break;
				}

				cout<<"你打去了"<<mon.monsterName<<temphp<<"滴血"<<endl;

				goto GW;
			}
		}

		else//怪物先出手
		{
			GW:if(mprob<mon.prob)//判断ai,怪物发动技能
			{
				if(mon.mp-mon.needmp>0)//mp够发动技能
				{
					ColorTextOut("惊叹!!!",false);
					cout<<mon.monsterName<<"凝气而动,发出独门绝招——"<<mon.skillName<<endl;
					if((mon.skilldamage-g_player.defendence)>0)//玩家防御太高了
						temphp=mon.skilldamage-g_player.defendence;
					else temphp=1;//最少1点血

					mon.mp-=mon.needmp;
					g_player.hp-=temphp;
					cout<<"你一声闷哼,中招了,耗去了"<<temphp<<"滴血"<<endl;
				}else goto CA;//一般攻击

				if(g_player.hp<=0)//战斗失败
				{
					goto FO;//进入死亡处理
				}
				else goto PL;//玩家没有死亡,玩家出手

			}else
			{
				CA:if((mon.attack-g_player.defendence)>0)
					temphp=mon.attack-g_player.defendence;
				else temphp=1;
				g_player.hp-=temphp;

				cout<<"你被耗去了"<<temphp<<"滴血"<<endl;
				if(g_player.hp<=0)
				{
					FO:ColorTextOut("胜败乃兵家常事,请英雄重新来过!",false);
					cout<<endl;

					//设置重生后的状态
					g_player.hp=1;
					g_player.pos[0]=0;
					g_player.pos[1]=0;

					//死亡损失
					if(g_player.level>=10)
						if((g_player.money-50*g_player.level)>0)
							g_player.money-=50*g_player.level;
						else g_player.money=0;

⌨️ 快捷键说明

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