summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/battle.c24
-rw-r--r--src/map/clif.c48
-rw-r--r--src/map/elemental.c1969
-rw-r--r--src/map/elemental.h206
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/homunculus.c16
-rw-r--r--src/map/instance.c2
-rw-r--r--src/map/map.c20
-rw-r--r--src/map/mercenary.c8
-rw-r--r--src/map/mob.c68
-rw-r--r--src/map/mob.h4
-rw-r--r--src/map/npc.c6
-rw-r--r--src/map/pc.c14
-rw-r--r--src/map/pc.h4
-rw-r--r--src/map/pet.c34
-rw-r--r--src/map/pet.h4
-rw-r--r--src/map/script.c44
-rw-r--r--src/map/skill.c206
-rw-r--r--src/map/status.c80
-rw-r--r--src/map/unit.c356
-rw-r--r--src/map/unit.h124
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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+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;i<MAX_SKILLUNITGROUP && ud->skillunit[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;i<MAX_SKILLTIMERSKILL;i++) {
@@ -3579,7 +3579,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
uint8 dir = iMap->calc_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;i<c;i++){
- if (!skill->blown(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_ */