From 2d5e8b6e1a67df8c0719e744211a188f9c855445 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 4 Sep 2006 14:10:14 +0000 Subject: - Some cleanup of how mobcount works. - status_calc_misc will now be invoked in status_calc_bl even on the first call, since status could have gone up due to skill bonuses. - Moved max HP/SP calculations to before invoking status_calc_misc - Simplified distance and check_distance to use "aegis" methods (greater of dx/dy = distance), there's a new define in map.h called CIRCULAR_AREA, when set, the previous method is used, and map for each in range calls will also check for distances, making most ground skills and battle system use real circles instead of squares. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@8609 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 10 ++++++ src/map/map.c | 29 ++++++++++++++--- src/map/map.h | 7 ++++ src/map/mob.c | 11 +++---- src/map/script.c | 9 ++---- src/map/status.c | 92 ++++++++++++++++++++++++++--------------------------- 6 files changed, 95 insertions(+), 63 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 71fd7d9d6..72b0c8cff 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,16 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2006/09/04 + * status_calc_misc will now be invoked in status_calc_bl even on the first + call, since status could have gone up due to skill bonuses. [Skotlex] + * Moved max HP/SP calculations to before invoking status_calc_misc + [Skotlex] + * Simplified distance and check_distance to use "aegis" methods (greater of + dx/dy = distance), there's a new define in map.h called CIRCULAR_AREA, when + set, the previous method is used, and "for each in range" calls will also + check for distances, making most ground skills and battle system use real + circles instead of squares. [Skotlex] 2006/09/03 * Fixed SC_BERSERK's no regen penalty lasting pretty much forever. [Skotlex] diff --git a/src/map/map.c b/src/map/map.c index 87300b2e4..c25c61e79 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -220,14 +220,20 @@ int map_getusers(void) { return map_users; } - //Distance functions, taken from http://www.flipcode.com/articles/article_fastdistance.shtml int check_distance(int dx, int dy, int distance) { +#ifdef CIRCULAR_AREA //In this case, we just do a square comparison. Add 1 tile grace for diagonal range checks. return (dx*dx + dy*dy <= distance*distance + (dx&&dy?1:0)); +#else + if (dx < 0) dx = -dx; + if (dy < 0) dy = -dy; + return ((dx> 8 ); +#else + if (dx < 0) dx = -dx; + if (dy < 0) dy = -dy; + return (dxnext){ if(bl && bl->type&type && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 - //For speed purposes, it does not checks actual range by default. - //Feel free to uncomment if you want a more "exact" approach. -// && check_distance_bl(center, bl, range) +#ifdef CIRCULAR_AREA + && check_distance_bl(center, bl, range) +#endif && bl_list_countnext){ if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 -// && check_distance_bl(center, bl, range) +#ifdef CIRCULAR_AREA + && check_distance_bl(center, bl, range) +#endif && bl_list_countnext){ if(bl && bl->type&type && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 +#ifdef CIRCULAR_AREA + && check_distance_bl(center, bl, range) +#endif && path_search_long(NULL,center->m,center->x,center->y,bl->x,bl->y) && bl_list_countnext){ if(bl && bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1 +#ifdef CIRCULAR_AREA + && check_distance_bl(center, bl, range) +#endif && path_search_long(NULL,center->m,center->x,center->y,bl->x,bl->y) && bl_list_countbl, bl); - if(dist < md->db->range2 && + if( ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) && battle_check_range(&md->bl,bl,md->db->range2) ) { //Pick closest target? @@ -825,9 +825,8 @@ static int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap) case BL_PC: case BL_HOM: //[orn] case BL_MOB: - if(check_distance_bl(&md->bl, bl, md->status.rhw.range) && - battle_check_range (&md->bl, bl, md->status.rhw.range) - ) { + if(battle_check_range (&md->bl, bl, md->status.rhw.range)) + { (*target) = bl; md->target_id=bl->id; md->min_chase= md->db->range3; @@ -852,8 +851,8 @@ static int mob_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) md=va_arg(ap,struct mob_data *); target= va_arg(ap,struct block_list**); - if((dist=distance_bl(&md->bl, bl)) < md->db->range2 && - mob_can_reach(md,bl,dist+1, MSS_LOOT) && + dist=distance_bl(&md->bl, bl); + if(mob_can_reach(md,bl,dist+1, MSS_LOOT) && ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) //New target closer than previous one. ) { (*target) = bl; diff --git a/src/map/script.c b/src/map/script.c index e497430ef..fea3661dd 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -9100,17 +9100,15 @@ int buildin_stoptimer(struct script_state *st) // Added by RoVeRT int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT { char *event=va_arg(ap,char *); - int *c=va_arg(ap,int *); - if(strcmp(event,((struct mob_data *)bl)->npc_event)==0) - (*c)++; + return 1; return 0; } int buildin_mobcount(struct script_state *st) // Added by RoVeRT { char *mapname,*event; - int m,c=0; + int m; mapname=conv_str(st,& (st->stack->stack_data[st->start+2])); event=conv_str(st,& (st->stack->stack_data[st->start+3])); check_event(st, event); @@ -9119,9 +9117,8 @@ int buildin_mobcount(struct script_state *st) // Added by RoVeRT push_val(st->stack,C_INT,-1); return 0; } - map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event,&c ); - push_val(st->stack,C_INT, (c)); + push_val(st->stack,C_INT,map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event)); return 0; } diff --git a/src/map/status.c b/src/map/status.c index 665d1df1e..f73513ca2 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1941,6 +1941,49 @@ int status_calc_pc(struct map_session_data* sd,int first) if((skill=pc_checkskill(sd,BS_HILTBINDING))>0) status->batk += 4; +// ----- HP MAX CALCULATION ----- + + // Basic MaxHP value + //We hold the standard Max HP here to make it faster to recalculate on vit changes. + sd->status.max_hp = status_base_pc_maxhp(sd,status); + status->max_hp += sd->status.max_hp; + + // Absolute modifiers from passive skills + if((skill=pc_checkskill(sd,CR_TRUST))>0) + status->max_hp += skill*200; + +// ----- SP MAX CALCULATION ----- + + // Basic MaxSP value + sd->status.max_sp = status_base_pc_maxsp(sd,status); + status->max_sp += sd->status.max_sp; + + // Absolute modifiers from passive skills + if((skill=pc_checkskill(sd,SL_KAINA))>0) + status->max_sp += 30*skill; + + if(status->sp>status->max_sp) + status->sp=status->max_sp; + +// ----- RESPAWN HP/SP ----- +// + //Calc respawn hp and store it on base_status + if (sd->special_state.restart_full_recover) + { + status->hp = status->max_hp; + status->sp = status->max_sp; + } else { + if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2) + && battle_config.restart_hp_rate < 50) + status->hp=status->max_hp>>1; + else + status->hp=status->max_hp * battle_config.restart_hp_rate/100; + if(!status->hp) + status->hp = 1; + + status->sp = status->max_sp * battle_config.restart_sp_rate /100; + } + // ----- MISC CALCULATION ----- status_calc_misc(&sd->bl, status, sd->status.base_level); @@ -2047,49 +2090,6 @@ int status_calc_pc(struct map_session_data* sd,int first) i = 800-status->agi*4; status->dmotion = cap_value(i, 400, 800); -// ----- HP MAX CALCULATION ----- - - // Basic MaxHP value - //We hold the standard Max HP here to make it faster to recalculate on vit changes. - sd->status.max_hp = status_base_pc_maxhp(sd,status); - status->max_hp += sd->status.max_hp; - - // Absolute modifiers from passive skills - if((skill=pc_checkskill(sd,CR_TRUST))>0) - status->max_hp += skill*200; - -// ----- SP MAX CALCULATION ----- - - // Basic MaxSP value - sd->status.max_sp = status_base_pc_maxsp(sd,status); - status->max_sp += sd->status.max_sp; - - // Absolute modifiers from passive skills - if((skill=pc_checkskill(sd,SL_KAINA))>0) - status->max_sp += 30*skill; - - if(status->sp>status->max_sp) - status->sp=status->max_sp; - -// ----- RESPAWN HP/SP ----- -// - //Calc respawn hp and store it on base_status - if (sd->special_state.restart_full_recover) - { - status->hp = status->max_hp; - status->sp = status->max_sp; - } else { - if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2) - && battle_config.restart_hp_rate < 50) - status->hp=status->max_hp>>1; - else - status->hp=status->max_hp * battle_config.restart_hp_rate/100; - if(!status->hp) - status->hp = 1; - - status->sp = status->max_sp * battle_config.restart_sp_rate /100; - } - // ----- MISC CALCULATIONS ----- // Weight @@ -2720,9 +2720,9 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag) unit_walktoxy(&sd->bl, sd->ud.to_x, sd->ud.to_y, sd->ud.state.walk_easy); } - //Avoid calculating twice (SCB_ALL -> status_calc_pc -> was calculated in - //status_calc_misc() [Skotlex] - if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP) && flag != SCB_ALL) + //Needs be done even when it was already done in status_calc_misc, because + //int/vit max hp/sp could have changed due to skills. + if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP)) status_calc_regen(&sd->bl, status, &sd->regen); if(flag&SCB_REGEN) -- cgit v1.2.3-70-g09d2