map2.c
来自「CS反恐精英1.6的部分C源代码。」· C语言 代码 · 共 2,313 行 · 第 1/5 页
C
2,313 行
// PvPGN YARE MOD V1.0 (Yeat Another Ragnarok Emulator) - (Server)
// Copyright (c) Project-YARE & PvPGN 2003
// www.project-yare.com
// forum.project-yare.net
// www.pvpgn.org
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <arpa/inet.h>
#include "core.h"
#include "mmo.h"
#include "grfio.h"
#include "npc.h"
#include "itemdb.h"
#include "skill_db.h"
#include "save.h"
#include "map2.h"
#include "party.h"
#include "guild.h"
// ADDED on 04/09/2003 --------------
#include "pet.h"
// ----------------------------------
const int packet_len_table[0x200]={
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6,
7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 3, 2, 27,
3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
-1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
90, 86, 24, 6, 30,102, 8, 4, 8, 4, 14, 10, -1, 6, 2, 6,
3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const unsigned short def_aspd[14][13] =
{
{ 500, 650, 700,2000,2000,2000,2000, 650, 700, 800,2000,2000,2000}, /* Novice */
{ 400, 500, 550, 600, 650, 700,2000,2000, 650, 700, 740,2000,2000}, /* Swordman */
{ 500, 600,2000,2000,2000,2000,2000, 700,2000,2000,2000,2000,2000}, /* Mage */
{ 400, 600,2000,2000,2000,2000, 700,2000,2000,2000,2000,2000,2000}, /* Archer */
{ 350,2000,2000,2000,2000,2000,2000, 600, 600,2000,2000,2000,2000}, /* Acolyte */
{ 400, 600, 700,2000,2000,2000,2000,2000, 700, 700, 750,2000,2000}, /* Marchant */
{ 400, 500, 650,2000,2000,2000, 850,2000,2000, 800,2000,2000,2000}, /* Thief */
{ 400, 500, 500, 550, 600, 650,2000,2000, 650, 700, 740,2000,2000}, /* Night */
{ 350,2000,2000,2000,2000,2000,2000, 600, 600,2000,2000,2000, 600}, /* Priest */
{ 500, 600,2000,2000,2000,2000,2000, 700,2000,2000,2000,2000,2000}, /* Wizard */
{ 400, 600, 700,2000,2000,2000,2000,2000, 700, 700, 750,2000,2000}, /* Blacksmith */
{ 400, 600,2000,2000,2000,2000, 600,2000,2000,2000,2000,2000,2000}, /* Hunter */
{ 400, 500, 650,2000,2000,2000,2000,2000,2000, 800,2000, 500,2000}, /* Assasin */
{ 400, 600,2000,2000,2000,2000, 600,2000,2000,2000,2000,2000,2000}, /* kami */
};
int count=0;
int rank;
int char_fd;
int current_attack_m = 0;
char userid[24];
char passwd[24];
char char_ip_str[16];
int char_port;
char map_ip_str[16];
int map_ip;
int map_port;
int map_port_fd;
char mapmove_name[24]="-mapmove-";
char map[MAX_MAP_PER_SERVER][16]={"prontera.gat",""};
struct mmo_map_data map_data[MAX_MAP_PER_SERVER];
int users,users_global;
char *npc_txt[256];
int npc_txt_num=0;
struct skill_db skill_db[MAX_SKILL];//skill database information
struct mmo_chat *last_chat;
struct block_list *object[50000];
int first_free_object_id,last_object_id;
struct mons_data mons_data[4000];
long ExpData[101];//Lvup experience value data
long SkillExpData[3][101];//skill lv up experience data
int PVP_flag=0;
int check_connect_timer;
int send_users_tochar_timer;
int clear_flooritem_timer;
int loop_monstersearch_timer;
int heal_hp_timer;
int heal_sp_timer;
int map_number;
//macro declaration
#define NOM_ATTACK(atk1,atk2,def) ((atk1+rand()%atk2)-def);//normal attack
#define CRI_ATTACK(atk1,atk2,s_lv,s_type) (atk1+atk2+s_lv*s_type);//critical attack
#define KAT_ATTACK(damage) ((damage/5)+1);//second katar attack
#define SKILL_ATTACK(matk1,matk2) (matk2+rand()%matk1);//skill attack
#define SKILL_HEAL(int_,blvl,lvl) ((blvl + int_)/8)*(12 * lvl);//( [ BLv + Int ] / 8 ) * ( 12 * SLv ) formula by Trihan
//#define SKILL_HEAL(int_) (rand()%2000+int_);//heal amount
#define SKILL_BASH(atk1,atk2,lvl) ( ( (atk1+rand()%atk2) * (100+(30*lvl))/100 ) - 0 );//skilllvlbonus = 100% 130 160 depend on skill lvl
// Find char, By SilentAvenger 16/6/03
int find_char(char* cname)
{
int i;
for(i=0;i<FD_SETSIZE;i++)
{
if(session[i]!=NULL && session[i]->session_data!=NULL)
{
struct map_session_data *sd=NULL;
sd = session[i]->session_data;
if(strcmp(sd->status.name,cname)==0) return i;
}
}
return -1;
}
// BugFix by -AL- 15/06/2003
void add_block(struct block_list *bl,int m,int x,int y)
{
struct block_list * head;
int blocknumber;
if(!bl){
printf("[Error] add_block : block_list is NULL\n");
return;
}
if((m<0)||(m>(MAX_MAP_PER_SERVER-1))){
printf("[Error] add_block : wrong map number (%d)\n",m);
return;
}
if((x<0)||(y<0)){
printf("[Error] add_block : x(%d) or y(%d) is negativ\n",x,y);
return;
}
//printf("[Debug] add_block : add (%d,%d,%d)\n",m,x,y);
blocknumber=x/BLOCK_SIZE+(y/BLOCK_SIZE)*map_data[m].bxs;
head = &map_data[m].block[blocknumber];
if (!head){
printf("[Error] add_block : block %d doesn't exist in map %d\n",blocknumber,m);
return;
}
bl->next = head->next;
bl->prev = head;
if(bl->next) bl->next->prev = bl;
head->next = bl;
return;
}
void del_block(struct block_list *bl)
{
if(bl->prev==NULL){
printf("del_block link error\n");
exit(1);
}
if(bl->next) bl->next->prev = bl->prev;
bl->prev->next = bl->next;
bl->next = NULL;
bl->prev = NULL;
}
int search_free_object_id(void)
{
int i;
if(first_free_object_id<2 || first_free_object_id>=50000)
first_free_object_id=2;
for(i=first_free_object_id;i<50000;i++)
if(object[i]==NULL)
break;
if(i==50000){
printf("no free object id\n");
return 0;
}
first_free_object_id=i;
if(last_object_id<i)
last_object_id=i;
return i;
}
int delete_object(int id)
{
if(object[id]==NULL)
return 0;
del_block(object[id]);
free(object[id]);
object[id]=NULL;
if(first_free_object_id>id)
first_free_object_id=id;
while(last_object_id>2 && object[last_object_id]==NULL)
last_object_id--;
return 0;
}
int set_pos(unsigned char *p,int x,int y)
{
*p=x>>2;
p[1]=(x<<6) | ((y>>4)&0x3f);
p[2]=y<<4;
return 0;
}
int set_2pos(unsigned char *p,int x0,int y0,int x1,int y1)
{
*p=x0>>2;
p[1]=(x0<<6) | ((y0>>4)&0x3f);
p[2]=(y0<<4) | ((x1>>6)&0x0f);
p[3]=(x1<<2) | ((y1>>8)&0x03);
p[4]=y1;
return 0;
}
int set_map(struct map_session_data *sd,char *mapname,int x,int y)
{
int i;
if(sd==NULL)
return -1;
sd->x = x;
sd->y = y;
memcpy(sd->mapname,mapname,16);
for(i=0;map[i][0];i++)
if(strcmp(map[i],mapname)==0)
break;
if(map[i][0]){
sd->mapno=i;
// printf("mapno %d \n",i);
}
else
return 1; // must send 0092?
if(sd->x <0 || sd->x >= map_data[i].xs)
sd->x=0;
if(sd->y <0 || sd->y >= map_data[i].ys)
sd->y=0;
add_block(&sd->block,i,sd->x,sd->y);
map_data[i].users++;
return 0;
}
int wait_close(int tid,unsigned int tick,int id,int data)
{
if(session[id]==NULL)
return 0;
session[id]->eof=1;
return 0;
}
int parse_tochar(int fd)
{
struct map_session_data *sd=NULL;
int i,j,fdc;
if(session[fd]->eof){
if(fd==char_fd)
char_fd=-1;
printf("parse_tochar close %d\n",fd);
close(fd);
delete_session(fd);
return 0;
}
//printf("parse_tochar : %d %d %d\n",fd,RFIFOREST(fd),RFIFOW(fd,0));
while(RFIFOREST(fd)>=2){
switch(RFIFOW(fd,0)){
case 0x2af9:
if(RFIFOREST(fd)<3)
return 0;
if(RFIFOB(fd,2)){
printf("connect char server error : %d\n",RFIFOB(fd,2));
exit(1);
}
RFIFOSKIP(fd,3);
WFIFOW(fd,0)=0x2afa;
for(i=0;map[i][0];i++){
memcpy(WFIFOP(fd,4+i*16),map[i],16);
}
WFIFOW(fd,2)=4+i*16;
WFIFOSET(fd,WFIFOW(fd,2));
break;
case 0x2afb:
if(RFIFOREST(fd)<3)
return 0;
if(RFIFOB(fd,2)!=0){
printf("send map error :%d\n",RFIFOB(fd,2));
exit(1);
}
RFIFOSKIP(fd,3);
break;
case 0x2afd:
if(RFIFOREST(fd)<4 || RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
for(i=0;i<FD_SETSIZE;i++)
if(session[i] && (sd=session[i]->session_data) && sd->account_id==RFIFOL(fd,4))
break;
for(j=i+1;j<FD_SETSIZE;j++){
struct map_session_data *tmp_sd;
if(session[j] && (tmp_sd=session[j]->session_data) && tmp_sd->account_id==RFIFOL(fd,4))
break;
}
if(j!=FD_SETSIZE){
//after certification, both players are dropped on a double login
//printf("Output 1 : %d / Output 2 : %d",session[i]->wdata_size,session[i]->wdata);
/* Testing fix by removing packets to null connections... and just raw closing the socket.. (hud) */
if ((i<FD_SETSIZE) && session[i] && session[i]->session_data)
{
WFIFOW(i,0)=0x81;
WFIFOB(i,2)=8;
WFIFOSET(i,3);
add_timer(gettick()+100,wait_close,i,0);
}
if ((j<FD_SETSIZE) && session[j] && session[j]->session_data)
{
WFIFOW(j,0)=0x81;
WFIFOB(j,2)=8;
WFIFOSET(j,3);
add_timer(gettick()+100,wait_close,j,0);
}
} else if(i!=FD_SETSIZE){
fdc=i;
memcpy(&sd->status,RFIFOP(fd,12),sizeof(sd->status));
set_map(sd,sd->status.last_point.map , sd->status.last_point.x , sd->status.last_point.y);
sd->speed = DEFAULT_WALK_SPEED;
sd->sitting=0;
sd->dir=0;
sd->head_dir=0;
WFIFOW(fdc,0)=0x73;
WFIFOL(fdc,2)=gettick();
set_pos(WFIFOP(fdc,6),sd->x,sd->y);
WFIFOB(fdc,9)=5;
WFIFOB(fdc,10)=5;
WFIFOSET(fdc,11);
sd->state.auth=1;
// ADDED on 04/09/2003 -------------
//pet_init(sd);
sd->status.pet.pet_id_as_npc = -1;
//printf("PET_ID=%d, ACTIVITY=%d\n",sd->status.pet.pet_id_as_npc,sd->status.pet.activity);
// ---------------------------------
}
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
case 0x2afe:
if(RFIFOREST(fd)<7)
return 0;
for(i=0;i<FD_SETSIZE;i++)
if(session[i] && (sd=session[i]->session_data) && sd->account_id==RFIFOL(fd,4))
break;
if(i!=FD_SETSIZE){
close(i);
session[i]->eof=1;
}
RFIFOSKIP(fd,7);
break;
case 0x2b00:
if(RFIFOREST(fd)<6)
return 0;
users_global=RFIFOL(fd,2);
RFIFOSKIP(fd,6);
break;
case 0x2b03:
if(RFIFOREST(fd)<7)
return 0;
for(i=0;i<FD_SETSIZE;i++)
if(session[i] && (sd=session[i]->session_data) && sd->account_id==RFIFOL(fd,2))
break;
if(i!=FD_SETSIZE){
WFIFOW(i,0)=0xb3;
WFIFOB(i,2)=1;
WFIFOSET(i,3);
}
RFIFOSKIP(fd,7);
break;
default:
printf("parse_tochar3 close %d %d\n",fd,RFIFOW(fd,0));
close(fd);
session[fd]->eof=1;
return 0;
}
}
return 0;
}
int mmo_map_sendblock(int m,int bx,int by,char *dat,int len,int srcfd,int wos)
{
struct block_list *bl;
struct map_session_data *srcsd,*dstsd;
int fd,c=0;
if(bx<0 || bx>=map_data[m].bxs ||
by<0 || by>=map_data[m].bys)
return 0;
bl=map_data[m].block[bx + by*map_data[m].bxs].next;
if(session[srcfd])
srcsd=session[srcfd]->session_data;
else
srcsd=NULL;
for(;bl;bl=bl->next){
if(bl->type==BL_PC){
dstsd=(struct map_session_data *)bl;
fd=dstsd->fd;
if(wos && fd == srcfd)
continue;
if(wos==2 && dstsd->chatID)
continue;
if(wos==3 && srcsd && srcsd->chatID==dstsd->chatID)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?