From 4eb223b62e70a293dd2c95f1ce8b29a3f0c83ef7 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Mon, 16 Sep 2013 07:08:32 -0300 Subject: HPM: Unit.c Interface Fully Interfaced Signed-off-by: shennetsind --- src/map/atcommand.c | 8 +- src/map/battle.c | 24 +- src/map/clif.c | 48 +- src/map/elemental.c | 1969 +++++++++++++++++++++++++------------------------- src/map/elemental.h | 206 +++--- src/map/guild.c | 2 +- src/map/homunculus.c | 16 +- src/map/instance.c | 2 +- src/map/map.c | 20 +- src/map/mercenary.c | 8 +- src/map/mob.c | 68 +- src/map/mob.h | 4 +- src/map/npc.c | 6 +- src/map/pc.c | 14 +- src/map/pc.h | 4 +- src/map/pet.c | 34 +- src/map/pet.h | 4 +- src/map/script.c | 44 +- src/map/skill.c | 206 +++--- src/map/status.c | 80 +- src/map/unit.c | 356 +++++---- src/map/unit.h | 124 ++-- 22 files changed, 1638 insertions(+), 1609 deletions(-) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 6b62f6325..6c44f8919 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1453,11 +1453,11 @@ ACMD(help) { // parameter: '0' - everyone, 'id' - only those attacking someone with that id static int atcommand_stopattack(struct block_list *bl,va_list ap) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); int id = va_arg(ap, int); if (ud && ud->attacktimer != INVALID_TIMER && (!id || id == ud->target)) { - unit_stop_attack(bl); + unit->stop_attack(bl); return 1; } return 0; @@ -5429,9 +5429,9 @@ ACMD(useskill) bl = &sd->bl; if (skill->get_inf(skill_id)&INF_GROUND_SKILL) - unit_skilluse_pos(bl, pl_sd->bl.x, pl_sd->bl.y, skill_id, skill_lv); + unit->skilluse_pos(bl, pl_sd->bl.x, pl_sd->bl.y, skill_id, skill_lv); else - unit_skilluse_id(bl, pl_sd->bl.id, skill_id, skill_lv); + unit->skilluse_id(bl, pl_sd->bl.id, skill_id, skill_lv); return true; } diff --git a/src/map/battle.c b/src/map/battle.c index 120b23368..bc963a7f4 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -50,7 +50,7 @@ int battle_getcurrentskill(struct block_list *bl) { //Returns the current/last s return su->group?su->group->skill_id:0; } - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); return ud?ud->skill_id:0; } @@ -74,7 +74,7 @@ int battle_gettargeted_sub(struct block_list *bl, va_list ap) { if (*c >= 24) return 0; - if ( !(ud = unit_bl2ud(bl)) ) + if ( !(ud = unit->bl2ud(bl)) ) return 0; if (ud->target == target_id || ud->skilltarget == target_id) { @@ -1250,7 +1250,7 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_ if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) { unsigned char target_count; //256 max targets should be a sane max - target_count = unit_counttargeted(target); + target_count = unit->counttargeted(target); if(target_count >= battle_config.vit_penalty_count) { if(battle_config.vit_penalty_type == 1) { if( !tsc || !tsc->data[SC_STEELBODY] ) @@ -2664,7 +2664,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam delay = 200; else delay = 100; - unit_set_walkdelay(bl, iTimer->gettick(), delay, 1); + unit->set_walkdelay(bl, iTimer->gettick(), delay, 1); if(sc->data[SC_CR_SHRINK] && rnd()%100<5*sce->val1) skill->blown(bl,src,skill->get_blewcount(CR_SHRINK,1),-1,0); @@ -2931,9 +2931,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam int dx[8]={0,-1,-1,-1,0,1,1,1}; int dy[8]={1,1,0,-1,-1,-1,0,1}; uint8 dir = iMap->calc_dir(bl, src->x, src->y); - if( unit_movepos(bl, src->x-dx[dir], src->y-dy[dir], 1, 1) ) { + if( unit->movepos(bl, src->x-dx[dir], src->y-dy[dir], 1, 1) ) { clif->slide(bl,src->x-dx[dir],src->y-dy[dir]); - unit_setdir(bl, dir); + unit->setdir(bl, dir); } d->dmg_lv = ATK_DEF; status_change_end(bl, SC_LIGHTNINGWALK, INVALID_TIMER); @@ -3837,7 +3837,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit_counttargeted(target); + attacker_count = unit->counttargeted(target); if(attacker_count >= battle_config.agi_penalty_count) { if (battle_config.agi_penalty_type == 1) @@ -4303,7 +4303,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) { unsigned char attacker_count; //256 max targets should be a sane max - attacker_count = unit_counttargeted(target); + attacker_count = unit->counttargeted(target); if(attacker_count >= battle_config.agi_penalty_count) { if (battle_config.agi_penalty_type == 1) flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100; @@ -5199,7 +5199,7 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * iStatus->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); + skill->blown(bl, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); clif->skill_damage(bl, src, iTimer->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, iTimer->gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0); @@ -5226,13 +5226,13 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i } if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !is_boss(src) ) { uint8 dir = iMap->calc_dir(bl,src->x,src->y), - t_dir = unit_getdir(bl); + t_dir = unit->getdir(bl); if( !iMap->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, iTimer->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); + 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, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); @@ -5417,7 +5417,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if( tsc && tsc->data[SC_AUTOCOUNTER] && iStatus->check_skilluse(target, src, KN_AUTOCOUNTER, 1) ) { uint8 dir = iMap->calc_dir(target,src->x,src->y); - int t_dir = unit_getdir(target); + int t_dir = unit->getdir(target); int dist = distance_bl(src, target); if(dist <= 0 || (!iMap->check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) { diff --git a/src/map/clif.c b/src/map/clif.c index 8c7790a8f..f8f88c691 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -902,7 +902,7 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en p.virtue = (sc) ? sc->opt3 : 0; p.isPKModeON = (sd) ? sd->status.karma : 0; p.sex = vd->sex; - WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); + WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.state = vd->dead_sit; p.clevel = clif_setlevel(bl); @@ -965,7 +965,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.virtue = (sc) ? sc->opt3 : 0; p.isPKModeON = (sd) ? sd->status.karma : 0; p.sex = vd->sex; - WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); + WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.state = vd->dead_sit; p.clevel = clif_setlevel(bl); @@ -1034,7 +1034,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { p.headDir = (sd)? sd->head_dir : 0; p.isPKModeON = (sd) ? sd->status.karma : 0; p.sex = vd->sex; - WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); + WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; clif->send(&p,sizeof(p),bl,target); @@ -1092,7 +1092,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { p.virtue = (sc) ? sc->opt3 : 0; p.isPKModeON = (sd) ? sd->status.karma : 0; p.sex = vd->sex; - WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); + WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.clevel = clif_setlevel(bl); #if PACKETVER >= 20080102 @@ -4328,7 +4328,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->option&OPTION_INVISIBLE)) return; - if ( ( ud = unit_bl2ud(bl) ) && ud->walktimer != INVALID_TIMER ) + if ( ( ud = unit->bl2ud(bl) ) && ud->walktimer != INVALID_TIMER ) clif->set_unit_walking(bl,sd,ud,SELF); else clif->set_unit_idle(bl,sd,SELF); @@ -4512,7 +4512,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic } if(src == dst) { - unit_setdir(src,unit_getdir(src)); + 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); @@ -9784,7 +9784,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) //Set last idle time... [Skotlex] sd->idletime = last_tick; - unit_walktoxy(&sd->bl, x, y, 4); + unit->walktoxy(&sd->bl, x, y, 4); } @@ -9945,7 +9945,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) pc->disguise(sd,sd->status.class_); if( pc_isdead(sd) ) clif_clearunit_single(-sd->bl.id, CLR_DEAD, sd->fd); - if( unit_is_walking(&sd->bl) ) + if( unit->is_walking(&sd->bl) ) clif->move(&sd->ud); } else if ( sd->disguise == sd->status.class_ && sd->fontcolor_tid != INVALID_TIMER ) { const struct TimerData *timer; @@ -10045,7 +10045,7 @@ void clif_changed_dir(struct block_list *bl, enum send_target target) WBUFW(buf,0) = 0x9c; WBUFL(buf,2) = bl->id; WBUFW(buf,6) = bl->type==BL_PC?((TBL_PC*)bl)->head_dir:0; - WBUFB(buf,8) = unit_getdir(bl); + WBUFB(buf,8) = unit->getdir(bl); clif->send(buf, packet_len(0x9c), bl, target); @@ -10169,7 +10169,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, pc->delinvincibletimer(sd); sd->idletime = last_tick; - unit_attack(&sd->bl, target_id, action_type != 0); + unit->attack(&sd->bl, target_id, action_type != 0); break; case 0x02: // sitdown if (battle_config.basic_skill_check && pc->checkskill(sd, NV_BASIC) < 3) { @@ -11248,7 +11248,7 @@ void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_dat if( skill_lv > lv ) skill_lv = lv; if( skill_lv ) - unit_skilluse_id(&hd->bl, target_id, skill_id, skill_lv); + unit->skilluse_id(&hd->bl, target_id, skill_id, skill_lv); } void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) @@ -11269,7 +11269,7 @@ void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_da if( skill_lv > lv ) skill_lv = lv; if( skill_lv ) - unit_skilluse_pos(&hd->bl, x, y, skill_id, skill_lv); + unit->skilluse_pos(&hd->bl, x, y, skill_id, skill_lv); } void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id) @@ -11291,7 +11291,7 @@ void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_ses if( skill_lv > lv ) skill_lv = lv; if( skill_lv ) - unit_skilluse_id(&md->bl, target_id, skill_id, skill_lv); + unit->skilluse_id(&md->bl, target_id, skill_id, skill_lv); } void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) @@ -11314,7 +11314,7 @@ void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_se if( skill_lv > lv ) skill_lv = lv; if( skill_lv ) - unit_skilluse_pos(&md->bl, x, y, skill_id, skill_lv); + unit->skilluse_pos(&md->bl, x, y, skill_id, skill_lv); } @@ -11398,7 +11398,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) skill_lv = sd->skillitemlv; if( !(tmp&INF_SELF_SKILL) ) pc->delinvincibletimer(sd); // Target skills thru items cancel invincibility. [Inkfish] - unit_skilluse_id(&sd->bl, target_id, skill_id, skill_lv); + unit->skilluse_id(&sd->bl, target_id, skill_id, skill_lv); return; } @@ -11418,7 +11418,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) pc->delinvincibletimer(sd); if( skill_lv ) - unit_skilluse_id(&sd->bl, target_id, skill_id, skill_lv); + unit->skilluse_id(&sd->bl, target_id, skill_id, skill_lv); } /*========================================== @@ -11490,14 +11490,14 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski if( sd->skillitem == skill_id ) { if( skill_lv != sd->skillitemlv ) skill_lv = sd->skillitemlv; - unit_skilluse_pos(&sd->bl, x, y, skill_id, skill_lv); + unit->skilluse_pos(&sd->bl, x, y, skill_id, skill_lv); } else { int lv; sd->skillitem = sd->skillitemlv = 0; if( (lv = pc->checkskill(sd, skill_id)) > 0 ) { if( skill_lv > lv ) skill_lv = lv; - unit_skilluse_pos(&sd->bl, x, y, skill_id,skill_lv); + unit->skilluse_pos(&sd->bl, x, y, skill_id,skill_lv); } } } @@ -14282,9 +14282,9 @@ void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) else return; - unit_calc_pos(bl, sd->bl.x, sd->bl.y, sd->ud.dir); - ud = unit_bl2ud(bl); - unit_walktoxy(bl, ud->to_x, ud->to_y, 4); + unit->calc_pos(bl, sd->bl.x, sd->bl.y, sd->ud.dir); + ud = unit->bl2ud(bl); + unit->walktoxy(bl, ud->to_x, ud->to_y, 4); } @@ -14305,7 +14305,7 @@ void clif_parse_HomMoveTo(int fd, struct map_session_data *sd) else return; - unit_walktoxy(bl, x, y, 4); + unit->walktoxy(bl, x, y, 4); } @@ -14326,8 +14326,8 @@ void clif_parse_HomAttack(int fd,struct map_session_data *sd) bl = &sd->md->bl; else return; - unit_stop_attack(bl); - unit_attack(bl, target_id, action_type != 0); + unit->stop_attack(bl); + unit->attack(bl, target_id, action_type != 0); } diff --git a/src/map/elemental.c b/src/map/elemental.c index 03aa93e49..1ef85b3e5 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -1,984 +1,985 @@ -// Copyright (c) Hercules Dev Team, licensed under GNU GPL. -// See the LICENSE file -// Portions Copyright (c) Athena Dev Teams - -#include "../common/cbasetypes.h" -#include "../common/malloc.h" -#include "../common/socket.h" -#include "../common/timer.h" -#include "../common/nullpo.h" -#include "../common/mmo.h" -#include "../common/showmsg.h" -#include "../common/utils.h" -#include "../common/random.h" -#include "../common/strlib.h" - -#include "log.h" -#include "clif.h" -#include "chrif.h" -#include "intif.h" -#include "itemdb.h" -#include "map.h" -#include "pc.h" -#include "status.h" -#include "skill.h" -#include "mob.h" -#include "pet.h" -#include "battle.h" -#include "party.h" -#include "guild.h" -#include "atcommand.h" -#include "script.h" -#include "npc.h" -#include "trade.h" -#include "unit.h" -#include "elemental.h" - -#include -#include -#include -#include - -int elemental_search_index(int class_) { - int i; - ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, elemental->elemental_db[i].class_ == class_); - return (i == MAX_ELEMENTAL_CLASS)?-1:i; -} - -bool elemental_class(int class_) { - return (bool)(elemental_search_index(class_) > -1); -} - -struct view_data * elemental_get_viewdata(int class_) { - int i = elemental_search_index(class_); - if( i < 0 ) - return 0; - - return &elemental->elemental_db[i].vd; -} - -int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime) { - struct s_elemental ele; - struct s_elemental_db *db; - int i; - - nullpo_retr(1,sd); - - if( (i = elemental_search_index(class_)) < 0 ) - return 0; - - db = &elemental->elemental_db[i]; - memset(&ele,0,sizeof(struct s_elemental)); - - ele.char_id = sd->status.char_id; - ele.class_ = class_; - ele.mode = EL_MODE_PASSIVE; // Initial mode - i = db->status.size+1; // summon level - - //[(Caster�s Max HP/ 3 ) + (Caster�s INT x 10 )+ (Caster�s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3] - ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3); - //Caster�s Max SP /4 - ele.sp = ele.max_sp = sd->battle_status.max_sp/4; - //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ] - ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100); - //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) ] - ele.atk2 = sd->battle_status.max_sp / 18; - //Caster�s HIT + (Caster�s Base Level ) - ele.hit = sd->battle_status.hit + sd->status.base_level; - //[Elemental Summon Skill Level x (Caster�s INT / 2 + Caster�s DEX / 4)] - ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4); - //150 + [Caster�s DEX / 10] + [Elemental Summon Skill Level x 3 ] - ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3; - //Caster�s DEF + (Caster�s Base Level / (5 � Elemental Summon Skill Level) - ele.def = sd->battle_status.def + sd->status.base_level / (5-i); - //Caster�s MDEF + (Caster�s INT / (5 - Elemental Summon Skill Level) - ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i); - //Caster�s FLEE + (Caster�s Base Level / (5 � Elemental Summon Skill Level) - ele.flee = sd->status.base_level / (5-i); - //Caster�s HIT + (Caster�s Base Level ) - ele.hit = sd->battle_status.hit + sd->status.base_level; - - //per individual bonuses - switch(db->class_){ - case 2114: case 2115: - case 2116: //ATK + (Summon Agni Skill Level x 20) / HIT + (Summon Agni Skill Level x 10) - ele.atk += i * 20; - ele.atk2 += i * 20; - ele.hit += i * 10; - break; - case 2117: case 2118: - case 2119: //MDEF + (Summon Aqua Skill Level x 10) / MATK + (Summon Aqua Skill Level x 20) - ele.mdef += i * 10; - ele.matk += i * 20; - break; - case 2120: case 2121: - case 2122: //FLEE + (Summon Ventus Skill Level x 20) / MATK + (Summon Ventus Skill Level x 10) - ele.flee += i * 20; - ele.matk += i * 10; - break; - case 2123: case 2124: - case 2125: //DEF + (Summon Tera Skill Level x 25) / ATK + (Summon Tera Skill Level x 5) - ele.def += i * 25; - ele.atk += i * 5; - ele.atk2 += i * 5; - break; - } - - if( (i=pc->checkskill(sd,SO_EL_SYMPATHY)) > 0 ){ - ele.hp = ele.max_hp = ele.max_hp * 5 * i / 100; - ele.sp = ele.max_sp = ele.max_sp * 5 * i / 100; - ele.atk += 25 * i; - ele.atk2 += 25 * i; - ele.matk += 25 * i; - } - - ele.life_time = lifetime; - - // Request Char Server to create this elemental - intif->elemental_create(&ele); - - return 1; -} - -int elemental_get_lifetime(struct elemental_data *ed) { - const struct TimerData * td; - if( ed == NULL || ed->summon_timer == INVALID_TIMER ) - return 0; - - td = iTimer->get_timer(ed->summon_timer); - return (td != NULL) ? DIFF_TICK(td->tick, iTimer->gettick()) : 0; -} - -int elemental_save(struct elemental_data *ed) { - ed->elemental.mode = ed->battle_status.mode; - ed->elemental.hp = ed->battle_status.hp; - ed->elemental.sp = ed->battle_status.sp; - ed->elemental.max_hp = ed->battle_status.max_hp; - ed->elemental.max_sp = ed->battle_status.max_sp; - ed->elemental.atk = ed->battle_status.rhw.atk; - ed->elemental.atk2 = ed->battle_status.rhw.atk2; - ed->elemental.matk = ed->battle_status.matk_min; - ed->elemental.def = ed->battle_status.def; - ed->elemental.mdef = ed->battle_status.mdef; - ed->elemental.flee = ed->battle_status.flee; - ed->elemental.hit = ed->battle_status.hit; - ed->elemental.life_time = elemental->get_lifetime(ed); - intif->elemental_save(&ed->elemental); - return 1; -} - -static int elemental_summon_end(int tid, unsigned int tick, int id, intptr_t data) { - struct map_session_data *sd; - struct elemental_data *ed; - - if( (sd = iMap->id2sd(id)) == NULL ) - return 1; - if( (ed = sd->ed) == NULL ) - return 1; - - if( ed->summon_timer != tid ) { - ShowError("elemental_summon_end %d != %d.\n", ed->summon_timer, tid); - return 0; - } - - ed->summon_timer = INVALID_TIMER; - elemental->delete(ed, 0); // Elemental's summon time is over. - - return 0; -} - -void elemental_summon_stop(struct elemental_data *ed) { - nullpo_retv(ed); - if( ed->summon_timer != INVALID_TIMER ) - iTimer->delete_timer(ed->summon_timer, elemental_summon_end); - ed->summon_timer = INVALID_TIMER; -} - -int elemental_delete(struct elemental_data *ed, int reply) { - struct map_session_data *sd; - nullpo_ret(ed); - - sd = ed->master; - ed->elemental.life_time = 0; - - elemental->clean_effect(ed); - elemental->summon_stop(ed); - - if( !sd ) - return unit_free(&ed->bl, 0); - - sd->ed = NULL; - sd->status.ele_id = 0; - - return unit_remove_map(&ed->bl, 0); -} - -void elemental_summon_init(struct elemental_data *ed) { - if( ed->summon_timer == INVALID_TIMER ) - ed->summon_timer = iTimer->add_timer(iTimer->gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0); - - ed->regen.state.block = 0; -} - -int elemental_data_received(struct s_elemental *ele, bool flag) { - struct map_session_data *sd; - struct elemental_data *ed; - struct s_elemental_db *db; - int i = elemental_search_index(ele->class_); - - if( (sd = iMap->charid2sd(ele->char_id)) == NULL ) - return 0; - - if( !flag || i < 0 ) { // Not created - loaded - DB info - sd->status.ele_id = 0; - return 0; - } - - db = &elemental->elemental_db[i]; - if( !sd->ed ) { // Initialize it after first summon. - sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); - ed->bl.type = BL_ELEM; - ed->bl.id = npc_get_new_npc_id(); - ed->master = sd; - ed->db = db; - memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); - iStatus->set_viewdata(&ed->bl, ed->elemental.class_); - ed->vd->head_mid = 10; // Why? - iStatus->change_init(&ed->bl); - unit_dataset(&ed->bl); - ed->ud.dir = sd->ud.dir; - - ed->bl.m = sd->bl.m; - ed->bl.x = sd->bl.x; - ed->bl.y = sd->bl.y; - unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir); - ed->bl.x = ed->ud.to_x; - ed->bl.y = ed->ud.to_y; - - iMap->addiddb(&ed->bl); - status_calc_elemental(ed,1); - ed->last_spdrain_time = ed->last_thinktime = iTimer->gettick(); - ed->summon_timer = INVALID_TIMER; - elemental_summon_init(ed); - } else { - memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental)); - ed = sd->ed; - } - - sd->status.ele_id = ele->elemental_id; - - if( ed->bl.prev == NULL && sd->bl.prev != NULL ) { - iMap->addblock(&ed->bl); - clif->spawn(&ed->bl); - clif->elemental_info(sd); - clif->elemental_updatestatus(sd,SP_HP); - clif->hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp); - clif->elemental_updatestatus(sd,SP_SP); - } - - return 1; -} - -int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id) { - struct block_list *bl; - sc_type type = iStatus->skill2sc(skill_id); - - nullpo_ret(ed); - - bl = battle->get_master(&ed->bl); - - if( type ) { - switch( type ) { - // Just remove status change. - case SC_PYROTECHNIC_OPTION: - case SC_HEATER_OPTION: - case SC_TROPIC_OPTION: - case SC_FIRE_CLOAK_OPTION: - case SC_AQUAPLAY_OPTION: - case SC_WATER_SCREEN_OPTION: - case SC_COOLER_OPTION: - case SC_CHILLY_AIR_OPTION: - case SC_GUST_OPTION: - case SC_WIND_STEP_OPTION: - case SC_BLAST_OPTION: - case SC_WATER_DROP_OPTION: - case SC_WIND_CURTAIN_OPTION: - case SC_WILD_STORM_OPTION: - case SC_PETROLOGY_OPTION: - case SC_SOLID_SKIN_OPTION: - case SC_CURSED_SOIL_OPTION: - case SC_STONE_SHIELD_OPTION: - case SC_UPHEAVAL_OPTION: - case SC_CIRCLE_OF_FIRE_OPTION: - case SC_TIDAL_WEAPON_OPTION: - if( bl ) status_change_end(bl,type,INVALID_TIMER); // Master - status_change_end(&ed->bl,type-1,INVALID_TIMER); // Elemental Spirit - break; - case SC_ZEPHYR: - if( bl ) status_change_end(bl,type,INVALID_TIMER); - break; - default: - ShowWarning("Invalid SC=%d in elemental_clean_single_effect\n",type); - break; - } - } - - return 1; -} - -int elemental_clean_effect(struct elemental_data *ed) { - struct map_session_data *sd; - - nullpo_ret(ed); - - // Elemental side - status_change_end(&ed->bl, SC_TROPIC, INVALID_TIMER); - status_change_end(&ed->bl, SC_HEATER, INVALID_TIMER); - status_change_end(&ed->bl, SC_AQUAPLAY, INVALID_TIMER); - status_change_end(&ed->bl, SC_COOLER, INVALID_TIMER); - status_change_end(&ed->bl, SC_CHILLY_AIR, INVALID_TIMER); - status_change_end(&ed->bl, SC_PYROTECHNIC, INVALID_TIMER); - status_change_end(&ed->bl, SC_FIRE_CLOAK, INVALID_TIMER); - status_change_end(&ed->bl, SC_WATER_DROP, INVALID_TIMER); - status_change_end(&ed->bl, SC_WATER_SCREEN, INVALID_TIMER); - status_change_end(&ed->bl, SC_GUST, INVALID_TIMER); - status_change_end(&ed->bl, SC_WIND_STEP, INVALID_TIMER); - status_change_end(&ed->bl, SC_BLAST, INVALID_TIMER); - status_change_end(&ed->bl, SC_WIND_CURTAIN, INVALID_TIMER); - status_change_end(&ed->bl, SC_WILD_STORM, INVALID_TIMER); - status_change_end(&ed->bl, SC_PETROLOGY, INVALID_TIMER); - status_change_end(&ed->bl, SC_SOLID_SKIN, INVALID_TIMER); - status_change_end(&ed->bl, SC_CURSED_SOIL, INVALID_TIMER); - status_change_end(&ed->bl, SC_STONE_SHIELD, INVALID_TIMER); - status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER); - status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER); - status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER); - - if( (sd = ed->master) == NULL ) - return 0; - - // Master side - status_change_end(&sd->bl, SC_TROPIC_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_HEATER_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_AQUAPLAY_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_COOLER_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_CHILLY_AIR_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_PYROTECHNIC_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_FIRE_CLOAK_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WATER_SCREEN_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_GUST_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_BLAST_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WIND_CURTAIN_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_WILD_STORM_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_ZEPHYR, INVALID_TIMER); - status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_PETROLOGY_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_SOLID_SKIN_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_CURSED_SOIL_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_STONE_SHIELD_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_UPHEAVAL_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_CIRCLE_OF_FIRE_OPTION, INVALID_TIMER); - status_change_end(&sd->bl, SC_TIDAL_WEAPON_OPTION, INVALID_TIMER); - - return 1; -} - -int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) { - struct skill_condition req; - uint16 skill_id, skill_lv; - int i; - - nullpo_ret(ed); - nullpo_ret(bl); - - if( !ed->master ) - return 0; - - if( ed->target_id ) - elemental->unlocktarget(ed); // Remove previous target. - - ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE)); - if( i == MAX_ELESKILLTREE ) - return 0; - - skill_id = ed->db->skill[i].id; - skill_lv = ed->db->skill[i].lv; - - if( elemental->skillnotok(skill_id, ed) ) - return 0; - - if( ed->ud.skilltimer != INVALID_TIMER ) - return 0; - else if( DIFF_TICK(tick, ed->ud.canact_tick) < 0 ) - return 0; - - ed->target_id = ed->ud.skilltarget = bl->id; // Set new target - ed->last_thinktime = tick; - - // Not in skill range. - if( !battle->check_range(&ed->bl,bl,skill->get_range(skill_id,skill_lv)) ) { - // Try to walk to the target. - if( !unit_walktobl(&ed->bl, bl, skill->get_range(skill_id,skill_lv), 2) ) - elemental->unlocktarget(ed); - else { - // Walking, waiting to be in range. Client don't handle it, then we must handle it here. - int walk_dist = distance_bl(&ed->bl,bl) - skill->get_range(skill_id,skill_lv); - ed->ud.skill_id = skill_id; - ed->ud.skill_lv = skill_lv; - - if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) - ed->ud.skilltimer = iTimer->add_timer( tick+iStatus->get_speed(&ed->bl)*walk_dist, skill->castend_pos, ed->bl.id, 0 ); - else - ed->ud.skilltimer = iTimer->add_timer( tick+iStatus->get_speed(&ed->bl)*walk_dist, skill->castend_id, ed->bl.id, 0 ); - } - return 1; - - } - - req = elemental->skill_get_requirements(skill_id, skill_lv); - - if(req.hp || req.sp){ - struct map_session_data *sd = BL_CAST(BL_PC, battle->get_master(&ed->bl)); - if( sd ){ - if( sd->skill_id_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast - (status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) ) - return 1; - else - status_zap(&ed->bl, req.hp, req.sp); - } - } - - //Otherwise, just cast the skill. - if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) - unit_skilluse_pos(&ed->bl, bl->x, bl->y, skill_id, skill_lv); - else - unit_skilluse_id(&ed->bl, bl->id, skill_id, skill_lv); - - // Reset target. - ed->target_id = 0; - - return 1; -} - -/*=============================================================== - * Action that elemental perform after changing mode. - * Activates one of the skills of the new mode. - *-------------------------------------------------------------*/ -int elemental_change_mode_ack(struct elemental_data *ed, int mode) { - struct block_list *bl = &ed->master->bl; - uint16 skill_id, skill_lv; - int i; - - nullpo_ret(ed); - - if( !bl ) - return 0; - - // Select a skill. - ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode)); - if( i == MAX_ELESKILLTREE ) - return 0; - - skill_id = ed->db->skill[i].id; - skill_lv = ed->db->skill[i].lv; - - if( elemental->skillnotok(skill_id, ed) ) - return 0; - - if( ed->ud.skilltimer != INVALID_TIMER ) - return 0; - else if( DIFF_TICK(iTimer->gettick(), ed->ud.canact_tick) < 0 ) - return 0; - - ed->target_id = bl->id; // Set new target - ed->last_thinktime = iTimer->gettick(); - - if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) - unit_skilluse_pos(&ed->bl, bl->x, bl->y, skill_id, skill_lv); - else - unit_skilluse_id(&ed->bl,bl->id,skill_id,skill_lv); - - ed->target_id = 0; // Reset target after casting the skill to avoid continious attack. - - return 1; -} - -/*=============================================================== - * Change elemental mode. - *-------------------------------------------------------------*/ -int elemental_change_mode(struct elemental_data *ed, int mode) { - nullpo_ret(ed); - - // Remove target - elemental->unlocktarget(ed); - - // Removes the effects of the previous mode. - if(ed->elemental.mode != mode ) elemental->clean_effect(ed); - - ed->battle_status.mode = ed->elemental.mode = mode; - - // Normalize elemental mode to elemental skill mode. - if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill. - else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill. - else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill. - - // Use a skill inmediately after every change mode. - if( mode != EL_SKILLMODE_AGGRESSIVE ) - elemental->change_mode_ack(ed,mode); - return 1; -} - -void elemental_heal(struct elemental_data *ed, int hp, int sp) { - if( hp ) - clif->elemental_updatestatus(ed->master, SP_HP); - if( sp ) - clif->elemental_updatestatus(ed->master, SP_SP); -} - -int elemental_dead(struct elemental_data *ed) { - elemental->delete(ed, 1); - return 0; -} - -int elemental_unlocktarget(struct elemental_data *ed) { - nullpo_ret(ed); - - ed->target_id = 0; - elemental_stop_attack(ed); - elemental_stop_walking(ed,1); - return 0; -} - -int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) { - int idx = skill->get_index(skill_id); - nullpo_retr(1,ed); - - if (idx == 0) - return 1; // invalid skill id - - return skill->not_ok(skill_id, ed->master); -} - -struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){ - struct skill_condition req; - int idx = skill->get_index(skill_id); - - memset(&req,0,sizeof(req)); - - if( idx == 0 ) // invalid skill id - return req; - - if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL ) - return req; - - req.hp = skill_db[idx].hp[skill_lv-1]; - req.sp = skill_db[idx].sp[skill_lv-1]; - - return req; -} - -int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) { - struct elemental_data *ed = sd->ed; - - nullpo_ret(ed); - nullpo_ret(bl); - - if( ed->bl.m != bl->m || !check_distance_bl(&ed->bl, bl, ed->db->range2) ) - return 0; - - if( !iStatus->check_skilluse(&ed->bl, bl, 0, 0) ) - return 0; - - if( ed->target_id == 0 ) - ed->target_id = bl->id; - - return 1; -} - -static int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) { - struct elemental_data *ed; - struct block_list **target; - int dist; - - nullpo_ret(bl); - - ed = va_arg(ap,struct elemental_data *); - target = va_arg(ap,struct block_list**); - - //If can't seek yet, not an enemy, or you can't attack it, skip. - if( (*target) == bl || !iStatus->check_skilluse(&ed->bl, bl, 0, 0) ) - return 0; - - if( battle->check_target(&ed->bl,bl,BCT_ENEMY) <= 0 ) - return 0; - - switch( bl->type ) { - case BL_PC: - if( !map_flag_vs(ed->bl.m) ) - return 0; - default: - dist = distance_bl(&ed->bl, bl); - if( ((*target) == NULL || !check_distance_bl(&ed->bl, *target, dist)) && battle->check_range(&ed->bl,bl,ed->db->range2) ) { //Pick closest target? - (*target) = bl; - ed->target_id = bl->id; - ed->min_chase = dist + ed->db->range3; - if( ed->min_chase > AREA_SIZE ) - ed->min_chase = AREA_SIZE; - return 1; - } - break; - } - return 0; -} - -static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) { - struct block_list *target = NULL; - int master_dist, view_range, mode; - - nullpo_ret(ed); - nullpo_ret(sd); - - if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL ) - return 0; - - // Check if caster can sustain the summoned elemental - if( DIFF_TICK(tick,ed->last_spdrain_time) >= 10000 ){// Drain SP every 10 seconds - int sp = 5; - - switch(ed->vd->class_){ - case 2115: case 2118: - case 2121: case 2124: - sp = 8; - break; - case 2116: case 2119: - case 2122: case 2125: - sp = 11; - break; - } - - if( status_get_sp(&sd->bl) < sp ){ // Can't sustain delete it. - elemental->delete(sd->ed,0); - return 0; - } - - status_zap(&sd->bl,0,sp); - ed->last_spdrain_time = tick; - } - - if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME ) - return 0; - - ed->last_thinktime = tick; - - if( ed->ud.skilltimer != INVALID_TIMER ) - return 0; - - if( ed->ud.walktimer != INVALID_TIMER && ed->ud.walkpath.path_pos <= 2 ) - return 0; //No thinking when you just started to walk. - - if(ed->ud.walkpath.path_pos < ed->ud.walkpath.path_len && ed->ud.target == sd->bl.id) - return 0; //No thinking until be near the master. - - if( ed->sc.count && ed->sc.data[SC_BLIND] ) - view_range = 3; - else - view_range = ed->db->range2; - - mode = status_get_mode(&ed->bl); - - master_dist = distance_bl(&sd->bl, &ed->bl); - if( master_dist > AREA_SIZE ) { // Master out of vision range. - elemental->unlocktarget(ed); - unit_warp(&ed->bl,sd->bl.m,sd->bl.x,sd->bl.y,CLR_TELEPORT); - clif->elemental_updatestatus(sd,SP_HP); - clif->elemental_updatestatus(sd,SP_SP); - return 0; - } else if( master_dist > MAX_ELEDISTANCE ) { // Master too far, chase. - short x = sd->bl.x, y = sd->bl.y; - if( ed->target_id ) - elemental->unlocktarget(ed); - if( ed->ud.walktimer != INVALID_TIMER && ed->ud.target == sd->bl.id ) - return 0; //Already walking to him - if( DIFF_TICK(tick, ed->ud.canmove_tick) < 0 ) - return 0; //Can't move yet. - if( iMap->search_freecell(&ed->bl, sd->bl.m, &x, &y, MIN_ELEDISTANCE, MIN_ELEDISTANCE, 1) - && unit_walktoxy(&ed->bl, x, y, 0) ) - return 0; - } - - if( mode == EL_MODE_AGGRESSIVE ) { - target = iMap->id2bl(ed->ud.target); - - if( !target ) - iMap->foreachinrange(elemental_ai_sub_timer_activesearch, &ed->bl, view_range, BL_CHAR, ed, &target, status_get_mode(&ed->bl)); - - if( !target ) { //No targets available. - elemental->unlocktarget(ed); - return 1; - } - - if( battle->check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill. - if( elemental->action(ed,target,tick) ) - return 1; - } - - //Attempt to attack. - //At this point we know the target is attackable, we just gotta check if the range matches. - if( ed->ud.target == target->id && ed->ud.attacktimer != INVALID_TIMER ) //Already locked. - return 1; - - if( battle->check_range(&ed->bl, target, ed->base_status.rhw.range) ) {//Target within range, engage - unit_attack(&ed->bl,target->id,1); - return 1; - } - - //Follow up if possible. - if( !unit_walktobl(&ed->bl, target, ed->base_status.rhw.range, 2) ) - elemental->unlocktarget(ed); - } - - return 0; -} - -static int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { - unsigned int tick = va_arg(ap,unsigned int); - if(sd->status.ele_id && sd->ed) - elemental_ai_sub_timer(sd->ed,sd,tick); - - return 0; -} - -static int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) { - iMap->map_foreachpc(elemental_ai_sub_foreachclient,tick); - return 0; -} - -int read_elementaldb(void) { - FILE *fp; - char line[1024], *p; - char *str[26]; - int i, j = 0, k = 0, ele; - struct s_elemental_db *db; - struct status_data *status; - - sprintf(line, "%s/%s", iMap->db_path, "elemental_db.txt"); - memset(elemental->elemental_db,0,sizeof(elemental->elemental_db)); - - fp = fopen(line, "r"); - if( !fp ) { - ShowError("read_elementaldb : can't read elemental_db.txt\n"); - return -1; - } - - while( fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS ) { - k++; - if( line[0] == '/' && line[1] == '/' ) - continue; - - if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') - continue; - - i = 0; - p = strtok(line, ","); - while( p != NULL && i < 26 ) { - str[i++] = p; - p = strtok(NULL, ","); - } - if( i < 26 ) { - ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k); - continue; - } - - db = &elemental->elemental_db[j]; - db->class_ = atoi(str[0]); - safestrncpy(db->sprite, str[1], NAME_LENGTH); - safestrncpy(db->name, str[2], NAME_LENGTH); - db->lv = atoi(str[3]); - - status = &db->status; - db->vd.class_ = db->class_; - - status->max_hp = atoi(str[4]); - status->max_sp = atoi(str[5]); - status->rhw.range = atoi(str[6]); - status->rhw.atk = atoi(str[7]); - status->rhw.atk2 = atoi(str[8]); - status->def = atoi(str[9]); - status->mdef = atoi(str[10]); - status->str = atoi(str[11]); - status->agi = atoi(str[12]); - status->vit = atoi(str[13]); - status->int_ = atoi(str[14]); - status->dex = atoi(str[15]); - status->luk = atoi(str[16]); - db->range2 = atoi(str[17]); - db->range3 = atoi(str[18]); - status->size = atoi(str[19]); - status->race = atoi(str[20]); - - ele = atoi(str[21]); - status->def_ele = ele%10; - status->ele_lv = ele/20; - if( status->def_ele >= ELE_MAX ) { - ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1); - status->def_ele = ELE_NEUTRAL; - } - if( status->ele_lv < 1 || status->ele_lv > 4 ) { - ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv); - status->ele_lv = 1; - } - - status->aspd_rate = 1000; - status->speed = atoi(str[22]); - status->adelay = atoi(str[23]); - status->amotion = atoi(str[24]); - status->dmotion = atoi(str[25]); - - j++; - } - - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j); - - return 0; -} - -int read_elemental_skilldb(void) { - FILE *fp; - char line[1024], *p; - char *str[4]; - struct s_elemental_db *db; - int i, j = 0, k = 0, class_; - uint16 skill_id, skill_lv; - int skillmode; - - sprintf(line, "%s/%s", iMap->db_path, "elemental_skill_db.txt"); - fp = fopen(line, "r"); - if( !fp ) { - ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n"); - return -1; - } - - while( fgets(line, sizeof(line), fp) ) { - k++; - if( line[0] == '/' && line[1] == '/' ) - continue; - - if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') - continue; - - i = 0; - p = strtok(line, ","); - while( p != NULL && i < 4 ) { - str[i++] = p; - p = strtok(NULL, ","); - } - if( i < 4 ) { - ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k); - continue; - } - - class_ = atoi(str[0]); - ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental->elemental_db[i].class_); - if( i == MAX_ELEMENTAL_CLASS ) { - ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k); - continue; - } - - skill_id = atoi(str[1]); - if( skill_id < EL_SKILLBASE || skill_id >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) { - ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k); - continue; - } - - db = &elemental->elemental_db[i]; - skill_lv = atoi(str[2]); - - skillmode = atoi(str[3]); - if( skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE ) { - ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k); - continue; - } - ARR_FIND( 0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skill_id ); - if( i == MAX_ELESKILLTREE ) { - ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skill_id, class_); - continue; - } - db->skill[i].id = skill_id; - db->skill[i].lv = skill_lv; - db->skill[i].mode = skillmode; - j++; - } - - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j); - return 0; -} - -void reload_elementaldb(void) { - read_elementaldb(); - elemental->reload_skilldb(); -} - -void reload_elemental_skilldb(void) { - elemental->read_skilldb(); -} - -int do_init_elemental(void) { - read_elementaldb(); - elemental->read_skilldb(); - - iTimer->add_timer_func_list(elemental_ai_timer,"elemental_ai_timer"); - iTimer->add_timer_interval(iTimer->gettick()+MIN_ELETHINKTIME,elemental_ai_timer,0,0,MIN_ELETHINKTIME); - - return 0; -} - -void do_final_elemental(void) { - return; -} - -/*===================================== -* Default Functions : elemental.h -* Generated by HerculesInterfaceMaker -* created by Susu -*-------------------------------------*/ -void elemental_defaults(void) { - elemental = &elemental_s; - /* funcs */ - - elemental->class = elemental_class; - elemental->get_viewdata = elemental_get_viewdata; - - elemental->create = elemental_create; - elemental->data_received = elemental_data_received; - elemental->save = elemental_save; - - elemental->change_mode_ack = elemental_change_mode_ack; - elemental->change_mode = elemental_change_mode; - - elemental->heal = elemental_heal; - elemental->dead = elemental_dead; - - elemental->delete = elemental_delete; - elemental->summon_stop = elemental_summon_stop; - - elemental->get_lifetime = elemental_get_lifetime; - - elemental->unlocktarget = elemental_unlocktarget; - elemental->skillnotok = elemental_skillnotok; - elemental->set_target = elemental_set_target; - elemental->clean_single_effect = elemental_clean_single_effect; - elemental->clean_effect = elemental_clean_effect; - elemental->action = elemental_action; - elemental->skill_get_requirements = elemental_skill_get_requirements; - - elemental->read_skilldb = read_elemental_skilldb; - elemental->reload_elementaldb = reload_elementaldb; - elemental->reload_skilldb = reload_elemental_skilldb; - elemental->do_init_elemental = do_init_elemental; - elemental->do_final_elemental = do_final_elemental; -} +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams + +#include "../common/cbasetypes.h" +#include "../common/malloc.h" +#include "../common/socket.h" +#include "../common/timer.h" +#include "../common/nullpo.h" +#include "../common/mmo.h" +#include "../common/showmsg.h" +#include "../common/utils.h" +#include "../common/random.h" +#include "../common/strlib.h" + +#include "log.h" +#include "clif.h" +#include "chrif.h" +#include "intif.h" +#include "itemdb.h" +#include "map.h" +#include "pc.h" +#include "status.h" +#include "skill.h" +#include "mob.h" +#include "pet.h" +#include "battle.h" +#include "party.h" +#include "guild.h" +#include "atcommand.h" +#include "script.h" +#include "npc.h" +#include "trade.h" +#include "unit.h" +#include "elemental.h" + +#include +#include +#include +#include + +int elemental_search_index(int class_) { + int i; + ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, elemental->elemental_db[i].class_ == class_); + return (i == MAX_ELEMENTAL_CLASS)?-1:i; +} + +bool elemental_class(int class_) { + return (bool)(elemental_search_index(class_) > -1); +} + +struct view_data * elemental_get_viewdata(int class_) { + int i = elemental_search_index(class_); + if( i < 0 ) + return 0; + + return &elemental->elemental_db[i].vd; +} + +int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime) { + struct s_elemental ele; + struct s_elemental_db *db; + int i; + + nullpo_retr(1,sd); + + if( (i = elemental_search_index(class_)) < 0 ) + return 0; + + db = &elemental->elemental_db[i]; + memset(&ele,0,sizeof(struct s_elemental)); + + ele.char_id = sd->status.char_id; + ele.class_ = class_; + ele.mode = EL_MODE_PASSIVE; // Initial mode + i = db->status.size+1; // summon level + + //[(Caster�s Max HP/ 3 ) + (Caster�s INT x 10 )+ (Caster�s Job Level x 20 )] x [(Elemental Summon Level + 2) / 3] + ele.hp = ele.max_hp = (sd->battle_status.max_hp/3 + sd->battle_status.int_*10 + sd->status.job_level) * ((i + 2) / 3); + //Caster�s Max SP /4 + ele.sp = ele.max_sp = sd->battle_status.max_sp/4; + //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) 1- 100 ] + ele.atk = (sd->battle_status.max_sp / (18 / i) * 1 - 100); + //Caster�s [ Max SP / (18 / Elemental Summon Skill Level) ] + ele.atk2 = sd->battle_status.max_sp / 18; + //Caster�s HIT + (Caster�s Base Level ) + ele.hit = sd->battle_status.hit + sd->status.base_level; + //[Elemental Summon Skill Level x (Caster�s INT / 2 + Caster�s DEX / 4)] + ele.matk = i * (sd->battle_status.int_ / 2 + sd->battle_status.dex / 4); + //150 + [Caster�s DEX / 10] + [Elemental Summon Skill Level x 3 ] + ele.amotion = 150 + sd->battle_status.dex / 10 + i * 3; + //Caster�s DEF + (Caster�s Base Level / (5 � Elemental Summon Skill Level) + ele.def = sd->battle_status.def + sd->status.base_level / (5-i); + //Caster�s MDEF + (Caster�s INT / (5 - Elemental Summon Skill Level) + ele.mdef = sd->battle_status.mdef + sd->battle_status.int_ / (5-i); + //Caster�s FLEE + (Caster�s Base Level / (5 � Elemental Summon Skill Level) + ele.flee = sd->status.base_level / (5-i); + //Caster�s HIT + (Caster�s Base Level ) + ele.hit = sd->battle_status.hit + sd->status.base_level; + + //per individual bonuses + switch(db->class_){ + case 2114: case 2115: + case 2116: //ATK + (Summon Agni Skill Level x 20) / HIT + (Summon Agni Skill Level x 10) + ele.atk += i * 20; + ele.atk2 += i * 20; + ele.hit += i * 10; + break; + case 2117: case 2118: + case 2119: //MDEF + (Summon Aqua Skill Level x 10) / MATK + (Summon Aqua Skill Level x 20) + ele.mdef += i * 10; + ele.matk += i * 20; + break; + case 2120: case 2121: + case 2122: //FLEE + (Summon Ventus Skill Level x 20) / MATK + (Summon Ventus Skill Level x 10) + ele.flee += i * 20; + ele.matk += i * 10; + break; + case 2123: case 2124: + case 2125: //DEF + (Summon Tera Skill Level x 25) / ATK + (Summon Tera Skill Level x 5) + ele.def += i * 25; + ele.atk += i * 5; + ele.atk2 += i * 5; + break; + } + + if( (i=pc->checkskill(sd,SO_EL_SYMPATHY)) > 0 ){ + ele.hp = ele.max_hp = ele.max_hp * 5 * i / 100; + ele.sp = ele.max_sp = ele.max_sp * 5 * i / 100; + ele.atk += 25 * i; + ele.atk2 += 25 * i; + ele.matk += 25 * i; + } + + ele.life_time = lifetime; + + // Request Char Server to create this elemental + intif->elemental_create(&ele); + + return 1; +} + +int elemental_get_lifetime(struct elemental_data *ed) { + const struct TimerData * td; + if( ed == NULL || ed->summon_timer == INVALID_TIMER ) + return 0; + + td = iTimer->get_timer(ed->summon_timer); + return (td != NULL) ? DIFF_TICK(td->tick, iTimer->gettick()) : 0; +} + +int elemental_save(struct elemental_data *ed) { + ed->elemental.mode = ed->battle_status.mode; + ed->elemental.hp = ed->battle_status.hp; + ed->elemental.sp = ed->battle_status.sp; + ed->elemental.max_hp = ed->battle_status.max_hp; + ed->elemental.max_sp = ed->battle_status.max_sp; + ed->elemental.atk = ed->battle_status.rhw.atk; + ed->elemental.atk2 = ed->battle_status.rhw.atk2; + ed->elemental.matk = ed->battle_status.matk_min; + ed->elemental.def = ed->battle_status.def; + ed->elemental.mdef = ed->battle_status.mdef; + ed->elemental.flee = ed->battle_status.flee; + ed->elemental.hit = ed->battle_status.hit; + ed->elemental.life_time = elemental->get_lifetime(ed); + intif->elemental_save(&ed->elemental); + return 1; +} + +static int elemental_summon_end(int tid, unsigned int tick, int id, intptr_t data) { + struct map_session_data *sd; + struct elemental_data *ed; + + if( (sd = iMap->id2sd(id)) == NULL ) + return 1; + if( (ed = sd->ed) == NULL ) + return 1; + + if( ed->summon_timer != tid ) { + ShowError("elemental_summon_end %d != %d.\n", ed->summon_timer, tid); + return 0; + } + + ed->summon_timer = INVALID_TIMER; + elemental->delete(ed, 0); // Elemental's summon time is over. + + return 0; +} + +void elemental_summon_stop(struct elemental_data *ed) { + nullpo_retv(ed); + if( ed->summon_timer != INVALID_TIMER ) + iTimer->delete_timer(ed->summon_timer, elemental_summon_end); + ed->summon_timer = INVALID_TIMER; +} + +int elemental_delete(struct elemental_data *ed, int reply) { + struct map_session_data *sd; + nullpo_ret(ed); + + sd = ed->master; + ed->elemental.life_time = 0; + + elemental->clean_effect(ed); + elemental->summon_stop(ed); + + if( !sd ) + return unit->free(&ed->bl, 0); + + sd->ed = NULL; + sd->status.ele_id = 0; + + return unit->remove_map(&ed->bl, 0, ALC_MARK); +} + +void elemental_summon_init(struct elemental_data *ed) { + if( ed->summon_timer == INVALID_TIMER ) + ed->summon_timer = iTimer->add_timer(iTimer->gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0); + + ed->regen.state.block = 0; +} + +int elemental_data_received(struct s_elemental *ele, bool flag) { + struct map_session_data *sd; + struct elemental_data *ed; + struct s_elemental_db *db; + int i = elemental_search_index(ele->class_); + + if( (sd = iMap->charid2sd(ele->char_id)) == NULL ) + return 0; + + if( !flag || i < 0 ) { // Not created - loaded - DB info + sd->status.ele_id = 0; + return 0; + } + + db = &elemental->elemental_db[i]; + if( !sd->ed ) { // Initialize it after first summon. + sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); + ed->bl.type = BL_ELEM; + ed->bl.id = npc_get_new_npc_id(); + ed->master = sd; + ed->db = db; + memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); + iStatus->set_viewdata(&ed->bl, ed->elemental.class_); + ed->vd->head_mid = 10; // Why? + iStatus->change_init(&ed->bl); + unit->dataset(&ed->bl); + ed->ud.dir = sd->ud.dir; + + ed->bl.m = sd->bl.m; + ed->bl.x = sd->bl.x; + ed->bl.y = sd->bl.y; + unit->calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir); + ed->bl.x = ed->ud.to_x; + ed->bl.y = ed->ud.to_y; + + iMap->addiddb(&ed->bl); + status_calc_elemental(ed,1); + ed->last_spdrain_time = ed->last_thinktime = iTimer->gettick(); + ed->summon_timer = INVALID_TIMER; + elemental_summon_init(ed); + } else { + memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental)); + ed = sd->ed; + } + + sd->status.ele_id = ele->elemental_id; + + if( ed->bl.prev == NULL && sd->bl.prev != NULL ) { + iMap->addblock(&ed->bl); + clif->spawn(&ed->bl); + clif->elemental_info(sd); + clif->elemental_updatestatus(sd,SP_HP); + clif->hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.max_hp); + clif->elemental_updatestatus(sd,SP_SP); + } + + return 1; +} + +int elemental_clean_single_effect(struct elemental_data *ed, uint16 skill_id) { + struct block_list *bl; + sc_type type = iStatus->skill2sc(skill_id); + + nullpo_ret(ed); + + bl = battle->get_master(&ed->bl); + + if( type ) { + switch( type ) { + // Just remove status change. + case SC_PYROTECHNIC_OPTION: + case SC_HEATER_OPTION: + case SC_TROPIC_OPTION: + case SC_FIRE_CLOAK_OPTION: + case SC_AQUAPLAY_OPTION: + case SC_WATER_SCREEN_OPTION: + case SC_COOLER_OPTION: + case SC_CHILLY_AIR_OPTION: + case SC_GUST_OPTION: + case SC_WIND_STEP_OPTION: + case SC_BLAST_OPTION: + case SC_WATER_DROP_OPTION: + case SC_WIND_CURTAIN_OPTION: + case SC_WILD_STORM_OPTION: + case SC_PETROLOGY_OPTION: + case SC_SOLID_SKIN_OPTION: + case SC_CURSED_SOIL_OPTION: + case SC_STONE_SHIELD_OPTION: + case SC_UPHEAVAL_OPTION: + case SC_CIRCLE_OF_FIRE_OPTION: + case SC_TIDAL_WEAPON_OPTION: + if( bl ) status_change_end(bl,type,INVALID_TIMER); // Master + status_change_end(&ed->bl,type-1,INVALID_TIMER); // Elemental Spirit + break; + case SC_ZEPHYR: + if( bl ) status_change_end(bl,type,INVALID_TIMER); + break; + default: + ShowWarning("Invalid SC=%d in elemental_clean_single_effect\n",type); + break; + } + } + + return 1; +} + +int elemental_clean_effect(struct elemental_data *ed) { + struct map_session_data *sd; + + nullpo_ret(ed); + + // Elemental side + status_change_end(&ed->bl, SC_TROPIC, INVALID_TIMER); + status_change_end(&ed->bl, SC_HEATER, INVALID_TIMER); + status_change_end(&ed->bl, SC_AQUAPLAY, INVALID_TIMER); + status_change_end(&ed->bl, SC_COOLER, INVALID_TIMER); + status_change_end(&ed->bl, SC_CHILLY_AIR, INVALID_TIMER); + status_change_end(&ed->bl, SC_PYROTECHNIC, INVALID_TIMER); + status_change_end(&ed->bl, SC_FIRE_CLOAK, INVALID_TIMER); + status_change_end(&ed->bl, SC_WATER_DROP, INVALID_TIMER); + status_change_end(&ed->bl, SC_WATER_SCREEN, INVALID_TIMER); + status_change_end(&ed->bl, SC_GUST, INVALID_TIMER); + status_change_end(&ed->bl, SC_WIND_STEP, INVALID_TIMER); + status_change_end(&ed->bl, SC_BLAST, INVALID_TIMER); + status_change_end(&ed->bl, SC_WIND_CURTAIN, INVALID_TIMER); + status_change_end(&ed->bl, SC_WILD_STORM, INVALID_TIMER); + status_change_end(&ed->bl, SC_PETROLOGY, INVALID_TIMER); + status_change_end(&ed->bl, SC_SOLID_SKIN, INVALID_TIMER); + status_change_end(&ed->bl, SC_CURSED_SOIL, INVALID_TIMER); + status_change_end(&ed->bl, SC_STONE_SHIELD, INVALID_TIMER); + status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER); + status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER); + status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER); + + if( (sd = ed->master) == NULL ) + return 0; + + // Master side + status_change_end(&sd->bl, SC_TROPIC_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_HEATER_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_AQUAPLAY_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_COOLER_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_CHILLY_AIR_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_PYROTECHNIC_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_FIRE_CLOAK_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WATER_SCREEN_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_GUST_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_BLAST_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WIND_CURTAIN_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_WILD_STORM_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_ZEPHYR, INVALID_TIMER); + status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_PETROLOGY_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_SOLID_SKIN_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_CURSED_SOIL_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_STONE_SHIELD_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_UPHEAVAL_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_CIRCLE_OF_FIRE_OPTION, INVALID_TIMER); + status_change_end(&sd->bl, SC_TIDAL_WEAPON_OPTION, INVALID_TIMER); + + return 1; +} + +int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) { + struct skill_condition req; + uint16 skill_id, skill_lv; + int i; + + nullpo_ret(ed); + nullpo_ret(bl); + + if( !ed->master ) + return 0; + + if( ed->target_id ) + elemental->unlocktarget(ed); // Remove previous target. + + ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE)); + if( i == MAX_ELESKILLTREE ) + return 0; + + skill_id = ed->db->skill[i].id; + skill_lv = ed->db->skill[i].lv; + + if( elemental->skillnotok(skill_id, ed) ) + return 0; + + if( ed->ud.skilltimer != INVALID_TIMER ) + return 0; + else if( DIFF_TICK(tick, ed->ud.canact_tick) < 0 ) + return 0; + + ed->target_id = ed->ud.skilltarget = bl->id; // Set new target + ed->last_thinktime = tick; + + // Not in skill range. + if( !battle->check_range(&ed->bl,bl,skill->get_range(skill_id,skill_lv)) ) { + // Try to walk to the target. + if( !unit->walktobl(&ed->bl, bl, skill->get_range(skill_id,skill_lv), 2) ) + elemental->unlocktarget(ed); + else { + // Walking, waiting to be in range. Client don't handle it, then we must handle it here. + int walk_dist = distance_bl(&ed->bl,bl) - skill->get_range(skill_id,skill_lv); + ed->ud.skill_id = skill_id; + ed->ud.skill_lv = skill_lv; + + if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) + ed->ud.skilltimer = iTimer->add_timer( tick+iStatus->get_speed(&ed->bl)*walk_dist, skill->castend_pos, ed->bl.id, 0 ); + else + ed->ud.skilltimer = iTimer->add_timer( tick+iStatus->get_speed(&ed->bl)*walk_dist, skill->castend_id, ed->bl.id, 0 ); + } + return 1; + + } + + req = elemental->skill_get_requirements(skill_id, skill_lv); + + if(req.hp || req.sp){ + struct map_session_data *sd = BL_CAST(BL_PC, battle->get_master(&ed->bl)); + if( sd ){ + if( sd->skill_id_old != SO_EL_ACTION && //regardless of remaining HP/SP it can be cast + (status_get_hp(&ed->bl) < req.hp || status_get_sp(&ed->bl) < req.sp) ) + return 1; + else + status_zap(&ed->bl, req.hp, req.sp); + } + } + + //Otherwise, just cast the skill. + if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) + unit->skilluse_pos(&ed->bl, bl->x, bl->y, skill_id, skill_lv); + else + unit->skilluse_id(&ed->bl, bl->id, skill_id, skill_lv); + + // Reset target. + ed->target_id = 0; + + return 1; +} + +/*=============================================================== + * Action that elemental perform after changing mode. + * Activates one of the skills of the new mode. + *-------------------------------------------------------------*/ +int elemental_change_mode_ack(struct elemental_data *ed, int mode) { + struct block_list *bl = &ed->master->bl; + uint16 skill_id, skill_lv; + int i; + + nullpo_ret(ed); + + if( !bl ) + return 0; + + // Select a skill. + ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode)); + if( i == MAX_ELESKILLTREE ) + return 0; + + skill_id = ed->db->skill[i].id; + skill_lv = ed->db->skill[i].lv; + + if( elemental->skillnotok(skill_id, ed) ) + return 0; + + if( ed->ud.skilltimer != INVALID_TIMER ) + return 0; + else if( DIFF_TICK(iTimer->gettick(), ed->ud.canact_tick) < 0 ) + return 0; + + ed->target_id = bl->id; // Set new target + ed->last_thinktime = iTimer->gettick(); + + if( skill->get_inf(skill_id) & INF_GROUND_SKILL ) + unit->skilluse_pos(&ed->bl, bl->x, bl->y, skill_id, skill_lv); + else + unit->skilluse_id(&ed->bl,bl->id,skill_id,skill_lv); + + ed->target_id = 0; // Reset target after casting the skill to avoid continious attack. + + return 1; +} + +/*=============================================================== + * Change elemental mode. + *-------------------------------------------------------------*/ +int elemental_change_mode(struct elemental_data *ed, int mode) { + nullpo_ret(ed); + + // Remove target + elemental->unlocktarget(ed); + + // Removes the effects of the previous mode. + if(ed->elemental.mode != mode ) elemental->clean_effect(ed); + + ed->battle_status.mode = ed->elemental.mode = mode; + + // Normalize elemental mode to elemental skill mode. + if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill. + else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill. + else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill. + + // Use a skill inmediately after every change mode. + if( mode != EL_SKILLMODE_AGGRESSIVE ) + elemental->change_mode_ack(ed,mode); + return 1; +} + +void elemental_heal(struct elemental_data *ed, int hp, int sp) { + if( hp ) + clif->elemental_updatestatus(ed->master, SP_HP); + if( sp ) + clif->elemental_updatestatus(ed->master, SP_SP); +} + +int elemental_dead(struct elemental_data *ed) { + elemental->delete(ed, 1); + return 0; +} + +int elemental_unlocktarget(struct elemental_data *ed) { + nullpo_ret(ed); + + ed->target_id = 0; + elemental_stop_attack(ed); + elemental_stop_walking(ed,1); + return 0; +} + +int elemental_skillnotok(uint16 skill_id, struct elemental_data *ed) { + int idx = skill->get_index(skill_id); + nullpo_retr(1,ed); + + if (idx == 0) + return 1; // invalid skill id + + return skill->not_ok(skill_id, ed->master); +} + +struct skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){ + struct skill_condition req; + int idx = skill->get_index(skill_id); + + memset(&req,0,sizeof(req)); + + if( idx == 0 ) // invalid skill id + return req; + + if( skill_lv < 1 || skill_lv > MAX_SKILL_LEVEL ) + return req; + + req.hp = skill_db[idx].hp[skill_lv-1]; + req.sp = skill_db[idx].sp[skill_lv-1]; + + return req; +} + +int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) { + struct elemental_data *ed = sd->ed; + + nullpo_ret(ed); + nullpo_ret(bl); + + if( ed->bl.m != bl->m || !check_distance_bl(&ed->bl, bl, ed->db->range2) ) + return 0; + + if( !iStatus->check_skilluse(&ed->bl, bl, 0, 0) ) + return 0; + + if( ed->target_id == 0 ) + ed->target_id = bl->id; + + return 1; +} + +static int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) { + struct elemental_data *ed; + struct block_list **target; + int dist; + + nullpo_ret(bl); + + ed = va_arg(ap,struct elemental_data *); + target = va_arg(ap,struct block_list**); + + //If can't seek yet, not an enemy, or you can't attack it, skip. + if( (*target) == bl || !iStatus->check_skilluse(&ed->bl, bl, 0, 0) ) + return 0; + + if( battle->check_target(&ed->bl,bl,BCT_ENEMY) <= 0 ) + return 0; + + switch( bl->type ) { + case BL_PC: + if( !map_flag_vs(ed->bl.m) ) + return 0; + default: + dist = distance_bl(&ed->bl, bl); + if( ((*target) == NULL || !check_distance_bl(&ed->bl, *target, dist)) && battle->check_range(&ed->bl,bl,ed->db->range2) ) { //Pick closest target? + (*target) = bl; + ed->target_id = bl->id; + ed->min_chase = dist + ed->db->range3; + if( ed->min_chase > AREA_SIZE ) + ed->min_chase = AREA_SIZE; + return 1; + } + break; + } + return 0; +} + +static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) { + struct block_list *target = NULL; + int master_dist, view_range, mode; + + nullpo_ret(ed); + nullpo_ret(sd); + + if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL ) + return 0; + + // Check if caster can sustain the summoned elemental + if( DIFF_TICK(tick,ed->last_spdrain_time) >= 10000 ){// Drain SP every 10 seconds + int sp = 5; + + switch(ed->vd->class_){ + case 2115: case 2118: + case 2121: case 2124: + sp = 8; + break; + case 2116: case 2119: + case 2122: case 2125: + sp = 11; + break; + } + + if( status_get_sp(&sd->bl) < sp ){ // Can't sustain delete it. + elemental->delete(sd->ed,0); + return 0; + } + + status_zap(&sd->bl,0,sp); + ed->last_spdrain_time = tick; + } + + if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME ) + return 0; + + ed->last_thinktime = tick; + + if( ed->ud.skilltimer != INVALID_TIMER ) + return 0; + + if( ed->ud.walktimer != INVALID_TIMER && ed->ud.walkpath.path_pos <= 2 ) + return 0; //No thinking when you just started to walk. + + if(ed->ud.walkpath.path_pos < ed->ud.walkpath.path_len && ed->ud.target == sd->bl.id) + return 0; //No thinking until be near the master. + + if( ed->sc.count && ed->sc.data[SC_BLIND] ) + view_range = 3; + else + view_range = ed->db->range2; + + mode = status_get_mode(&ed->bl); + + master_dist = distance_bl(&sd->bl, &ed->bl); + if( master_dist > AREA_SIZE ) { // Master out of vision range. + elemental->unlocktarget(ed); + unit->warp(&ed->bl,sd->bl.m,sd->bl.x,sd->bl.y,CLR_TELEPORT); + clif->elemental_updatestatus(sd,SP_HP); + clif->elemental_updatestatus(sd,SP_SP); + return 0; + } else if( master_dist > MAX_ELEDISTANCE ) { // Master too far, chase. + short x = sd->bl.x, y = sd->bl.y; + if( ed->target_id ) + elemental->unlocktarget(ed); + if( ed->ud.walktimer != INVALID_TIMER && ed->ud.target == sd->bl.id ) + return 0; //Already walking to him + if( DIFF_TICK(tick, ed->ud.canmove_tick) < 0 ) + return 0; //Can't move yet. + if( iMap->search_freecell(&ed->bl, sd->bl.m, &x, &y, MIN_ELEDISTANCE, MIN_ELEDISTANCE, 1) + && unit->walktoxy(&ed->bl, x, y, 0) ) + return 0; + } + + if( mode == EL_MODE_AGGRESSIVE ) { + target = iMap->id2bl(ed->ud.target); + + if( !target ) + iMap->foreachinrange(elemental_ai_sub_timer_activesearch, &ed->bl, view_range, BL_CHAR, ed, &target, status_get_mode(&ed->bl)); + + if( !target ) { //No targets available. + elemental->unlocktarget(ed); + return 1; + } + + if( battle->check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill. + if( elemental->action(ed,target,tick) ) + return 1; + } + + //Attempt to attack. + //At this point we know the target is attackable, we just gotta check if the range matches. + if( ed->ud.target == target->id && ed->ud.attacktimer != INVALID_TIMER ) //Already locked. + return 1; + + if( battle->check_range(&ed->bl, target, ed->base_status.rhw.range) ) {//Target within range, engage + unit->attack(&ed->bl,target->id,1); + return 1; + } + + //Follow up if possible. + if( !unit->walktobl(&ed->bl, target, ed->base_status.rhw.range, 2) ) + elemental->unlocktarget(ed); + } + + return 0; +} + +static int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { + unsigned int tick = va_arg(ap,unsigned int); + if(sd->status.ele_id && sd->ed) + elemental_ai_sub_timer(sd->ed,sd,tick); + + return 0; +} + +static int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) { + iMap->map_foreachpc(elemental_ai_sub_foreachclient,tick); + return 0; +} + +int read_elementaldb(void) { + FILE *fp; + char line[1024], *p; + char *str[26]; + int i, j = 0, k = 0, ele; + struct s_elemental_db *db; + struct status_data *status; + + sprintf(line, "%s/%s", iMap->db_path, "elemental_db.txt"); + memset(elemental->elemental_db,0,sizeof(elemental->elemental_db)); + + fp = fopen(line, "r"); + if( !fp ) { + ShowError("read_elementaldb : can't read elemental_db.txt\n"); + return -1; + } + + while( fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS ) { + k++; + if( line[0] == '/' && line[1] == '/' ) + continue; + + if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') + continue; + + i = 0; + p = strtok(line, ","); + while( p != NULL && i < 26 ) { + str[i++] = p; + p = strtok(NULL, ","); + } + if( i < 26 ) { + ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k); + continue; + } + + db = &elemental->elemental_db[j]; + db->class_ = atoi(str[0]); + safestrncpy(db->sprite, str[1], NAME_LENGTH); + safestrncpy(db->name, str[2], NAME_LENGTH); + db->lv = atoi(str[3]); + + status = &db->status; + db->vd.class_ = db->class_; + + status->max_hp = atoi(str[4]); + status->max_sp = atoi(str[5]); + status->rhw.range = atoi(str[6]); + status->rhw.atk = atoi(str[7]); + status->rhw.atk2 = atoi(str[8]); + status->def = atoi(str[9]); + status->mdef = atoi(str[10]); + status->str = atoi(str[11]); + status->agi = atoi(str[12]); + status->vit = atoi(str[13]); + status->int_ = atoi(str[14]); + status->dex = atoi(str[15]); + status->luk = atoi(str[16]); + db->range2 = atoi(str[17]); + db->range3 = atoi(str[18]); + status->size = atoi(str[19]); + status->race = atoi(str[20]); + + ele = atoi(str[21]); + status->def_ele = ele%10; + status->ele_lv = ele/20; + if( status->def_ele >= ELE_MAX ) { + ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1); + status->def_ele = ELE_NEUTRAL; + } + if( status->ele_lv < 1 || status->ele_lv > 4 ) { + ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv); + status->ele_lv = 1; + } + + status->aspd_rate = 1000; + status->speed = atoi(str[22]); + status->adelay = atoi(str[23]); + status->amotion = atoi(str[24]); + status->dmotion = atoi(str[25]); + + j++; + } + + fclose(fp); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j); + + return 0; +} + +int read_elemental_skilldb(void) { + FILE *fp; + char line[1024], *p; + char *str[4]; + struct s_elemental_db *db; + int i, j = 0, k = 0, class_; + uint16 skill_id, skill_lv; + int skillmode; + + sprintf(line, "%s/%s", iMap->db_path, "elemental_skill_db.txt"); + fp = fopen(line, "r"); + if( !fp ) { + ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n"); + return -1; + } + + while( fgets(line, sizeof(line), fp) ) { + k++; + if( line[0] == '/' && line[1] == '/' ) + continue; + + if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') + continue; + + i = 0; + p = strtok(line, ","); + while( p != NULL && i < 4 ) { + str[i++] = p; + p = strtok(NULL, ","); + } + if( i < 4 ) { + ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k); + continue; + } + + class_ = atoi(str[0]); + ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental->elemental_db[i].class_); + if( i == MAX_ELEMENTAL_CLASS ) { + ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k); + continue; + } + + skill_id = atoi(str[1]); + if( skill_id < EL_SKILLBASE || skill_id >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) { + ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k); + continue; + } + + db = &elemental->elemental_db[i]; + skill_lv = atoi(str[2]); + + skillmode = atoi(str[3]); + if( skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE ) { + ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k); + continue; + } + ARR_FIND( 0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skill_id ); + if( i == MAX_ELESKILLTREE ) { + ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skill_id, class_); + continue; + } + db->skill[i].id = skill_id; + db->skill[i].lv = skill_lv; + db->skill[i].mode = skillmode; + j++; + } + + fclose(fp); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j); + return 0; +} + +void reload_elementaldb(void) { + read_elementaldb(); + elemental->reload_skilldb(); +} + +void reload_elemental_skilldb(void) { + elemental->read_skilldb(); +} + +int do_init_elemental(void) { + read_elementaldb(); + elemental->read_skilldb(); + + iTimer->add_timer_func_list(elemental_ai_timer,"elemental_ai_timer"); + iTimer->add_timer_interval(iTimer->gettick()+MIN_ELETHINKTIME,elemental_ai_timer,0,0,MIN_ELETHINKTIME); + + return 0; +} + +void do_final_elemental(void) { + return; +} + +/*===================================== +* Default Functions : elemental.h +* Generated by HerculesInterfaceMaker +* created by Susu +*-------------------------------------*/ +void elemental_defaults(void) { + elemental = &elemental_s; + + /* funcs */ + + elemental->class = elemental_class; + elemental->get_viewdata = elemental_get_viewdata; + + elemental->create = elemental_create; + elemental->data_received = elemental_data_received; + elemental->save = elemental_save; + + elemental->change_mode_ack = elemental_change_mode_ack; + elemental->change_mode = elemental_change_mode; + + elemental->heal = elemental_heal; + elemental->dead = elemental_dead; + + elemental->delete = elemental_delete; + elemental->summon_stop = elemental_summon_stop; + + elemental->get_lifetime = elemental_get_lifetime; + + elemental->unlocktarget = elemental_unlocktarget; + elemental->skillnotok = elemental_skillnotok; + elemental->set_target = elemental_set_target; + elemental->clean_single_effect = elemental_clean_single_effect; + elemental->clean_effect = elemental_clean_effect; + elemental->action = elemental_action; + elemental->skill_get_requirements = elemental_skill_get_requirements; + + elemental->read_skilldb = read_elemental_skilldb; + elemental->reload_elementaldb = reload_elementaldb; + elemental->reload_skilldb = reload_elemental_skilldb; + elemental->do_init_elemental = do_init_elemental; + elemental->do_final_elemental = do_final_elemental; +} diff --git a/src/map/elemental.h b/src/map/elemental.h index 96d2ed89f..ccc3bcb5f 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -1,106 +1,100 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder -#ifndef _ELEMENTAL_H_ -#define _ELEMENTAL_H_ -#include "status.h" // struct status_data, struct status_change -#include "unit.h" // struct unit_data -#define MIN_ELETHINKTIME 100 -#define MIN_ELEDISTANCE 2 -#define MAX_ELEDISTANCE 5 -#define EL_MODE_AGGRESSIVE (MD_CANMOVE|MD_AGGRESSIVE|MD_CANATTACK) -#define EL_MODE_ASSIST (MD_CANMOVE|MD_ASSIST) -#define EL_MODE_PASSIVE MD_CANMOVE -#define EL_SKILLMODE_PASIVE 0x1 -#define EL_SKILLMODE_ASSIST 0x2 -#define EL_SKILLMODE_AGGRESSIVE 0x4 -struct elemental_skill { - unsigned short id, lv; - short mode; -}; -struct s_elemental_db { - int class_; - char sprite[NAME_LENGTH], name[NAME_LENGTH]; - unsigned short lv; - short range2, range3; - struct status_data status; - struct view_data vd; - struct elemental_skill skill[MAX_ELESKILLTREE]; -}; -struct elemental_data { - struct block_list bl; - struct unit_data ud; - struct view_data *vd; - struct status_data base_status, battle_status; - struct status_change sc; - struct regen_data regen; - - struct s_elemental_db *db; - struct s_elemental elemental; - - struct map_session_data *master; - int summon_timer; - int skill_timer; - - unsigned last_thinktime, last_linktime, last_spdrain_time; - short min_chase; - int target_id, attacked_id; -}; - - - - - - - - -#define elemental_stop_walking(ed, type) unit_stop_walking(&(ed)->bl, type) -#define elemental_stop_attack(ed) unit_stop_attack(&(ed)->bl) - - -/*===================================== -* Interface : elemental.h -* Generated by HerculesInterfaceMaker -* created by Susu -*-------------------------------------*/ -struct elemental_interface { - /* vars */ - struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS]; // Elemental Database - /* funcs */ - bool (*class) (int class_); - struct view_data * (*get_viewdata) (int class_); - - int (*create) (struct map_session_data *sd, int class_, unsigned int lifetime); - int (*data_received) (struct s_elemental *ele, bool flag); - int (*save) (struct elemental_data *ed); - - int (*change_mode_ack) (struct elemental_data *ed, int mode); - int (*change_mode) (struct elemental_data *ed, int mode); - - void (*heal) (struct elemental_data *ed, int hp, int sp); - int (*dead) (struct elemental_data *ed); - - int (*delete) (struct elemental_data *ed, int reply); - void (*summon_stop) (struct elemental_data *ed); - - int (*get_lifetime) (struct elemental_data *ed); - - int (*unlocktarget) (struct elemental_data *ed); - int (*skillnotok) (uint16 skill_id, struct elemental_data *ed); - int (*set_target) (struct map_session_data *sd, struct block_list *bl); - int (*clean_single_effect) (struct elemental_data *ed, uint16 skill_id); - int (*clean_effect) (struct elemental_data *ed); - int (*action) (struct elemental_data *ed, struct block_list *bl, unsigned int tick); - struct skill_condition (*skill_get_requirements) (uint16 skill_id, uint16 skill_lv); - - int (*read_skilldb) (void); - void (*reload_elementaldb) (void); - void (*reload_skilldb) (void); - int (*do_init_elemental) (void); - void (*do_final_elemental) (void); -} elemental_s; - -struct elemental_interface *elemental; - -void elemental_defaults(void); - -#endif /* _ELEMENTAL_H_ */ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder +#ifndef _ELEMENTAL_H_ +#define _ELEMENTAL_H_ +#include "status.h" // struct status_data, struct status_change +#include "unit.h" // struct unit_data +#define MIN_ELETHINKTIME 100 +#define MIN_ELEDISTANCE 2 +#define MAX_ELEDISTANCE 5 +#define EL_MODE_AGGRESSIVE (MD_CANMOVE|MD_AGGRESSIVE|MD_CANATTACK) +#define EL_MODE_ASSIST (MD_CANMOVE|MD_ASSIST) +#define EL_MODE_PASSIVE MD_CANMOVE +#define EL_SKILLMODE_PASIVE 0x1 +#define EL_SKILLMODE_ASSIST 0x2 +#define EL_SKILLMODE_AGGRESSIVE 0x4 +struct elemental_skill { + unsigned short id, lv; + short mode; +}; +struct s_elemental_db { + int class_; + char sprite[NAME_LENGTH], name[NAME_LENGTH]; + unsigned short lv; + short range2, range3; + struct status_data status; + struct view_data vd; + struct elemental_skill skill[MAX_ELESKILLTREE]; +}; +struct elemental_data { + struct block_list bl; + struct unit_data ud; + struct view_data *vd; + struct status_data base_status, battle_status; + struct status_change sc; + struct regen_data regen; + + struct s_elemental_db *db; + struct s_elemental elemental; + + struct map_session_data *master; + int summon_timer; + int skill_timer; + + unsigned last_thinktime, last_linktime, last_spdrain_time; + short min_chase; + int target_id, attacked_id; +}; + +#define elemental_stop_walking(ed, type) unit->stop_walking(&(ed)->bl, type) +#define elemental_stop_attack(ed) unit->stop_attack(&(ed)->bl) + +/*===================================== +* Interface : elemental.h +* Generated by HerculesInterfaceMaker +* created by Susu +*-------------------------------------*/ +struct elemental_interface { + + /* vars */ + struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS]; // Elemental Database + + /* funcs */ + bool (*class) (int class_); + struct view_data * (*get_viewdata) (int class_); + + int (*create) (struct map_session_data *sd, int class_, unsigned int lifetime); + int (*data_received) (struct s_elemental *ele, bool flag); + int (*save) (struct elemental_data *ed); + + int (*change_mode_ack) (struct elemental_data *ed, int mode); + int (*change_mode) (struct elemental_data *ed, int mode); + + void (*heal) (struct elemental_data *ed, int hp, int sp); + int (*dead) (struct elemental_data *ed); + + int (*delete) (struct elemental_data *ed, int reply); + void (*summon_stop) (struct elemental_data *ed); + + int (*get_lifetime) (struct elemental_data *ed); + + int (*unlocktarget) (struct elemental_data *ed); + int (*skillnotok) (uint16 skill_id, struct elemental_data *ed); + int (*set_target) (struct map_session_data *sd, struct block_list *bl); + int (*clean_single_effect) (struct elemental_data *ed, uint16 skill_id); + int (*clean_effect) (struct elemental_data *ed); + int (*action) (struct elemental_data *ed, struct block_list *bl, unsigned int tick); + struct skill_condition (*skill_get_requirements) (uint16 skill_id, uint16 skill_lv); + + int (*read_skilldb) (void); + void (*reload_elementaldb) (void); + void (*reload_skilldb) (void); + int (*do_init_elemental) (void); + void (*do_final_elemental) (void); +} elemental_s; + +struct elemental_interface *elemental; + +void elemental_defaults(void); + +#endif /* _ELEMENTAL_H_ */ diff --git a/src/map/guild.c b/src/map/guild.c index 995c090ec..37335f9d0 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -1883,7 +1883,7 @@ int guild_break(struct map_session_data *sd,char *name) { } /* regardless of char server allowing it, we clear the guild master's auras */ - if( (ud = unit_bl2ud(&sd->bl)) ) { + if( (ud = unit->bl2ud(&sd->bl)) ) { int count = 0; struct skill_unit_group *groups[4]; for (i=0;iskillunit[i];i++) { diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 3a6ed074c..e0443f1f6 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -157,7 +157,7 @@ int homunculus_vaporize(struct map_session_data *sd, int flag) { memset(hd->blockskill, 0, sizeof(hd->blockskill)); clif->hominfo(sd, sd->hd, 0); homun->save(hd); - return unit_remove_map(&hd->bl, CLR_OUTSIGHT); + return unit->remove_map(&hd->bl, CLR_OUTSIGHT, ALC_MARK); } //delete a homunculus, completely "killing it". @@ -168,7 +168,7 @@ int homunculus_delete(struct homun_data *hd, int emote) { sd = hd->master; if (!sd) - return unit_free(&hd->bl,CLR_DEAD); + return unit->free(&hd->bl,CLR_DEAD); if (emote >= 0) clif->emotion(&sd->bl, emote); @@ -178,7 +178,7 @@ int homunculus_delete(struct homun_data *hd, int emote) { // Send homunculus_dead to client hd->homunculus.hp = 0; clif->hominfo(sd, hd, 0); - return unit_remove_map(&hd->bl,CLR_OUTSIGHT); + return unit->remove_map(&hd->bl,CLR_OUTSIGHT, ALC_MARK); } int homunculus_calc_skilltree(struct homun_data *hd, int flag_evolve) { @@ -403,7 +403,7 @@ bool homunculus_evolve(struct homun_data *hd) { hom->luk += 10*rnd_value(min->luk, max->luk); hom->intimacy = 500; - unit_remove_map(&hd->bl, CLR_OUTSIGHT); + unit->remove_map(&hd->bl, CLR_OUTSIGHT, ALC_MARK); iMap->addblock(&hd->bl); clif->spawn(&hd->bl); @@ -447,7 +447,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) { return false; } - unit_remove_map(&hd->bl, CLR_OUTSIGHT); + unit->remove_map(&hd->bl, CLR_OUTSIGHT, ALC_MARK); iMap->addblock(&hd->bl); clif->spawn(&hd->bl); @@ -745,14 +745,14 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { iStatus->set_viewdata(&hd->bl, hd->homunculus.class_); iStatus->change_init(&hd->bl); - unit_dataset(&hd->bl); + unit->dataset(&hd->bl); hd->ud.dir = sd->ud.dir; // Find a random valid pos around the player hd->bl.m = sd->bl.m; hd->bl.x = sd->bl.x; hd->bl.y = sd->bl.y; - unit_calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); + unit->calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); hd->bl.x = hd->ud.to_x; hd->bl.y = hd->ud.to_y; @@ -801,7 +801,7 @@ bool homunculus_call(struct map_session_data *sd) { homun->save(hd); } else //Warp him to master. - unit_warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,CLR_OUTSIGHT); + unit->warp(&hd->bl,sd->bl.m, sd->bl.x, sd->bl.y,CLR_OUTSIGHT); return true; } diff --git a/src/map/instance.c b/src/map/instance.c index 4e145fb8f..204b7c137 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -344,7 +344,7 @@ int instance_cleanup_sub(struct block_list *bl, va_list ap) { npc_unload((struct npc_data *)bl,true); break; case BL_MOB: - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); break; case BL_PET: //There is no need for this, the pet is removed together with the player. [Skotlex] diff --git a/src/map/map.c b/src/map/map.c index 90ad63adf..64e765b27 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1307,7 +1307,7 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 if (iMap->getcell(m,*x,*y,CELL_CHKREACH)) { - if(flag&2 && !unit_can_reach_pos(src, *x, *y, 1)) + if(flag&2 && !unit->can_reach_pos(src, *x, *y, 1)) continue; if(flag&4) { if (spawn >= 100) return 0; //Limit of retries reached. @@ -1595,7 +1595,7 @@ int map_quit(struct map_session_data *sd) { if( sd->ed ) { elemental->clean_effect(sd->ed); - unit_remove_map(&sd->ed->bl,CLR_TELEPORT); + unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK); } if( hChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) { @@ -1604,7 +1604,7 @@ int map_quit(struct map_session_data *sd) { clif->chsys_quit(sd); - unit_remove_map_pc(sd,CLR_TELEPORT); + unit->remove_map_pc(sd,CLR_TELEPORT); if( map[sd->bl.m].instance_id >= 0 ) { // Avoid map conflicts and warnings on next login int16 m; @@ -1630,7 +1630,7 @@ int map_quit(struct map_session_data *sd) { pc->makesavestatus(sd); pc->clean_skilltree(sd); chrif->save(sd,1); - unit_free_pc(sd); + unit->free_pc(sd); return 0; } @@ -2135,7 +2135,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap) if( md->db->mexp > 0 ) return 0; - unit_free(&md->bl,CLR_OUTSIGHT); + unit->free(&md->bl,CLR_OUTSIGHT); return 1; } @@ -2244,7 +2244,7 @@ uint8 map_calc_dir(struct block_list* src, int16 x, int16 y) if( dx == 0 && dy == 0 ) { // both are standing on the same spot //dir = 6; // aegis-style, makes knockback default to the left - dir = unit_getdir(src); // athena-style, makes knockback default to behind 'src' + dir = unit->getdir(src); // athena-style, makes knockback default to behind 'src' } else if( dx >= 0 && dy >=0 ) { // upper-right @@ -4872,7 +4872,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) { npc_unload((struct npc_data *)bl,false); break; case BL_MOB: - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); break; case BL_PET: //There is no need for this, the pet is removed together with the player. [Skotlex] @@ -4950,7 +4950,7 @@ void do_final(void) atcommand->final_msg(); skill->final(); iStatus->do_final_status(); - do_final_unit(); + unit->final(); do_final_battleground(); iDuel->do_final_duel(); elemental->do_final_elemental(); @@ -5169,6 +5169,7 @@ void map_hp_symbols(void) { HPM->share(intif,"intif"); HPM->share(mercenary,"mercenary"); HPM->share(mob,"mob"); + HPM->share(unit,"unit"); /* partial */ HPM->share(mapit,"mapit"); @@ -5215,6 +5216,7 @@ void map_load_defaults(void) { intif_defaults(); mercenary_defaults(); mob_defaults(); + unit_defaults(); } int do_init(int argc, char *argv[]) { @@ -5415,7 +5417,7 @@ int do_init(int argc, char *argv[]) elemental->do_init_elemental(); do_init_quest(); do_init_npc(); - do_init_unit(); + unit->init(); do_init_battleground(); iDuel->do_init_duel(); vending->init(); diff --git a/src/map/mercenary.c b/src/map/mercenary.c index bb30bb0d1..8bafcde97 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -247,7 +247,7 @@ int merc_delete(struct mercenary_data *md, int reply) mercenary->contract_stop(md); if( !sd ) - return unit_free(&md->bl, CLR_OUTSIGHT); + return unit->free(&md->bl, CLR_OUTSIGHT); if( md->devotion_flag ) { @@ -262,7 +262,7 @@ int merc_delete(struct mercenary_data *md, int reply) } clif->mercenary_message(sd, reply); - return unit_remove_map(&md->bl, CLR_OUTSIGHT); + return unit->remove_map(&md->bl, CLR_OUTSIGHT, ALC_MARK); } void merc_contract_stop(struct mercenary_data *md) @@ -309,13 +309,13 @@ int merc_data_received(struct s_mercenary *merc, bool flag) memcpy(&md->mercenary, merc, sizeof(struct s_mercenary)); iStatus->set_viewdata(&md->bl, md->mercenary.class_); iStatus->change_init(&md->bl); - unit_dataset(&md->bl); + unit->dataset(&md->bl); md->ud.dir = sd->ud.dir; md->bl.m = sd->bl.m; md->bl.x = sd->bl.x; md->bl.y = sd->bl.y; - unit_calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir); + unit->calc_pos(&md->bl, sd->bl.x, sd->bl.y, sd->ud.dir); md->bl.x = md->ud.to_x; md->bl.y = md->ud.to_y; diff --git a/src/map/mob.c b/src/map/mob.c index 49120fdaf..c566262df 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -283,7 +283,7 @@ struct mob_data* mob_spawn_dataset(struct spawn_data *data) { md->skill_idx = -1; iStatus->set_viewdata(&md->bl, md->class_); iStatus->change_init(&md->bl); - unit_dataset(&md->bl); + unit->dataset(&md->bl); iMap->addiddb(&md->bl); return md; @@ -597,7 +597,7 @@ int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) } else { if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); - unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. + unit->free(&md->bl,CLR_OUTSIGHT); //Remove guardian. } return 0; } @@ -783,7 +783,7 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state easy = 1; break; } - return unit_can_reach_bl(&md->bl, bl, range, easy, NULL, NULL); + return unit->can_reach_bl(&md->bl, bl, range, easy, NULL, NULL); } /*========================================== @@ -846,7 +846,7 @@ int mob_setdelayspawn(struct mob_data *md) struct mob_db *db; if (!md->spawn) //Doesn't has respawn data! - return unit_free(&md->bl,CLR_DEAD); + return unit->free(&md->bl,CLR_DEAD); spawntime = md->spawn->delay1; //Base respawn time if (md->spawn->delay2) //random variance @@ -900,10 +900,8 @@ int mob_spawn (struct mob_data *md) md->last_thinktime = tick; if (md->bl.prev != NULL) - unit_remove_map(&md->bl,CLR_RESPAWN); - else - if (md->spawn && md->class_ != md->spawn->class_) - { + unit->remove_map(&md->bl,CLR_RESPAWN,ALC_MARK); + else if (md->spawn && md->class_ != md->spawn->class_) { md->class_ = md->spawn->class_; iStatus->set_viewdata(&md->bl, md->class_); md->db = mob->db(md->class_); @@ -1226,7 +1224,7 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) md->master_dist > MAX_MINCHASE ){ md->master_dist = 0; - unit_warp(&md->bl,bl->m,bl->x,bl->y,CLR_TELEPORT); + unit->warp(&md->bl,bl->m,bl->x,bl->y,CLR_TELEPORT); return 1; } @@ -1235,12 +1233,12 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) // Approach master if within view range, chase back to Master's area also if standing on top of the master. if((md->master_dist>MOB_SLAVEDISTANCE || md->master_dist == 0) && - unit_can_move(&md->bl)) + unit->can_move(&md->bl)) { short x = bl->x, y = bl->y; mob_stop_attack(md); if(iMap->search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1) - && unit_walktoxy(&md->bl, x, y, 0)) + && unit->walktoxy(&md->bl, x, y, 0)) return 1; } } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) { @@ -1252,7 +1250,7 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) //Avoid attempting to lock the master's target too often to avoid unnecessary overload. [Skotlex] if (DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); md->last_linktime = tick; if (ud) { @@ -1316,7 +1314,7 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick) if (md->target_id) { md->target_id=0; md->ud.target_to = 0; - unit_set_target(&md->ud, 0); + unit->set_target(&md->ud, 0); } return 0; } @@ -1332,7 +1330,7 @@ int mob_randomwalk(struct mob_data *md,unsigned int tick) nullpo_ret(md); if(DIFF_TICK(md->next_walktime,tick)>0 || - !unit_can_move(&md->bl) || + !unit->can_move(&md->bl) || !(status_get_mode(&md->bl)&MD_CANMOVE)) return 0; @@ -1345,7 +1343,7 @@ int mob_randomwalk(struct mob_data *md,unsigned int tick) x+=md->bl.x; y+=md->bl.y; - if((iMap->getcell(md->bl.m,x,y,CELL_CHKPASS)) && unit_walktoxy(&md->bl,x,y,1)){ + if((iMap->getcell(md->bl.m,x,y,CELL_CHKPASS)) && unit->walktoxy(&md->bl,x,y,1)){ break; } } @@ -1389,7 +1387,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target) iMap->foreachinrange (mob->warpchase_sub, &md->bl, md->db->range2, BL_NPC, target, &warp, &distance); - if (warp && unit_walktobl(&md->bl, &warp->bl, 1, 1)) + if (warp && unit->walktobl(&md->bl, &warp->bl, 1, 1)) return 1; return 0; } @@ -1430,7 +1428,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) view_range = md->db->range2; mode = status_get_mode(&md->bl); - can_move = (mode&MD_CANMOVE)&&unit_can_move(&md->bl); + can_move = (mode&MD_CANMOVE)&&unit->can_move(&md->bl); if (md->target_id) { //Check validity of current target. [Skotlex] @@ -1464,7 +1462,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) ) && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack - && can_move && unit_escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape + && can_move && unit->escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape { //Escaped md->attacked_id = 0; return true; @@ -1489,7 +1487,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) { // Rude attacked if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) && can_move - && !tbl && unit_escape(&md->bl, abl, rnd()%10 +1)) + && !tbl && unit->escape(&md->bl, abl, rnd()%10 +1)) { //Escaped. //TODO: Maybe it shouldn't attempt to run if it has another, valid target? md->attacked_id = 0; @@ -1555,7 +1553,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) return true;/* we are already moving */ iMap->foreachinrange (mob->ai_sub_hard_bg_ally, &md->bl, view_range, BL_PC, md, &tbl, mode); if( tbl ) { - if( distance_blxy(&md->bl, tbl->x, tbl->y) <= 3 || unit_walktobl(&md->bl, tbl, 1, 1) ) + if( distance_blxy(&md->bl, tbl->x, tbl->y) <= 3 || unit->walktobl(&md->bl, tbl, 1, 1) ) return true;/* we're moving or close enough don't unlock the target. */ } } @@ -1586,7 +1584,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) if (!can_move) //Stuck. Wait before walking. return true; md->state.skillstate = MSS_LOOT; - if (!unit_walktobl(&md->bl, tbl, 1, 1)) + if (!unit->walktobl(&md->bl, tbl, 1, 1)) mob->unlocktarget(md, tick); //Can't loot... return true; } @@ -1610,7 +1608,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) { //Give them walk act/delay to properly mimic players. [Skotlex] clif->takeitem(&md->bl,tbl); md->ud.canact_tick = tick + md->status.amotion; - unit_set_walkdelay(&md->bl, tick, md->status.amotion, 1); + unit->set_walkdelay(&md->bl, tick, md->status.amotion, 1); } //Clear item. iMap->clearflooritem (tbl); @@ -1627,7 +1625,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) if(tbl->type == BL_PC) mob->log_damage(md, tbl, 0); //Log interaction (counts as 'attacker' for the exp bonus) - unit_attack(&md->bl,tbl->id,1); + unit->attack(&md->bl,tbl->id,1); return true; } @@ -1657,7 +1655,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) //Follow up if possible. if(!mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) || - !unit_walktobl(&md->bl, tbl, md->status.rhw.range, 2)) + !unit->walktobl(&md->bl, tbl, md->status.rhw.range, 2)) mob->unlocktarget(md,tick); return true; @@ -1738,7 +1736,7 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args) return 0; } - if( DIFF_TICK(md->next_walktime,tick) < 0 && (status_get_mode(&md->bl)&MD_CANMOVE) && unit_can_move(&md->bl) ) + if( DIFF_TICK(md->next_walktime,tick) < 0 && (status_get_mode(&md->bl)&MD_CANMOVE) && unit->can_move(&md->bl) ) { if( map[md->bl.m].users > 0 ) { @@ -1876,7 +1874,7 @@ int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data) } //for Alchemist CANNIBALIZE [Lupus] md->deletetimer = INVALID_TIMER; - unit_free(bl, CLR_TELEPORT); + unit->free(bl, CLR_TELEPORT); } return 0; } @@ -2673,7 +2671,7 @@ int mob_guardian_guildchange(struct mob_data *md) } else { if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0); - unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. + unit->free(&md->bl,CLR_OUTSIGHT); //Remove guardian. } return 0; } @@ -2684,7 +2682,7 @@ int mob_guardian_guildchange(struct mob_data *md) ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id); if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS) guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0); - unit_free(&md->bl,CLR_OUTSIGHT); + unit->free(&md->bl,CLR_OUTSIGHT); return 0; } @@ -2757,7 +2755,7 @@ int mob_class_change (struct mob_data *md, int class_) mob_stop_attack(md); mob_stop_walking(md, 0); - unit_skillcastcancel(&md->bl, 0); + unit->skillcastcancel(&md->bl, 0); iStatus->set_viewdata(&md->bl, class_); clif->class_change(&md->bl, md->vd->class_, 1); status_calc_mob(md, 1); @@ -2810,7 +2808,7 @@ int mob_warpslave_sub(struct block_list *bl,va_list ap) return 0; iMap->search_freecell(master, 0, &x, &y, range, range, 0); - unit_warp(&md->bl, master->m, x, y,CLR_RESPAWN); + unit->warp(&md->bl, master->m, x, y,CLR_RESPAWN); return 1; } @@ -3148,11 +3146,11 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) case MSC_SLAVELT: // slave < num flag = (mob->countslave(&md->bl) < c2 ); break; case MSC_ATTACKPCGT: // attack pc > num - flag = (unit_counttargeted(&md->bl) > c2); break; + flag = (unit->counttargeted(&md->bl) > c2); break; case MSC_SLAVELE: // slave <= num flag = (mob->countslave(&md->bl) <= c2 ); break; case MSC_ATTACKPCGE: // attack pc >= num - flag = (unit_counttargeted(&md->bl) >= c2); break; + flag = (unit->counttargeted(&md->bl) >= c2); break; case MSC_AFTERSKILL: flag = (md->ud.skill_id == c2); break; case MSC_RUDEATTACKED: @@ -3162,7 +3160,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) case MSC_MASTERHPLTMAXRATE: flag = ((fbl = mob->getmasterhpltmaxrate(md, ms[i].cond2)) != NULL); break; case MSC_MASTERATTACKED: - flag = (md->master_id > 0 && (fbl=iMap->id2bl(md->master_id)) && unit_counttargeted(fbl) > 0); break; + flag = (md->master_id > 0 && (fbl=iMap->id2bl(md->master_id)) && unit->counttargeted(fbl) > 0); break; case MSC_ALCHEMIST: flag = (md->state.alchemist); break; @@ -3214,7 +3212,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) md->skill_idx = i; iMap->freeblock_lock(); if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) || - !unit_skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) + !unit->skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) { iMap->freeblock_unlock(); continue; @@ -3252,7 +3250,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) md->skill_idx = i; iMap->freeblock_lock(); if( !battle->check_range(&md->bl,bl,skill->get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) || - !unit_skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) + !unit->skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) { iMap->freeblock_unlock(); continue; diff --git a/src/map/mob.h b/src/map/mob.h index 7e9ecbd28..4ac8f7bcb 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -243,8 +243,8 @@ struct item_drop_list { }; -#define mob_stop_walking(md, type) unit_stop_walking(&(md)->bl, type) -#define mob_stop_attack(md) unit_stop_attack(&(md)->bl) +#define mob_stop_walking(md, type) unit->stop_walking(&(md)->bl, type) +#define mob_stop_attack(md) unit->stop_attack(&(md)->bl) #define mob_is_battleground(md) ( map[(md)->bl.m].flag.battleground && ((md)->class_ == MOBID_BARRICADE2 || ((md)->class_ >= MOBID_FOOD_STOR && (md)->class_ <= MOBID_PINK_CRYST)) ) #define mob_is_gvg(md) (map[(md)->bl.m].flag.gvg_castle && ( (md)->class_ == MOBID_EMPERIUM || (md)->class_ == MOBID_BARRICADE1 || (md)->class_ == MOBID_GUARIDAN_STONE1 || (md)->class_ == MOBID_GUARIDAN_STONE2) ) #define mob_is_treasure(md) (((md)->class_ >= MOBID_TREAS01 && (md)->class_ <= MOBID_TREAS40) || ((md)->class_ >= MOBID_TREAS41 && (md)->class_ <= MOBID_TREAS49)) diff --git a/src/map/npc.c b/src/map/npc.c index c7c537e1f..c4ef1bcf9 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -971,7 +971,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) if( npc_ontouch_event(sd,map[m].npc[i]) > 0 && npc_ontouch2_event(sd,map[m].npc[i]) > 0 ) { // failed to run OnTouch event, so just click the npc - struct unit_data *ud = unit_bl2ud(&sd->bl); + struct unit_data *ud = unit->bl2ud(&sd->bl); if( ud && ud->walkpath.path_pos < ud->walkpath.path_len ) { // Since walktimer always == INVALID_TIMER at this time, we stop walking manually. [Inkfish] clif->fixpos(&sd->bl); @@ -1021,7 +1021,7 @@ int npc_touch_areanpc2(struct mob_data *md) xs = iMap->mapindex2mapid(map[m].npc[i]->u.warp.mapindex); if( m < 0 ) break; // Cannot Warp between map servers - if( unit_warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 ) + if( unit->warp(&md->bl, xs, map[m].npc[i]->u.warp.x, map[m].npc[i]->u.warp.y, CLR_OUTSIGHT) == 0 ) return 1; // Warped break; case SCRIPT: @@ -3796,7 +3796,7 @@ int npc_reload(void) { npc_unload((struct npc_data *)bl, false); break; case BL_MOB: - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); break; } } diff --git a/src/map/pc.c b/src/map/pc.c index ce275a21c..d502d9a3a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1082,7 +1082,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim //Set here because we need the inventory data for weapon sprite parsing. iStatus->set_viewdata(&sd->bl, sd->status.class_); - unit_dataset(&sd->bl); + unit->dataset(&sd->bl); sd->guild_x = -1; sd->guild_y = -1; @@ -4933,7 +4933,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y npc_event_dequeue(sd); npc_script_event(sd, NPCE_LOGOUT); //remove from map, THEN change x/y coordinates - unit_remove_map_pc(sd,clrtype); + unit->remove_map_pc(sd,clrtype); sd->mapindex = mapindex; sd->bl.x=x; sd->bl.y=y; @@ -4942,7 +4942,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y chrif->changemapserver(sd, ip, (short)port); //Free session data from this map server [Kevin] - unit_free_pc(sd); + unit->free_pc(sd); return 0; } @@ -4965,7 +4965,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } if(sd->bl.prev != NULL){ - unit_remove_map_pc(sd,clrtype); + unit->remove_map_pc(sd,clrtype); clif->changemap(sd,m,x,y); // [MouseJstr] } else if(sd->state.active) //Tag player for rewarping after map-loading is done. [Skotlex] @@ -5730,9 +5730,9 @@ int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data) if (sd->bl.prev != NULL && tbl->prev != NULL && sd->ud.skilltimer == INVALID_TIMER && sd->ud.attacktimer == INVALID_TIMER && sd->ud.walktimer == INVALID_TIMER) { - if((sd->bl.m == tbl->m) && unit_can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) { + if((sd->bl.m == tbl->m) && unit->can_reach_bl(&sd->bl,tbl, AREA_SIZE, 0, NULL, NULL)) { if (!check_distance_bl(&sd->bl, tbl, 5)) - unit_walktobl(&sd->bl, tbl, 5, 0); + unit->walktobl(&sd->bl, tbl, 5, 0); } else pc->setpos(sd, map_id2index(tbl->m), tbl->x, tbl->y, CLR_TELEPORT); } @@ -5753,7 +5753,7 @@ int pc_stop_following (struct map_session_data *sd) sd->followtarget = -1; sd->ud.target_to = 0; - unit_stop_walking(&sd->bl, 1); + unit->stop_walking(&sd->bl, 1); return 0; } diff --git a/src/map/pc.h b/src/map/pc.h index 231f369d8..c8e7e17d5 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -645,8 +645,8 @@ enum equip_pos { // Rune Knight Dragon #define pc_isridingdragon(sd) ( (sd)->sc.option&OPTION_DRAGON ) -#define pc_stop_walking(sd, type) unit_stop_walking(&(sd)->bl, type) -#define pc_stop_attack(sd) unit_stop_attack(&(sd)->bl) +#define pc_stop_walking(sd, type) unit->stop_walking(&(sd)->bl, type) +#define pc_stop_attack(sd) unit->stop_attack(&(sd)->bl) //Weapon check considering dual wielding. #define pc_check_weapontype(sd, type) ((type)&((sd)->status.weapon < MAX_WEAPON_TYPE? \ diff --git a/src/map/pet.c b/src/map/pet.c index 796edd0b8..d7f7c29c8 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -121,9 +121,9 @@ int pet_attackskill(struct pet_data *pd, int target_id) inf = skill->get_inf(pd->a_skill->id); if (inf & INF_GROUND_SKILL) - unit_skilluse_pos(&pd->bl, bl->x, bl->y, pd->a_skill->id, pd->a_skill->lv); + unit->skilluse_pos(&pd->bl, bl->x, bl->y, pd->a_skill->id, pd->a_skill->lv); else //Offensive self skill? Could be stuff like GX. - unit_skilluse_id(&pd->bl,(inf&INF_SELF_SKILL?pd->bl.id:bl->id), pd->a_skill->id, pd->a_skill->lv); + unit->skilluse_id(&pd->bl,(inf&INF_SELF_SKILL?pd->bl.id:bl->id), pd->a_skill->id, pd->a_skill->lv); return 1; //Skill invoked. } return 0; @@ -309,7 +309,7 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd) iMap->addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } pd->pet.incuvate = 1; - unit_free(&pd->bl,CLR_OUTSIGHT); + unit->free(&pd->bl,CLR_OUTSIGHT); status_calc_pc(sd,0); sd->status.pet_id = 0; @@ -356,13 +356,13 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet) pd->db = mob->db(pet->class_); memcpy(&pd->pet, pet, sizeof(struct s_pet)); iStatus->set_viewdata(&pd->bl, pet->class_); - unit_dataset(&pd->bl); + unit->dataset(&pd->bl); pd->ud.dir = sd->ud.dir; pd->bl.m = sd->bl.m; pd->bl.x = sd->bl.x; pd->bl.y = sd->bl.y; - unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); + unit->calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); pd->bl.x = pd->ud.to_x; pd->bl.y = pd->ud.to_y; @@ -526,7 +526,7 @@ int pet_catch_process2(struct map_session_data* sd, int target_id) if(rnd()%10000 < pet_catch_rate) { - unit_remove_map(&md->bl,CLR_OUTSIGHT); + unit->remove_map(&md->bl,CLR_OUTSIGHT,ALC_MARK); status_kill(&md->bl); clif->pet_roulette(sd,1); intif->create_pet(sd->status.account_id,sd->status.char_id,pet_db[i].class_,mob->db(pet_db[i].class_)->lv, @@ -793,7 +793,7 @@ static int pet_randomwalk(struct pet_data *pd,unsigned int tick) Assert((pd->msd == 0) || (pd->msd->pd == pd)); - if(DIFF_TICK(pd->next_walktime,tick) < 0 && unit_can_move(&pd->bl)) { + if(DIFF_TICK(pd->next_walktime,tick) < 0 && unit->can_move(&pd->bl)) { const int retrycount=20; int i,x,y,c,d=12-pd->move_fail_count; if(d<5) d=5; @@ -801,7 +801,7 @@ static int pet_randomwalk(struct pet_data *pd,unsigned int tick) int r=rnd(); x=pd->bl.x+r%(d*2+1)-d; y=pd->bl.y+r/(d*2+1)%(d*2+1)-d; - if(iMap->getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit_walktoxy(&pd->bl,x,y,0)){ + if(iMap->getcell(pd->bl.m,x,y,CELL_CHKPASS) && unit->walktoxy(&pd->bl,x,y,0)){ pd->move_fail_count=0; break; } @@ -862,7 +862,7 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns pd->status.speed = (sd->battle_status.speed>>1); if(pd->status.speed <= 0) pd->status.speed = 1; - if (!unit_walktobl(&pd->bl, &sd->bl, 3, 0)) + if (!unit->walktobl(&pd->bl, &sd->bl, 3, 0)) pet_randomwalk(pd,tick); return 0; } @@ -899,8 +899,8 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns if(pd->ud.walktimer != INVALID_TIMER && check_distance_blxy(&sd->bl, pd->ud.to_x,pd->ud.to_y, 3)) return 0; //Already walking to him - unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); - if(!unit_walktoxy(&pd->bl,pd->ud.to_x,pd->ud.to_y,0)) + unit->calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); + if(!unit->walktoxy(&pd->bl,pd->ud.to_x,pd->ud.to_y,0)) pet_randomwalk(pd,tick); return 0; @@ -914,16 +914,16 @@ static int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, uns { //enemy targetted if(!battle->check_range(&pd->bl,target,pd->status.rhw.range)) { //Chase - if(!unit_walktobl(&pd->bl, target, pd->status.rhw.range, 2)) + if(!unit->walktobl(&pd->bl, target, pd->status.rhw.range, 2)) pet_unlocktarget(pd); //Unreachable target. return 0; } //Continuous attack. - unit_attack(&pd->bl, pd->target_id, 1); + unit->attack(&pd->bl, pd->target_id, 1); } else { //Item Targeted, attempt loot if (!check_distance_bl(&pd->bl, target, 1)) { //Out of range - if(!unit_walktobl(&pd->bl, target, 1, 1)) //Unreachable target. + if(!unit->walktobl(&pd->bl, target, 1, 1)) //Unreachable target. pet_unlocktarget(pd); return 0; } else{ @@ -971,7 +971,7 @@ static int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) if(sd_charid && sd_charid != pd->msd->status.char_id) return 0; - if(unit_can_reach_bl(&pd->bl,bl, pd->db->range2, 1, NULL, NULL) && + if(unit->can_reach_bl(&pd->bl,bl, pd->db->range2, 1, NULL, NULL) && ((*target) == NULL || //New target closer than previous one. !check_distance_bl(&pd->bl, *target, distance_bl(&pd->bl, bl)))) { @@ -1197,9 +1197,9 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data) pet_stop_walking(pd,1); pd->s_skill->timer=iTimer->add_timer(tick+pd->s_skill->delay*1000,pet_skill_support_timer,sd->bl.id,0); if (skill->get_inf(pd->s_skill->id) & INF_GROUND_SKILL) - unit_skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv); + unit->skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv); else - unit_skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv); + unit->skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv); return 0; } diff --git a/src/map/pet.h b/src/map/pet.h index b46f55229..4060b5382 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -126,8 +126,8 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data); // int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data); // [Valaris] int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data); // [Valaris] -#define pet_stop_walking(pd, type) unit_stop_walking(&(pd)->bl, type) -#define pet_stop_attack(pd) unit_stop_attack(&(pd)->bl) +#define pet_stop_walking(pd, type) unit->stop_walking(&(pd)->bl, type) +#define pet_stop_attack(pd) unit->stop_attack(&(pd)->bl) int read_petdb(void); int do_init_pet(void); diff --git a/src/map/script.c b/src/map/script.c index 337f99cf0..70c9bd9f1 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12635,7 +12635,7 @@ BUILDIN(npcspeed) { nd = (struct npc_data *)iMap->id2bl(st->oid); if( nd ) { - unit_bl2ud2(&nd->bl); // ensure nd->ud is safe to edit + unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit nd->speed = speed; nd->ud->state.speed_changed = 1; } @@ -12651,13 +12651,13 @@ BUILDIN(npcwalkto) { y=script_getnum(st,3); if( nd ) { - unit_bl2ud2(&nd->bl); // ensure nd->ud is safe to edit + unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit if (!nd->status.hp) { status_calc_npc(nd, true); } else { status_calc_npc(nd, false); } - unit_walktoxy(&nd->bl,x,y,0); + unit->walktoxy(&nd->bl,x,y,0); } return true; @@ -12667,8 +12667,8 @@ BUILDIN(npcstop) { struct npc_data *nd = (struct npc_data *)iMap->id2bl(st->oid); if( nd ) { - unit_bl2ud2(&nd->bl); // ensure nd->ud is safe to edit - unit_stop_walking(&nd->bl,1|4); + unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit + unit->stop_walking(&nd->bl,1|4); } return true; @@ -14918,15 +14918,15 @@ BUILDIN(unitwalk) { } if( bl->type == BL_NPC ) { - unit_bl2ud2(bl); // ensure the ((TBL_NPC*)bl)->ud is safe to edit + unit->bl2ud2(bl); // ensure the ((TBL_NPC*)bl)->ud is safe to edit } if( script_hasdata(st,4) ) { int x = script_getnum(st,3); int y = script_getnum(st,4); - script_pushint(st, unit_walktoxy(bl,x,y,0));// We'll use harder calculations. + script_pushint(st, unit->walktoxy(bl,x,y,0));// We'll use harder calculations. } else { int map_id = script_getnum(st,3); - script_pushint(st, unit_walktobl(bl,iMap->id2bl(map_id),65025,1)); + script_pushint(st, unit->walktobl(bl,iMap->id2bl(map_id),65025,1)); } return true; @@ -14972,8 +14972,8 @@ BUILDIN(unitwarp) { map = iMap->mapname2mapid(mapname); if( map >= 0 && bl != NULL ) { - unit_bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit - script_pushint(st, unit_warp(bl,map,x,y,CLR_OUTSIGHT)); + unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit + script_pushint(st, unit->warp(bl,map,x,y,CLR_OUTSIGHT)); } else { script_pushint(st, 0); } @@ -15039,7 +15039,7 @@ BUILDIN(unitattack) script_pushint(st, 0); return false; } - script_pushint(st, unit_walktobl(unit_bl, target_bl, 65025, 2)); + script_pushint(st, unit->walktobl(unit_bl, target_bl, 65025, 2)); return true; } @@ -15055,9 +15055,9 @@ BUILDIN(unitstop) { bl = iMap->id2bl(unit_id); if( bl != NULL ) { - unit_bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit - unit_stop_attack(bl); - unit_stop_walking(bl,4); + unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit + unit->stop_attack(bl); + unit->stop_walking(bl,4); if( bl->type == BL_MOB ) ((TBL_MOB*)bl)->target_id = 0; } @@ -15139,7 +15139,7 @@ BUILDIN(unitskilluseid) status_calc_npc(((TBL_NPC*)bl), false); } } - unit_skilluse_id(bl, target_id, skill_id, skill_lv); + unit->skilluse_id(bl, target_id, skill_id, skill_lv); } return true; @@ -15174,7 +15174,7 @@ BUILDIN(unitskillusepos) status_calc_npc(((TBL_NPC*)bl), false); } } - unit_skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv); + unit->skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv); } return true; @@ -16373,12 +16373,12 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap) return 0; if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill. - unit_skillcastcancel(bl,0); + unit->skillcastcancel(bl,0); if( skill->get_casttype(skill_id) == CAST_GROUND ) - unit_skilluse_pos2(&md->bl, tbl->x, tbl->y, skill_id, skill_lv, casttime, cancel); + unit->skilluse_pos2(&md->bl, tbl->x, tbl->y, skill_id, skill_lv, casttime, cancel); else - unit_skilluse_id2(&md->bl, tbl->id, skill_id, skill_lv, casttime, cancel); + unit->skilluse_id2(&md->bl, tbl->id, skill_id, skill_lv, casttime, cancel); clif->emotion(&md->bl, emotion); @@ -16475,7 +16475,7 @@ BUILDIN(pushpc) dx = dirx[dir]; dy = diry[dir]; - unit_blown(&sd->bl, dx, dy, cells, 0); + unit->blown(&sd->bl, dx, dy, cells, 0); return true; } @@ -17140,9 +17140,9 @@ BUILDIN(npcskill) } if (skill->get_inf(skill_id)&INF_GROUND_SKILL) { - unit_skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level); + unit->skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level); } else { - unit_skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level); + unit->skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level); } return true; diff --git a/src/map/skill.c b/src/map/skill.c index 025ed4486..08da07137 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -863,7 +863,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint break; case WZ_FIREPILLAR: - unit_set_walkdelay(bl, tick, skill->get_time2(skill_id, skill_lv), 1); + unit->set_walkdelay(bl, tick, skill->get_time2(skill_id, skill_lv), 1); break; case MG_FROSTDIVER: @@ -1447,7 +1447,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint } if( sd && sd->ed && sc && !iStatus->isdead(bl) && !skill_id ){ - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); if( sc->data[SC_WILD_STORM_OPTION] ) temp = sc->data[SC_WILD_STORM_OPTION]->val2; @@ -1559,7 +1559,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint } sd->state.autocast = 0; //Set canact delay. [Skotlex] - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); if (ud) { rate = skill->delay_fix(src, temp, skill_lv); if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){ @@ -1900,7 +1900,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } dstsd->state.autocast = 0; //Set canact delay. [Skotlex] - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (ud) { rate = skill->delay_fix(bl, skill_id, skill_lv); if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){ @@ -2103,7 +2103,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in dy = -diry[dir]; } - return unit_blown(target, dx, dy, count, flag); // send over the proper flag + return unit->blown(target, dx, dy, count, flag); // send over the proper flag } @@ -2338,7 +2338,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds sce->timer = iTimer->add_timer(tick+sce->val4, iStatus->change_timer, src->id, SC_COMBOATTACK); break; } - unit_cancel_combo(src); // Cancel combo wait + unit->cancel_combo(src); // Cancel combo wait break; default: if( src == dsrc ) // Ground skills are exceptions. [Inkfish] @@ -2617,7 +2617,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if (dmg.dmg_lv >= ATK_MISS && (type = skill->get_walkdelay(skill_id, skill_lv)) > 0) { //Skills with can't walk delay also stop normal attacking for that //duration when the attack connects. [Skotlex] - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0) ud->attackabletime = tick + type; } @@ -2650,7 +2650,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case SR_KNUCKLEARROW: case GN_WALLOFTHORN: case EL_FIRE_MANTLE: - dir = unit_getdir(bl);// backwards + dir = unit->getdir(bl);// backwards break; // This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics. case WZ_STORMGUST: @@ -2688,7 +2688,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } break; case GN_WALLOFTHORN: - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); skill->blown(dsrc,bl,dmg.blewcount,dir, 0x2 ); clif->fixpos(bl); break; @@ -3037,7 +3037,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, if( !type ) switch( state ) { case ST_MOVE_ENABLE: - if( !unit_can_move(bl) ) { + if( !unit->can_move(bl) ) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); return 0; } @@ -3086,7 +3086,7 @@ int skill_area_sub_count (struct block_list *src, struct block_list *target, uin *------------------------------------------*/ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { struct block_list *src = iMap->id2bl(id),*target; - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); struct skill_timerskill *skl; int range; @@ -3116,11 +3116,11 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { switch(skl->skill_id) { case RG_INTIMIDATE: - if (unit_warp(src,-1,-1,-1,CLR_TELEPORT) == 0) { + if (unit->warp(src,-1,-1,-1,CLR_TELEPORT) == 0) { short x,y; iMap->search_freecell(src, 0, &x, &y, 1, 1, 0); if (target != src && !iStatus->isdead(target)) - unit_warp(target, -1, x, y, CLR_TELEPORT); + unit->warp(target, -1, x, y, CLR_TELEPORT); } break; case BA_FROSTJOKER: @@ -3193,11 +3193,11 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { break; case SC_FATALMENACE: if( src == target ) // Casters Part - unit_warp(src, -1, skl->x, skl->y, 3); + unit->warp(src, -1, skl->x, skl->y, 3); else { // Target's Part short x = skl->x, y = skl->y; iMap->search_freecell(NULL, target->m, &x, &y, 2, 2, 1); - unit_warp(target,-1,x,y,3); + unit->warp(target,-1,x,y,3); } break; case LG_MOONSLASHER: @@ -3241,7 +3241,7 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { case SC_ESCAPE: if( skl->type < 4+skl->skill_lv ){ clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,5); - skill->blown(src,src,1,unit_getdir(src),0); + skill->blown(src,src,1,unit->getdir(src),0); skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0); } break; @@ -3300,7 +3300,7 @@ int skill_addtimerskill (struct block_list *src, unsigned int tick, int target, nullpo_retr(1, src); if (src->prev == NULL) return 0; - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); nullpo_retr(1, ud); ARR_FIND( 0, MAX_SKILLTIMERSKILL, i, ud->skilltimerskill[i] == 0 ); @@ -3328,7 +3328,7 @@ int skill_cleartimerskill (struct block_list *src) int i; struct unit_data *ud; nullpo_ret(src); - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); nullpo_ret(ud); for(i=0;icalc_dir(bl, src->x, src->y); // teleport to target (if not on WoE grounds) - if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 0, 1) ) + if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit->movepos(src, bl->x, bl->y, 0, 1) ) clif->slide(src, bl->x, bl->y); // cause damage and knockback if the path to target was a straight one @@ -3588,7 +3588,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill->blown(src, bl, dist, dir, 0); //HACK: since knockback officially defaults to the left, the client also turns to the left... therefore, // make the caster look in the direction of the target - unit_setdir(src, (dir+4)%8); + unit->setdir(src, (dir+4)%8); } } @@ -3626,12 +3626,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case RG_BACKSTAP: { - uint8 dir = iMap->calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl); + uint8 dir = iMap->calc_dir(src, bl->x, bl->y), t_dir = unit->getdir(bl); if ((!check_distance_bl(src, bl, 0) && !iMap->check_dir(dir, t_dir)) || bl->type == BL_SKILL) { status_change_end(src, SC_HIDING, INVALID_TIMER); skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest] - unit_setdir(bl,dir); + unit->setdir(bl,dir); } else if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); @@ -3691,7 +3691,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint else if( dir == 7 || dir < 2 ) y = i; else y = 0; if( (mbl == src || (!map_flag_gvg2(src->m) && !map[src->m].flag.battleground) ) && // only NJ_ISSEN don't have slide effect in GVG - unit_movepos(src, mbl->x+x, mbl->y+y, 1, 1) ) { + unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1) ) { clif->slide(src, src->x, src->y); clif->fixpos(src); clif->spiritball(src); @@ -3830,7 +3830,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint c = skill->get_blewcount(skill_id,skill_lv); // keep moving target in the direction that src is looking, square by square for(i=0;iblown(src,bl,1,(unit_getdir(src)+4)%8,0x1)) + if (!skill->blown(src,bl,1,(unit->getdir(src)+4)%8,0x1)) break; //Can't knockback skill_area_temp[0] = iMap->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count); if( skill_area_temp[0] > 1 ) break; // collision @@ -4073,17 +4073,17 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint { //You don't move on GVG grounds. short x, y; iMap->search_freecell(bl, 0, &x, &y, 1, 1, 0); - if (unit_movepos(src, x, y, 0, 0)) + if (unit->movepos(src, x, y, 0, 0)) clif->slide(src,src->x,src->y); } status_change_end(src, SC_HIDING, INVALID_TIMER); skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; case RK_PHANTOMTHRUST: - unit_setdir(src,iMap->calc_dir(src, bl->x, bl->y)); + unit->setdir(src,iMap->calc_dir(src, bl->x, bl->y)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - skill->blown(src,bl,distance_bl(src,bl)-1,unit_getdir(src),0); + skill->blown(src,bl,distance_bl(src,bl)-1,unit->getdir(src),0); if( battle->check_target(src,bl,BCT_ENEMY) > 0 ) skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -4100,7 +4100,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint else if( dir == 7 || dir < 2 ) y = -2; else y = 0; - if( unit_movepos(src, bl->x+x, bl->y+y, 1, 1) ) + if( unit->movepos(src, bl->x+x, bl->y+y, 1, 1) ) { clif->slide(src,bl->x+x,bl->y+y); clif->fixpos(src); // the official server send these two packts. @@ -4270,7 +4270,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint short y[8]={1,1,0,-1,-1,-1,0,1}; uint8 dir = iMap->calc_dir(bl, src->x, src->y); - if( unit_movepos(src, bl->x+x[dir], bl->y+y[dir], 1, 1) ) + if( unit->movepos(src, bl->x+x[dir], bl->y+y[dir], 1, 1) ) { clif->slide(src, bl->x+x[dir], bl->y+y[dir]); clif->fixpos(src); @@ -4350,7 +4350,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint } break; case LG_PINPOINTATTACK: - if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) ) + if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit->movepos(src, bl->x, bl->y, 1, 1) ) clif->slide(src,bl->x,bl->y); skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -4375,7 +4375,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case SR_KNUCKLEARROW: - if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) ) { + if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground && unit->movepos(src, bl->x, bl->y, 1, 1) ) { clif->slide(src,bl->x,bl->y); clif->fixpos(src); // Aegis send this packet too. } @@ -4523,7 +4523,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); break; case MH_TINDER_BREAKER: - if (unit_movepos(src, bl->x, bl->y, 1, 1)) { + if (unit->movepos(src, bl->x, bl->y, 1, 1)) { #if PACKETVER >= 20111005 clif->snap(src, bl->x, bl->y); #else @@ -4600,7 +4600,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) return 0;// not found } - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); if( ud == NULL ) { ShowDebug("skill_castend_id: ud == NULL (tid=%d, id=%d)\n", tid, id); @@ -4615,7 +4615,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) return 0; } - if(ud->skill_id != SA_CASTCANCEL && ud->skill_id != SO_SPELLFIST) {// otherwise handled in unit_skillcastcancel() + if(ud->skill_id != SA_CASTCANCEL && ud->skill_id != SO_SPELLFIST) {// otherwise handled in unit->skillcastcancel() if( ud->skilltimer != tid ) { ShowError("skill_castend_id: Timer mismatch %d!=%d!\n", ud->skilltimer, tid); ud->skilltimer = INVALID_TIMER; @@ -4668,7 +4668,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } if(ud->skill_id == RG_BACKSTAP) { - uint8 dir = iMap->calc_dir(src,target->x,target->y),t_dir = unit_getdir(target); + uint8 dir = iMap->calc_dir(src,target->x,target->y),t_dir = unit->getdir(target); if(check_distance_bl(src, target, 0) || iMap->check_dir(dir,t_dir)) { break; } @@ -4782,7 +4782,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH) - unit_stop_walking(src,1); + unit->stop_walking(src,1); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish] @@ -4819,7 +4819,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } } if (skill->get_state(ud->skill_id) != ST_MOVE_ENABLE) - unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1); + unit->set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1); if(battle_config.skill_log && battle_config.skill_log&src->type) ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n", @@ -4886,7 +4886,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) if( dir > 2 && dir < 6 ) y = -2; else if( dir == 7 || dir < 2 ) y = 2; else y = 0; - if (unit_movepos(src, src->x+x, src->y+y, 1, 1)) + if (unit->movepos(src, src->x+x, src->y+y, 1, 1)) { //Display movement + animation. clif->slide(src,src->x,src->y); clif->spiritball(src); @@ -5217,14 +5217,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } else {// mob-casted - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); int inf = skill->get_inf(abra_skill_id); if (!ud) break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { if (src->type == BL_PET) bl = (struct block_list*)((TBL_PET*)src)->msd; if (!bl) bl = src; - unit_skilluse_id(src, bl->id, abra_skill_id, abra_skill_lv); + unit->skilluse_id(src, bl->id, abra_skill_id, abra_skill_lv); } else { //Assume offensive skills int target_id = 0; if (ud->target) @@ -5238,9 +5238,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (skill->get_casttype(abra_skill_id) == CAST_GROUND) { bl = iMap->id2bl(target_id); if (!bl) bl = src; - unit_skilluse_pos(src, bl->x, bl->y, abra_skill_id, abra_skill_lv); + unit->skilluse_pos(src, bl->x, bl->y, abra_skill_id, abra_skill_lv); } else - unit_skilluse_id(src, target_id, abra_skill_id, abra_skill_lv); + unit->skilluse_id(src, target_id, abra_skill_id, abra_skill_lv); } } } @@ -5474,10 +5474,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case TK_JUMPKICK: - /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit_movepos (exploitable) */ + /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit->movepos (exploitable) */ if( battle->check_target(src, bl, BCT_ENEMY) > 0 ) { - if( unit_movepos(src, bl->x, bl->y, 1, 1) ) + if( unit->movepos(src, bl->x, bl->y, 1, 1) ) { skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); clif->slide(src,bl->x,bl->y); @@ -5726,7 +5726,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui iMap->freeblock_unlock(); return 0; } - unit_skillcastcancel(bl, 2); + unit->skillcastcancel(bl, 2); if( tsc && tsc->count ) { @@ -6069,7 +6069,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui iMap->freeblock_unlock(); return 0; } - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit_getdir(bl),0,0,0)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,0)); if (sd) // If the client receives a skill-use packet inmediately before a walkok packet, it will discard the walk packet! [Skotlex] clif->walkok(sd); // So aegis has to resend the walk ok. break; @@ -6364,12 +6364,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui else clif->skill_warppoint(sd,skill_id,skill_lv, (unsigned short)-1,sd->status.save_point.map,0,0); } else - unit_warp(bl,-1,-1,-1,CLR_TELEPORT); + unit->warp(bl,-1,-1,-1,CLR_TELEPORT); break; case NPC_EXPULSION: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - unit_warp(bl,-1,-1,-1,CLR_TELEPORT); + unit->warp(bl,-1,-1,-1,CLR_TELEPORT); break; case AL_HOLYWATER: @@ -6704,12 +6704,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex] clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit_getdir(bl),0); + skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0); break; case TK_HIGHJUMP: { - int x,y, dir = unit_getdir(src); + int x,y, dir = unit->getdir(src); //Fails on noteleport maps, except for GvG and BG maps [Skotlex] if( map[src->m].flag.noteleport && @@ -6725,7 +6725,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif->skill_nodamage(src,bl,TK_HIGHJUMP,skill_lv,1); if(!iMap->count_oncell(src->m,x,y,BL_PC|BL_NPC|BL_MOB) && iMap->getcell(src->m,x,y,CELL_CHKREACH)) { clif->slide(src,x,y); - unit_movepos(src, x, y, 1, 0); + unit->movepos(src, x, y, 1, 0); } } break; @@ -6733,7 +6733,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SA_CASTCANCEL: case SO_SPELLFIST: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - unit_skillcastcancel(src,1); + unit->skillcastcancel(src,1); if(sd) { int sp = skill->get_sp(sd->skill_id_old,sd->skill_lv_old); if( skill_id == SO_SPELLFIST ){ @@ -6756,7 +6756,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui iStatus->heal(bl,0,sp,2); status_percent_damage(bl, src, 0, -20, false); //20% max SP damage. } else { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); int bl_skill_id=0,bl_skill_lv=0,hp = 0; if (!ud || ud->skilltimer == INVALID_TIMER) break; //Nothing to cancel. @@ -6773,7 +6773,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui hp = tstatus->max_hp/50; //Recover 2% HP [Skotlex] clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - unit_skillcastcancel(bl,0); + unit->skillcastcancel(bl,0); sp = skill->get_sp(bl_skill_id,bl_skill_lv); status_zap(bl, hp, sp); @@ -6879,7 +6879,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_BARRIER: { int skill_time = skill->get_time(skill_id,skill_lv); - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if (clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,type,100,skill_lv,skill_time)) && ud) { //Disable attacking/acting/moving for skill's duration. @@ -6955,10 +6955,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_RUN: { const int mask[8][2] = {{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}}; - uint8 dir = (bl == src)?unit_getdir(src):iMap->calc_dir(src,bl->x,bl->y); //If cast on self, run forward, else run away. - unit_stop_attack(src); + uint8 dir = (bl == src)?unit->getdir(src):iMap->calc_dir(src,bl->x,bl->y); //If cast on self, run forward, else run away. + unit->stop_attack(src); //Run skillv tiles overriding the can-move check. - if (unit_walktoxy(src, src->x + skill_lv * mask[dir][0], src->y + skill_lv * mask[dir][1], 2) && md) + if (unit->walktoxy(src, src->x + skill_lv * mask[dir][0], src->y + skill_lv * mask[dir][1], 2) && md) md->state.skillstate = MSS_WALK; //Otherwise it isn't updated in the ai. } break; @@ -7152,7 +7152,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case BD_ENCORE: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); if(sd) - unit_skilluse_id(src,src->id,sd->skill_id_dance,sd->skill_lv_dance); + unit->skilluse_id(src,src->id,sd->skill_id_dance,sd->skill_lv_dance); break; case AS_SPLASHER: @@ -7198,7 +7198,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui return 0; } - unit_skillcastcancel(bl,0); + unit->skillcastcancel(bl,0); if(tsc && tsc->count){ status_change_end(bl, SC_FREEZE, INVALID_TIMER); @@ -7361,7 +7361,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case 5: // 2000HP heal, random teleported iStatus->heal(src, 2000, 0, 0); if( !map_flag_vs(bl->m) ) - unit_warp(bl, -1,-1,-1, CLR_TELEPORT); + unit->warp(bl, -1,-1,-1, CLR_TELEPORT); break; case 6: // random 2 other effects if (count == -1) @@ -7605,10 +7605,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (hd) skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id,skill_lv)); - if (unit_movepos(src,bl->x,bl->y,0,0)) { + if (unit->movepos(src,bl->x,bl->y,0,0)) { clif->skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc clif->slide(src,bl->x,bl->y) ; - if (unit_movepos(bl,x,y,0,0)) + if (unit->movepos(bl,x,y,0,0)) { clif->skill_nodamage(bl,bl,skill_id,skill_lv,1); // Master clif->slide(bl,x,y) ; @@ -8233,7 +8233,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui return 0; } if( sd && pc_isridingwug(sd) ) { - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit_getdir(bl),0,0,1)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,1)); clif->walkok(sd); } break; @@ -8249,7 +8249,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NC_F_SIDESLIDE: case NC_B_SIDESLIDE: { - uint8 dir = (skill_id == NC_F_SIDESLIDE) ? (unit_getdir(src)+4)%8 : unit_getdir(src); + uint8 dir = (skill_id == NC_F_SIDESLIDE) ? (unit->getdir(src)+4)%8 : unit->getdir(src); skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),dir,0); clif->slide(src,src->x,src->y); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -8561,7 +8561,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( sc_start2(bl, type, 100, skill_lv, src->id, skill->get_time(skill_id, skill_lv))) { if( bl->type == BL_MOB ) mob->unlocktarget((TBL_MOB*)bl,iTimer->gettick()); - unit_stop_attack(bl); + unit->stop_attack(bl); clif->bladestop(src, bl->id, 1); iMap->freeblock_unlock(); return 1; @@ -8796,14 +8796,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui sd->skillitemlv = improv_skill_lv; clif->item_skill(sd, improv_skill_id, improv_skill_lv); } else { - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); int inf = skill->get_inf(improv_skill_id); if (!ud) break; if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) { if (src->type == BL_PET) bl = (struct block_list*)((TBL_PET*)src)->msd; if (!bl) bl = src; - unit_skilluse_id(src, bl->id, improv_skill_id, improv_skill_lv); + unit->skilluse_id(src, bl->id, improv_skill_id, improv_skill_lv); } else { int target_id = 0; if (ud->target) @@ -8817,9 +8817,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (skill->get_casttype(improv_skill_id) == CAST_GROUND) { bl = iMap->id2bl(target_id); if (!bl) bl = src; - unit_skilluse_pos(src, bl->x, bl->y, improv_skill_id, improv_skill_lv); + unit->skilluse_pos(src, bl->x, bl->y, improv_skill_id, improv_skill_lv); } else - unit_skilluse_id(src, target_id, improv_skill_id, improv_skill_lv); + unit->skilluse_id(src, target_id, improv_skill_id, improv_skill_lv); } } } @@ -9158,7 +9158,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui mob->spawn( md ); pc->setinvincibletimer(sd,500);// unlock target lock clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit_getdir(bl),0); + skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0); } } break; @@ -9198,11 +9198,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } - if (unit_movepos(src, bl->x, bl->y, 0, 0)) { + if (unit->movepos(src, bl->x, bl->y, 0, 0)) { clif->skill_nodamage(src, src, skill_id, skill_lv, 1); clif->slide(src, bl->x, bl->y) ; sc_start(src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv)); - if ( !is_boss(bl) && unit_stop_walking(&sd->bl, 1) && unit_movepos(bl, x, y, 0, 0) ) + if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) ) { if( dstsd && pc_issit(dstsd) ) pc->setstand(dstsd); @@ -9389,7 +9389,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) struct block_list* src = iMap->id2bl(id); int maxcount; struct map_session_data *sd; - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); struct mob_data *md; nullpo_ret(ud); @@ -9485,7 +9485,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) src->type, src->id, ud->skill_id, ud->skill_lv, ud->skillx, ud->skilly); if (ud->walktimer != INVALID_TIMER) - unit_stop_walking(src,1); + unit->stop_walking(src,1); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); @@ -9511,7 +9511,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) // break; // } // } - unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1); + unit->set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1); status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);// only normal attack and auto cast skills benefit from its bonuses iMap->freeblock_lock(); skill->castend_pos2(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv,tick,0); @@ -9969,7 +9969,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui return 0; // not to consume item. case MO_BODYRELOCATION: - if (unit_movepos(src, x, y, 1, 1)) { + if (unit->movepos(src, x, y, 1, 1)) { #if PACKETVER >= 20111005 clif->snap(src, src->x, src->y); #else @@ -9981,7 +9981,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case NJ_SHADOWJUMP: if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground ) { //You don't move on GVG grounds. - unit_movepos(src, x, y, 1, 0); + unit->movepos(src, x, y, 1, 0); clif->slide(src,x,y); } status_change_end(src, SC_HIDING, INVALID_TIMER); @@ -10248,7 +10248,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case SC_FEINTBOMB: skill->unitsetting(src,skill_id,skill_lv,x,y,0); // Set bomb on current Position clif->skill_nodamage(src,src,skill_id,skill_lv,1); - if( skill->blown(src,src,6,unit_getdir(src),0) ) + if( skill->blown(src,src,6,unit->getdir(src),0) ) skill->castend_nodamage_id(src,src,TF_HIDING,1,tick,0x2); break; @@ -10312,7 +10312,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case GN_FIRE_EXPANSION: { int i; - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); if( !ud ) break; @@ -11093,7 +11093,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned } else if(bl->type == BL_MOB && battle_config.mob_warp&2) { int16 m = iMap->mapindex2mapid(sg->val3); if (m < 0) break; //Map not available on this map-server. - unit_warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT); + unit->warp(bl,m,sg->val2>>16,sg->val2&0xffff,CLR_TELEPORT); } } break; @@ -11182,7 +11182,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned break; if (ss == bl) //Also needed to prevent infinite loop crash. break; - skill->blown(ss,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); + skill->blown(ss,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit->getdir(bl),0); break; case UNT_WALLOFTHORN: @@ -11399,7 +11399,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_SKIDTRAP: { - skill->blown(&src->bl,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit_getdir(bl),0); + skill->blown(&src->bl,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit->getdir(bl),0); sg->unit_id = UNT_USED_TRAPS; clif->changetraplook(&src->bl, UNT_USED_TRAPS); sg->limit=DIFF_TICK(tick,sg->tick)+1500; @@ -11415,7 +11415,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( td ) sec = DIFF_TICK(td->tick, tick); if( sg->unit_id == UNT_MANHOLE || battle_config.skill_trap_type || !map_flag_gvg2(src->bl.m) ) { - unit_movepos(bl, src->bl.x, src->bl.y, 0, 0); + unit->movepos(bl, src->bl.x, src->bl.y, 0, 0); clif->fixpos(bl); } sg->val2 = bl->id; @@ -11644,7 +11644,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns int i = battle->check_target(&src->bl, bl, BCT_ENEMY); if( i > 0 && !(status_get_mode(bl)&MD_BOSS) ) { // knock-back any enemy except Boss - skill->blown(&src->bl, bl, 2, unit_getdir(bl), 0); + skill->blown(&src->bl, bl, 2, unit->getdir(bl), 0); clif->fixpos(bl); } @@ -11720,7 +11720,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( tsd && !map[bl->m].flag.noteleport ) pc->randomwarp(tsd,3); else if( bl->type == BL_MOB && battle_config.mob_warp&8 ) - unit_warp(bl,-1,-1,-1,3); + unit->warp(bl,-1,-1,-1,3); break; case UNT_REVERBERATION: @@ -11851,21 +11851,21 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range)// don't consider outer bounderies sc_start(bl, type, 100, sg->skill_lv, sec); - if( unit_is_walking(bl) && // wait until target stop walking + if( unit->is_walking(bl) && // wait until target stop walking ( tsc && tsc->data[type] && tsc->data[type]->val4 >= tsc->data[type]->val3-range )) break; if( tsc && ( !tsc->data[type] || (tsc->data[type] && tsc->data[type]->val4 < 1 ) ) ) break; - if( unit_is_walking(bl) && + if( unit->is_walking(bl) && distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) > range )// going outside of boundaries? then force it to stop - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); - if( !unit_is_walking(bl) && + if( !unit->is_walking(bl) && distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range && // only snap if the target is inside the range or src->bl.x != bl->x && src->bl.y != bl->y){// diagonal position parallel to VE's center - unit_movepos(bl, src->bl.x, src->bl.y, 0, 0); + unit->movepos(bl, src->bl.x, src->bl.y, 0, 0); clif->fixpos(bl); } } @@ -12193,7 +12193,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap) { switch(skill_id) { case PR_BENEDICTIO: { uint8 dir = iMap->calc_dir(&sd->bl,tsd->bl.x,tsd->bl.y); - dir = (unit_getdir(&sd->bl) + dir)%8; //This adjusts dir to account for the direction the sd is facing. + dir = (unit->getdir(&sd->bl) + dir)%8; //This adjusts dir to account for the direction the sd is facing. if ((tsd->class_&MAPID_BASEMASK) == MAPID_ACOLYTE && (dir == 2 || dir == 6) //Must be standing to the left/right of Priest. && sd->status.sp >= 10) p_sd[(*c)++]=tsd->bl.id; @@ -12217,7 +12217,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap) { default: //Warning: Assuming Ensemble Dance/Songs for code speed. [Skotlex] { uint16 skill_lv; - if(pc_issit(tsd) || !unit_can_move(&tsd->bl)) + if(pc_issit(tsd) || !unit->can_move(&tsd->bl)) return 0; if (sd->status.sex != tsd->status.sex && (tsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER && @@ -12546,7 +12546,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } } - else if( !unit_can_move(&sd->bl) ) + else if( !unit->can_move(&sd->bl) ) { //Placed here as ST_MOVE_ENABLE should not apply if rooted or on a combo. [Skotlex] clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; @@ -12590,7 +12590,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } if(sc->data[SC_COMBOATTACK]->val1 != skill_id && !( sd && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait. - unit_cancel_combo(&sd->bl); + unit->cancel_combo(&sd->bl); return 0; } break; //Combo ready. @@ -13093,7 +13093,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id if (sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == skill_id) sd->ud.canmove_tick = iTimer->gettick(); //When using a combo, cancel the can't move delay to enable the skill. [Skotlex] - if (!unit_can_move(&sd->bl)) { + if (!unit->can_move(&sd->bl)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } @@ -14614,7 +14614,7 @@ int skill_attack_area (struct block_list *bl, va_list ap) *------------------------------------------*/ int skill_clear_group (struct block_list *bl, int flag) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); struct skill_unit_group *group[MAX_SKILLUNITGROUP]; int i, count=0; @@ -14653,7 +14653,7 @@ int skill_clear_group (struct block_list *bl, int flag) * Returns the first element field found [Skotlex] *------------------------------------------*/ struct skill_unit_group *skill_locate_element_field(struct block_list *bl) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); int i; nullpo_ret(bl); if (!ud) return NULL; @@ -14859,7 +14859,7 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap) { struct mob_data* md; - struct unit_data*ud = unit_bl2ud(bl); + struct unit_data*ud = unit->bl2ud(bl); struct block_list *from_bl; struct block_list *to_bl; md = (struct mob_data*)bl; @@ -15247,7 +15247,7 @@ static int skill_get_new_group_id(void) struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count, uint16 skill_id, uint16 skill_lv, int unit_id, int limit, int interval) { - struct unit_data* ud = unit_bl2ud( src ); + struct unit_data* ud = unit->bl2ud( src ); struct skill_unit_group* group; int i; @@ -15318,7 +15318,7 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin } src=iMap->id2bl(group->src_id); - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); if(!src || !ud) { ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id); return 0; @@ -15442,7 +15442,7 @@ int skill_delunitgroup(struct skill_unit_group *group, const char* file, int lin *------------------------------------------*/ int skill_clear_unitgroup (struct block_list *src) { - struct unit_data *ud = unit_bl2ud(src); + struct unit_data *ud = unit->bl2ud(src); nullpo_ret(ud); @@ -15464,7 +15464,7 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_lis if (group->interval==-1) return NULL; - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (!ud) return NULL; set = ud->skillunittick; diff --git a/src/map/status.c b/src/map/status.c index 2db38cb15..6efc0b6ca 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1225,7 +1225,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, if(sc->data[SC_KAGEMUSYA] && --(sc->data[SC_KAGEMUSYA]->val3) <= 0) status_change_end(target, SC_KAGEMUSYA, INVALID_TIMER); } - unit_skillcastcancel(target, 2); + unit->skillcastcancel(target, 2); } status->hp-= hp; @@ -1253,13 +1253,13 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, } if( src && target->type == BL_PC && (((TBL_PC*)target)->disguise) > 0 ) {// stop walking when attacked in disguise to prevent walk-delay bug - unit_stop_walking( target, 1 ); + unit->stop_walking( target, 1 ); } if( status->hp || (flag&8) ) { //Still lives or has been dead before this damage. if (walkdelay) - unit_set_walkdelay(target, iTimer->gettick(), walkdelay, 0); + unit->set_walkdelay(target, iTimer->gettick(), walkdelay, 0); return (int)(hp+sp); } @@ -1339,13 +1339,13 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, iStatus->change_clear(target,0); if(flag&4) //Delete from memory. (also invokes map removal code) - unit_free(target,CLR_DEAD); + unit->free(target,CLR_DEAD); else if(flag&2) //remove from map - unit_remove_map(target,CLR_DEAD); + unit->remove_map(target,CLR_DEAD,ALC_MARK); else { //Some death states that would normally be handled by unit_remove_map - unit_stop_attack(target); - unit_stop_walking(target,1); - unit_skillcastcancel(target,0); + unit->stop_attack(target); + unit->stop_walking(target,1); + unit->skillcastcancel(target,0); clif->clearunit_area(target,CLR_DEAD); skill->unit_move(target,iTimer->gettick(),4); skill->cleartimerskill(target); @@ -1628,8 +1628,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; if (sc->data[SC_DC_WINKCHARM] && target && !flag) { //Prevents skill usage - if( unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER ) - unit_walktobl(src, iMap->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); + if( unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER ) + unit->walktobl(src, iMap->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); clif->emotion(src, E_LV); return 0; } @@ -2088,7 +2088,7 @@ int status_calc_mob_(struct mob_data* md, bool first) if (flag&16 && mbl) { //Max HP setting from Summon Flora/marine Sphere - struct unit_data *ud = unit_bl2ud(mbl); + struct unit_data *ud = unit->bl2ud(mbl); //Remove special AI when this is used by regular mobs. if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai) md->special_state.ai = 0; @@ -3743,7 +3743,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) } if(flag&SCB_SPEED) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); status->speed = status_calc_speed(bl, sc, b_status->speed); //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER @@ -3798,9 +3798,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) status->mode = status_calc_mode(bl, sc, b_status->mode); //Since mode changed, reset their state. if (!(status->mode&MD_CANATTACK)) - unit_stop_attack(bl); + unit->stop_attack(bl); if (!(status->mode&MD_CANMOVE)) - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); } // No status changes alter these yet. @@ -5883,7 +5883,7 @@ defType status_get_def(struct block_list *bl) { struct unit_data *ud; struct status_data *status = iStatus->get_status_data(bl); int def = status?status->def:0; - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (ud && ud->skilltimer != INVALID_TIMER) def -= def * skill->get_castdef(ud->skill_id)/100; @@ -7554,7 +7554,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_HANBOK: if (!vd) return 0; //Store previous values as they could be removed. - unit_stop_attack(bl); + unit->stop_attack(bl); break; case SC_NOCHAT: // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_? @@ -7914,11 +7914,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val //val3: When set, this combo time should NOT delay attack/movement //val3: TK: Last used kick //val4: TK: Combo time - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if (ud && !val3) { tick += 300 * battle_config.combo_delay_rate/100; ud->attackabletime = iTimer->gettick()+tick; - unit_set_walkdelay(bl, iTimer->gettick(), tick, 1); + unit->set_walkdelay(bl, iTimer->gettick(), tick, 1); } val3 = 0; val4 = tick; @@ -8498,7 +8498,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_UNLIMITED_HUMMING_VOICE: { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if( ud == NULL ) return 0; ud->state.skillcastcancel = 0; val3 = 15 - (2 * val2); @@ -8861,9 +8861,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val status_change_end(bl, SC_DANCING, INVALID_TIMER); // Cancel cast when get status [LuzZza] if (battle_config.sc_castcancel&bl->type) - unit_skillcastcancel(bl, 0); + unit->skillcastcancel(bl, 0); case SC_WHITEIMPRISON: - unit_stop_attack(bl); + unit->stop_attack(bl); case SC_STOP: case SC_CONFUSION: case SC_RG_CCONFINE_M: @@ -8882,11 +8882,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_KYOUGAKU: case SC_NEEDLE_OF_PARALYZE: case SC_DEATHBOUND: - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); break; case SC_ANKLESNARE: if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); break; case SC_HIDING: case SC_CLOAKING: @@ -8895,11 +8895,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_WEIGHTOVER90: case SC_CAMOUFLAGE: case SC_SIREN: - unit_stop_attack(bl); + unit->stop_attack(bl); break; case SC_SILENCE: if (battle_config.sc_castcancel&bl->type) - unit_skillcastcancel(bl, 0); + unit->skillcastcancel(bl, 0); break; /* */ case SC_ITEMSCRIPT: @@ -9148,9 +9148,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_RUN: { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if( ud ) - ud->state.running = unit_run(bl); + ud->state.running = unit->run(bl); } break; case SC_CASH_BOSS_ALARM: @@ -9167,9 +9167,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val **/ case SC_WUGDASH: { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if( ud ) - ud->state.running = unit_wugdash(bl, sd); + ud->state.running = unit->wugdash(bl, sd); } break; case SC_COMBOATTACK: @@ -9365,14 +9365,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const break; case SC_RUN: { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); bool begin_spurt = true; if (ud) { if(!ud->state.running) begin_spurt = false; ud->state.running = 0; if (ud->walktimer != INVALID_TIMER) - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); } if (begin_spurt && sce->val1 >= 7 && DIFF_TICK(iTimer->gettick(), sce->val4) <= 1000 && @@ -9681,11 +9681,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const break; case SC_WUGDASH: { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if (ud) { ud->state.running = 0; if (ud->walktimer != -1) - unit_stop_walking(bl,1); + unit->stop_walking(bl,1); } } break; @@ -10131,8 +10131,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) case SC_STONE: if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { sce->val4 = 0; - unit_stop_walking(bl,1); - unit_stop_attack(bl); + unit->stop_walking(bl,1); + unit->stop_attack(bl); sc->opt1 = OPT1_STONE; clif->changeoption(bl); sc_timer_next(1000+tick,iStatus->change_timer, bl->id, data ); @@ -10392,7 +10392,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( --(sce->val4) > 0 ) { int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) damage += status->vit * (sce->val1 - 3); - unit_skillcastcancel(bl,2); + unit->skillcastcancel(bl,2); iMap->freeblock_lock(); iStatus->damage(bl, bl, damage, 0, clif->damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); if( sc->data[type] ) { @@ -10420,8 +10420,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if( !flag ) { // Random Skill Cast if (sd && !pc_issit(sd)) { //can't cast if sit int mushroom_skill_id = 0, i; - unit_stop_attack(bl); - unit_skillcastcancel(bl,1); + unit->stop_attack(bl); + unit->skillcastcancel(bl,1); do { i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; mushroom_skill_id = skill_magicmushroom_db[i].skill_id; @@ -10618,7 +10618,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) iMap->freeblock_lock(); damage = sce->val3; iStatus->damage(src, bl, damage, 0, clif->damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,0,0), 1); - unit_skillcastcancel(bl,1); + unit->skillcastcancel(bl,1); if ( sc->data[type] ) { sc_timer_next(1000 + tick, iStatus->change_timer, bl->id, data); } @@ -11299,7 +11299,7 @@ static int status_natural_heal(struct block_list* bl, va_list args) if (flag && regen->state.overweight) flag=0; - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER) { diff --git a/src/map/unit.c b/src/map/unit.c index 228cd75dd..65eea39c9 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -45,6 +45,8 @@ const short dirx[8]={0,-1,-1,-1,0,1,1,1}; const short diry[8]={1,1,0,-1,-1,-1,0,1}; +struct unit_interface unit_s; + /** * Returns the unit_data for the given block_list. If the object is using * shared unit_data (i.e. in case of BL_NPC), it returns the shared data. @@ -75,13 +77,13 @@ struct unit_data* unit_bl2ud2(struct block_list *bl) { struct npc_data *nd = (struct npc_data *)bl; nd->ud = NULL; CREATE(nd->ud, struct unit_data, 1); - unit_dataset(&nd->bl); + unit->dataset(&nd->bl); } - return unit_bl2ud(bl); + return unit->bl2ud(bl); } -static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data); -static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data); +int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data); +int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data); int unit_walktoxy_sub(struct block_list *bl) { @@ -90,7 +92,7 @@ int unit_walktoxy_sub(struct block_list *bl) struct unit_data *ud = NULL; nullpo_retr(1, bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if(ud == NULL) return 0; if( !path_search(&wpd,bl->m,bl->x,bl->y,ud->to_x,ud->to_y,ud->state.walk_easy,CELL_CHKNOPASS) ) @@ -131,11 +133,11 @@ int unit_walktoxy_sub(struct block_list *bl) else i = iStatus->get_speed(bl); if( i > 0) - ud->walktimer = iTimer->add_timer(iTimer->gettick()+i,unit_walktoxy_timer,bl->id,i); + ud->walktimer = iTimer->add_timer(iTimer->gettick()+i,unit->walktoxy_timer,bl->id,i); return 1; } -static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) +int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { int i; int x,y,dx,dy; @@ -152,7 +154,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data sd = BL_CAST(BL_PC, bl); md = BL_CAST(BL_MOB, bl); mrd = BL_CAST(BL_MER, bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if(ud == NULL) return 0; @@ -178,7 +180,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data dy = diry[(int)dir]; if(iMap->getcell(bl->m,x+dx,y+dy,CELL_CHKNOPASS)) - return unit_walktoxy_sub(bl); + return unit->walktoxy_sub(bl); //Refresh view for all those we lose sight iMap->foreachinmovearea(clif->outsight, bl, AREA_SIZE, dx, dy, sd?BL_ALL:BL_PC, bl); @@ -216,7 +218,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data else if (DIFF_TICK(iTimer->gettick(), sd->md->masterteleport_timer) > 3000) { sd->md->masterteleport_timer = 0; - unit_warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); + unit->warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); } } else if( sd->md ) @@ -257,7 +259,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data else if (DIFF_TICK(iTimer->gettick(), mrd->masterteleport_timer) > 3000) { mrd->masterteleport_timer = 0; - unit_warp( bl, mrd->master->bl.id, mrd->master->bl.x, mrd->master->bl.y, CLR_TELEPORT ); + unit->warp( bl, mrd->master->bl.id, mrd->master->bl.x, mrd->master->bl.y, CLR_TELEPORT ); } } else @@ -270,7 +272,7 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data return 0; if(ud->state.change_walk_target) - return unit_walktoxy_sub(bl); + return unit->walktoxy_sub(bl); ud->walkpath.path_pos++; if(ud->walkpath.path_pos>=ud->walkpath.path_len) @@ -281,12 +283,12 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data i = iStatus->get_speed(bl); if(i > 0) { - ud->walktimer = iTimer->add_timer(tick+i,unit_walktoxy_timer,id,i); + ud->walktimer = iTimer->add_timer(tick+i,unit->walktoxy_timer,id,i); if( md && DIFF_TICK(tick,md->dmgtick) < 3000 )//not required not damaged recently clif->move(ud); } else if(ud->state.running) { //Keep trying to run. - if ( !(unit_run(bl) || unit_wugdash(bl,sd)) ) + if ( !(unit->run(bl) || unit->wugdash(bl,sd)) ) ud->state.running = 0; } else if (ud->target_to) { @@ -307,10 +309,10 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data //only need this one for syncing purposes. [Skotlex] ud->target_to = 0; clif->fixpos(bl); - unit_attack(bl, tbl->id, ud->state.attack_continue); + unit->attack(bl, tbl->id, ud->state.attack_continue); } } else { //Update chase-path - unit_walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy|(ud->state.attack_continue?2:0)); + unit->walktobl(bl, tbl, ud->chaserange, ud->state.walk_easy|(ud->state.attack_continue?2:0)); return 0; } } @@ -321,13 +323,13 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data return 0; } -static int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) +int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { struct block_list *bl = iMap->id2bl(id); if (!bl || bl->prev == NULL) return 0; - unit_walktoxy(bl, (short)((data>>16)&0xffff), (short)(data&0xffff), 0); + unit->walktoxy(bl, (short)((data>>16)&0xffff), (short)(data&0xffff), 0); return 1; } @@ -343,7 +345,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) nullpo_ret(bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if( ud == NULL) return 0; @@ -362,17 +364,17 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) if (flag&4 && DIFF_TICK(ud->canmove_tick, iTimer->gettick()) > 0 && DIFF_TICK(ud->canmove_tick, iTimer->gettick()) < 2000) { // Delay walking command. [Skotlex] - iTimer->add_timer(ud->canmove_tick+1, unit_delay_walktoxy_timer, bl->id, (x<<16)|(y&0xFFFF)); + iTimer->add_timer(ud->canmove_tick+1, unit->delay_walktoxy_timer, bl->id, (x<<16)|(y&0xFFFF)); return 1; } - if(!(flag&2) && (!(status_get_mode(bl)&MD_CANMOVE) || !unit_can_move(bl))) + if(!(flag&2) && (!(status_get_mode(bl)&MD_CANMOVE) || !unit->can_move(bl))) return 0; ud->state.walk_easy = flag&1; ud->to_x = x; ud->to_y = y; - unit_set_target(ud, 0); + unit->set_target(ud, 0); sc = iStatus->get_sc(bl); if (sc && sc->data[SC_CONFUSION]) //Randomize the target position @@ -380,17 +382,17 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) if(ud->walktimer != INVALID_TIMER) { // When you come to the center of the grid because the change of destination while you're walking right now - // Call a function from a timer unit_walktoxy_sub + // Call a function from a timer unit->walktoxy_sub ud->state.change_walk_target = 1; return 1; } if(ud->attacktimer != INVALID_TIMER) { - iTimer->delete_timer( ud->attacktimer, unit_attack_timer ); + iTimer->delete_timer( ud->attacktimer, unit->attack_timer ); ud->attacktimer = INVALID_TIMER; } - return unit_walktoxy_sub(bl); + return unit->walktoxy_sub(bl); } //To set Mob's CHASE/FOLLOW states (shouldn't be done if there's no path to reach) @@ -402,18 +404,18 @@ static inline void set_mobstate(struct block_list* bl, int flag) md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH; } -static int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) +int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) { struct block_list *bl = iMap->id2bl(id); - struct unit_data *ud = bl?unit_bl2ud(bl):NULL; + struct unit_data *ud = bl?unit->bl2ud(bl):NULL; if (ud && ud->walktimer == INVALID_TIMER && ud->target == data) { if (DIFF_TICK(ud->canmove_tick, tick) > 0) //Keep waiting? - iTimer->add_timer(ud->canmove_tick+1, unit_walktobl_sub, id, data); - else if (unit_can_move(bl)) + iTimer->add_timer(ud->canmove_tick+1, unit->walktobl_sub, id, data); + else if (unit->can_move(bl)) { - if (unit_walktoxy_sub(bl)) + if (unit->walktoxy_sub(bl)) set_mobstate(bl, ud->state.attack_continue); } } @@ -430,13 +432,13 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int nullpo_ret(bl); nullpo_ret(tbl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if( ud == NULL) return 0; if (!(status_get_mode(bl)&MD_CANMOVE)) return 0; - if (!unit_can_reach_bl(bl, tbl, distance_bl(bl, tbl)+1, flag&1, &ud->to_x, &ud->to_y)) { + if (!unit->can_reach_bl(bl, tbl, distance_bl(bl, tbl)+1, flag&1, &ud->to_x, &ud->to_y)) { ud->to_x = bl->x; ud->to_y = bl->y; ud->target_to = 0; @@ -447,7 +449,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int ud->target_to = tbl->id; ud->chaserange = range; //Note that if flag&2, this SHOULD be attack-range ud->state.attack_continue = flag&2?1:0; //Chase to attack. - unit_set_target(ud, 0); + unit->set_target(ud, 0); sc = iStatus->get_sc(bl); if (sc && sc->data[SC_CONFUSION]) //Randomize the target position @@ -461,19 +463,19 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int if(DIFF_TICK(ud->canmove_tick, iTimer->gettick()) > 0) { //Can't move, wait a bit before invoking the movement. - iTimer->add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target); + iTimer->add_timer(ud->canmove_tick+1, unit->walktobl_sub, bl->id, ud->target); return 1; } - if(!unit_can_move(bl)) + if(!unit->can_move(bl)) return 0; if(ud->attacktimer != INVALID_TIMER) { - iTimer->delete_timer( ud->attacktimer, unit_attack_timer ); + iTimer->delete_timer( ud->attacktimer, unit->attack_timer ); ud->attacktimer = INVALID_TIMER; } - if (unit_walktoxy_sub(bl)) { + if (unit->walktoxy_sub(bl)) { set_mobstate(bl, flag&2); return 1; } @@ -490,7 +492,7 @@ int unit_run(struct block_list *bl) if (!(sc && sc->data[SC_RUN])) return 0; - if (!unit_can_move(bl)) { + if (!unit->can_move(bl)) { status_change_end(bl, SC_RUN, INVALID_TIMER); return 0; } @@ -520,30 +522,30 @@ int unit_run(struct block_list *bl) clif->sc_load(bl,bl->id,AREA,SI_TING,0,0,0); //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin] - unit_bl2ud(bl)->state.running = 0; + unit->bl2ud(bl)->state.running = 0; status_change_end(bl, SC_RUN, INVALID_TIMER); - skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit_getdir(bl),0); + skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit->getdir(bl),0); clif->fixpos(bl); //Why is a clif->slide (skill->blown) AND a fixpos needed? Ask Aegis. clif->sc_end(bl,bl->id,AREA,SI_TING); return 0; } - if (unit_walktoxy(bl, to_x, to_y, 1)) + if (unit->walktoxy(bl, to_x, to_y, 1)) return 1; //There must be an obstacle nearby. Attempt walking one cell at a time. do { to_x -= dir_x; to_y -= dir_y; - } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1)); + } while (--i > 0 && !unit->walktoxy(bl, to_x, to_y, 1)); if ( i == 0 ) { // copy-paste from above clif->sc_load(bl,bl->id,AREA,SI_TING,0,0,0); //Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin] - unit_bl2ud(bl)->state.running = 0; + unit->bl2ud(bl)->state.running = 0; status_change_end(bl, SC_RUN, INVALID_TIMER); - skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit_getdir(bl),0); + skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit->getdir(bl),0); clif->fixpos(bl); clif->sc_end(bl,bl->id,AREA,SI_TING); return 0; @@ -563,7 +565,7 @@ int unit_wugdash(struct block_list *bl, struct map_session_data *sd) { nullpo_ret(sd); nullpo_ret(bl); - if (!unit_can_move(bl)) { + if (!unit->can_move(bl)) { status_change_end(bl,SC_WUGDASH,INVALID_TIMER); return 0; } @@ -588,7 +590,7 @@ int unit_wugdash(struct block_list *bl, struct map_session_data *sd) { if(to_x == bl->x && to_y == bl->y) { - unit_bl2ud(bl)->state.running = 0; + unit->bl2ud(bl)->state.running = 0; status_change_end(bl,SC_WUGDASH,INVALID_TIMER); if( sd ){ @@ -597,15 +599,15 @@ int unit_wugdash(struct block_list *bl, struct map_session_data *sd) { } return 0; } - if (unit_walktoxy(bl, to_x, to_y, 1)) + if (unit->walktoxy(bl, to_x, to_y, 1)) return 1; do { to_x -= dir_x; to_y -= dir_y; - } while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1)); + } while (--i > 0 && !unit->walktoxy(bl, to_x, to_y, 1)); if (i==0) { - unit_bl2ud(bl)->state.running = 0; + unit->bl2ud(bl)->state.running = 0; status_change_end(bl,SC_WUGDASH,INVALID_TIMER); if( sd ){ @@ -623,7 +625,7 @@ int unit_escape(struct block_list *bl, struct block_list *target, short dist) uint8 dir = iMap->calc_dir(target, bl->x, bl->y); while( dist > 0 && iMap->getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH) ) dist--; - return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) ); + return ( dist > 0 && unit->walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) ); } //Instant warp function. @@ -636,12 +638,12 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool nullpo_ret(bl); sd = BL_CAST(BL_PC, bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if( ud == NULL) return 0; - unit_stop_walking(bl,1); - unit_stop_attack(bl); + unit->stop_walking(bl,1); + unit->stop_attack(bl); if( checkpath && (iMap->getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) ) return 0; // unreachable @@ -683,7 +685,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool flag = 2; if( flag ) { - unit_movepos(bl,sd->bl.x,sd->bl.y, 0, 0); + unit->movepos(bl,sd->bl.x,sd->bl.y, 0, 0); clif->slide(bl,bl->x,bl->y); } } @@ -695,7 +697,7 @@ int unit_setdir(struct block_list *bl,unsigned char dir) { struct unit_data *ud; nullpo_ret(bl ); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (!ud) return 0; ud->dir = dir; if (bl->type == BL_PC) @@ -710,7 +712,7 @@ uint8 unit_getdir(struct block_list *bl) { if( bl->type == BL_NPC ) return ((TBL_NPC*)bl)->dir; - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if (!ud) return 0; return ud->dir; } @@ -735,7 +737,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag) ny = result&0xffff; if(!su) { - unit_stop_walking(bl, 0); + unit->stop_walking(bl, 0); } if( sd ) { @@ -786,7 +788,7 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) { struct unit_data *ud; nullpo_ret(bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if(bl->prev==NULL || !ud) return 1; @@ -832,7 +834,7 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) if (bl->type == BL_PC) //Use pc_setpos return pc->setpos((TBL_PC*)bl, map_id2index(m), x, y, type); - if (!unit_remove_map(bl, type)) + if (!unit->remove_map(bl, type, ALC_MARK)) return 3; if (bl->m != m && battle_config.clear_unit_onwarp && @@ -865,14 +867,14 @@ int unit_stop_walking(struct block_list *bl,int type) unsigned int tick; nullpo_ret(bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); if(!ud || ud->walktimer == INVALID_TIMER) return 0; //NOTE: We are using timer data after deleting it because we know the //iTimer->delete_timer function does not messes with it. If the function's //behaviour changes in the future, this code could break! td = iTimer->get_timer(ud->walktimer); - iTimer->delete_timer(ud->walktimer, unit_walktoxy_timer); + iTimer->delete_timer(ud->walktimer, unit->walktoxy_timer); ud->walktimer = INVALID_TIMER; ud->state.change_walk_target = 0; tick = iTimer->gettick(); @@ -880,7 +882,7 @@ int unit_stop_walking(struct block_list *bl,int type) || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell ) { ud->walkpath.path_len = ud->walkpath.path_pos+1; - unit_walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos); + unit->walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos); } if(type&0x01) @@ -903,7 +905,7 @@ int unit_stop_walking(struct block_list *bl,int type) int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv) { - return unit_skilluse_id2( + return unit->skilluse_id2( src, target_id, skill_id, skill_lv, skill->cast_fix(src, skill_id, skill_lv), skill->get_castcancel(skill_id) @@ -912,7 +914,7 @@ int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uin int unit_is_walking(struct block_list *bl) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); nullpo_ret(bl); if(!ud) return 0; return (ud->walktimer != INVALID_TIMER); @@ -927,7 +929,7 @@ int unit_can_move(struct block_list *bl) { struct status_change *sc; nullpo_ret(bl); - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); sc = iStatus->get_sc(bl); sd = BL_CAST(BL_PC, bl); @@ -1013,10 +1015,10 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) if(sd && pc_isridingwug(sd)) clif->skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skill_lv, - sc_start4(ud->bl,iStatus->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit_getdir(ud->bl),0,0,1)); + sc_start4(ud->bl,iStatus->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1)); else clif->skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skill_lv, - sc_start4(ud->bl,iStatus->skill2sc(TK_RUN),100,ud->skill_lv,unit_getdir(ud->bl),0,0,0)); + sc_start4(ud->bl,iStatus->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0)); if (sd) clif->walkok(sd); @@ -1032,7 +1034,7 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) *------------------------------------------*/ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if (delay <= 0 || !ud) return 0; /** @@ -1046,7 +1048,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int return 0; } else { //Don't set walk delays when already trapped. - if (!unit_can_move(bl)) + if (!unit->can_move(bl)) return 0; } ud->canmove_tick = tick + delay; @@ -1054,18 +1056,18 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int { //Stop walking, if chasing, readjust timers. if (delay == 1) { //Minimal delay (walk-delay) disabled. Just stop walking. - unit_stop_walking(bl,4); + unit->stop_walking(bl,4); } else { //Resume running after can move again [Kevin] if(ud->state.running) { - iTimer->add_timer(ud->canmove_tick, unit_resume_running, bl->id, (intptr_t)ud); + iTimer->add_timer(ud->canmove_tick, unit->resume_running, bl->id, (intptr_t)ud); } else { - unit_stop_walking(bl,2|4); + unit->stop_walking(bl,2|4); if(ud->target) - iTimer->add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target); + iTimer->add_timer(ud->canmove_tick+1, unit->walktobl_sub, bl->id, ud->target); } } } @@ -1087,7 +1089,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui return 0; //Do not continue source is dead sd = BL_CAST(BL_PC, src); - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); if(ud == NULL) return 0; sc = iStatus->get_sc(src); @@ -1234,7 +1236,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui //(these are supposed to always have the same range as your attack) if( src->id != target_id && (!temp || ud->attacktimer == INVALID_TIMER) ) { if( skill->get_state(ud->skill_id) == ST_MOVE_ENABLE ) { - if( !unit_can_reach_bl(src, target, range + 1, 1, NULL, NULL) ) + if( !unit->can_reach_bl(src, target, range + 1, 1, NULL, NULL) ) return 0; // Walk-path check failed. } else if( src->type == BL_MER && skill_id == MA_REMOVETRAP ) { if( !battle->check_range(battle->get_master(src), target, range + 1) ) @@ -1245,7 +1247,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui } if (!temp) //Stop attack on non-combo skills [Skotlex] - unit_stop_attack(src); + unit->stop_attack(src); else if(ud->attacktimer != INVALID_TIMER) //Elsewise, delay current attack sequence ud->attackabletime = tick + status_get_adelay(src); @@ -1349,7 +1351,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui } if(!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 - unit_stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829 + unit->stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829 // in official this is triggered even if no cast time. clif->skillcasting(src, src->id, target_id, 0,0, skill_id, skill->get_ele(skill_id, skill_lv), casttime); @@ -1430,7 +1432,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv) { - return unit_skilluse_pos2( + return unit->skilluse_pos2( src, skill_x, skill_y, skill_id, skill_lv, skill->cast_fix(src, skill_id, skill_lv), skill->get_castcancel(skill_id) @@ -1452,7 +1454,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui if(iStatus->isdead(src)) return 0; sd = BL_CAST(BL_PC, src); - ud = unit_bl2ud(src); + ud = unit->bl2ud(src); if(ud == NULL) return 0; if(ud->skilltimer != INVALID_TIMER) //Normally not needed since clif.c checks for it, but at/char/script commands don't! [Skotlex] @@ -1501,12 +1503,12 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui range = skill->get_range2(src, skill_id, skill_lv); // Skill cast distance from database if( skill->get_state(ud->skill_id) == ST_MOVE_ENABLE ) { - if( !unit_can_reach_bl(src, &bl, range + 1, 1, NULL, NULL) ) + if( !unit->can_reach_bl(src, &bl, range + 1, 1, NULL, NULL) ) return 0; //Walk-path check failed. } else if( !battle->check_range(src, &bl, range + 1) ) return 0; //Arrow-path check failed. - unit_stop_attack(src); + unit->stop_attack(src); // moved here to prevent Suffragium from ending if skill fails #ifndef RENEWAL_CAST @@ -1550,7 +1552,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui } } - unit_stop_walking(src,1); + unit->stop_walking(src,1); // in official this is triggered even if no cast time. clif->skillcasting(src, src->id, 0, skill_x, skill_y, skill_id, skill->get_ele(skill_id, skill_lv), casttime); if( casttime > 0 ) { @@ -1575,9 +1577,9 @@ int unit_set_target(struct unit_data* ud, int target_id) nullpo_ret(ud); if( ud->target != target_id ) { - if( ud->target && (target = iMap->id2bl(ud->target)) && (ux = unit_bl2ud(target)) && ux->target_count > 0 ) + if( ud->target && (target = iMap->id2bl(ud->target)) && (ux = unit->bl2ud(target)) && ux->target_count > 0 ) ux->target_count --; - if( target_id && (target = iMap->id2bl(target_id)) && (ux = unit_bl2ud(target)) ) + if( target_id && (target = iMap->id2bl(target_id)) && (ux = unit->bl2ud(target)) ) ux->target_count ++; } @@ -1587,25 +1589,25 @@ int unit_set_target(struct unit_data* ud, int target_id) int unit_stop_attack(struct block_list *bl) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); nullpo_ret(bl); if(!ud || ud->attacktimer == INVALID_TIMER) return 0; - iTimer->delete_timer( ud->attacktimer, unit_attack_timer ); + iTimer->delete_timer( ud->attacktimer, unit->attack_timer ); ud->attacktimer = INVALID_TIMER; - unit_set_target(ud, 0); + unit->set_target(ud, 0); return 0; } //Means current target is unattackable. For now only unlocks mobs. int unit_unattackable(struct block_list *bl) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); if (ud) { ud->state.attack_continue = 0; - unit_set_target(ud, 0); + unit->set_target(ud, 0); } if(bl->type == BL_MOB) @@ -1624,11 +1626,11 @@ int unit_attack(struct block_list *src,int target_id,int continuous) struct block_list *target; struct unit_data *ud; - nullpo_ret(ud = unit_bl2ud(src)); + nullpo_ret(ud = unit->bl2ud(src)); target = iMap->id2bl(target_id); if( target==NULL || iStatus->isdead(target) ) { - unit_unattackable(src); + unit->unattackable(src); return 1; } @@ -1639,16 +1641,16 @@ int unit_attack(struct block_list *src,int target_id,int continuous) return 0; } if( pc_is90overweight(sd) || pc_isridingwug(sd) ) { // overweight or mounted on warg - stop attacking - unit_stop_attack(src); + unit->stop_attack(src); return 0; } } if( battle->check_target(src,target,BCT_ENEMY) <= 0 || !iStatus->check_skilluse(src, target, 0, 0) ) { - unit_unattackable(src); + unit->unattackable(src); return 1; } ud->state.attack_continue = continuous; - unit_set_target(ud, target_id); + unit->set_target(ud, target_id); if (continuous) //If you're to attack continously, set to auto-case character ud->chaserange = status_get_range(src); @@ -1663,9 +1665,9 @@ int unit_attack(struct block_list *src,int target_id,int continuous) if(DIFF_TICK(ud->attackabletime, iTimer->gettick()) > 0) //Do attack next time it is possible. [Skotlex] - ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit_attack_timer,src->id,0); + ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit->attack_timer,src->id,0); else //Attack NOW. - unit_attack_timer(INVALID_TIMER, iTimer->gettick(), src->id, 0); + unit->attack_timer(INVALID_TIMER, iTimer->gettick(), src->id, 0); return 0; } @@ -1679,7 +1681,7 @@ int unit_cancel_combo(struct block_list *bl) if (!status_change_end(bl, SC_COMBOATTACK, INVALID_TIMER)) return 0; //Combo wasn't active. - ud = unit_bl2ud(bl); + ud = unit->bl2ud(bl); nullpo_ret(ud); ud->attackabletime = iTimer->gettick() + status_get_amotion(bl); @@ -1687,8 +1689,8 @@ int unit_cancel_combo(struct block_list *bl) if (ud->attacktimer == INVALID_TIMER) return 1; //Nothing more to do. - iTimer->delete_timer(ud->attacktimer, unit_attack_timer); - ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit_attack_timer,bl->id,0); + iTimer->delete_timer(ud->attacktimer, unit->attack_timer); + ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit->attack_timer,bl->id,0); return 1; } /*========================================== @@ -1747,7 +1749,7 @@ bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) { int dx, dy, x, y, i, k; - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); nullpo_ret(ud); if(dir > 7) @@ -1762,11 +1764,11 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) x = tx + dx; y = ty + dy; - if( !unit_can_reach_pos(bl, x, y, 0) ) + if( !unit->can_reach_pos(bl, x, y, 0) ) { if( dx > 0 ) x--; else if( dx < 0 ) x++; if( dy > 0 ) y--; else if( dy < 0 ) y++; - if( !unit_can_reach_pos(bl, x, y, 0) ) + if( !unit->can_reach_pos(bl, x, y, 0) ) { for( i = 0; i < 12; i++ ) { @@ -1775,20 +1777,20 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) dy = -diry[k] * 2; x = tx + dx; y = ty + dy; - if( unit_can_reach_pos(bl, x, y, 0) ) + if( unit->can_reach_pos(bl, x, y, 0) ) break; else { if( dx > 0 ) x--; else if( dx < 0 ) x++; if( dy > 0 ) y--; else if( dy < 0 ) y++; - if( unit_can_reach_pos(bl, x, y, 0) ) + if( unit->can_reach_pos(bl, x, y, 0) ) break; } } if( i == 12 ) { x = tx; y = tx; // Exactly Master Position - if( !unit_can_reach_pos(bl, x, y, 0) ) + if( !unit->can_reach_pos(bl, x, y, 0) ) return 1; } } @@ -1802,7 +1804,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) /*========================================== * Continuous Attack (function timer) *------------------------------------------*/ -static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick) +int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick) { struct block_list *target; struct unit_data *ud; @@ -1811,7 +1813,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t struct mob_data *md = NULL; int range; - if( (ud=unit_bl2ud(src))==NULL ) + if( (ud=unit->bl2ud(src))==NULL ) return 0; if( ud->attacktimer != tid ) { @@ -1855,7 +1857,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t if( ud->state.attack_continue ) { if( DIFF_TICK(ud->canact_tick, ud->attackabletime) > 0 ) ud->attackabletime = ud->canact_tick; - ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit_attack_timer,src->id,0); + ud->attacktimer=iTimer->add_timer(ud->attackabletime,unit->attack_timer,src->id,0); } return 1; } @@ -1863,20 +1865,20 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t sstatus = iStatus->get_status_data(src); range = sstatus->rhw.range + 1; - if( unit_is_walking(target) ) + if( unit->is_walking(target) ) range++; //Extra range when chasing if( !check_distance_bl(src,target,range) ) { //Chase if required. if(sd) clif->movetoattack(sd,target); else if(ud->state.attack_continue) - unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2); + unit->walktobl(src,target,ud->chaserange,ud->state.walk_easy|2); return 1; } if( !battle->check_range(src,target,range) ) { //Within range, but no direct line of attack if( ud->state.attack_continue ) { if(ud->chaserange > 2) ud->chaserange-=2; - unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2); + unit->walktobl(src,target,ud->chaserange,ud->state.walk_easy|2); } return 1; } @@ -1890,7 +1892,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t ud->dir = iMap->calc_dir(src, target->x,target->y ); } if(ud->walktimer != INVALID_TIMER) - unit_stop_walking(src,1); + unit->stop_walking(src,1); if(md) { if (mob->skill_use(md,tick,-1)) return 1; @@ -1919,24 +1921,24 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t ud->attackabletime = tick + sstatus->adelay; // You can't move if you can't attack neither. if (src->type&battle_config.attack_walk_delay) - unit_set_walkdelay(src, tick, sstatus->amotion, 1); + unit->set_walkdelay(src, tick, sstatus->amotion, 1); } if(ud->state.attack_continue) { if( src->type == BL_PC ) ((TBL_PC*)src)->idletime = last_tick; - ud->attacktimer = iTimer->add_timer(ud->attackabletime,unit_attack_timer,src->id,0); + ud->attacktimer = iTimer->add_timer(ud->attackabletime,unit->attack_timer,src->id,0); } return 1; } -static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) +int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) { struct block_list *bl; bl = iMap->id2bl(id); - if(bl && unit_attack_timer_sub(bl, tid, tick) == 0) - unit_unattackable(bl); + if(bl && unit->attack_timer_sub(bl, tid, tick) == 0) + unit->unattackable(bl); return 0; } @@ -1948,7 +1950,7 @@ static int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) int unit_skillcastcancel(struct block_list *bl,int type) { struct map_session_data *sd = NULL; - struct unit_data *ud = unit_bl2ud( bl); + struct unit_data *ud = unit->bl2ud( bl); unsigned int tick=iTimer->gettick(); int ret=0, skill_id; @@ -2004,7 +2006,7 @@ int unit_skillcastcancel(struct block_list *bl,int type) // unit_data initialization process void unit_dataset(struct block_list *bl) { struct unit_data *ud; - nullpo_retv(ud = unit_bl2ud(bl)); + nullpo_retv(ud = unit->bl2ud(bl)); memset( ud, 0, sizeof( struct unit_data) ); ud->bl = bl; @@ -2022,7 +2024,7 @@ void unit_dataset(struct block_list *bl) { int unit_counttargeted(struct block_list* bl) { struct unit_data* ud; - if( bl && (ud = unit_bl2ud(bl)) ) + if( bl && (ud = unit->bl2ud(bl)) ) return ud->target_count; return 0; } @@ -2067,9 +2069,9 @@ int unit_changeviewsize(struct block_list *bl,short size) * Otherwise it is assumed bl is being warped. * On-Kill specific stuff is not performed here, look at iStatus->damage for that. *------------------------------------------*/ -int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func) +int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func) { - struct unit_data *ud = unit_bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); struct status_change *sc = iStatus->get_sc(bl); nullpo_ret(ud); @@ -2078,14 +2080,14 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, iMap->freeblock_lock(); - unit_set_target(ud, 0); + unit->set_target(ud, 0); if (ud->walktimer != INVALID_TIMER) - unit_stop_walking(bl,0); + unit->stop_walking(bl,0); if (ud->attacktimer != INVALID_TIMER) - unit_stop_attack(bl); + unit->stop_attack(bl); if (ud->skilltimer != INVALID_TIMER) - unit_skillcastcancel(bl,0); + unit->skillcastcancel(bl,0); // Do not reset can-act delay. [Skotlex] ud->attackabletime = ud->canmove_tick /*= ud->canact_tick*/ = iTimer->gettick(); @@ -2233,10 +2235,10 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, case BL_PET: { struct pet_data *pd = (struct pet_data*)bl; if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) ) - { //If logging out, this is deleted on unit_free + { //If logging out, this is deleted on unit->free clif->clearunit_area(bl,clrtype); iMap->delblock(bl); - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); iMap->freeblock_unlock(); return 0; } @@ -2247,11 +2249,11 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, struct homun_data *hd = (struct homun_data *)bl; ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick. if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) ) - { //If logging out, this is deleted on unit_free + { //If logging out, this is deleted on unit->free clif->emotion(bl, E_SOB); clif->clearunit_area(bl,clrtype); iMap->delblock(bl); - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); iMap->freeblock_unlock(); return 0; } @@ -2264,7 +2266,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, { clif->clearunit_area(bl,clrtype); iMap->delblock(bl); - unit_free(bl,CLR_OUTSIGHT); + unit->free(bl,CLR_OUTSIGHT); iMap->freeblock_unlock(); return 0; } @@ -2277,7 +2279,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, { clif->clearunit_area(bl,clrtype); iMap->delblock(bl); - unit_free(bl,0); + unit->free(bl,0); iMap->freeblock_unlock(); return 0; } @@ -2297,27 +2299,27 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, void unit_remove_map_pc(struct map_session_data *sd, clr_type clrtype) { - unit_remove_map(&sd->bl,clrtype); + unit->remove_map(&sd->bl,clrtype,ALC_MARK); if (clrtype == CLR_TELEPORT) clrtype = CLR_OUTSIGHT; //CLR_TELEPORT is the warp from logging out, but pets/homunc need to just 'vanish' instead of showing the warping out animation. if(sd->pd) - unit_remove_map(&sd->pd->bl, clrtype); + unit->remove_map(&sd->pd->bl, clrtype, ALC_MARK); if(homun_alive(sd->hd)) - unit_remove_map(&sd->hd->bl, clrtype); + unit->remove_map(&sd->hd->bl, clrtype, ALC_MARK); if(sd->md) - unit_remove_map(&sd->md->bl, clrtype); + unit->remove_map(&sd->md->bl, clrtype, ALC_MARK); if(sd->ed) - unit_remove_map(&sd->ed->bl, clrtype); + unit->remove_map(&sd->ed->bl, clrtype, ALC_MARK); } void unit_free_pc(struct map_session_data *sd) { - if (sd->pd) unit_free(&sd->pd->bl,CLR_OUTSIGHT); - if (sd->hd) unit_free(&sd->hd->bl,CLR_OUTSIGHT); - if (sd->md) unit_free(&sd->md->bl,CLR_OUTSIGHT); - if (sd->ed) unit_free(&sd->ed->bl,CLR_OUTSIGHT); - unit_free(&sd->bl,CLR_TELEPORT); + if (sd->pd) unit->free(&sd->pd->bl,CLR_OUTSIGHT); + if (sd->hd) unit->free(&sd->hd->bl,CLR_OUTSIGHT); + if (sd->md) unit->free(&sd->md->bl,CLR_OUTSIGHT); + if (sd->ed) unit->free(&sd->ed->bl,CLR_OUTSIGHT); + unit->free(&sd->bl,CLR_TELEPORT); } /*========================================== @@ -2326,12 +2328,12 @@ void unit_free_pc(struct map_session_data *sd) *------------------------------------------*/ int unit_free(struct block_list *bl, clr_type clrtype) { - struct unit_data *ud = unit_bl2ud( bl ); + struct unit_data *ud = unit->bl2ud( bl ); nullpo_ret(ud); iMap->freeblock_lock(); if( bl->prev ) //Players are supposed to logout with a "warp" effect. - unit_remove_map(bl, clrtype); + unit->remove_map(bl, clrtype, ALC_MARK); switch( bl->type ) { case BL_PC: @@ -2590,17 +2592,67 @@ int unit_free(struct block_list *bl, clr_type clrtype) return 0; } -int do_init_unit(void) -{ - iTimer->add_timer_func_list(unit_attack_timer, "unit_attack_timer"); - iTimer->add_timer_func_list(unit_walktoxy_timer,"unit_walktoxy_timer"); - iTimer->add_timer_func_list(unit_walktobl_sub, "unit_walktobl_sub"); - iTimer->add_timer_func_list(unit_delay_walktoxy_timer,"unit_delay_walktoxy_timer"); +int do_init_unit(void) { + iTimer->add_timer_func_list(unit->attack_timer, "unit_attack_timer"); + iTimer->add_timer_func_list(unit->walktoxy_timer,"unit_walktoxy_timer"); + iTimer->add_timer_func_list(unit->walktobl_sub, "unit_walktobl_sub"); + iTimer->add_timer_func_list(unit->delay_walktoxy_timer,"unit_delay_walktoxy_timer"); return 0; } -int do_final_unit(void) -{ +int do_final_unit(void) { // nothing to do return 0; } + +void unit_defaults(void) { + unit = &unit_s; + + unit->init = do_init_unit; + unit->final = do_final_unit; + /* */ + unit->bl2ud = unit_bl2ud; + unit->bl2ud2 = unit_bl2ud2; + unit->attack_timer = unit_attack_timer; + unit->walktoxy_timer = unit_walktoxy_timer; + unit->walktoxy_sub = unit_walktoxy_sub; + unit->delay_walktoxy_timer = unit_delay_walktoxy_timer; + unit->walktoxy = unit_walktoxy; + unit->walktobl_sub = unit_walktobl_sub; + unit->walktobl = unit_walktobl; + unit->run = unit_run; + unit->wugdash = unit_wugdash; + unit->escape = unit_escape; + unit->movepos = unit_movepos; + unit->setdir = unit_setdir; + unit->getdir = unit_getdir; + unit->blown = unit_blown; + unit->warp = unit_warp; + unit->stop_walking = unit_stop_walking; + unit->skilluse_id = unit_skilluse_id; + unit->is_walking = unit_is_walking; + unit->can_move = unit_can_move; + unit->resume_running = unit_resume_running; + unit->set_walkdelay = unit_set_walkdelay; + unit->skilluse_id2 = unit_skilluse_id2; + unit->skilluse_pos = unit_skilluse_pos; + unit->skilluse_pos2 = unit_skilluse_pos2; + unit->set_target = unit_set_target; + unit->stop_attack = unit_stop_attack; + unit->unattackable = unit_unattackable; + unit->attack = unit_attack; + unit->cancel_combo = unit_cancel_combo; + unit->can_reach_pos = unit_can_reach_pos; + unit->can_reach_bl = unit_can_reach_bl; + unit->calc_pos = unit_calc_pos; + unit->attack_timer_sub = unit_attack_timer_sub; + unit->skillcastcancel = unit_skillcastcancel; + unit->dataset = unit_dataset; + unit->counttargeted = unit_counttargeted; + unit->fixdamage = unit_fixdamage; + unit->changeviewsize = unit_changeviewsize; + unit->remove_map = unit_remove_map; + unit->remove_map_pc = unit_remove_map_pc; + unit->free_pc = unit_free_pc; + unit->free = unit_free; +} diff --git a/src/map/unit.h b/src/map/unit.h index b743fc8cb..be7b789d9 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -68,79 +68,61 @@ struct view_data { unsigned dead_sit : 2; }; -// PC, MOB, PET ɋʂ鏈P‚ɂ܂Ƃ߂v - -// sJn -// ߂ĺA0 ( ), 1 ( s ) -int unit_walktoxy( struct block_list *bl, short x, short y, int easy); -int unit_walktobl( struct block_list *bl, struct block_list *target, int range, int easy); -int unit_run(struct block_list *bl); -int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir); - -// s~ -// type͈ȉ̑gݍ킹 : -// 1: ʒȗM( ̊֐̌Ɉʒu𑗐Mꍇ͕sv ) -// 2: _[WfBCL -// 4: s(MOB̂݁H) -int unit_stop_walking(struct block_list *bl,int type); -int unit_can_move(struct block_list *bl); -int unit_is_walking(struct block_list *bl); -int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type); - -int unit_escape(struct block_list *bl, struct block_list *target, short dist); -// ʒűړ(΂Ȃ) -int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath); -int unit_warp(struct block_list *bl, short map, short x, short y, clr_type type); -int unit_setdir(struct block_list *bl,unsigned char dir); -uint8 unit_getdir(struct block_list *bl); -int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag); - -// ܂ŕsłǂ蒅邩̔ -bool unit_can_reach_pos(struct block_list *bl,int x,int y,int easy); -bool unit_can_reach_bl(struct block_list *bl,struct block_list *tbl, int range, int easy, short *x, short *y); - -// U֘A -int unit_stop_attack(struct block_list *bl); -int unit_attack(struct block_list *src,int target_id,int continuous); -int unit_cancel_combo(struct block_list *bl); - -// XLgp -int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv); -int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv); - -// XLgp( ␳ς݃LXgԁALZsݒt ) -int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); -int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); - -// rLZ -int unit_skillcastcancel(struct block_list *bl,int type); - -int unit_counttargeted(struct block_list *bl); -int unit_set_target(struct unit_data* ud, int target_id); - -// unit_data ̏ -void unit_dataset(struct block_list *bl); +extern const short dirx[8]; +extern const short diry[8]; -int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int64 damage,int div,int type,int64 damage2); -// ̑ -struct unit_data* unit_bl2ud(struct block_list *bl); -struct unit_data* unit_bl2ud2(struct block_list *bl); -void unit_remove_map_pc(struct map_session_data *sd, clr_type clrtype); -void unit_free_pc(struct map_session_data *sd); -#define unit_remove_map(bl,clrtype) unit_remove_map_(bl,clrtype,__FILE__,__LINE__,__func__) -int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func); -int unit_free(struct block_list *bl, clr_type clrtype); -int unit_changeviewsize(struct block_list *bl,short size); +struct unit_interface { + int (*init) (void); + int (*final) (void); + /* */ + struct unit_data* (*bl2ud) (struct block_list *bl); + struct unit_data* (*bl2ud2) (struct block_list *bl); + int (*attack_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*walktoxy_sub) (struct block_list *bl); + int (*delay_walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*walktoxy) (struct block_list *bl, short x, short y, int flag); + int (*walktobl_sub) (int tid, unsigned int tick, int id, intptr_t data); + int (*walktobl) (struct block_list *bl, struct block_list *tbl, int range, int flag); + int (*run) (struct block_list *bl); + int (*wugdash) (struct block_list *bl, struct map_session_data *sd); + int (*escape) (struct block_list *bl, struct block_list *target, short dist); + int (*movepos) (struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath); + int (*setdir) (struct block_list *bl, unsigned char dir); + uint8 (*getdir) (struct block_list *bl); + int (*blown) (struct block_list *bl, int dx, int dy, int count, int flag); + int (*warp) (struct block_list *bl, short m, short x, short y, clr_type type); + int (*stop_walking) (struct block_list *bl, int type); + int (*skilluse_id) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv); + int (*is_walking) (struct block_list *bl); + int (*can_move) (struct block_list *bl); + int (*resume_running) (int tid, unsigned int tick, int id, intptr_t data); + int (*set_walkdelay) (struct block_list *bl, unsigned int tick, int delay, int type); + int (*skilluse_id2) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); + int (*skilluse_pos) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv); + int (*skilluse_pos2) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); + int (*set_target) (struct unit_data *ud, int target_id); + int (*stop_attack) (struct block_list *bl); + int (*unattackable) (struct block_list *bl); + int (*attack) (struct block_list *src, int target_id, int continuous); + int (*cancel_combo) (struct block_list *bl); + bool (*can_reach_pos) (struct block_list *bl, int x, int y, int easy); + bool (*can_reach_bl) (struct block_list *bl, struct block_list *tbl, int range, int easy, short *x, short *y); + int (*calc_pos) (struct block_list *bl, int tx, int ty, uint8 dir); + int (*attack_timer_sub) (struct block_list *src, int tid, unsigned int tick); + int (*skillcastcancel) (struct block_list *bl, int type); + void (*dataset) (struct block_list *bl); + int (*counttargeted) (struct block_list *bl); + int (*fixdamage) (struct block_list *src, struct block_list *target, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2); + int (*changeviewsize) (struct block_list *bl, short size); + int (*remove_map) (struct block_list *bl, clr_type clrtype, const char *file, int line, const char *func); + void (*remove_map_pc) (struct map_session_data *sd, clr_type clrtype); + void (*free_pc) (struct map_session_data *sd); + int (*free) (struct block_list *bl, clr_type clrtype); +}; -// [` -int do_init_unit(void); -int do_final_unit(void); -/** - * Ranger - **/ -int unit_wugdash(struct block_list *bl, struct map_session_data *sd); +struct unit_interface *unit; -extern const short dirx[8]; -extern const short diry[8]; +void unit_defaults(void); #endif /* _UNIT_H_ */ -- cgit v1.2.3-60-g2f50