map2.c

来自「CS反恐精英1.6的部分C源代码。」· C语言 代码 · 共 2,313 行 · 第 1/5 页

C
2,313
字号
  if(len>0) WFIFOSET(fd,len);
  // ASPD
  len=mmo_map_set_param(fd,WFIFOP(fd,0),SP_ASPD);
  if(len>0) WFIFOSET(fd,len);
  // skill
  //skill information and aquisition 
  len=mmo_map_all_skill(fd,WFIFOP(fd,0),sd->status.skill_point,0);
  if(len>0) WFIFOSET(fd,len);
  return 0;
}

/*reworking jobchange function (experimental)*/
int mmo_map_jobchange(int fd,int class)
{
  int len;
  struct map_session_data *sd;

  sd=session[fd]->session_data;
  //Fred JobLevel Reset ;)    
  sd->status.job_level=1;
  WFIFOW(fd,0) = 0xb0;
  WFIFOW(fd,2) = 0x37;
  WFIFOL(fd,4) = 1;
  WFIFOSET(fd,8);
  //Hud Skill Point Reset
  mmo_map_update_param(fd,SP_SKILLPOINT,-(sd->status.skill_point));
  sd->status.class=class;
  //the argument you see changes (3~)丂sd->account_id(apply ID)LOOK_BASE乮substance乯,sd->status.class(type)
  len=mmo_map_set_look(fd,WFIFOP(fd,0),sd->account_id,LOOK_BASE,sd->status.class);
  if(len>0) mmo_map_sendarea(fd,WFIFOP(fd,0),len,0);
  mmo_map_calc_status(fd,0,0);
  len = mmo_map_all_skill(fd,WFIFOP(fd,0),sd->status.skill_point,0);
	 if(len>0) WFIFOSET(fd,len);
  return 0;
}

int mmo_map_make_flooritem(struct item *item_data,int amount,int m,int x,int y)
{
  int i,j,c,free_cell,r;
  int id;
  struct flooritem_data *fitem;
  unsigned char buf[64];
  int len;

  if((id=search_free_object_id())==0)
    return 0;

  // (x-1,y-1)-(x+1,y+1) possible cell searching among them. random drops?
  for(free_cell=0,i=-1;i<=1;i++){
    if(i+y<0 || i+y>=map_data[m].ys)
      continue;
    for(j=-1;j<=1;j++){
      if(j+x<0 || j+x>=map_data[m].xs)
	continue;
      if((c=map_data[m].gat[j+x+(i+y)*map_data[m].xs])==1 || c==5)
	continue;
      free_cell++;
    }
  }
  if(free_cell==0)
    return 0;
  r=rand();
  free_cell=r%free_cell;
  r=r>>4;
  for(i=-1;i<=1;i++){
    if(i+y<0 || i+y>=map_data[m].ys)
      continue;
    for(j=-1;j<=1;j++){
      if(j+x<0 || j+x>=map_data[m].xs)
	continue;
      if((c=map_data[m].gat[j+x+(i+y)*map_data[m].xs])==1 || c==5)
	continue;
      if(free_cell==0){
	x+=j;
	y+=i;
	i=3;
	break;
      }
      free_cell--;
    }
  }

  fitem=malloc(sizeof(*fitem));
  object[id]=&fitem->block;
  fitem->id=id;
  fitem->m=m;
  fitem->x=x;
  fitem->y=y;
  memcpy(&fitem->item_data,item_data,sizeof(*item_data));
  fitem->item_data.amount=amount;
  fitem->subx=(r&3)*3+3;
  fitem->suby=((r>>2)&3)*3+3;
  fitem->drop_tick=gettick();
  //printf("(%d,%d)+(%d,%d)\n",fitem->x,fitem->y,fitem->subx,fitem->suby);

  fitem->block.type=BL_ITEM;
  add_block(&fitem->block,fitem->m,fitem->x,fitem->y);

  len=mmo_map_set_dropitem(0,buf,fitem);
  if(len>0)
    mmo_map_sendarea_mxy(m,x,y,buf,len);

  return id;
}

int mmo_map_dropitem(int fd,int index,int amount)
{
  int len;
  struct map_session_data *sd;
  struct item item_data_tmp;

  if(index<2 || index>=MAX_INVENTORY+2)
    return -1;
  sd=session[fd]->session_data;
  memcpy(&item_data_tmp,&sd->status.inventory[index-2],sizeof(item_data_tmp));
  len=mmo_map_item_lost(fd,WFIFOP(fd,0),index,amount);
  if(len<=0)
    return -1;
  WFIFOSET(fd,len);
  mmo_map_make_flooritem(&item_data_tmp,amount,sd->mapno,sd->x,sd->y);
  return 0;
}

