⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mob.c

📁 最新的仙镜传说服务器C语言源码
💻 C
📖 第 1 页 / 共 5 页
字号:

		if((pid=tmpsd[i]->status.party_id)>0){	// 僷乕僥傿偵擖偭偰偄傞
			int j=0;
			for(j=0;j<pnum;j++)	// 岞暯僷乕僥傿儕僗僩偵偄傞偐偳偆偐
				if(pt[j].id==pid)
					break;
			if(j==pnum){	// 偄側偄偲偒偼岞暯偐偳偆偐妋擣
				if((p=party_search(pid))!=NULL && p->exp!=0){
					pt[pnum].id=pid;
					pt[pnum].p=p;
					pt[pnum].base_exp=base_exp;
					pt[pnum].job_exp=job_exp;
					pnum++;
					flag=0;
				}
			}else{	// 偄傞偲偒偼岞暯
				pt[j].base_exp+=base_exp;
				pt[j].job_exp+=job_exp;
				flag=0;
			}
		}
		if(flag)	// 奺帺強摼
			pc_gainexp(tmpsd[i],base_exp,job_exp);
	}
	// 岞暯暘攝
	for(i=0;i<pnum;i++)
		party_exp_share(pt[i].p,md->bl.m,pt[i].base_exp,pt[i].job_exp);

	// item drop
	if(!(type&1)) {
		for(i=0;i<8;i++){
			struct delay_item_drop *ditem;
			int drop_rate;

			if(mob_db[md->class].dropitem[i].nameid <= 0)
				continue;
			drop_rate = mob_db[md->class].dropitem[i].p;
			if(drop_rate <= 0 && battle_config.drop_rate0item)
				drop_rate = 1;
			if(drop_rate <= rand()%10000)
				continue;

			ditem=calloc(sizeof(*ditem), 1);
			if(ditem==NULL){
				printf("out of memory : mob_damage\n");
				exit(1);
			}

			ditem->nameid = mob_db[md->class].dropitem[i].nameid;
			ditem->amount = 1;
			ditem->m = md->bl.m;
			ditem->x = md->bl.x;
			ditem->y = md->bl.y;
			ditem->first_sd = mvp_sd;
			ditem->second_sd = second_sd;
			ditem->third_sd = third_sd;
			add_timer(tick+500+i,mob_delay_item_drop,(int)ditem,0);
		}
		if(sd && sd->state.attack_type == BF_WEAPON) {
			for(i=0;i<sd->monster_drop_item_count;i++) {
				struct delay_item_drop *ditem;
				int race = battle_get_race(&md->bl);
				if(sd->monster_drop_itemid[i] <= 0)
					continue;
				if(sd->monster_drop_race[i] & (1<<race) || 
					(mob_db[md->class].mode & 0x20 && sd->monster_drop_race[i] & 1<<10) ||
					(!(mob_db[md->class].mode & 0x20) && sd->monster_drop_race[i] & 1<<11) ) {
					if(sd->monster_drop_itemrate[i] <= rand()%10000)
						continue;

					ditem=calloc(sizeof(*ditem), 1);
					if(ditem==NULL){
						printf("out of memory : mob_damage\n");
						exit(1);
					}

					ditem->nameid = sd->monster_drop_itemid[i];
					ditem->amount = 1;
					ditem->m = md->bl.m;
					ditem->x = md->bl.x;
					ditem->y = md->bl.y;
					ditem->first_sd = mvp_sd;
					ditem->second_sd = second_sd;
					ditem->third_sd = third_sd;
					add_timer(tick+520+i,mob_delay_item_drop,(int)ditem,0);
				}
			}
			if(sd->get_zeny_num > 0)
				pc_getzeny(sd,mob_db[md->class].lv*10 + rand()%(sd->get_zeny_num+1));
		}
		if(md->lootitem) {
			for(i=0;i<md->lootitem_count;i++) {
				struct delay_item_drop2 *ditem;

				ditem=calloc(sizeof(*ditem), 1);
				if(ditem==NULL){
					printf("out of memory : mob_damage\n");
					exit(1);
				}
				memcpy(&ditem->item_data,&md->lootitem[i],sizeof(md->lootitem[0]));
				ditem->m = md->bl.m;
				ditem->x = md->bl.x;
				ditem->y = md->bl.y;
				ditem->first_sd = mvp_sd;
				ditem->second_sd = second_sd;
				ditem->third_sd = third_sd;
				add_timer(tick+540+i,mob_delay_item_drop2,(int)ditem,0);
			}
		}
	}

	// mvp張棟
	if(mvp_sd && mob_db[md->class].mexp > 0 ){
		int j;
		int mexp;
		temp = ((double)mob_db[md->class].mexp * (double)battle_config.mvp_exp_rate * (9.+(double)count)/1000.);
		mexp = (temp > 2147483647.)? 0x7fffffff:(int)temp;
		if(mexp < 1) mexp = 1;
		clif_mvp_effect(mvp_sd);					// 僄僼僃僋僩
		clif_mvp_exp(mvp_sd,mexp);
		pc_gainexp(mvp_sd,mexp,0);
		for(j=0;j<3;j++){
			i = rand() % 3;
			struct item item;
			int ret;
			int drop_rate;
			if(mob_db[md->class].mvpitem[i].nameid <= 0)
				continue;
			drop_rate = mob_db[md->class].mvpitem[i].p;
			if(drop_rate <= 0 && battle_config.drop_rate0item)
				drop_rate = 1;
			if(drop_rate <= rand()%10000)
				continue;
			memset(&item,0,sizeof(item));
			item.nameid=mob_db[md->class].mvpitem[i].nameid;
			item.identify=!itemdb_isequip3(item.nameid);
			clif_mvp_item(mvp_sd,item.nameid);
			if(mvp_sd->weight*2 > mvp_sd->max_weight)
				map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd,second_sd,third_sd,1);
			else if((ret = pc_additem(mvp_sd,&item,1))) {
				clif_additem(sd,0,0,ret);
				map_addflooritem(&item,1,mvp_sd->bl.m,mvp_sd->bl.x,mvp_sd->bl.y,mvp_sd,second_sd,third_sd,1);
			}
			break;
		}
	}

	// <Agit> NPC Event [OnAgitBreak]
	if(md->npc_event[0] && strcmp(((md->npc_event)+strlen(md->npc_event)-13),"::OnAgitBreak") == 0) {
		printf("MOB.C: Run NPC_Event[OnAgitBreak].\n");
		if (agit_flag == 1) //Call to Run NPC_Event[OnAgitBreak]
			guild_agit_break(md);	
	}
	
		// SCRIPT幚峴
	if(md->npc_event[0]){
//		if(battle_config.battle_log)
//			printf("mob_damage : run event : %s\n",md->npc_event);
		if(src && src->type == BL_PET)
			sd = ((struct pet_data *)src)->msd;
		if(sd == NULL) {
			if(mvp_sd != NULL)
				sd = mvp_sd;
			else {
				struct map_session_data *tmpsd;
				int i;
				for(i=0;i<fd_max;i++){
					if(session[i] && (tmpsd=session[i]->session_data) && tmpsd->state.auth) {
						if(md->bl.m == tmpsd->bl.m) {
							sd = tmpsd;
							break;
						}
					}
				}
			}
		}
		if(sd)
			npc_event(sd,md->npc_event);
	}

	clif_clearchar_area(&md->bl,1);
	map_delblock(&md->bl);
	if(mob_get_viewclass(md->class) <= 1000)
		clif_clearchar_delay(tick+3000,&md->bl,0);
	mob_deleteslave(md);
	mob_setdelayspawn(md->bl.id);
	map_freeblock_unlock();

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int mob_class_change(struct mob_data *md,int *value)
{
	unsigned int tick = gettick();
	int i,c,hp_rate,max_hp,class,count = 0;

	if(value[0]<=1000 || value[0]>2000)
		return 0;
	if(md->bl.prev == NULL) return 0;

	while(count < 5 && value[count] > 1000 && value[count] <= 2000) count++;
	if(count < 1) return 0;

	class = value[rand()%count];
	if(class<=1000 || class>2000) return 0;

	max_hp = battle_get_max_hp(&md->bl);
	hp_rate = md->hp*100/max_hp;
	clif_mob_class_change(md,class);
	md->class = class;
	max_hp = battle_get_max_hp(&md->bl);
	if(battle_config.monster_class_change_full_recover) {
		md->hp = max_hp;
		memset(md->dmglog,0,sizeof(md->dmglog));
	}
	else
		md->hp = max_hp*hp_rate/100;
	if(md->hp > max_hp) md->hp = max_hp;
	else if(md->hp < 1) md->hp = 1;

	memcpy(md->name,mob_db[class].jname,24);
	memset(&md->state,0,sizeof(md->state));
	md->attacked_id = 0;
	md->target_id = 0;
	md->move_fail_count = 0;

	md->speed = mob_db[md->class].speed;
	md->def_ele = mob_db[md->class].element;

	mob_changestate(md,MS_IDLE,0);
	skill_castcancel(&md->bl,0);
	md->state.skillstate = MSS_IDLE;
	md->last_thinktime = tick;
	md->next_walktime = tick+rand()%50+5000;
	md->attackabletime = tick;
	md->canmove_tick = tick;

	for(i=0,c=tick-1000*3600*10;i<MAX_MOBSKILL;i++)
		md->skilldelay[i] = c;
	md->skillid=0;
	md->skilllv=0;

	if(md->lootitem == NULL && mob_db[class].mode&0x02) {
		md->lootitem=calloc(sizeof(struct item)*LOOTITEM_SIZE, 1);
		if(md->lootitem==NULL){
			printf("mob_class_change: out of memory !\n");
			exit(1);
		}
	}

	skill_clear_unitgroup(&md->bl);
	skill_cleartimerskill(&md->bl);

	clif_clearchar_area(&md->bl,0);
	clif_spawnmob(md);

	return 0;
}

