summaryrefslogtreecommitdiff
path: root/src/map/unit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/unit.c')
-rw-r--r--src/map/unit.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/src/map/unit.c b/src/map/unit.c
index a879a125f..a6afb5ee7 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -96,6 +96,8 @@ static struct unit_data *unit_bl2ud(struct block_list *bl)
return &BL_UCAST(BL_MER, bl)->ud;
case BL_ELEM:
return &BL_UCAST(BL_ELEM, bl)->ud;
+ case BL_SKILL: // No assertion to not spam the server console when attacking a skill type unit such as Ice Wall.
+ return NULL;
default:
Assert_retr(NULL, false);
}
@@ -128,6 +130,8 @@ static const struct unit_data *unit_cbl2ud(const struct block_list *bl)
return &BL_UCCAST(BL_MER, bl)->ud;
case BL_ELEM:
return &BL_UCCAST(BL_ELEM, bl)->ud;
+ case BL_SKILL: // No assertion to not spam the server console when attacking a skill type unit such as Ice Wall.
+ return NULL;
default:
Assert_retr(NULL, false);
}
@@ -326,7 +330,7 @@ static int unit_warpto_master(struct block_list *master_bl, struct block_list *s
static int unit_walk_toxy_timer(int tid, int64 tick, int id, intptr_t data)
{
struct block_list *bl = map->id2bl(id);
- if (bl == NULL || bl->prev == NULL) // Stop moved because it is missing from the block_list
+ if (bl == NULL)
return 1;
struct unit_data *ud = unit->bl2ud(bl);
if (ud == NULL)
@@ -336,8 +340,12 @@ static int unit_walk_toxy_timer(int tid, int64 tick, int id, intptr_t data)
ShowError("unit_walk_timer mismatch %d != %d\n",ud->walktimer,tid);
return 1;
}
+
ud->walktimer = INVALID_TIMER;
+ if (bl->prev == NULL) // Stop moved because it is missing from the block_list.
+ return 1;
+
if (ud->walkpath.path_pos >= ud->walkpath.path_len)
return 1;
@@ -428,7 +436,7 @@ static int unit_walk_toxy_timer(int tid, int64 tick, int id, intptr_t data)
// Walk skills are triggered regardless of target due to the idle-walk mob state.
// But avoid triggering on stop-walk calls.
if (tid != INVALID_TIMER && (ud->walk_count % WALK_SKILL_INTERVAL) == 0
- && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 1) {
+ && map->list[bl->m].users > 0 && mob->skill_use(md, tick, -1) == 0) {
// Walk skills are supposed to be used while walking
if (!(ud->skill_id == NPC_SELFDESTRUCTION && ud->skilltimer != INVALID_TIMER)
&& md->state.skillstate != MSS_WALK) {
@@ -898,7 +906,7 @@ static int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int eas
} else
npc->untouch_areanpc(sd, bl->m, bl->x, bl->y);
- if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
+ if (sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > PET_INTIMACY_NONE)
{ // Check if pet needs to be teleported. [Skotlex]
int flag = 0;
struct block_list* pbl = &sd->pd->bl;
@@ -1144,12 +1152,13 @@ static int unit_stop_walking(struct block_list *bl, int flag)
static int unit_skilluse_id(struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv)
{
int casttime = skill->cast_fix(src, skill_id, skill_lv);
- int castcancel = skill->get_castcancel(skill_id);
+ int castcancel = skill->get_castcancel(skill_id, skill_lv);
int ret = unit->skilluse_id2(src, target_id, skill_id, skill_lv, casttime, castcancel);
struct map_session_data *sd = BL_CAST(BL_PC, src);
- if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv)))
- pc->itemskill_clear(sd);
+ if (sd != NULL)
+ pc->autocast_remove(sd, sd->auto_cast_current.type, sd->auto_cast_current.skill_id,
+ sd->auto_cast_current.skill_lv);
return ret;
}
@@ -1558,7 +1567,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill
//Check range when not using skill on yourself or is a combo-skill during attack
//(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 (skill->get_state(ud->skill_id, ud->skill_lv) == ST_MOVE_ENABLE) {
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 ) {
@@ -1708,7 +1717,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill
if (!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026
unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);// even though this is not how official works but this will do the trick. bugreport:6829
- if (sd != NULL && sd->state.itemskill_no_casttime == 1 && skill->is_item_skill(sd, skill_id, skill_lv))
+ if (sd != NULL && sd->auto_cast_current.itemskill_instant_cast && sd->auto_cast_current.type == AUTOCAST_ITEM)
casttime = 0;
// in official this is triggered even if no cast time.
@@ -1746,7 +1755,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill
if( casttime <= 0 )
ud->state.skillcastcancel = 0;
- if( !sd || sd->skillitem != skill_id || skill->get_cast(skill_id,skill_lv) )
+ if (sd == NULL || sd->auto_cast_current.type < AUTOCAST_ABRA || skill->get_cast(skill_id, skill_lv) != 0)
ud->canact_tick = tick + casttime + 100;
if( sd )
{
@@ -1781,12 +1790,13 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill
static int unit_skilluse_pos(struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv)
{
int casttime = skill->cast_fix(src, skill_id, skill_lv);
- int castcancel = skill->get_castcancel(skill_id);
+ int castcancel = skill->get_castcancel(skill_id, skill_lv);
int ret = unit->skilluse_pos2(src, skill_x, skill_y, skill_id, skill_lv, casttime, castcancel);
struct map_session_data *sd = BL_CAST(BL_PC, src);
- if (sd != NULL && (ret == 0 || !skill->is_item_skill(sd, skill_id, skill_lv)))
- pc->itemskill_clear(sd);
+ if (sd != NULL)
+ pc->autocast_remove(sd, sd->auto_cast_current.type, sd->auto_cast_current.skill_id,
+ sd->auto_cast_current.skill_lv);
return ret;
}
@@ -1862,7 +1872,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill
return 0; // Attacking will be handled by unit_walk_toxy_timer in this case
}
- if( skill->get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
+ if (skill->get_state(ud->skill_id, ud->skill_lv) == ST_MOVE_ENABLE) {
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) )
@@ -1883,7 +1893,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill
}
ud->state.skillcastcancel = castcancel&&casttime>0?1:0;
- if( !sd || sd->skillitem != skill_id || skill->get_cast(skill_id,skill_lv) )
+ if (sd == NULL || sd->auto_cast_current.type < AUTOCAST_ABRA || skill->get_cast(skill_id, skill_lv) != 0)
ud->canact_tick = tick + casttime + 100;
#if 0
if (sd) {
@@ -1914,7 +1924,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill
unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);
- if (sd != NULL && sd->state.itemskill_no_casttime == 1 && skill->is_item_skill(sd, skill_id, skill_lv))
+ if (sd != NULL && sd->auto_cast_current.itemskill_instant_cast && sd->auto_cast_current.type == AUTOCAST_ITEM)
casttime = 0;
// in official this is triggered even if no cast time.
@@ -2333,7 +2343,7 @@ static int unit_attack_timer_sub(struct block_list *src, int tid, int64 tick)
if(md) {
//First attack is always a normal attack
if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) {
- if (mob->skill_use(md,tick,-1)) {
+ if (mob->skill_use(md, tick, -1) == 0) {
map->freeblock_unlock();
return 1;
}
@@ -2718,7 +2728,7 @@ static int unit_remove_map(struct block_list *bl, enum clr_type clrtype, const c
case BL_PET:
{
struct pet_data *pd = BL_UCAST(BL_PET, bl);
- if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) ) {
+ if (pd->pet.intimate <= PET_INTIMACY_NONE && !(pd->msd && !pd->msd->state.active)) {
//If logging out, this is deleted on unit->free
clif->clearunit_area(bl,clrtype);
map->delblock(bl);
@@ -2877,6 +2887,8 @@ static int unit_free(struct block_list *bl, enum clr_type clrtype)
aFree(sd->instance);
sd->instance = NULL;
}
+
+ VECTOR_CLEAR(sd->auto_cast); // Clear auto-cast vector.
VECTOR_CLEAR(sd->channels);
VECTOR_CLEAR(sd->script_queues);
VECTOR_CLEAR(sd->achievement); // Achievement [Smokexyz/Hercules]
@@ -2932,7 +2944,7 @@ static int unit_free(struct block_list *bl, enum clr_type clrtype)
aFree (pd->loot);
pd->loot = NULL;
}
- if (pd->pet.intimate > 0) {
+ if (pd->pet.intimate > PET_INTIMACY_NONE) {
intif->save_petdata(pd->pet.account_id,&pd->pet);
} else {
//Remove pet.