int mmo_map_takeitem(int fd,int item_id)
{
  int len;
  struct map_session_data *sd;
  struct flooritem_data *fitem;

  if(item_id<2 || item_id>=50000 || object[item_id]==NULL || object[item_id]->type!=BL_ITEM)
    return -1;

  sd=session[fd]->session_data;
  fitem=(struct flooritem_data*)object[item_id];

  len=mmo_map_item_get(fd,WFIFOP(fd,0),&fitem->item_data);
  if(len>0){
    WFIFOSET(fd,len);

    WFIFOW(fd,0)=0x8a;	// take motion
    WFIFOL(fd,2)=sd->account_id;
    WFIFOL(fd,6)=item_id;
    WFIFOL(fd,10)=gettick();
    WFIFOB(fd,26)=1;
    mmo_map_sendarea(fd,WFIFOP(fd,0),packet_len_table[0x8a],0);

    WFIFOW(fd,0)=0xa1;	// delete floor item
    WFIFOL(fd,2)=item_id;
    mmo_map_sendarea(fd,WFIFOP(fd,0),packet_len_table[0xa1],0);

    delete_object(item_id);
  }

  return 0;
}

int clear_flooritem(int tid,unsigned int tick,int id,int data)
{
  int i;
  struct flooritem_data *fitem;
  unsigned char buf[64];

  for(i=2;i<=last_object_id;i++){
    if(object[i]==NULL || object[i]->type!=BL_ITEM)
      continue;
    fitem=(struct flooritem_data *)object[i];
    if(tick-fitem->drop_tick < LIFETIME_FLOORITEM*1000)
      continue;

    WBUFW(buf,0)=0xa1;	// delete floor item
    WBUFL(buf,2)=i;
    mmo_map_sendarea_mxy(fitem->m,fitem->x,fitem->y,buf,packet_len_table[0xa1]);

    delete_object(i);
  }
  return 0;
}

#define MAX_TMP_PATH (150)

int calc_cost(struct mmo_tmp_path *p,int x1,int y1)
{
  int xd,yd;
  xd=x1-p->x;
  if(xd<0) xd=-xd;
  yd=y1-p->y;
  if(yd<0) yd=-yd;
  return (xd+yd)*10+p->dist;
}

int add_path(struct mmo_tmp_path *path,int *wp,int x,int y,int dist,int dir,int before,int x1,int y1)
{
  int i;
  for(i=0;i<*wp;i++)
    if(path[i].x==x && path[i].y==y){
      if(path[i].dist>dist){
	path[i].dist=dist;
	path[i].dir=dir;
	path[i].before=before;
	path[i].cost=calc_cost(&path[i],x1,y1);
	path[i].flag=0;
      }
      return 0;
    }
  //printf("add_path %d %d,%d,%d,%d,%d\n",*wp,x,y,dist,dir,before);
  path[*wp].x=x;
  path[*wp].y=y;
  path[*wp].dist=dist;
  path[*wp].dir=dir;
  path[*wp].before=before;
  path[*wp].cost=calc_cost(&path[*wp],x1,y1);
  path[*wp].flag=0;
  *wp=*wp+1;
  return 0;
}

int can_move(struct mmo_map_data *m,int x0,int y0,int x1,int y1)
{
  int c;

  if(x0-x1<-1 || x0-x1>1 || y0-y1<-1 || y0-y1>1)
    return 0;
  if(x1<0 || y1<0 || x1>=m->xs || y1>=m->ys)
    return 0;
  if((c=m->gat[x0+y0*m->xs])==1 || c==5)
    return 0;
  if((c=m->gat[x1+y1*m->xs])==1 || c==5)
    return 0;
  if(x0==x1 || y0==y1)
    return 1;
  if(((c=m->gat[x0+y1*m->xs])==1 || c==5) ||
     ((c=m->gat[x1+y0*m->xs])==1 || c==5))
    return 0;
  return 1;
}

