接受任务,提交任务,显示任务
玩家里面应该有一个容器,用来存放已接收的任务,
任务NPC里面也应该有一个容器,用来存放开启的任务
接受任务:
1.不同NPC对应不同任务:
任务数据里面应该对应包含NPCID属性。由此实现不同npc对应不同任务(同商店)
2.NPC里面有开启的任务,和没开启的任务:
任务数据应该具有是否开启的属性,满足条件开启任务,否则不开启,NPC里面只显示开启的任务。
3.接受任务后,玩家任务窗口里应当显示当前任务,以及任务进度。完成任务后,任务属性应当变为已完成。
如何实现任务进度?
提交任务:
当当前任务完成时,提交任务成功,并获取相应奖励。
显示任务:
玩家应当包含一个装有已接任务的容器,定义对任务属性的数据更新和渲染(装备和技能是否也是如此?装备和任务系统是否可以都继承某个窗口类,所以玩家里面应该包含装备管理者、技能管理者、任务管理者的成员去进行管理),当按下某个建的时候,gameMgr对任务进行数据更新和渲染。对窗口基类进行数据更新、以及渲染。(battle我是直接归游戏管理者管理了,事实上,让其属于map管理(battl只需要enemy和player数据,map中均可以拿到),这样battle也能够变成一个窗口延伸了。)
任务是商品吗?任务不应当是商品。任务应当单独配表
三、不同任务不同的达成条件:
1.杀怪 2.找npc 3.购买相关物品
四、完成任务后获取相关奖励
1.经验、金币
2.装备
3.开启相应任务
具体实现:
整个任务系统包含三个类:CMission类、MissionMgr类、CMissionNpc类、CRecivedMission类
四个类分别进行:CMission:任务的逻辑处理,如获取奖励,判断任务是否完成等。
CMissionMgr类:创建所有任务、并对其初始化,获取已接任务和已解锁任务分别传给CRecivedMission类和CMissionNpc类。
CMissionNpc类:任务NPC的处理,和商店买卖物品类似的功能,处理任务的接受、提交、对话等
CRecivedMission类:玩家的任务窗口,用于显示已经接受的任务、以及任务描述等
源代码:
CMission类:
#pragma once
#include "Talk.h"
class CMission
{
public:
CMission();
~CMission();
void getReward();
int getID()
{
return m_nID;
};
void initMission(SMissionDt* data);
void showName();
void showDescripe();
void showSchedule();
void updataIsAchieve();
CTalk* getTalk(){ return m_pTalk; }
CTalk* getFinishTalk(){ return m_pFinishTalk; }
int getNpcID(){ return m_nNpcID; };
GETTER_SETTER(bool, isAchieve, m_bIsAchieve);
GETTER_SETTER(bool, isRecived, m_bIsRecived);
GETTER_SETTER(bool, isUnlock, m_bIsUnlocked);
private:
int m_nID;
int m_nNpcID;
char m_szName[32];
char m_szDescripe[128];
CTalk* m_pTalk;
CTalk* m_pFinishTalk;
};
MissionMgr类:
#pragma once
#include "Mission.h"
class CMissionMgr
{
public:
CMissionMgr();
~CMissionMgr();
void creatAllMission();
vector<CMission*>getUnlockMission();
vector<CMission*>getRecivedMission();
CMission* getMission(int nID);
private:
vector<CMission*>m_vecMissions;
};
CMissionNpc类:
#pragma once
#include "Mission.h"
class CMissionNpc:public CWndBase
{
public:
CMissionNpc();
~CMissionNpc();
void updata();
void onRander();
void updataMission();
void setMissions(int nNpcID);
private:
vector<CMission*>m_vecUnlockedMission;
int m_nIndex;
};
CRecivedMission类:
#pragma once
#include "Mission.h"
#include "WndBase.h"
class CRecivedMission:public CWndBase
{
public:
CRecivedMission();
~CRecivedMission();
void setMission();
void updata();
void onRander();
private:
vector<CMission*>m_vecRecivedMission;
int m_nIndex;
};
CMission类的实现:
#include "stdafx.h"
#include "Mission.h"
CMission::CMission()
{
m_nID = 0;
m_nNpcID = 0;
m_bIsRecived = false;
m_bIsUnlocked = false;
memset(m_szName, 0, sizeof(m_szName));
memset(m_szDescripe, 0, sizeof(m_szDescripe));
m_bIsAchieve=false;
m_pTalk = new CTalk;
m_pFinishTalk = new CTalk;
}
CMission::~CMission()
{
}
void CMission::initMission(SMissionDt* data)
{
m_nID = data->nID;
m_nNpcID = data->nNpcID;
m_bIsRecived = data->bIsRecive;
m_bIsUnlocked = data->bIsUnlocked;
memcpy(m_szName, data->szName, sizeof(data->szName));
memcpy(m_szDescripe, data->szDescripe, sizeof(data->szDescripe));
//接收任务时的对话
m_pTalk->setTalkLines(data->nTalkLines);
memcpy(m_pTalk->getArrTalk()->arrTalk, data->arrTalk, sizeof(data->arrTalk));
//提交任务时的对话
m_pFinishTalk->setTalkLines(data->nFinishTalkLines);
memcpy(m_pFinishTalk->getArrTalk()->arrTalk, data->arrFinishTalkLines, sizeof(data->arrFinishTalkLines));
}
void CMission::showName()
{
cout << m_szName;
}
void CMission::showDescripe()
{
cout << m_szDescripe;
}
void CMission::updataIsAchieve()
{
CPlayer* player = g_GameMgr->getGameMap()->getplayer();
switch (m_nID)
{
case 6001:
if (2 <= player->getKillEnemyNum(4001))
{
m_bIsAchieve = true;
}
break;
case 6002:
if (2 <= player->getKillEnemyNum(4002))
{
m_bIsAchieve = true;
}
break;
case 6003:
if (2 <= player->getKillEnemyNum(4003))
{
m_bIsAchieve = true;
}
break;
case 6004:
if (10 <= player->getPackage()->getItemNum(3004))
{
m_bIsAchieve = true;
}
break;
case 6005:
//当背包里面有回信的时候,完成任务。
if (player->getPackage()->getItemNum(3013)>0)
{
m_bIsAchieve = true;
}
break;
case 6006:
if (player->getPackage()->getItemNum(3014) > 0)
{
m_bIsAchieve = true;
}
break;
default:
break;
}
}
void CMission::getReward()
{
CPlayer* player = g_GameMgr->getGameMap()->getplayer();
switch (m_nID)
{
case 6001:
player->addExp(100);
player->changeMoney(5000);
player->getEquitment()->addEquiepment(g_DataMgr->getIteamDtMgr()->getByID(3001));
break;
case 6002:
player->addExp(100);
player->changeMoney(5000);
break;
case 6003:
player->addExp(100);
player->changeMoney(5000);
break;
case 6004:
player->addExp(100);
player->changeMoney(5000);
break;
case 6005:
player->addExp(100);
player->changeMoney(400);
//解锁新的任务
g_GameMgr->getMissionMgr()->getMission(6006)->setisUnlock(true);
//任务物品消失
g_GameMgr->getGameMap()->getplayer()->getPackage()->deleteItem(3013);
男人移动
//g_GameMgr->getGameMap()->getNpcMgr()->moveNpc(2007,1003, 5, 10);
/*男人消失*/
g_GameMgr->getGameMap()->getNpcMgr()->deleteNpc(2007);
break;
case 6006:
player->addExp(100);
player->changeMoney(5000);
player->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3006));
break;
default:
break;
}
}
void CMission::showSchedule()
{
CPlayer* player = g_GameMgr->getGameMap()->getplayer();
switch (m_nID)
{
case 6001:
cout << player->getKillEnemyNum(4001)<<"/2";
break;
case 6002:
cout << player->getKillEnemyNum(4002)<< "/2";
break;
case 6003:
cout << player->getKillEnemyNum(4003)<< "/2";
break;
case 6004:
cout << player->getPackage()->getItemNum(3004)<< "/10";
break;
case 6005:
cout << " 杰克马上要奔赴战场了,找到珍妮,并把这封信交给她";
break;
case 6006:
cout << " 在漫长的日子里,珍妮愈发的思念杰克,她让我务必把这封信交到杰克手中";
break;
default:
break;
}
}
CMissionMgr类的实现:
#include "stdafx.h"
#include "MissionMgr.h"
CMissionMgr::CMissionMgr()
{
creatAllMission();
}
CMissionMgr::~CMissionMgr()
{
}
void CMissionMgr::creatAllMission()
{
for (int i = 0; i < 6;i++)
{
SMissionDt* pData = g_DataMgr->getMissionDtMgr()->getByID(6001 + i);
CMission* pMission = new CMission;
pMission->initMission(pData);
m_vecMissions.push_back(pMission);
}
}
vector<CMission*> CMissionMgr::getUnlockMission()
{
vector<CMission*>vecUnlockMission;
for (int i = 0; i < m_vecMissions.size();i++)
{
if (m_vecMissions[i]->getisUnlock()==true)
{
vecUnlockMission.push_back(m_vecMissions[i]);
}
}
return vecUnlockMission;
}
vector<CMission*> CMissionMgr::getRecivedMission()
{
vector<CMission*>vecRecivedMission;
for (int i = 0; i < m_vecMissions.size();i++)
{
if (m_vecMissions[i]->getisRecived()==true)
{
vecRecivedMission.push_back(m_vecMissions[i]);
}
}
return vecRecivedMission;
}
CMission* CMissionMgr::getMission(int nID)
{
for (int i = 0; i < m_vecMissions.size();i++)
{
if (nID==m_vecMissions[i]->getID())
{
return m_vecMissions[i];
}
}
return nullptr;
}
CReceivedMission类:
#include "stdafx.h"
#include "RecivedMission.h"
CRecivedMission::CRecivedMission()
{
}
CRecivedMission::~CRecivedMission()
{
}
void CRecivedMission::updata()
{
if (KEY_DOWN(VK_UP))
{
m_nIndex--;
if (m_nIndex < 0)
{
m_nIndex = m_vecRecivedMission.size() - 1;
}
}
else if (KEY_DOWN(VK_DOWN))
{
m_nIndex++;
if (m_nIndex >m_vecRecivedMission.size() - 1)
{
m_nIndex = 0;
}
}
if (KEY_DOWN(VK_ESCAPE))
{
g_GameMgr->recoverWnd();
}
}
void CRecivedMission::onRander()
{
for (int i = 0; i < m_vecRecivedMission.size(); i++)
{
if (i == m_nIndex)
{
cout << "->";
}
else
{
cout << " ";
}
m_vecRecivedMission[i]->showName();
if (i == m_nIndex)
{
cout << "\t";
m_vecRecivedMission[i]->showDescripe();
m_vecRecivedMission[i]->showSchedule();
}
cout << endl;
}
}
void CRecivedMission::setMission()
{
m_vecRecivedMission=g_GameMgr->getMissionMgr()->getRecivedMission();//调用MissionMgr的获取接口,每次进入任务界面时,更新任务数据
}
CMissionNpc类:
#include "stdafx.h"
#include "MissionNpc.h"
CMissionNpc::CMissionNpc()
{
m_nIndex = 0;
}
CMissionNpc::~CMissionNpc()
{
}
void CMissionNpc::setMissions(int nNpcID)
{
//每次进入前要把之前的任务清除
m_vecUnlockedMission.clear();
vector<CMission*> vecUnlockedMission = g_GameMgr->getMissionMgr()->getUnlockMission();
for (int i = 0; i < vecUnlockedMission.size();i++)
{
if (vecUnlockedMission[i]->getNpcID()==nNpcID)
{
m_vecUnlockedMission.push_back(vecUnlockedMission[i]);
}
}
}
void CMissionNpc::updata()
{
if (KEY_DOWN(VK_UP))
{
m_nIndex--;
if (m_nIndex < 0)
{
m_nIndex = m_vecUnlockedMission.size() - 1;
}
}
else if (KEY_DOWN(VK_DOWN))
{
m_nIndex++;
if (m_nIndex >m_vecUnlockedMission.size() - 1)
{
m_nIndex = 0;
}
}
if (KEY_DOWN(VK_ESCAPE))
{
g_GameMgr->recoverWnd();
}
if (KEY_DOWN(VK_RETURN))
{
updataMission();
}
}
void CMissionNpc::onRander()
{
for (int i = 0; i < m_vecUnlockedMission.size();i++)
{
if (i==m_nIndex)
{
cout << "->";
}
else
{
cout << " ";
}
m_vecUnlockedMission[i]->showName();
if (i==m_nIndex)
{
cout << "\t";
m_vecUnlockedMission[i]->showDescripe();
}
cout << endl;
}
}
void CMissionNpc::updataMission()
{
if (!m_vecUnlockedMission.empty())
{
//如果当前任务已经接受.
if (m_vecUnlockedMission[m_nIndex]->getisRecived())
{
//更新任务状态
m_vecUnlockedMission[m_nIndex]->updataIsAchieve();
if (m_vecUnlockedMission[m_nIndex]->getisAchieve())
{
if (!m_vecUnlockedMission[m_nIndex]->getFinishTalk()->getIsTalked())
{
//进行完成任务时候的对话
g_GameMgr->changWnd(m_vecUnlockedMission[m_nIndex]->getFinishTalk());
}
else
{
m_vecUnlockedMission[m_nIndex]->getReward();
//将任务从待接任务中移除。
SAFE_DELET(m_vecUnlockedMission[m_nIndex]);
m_vecUnlockedMission.erase(m_vecUnlockedMission.begin() + m_nIndex);
//回到地图
g_GameMgr->recoverWnd();
}
}
else
{
cout << "请去完成任务再来获取奖励" << endl;
}
}
//如果当前任务并未接受
else
{
//男人的任务
if (m_vecUnlockedMission[m_nIndex]->getID() == 6005)
{
g_GameMgr->getGameMap()->getplayer()->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3012));
}
//女人的任务
else if (m_vecUnlockedMission[m_nIndex]->getID() == 6006)
{
g_GameMgr->getGameMap()->getplayer()->getPackage()->addItem(g_DataMgr->getIteamDtMgr()->getByID(3014));
}
//按下return键位,接受当前任务,将该任务是否被接受设置为被接受,将当前任务目标置零,是否完成置为false
m_vecUnlockedMission[m_nIndex]->setisRecived(true);
g_GameMgr->getGameMap()->getplayer()->setKillEnemyNumToZero(m_vecUnlockedMission[m_nIndex]->getID());
m_vecUnlockedMission[m_nIndex]->setisAchieve(false);
//进行接受任务时候的对话
if (!m_vecUnlockedMission[m_nIndex]->getTalk()->getIsTalked())
{
g_GameMgr->changWnd(m_vecUnlockedMission[m_nIndex]->getTalk());
}
///*回到地图界面*/
//g_GameMgr->recoverWnd();
}
}
}
待改进:
任务分为:对话任务,杀怪任务,购买物品任务。
杀怪任务和购买物品可以写成同一种任务:判断玩家背包中是否有足够的相对应的物品(红药水数量、杀某种怪掉落的物品数量),从而判断任务是否完成。对话任务也可以判断玩家背包中是否拥有某一种物品,来判断是否完成任务。所以任务类的任务是否完成可以封装成一个函数,通过传入需要完成任务的物品ID和需要的数量,来判断是否完成。这样,任务的数据就可以配备在表中,而不是我现在这样写死的方式。