📄 npc.c
字号:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "core.h"
#include "mmo.h"
#include "npc.h"
#include "itemdb.h"
#include "script.h"
struct mons_data m_data[99999];
static int npc_id=50000;
extern char npc_txt[];
extern char map[][16];
extern struct mmo_map_data map_data[];
extern int packet_len_table[];
#define WARP_CLASS 45
#define add_block_npc(m,n) {add_block(&map_data[m].npc[n]->block,m,map_data[m].npc[n]->x,map_data[m].npc[n]->y); \
map_data[m].npc[n]->block.type=BL_NPC;}
int mmo_map_npc_say(int fd, unsigned char* buf,unsigned long id, char *string)
{
WBUFW(buf,0)=0xb4;
WBUFW(buf,2)=strlen(string)+9;
WBUFL(buf,4)=id;
strncpy(WBUFP(buf,8), string,strlen(string)+1);
return WBUFW(buf,2);
}
int send_image(int fd,unsigned char *buf, char *name,int type)
{
name[15]=0; //So it doesn't copy more than 15 bytes
WBUFW(buf,0)=0x0145;
strcpy(WBUFP(buf,2),name);
WBUFB(buf,18)=type;
return 19;
}
int mmo_map_npc_next(int fd, unsigned char* buf, unsigned long id)
{
WBUFW(buf,0)=0xb5;
WBUFL(buf,2)=id;
return 6;
}
int mmo_map_npc_close(int fd, unsigned char* buf, unsigned long id)
{
WBUFW(buf,0)=0xb6;
WBUFL(buf,2)=id;
return 6;
}
int mmo_map_npc_select(int fd, unsigned char* buf, unsigned long id, char *string)
{
WBUFW(buf,0)=0xb7;
WBUFW(buf,2)=strlen(string)+9;
WBUFL(buf,4)=id;
strncpy(WBUFP(buf,8), string, strlen(string)+1);
return WBUFW(buf,2);
}
int mmo_map_npc_amount_request(int fd, unsigned char* buf, unsigned long id)
{
WBUFW(buf,0)=0x142;
WBUFL(buf,2)=id;
return 6;
}
int mmo_map_npc_buysell(int fd, unsigned char* buf, unsigned long id)
{
WBUFW(buf,0)=0xc4;
WBUFL(buf,2)=id;
return 6;
}
int mmo_map_npc_buy(int fd, unsigned char* buf, unsigned long id, struct npc_item_list *items, int dc_skill)
{
int i;
WBUFW(buf,0)=0xc6;
for(i=0;items[i].nameid;i++){
WBUFL(buf,4+i*11)=items[i].value;
WBUFL(buf,8+i*11)=items[i].value;
WBUFB(buf,12+i*11)=itemdb_type(items[i].nameid);
WBUFW(buf,13+i*11)=items[i].nameid;
}
WBUFW(buf,2)=i*11+4;
return i*11+4;
}
int mmo_map_npc_sell(int fd, unsigned char* buf, unsigned long id, int oc_skill)
{
int i,c_item=0;
struct map_session_data *sd;
sd=session[fd]->session_data;
WBUFW(buf,0)=0xc7;
for(i=0;i<MAX_INVENTORY;i++) {
if(sd->status.inventory[i].nameid) {
WBUFW(buf,4+c_item*10)=i+2;
WBUFL(buf,6+c_item*10)=itemdb_sellvalue(sd->status.inventory[i].nameid);
WBUFL(buf,10+c_item*10)=WBUFL(buf,6+c_item*10);
c_item++;
}
}
WBUFW(buf,2)=c_item*10+4;
return c_item*10+4;
}
int npc_click(int fd,int npc_id)
{
int npc_len,n;
struct map_session_data *sd;
sd=session[fd]->session_data;
for(n=0;n<map_data[sd->mapno].npc_num;n++)
if(map_data[sd->mapno].npc[n]->id==npc_id)
break;
if(n==map_data[sd->mapno].npc_num ||
map_data[sd->mapno].npc[n]->block.type!=BL_NPC)
return -1;
switch(map_data[sd->mapno].npc[n]->block.subtype){
case SCRIPT:
sd->npc_pc=0;
sd->npc_id=npc_id;
sd->npc_n=n;
run_script(fd,sd);
break;
case SHOP:
npc_len = mmo_map_npc_buysell(fd, WFIFOP(fd,0),npc_id);
WFIFOSET(fd, npc_len);
sd->npc_id=npc_id;
sd->npc_n=n;
break;
}
#if 0
/*NPC test code*/
if(npc_id==1) {
npc_len = mmo_map_npc_say(fd, WFIFOP(fd,0),1,"test");
WFIFOSET(fd, npc_len);
mmo_map_npc_next(fd, WFIFOP(fd,0),1);
WFIFOSET(fd, 6);
}
#endif
return 0;
}
int npc_menu_select(int fd,int npc_id,int sel)
{
struct map_session_data *sd;
sd=session[fd]->session_data;
sd->local_reg[15]=sel;
if(sel==0xff){
sd->npc_pc=0;
sd->npc_id=0;
sd->npc_n=0;
return 0;
}
run_script(fd,sd);
return 0;
}
int npc_next_click(int fd,int npc_id)
{
struct map_session_data *sd;
sd=session[fd]->session_data;
run_script(fd,sd);
return 0;
}
int npc_amount_input(int fd,int npc_id,int val)
{
struct map_session_data *sd;
sd=session[fd]->session_data;
sd->local_reg[14]=val;
run_script(fd,sd);
return 0;
}
int npc_close_click(int fd,int npc_id)
{
return 0;
}
int npc_buysell_selected(int fd,int npc_id,int sell)
{
int npc_len,n;
struct map_session_data *sd;
sd=session[fd]->session_data;
for(n=0;n<map_data[sd->mapno].npc_num;n++)
if(map_data[sd->mapno].npc[n]->id==npc_id)
break;
if(n==map_data[sd->mapno].npc_num ||
map_data[sd->mapno].npc[n]->block.type!=BL_NPC ||
map_data[sd->mapno].npc[n]->block.subtype!=SHOP ||
sd->npc_id!=npc_id)
return -1;
if(sell){
npc_len = mmo_map_npc_sell(fd, WFIFOP(fd,0),npc_id,0);
} else {
npc_len = mmo_map_npc_buy(fd, WFIFOP(fd,0),npc_id,map_data[sd->mapno].npc[n]->u.shop_item,0);
}
WFIFOSET(fd, npc_len);
return 0;
}
struct map_session_data* make_rollback_point(struct map_session_data *sd)
{
struct map_session_data *back;
back=malloc(sizeof(*back));
memcpy(back,sd,sizeof(*back));
return back;
}
int do_rollback(struct map_session_data *sd,struct map_session_data *back)
{
memcpy(sd,back,sizeof(*back));
free(back);
return 0;
}
int delete_rollback_point(struct map_session_data *back)
{
free(back);
return 0;
}
int npc_buy_selected(int fd,void *list,int num)
{
int i,j,n,len,pos;
struct item tmp_item;
struct map_session_data *sd,*back;
int fail=0;
sd=session[fd]->session_data;
for(n=0;n<map_data[sd->mapno].npc_num;n++)
if(map_data[sd->mapno].npc[n]->id==sd->npc_id)
break;
if(n==map_data[sd->mapno].npc_num ||
map_data[sd->mapno].npc[n]->block.type!=BL_NPC ||
map_data[sd->mapno].npc[n]->block.subtype!=SHOP)
return -1;
back=make_rollback_point(sd);
memset(&tmp_item,0,sizeof(tmp_item));
for(i=pos=0;i<num;i++){
tmp_item.amount=RBUFW(list,i*4); // amount
tmp_item.nameid=RBUFW(list,i*4+2); // nameid
tmp_item.identify=1;
for(j=0;map_data[sd->mapno].npc[n]->u.shop_item[j].nameid;j++)
if(map_data[sd->mapno].npc[n]->u.shop_item[j].nameid==tmp_item.nameid)
break;
if(map_data[sd->mapno].npc[n]->u.shop_item[j].nameid==0){
fail=1; // 海お厦面のNPCで卿ってないアイテムが回年されたっぽ
session[fd]->eof=1; // プチっ
break;
}
len=mmo_map_item_get(fd,WFIFOP(fd,pos),&tmp_item);
if(len<=0){
if(len==-1)
fail=3; // 硷梧眶亩册。3它改臂えも雇えられるけど、烫泡なので琵办
else if(len==-2)
fail=2; // 脚翁オ〖バ
else
fail=3; // 奇
break;
}
pos+=len;
sd->status.zeny -= map_data[sd->mapno].npc[n]->u.shop_item[j].value*tmp_item.amount;
if(sd->status.zeny < 0){
fail=1; // お垛稍颅
break;
}
pos+=mmo_map_set_param(fd,WFIFOP(fd,pos),SP_ZENY);
}
if(fail){
do_rollback(sd,back);
} else {
WFIFOSET(fd,pos);
delete_rollback_point(back);
}
WFIFOW(fd,0)=0xca;
WFIFOB(fd,2)=fail;
WFIFOSET(fd,3);
return 0;
}
int npc_sell_selected(int fd,void *list,int num)
{
int i,len,pos;
struct map_session_data *sd,*back;
int fail=0;
sd=session[fd]->session_data;
back=make_rollback_point(sd);
for(i=pos=0;i<num;i++){
sd->status.zeny+=itemdb_sellvalue(sd->status.inventory[RBUFW(list,i*4)-2].nameid)*RBUFW(list,i*4+2);
pos+=mmo_map_set_param(fd,WFIFOP(fd,pos),SP_ZENY);
len=mmo_map_item_lost(fd,WFIFOP(fd,pos),RBUFW(list,i*4),RBUFW(list,i*4+2));
if(len<=0){
fail=1;
break;
}
pos+=len;
}
if(fail){
do_rollback(sd,back);
} else {
WFIFOSET(fd,pos);
delete_rollback_point(back);
}
WFIFOW(fd,0)=0xcb;
WFIFOB(fd,2)=fail;
WFIFOSET(fd,3);
return 0;
}
int set_monster_random_point(int m,int n)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -