diff options
-rw-r--r-- | src/common/mapindex.c | 1 | ||||
-rw-r--r-- | src/map/atcommand.c | 2 | ||||
-rw-r--r-- | src/map/battle.c | 188 | ||||
-rw-r--r-- | src/map/battle.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 166 | ||||
-rw-r--r-- | src/map/clif.h | 4 | ||||
-rw-r--r-- | src/map/packets_struct.h | 45 | ||||
-rw-r--r-- | src/map/skill.c | 8 |
8 files changed, 213 insertions, 203 deletions
diff --git a/src/common/mapindex.c b/src/common/mapindex.c index a95e143c3..1d2569afe 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -179,6 +179,7 @@ int mapindex_init(void) { } int mapindex_removemap(int index){ + strdb_remove(mapindex_db, indexes[index].name); indexes[index].name[0] = '\0'; return 0; } diff --git a/src/map/atcommand.c b/src/map/atcommand.c index b18868b0c..37cc5bf29 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -4622,7 +4622,7 @@ ACMD(disguise) if(sd->sc.data[SC_MONSTER_TRANSFORM]) { - clif->message(fd, msg_txt(1488)); // Character cannot be disguised while in monster form. + clif->message(fd, msg_txt(1487)); // Character cannot be disguised while in monster form. return false; } diff --git a/src/map/battle.c b/src/map/battle.c index 812301cd6..8ede99509 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4994,45 +4994,44 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list break; } - if( wd.damage + wd.damage2 ) - { //There is a total damage value - int64 damage = wd.damage + wd.damage2, rdamage = 0; - int rdelay = 0; - - if( src != target && - (!skill_id || skill_id || - ( src->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) )) ){ + if( wd.damage + wd.damage2 ) { //There is a total damage value + if( src != target ) { // Don't reflect your own damage (Grand Cross) + int64 rdamage = 0; + + rdamage = battle->calc_return_damage(target, src, wd.damage + wd.damage2, wd.flag, skill_id); + + if( tsc && tsc->data[SC_DEATHBOUND] ) { + wd.damage = wd.damage + wd.damage2; + wd.damage2 = 0; + status_change_end(target,SC_DEATHBOUND,INVALID_TIMER); + } - rdamage = battle->calc_return_damage(target, src, &damage, wd.flag, 0, &rdelay); + if( rdamage > 0 ) { + + if( tsc && tsc->data[SC_LG_REFLECTDAMAGE] ) { + bool change = false; + if( sd && !sd->state.autocast ) + change = true; + if( change ) + sd->state.autocast = 1; + map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,timer->gettick(),target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race); + if( change ) + sd->state.autocast = 0; + } else { + int rdelay; + + rdelay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); - if( tsc && tsc->count ) { - if( tsc && tsc->data[SC_DEATHBOUND] ){ - wd.damage = damage; - wd.damage2 = 0; - status_change_end(target,SC_DEATHBOUND,INVALID_TIMER); - } - } - if( rdamage > 0 ) { - if( tsc && tsc->data[SC_LG_REFLECTDAMAGE] ) { - if( src != target ) {// Don't reflect your own damage (Grand Cross) - bool change = false; - if( sd && !sd->state.autocast ) - change = true; - if( change ) - sd->state.autocast = 1; - map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,timer->gettick(),target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race); - if( change ) - sd->state.autocast = 0; - } - } else { - //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] - if( tsd && src != target ) - battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); - battle->delay_damage(timer->gettick(), wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); - skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,timer->gettick()); - } + //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] + if( tsd ) + battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); + battle->delay_damage(timer->gettick(), wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,timer->gettick()); } + + } } + if(!wd.damage2) { wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) @@ -5137,85 +5136,100 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl } //Calculates BF_WEAPON returned damage. -int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, int64 *dmg, int flag, uint16 skill_id, int *delay){ - int64 rdamage = 0, damage = *dmg, trdamage = 0; +int64 battle_calc_return_damage(struct block_list *target, struct block_list *src, int64 damage, int flag, uint16 skill_id){ + int64 rdamage = 0, trdamage = 0; struct map_session_data* sd; struct status_change* sc; #ifdef RENEWAL int max_reflect_damage; - max_reflect_damage = max(status_get_max_hp(bl), status_get_max_hp(bl) * status->get_lv(bl) / 100); + max_reflect_damage = max(status_get_max_hp(target), status_get_max_hp(target) * status->get_lv(target) / 100); #endif - sd = BL_CAST(BL_PC, bl); - sc = status->get_sc(bl); + sd = BL_CAST(BL_PC, target); + sc = status->get_sc(target); #ifdef RENEWAL -#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, min(max_reflect_damage, (d))) ) + #define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, min(max_reflect_damage, (d))) ) #else -#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, (d)) ) + #define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, (d)) ) #endif + + if( sc && !sc->count ) + sc = NULL; + + if( sc ) { + + if( sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){ + //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}] + int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status->get_lv(target) / 125; + if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK + rdamage = rdamage * ratio / 100 + (damage) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; + skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); + clif->skill_damage(target, src, timer->gettick(), status_get_amotion(src), 0, rdamage, + 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does + clif->damage(src, target, timer->gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0); + status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1); + status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER); + return 0; // Just put here to minimize redundancy + } + + if( sc->data[SC_KYOMU] && !sc->data[SC_DEATHBOUND] ){ + // Nullify reflecting ability + return 0; + } - if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){ - //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}] - int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status->get_lv(bl) / 125; - if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK - rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; - skill->blown(bl, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); - clif->skill_damage(bl, src, timer->gettick(), status_get_amotion(src), 0, rdamage, - 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does - clif->damage(src, bl, timer->gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0); - status->damage(src, bl, status->damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1); - status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER); - return 0; // Just put here to minimize redundancy - } + } + if( flag & BF_SHORT) {//Bounces back part of the damage. - if ( sd && sd->bonus.short_weapon_damage_return ){ + if ( sd && sd->bonus.short_weapon_damage_return ) { NORMALIZE_RDAMAGE(damage * sd->bonus.short_weapon_damage_return / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); } - if( sc && sc->count ) { + if( sc ) { if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ){ - NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100); - *delay = clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4); + int64 t = damage * sc->data[SC_REFLECTSHIELD]->val2 / 100; + + if (flag & BF_SKILL) { + if (flag&BF_WEAPON) + t = t * map->list[src->m].weapon_damage_rate / 100; + if (flag&BF_MISC) + t = t * map->list[src->m].misc_damage_rate / 100; + } else { + if (flag & BF_SHORT) + t = t * map->list[src->m].short_damage_rate / 100; + } + + NORMALIZE_RDAMAGE(t); } if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) { - if( skill_id != HT_LANDMINE && skill_id != HT_CLAYMORETRAP - && skill_id != RA_CLUSTERBOMB && (skill_id <= RA_VERDURETRAP || skill_id > RA_ICEBOUNDTRAP) && skill_id != MA_LANDMINE ){ - NORMALIZE_RDAMAGE((*dmg) * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); - } + NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100); } - if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !is_boss(src) ) { - uint8 dir = map->calc_dir(bl,src->x,src->y), - t_dir = unit->getdir(bl); - - if( !map->check_dir(dir,t_dir) ) { - int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. - trdamage += rdamage = rd1 - (*dmg = rd1 * 30 / 100); // not normalized as intended. - clif->skill_damage(src, bl, timer->gettick(), status_get_amotion(src), 0, -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6); - skill->blown(bl, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0); - if( skill_id ) - status_change_end(bl, SC_DEATHBOUND, INVALID_TIMER); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + + if( !is_boss(src) ) { + + if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION ) { + uint8 dir = map->calc_dir(target,src->x,src->y), + t_dir = unit->getdir(target); + + if( !map->check_dir(dir,t_dir) ) { + int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. + trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended. + clif->skill_damage(src, target, timer->gettick(), status_get_amotion(src), 0, -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6); + skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0); + } } - } - if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !is_boss(src) ){ - NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + + if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){ + NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100); + } + } } } else { if (sd && sd->bonus.long_weapon_damage_return){ NORMALIZE_RDAMAGE(damage * sd->bonus.long_weapon_damage_return / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); } } - if( !(sc && sc->data[SC_DEATHBOUND]) ){ - if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability - return 0; - } - return max(0, trdamage); #undef NORMALIZE_RDAMAGE } diff --git a/src/map/battle.h b/src/map/battle.h index a8b291818..645b1761f 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -527,7 +527,7 @@ struct battle_interface { /* drain damage */ void (*drain) (struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss); /* damage return/reflect */ - int64 (*calc_return_damage) (struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, int *rdelay); + int64 (*calc_return_damage) (struct block_list *target, struct block_list *src, int64 damage, int flag, uint16 skill_id); /* attribute rate */ int (*attr_ratio) (int atk_elem, int def_type, int def_lv); /* applies attribute modifiers */ diff --git a/src/map/clif.c b/src/map/clif.c index 913f55784..9cefb56f2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4415,6 +4415,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int64 tick, int WBUFW(buf,26)=div; WBUFB(buf,28)=type; #endif + if(disguised(dst)) { clif->send(buf,packet_len(cmd),dst,AREA_WOS); WBUFL(buf,6) = -dst->id; @@ -4439,6 +4440,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int64 tick, int if(src == dst) { unit->setdir(src,unit->getdir(src)); } + //Return adjusted can't walk delay for further processing. return clif->calc_walkdelay(dst,ddelay,type,damage+damage2,div); } @@ -4503,8 +4505,7 @@ void clif_standing(struct block_list* bl) /// Inform client(s) about a map-cell change (ZC_UPDATE_MAPINFO). /// 0192 <x>.W <y>.W <type>.W <map name>.16B -void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target) -{ +void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target) { unsigned char buf[32]; WBUFW(buf,0) = 0x192; @@ -4550,65 +4551,72 @@ void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fi WFIFOSET(fd,packet_len(0x9d)); } +void clif_graffiti_entry(struct block_list *bl, struct skill_unit *su, enum send_target target) { + struct packet_graffiti_entry p; + + p.PacketType = graffiti_entryType; + p.AID = su->bl.id; + p.creatorAID = su->group->src_id; + p.xPos = su->bl.x; + p.yPos = su->bl.y; + p.job = su->group->unit_id; + p.isContens = 1; + p.isVisible = 1; + safestrncpy(p.msg, su->group->valstr, 80); + + clif->send(&p,sizeof(p),bl,target); +} /// Notifies the client of a skill unit. /// 011f <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B (ZC_SKILL_ENTRY) /// 01c9 <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B <has msg>.B <msg>.80B (ZC_SKILL_ENTRY2) /// 08c7 <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.B <range>.W <visible>.B (ZC_SKILL_ENTRY3) /// 099f <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.L <range>.W <visible>.B (ZC_SKILL_ENTRY4) -void clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *su) { - int fd = sd->fd, header = 0x11f, pos=0; - +void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *su, enum send_target target) { + struct packet_skill_entry p; + if( su->group->state.guildaura ) return; -#if PACKETVER >= 20130320 - if(su->group->unit_id > UCHAR_MAX) { - header = 0x99f; - pos = 2; - } -#endif - #if PACKETVER >= 3 - if(su->group->unit_id==UNT_GRAFFITI) { - // Graffiti [Valaris] - WFIFOHEAD(fd,packet_len(0x1c9)); - WFIFOW(fd, 0)=0x1c9; - WFIFOL(fd, 2)=su->bl.id; - WFIFOL(fd, 6)=su->group->src_id; - WFIFOW(fd,10)=su->bl.x; - WFIFOW(fd,12)=su->bl.y; - WFIFOB(fd,14)=su->group->unit_id; - WFIFOB(fd,15)=1; - WFIFOB(fd,16)=1; - safestrncpy((char*)WFIFOP(fd,17),su->group->valstr,MESSAGE_SIZE); - WFIFOSET(fd,packet_len(0x1c9)); + if(su->group->unit_id == UNT_GRAFFITI) { + clif->graffiti_entry(bl,su,target); return; } #endif - WFIFOHEAD(fd,packet_len(header)); - WFIFOW(fd, 0)=header; - if(pos > 0) - WFIFOL(fd, pos)=packet_len(header); - WFIFOL(fd, 2 + pos)=su->bl.id; - WFIFOL(fd, 6 + pos)=su->group->src_id; - WFIFOW(fd,10 + pos)=su->bl.x; - WFIFOW(fd,12 + pos)=su->bl.y; - if (battle_config.traps_setting&1 && skill->get_inf2(su->group->skill_id)&INF2_TRAP) - WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps. - else if (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT)) - WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps. - else if(pos > 0){ - WFIFOL(fd,16)=su->group->unit_id; - WFIFOW(fd,20)=su->range; - pos += 5; - }else - WFIFOB(fd,14)=su->group->unit_id; - WFIFOB(fd,15 + pos)=1; // ignored by client (always gets set to 1) - WFIFOSET(fd,packet_len(header)); + + p.PacketType = skill_entryType; + +#if PACKETVER >= 20110718 + p.PacketLength = sizeof(p); +#endif + + p.AID = su->bl.id; + p.creatorAID = su->group->src_id; + p.xPos = su->bl.x; + p.yPos = su->bl.y; + + //Use invisible unit id for traps. + if ((battle_config.traps_setting&1 && skill->get_inf2(su->group->skill_id)&INF2_TRAP) || + (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT))) + p.job = UNT_DUMMYSKILL; + else + p.job = su->group->unit_id; + +#if PACKETVER >= 20110718 + p.RadiusRange = su->range; +#endif + + p.isVisible = 1; + +#if PACKETVER >= 20130731 + p.level = (unsigned char)unit->group->skill_lv; +#endif + + clif->send(&p,sizeof(p),bl,target); if(su->group->skill_id == WZ_ICEWALL) - clif->changemapcell(fd,su->bl.m,su->bl.x,su->bl.y,5,SELF); + clif->changemapcell(bl->type == BL_PC ? ((TBL_PC*)bl)->fd : 0,su->bl.m,su->bl.x,su->bl.y,5,SELF); } @@ -4674,7 +4682,7 @@ int clif_getareachar(struct block_list* bl,va_list ap) { clif->getareachar_item(sd,(struct flooritem_data*) bl); break; case BL_SKILL: - clif->getareachar_skillunit(sd,(TBL_SKILL*)bl); + clif->getareachar_skillunit(&sd->bl,(TBL_SKILL*)bl,SELF); break; default: if(&sd->bl == bl) @@ -4758,7 +4766,7 @@ int clif_insight(struct block_list *bl,va_list ap) clif->getareachar_item(tsd,(struct flooritem_data*)bl); break; case BL_SKILL: - clif->getareachar_skillunit(tsd,(TBL_SKILL*)bl); + clif->getareachar_skillunit(&tsd->bl,(TBL_SKILL*)bl,SELF); break; default: clif->getareachar_unit(tsd,bl); @@ -5247,65 +5255,6 @@ void clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int clif->send(buf,packet_len(0x117),src,AREA); } - -/*========================================== - * Tells all client's nearby 'unit' sight range that it spawned - *------------------------------------------*/ -//FIXME: this is just an AREA version of clif_getareachar_skillunit() -void clif_skill_setunit(struct skill_unit *su) { - unsigned char buf[128]; - int header = 0x11f, pos = 0; - - nullpo_retv(su); - - if( su->group->state.guildaura ) - return; - -#if PACKETVER >= 20130320 - if(su->group->unit_id > UCHAR_MAX) { - header = 0x99f; - pos = 2; - } -#endif - -#if PACKETVER >= 3 - if(su->group->unit_id==UNT_GRAFFITI) { - // Graffiti [Valaris] - WBUFW(buf, 0)=0x1c9; - WBUFL(buf, 2)=su->bl.id; - WBUFL(buf, 6)=su->group->src_id; - WBUFW(buf,10)=su->bl.x; - WBUFW(buf,12)=su->bl.y; - WBUFB(buf,14)=su->group->unit_id; - WBUFB(buf,15)=1; - WBUFB(buf,16)=1; - safestrncpy((char*)WBUFP(buf,17),su->group->valstr,MESSAGE_SIZE); - clif->send(buf,packet_len(0x1c9),&su->bl,AREA); - return; - } -#endif - WBUFW(buf, 0)=header; - if(pos > 0) - WBUFW(buf, pos)=packet_len(header); - WBUFL(buf, 2 + pos)=su->bl.id; - WBUFL(buf, 6 + pos)=su->group->src_id; - WBUFW(buf,10 + pos)=su->bl.x; - WBUFW(buf,12 + pos)=su->bl.y; - if (su->group->state.song_dance&0x1 && su->val2&UF_ENSEMBLE) - WBUFB(buf,14)=su->val2&UF_SONG?UNT_DISSONANCE:UNT_UGLYDANCE; - else if (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT)) - WBUFB(buf, 14) = UNT_DUMMYSKILL; // Only display the unit at center. - else if(pos > 0) { - WBUFL(buf,16)=su->group->unit_id; - WBUFW(buf,20)=su->range; - pos += 5; - }else - WBUFB(buf,14)=su->group->unit_id; - WBUFB(buf,15 + pos)=1; // ignored by client (always gets set to 1) - clif->send(buf,packet_len(header),&su->bl,AREA); -} - - /// Presents a list of available warp destinations (ZC_WARPLIST). /// 011c <skill id>.W { <map name>.16B }*4 void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4) @@ -9568,6 +9517,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { clif->clearunit_area(&sd->bl, CLR_DEAD); else { skill->usave_trigger(sd); + sd->ud.dir = 0;/* enforce north-facing (not visually, virtually) */ } // Trigger skill effects if you appear standing on them @@ -18355,7 +18305,6 @@ void clif_defaults(void) { clif->changetraplook = clif_changetraplook; clif->refreshlook = clif_refreshlook; clif->class_change = clif_class_change; - clif->skill_setunit = clif_skill_setunit; clif->skill_delunit = clif_skill_delunit; clif->skillunit_update = clif_skillunit_update; clif->clearunit_delayed_sub = clif_clearunit_delayed_sub; @@ -18369,6 +18318,7 @@ void clif_defaults(void) { clif->getareachar_unit = clif_getareachar_unit; clif->clearchar_skillunit = clif_clearchar_skillunit; clif->getareachar = clif_getareachar; + clif->graffiti_entry = clif_graffiti_entry; /* main unit spawn */ clif->spawn = clif_spawn; /* map-related */ diff --git a/src/map/clif.h b/src/map/clif.h index 76d52311f..47ee383e3 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -586,7 +586,6 @@ struct clif_interface { void (*changetraplook) (struct block_list *bl,int val); void (*refreshlook) (struct block_list *bl,int id,int type,int val,enum send_target target); void (*class_change) (struct block_list *bl,int class_,int type); - void (*skill_setunit) (struct skill_unit *su); void (*skill_delunit) (struct skill_unit *su); void (*skillunit_update) (struct block_list* bl); int (*clearunit_delayed_sub) (int tid, int64 tick, int id, intptr_t data); @@ -596,10 +595,11 @@ struct clif_interface { void (*set_unit_idle2) (struct block_list* bl, struct map_session_data *tsd, enum send_target target); void (*set_unit_walking) (struct block_list* bl, struct map_session_data *tsd,struct unit_data* ud, enum send_target target); int (*calc_walkdelay) (struct block_list *bl,int delay, int type, int damage, int div_); - void (*getareachar_skillunit) (struct map_session_data *sd, struct skill_unit *su); + void (*getareachar_skillunit) (struct block_list *bl, struct skill_unit *su, enum send_target target); void (*getareachar_unit) (struct map_session_data* sd,struct block_list *bl); void (*clearchar_skillunit) (struct skill_unit *su, int fd); int (*getareachar) (struct block_list* bl,va_list ap); + void (*graffiti_entry) (struct block_list *bl, struct skill_unit *su, enum send_target target); /* main unit spawn */ int (*spawn) (struct block_list *bl); /* map-related */ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index fa947a163..882c2fe24 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -101,6 +101,16 @@ enum packet_headers { bgqueue_notify_entryType = 0x8d9, bgqueue_battlebeginsType = 0x8df, notify_bounditemType = 0x2d3, +#if PACKETVER < 3 + skill_entryType = 0x11f, +#elif PACKETVER < 20121212 + skill_entryType = 0x8c7, +#elif PACKETVER < 20130731 + skill_entryType = 0x99f, +#else + skill_entryType = 0x9ca, +#endif + graffiti_entryType = 0x1c9, #if PACKETVER > 20130000 /* not sure date */ dropflooritemType = 0x84b, #else @@ -811,6 +821,41 @@ struct packet_notify_bounditem { unsigned short index; } __attribute__((packed)); +struct packet_skill_entry { + short PacketType; +#if PACKETVER >= 20110718 + short PacketLength; +#endif + unsigned int AID; + unsigned int creatorAID; + short xPos; + short yPos; +#if PACKETVER >= 20121212 + int job; +#else + unsigned char job; +#endif +#if PACKETVER >= 20110718 + char RadiusRange; +#endif + unsigned char isVisible; +#if PACKETVER >= 20130731 + unsigned char level; +#endif +} __attribute__((packed)); + +struct packet_graffiti_entry { + short PacketType; + unsigned int AID; + unsigned int creatorAID; + short xPos; + short yPos; + unsigned char job; + unsigned char isVisible; + unsigned char isContens; + char msg[80]; +} __attribute__((packed)); + #pragma pack(pop) #endif /* _PACKETS_STRUCT_H_ */ diff --git a/src/map/skill.c b/src/map/skill.c index 43d669a53..8cce62f94 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3344,7 +3344,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) { if (su->alive && su->group && skill->get_inf2(su->group->skill_id)&INF2_TRAP) { //Reveal trap. //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex] //clif->changetraplook(bl, su->group->unit_id); - clif->skill_setunit(su); + clif->getareachar_skillunit(&su->bl,su,AREA); return 1; } return 0; @@ -10364,7 +10364,7 @@ int skill_dance_overlap_sub(struct block_list* bl, va_list ap) { else //Remove dissonance target->val2 &= ~UF_ENSEMBLE; - clif->skill_setunit(target); //Update look of affected cell. + clif->getareachar_skillunit(&target->bl,target,AREA); //Update look of affected cell. return 1; } @@ -15176,7 +15176,7 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int break; } - clif->skill_setunit(su); + clif->getareachar_skillunit(&su->bl,su,AREA); return su; } @@ -15979,7 +15979,7 @@ int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1 if (group->state.song_dance&0x1) //Check for dissonance effect. skill->dance_overlap(su1, 1); - clif->skill_setunit(su1); + clif->getareachar_skillunit(&su1->bl,su1,AREA); map->foreachincell(skill->unit_effect,su1->bl.m,su1->bl.x,su1->bl.y,group->bl_flag,&su1->bl,tick,1); } } |