📄 npc_stoneserviceman.c
字号:
//Terry 2001/09/27
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "char.h"
#include "object.h"
#include "char_base.h"
#include "npcutil.h"
#include "lssproto_serv.h"
#include "npc_stoneserviceman.h"
#include "readmap.h"
#include "battle.h"
#include "log.h"
#include "enemy.h"
#include "configfile.h"
#ifdef _SERVICE
#define LOOP_TIME 100 //0.1秒(进入loop function 的时间)
#define MAX_AP_MSG 128 // 接收AP送来讯息的最大数
// socket struct
struct socketaddr_in
{
u_short sin_family;
u_short sin_port;
u_long sin_addr;
char sin_zero[8];
};
// 接收AP传来的讯息
typedef struct _MSG
{
int nAid; // nAid => 流水号*10 + 讯息代号(_AP_CLIENT_MESSAGE)
int nIndex; // NPC的index值
int nLen; // 讯息长度
LPList Data; // 实际资料
int bIsUse; // 这个讯息是否有使用过
}Msg,*pMsg;
Msg g_APMsg[MAX_AP_MSG];
// 动作id
enum _AP_CLIENT_MESSAGE
{
Cli_CHECKPLAYER, //要求AP对玩家是否有购买产品的确认 0
AP_CHECKPLAYER, //AP回应玩家是否有购买产品
Cli_YES, //玩家确定要将奖品拿走
Cli_CANCEL, //通知AP把lock栏位清为0
Cli_GET, //通知AP给物品
AP_GET, //AP回应物品 5
Cli_CONNECT, //测试是否有连到AP
AP_CONNECT, //AP回应
AP_ERROR //AP有错误
};
// NPC的工作变数
enum
{
NPC_WORK_FLAG1 = CHAR_NPCWORKINT2, //flag1
NPC_WORK_FLAG2 = CHAR_NPCWORKINT3, //flag2
NPC_WORK_FLAG3 = CHAR_NPCWORKINT4, //flag3
NPC_WORK_TIMEOUT = CHAR_NPCWORKINT5, //time out 时间
NPC_WORK_STATE = CHAR_NPCWORKINT6, //目前执行状态
NPC_WORK_START = CHAR_NPCWORKINT7, //开始计时flag
NPC_WORK_LEAVE_COUNT = CHAR_NPCWORKINT8, //玩家talk时间计时
NPC_WORK_TOINDEX = CHAR_NPCWORKINT9, //玩家的index值
NPC_WORK_SERIALNUM = CHAR_NPCWORKINT10, //流水号
NPC_WORK_ISUSE = CHAR_NPCWORKINT11, //目前NPC是否有玩家在使用
};
// 执行的状态
enum
{
SERVICE_STATE_1, // check 有没有和AP连线中
SERVICE_STATE_2, // 向AP取得玩家有无买产品
SERVICE_STATE_3, // 取得要给玩家的东西的资料
SERVICE_STATE_4 // end state
};
extern int errno;
int g_nServiceSocket;
int g_EnableService = 0;
char g_ApID[32];
struct socketaddr_in server_sin;
struct sockaddr temp;
unsigned short g_Port;
static void NPC_StoneServiceMan_selectWindow(int meindex,int toindex,int num,int select);
extern int GetSerialNum(void);
static int flag = 1;
/*********************************
* 初始化
*********************************/
BOOL NPC_StoneServiceManInit(int meindex )
{
char npcarg[NPC_UTIL_GETARGSTR_BUFSIZE];
if(NPC_Util_GetArgStr(meindex,npcarg,sizeof(npcarg)) == NULL){
print("StoneServiceMan:GetArgStrErr");
return FALSE;
}
CHAR_setInt(meindex,CHAR_LOOPINTERVAL,LOOP_TIME);
CHAR_setInt(meindex,CHAR_WHICHTYPE,CHAR_TYPESTONESERVICEMAN);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG1,1);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,1);
CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
CHAR_setWorkInt(meindex,NPC_WORK_STATE,SERVICE_STATE_2);
CHAR_setWorkInt(meindex,NPC_WORK_START,0);
CHAR_setWorkInt(meindex,NPC_WORK_TOINDEX,-1);
CHAR_setWorkInt(meindex,NPC_WORK_ISUSE,0);
CHAR_setWorkInt(meindex,NPC_WORK_LEAVE_COUNT,0);
CHAR_setWorkInt(meindex,NPC_WORK_SERIALNUM,-1);
g_EnableService = getEnableService();
//连线到AP在init时只做一次
if(flag && g_EnableService){
strcpy(g_ApID,getApID());
g_Port = getApPort();
bzero(g_APMsg,sizeof(g_APMsg));
ConnectToAP();//连线到AP
flag = 0;
}
return TRUE;
}
void NPC_StoneServiceManTalked(int meindex,int talkerindex,char *szMes,int color)
{
if(CHAR_getInt(talkerindex,CHAR_WHICHTYPE) != CHAR_TYPEPLAYER) return;
if(NPC_Util_isFaceToFace(talkerindex,meindex,1) == FALSE) return;
NPC_StoneServiceMan_selectWindow(meindex,talkerindex,0,-1);
}
static void NPC_StoneServiceMan_selectWindow(int meindex,int toindex,int num,int select)
{
char npcarg[NPC_UTIL_GETARGSTR_BUFSIZE];
char token[1024],buf[128],*pUserid;
int buttontype = 0, windowtype = 0, windowno = 0,nAid,nLen;
int fd = getfdFromCharaIndex(toindex);
char Data[3][32],talk[128];
int i,j,k,Ret;
LPList DataList = NULL,Kill = NULL;
if(fd == -1)
{
print("getfd err\n");
return;
}
if(NPC_Util_GetArgStr(meindex,npcarg,sizeof(npcarg)) == NULL)
{
print("GetArgStrErr");
return ;
}
token[0] = '\0';
//如果不使用石器服务员的功能
if(!g_EnableService)
{
sprintf(token,"\n 请到此星系的最後一颗星球使用此服务,谢谢!");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_WAIT;
lssproto_WN_send(fd,windowtype,buttontype,windowno,
CHAR_getWorkInt(meindex,CHAR_WORKOBJINDEX),
token);
return;
}
//如果这个玩家是第一个和NPC讲话
if(CHAR_getWorkInt(meindex,NPC_WORK_ISUSE) == 0 &&
CHAR_getWorkInt(meindex,NPC_WORK_TOINDEX) == -1)
{
//记住第一个和NPC讲话的是谁
CHAR_setWorkInt(meindex,NPC_WORK_TOINDEX,toindex);
//设定为NPC正在使用中
CHAR_setWorkInt(meindex,NPC_WORK_ISUSE,1);
}
//如果是第二个以後和NPC讲话的人
else if(CHAR_getWorkInt(meindex,NPC_WORK_ISUSE) == 1 &&
CHAR_getWorkInt(meindex,NPC_WORK_TOINDEX) != toindex)
{
sprintf(token,"\n 正在服务其他玩家中,请稍等...");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_WAIT;
lssproto_WN_send(fd,windowtype,buttontype,windowno,
CHAR_getWorkInt(meindex,CHAR_WORKOBJINDEX),
token);
return;
}
if(flag)
{
ConnectToAP();
flag = 0;
}
switch(num)
{
case 0:
case 1:
//取得玩家的id
pUserid = CHAR_getChar(toindex,CHAR_CDKEY);
if(CHAR_getWorkInt(meindex,NPC_WORK_FLAG2) == 1)
{
if(pUserid == NULL || SendToAP(Cli_CHECKPLAYER,meindex,1,pUserid,NULL) == 0)
{
if(NPC_Util_GetStrFromStrWithDelim(npcarg,"SysBusyMsg",buf,sizeof(buf)) == NULL) return;
sprintf(token,"\n %s",buf);
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
break;
}
CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,0);
CHAR_setWorkInt(meindex,NPC_WORK_START,1);
}
if(CHAR_getWorkInt(meindex,NPC_WORK_STATE) == SERVICE_STATE_2)
{
// 超过五秒time out
if(CHAR_getWorkInt(meindex,NPC_WORK_TIMEOUT) >= 50)
{
close(g_nServiceSocket);
flag = 1;
sprintf(token,"\n 重新与系统取得连线...");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
CHAR_setWorkInt(meindex,NPC_WORK_START,0);
break;
}
if((Ret = RecvFromAP(&nAid,meindex,&nLen,&DataList)) == -1)
{
sprintf(token,"\n 等待回应...");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
break;
}
else
{
for(i=0;i<nLen;i++)
{
strcpy(Data[i],DataList->Data);
Kill = DataList;
DataList = DataList->Next;
if(Kill != NULL) free(Kill);
}
// 使用过的讯息清空
bzero(&g_APMsg[Ret],sizeof(Msg));
}
if(nAid == AP_CHECKPLAYER)
{
switch(atoi(Data[0]))
{
case 0: //没买
if(NPC_Util_GetStrFromStrWithDelim(npcarg,"ErrMsg",buf,sizeof(buf)) == NULL) return;
sprintf(token,"\n %s",buf);
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
break;
case 1: //有买
if(NPC_Util_GetStrFromStrWithDelim(npcarg,"MainMsg",buf,sizeof(buf)) == NULL) return;
sprintf(token,"5\n %s"
"\n 你要将%s"
"\n 的奖品给这个角色吗?\n"
"\n"
"\n 《 确 定 》"
"\n"
"\n 《 取 消 》",
buf,Data[1]);
buttontype = WINDOW_BUTTONTYPE_NONE;
windowtype = WINDOW_MESSAGETYPE_SELECT;
windowno = CHAR_WINDOWTYPE_SERVICE_START;
break;
//另一个角色正在使用中
case 2:
sprintf(token,"\n 目前您的另一个角色正在领取.");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
break;
//玩家的奖品已领完
case 3:
sprintf(token,"\n 您的奖品已经领完了!!");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
break;
break;
}
}
else
{
sprintf(token,"\n 系统讯息错误!!(%d)",nAid);
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
}
CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG2,1);
}
else
{
sprintf(token,"\n 等待回应...");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
}
break;
case 2:
//取得玩家的id
pUserid = CHAR_getChar(toindex,CHAR_CDKEY);
if(CHAR_getWorkInt(meindex,NPC_WORK_FLAG3) == 1){
if(pUserid == NULL || SendToAP(Cli_GET,meindex,1,pUserid,NULL) == 0){
if(NPC_Util_GetStrFromStrWithDelim(npcarg,"SysBusyMsg",buf,sizeof(buf)) == NULL) return;
sprintf(token,"\n %s",buf);
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_EXIT;
break;
}
CHAR_setWorkInt(meindex,NPC_WORK_START,1);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,0);
}
if(CHAR_getWorkInt(meindex,NPC_WORK_STATE) == SERVICE_STATE_3){
// 超过五秒time out
if(CHAR_getWorkInt(meindex,NPC_WORK_TIMEOUT) >= 50){
close(g_nServiceSocket);
flag = 1;
sprintf(token,"\n 重新与系统取得连线...");
buttontype = WINDOW_BUTTONTYPE_OK;
windowtype = WINDOW_MESSAGETYPE_MESSAGE;
windowno = CHAR_WINDOWTYPE_SERVICE_CONTINUE;
CHAR_setWorkInt(meindex,NPC_WORK_TIMEOUT,0);
CHAR_setWorkInt(meindex,NPC_WORK_FLAG3,1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -