summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt10
-rw-r--r--src/map/map.c29
-rw-r--r--src/map/map.h7
-rw-r--r--src/map/mob.c11
-rw-r--r--src/map/script.c9
-rw-r--r--src/map/status.c92
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<dy?dy:dx) <= distance);
+#endif
}
unsigned int distance(int dx, int dy) {
+#ifdef CIRCULAR_AREA
unsigned int min, max;
if ( dx < 0 ) dx = -dx;
@@ -247,6 +253,11 @@ unsigned int distance(int dx, int dy) {
// coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min )
return ((( max << 8 ) + ( max << 3 ) - ( max << 4 ) - ( max << 1 ) +
( min << 7 ) - ( min << 5 ) + ( min << 3 ) - ( min << 1 )) >> 8 );
+#else
+ if (dx < 0) dx = -dx;
+ if (dy < 0) dy = -dy;
+ return (dx<dy?dy:dx);
+#endif
}
//
@@ -657,9 +668,9 @@ int map_foreachinrange(int (*func)(struct block_list*,va_list),struct block_list
for(i=0;i<c && bl;i++,bl=bl->next){
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_count<BL_LIST_MAX)
bl_list[bl_list_count++]=bl;
}
@@ -673,7 +684,9 @@ int map_foreachinrange(int (*func)(struct block_list*,va_list),struct block_list
for(i=0;i<c && bl;i++,bl=bl->next){
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_count<BL_LIST_MAX)
bl_list[bl_list_count++]=bl;
}
@@ -731,6 +744,9 @@ int map_foreachinshootrange(int (*func)(struct block_list*,va_list),struct block
for(i=0;i<c && bl;i++,bl=bl->next){
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_count<BL_LIST_MAX)
bl_list[bl_list_count++]=bl;
@@ -745,6 +761,9 @@ int map_foreachinshootrange(int (*func)(struct block_list*,va_list),struct block
for(i=0;i<c && bl;i++,bl=bl->next){
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_count<BL_LIST_MAX)
bl_list[bl_list_count++]=bl;
diff --git a/src/map/map.h b/src/map/map.h
index 2cb6896e4..5788efbdb 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -14,6 +14,13 @@
//Only chars affected are those defined in BL_CHAR (mobs and players currently)
//#define CELL_NOSTACK
+//Uncomment to enable circular area checks.
+//By default, all range checks in Aegis are of Square shapes, so a weapon range
+// of 10 allows you to attack from anywhere within a 21x21 area.
+//Enabling this changes such checks to circular checks, which is more realistic,
+// but is not the official behaviour.
+//#define CIRCULAR_AREA
+
#define MAX_PC_CLASS 4050
#define PC_CLASS_BASE 0
#define PC_CLASS_BASE2 (PC_CLASS_BASE + 4001)
diff --git a/src/map/mob.c b/src/map/mob.c
index 636d94ff0..0d7fceb83 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -786,7 +786,7 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
return 0; //For some reason Homun targets are never overriden.
dist = distance_bl(&md->bl, 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)