//FRED11
int search_path(struct map_session_data *sd,int mapno,int x0,int y0,int 
x1,int y1,int easy_only)
{
 struct mmo_tmp_path tmp_path[MAX_TMP_PATH];
 int rp,wp,i;
 int x,y,dx,dy;
 struct mmo_map_data *m;

// printf("search_path %s (%d,%d)-(%d,%d)n",map[mapno],x0,y0,x1,y1);
 if(!map[mapno][0])
   return -1;
 m=&map_data[mapno];
 if( (x0>0) && (y0>0)&& (x1>0) &&(y1>0) ) {
 // easy
 dx = (x1-x0<0) ? -1 : 1;
 dy = (y1-y0<0) ? -1 : 1;
 for(x=x0,y=y0,i=0;(x!=x1 || y!=y1) && (i<64);){
   
   if (x!=x1 && y!=y1) {
     if(!can_move(m,x,y,x+dx,y+dy))
      break;
   x+=dx;
   y+=dy;
   sd->walkpath[i++]=(dx<0) ? ((dy>0)? 1 : 3) : ((dy<0)? 5 : 7);
    } 
    
    else if ( x!=x1) {
         if(!can_move(m,x,y,x+dx,y   ))
         break;
     x+=dx;
     sd->walkpath[i++]=(dx<0) ? 2 : 6;
   } 
   else { // y!=y1
              if(!can_move(m,x,y,x   ,y+dy))
          break;
        y+=dy;
        sd->walkpath[i++]=(dy>0) ? 0 : 4;
    }
    
         if(x==x1 && y==y1){
             sd->walkpath_len=i;
             sd->walkpath_pos=0;
             return 0;
         }

}

 if(easy_only)
   return -1;

 // difficult
 wp=0;
 tmp_path[wp].x=x0;
 tmp_path[wp].y=y0;
 tmp_path[wp].dist=0;
 tmp_path[wp].dir=0;
 tmp_path[wp].before=0;
 tmp_path[wp].cost=calc_cost(&tmp_path[wp],x1,y1);
 tmp_path[wp++].flag=0;
 while(1){
   int min_cost,min_pos,max_dist;
   for(i=0,min_cost=65536,max_dist=-1,min_pos=-1;i<wp;i++){
     if(tmp_path[i].flag==0 && (tmp_path[i].cost<min_cost || 
(tmp_path[i].cost==min_cost && tmp_path[i].dist>max_dist))){
    min_pos=i;
    min_cost=tmp_path[i].cost;
    max_dist=tmp_path[i].dist;
     }
   }
   if(min_pos<0)
     return -1;
   rp=min_pos;
   x=tmp_path[rp].x;
   y=tmp_path[rp].y;
   if(x==x1 && y==y1){
     int len,j;
     for(len=0,i=rp;len<100 && i!=0;i=tmp_path[i].before,len++);
     if(len==100 || len>=sizeof(sd->walkpath))
    return -1;
     sd->walkpath_len=len;
     sd->walkpath_pos=0;
     for(i=rp,j=len-1;i!=0;i=tmp_path[i].before,j--)
    sd->walkpath[j]=tmp_path[i].dir;
     //printf("search path ok (%d,%d)-(%d,%d) ",x0,y0,x1,y1);
     //for(i=0;i<len;i++)
     //printf("%d",sd->walkpath[i]);
     //printf("n");
     return 0;
   }
   if(can_move(m,x,y,x+1,y-1))
     add_path(tmp_path,&wp,x+1,y-1,tmp_path[rp].dist+14,5,rp,x1,y1);
   if(can_move(m,x,y,x+1,y  ))
     add_path(tmp_path,&wp,x+1,y  ,tmp_path[rp].dist+10,6,rp,x1,y1);
   if(can_move(m,x,y,x+1,y+1))
     add_path(tmp_path,&wp,x+1,y+1,tmp_path[rp].dist+14,7,rp,x1,y1);
   if(can_move(m,x,y,x  ,y+1))
     add_path(tmp_path,&wp,x  ,y+1,tmp_path[rp].dist+10,0,rp,x1,y1);
   if(can_move(m,x,y,x-1,y+1))
     add_path(tmp_path,&wp,x-1,y+1,tmp_path[rp].dist+14,1,rp,x1,y1);
   if(can_move(m,x,y,x-1,y  ))
     add_path(tmp_path,&wp,x-1,y  ,tmp_path[rp].dist+10,2,rp,x1,y1);
   if(can_move(m,x,y,x-1,y-1))
     add_path(tmp_path,&wp,x-1,y-1,tmp_path[rp].dist+14,3,rp,x1,y1);
   if(can_move(m,x,y,x  ,y-1))
     add_path(tmp_path,&wp,x  ,y-1,tmp_path[rp].dist+10,4,rp,x1,y1);
   if(wp>=MAX_TMP_PATH-5)
     return -1;
   tmp_path[rp].flag=1;
 }
 return -1;
}
return -1;  
}

int calc_next_walk_step(int fd)
{
  struct map_session_data *sd;

  if(session[fd]==NULL || (sd=session[fd]->session_data)==NULL)
    return -1;
  if(sd->walkpath_pos>=sd->walkpath_len)
    return -1;
  if(sd->walkpath[sd->walkpath_pos]&1)
    return sd->speed*14/10;
  return sd->speed;
}

