From 092949e0fea0c103c7d3fb32953182781853f575 Mon Sep 17 00:00:00 2001 From: "Hercules.ws" Date: Mon, 3 Nov 2014 11:47:00 +0100 Subject: HPM Hooks Update Signed-off-by: HerculesWSAPI --- src/config/core.h | 2 +- src/map/battle.c | 10 +- src/map/battle.h | 2 +- src/map/map.c | 188 ++++++++++----------- src/map/mob.c | 8 +- src/map/unit.c | 22 +-- .../HPMHooking/HPMHooking_map.HPMHooksCore.inc | 4 + .../HPMHooking/HPMHooking_map.HookingPoints.inc | 1 + src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 39 ++++- 9 files changed, 154 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/src/config/core.h b/src/config/core.h index dc0354f42..da9296bda 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -35,7 +35,7 @@ //#define STATS_OPT_OUT /// Uncomment to enable the Cell Stack Limit mod. -/// It's only config is the battle_config custom_cell_stack_limit. +/// It's only config is the battle_config custom_cell_stack_limit. /// Only chars affected are those defined in BL_CHAR //#define CELL_NOSTACK diff --git a/src/map/battle.c b/src/map/battle.c index 66926e037..73b563d4b 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6639,8 +6639,8 @@ static const struct battle_data { { "bone_drop", &battle_config.bone_drop, 0, 0, 2, }, { "buyer_name", &battle_config.buyer_name, 1, 0, 1, }, { "skill_wall_check", &battle_config.skill_wall_check, 1, 0, 1, }, - { "official_cell_stack_limit", &battle_config.official_cell_stack_limit, 1, 1, 255, }, - { "custom_cell_stack_limit", &battle_config.custom_cell_stack_limit, 1, 1, 255, }, + { "official_cell_stack_limit", &battle_config.official_cell_stack_limit, 1, 1, 255, }, + { "custom_cell_stack_limit", &battle_config.custom_cell_stack_limit, 1, 1, 255, }, { "dancing_weaponswitch_fix", &battle_config.dancing_weaponswitch_fix, 1, 0, 1, }, // eAthena additions @@ -7109,9 +7109,9 @@ void battle_adjust_conf(void) { #endif -#ifndef CELL_NOSTACK - if (battle_config.custom_cell_stack_limit != 1) - ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); +#ifndef CELL_NOSTACK + if (battle_config.custom_cell_stack_limit != 1) + ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); #endif } diff --git a/src/map/battle.h b/src/map/battle.h index cef54f42a..c44e3e19d 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -381,7 +381,7 @@ struct Battle_Config { int allow_skill_without_day; // [Komurka] int allow_es_magic_pc; // [Skotlex] int skill_wall_check; // [Skotlex] - int official_cell_stack_limit; // [Playtester] + int official_cell_stack_limit; // [Playtester] int custom_cell_stack_limit; // [Skotlex] int skill_caster_check; // [Skotlex] int sc_castcancel; // [Skotlex] diff --git a/src/map/map.c b/src/map/map.c index b3efe7c57..5c0f5d65e 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -395,7 +395,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { /*========================================== * Counts specified number of objects on given cell. - * flag: + * flag: * 0x1 - only count standing units * TODO: merge with bl_getall_area *------------------------------------------*/ @@ -412,26 +412,26 @@ int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) { if (type&~BL_MOB) for( bl = map->list[m].block[bx+by*map->list[m].bxs] ; bl != NULL ; bl = bl->next ) - if(bl->x == x && bl->y == y && bl->type&type) { - if(flag&1) { - struct unit_data *ud = unit->bl2ud(bl); - if(!ud || ud->walktimer == INVALID_TIMER) - count++; - } else { - count++; - } + if(bl->x == x && bl->y == y && bl->type&type) { + if(flag&1) { + struct unit_data *ud = unit->bl2ud(bl); + if(!ud || ud->walktimer == INVALID_TIMER) + count++; + } else { + count++; + } } if (type&BL_MOB) for( bl = map->list[m].block_mob[bx+by*map->list[m].bxs] ; bl != NULL ; bl = bl->next ) - if(bl->x == x && bl->y == y) { - if(flag&1) { - struct unit_data *ud = unit->bl2ud(bl); - if(!ud || ud->walktimer == INVALID_TIMER) - count++; - } else { - count++; - } + if(bl->x == x && bl->y == y) { + if(flag&1) { + struct unit_data *ud = unit->bl2ud(bl); + if(!ud || ud->walktimer == INVALID_TIMER) + count++; + } else { + count++; + } } return count; @@ -1488,83 +1488,83 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 return 0; } -/*========================================== - * Locates the closest, walkable cell with no blocks of a certain type on it - * Returns true on success and sets x and y to cell found. - * Otherwise returns false and x and y are not changed. - * type: Types of block to count - * flag: - * 0x1 - only count standing units - *------------------------------------------*/ -bool map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag) -{ - uint8 dir = 6; - int16 tx = *x; - int16 ty = *y; - int costrange = 10; - - if(!map->count_oncell(m, tx, ty, type, flag)) - return true; //Current cell is free - - //Algorithm only works up to costrange of 34 - while(costrange <= 34) { - short dx = dirx[dir]; - short dy = diry[dir]; - - //Linear search - if(dir%2 == 0 && costrange%MOVE_COST == 0) { - tx = *x+dx*(costrange/MOVE_COST); - ty = *y+dy*(costrange/MOVE_COST); - if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { - *x = tx; - *y = ty; - return true; - } - } - //Full diagonal search - else if(dir%2 == 1 && costrange%MOVE_DIAGONAL_COST == 0) { - tx = *x+dx*(costrange/MOVE_DIAGONAL_COST); - ty = *y+dy*(costrange/MOVE_DIAGONAL_COST); - if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { - *x = tx; - *y = ty; - return true; - } - } - //One cell diagonal, rest linear (TODO: Find a better algorithm for this) - else if(dir%2 == 1 && costrange%MOVE_COST == 4) { - tx = *x+dx*((dir%4==3)?(costrange/MOVE_COST):1); - ty = *y+dy*((dir%4==1)?(costrange/MOVE_COST):1); - if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { - *x = tx; - *y = ty; - return true; - } - tx = *x+dx*((dir%4==1)?(costrange/MOVE_COST):1); - ty = *y+dy*((dir%4==3)?(costrange/MOVE_COST):1); - if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { - *x = tx; - *y = ty; - return true; - } - } - - //Get next direction - if (dir == 5) { - //Diagonal search complete, repeat with higher cost range - if(costrange == 14) costrange += 6; - else if(costrange == 28 || costrange >= 38) costrange += 2; - else costrange += 4; - dir = 6; - } else if (dir == 4) { - //Linear search complete, switch to diagonal directions - dir = 7; - } else { - dir = (dir+2)%8; - } - } - - return false; +/*========================================== + * Locates the closest, walkable cell with no blocks of a certain type on it + * Returns true on success and sets x and y to cell found. + * Otherwise returns false and x and y are not changed. + * type: Types of block to count + * flag: + * 0x1 - only count standing units + *------------------------------------------*/ +bool map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag) +{ + uint8 dir = 6; + int16 tx = *x; + int16 ty = *y; + int costrange = 10; + + if(!map->count_oncell(m, tx, ty, type, flag)) + return true; //Current cell is free + + //Algorithm only works up to costrange of 34 + while(costrange <= 34) { + short dx = dirx[dir]; + short dy = diry[dir]; + + //Linear search + if(dir%2 == 0 && costrange%MOVE_COST == 0) { + tx = *x+dx*(costrange/MOVE_COST); + ty = *y+dy*(costrange/MOVE_COST); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + //Full diagonal search + else if(dir%2 == 1 && costrange%MOVE_DIAGONAL_COST == 0) { + tx = *x+dx*(costrange/MOVE_DIAGONAL_COST); + ty = *y+dy*(costrange/MOVE_DIAGONAL_COST); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + //One cell diagonal, rest linear (TODO: Find a better algorithm for this) + else if(dir%2 == 1 && costrange%MOVE_COST == 4) { + tx = *x+dx*((dir%4==3)?(costrange/MOVE_COST):1); + ty = *y+dy*((dir%4==1)?(costrange/MOVE_COST):1); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + tx = *x+dx*((dir%4==1)?(costrange/MOVE_COST):1); + ty = *y+dy*((dir%4==3)?(costrange/MOVE_COST):1); + if(!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m,tx,ty,CELL_CHKPASS)) { + *x = tx; + *y = ty; + return true; + } + } + + //Get next direction + if (dir == 5) { + //Diagonal search complete, repeat with higher cost range + if(costrange == 14) costrange += 6; + else if(costrange == 28 || costrange >= 38) costrange += 2; + else costrange += 4; + dir = 6; + } else if (dir == 4) { + //Linear search complete, switch to diagonal directions + dir = 7; + } else { + dir = (dir+2)%8; + } + } + + return false; } /*========================================== diff --git a/src/map/mob.c b/src/map/mob.c index c05f4c4a2..2605b414f 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -1303,8 +1303,8 @@ int mob_unlocktarget(struct mob_data *md, int64 tick) { md->ud.target_to = 0; unit->set_target(&md->ud, 0); } - if(map->count_oncell(md->bl.m, md->bl.x, md->bl.y, BL_CHAR|BL_NPC, 1) > battle_config.official_cell_stack_limit) { - unit->walktoxy(&md->bl, md->bl.x, md->bl.y, 8); + if(map->count_oncell(md->bl.m, md->bl.x, md->bl.y, BL_CHAR|BL_NPC, 1) > battle_config.official_cell_stack_limit) { + unit->walktoxy(&md->bl, md->bl.x, md->bl.y, 8); } return 0; @@ -1433,8 +1433,8 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { //No valid target if (mob->warpchase(md, tbl)) return true; //Chasing this target. - if(md->ud.walktimer != INVALID_TIMER && (!can_move || md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh) - && (tbl || md->ud.walkpath.path_pos == 0)) + if(md->ud.walktimer != INVALID_TIMER && (!can_move || md->ud.walkpath.path_pos <= battle_config.mob_chase_refresh) + && (tbl || md->ud.walkpath.path_pos == 0)) return true; //Walk at least "mob_chase_refresh" cells before dropping the target unless target is non-existent mob_unlocktarget(md, tick); //Unlock target tbl = NULL; diff --git a/src/map/unit.c b/src/map/unit.c index f7b484e0c..044d7a43c 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -440,14 +440,14 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { ud->to_x = bl->x; ud->to_y = bl->y; - if(map->count_oncell(bl->m, x, y, BL_CHAR|BL_NPC, 1) > battle_config.official_cell_stack_limit) { - //Walked on occupied cell, call unit_walktoxy again - if(ud->steptimer != INVALID_TIMER) { - //Execute step timer on next step instead - timer->delete(ud->steptimer, unit_step_timer); - ud->steptimer = INVALID_TIMER; - } - return unit->walktoxy(bl, x, y, 8); + if(map->count_oncell(bl->m, x, y, BL_CHAR|BL_NPC, 1) > battle_config.official_cell_stack_limit) { + //Walked on occupied cell, call unit_walktoxy again + if(ud->steptimer != INVALID_TIMER) { + //Execute step timer on next step instead + timer->delete(ud->steptimer, unit_step_timer); + ud->steptimer = INVALID_TIMER; + } + return unit->walktoxy(bl, x, y, 8); } } return 0; @@ -479,7 +479,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) if( ud == NULL) return 0; - if ((flag&8) && !map->closest_freecell(bl->m, &x, &y, BL_CHAR|BL_NPC, 1)) //This might change x and y + if ((flag&8) && !map->closest_freecell(bl->m, &x, &y, BL_CHAR|BL_NPC, 1)) //This might change x and y return 0; if (!path->search(&wpd, bl->m, bl->x, bl->y, x, y, flag&1, CELL_CHKNOPASS)) // Count walk path cells @@ -1853,7 +1853,7 @@ int unit_attack(struct block_list *src,int target_id,int continuous) { unit->unattackable(src); return 1; } - ud->state.attack_continue = (continuous&1)?1:0; + ud->state.attack_continue = (continuous&1)?1:0; ud->state.step_attack = (continuous&2)?1:0; unit->set_target(ud, target_id); @@ -2080,7 +2080,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) { sstatus = status->get_status_data(src); range = sstatus->rhw.range; - if( (unit_is_walking(target) || ud->state.step_attack) + if( (unit_is_walking(target) || ud->state.step_attack) && (target->type == BL_PC || !map->getcell(target->m,target->x,target->y,CELL_CHKICEWALL)) ) range++; // Extra range when chasing (does not apply to mobs locked in an icewall) diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index ba42106f6..81e0c1c2d 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -2687,6 +2687,8 @@ struct { struct HPMHookPoint *HP_map_get_new_object_id_post; struct HPMHookPoint *HP_map_search_freecell_pre; struct HPMHookPoint *HP_map_search_freecell_post; + struct HPMHookPoint *HP_map_closest_freecell_pre; + struct HPMHookPoint *HP_map_closest_freecell_post; struct HPMHookPoint *HP_map_quit_pre; struct HPMHookPoint *HP_map_quit_post; struct HPMHookPoint *HP_map_addnpc_pre; @@ -7748,6 +7750,8 @@ struct { int HP_map_get_new_object_id_post; int HP_map_search_freecell_pre; int HP_map_search_freecell_post; + int HP_map_closest_freecell_pre; + int HP_map_closest_freecell_post; int HP_map_quit_pre; int HP_map_quit_post; int HP_map_addnpc_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index 21e3d616d..5fa0bff3f 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -1365,6 +1365,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(map->find_skill_unit_oncell, HP_map_find_skill_unit_oncell) }, { HP_POP(map->get_new_object_id, HP_map_get_new_object_id) }, { HP_POP(map->search_freecell, HP_map_search_freecell) }, + { HP_POP(map->closest_freecell, HP_map_closest_freecell) }, { HP_POP(map->quit, HP_map_quit) }, { HP_POP(map->addnpc, HP_map_addnpc) }, { HP_POP(map->clearflooritem_timer, HP_map_clearflooritem_timer) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 3407c3268..9b518d097 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -35481,15 +35481,15 @@ int HP_map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { } return retVal___; } -int HP_map_count_oncell(int16 m, int16 x, int16 y, int type) { +int HP_map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_count_oncell_pre ) { - int (*preHookFunc) (int16 *m, int16 *x, int16 *y, int *type); + int (*preHookFunc) (int16 *m, int16 *x, int16 *y, int *type, int *flag); *HPMforce_return = false; for(hIndex = 0; hIndex < HPMHooks.count.HP_map_count_oncell_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_count_oncell_pre[hIndex].func; - retVal___ = preHookFunc(&m, &x, &y, &type); + retVal___ = preHookFunc(&m, &x, &y, &type, &flag); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -35497,13 +35497,13 @@ int HP_map_count_oncell(int16 m, int16 x, int16 y, int type) { } } { - retVal___ = HPMHooks.source.map.count_oncell(m, x, y, type); + retVal___ = HPMHooks.source.map.count_oncell(m, x, y, type, flag); } if( HPMHooks.count.HP_map_count_oncell_post ) { - int (*postHookFunc) (int retVal___, int16 *m, int16 *x, int16 *y, int *type); + int (*postHookFunc) (int retVal___, int16 *m, int16 *x, int16 *y, int *type, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_count_oncell_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_count_oncell_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &m, &x, &y, &type); + retVal___ = postHookFunc(retVal___, &m, &x, &y, &type, &flag); } } return retVal___; @@ -35589,6 +35589,33 @@ int HP_map_search_freecell(struct block_list *src, int16 m, int16 *x, int16 *y, } return retVal___; } +bool HP_map_closest_freecell(int16 m, int16 *x, int16 *y, int type, int flag) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_map_closest_freecell_pre ) { + bool (*preHookFunc) (int16 *m, int16 *x, int16 *y, int *type, int *flag); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_closest_freecell_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_map_closest_freecell_pre[hIndex].func; + retVal___ = preHookFunc(&m, x, y, &type, &flag); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.map.closest_freecell(m, x, y, type, flag); + } + if( HPMHooks.count.HP_map_closest_freecell_post ) { + bool (*postHookFunc) (bool retVal___, int16 *m, int16 *x, int16 *y, int *type, int *flag); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_closest_freecell_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_map_closest_freecell_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &m, x, y, &type, &flag); + } + } + return retVal___; +} int HP_map_quit(struct map_session_data *sd) { int hIndex = 0; int retVal___ = 0; -- cgit v1.2.3-70-g09d2