📄 mob.c
字号:
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 + -