int mmo_map_changemap(int id,struct map_session_data *sd,char *mapname,int x,int y,int type)
{
	int m,j;
	m=sd->mapno;
	  //changing maps while escaping
	for(j=0;j<map_data[m].npc_num;j++){
		if(map_data[m].npc[j]->block.subtype==MONS){//if monster
			if(map_data[m].npc[j]->u.mons.target_id == sd->account_id){
				mmo_mons_attack_no(m,j,sd->account_id,gettick());
				}
	  		}
	}
  del_block(&sd->block);

	// pet processing
	if(sd->status.pet.activity == 1)
	{
		// changing maps on the same server
		WFIFOW(id,0) = 0x80;
		WFIFOL(id,2) = sd->status.pet.pet_id_as_npc;
		WFIFOB(id,6) = 0;
		WFIFOSET(id,7);

		del_block(&map_data[sd->mapno].npc[sd->status.pet.pet_npc_id_on_map[sd->mapno]]->block);
	}

  WFIFOW(id,0)=0x80;
  WFIFOL(id,2)=sd->account_id;
  WFIFOB(id,6)=type;
  mmo_map_sendarea(id,WFIFOP(id,0),packet_len_table[0x80], 1 );
  current_attack_m=0;
  map_data[sd->mapno].users--;
  set_map(sd,mapname,x,y);
  WFIFOW(id,0)=0x91; // in same server move
  memcpy(WFIFOP(id,2),mapname,16);
  WFIFOW(id,18)=x;
  WFIFOW(id,20)=y;
  WFIFOSET(id,22);
  return 0;
}

int walk_char(int tid,unsigned int tick,int id,int data)
{
  struct map_session_data *sd;
  int i,m,nx,ny,dx,dy;
  static int dirx[8]={0,-1,-1,-1,0,1,1,1};
  static int diry[8]={1,1,0,-1,-1,-1,0,1};
  // ADDED on 04/09/2003 ------------------
  char buf[256];
  // --------------------------------------

  //printf("walk_char %d %08x %d\n",id,tick,data);

  if(session[id]==NULL || (sd=session[id]->session_data)==NULL)
    return 0;
  if(sd->walktimer != tid){
    //printf("walk_char %d != %d\n",sd->walktimer,tid);
    return 0;
  }
  if(sd->walkpath_pos>=sd->walkpath_len || sd->walkpath_pos!=data || sd->walktimer<0){
    sd->walktimer=-1;
    return 0;
  }
  dx=dirx[(int)sd->walkpath[sd->walkpath_pos]];
  dy=diry[(int)sd->walkpath[sd->walkpath_pos]];
  nx=sd->x+dx;
  ny=sd->y+dy;
  if(nx/BLOCK_SIZE != sd->x/BLOCK_SIZE || ny/BLOCK_SIZE != sd->y/BLOCK_SIZE){
    unsigned char buf[256];
    int bx,by;
    bx=sd->x/BLOCK_SIZE;
    by=sd->y/BLOCK_SIZE;
    WBUFW(buf,0)=0x80;
    WBUFL(buf,2)=sd->account_id;
    WBUFB(buf,6)=0;	// no effect?
    if(nx/BLOCK_SIZE != sd->x/BLOCK_SIZE && bx-dx*AREA_SIZE>=0 && bx-dx*AREA_SIZE<map_data[sd->mapno].bxs){
      for(i=-AREA_SIZE;i<=AREA_SIZE;i++){
	if(by+i < 0 || by+i >= map_data[sd->mapno].bys)
	  continue;
	mmo_map_sendblock(sd->mapno,bx-dx*AREA_SIZE,by+i,buf,packet_len_table[0x80],id,1);
	mmo_map_clrblockchar(id,sd->mapno,bx-dx*AREA_SIZE,by+i);
      }
    }
    if(ny/BLOCK_SIZE != sd->y/BLOCK_SIZE && by-dy*AREA_SIZE>=0 && by-dy*AREA_SIZE<map_data[sd->mapno].bys){
      for(i=-AREA_SIZE;i<=AREA_SIZE;i++){
	if(bx+i < 0 || bx+i >= map_data[sd->mapno].bxs)
	  continue;
	mmo_map_sendblock(sd->mapno,bx+i,by-dy*AREA_SIZE,buf,packet_len_table[0x80],id,1);
	mmo_map_clrblockchar(id,sd->mapno,bx+i,by-dy*AREA_SIZE);
      }
    }
    del_block(&sd->block);
    add_block(&sd->block,sd->mapno,nx,ny);
    mmo_map_set007b(id,buf,tick,sd->x,sd->y,sd->to_x,sd->to_y);
    bx=nx/BLOCK_SIZE;
    by=ny/BLOCK_SIZE;
    if(nx/BLOCK_SIZE != sd->x/BLOCK_SIZE && bx+dx*AREA_SIZE>

⌨️ 快捷键说明

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