/*==========================================
 * mob夞暅
 *------------------------------------------
 */
int mob_heal(struct mob_data *md,int heal)
{
	int max_hp = battle_get_max_hp(&md->bl);
	md->hp += heal;
	if( max_hp < md->hp )
		md->hp = max_hp;
	return 0;
}

/*==========================================
 * mob儚乕僾
 *------------------------------------------
 */
int mob_warp(struct mob_data *md,int m,int x,int y,int type)
{
	int i=0,c,xs=0,ys=0,bx=x,by=y;
	if( md==NULL || md->bl.prev==NULL )
		return 0;

	if( m<0 ) m=md->bl.m;

	if(type >= 0) {
		if(map[md->bl.m].flag.monster_noteleport)
			return 0;
		clif_clearchar_area(&md->bl,type);
	}
	skill_unit_out_all(&md->bl,gettick(),1);
	map_delblock(&md->bl);

	if(bx>0 && by>0){	// 埵抲巜掕偺応崌廃埻俋僙儖傪扵嶕
		xs=ys=9;
	}

	while( ( x<0 || y<0 || ((c=read_gat(m,x,y))==1 || c==5) ) && (i++)<1000 ){
		if( xs>0 && ys>0 && i<250 ){	// 巜掕埵抲晅嬤偺扵嶕
			x=bx+rand()%xs-xs/2;
			y=by+rand()%ys-ys/2;
		}else{			// 姰慡儔儞僟儉扵嶕
			x=rand()%(map[m].xs-2)+1;
			y=rand()%(map[m].ys-2)+1;
		}
	}
	md->dir=0;
	if(i<1000){
		md->bl.x=md->to_x=x;
		md->bl.y=md->to_y=y;
		md->bl.m=m;
	}else {
		m=md->bl.m;
		if(battle_config.error_log)
			printf("MOB %d warp failed, class = %d\n",md->bl.id,md->class);
	}

	md->target_id=0;	// 僞僎傪夝彍偡傞
	md->state.targettype=NONE_ATTACKABLE;
	md->attacked_id=0;
	md->state.skillstate=MSS_IDLE;
	mob_changestate(md,MS_IDLE,0);

	if(type>0 && i==1000) {
		if(battle_config.battle_log)
			printf("MOB %d warp to (%d,%d), class = %d\n",md->bl.id,x,y,md->class);
	}

	map_addblock(&md->bl);
	if(type>0)
		clif_spawnmob(md);
	return 0;
}

