📄 battle.c
字号:
return ((struct skill_unit *)bl)->group->party_id;
else
return 0;
}
int battle_get_guild_id(struct block_list *bl)
{
if( bl->type == BL_PC )
return ((struct map_session_data *)bl)->status.guild_id;
else if( bl->type==BL_MOB )
return ((struct mob_data *)bl)->class;
else if( bl->type==BL_SKILL )
return ((struct skill_unit *)bl)->group->guild_id;
else
return 0;
}
int battle_get_race(struct block_list *bl)
{
if(bl->type==BL_MOB)
return mob_db[((struct mob_data *)bl)->class].race;
else if(bl->type==BL_PC)
return 7;
else if(bl->type==BL_PET)
return mob_db[((struct pet_data *)bl)->class].race;
else
return 0;
}
int battle_get_size(struct block_list *bl)
{
if(bl->type==BL_MOB)
return mob_db[((struct mob_data *)bl)->class].size;
else if(bl->type==BL_PC)
return 1;
else if(bl->type==BL_PET)
return mob_db[((struct pet_data *)bl)->class].size;
else
return 1;
}
int battle_get_mode(struct block_list *bl)
{
if(bl->type==BL_MOB)
return mob_db[((struct mob_data *)bl)->class].mode;
else if(bl->type==BL_PET)
return mob_db[((struct pet_data *)bl)->class].mode;
else
return 0x01; // 偲傝偁偊偢摦偔偲偄偆偙偲偱1
}
int battle_get_mexp(struct block_list *bl)
{
if(bl->type==BL_MOB)
return mob_db[((struct mob_data *)bl)->class].mexp;
else if(bl->type==BL_PET)
return mob_db[((struct pet_data *)bl)->class].mexp;
else
return 0;
}
// StatusChange宯偺強摼
struct status_change *battle_get_sc_data(struct block_list *bl)
{
if(bl->type==BL_MOB)
return ((struct mob_data*)bl)->sc_data;
else if(bl->type==BL_PC)
return ((struct map_session_data*)bl)->sc_data;
return NULL;
}
short *battle_get_sc_count(struct block_list *bl)
{
if(bl->type==BL_MOB)
return &((struct mob_data*)bl)->sc_count;
else if(bl->type==BL_PC)
return &((struct map_session_data*)bl)->sc_count;
return NULL;
}
short *battle_get_opt1(struct block_list *bl)
{
if(bl->type==BL_MOB)
return &((struct mob_data*)bl)->opt1;
else if(bl->type==BL_PC)
return &((struct map_session_data*)bl)->opt1;
return NULL;
}
short *battle_get_opt2(struct block_list *bl)
{
if(bl->type==BL_MOB)
return &((struct mob_data*)bl)->opt2;
else if(bl->type==BL_PC)
return &((struct map_session_data*)bl)->opt2;
return NULL;
}
short *battle_get_option(struct block_list *bl)
{
if(bl->type==BL_MOB)
return &((struct mob_data*)bl)->option;
else if(bl->type==BL_PC)
return &((struct map_session_data*)bl)->status.option;
return NULL;
}
//-------------------------------------------------------------------
// 僟儊乕僕偺抶墑
struct battle_delay_damage_ {
struct block_list *src,*target;
int damage;
int flag;
};
int battle_delay_damage_sub(int tid,unsigned int tick,int id,int data)
{
struct battle_delay_damage_ *dat=(struct battle_delay_damage_ *)data;
if( map_id2bl(id)==dat->src && dat->target->prev!=NULL)
battle_damage(dat->src,dat->target,dat->damage,dat->flag);
free(dat);
return 0;
}
int battle_delay_damage(unsigned int tick,struct block_list *src,struct block_list *target,int damage,int flag)
{
struct battle_delay_damage_ *dat =
(struct battle_delay_damage_*)calloc(sizeof *dat, 1);
if (dat == NULL) {
printf("out of memory: battle_delay_damage\n");
exit(1);
}
dat->src=src;
dat->target=target;
dat->damage=damage;
dat->flag=flag;
add_timer(tick,battle_delay_damage_sub,src->id,(int)dat);
return 0;
}
// 幚嵺偵HP傪憖嶌
int battle_damage(struct block_list *bl,struct block_list *target,int damage,int flag)
{
struct map_session_data *sd=NULL;
struct status_change *sc_data=battle_get_sc_data(target);
short *sc_count;
int i;
if(damage==0 || target->type == BL_PET)
return 0;
if(target->prev == NULL)
return 0;
if(bl) {
if(bl->prev==NULL)
return 0;
if(bl->type==BL_PC)
sd=(struct map_session_data *)bl;
}
if(damage<0)
return battle_heal(bl,target,-damage,0,flag);
if(!flag && (sc_count=battle_get_sc_count(target))!=NULL && *sc_count>0){
// 搥寢丄愇壔丄悋柊傪徚嫀
if(sc_data[SC_FREEZE].timer!=-1)
skill_status_change_end(target,SC_FREEZE,-1);
if(sc_data[SC_STONE].timer!=-1 && sc_data[SC_STONE].val2==0)
skill_status_change_end(target,SC_STONE,-1);
if(sc_data[SC_SLEEP].timer!=-1)
skill_status_change_end(target,SC_SLEEP,-1);
}
if(target->type==BL_MOB){ // MOB
struct mob_data *md=(struct mob_data *)target;
if(md->skilltimer!=-1 && md->state.skillcastcancel) // 塺彞朩奞
skill_castcancel(target,0);
return mob_damage(bl,md,damage,0);
}
else if(target->type==BL_PC){ // PC
struct map_session_data *tsd=(struct map_session_data *)target;
if(tsd->sc_data[SC_DEVOTION].val1){ // 僨傿儃乕僔儑儞傪偐偗傜傟偰偄傞
struct map_session_data *md = map_id2sd(tsd->sc_data[SC_DEVOTION].val1);
if(md && skill_devotion3(&md->bl,target->id)){
skill_devotion(md,target->id);
}
else if(md)
for(i=0;i<5;i++)
if(md->dev.val1[i] == target->id){
clif_damage(bl,&md->bl, gettick(), 0, 0,
damage, 0 , 0, 0);
pc_damage(&md->bl,md,damage);
return 0;
}
}
if(tsd->skilltimer!=-1){ // 塺彞朩奞
// 僼僃儞僇乕僪傗朩奞偝傟側偄僗僉儖偐偺専嵏
if( (!tsd->special_state.no_castcancel || map[bl->m].flag.gvg) && tsd->state.skillcastcancel &&
!tsd->special_state.no_castcancel2)
skill_castcancel(target,0);
}
return pc_damage(bl,tsd,damage);
}
else if(target->type==BL_SKILL)
return skill_unit_ondamaged((struct skill_unit *)target,bl,damage,gettick());
return 0;
}
int battle_heal(struct block_list *bl,struct block_list *target,int hp,int sp,int flag)
{
if(target->type == BL_PET)
return 0;
if( target->type ==BL_PC && pc_isdead((struct map_session_data *)target) )
return 0;
if(hp==0 && sp==0)
return 0;
if(hp<0)
return battle_damage(bl,target,-hp,flag);
if(target->type==BL_MOB)
return mob_heal((struct mob_data *)target,hp);
else if(target->type==BL_PC)
return pc_heal((struct map_session_data *)target,hp,sp);
return 0;
}
// 峌寕掆巭
int battle_stopattack(struct block_list *bl)
{
if(bl->type==BL_MOB)
return mob_stopattack((struct mob_data*)bl);
else if(bl->type==BL_PC)
return pc_stopattack((struct map_session_data*)bl);
else if(bl->type==BL_PET)
return pet_stopattack((struct pet_data*)bl);
return 0;
}
// 堏摦掆巭
int battle_stopwalking(struct block_list *bl,int type)
{
if(bl->type==BL_MOB)
return mob_stop_walking((struct mob_data*)bl,type);
else if(bl->type==BL_PC)
return pc_stop_walking((struct map_session_data*)bl,type);
else if(bl->type==BL_PET)
return pet_stop_walking((struct pet_data*)bl,type);
return 0;
}
/*==========================================
* 僟儊乕僕偺懏惈廋惓
*------------------------------------------
*/
int battle_attr_fix(int damage,int atk_elem,int def_elem)
{
int def_type= def_elem%10, def_lv=def_elem/10/2;
if( atk_elem<0 || atk_elem>9 || def_type<0 || def_type>9 ||
def_lv<1 || def_lv>4){ // 懏 惈抣偑偍偐偟偄偺偱偲傝偁偊偢偦偺傑傑曉偡
if(battle_config.error_log)
printf("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv);
return damage;
}
return damage*attr_fix_table[def_lv-1][atk_elem][def_type]/100;
}
/*==========================================
* 僟儊乕僕嵟廔寁嶼
*------------------------------------------
*/
int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag)
{
struct map_session_data *sd=NULL;
struct mob_data *md=NULL;
struct status_change *sc_data,*sc;
short *sc_count;
int class = battle_get_class(bl);
if(bl->type==BL_MOB) md=(struct mob_data *)bl;
else sd=(struct map_session_data *)bl;
sc_data=battle_get_sc_data(bl);
sc_count=battle_get_sc_count(bl);
if(sc_count!=NULL && *sc_count>0){
if(sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK){
// 僙乕僼僥傿僂僅乕儖
struct skill_unit *unit=(struct skill_unit*)sc_data[SC_SAFETYWALL].val2;
if( unit->alive && (--unit->group->val2)<=0 )
skill_delunit(unit);
skill_unit_move(bl,gettick(),1); // 廳偹妡偗僠僃僢僋
damage=0;
}
if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 && flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK){
// 僯儏乕儅
damage=0;
}
if(sc_data[SC_AETERNA].timer!=-1 && damage>0){ // 儗僢僋僗僄乕僥儖僫
damage<<=1;
skill_status_change_end( bl,SC_AETERNA,-1 );
}
//懏惈応偺僟儊乕僕憹壛
if(sc_data[SC_VOLCANO].timer!=-1){ // 儃儖働乕僲
if(flag&BF_SKILL && skill_get_pl(skill_num)==3)
damage += damage*sc_data[SC_VOLCANO].val4/100;
else if(!flag&BF_SKILL && battle_get_attack_element(bl)==3)
damage += damage*sc_data[SC_VOLCANO].val4/100;
}
if(sc_data[SC_VIOLENTGALE].timer!=-1){ // 僶僀僆儗儞僩僎僀儖
if(flag&BF_SKILL && skill_get_pl(skill_num)==4)
damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
else if(!flag&BF_SKILL && battle_get_attack_element(bl)==4)
damage += damage*sc_data[SC_VIOLENTGALE].val4/100;
}
if(sc_data[SC_DELUGE].timer!=-1){ // 僨儕儏乕僕
if(flag&BF_SKILL && skill_get_pl(skill_num)==1)
damage += damage*sc_data[SC_DELUGE].val4/100;
else if(!flag&BF_SKILL && battle_get_attack_element(bl)==1)
damage += damage*sc_data[SC_DELUGE].val4/100;
}
if(sc_data[SC_ENERGYCOAT].timer!=-1 && damage>0 && flag&BF_WEAPON){ // 僄僫僕乕僐乕僩
if(sd){
if(sd->status.sp>0){
int per = sd->status.sp * 5 / (sd->status.max_sp + 1);
sd->status.sp -= sd->status.sp * (per * 5 + 10) / 1000;
if( sd->status.sp < 0 ) sd->status.sp = 0;
damage -= damage * ((per+1) * 6) / 100;
clif_updatestatus(sd,SP_SP);
}
if(sd->status.sp<=0)
skill_status_change_end( bl,SC_ENERGYCOAT,-1 );
}
else
damage -= damage * (sc_data[SC_ENERGYCOAT].val1 * 6) / 100;
}
if(sc_data[SC_KYRIE].timer!=-1 && damage > 0){ // 僉儕僄僄儗僀僜儞
sc=&sc_data[SC_KYRIE];
sc->val2-=damage;
if(flag&BF_WEAPON){
if(sc->val2>=0) damage=0;
else damage=-sc->val2;
}
if((--sc->val3)<=0 || (sc->val2<=0) || skill_num == AL_HOLYLIGHT)
skill_status_change_end(bl, SC_KYRIE, -1);
}
if(sc_data[SC_AUTOGUARD].timer != -1 && damage > 0 && flag&BF_WEAPON) {
if(rand()%100 < sc_data[SC_AUTOGUARD].val2) {
damage = 0;
clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc_data[SC_AUTOGUARD].val1,1);
if(bl->type == BL_PC)
((struct map_session_data *)bl)->canmove_tick = gettick() + 300;
else if(bl->type == BL_MOB)
((struct mob_data *)bl)->canmove_tick = gettick() + 300;
}
}
}
if(class == 1288) {
if(flag&BF_SKILL)
damage=0;
if(src->type == BL_PC) {
struct guild *g=guild_search(((struct map_session_data *)src)->status.guild_id);
struct guild_castle *gc=guild_mapname2gc(map[bl->m].name);
if(g == NULL)
damage=0;//僊儖僪枹壛擖側傜僟儊乕僕柍偟
else if(g->guild_id == gc->guild_id)
damage=0;//帺愯椞僊儖僪偺僄儞儁側傜僟儊乕僕柍偟
else if(guild_checkskill(g,GD_APPROVAL) <= 0)
damage=0;//惓婯僊儖僪彸擣偑側偄偲僟儊乕僕柍偟
}
else damage = 0;
}
if(map[bl->m].flag.gvg && damage > 0) { //GvG
if(flag&BF_WEAPON) {
if(flag&BF_SHORT)
damage=damage*battle_config.gvg_short_damage_rate/100;
if(flag&BF_LONG)
damage=damage*battle_config.gvg_long_damage_rate/100;
}
if(flag&BF_MAGIC)
damage = damage*battle_config.gvg_magic_damage_rate/100;
if(flag&BF_MISC)
damage=damage*battle_config.gvg_misc_damage_rate/100;
if(damage < 1) damage = 1;
}
if(battle_config.skill_min_damage || flag&BF_MISC) {
if(div_ < 255) {
if(damage > 0 && damage < div_)
damage = div_;
}
else if(damage > 0 && damage < 3)
damage = 3;
}
if( md!=NULL && md->hp>0 && damage > 0 ) // 斀寕側偳偺MOB僗僉儖敾掕
mobskill_event(md,flag);
return damage;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -