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.c171
1 files changed, 85 insertions, 86 deletions
diff --git a/src/map/unit.c b/src/map/unit.c
index b195d3c91..47cf07ef6 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -82,9 +82,6 @@ struct unit_data* unit_bl2ud2(struct block_list *bl) {
return unit->bl2ud(bl);
}
-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)
{
int i;
@@ -137,7 +134,7 @@ int unit_walktoxy_sub(struct block_list *bl)
return 1;
}
-int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
int i;
int x,y,dx,dy;
uint8 dir;
@@ -207,23 +204,28 @@ int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
} else
sd->areanpc_id=0;
- if( sd->md && !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) )
- {
- // mercenary should be warped after being 3 seconds too far from the master [greenbox]
- if (sd->md->masterteleport_timer == 0)
- {
- sd->md->masterteleport_timer = timer->gettick();
- }
- else if (DIFF_TICK(timer->gettick(), sd->md->masterteleport_timer) > 3000)
- {
+ if( sd->md ) { // mercenary should be warped after being 3 seconds too far from the master [greenbox]
+ if( !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) ) {
+ if (sd->md->masterteleport_timer == 0)
+ sd->md->masterteleport_timer = timer->gettick();
+ else if (DIFF_TICK(timer->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 );
+ }
+ } else // reset the tick, he is not far anymore
sd->md->masterteleport_timer = 0;
- unit->warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT );
- }
+
}
- else if( sd->md )
- {
- // reset the tick, he is not far anymore
- sd->md->masterteleport_timer = 0;
+ if( sd->hd ) {
+ if( homun_alive(sd->hd) && !check_distance_bl(&sd->bl, &sd->hd->bl, MAX_MER_DISTANCE) ) {
+ if (sd->hd->masterteleport_timer == 0)
+ sd->hd->masterteleport_timer = timer->gettick();
+ else if (DIFF_TICK(timer->gettick(), sd->hd->masterteleport_timer) > 3000) {
+ sd->hd->masterteleport_timer = 0;
+ unit->warp( &sd->hd->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT );
+ }
+ } else
+ sd->hd->masterteleport_timer = 0;
}
} else if (md) {
if( map->getcell(bl->m,x,y,CELL_CHKNPC) ) {
@@ -322,7 +324,7 @@ int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
-int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_delay_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = map->id2bl(id);
if (!bl || bl->prev == NULL)
@@ -375,7 +377,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
unit->set_target(ud, 0);
sc = status->get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position
map->random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) {
@@ -402,7 +404,7 @@ static inline void set_mobstate(struct block_list* bl, int flag)
md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH;
}
-int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_walktobl_sub(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = map->id2bl(id);
struct unit_data *ud = bl?unit->bl2ud(bl):NULL;
@@ -447,7 +449,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
unit->set_target(ud, 0);
sc = status->get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position
map->random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) {
@@ -668,15 +670,15 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
{ // Check if pet needs to be teleported. [Skotlex]
int flag = 0;
- struct block_list* bl = &sd->pd->bl;
- if( !checkpath && !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
+ struct block_list* pbl = &sd->pd->bl;
+ if( !checkpath && !path->search(NULL,pbl->m,pbl->x,pbl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
flag = 1;
- else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport.
+ else if (!check_distance_bl(&sd->bl, pbl, AREA_SIZE)) //Too far, teleport.
flag = 2;
if( flag )
{
- unit->movepos(bl,sd->bl.x,sd->bl.y, 0, 0);
- clif->slide(bl,bl->x,bl->y);
+ unit->movepos(pbl,sd->bl.x,sd->bl.y, 0, 0);
+ clif->slide(pbl,pbl->x,pbl->y);
}
}
}
@@ -718,6 +720,8 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)
struct skill_unit* su = NULL;
int nx, ny, result;
+ nullpo_ret(bl);
+
sd = BL_CAST(BL_PC, bl);
su = BL_CAST(BL_SKILL, bl);
@@ -854,7 +858,7 @@ int unit_stop_walking(struct block_list *bl,int type)
{
struct unit_data *ud;
const struct TimerData* td;
- unsigned int tick;
+ int64 tick;
nullpo_ret(bl);
ud = unit->bl2ud(bl);
@@ -964,7 +968,7 @@ int unit_can_move(struct block_list *bl) {
|| sc->data[SC_CURSEDCIRCLE_ATKER]
|| sc->data[SC_CURSEDCIRCLE_TARGET]
|| (sc->data[SC_COLD] && bl->type != BL_MOB)
- || sc->data[SC_NETHERWORLD]
+ || sc->data[SC_DEEP_SLEEP]
|| (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3 && !(sc->data[SC_CAMOUFLAGE]->val3&1))
|| sc->data[SC_MEIKYOUSISUI]
|| sc->data[SC_KG_KAGEHUMI]
@@ -1001,17 +1005,17 @@ int unit_can_move(struct block_list *bl) {
* Resume running after a walk delay
*------------------------------------------*/
-int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_resume_running(int tid, int64 tick, int id, intptr_t data) {
struct unit_data *ud = (struct unit_data *)data;
TBL_PC * sd = map->id2sd(id);
if(sd && pc_isridingwug(sd))
clif->skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skill_lv,
- sc_start4(ud->bl,status->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1));
+ sc_start4(ud->bl,ud->bl,status->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,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0));
+ sc_start4(ud->bl,ud->bl,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0));
if (sd) clif->walkok(sd);
@@ -1025,8 +1029,7 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) {
* if type is 0, this is a damage induced delay: if previous delay is active, do not change it.
* if type is 1, this is a skill induced delay: walk-delay may only be increased, not decreased.
*------------------------------------------*/
-int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type)
-{
+int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) {
struct unit_data *ud = unit->bl2ud(bl);
if (delay <= 0 || !ud) return 0;
@@ -1073,7 +1076,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
struct status_change *sc;
struct map_session_data *sd = NULL;
struct block_list * target = NULL;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int temp = 0, range;
nullpo_ret(src);
@@ -1342,6 +1345,19 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
casttime = 0;
}
+ if( sc ) {
+ /**
+ * why the if else chain: these 3 status do not stack, so its efficient that way.
+ **/
+ if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_id != AS_CLOAKING ) {
+ status_change_end(src, SC_CLOAKING, INVALID_TIMER);
+ if (!src->prev) return 0; //Warped away!
+ } else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_id != GC_CLOAKINGEXCEED ) {
+ status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER);
+ if (!src->prev) return 0;
+ }
+ }
+
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
@@ -1398,20 +1414,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
ud->skill_id = skill_id;
ud->skill_lv = skill_lv;
- if( sc ) {
- /**
- * why the if else chain: these 3 status do not stack, so its efficient that way.
- **/
- if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_id != AS_CLOAKING ) {
- status_change_end(src, SC_CLOAKING, INVALID_TIMER);
- if (!src->prev) return 0; //Warped away!
- } else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_id != GC_CLOAKINGEXCEED ) {
- status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER);
- if (!src->prev) return 0;
- }
- }
-
-
if( casttime > 0 ) {
ud->skilltimer = timer->add( tick+casttime, skill->castend_id, src->id, 0 );
if( sd && (pc->checkskill(sd,SA_FREECAST) > 0 || skill_id == LG_EXEEDBREAK) )
@@ -1437,7 +1439,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
struct unit_data *ud = NULL;
struct status_change *sc;
struct block_list bl;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int range;
nullpo_ret(src);
@@ -1468,10 +1470,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
- if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map->getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
}
if (!status->check_skilluse(src, NULL, skill_id, 0))
@@ -1795,8 +1793,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir)
/*==========================================
* Continuous Attack (function timer)
*------------------------------------------*/
-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, int64 tick) {
struct block_list *target;
struct unit_data *ud;
struct status_data *sstatus;
@@ -1915,15 +1912,15 @@ int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
}
if(ud->state.attack_continue) {
- if( src->type == BL_PC )
- ((TBL_PC*)src)->idletime = last_tick;
+ if( src->type == BL_PC && battle_config.idletime_criteria & BCIDLE_ATTACK )
+ ((TBL_PC*)src)->idletime = sockt->last_tick;
ud->attacktimer = timer->add(ud->attackabletime,unit->attack_timer,src->id,0);
}
return 1;
}
-int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_attack_timer(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl;
bl = map->id2bl(id);
if(bl && unit->attack_timer_sub(bl, tid, tick) == 0)
@@ -1940,7 +1937,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
{
struct map_session_data *sd = NULL;
struct unit_data *ud = unit->bl2ud( bl);
- unsigned int tick=timer->gettick();
+ int64 tick = timer->gettick();
int ret=0, skill_id;
nullpo_ret(bl);
@@ -1955,7 +1952,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
return 0;
if (sd && (sd->special_state.no_castcancel2 ||
- ((sd->sc.data[SC_UNLIMITED_HUMMING_VOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
+ ( sd->special_state.no_castcancel && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
return 0;
}
@@ -1971,7 +1968,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
else
ret = timer->delete( ud->skilltimer, skill->castend_id );
if( ret < 0 )
- ShowError("delete timer error : skill_id : %d\n",ret);
+ ShowError("delete timer error %d : skill %d (%s)\n",ret,skill_id,skill->get_name(skill_id));
ud->skilltimer = INVALID_TIMER;
@@ -2021,14 +2018,13 @@ int unit_counttargeted(struct block_list* bl)
/*==========================================
*
*------------------------------------------*/
-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)
-{
+int unit_fixdamage(struct block_list *src, struct block_list *target, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2) {
nullpo_ret(target);
if(damage+damage2 <= 0)
return 0;
- return status_fix_damage(src,target,damage+damage2,clif->damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2));
+ return status_fix_damage(src,target,damage+damage2,clif->damage(target,target,sdelay,ddelay,damage,div,type,damage2));
}
/*==========================================
@@ -2106,6 +2102,11 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
status_change_end(bl, SC_STOP, INVALID_TIMER);
status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC_MAGNETICFIELD, INVALID_TIMER);
+ status_change_end(bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER);
+ status_change_end(bl, SC_NEUTRALBARRIER, INVALID_TIMER);
+ status_change_end(bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER);
+ status_change_end(bl, SC_STEALTHFIELD, INVALID_TIMER);
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
@@ -2200,6 +2201,10 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
instance->list[map->list[bl->m].instance_id].users--;
instance->check_idle(map->list[bl->m].instance_id);
}
+ if( sd->state.hpmeter_visible ) {
+ map->list[bl->m].hpmeter_visible--;
+ sd->state.hpmeter_visible = 0;
+ }
sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
sd->debug_file = file;
sd->debug_line = line;
@@ -2233,7 +2238,6 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
}
case BL_HOM: {
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
clif->emotion(bl, E_SOB);
@@ -2350,29 +2354,16 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
for(i = 1; i < 5; i++)
pc->del_charm(sd, sd->charm[i], i);
- if( sd->reg ) { //Double logout already freed pointer fix... [Skotlex]
- aFree(sd->reg);
- sd->reg = NULL;
- sd->reg_num = 0;
- }
- if( sd->regstr ) {
- for( i = 0; i < sd->regstr_num; ++i )
- if( sd->regstr[i].data )
- aFree(sd->regstr[i].data);
- aFree(sd->regstr);
- sd->regstr = NULL;
- sd->regstr_num = 0;
- }
if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
script->free_state(sd->st);
sd->st = NULL;
sd->npc_id = 0;
}
- if( sd->combos.count ) {
- aFree(sd->combos.bonus);
- aFree(sd->combos.id);
- sd->combos.count = 0;
+ if( sd->combos ) {
+ aFree(sd->combos);
+ sd->combos = NULL;
}
+ sd->combo_count = 0;
/* [Ind/Hercules] */
if( sd->sc_display_count ) {
for(i = 0; i < sd->sc_display_count; i++) {
@@ -2392,12 +2383,17 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
aFree(sd->queues);
sd->queues = NULL;
}
+ if( sd->quest_log != NULL ) {
+ aFree(sd->quest_log);
+ sd->quest_log = NULL;
+ sd->num_quests = sd->avail_quests = 0;
+ }
for( k = 0; k < sd->hdatac; k++ ) {
if( sd->hdata[k]->flag.free ) {
aFree(sd->hdata[k]->data);
- aFree(sd->hdata[k]);
}
+ aFree(sd->hdata[k]);
}
if( sd->hdata )
aFree(sd->hdata);
@@ -2576,7 +2572,10 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
return 0;
}
-int do_init_unit(void) {
+int do_init_unit(bool minimal) {
+ if (minimal)
+ return 0;
+
timer->add_func_list(unit->attack_timer, "unit_attack_timer");
timer->add_func_list(unit->walktoxy_timer,"unit_walktoxy_timer");
timer->add_func_list(unit->walktobl_sub, "unit_walktobl_sub");