/*==========================================
 * 夋柺撪偺庢傝姫偒偺悢寁嶼梡(foreachinarea)
 *------------------------------------------
 */
int mob_countslave_sub(struct block_list *bl,va_list ap)
{
	int id,*c;
	id=va_arg(ap,int);
	c=va_arg(ap,int *);
	if( ((struct mob_data *)bl)->master_id==id )
		(*c)++;
	return 0;
}
/*==========================================
 * 夋柺撪偺庢傝姫偒偺悢寁嶼
 *------------------------------------------
 */
int mob_countslave(struct mob_data *md)
{
	int c=0;
	map_foreachinarea(mob_countslave_sub, md->bl.m,
		0,0,map[md->bl.m].xs-1,map[md->bl.m].ys-1,
		BL_MOB,md->bl.id,&c);
	return c;
}
/*==========================================
 * 庤壓MOB彚姭
 *------------------------------------------
 */
int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
{
	struct mob_data *md;
	int bx=md2->bl.x,by=md2->bl.y,m=md2->bl.m,count = 0,class,k,a = amount;

	if(value[0]<=1000 || value[0]>2000)	// 抣偑堎忢側傜彚姭傪巭傔傞
		return 0;
	while(count < 5 && value[count] > 1000 && value[count] <= 2000) count++;
	if(count < 1) return 0;

	for(k=0;k<count;k++) {
		amount = a;
		class = value[k];
		if(class<=1000 || class>2000) continue;
		for(;amount>0;amount--){
			int x=0,y=0,c=0,i=0;
			md=calloc(sizeof(struct mob_data), 1);
			if(md==NULL){
				printf("mob_once_spawn: out of memory !\n");
				exit(1);
			}
			if(mob_db[class].mode&0x02) {
				md->lootitem=calloc(sizeof(struct item)*LOOTITEM_SIZE, 1);
				if(md->lootitem==NULL){
					printf("mob_once_spawn: out of memory !\n");
					exit(1);
				}
			}
			else
				md->lootitem=NULL;

			while((x<=0 || y<=0 || (c=map_getcell(m,x,y))==1 || c==5 ) && (i++)<100){
				x=rand()%9-4+bx;
				y=rand()%9-4+by;
			}
			if(i>=100){
				x=bx;
				y=by;
			}

			mob_spawn_dataset(md,"--ja--",class);
			md->bl.m=m;
			md->bl.x=x;
			md->bl.y=y;

			md->m =m;
			md->x0=x;
			md->y0=y;
			md->xs=0;
			md->ys=0;
			md->spawndelay1=-1;	// 堦搙偺傒僼儔僌
			md->spawndelay2=-1;	// 堦搙偺傒僼儔僌

			memset(md->npc_event,0,sizeof(md->npc_event));
			md->bl.type=BL_MOB;
			map_addiddb(&md->bl);
			mob_spawn(md->bl.id);
			clif_skill_nodamage(&md->bl,&md->bl,(flag)? NPC_SUMMONSLAVE:NPC_SUMMONMONSTER,a,1);

			if(flag)
				md->master_id=md2->bl.id;
		}
	}
	return 0;
}

/*==========================================
 * 帺暘傪儘僢僋偟偰偄傞PC偺悢傪悢偊傞(foreachclient)
 *------------------------------------------
 */
static int mob_counttargeted_sub(struct block_list *bl,va_list ap)
{
	int id,*c;
	struct block_list *src;
	id=va_arg(ap,int);
	c=va_arg(ap,int *);
	src=va_arg(ap,struct block_list *);
	if(id == bl->id || (src && id == src->id)) return 0;
	if(bl->type == BL_PC) {
		if(((struct map_session_data *)bl)->attacktarget == id && ((struct map_session_data *)bl)->attacktimer != -1)
			(*c)++;
	}
	else if(bl->type == BL_MOB) {
		if(((struct mob_data *)bl)->target_id == id && ((struct mob_data *)bl)->timer != -1 && ((struct mob_data *)bl)->state.state == MS_ATTACK)
			(*c)++;
	}
	else if(bl->type == BL_PET) {
		if(((struct pet_data *)bl)->target_id == id && ((struct pet_data *)bl)->timer != -1 && ((struct pet_data *)bl)->state.state == MS_ATTACK)
			(*c)++;
	}
	return 0;
}
/*==========================================
 * 帺暘傪儘僢僋偟偰偄傞PC偺悢傪悢偊傞
 *------------------------------------------
 */
int mob_counttargeted(struct mob_data *md,struct block_list *src)
{
	int c=0;
	map_foreachinarea(mob_counttargeted_sub, md->bl.m,
		md->bl.x-A

⌨️ 快捷键说明

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