summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-05-15 10:27:05 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-05-15 10:27:05 +0000
commitc0f2069689110d1df816d52e36d049d4b97a7a22 (patch)
tree79b5d2a9dbaff90eaf32470e1fd586f8c7ad43aa /src
parentf51be442a0990eb5755e10346abaeb94404af2b1 (diff)
downloadhercules-c0f2069689110d1df816d52e36d049d4b97a7a22.tar.gz
hercules-c0f2069689110d1df816d52e36d049d4b97a7a22.tar.bz2
hercules-c0f2069689110d1df816d52e36d049d4b97a7a22.tar.xz
hercules-c0f2069689110d1df816d52e36d049d4b97a7a22.zip
- Fixed a bunch of invalid memory access bugs as reported by Valgrind.
- Updated unit_stop_walking to not move character an extra cell when it is already half-way there unless flag 0x4 is passed. (bugreport:3078) - Fixed the monster MD_CASTSENSOR code not correctly setting the monster's aggressive state. - Corrected a few compiler warnings - Changed a bit the code for SC_BOSSMAPINFO so it is not so hideously ugly. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13774 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/map/atcommand.c2
-rw-r--r--src/map/clif.c7
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/map.c4
-rw-r--r--src/map/mob.c7
-rw-r--r--src/map/mob.h2
-rw-r--r--src/map/npc.c2
-rw-r--r--src/map/pc.c2
-rw-r--r--src/map/script.c6
-rw-r--r--src/map/skill.c8
-rw-r--r--src/map/status.c37
-rw-r--r--src/map/storage.c4
-rw-r--r--src/map/unit.c45
13 files changed, 58 insertions, 70 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 9019fd86a..48e8b2464 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -9176,7 +9176,7 @@ void do_final_atcommand()
int atcommand_commands(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
char line_buff[CHATBOX_SIZE];
- int i, gm_lvl = pc_isGM(sd), count = 0, count2 = 0;
+ int i, gm_lvl = pc_isGM(sd), count = 0;
char* cur = line_buff;
memset(line_buff,' ',CHATBOX_SIZE);
diff --git a/src/map/clif.c b/src/map/clif.c
index a7b25d345..aed6f6057 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9707,7 +9707,7 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_Cooking(int fd,struct map_session_data *sd)
{
- int type = RFIFOW(fd,2); // '1' for cooking
+ //int type = RFIFOW(fd,2); // '1' for cooking, but what do other values mean?
int nameid = RFIFOW(fd,4);
if (pc_istrading(sd)) {
@@ -11605,7 +11605,6 @@ void clif_parse_HomAttack(int fd,struct map_session_data *sd)
bl = &sd->md->bl;
else return;
- unit_stop_walking(bl, 1);
unit_stop_attack(bl);
unit_attack(bl, target_id, action_type != 0);
}
@@ -12494,7 +12493,7 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag)
else
WFIFOB(fd,2) = 2; // First Time
}
- else
+ else if (md->spawn_timer != -1)
{ // Boss is Dead
const struct TimerData * timer_data = get_timer(md->spawn_timer);
unsigned int seconds;
@@ -13311,7 +13310,7 @@ static int packetdb_readdb(void)
0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0280
0, 0, 0, 6, 0, 0, 0, 0, 0, 8, 18, 0, 0, 0, 0, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 0, 0, 0, 0,
//#0x02C0
diff --git a/src/map/guild.c b/src/map/guild.c
index 5296f5970..365461593 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1730,7 +1730,7 @@ int guild_addcastleinfoevent(int castle_id,int index,const char *name)
return 0;
ev = (struct eventlist *)aMalloc(sizeof(struct eventlist));
- memcpy(ev->name,name,sizeof(ev->name));
+ strncpy(ev->name,name,ARRAYLENGTH(ev->name));
//The next event becomes whatever was currently stored.
ev->next = (struct eventlist *)idb_put(guild_castleinfoevent_db,code,ev);
return 0;
diff --git a/src/map/map.c b/src/map/map.c
index 3222c5579..7cad8961b 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1459,10 +1459,10 @@ void map_addiddb(struct block_list *bl)
}
else if( bl->type == BL_MOB )
{
- struct mob_data* md = BL_CAST(BL_MOB, bl);
+ TBL_MOB* md = (TBL_MOB*)bl;
idb_put(mobid_db,bl->id,bl);
- if( md && (md->db->status.mode&MD_BOSS) && md->db->mexp > 0 )
+ if( (md->db->status.mode&MD_BOSS) && md->db->mexp > 0 )
idb_put(bossid_db, bl->id, bl);
}
diff --git a/src/map/mob.c b/src/map/mob.c
index 42e00b9ec..d6ac54517 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -3281,12 +3281,16 @@ int mob_clone_spawn(struct map_session_data *sd, int m, int x, int y, const char
return md->bl.id;
}
-int mob_clone_delete(int class_)
+int mob_clone_delete(struct mob_data *md)
{
+ const int class_ = md->class_;
if (class_ >= MOB_CLONE_START && class_ < MOB_CLONE_END
&& mob_db_data[class_]!=NULL) {
aFree(mob_db_data[class_]);
mob_db_data[class_]=NULL;
+ //Clear references to the db
+ md->db = NULL;
+ md->vd = NULL;
return 1;
}
return 0;
@@ -4134,7 +4138,6 @@ static int mob_readskilldb(void)
while(fgets(line, sizeof(line), fp))
{
char *str[20], *p, *np;
- int j=0;
lines++;
if(line[0] == '/' && line[1] == '/')
diff --git a/src/map/mob.h b/src/map/mob.h
index 92565b6c0..0ea82abcd 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -254,7 +254,7 @@ int mob_countslave(struct block_list *bl);
int mob_is_clone(int class_);
int mob_clone_spawn(struct map_session_data *sd, int m, int x, int y, const char *event, int master_id, int mode, int flag, unsigned int duration);
-int mob_clone_delete(int class_);
+int mob_clone_delete(struct mob_data *md);
void mob_reload(void);
diff --git a/src/map/npc.c b/src/map/npc.c
index cab526151..042da1a0c 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -666,7 +666,7 @@ int npc_settimerevent_tick(struct npc_data* nd, int newtimer)
{
bool flag;
int old_rid;
- struct map_session_data *sd = NULL;
+ //struct map_session_data *sd = NULL;
nullpo_retr(0, nd);
diff --git a/src/map/pc.c b/src/map/pc.c
index d3802c80b..d7c2013c3 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -5206,7 +5206,7 @@ int pc_resethate(struct map_session_data* sd)
int pc_skillatk_bonus(struct map_session_data *sd, int skill_num)
{
int i, bonus = 0;
- ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id && sd->skillatk[i].id == skill_num);
+ ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, !sd->skillatk[i].id || sd->skillatk[i].id == skill_num);
if( i < ARRAYLENGTH(sd->skillatk) && sd->skillatk[i].id )
bonus = sd->skillatk[i].val;
if( sd->sc.data[SC_SKILLATKBONUS] )
diff --git a/src/map/script.c b/src/map/script.c
index f0fab4ce6..a85346218 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -7519,7 +7519,9 @@ BUILDIN_FUNC(killmonster)
}
}
+ map_freeblock_lock();
map_foreachinmap(buildin_killmonster_sub_strip, m, BL_MOB, event ,allflag);
+ map_freeblock_unlock();
return 0;
}
@@ -11160,7 +11162,7 @@ BUILDIN_FUNC(npcstop)
struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
if(nd) {
- unit_stop_walking(&nd->bl,1);
+ unit_stop_walking(&nd->bl,5);
}
return 0;
@@ -12738,7 +12740,7 @@ BUILDIN_FUNC(unitstop)
if( bl != NULL )
{
unit_stop_attack(bl);
- unit_stop_walking(bl,0);
+ unit_stop_walking(bl,4);
if( bl->type == BL_MOB )
((TBL_MOB*)bl)->target_id = 0;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 8ea6ca7b5..cc3c034dc 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -5904,7 +5904,8 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr data)
if(battle_config.skill_log && battle_config.skill_log&src->type)
ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
src->type, src->id, ud->skillid, ud->skilllv, ud->skillx, ud->skilly);
- unit_stop_walking(src,1);
+ if (ud->walktimer != -1)
+ unit_stop_walking(src,1);
ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv);
if ( battle_config.display_status_timers && sd )
clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, ud->skillid, ud->skilllv));
@@ -7707,7 +7708,7 @@ static int skill_unit_effect (struct block_list* bl, va_list ap)
int skill_id;
bool dissonance;
- if( !unit->alive || bl->prev == NULL )
+ if( (!unit->alive && !(flag&4)) || bl->prev == NULL )
return 0;
nullpo_retr(0, group);
@@ -9751,6 +9752,8 @@ int skill_delunit (struct skill_unit* unit)
nullpo_retr(0, unit);
if( !unit->alive )
return 0;
+ unit->alive=0;
+
nullpo_retr(0, group=unit->group);
if( group->state.song_dance&0x1 ) //Cancel dissonance effect.
@@ -9784,7 +9787,6 @@ int skill_delunit (struct skill_unit* unit)
clif_skill_delunit(unit);
unit->group=NULL;
- unit->alive=0;
map_delblock(&unit->bl); // don't free yet
map_deliddb(&unit->bl);
idb_remove(skillunit_db, unit->bl.id);
diff --git a/src/map/status.c b/src/map/status.c
index 362afa014..a308de734 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -817,7 +817,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
else
{ //Some death states that would normally be handled by unit_remove_map
unit_stop_attack(target);
- unit_stop_walking(target,0);
+ unit_stop_walking(target,1);
unit_skillcastcancel(target,0);
clif_clearunit_area(target,1);
skill_unit_move(target,gettick(),4);
@@ -2992,8 +2992,7 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
void status_calc_bl_sub_mer(struct mercenary_data *md, unsigned long flag)
{
struct status_data
- *status = &md->battle_status,
- *b_status = &md->base_status;
+ *status = &md->battle_status;
if( flag&(SCB_MAXHP|SCB_VIT) )
{
@@ -3192,7 +3191,7 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
if (!(status->mode&MD_CANATTACK))
unit_stop_attack(bl);
if (!(status->mode&MD_CANMOVE))
- unit_stop_walking(bl,0);
+ unit_stop_walking(bl,1);
}
// No status changes alter these yet.
@@ -4441,7 +4440,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
struct view_data* vd;
nullpo_retv(bl);
if (mobdb_checkid(class_) || mob_is_clone(class_))
- vd = mob_get_viewdata(class_);
+ vd = mob_get_viewdata(class_);
else if (npcdb_checkid(class_) || (bl->type == BL_NPC && class_ == WARP_CLASS))
vd = npc_get_viewdata(class_);
else if (homdb_checkid(class_))
@@ -4774,8 +4773,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
struct view_data *vd;
int opt_flag, calc_flag, undead_flag;
- struct mob_data *boss_md = NULL;
-
nullpo_retr(0, bl);
sc = status_get_sc(bl);
status = status_get_status_data(bl);
@@ -5465,13 +5462,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_BOSSMAPINFO:
if( sd != NULL )
{
- boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
+ struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
if( boss_md == NULL || boss_md->bl.prev == NULL )
{ // No MVP on this map - MVP is dead
clif_bossmapinfo(sd->fd, boss_md, 1);
return 0; // No need to start SC
}
-
val1 = boss_md->bl.id;
if( (val4 = tick/1000) < 1 )
val4 = 1;
@@ -6280,8 +6276,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
case SC_BOSSMAPINFO:
- if( boss_md != NULL )
- clif_bossmapinfo(sd->fd, boss_md, 0); // First Message
+ clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message
break;
case SC_MERC_HPUP:
status_percent_heal(bl, 100, 0); // Recover Full HP
@@ -6894,9 +6889,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
struct status_change *sc;
struct status_change_entry *sce;
- struct mob_data *boss_md = NULL;
- int result;
-
bl = map_id2bl(id);
if(!bl)
{
@@ -7097,12 +7089,14 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
case SC_BOSSMAPINFO:
if( sd && --(sce->val4) >= 0 )
{
- boss_md = map_id2boss(sce->val1);
- if( boss_md && boss_md->bl.prev != NULL && sd->bl.m == boss_md->bl.m )
+ struct mob_data *boss_md = map_id2boss(sce->val1);
+ if( boss_md && sd->bl.m == boss_md->bl.m )
{
clif_bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap
- sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
- return 0;
+ if (boss_md->bl.prev != NULL) {
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
}
}
break;
@@ -7258,12 +7252,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr data)
}
// default for all non-handled control paths is to end the status
- result = status_change_end( bl,type,tid );
-
- if( sd && boss_md && boss_md->bl.prev == NULL )
- clif_bossmapinfo(sd->fd, boss_md, 1); // Killed MVP - Show next spawn info
-
- return result;
+ return status_change_end( bl,type,tid );
#undef sc_timer_next
}
diff --git a/src/map/storage.c b/src/map/storage.c
index 33a72d0d7..f9f695c04 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -42,13 +42,13 @@ static int storage_comp_item(const void *_i1, const void *_i2)
return -1;
return i1->nameid - i2->nameid;
}
-
+/* In case someone wants to use it in the future.
static void storage_sortitem(struct storage_data* stor)
{
nullpo_retv(stor);
qsort(stor->items, MAX_STORAGE, sizeof(struct item), storage_comp_item);
}
-
+*/
static void storage_gsortitem(struct guild_storage* gstor)
{
nullpo_retv(gstor);
diff --git a/src/map/unit.c b/src/map/unit.c
index 0a264fb30..8fa929da8 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -508,7 +508,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
map_moveblock(bl, dst_x, dst_y, gettick());
- ud->walktimer = 1; //FIXME: why '1'? [ultramage]
+ ud->walktimer = 1; //Enables clif_insight related packets to spawn character in moving animation.
map_foreachinmovearea(clif_insight, bl, AREA_SIZE, -dx, -dy, sd?BL_ALL:BL_PC, bl);
ud->walktimer = INVALID_TIMER;
@@ -631,7 +631,12 @@ int unit_warp(struct block_list *bl,short m,short x,short y,int type)
}
/*==========================================
- * s~
+ * Caused the target object to stop moving.
+ * Flag values:
+ * &0x1: Issue a fixpos packet afterwards
+ * &0x2: Force the unit to move one cell if it hasn't yet
+ * &0x4: Enable moving to the next cell when unit was already half-way there
+ * (could trigger additional on-touch/place code)
*------------------------------------------*/
int unit_stop_walking(struct block_list *bl,int type)
{
@@ -652,7 +657,7 @@ int unit_stop_walking(struct block_list *bl,int type)
ud->state.change_walk_target = 0;
tick = gettick();
if ((type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell.
- || (td && DIFF_TICK(td->tick, tick) <= td->data/2)) //Enough time has passed to cover half-cell
+ || (!(type&0x04) && td && DIFF_TICK(td->tick, tick) <= td->data/2)) //Enough time has passed to cover half-cell
{
ud->walkpath.path_len = ud->walkpath.path_pos+1;
unit_walktoxy_timer(-1, tick, bl->id, ud->walkpath.path_pos);
@@ -800,7 +805,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
{ //Stop walking, if chasing, readjust timers.
if (delay == 1)
{ //Minimal delay (walk-delay) disabled. Just stop walking.
- unit_stop_walking(bl,0);
+ unit_stop_walking(bl,4);
} else {
//Resume running after can move again [Kevin]
if(ud->state.running)
@@ -809,7 +814,7 @@ int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int
}
else
{
- unit_stop_walking(bl,2);
+ unit_stop_walking(bl,6);
if(ud->target)
add_timer(ud->canmove_tick+1, unit_walktobl_sub, bl->id, ud->target);
}
@@ -1034,13 +1039,13 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if( casttime > 0 || temp )
{
+ unit_stop_walking(src,1);
clif_skillcasting(src, src->id, target_id, 0,0, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
if (sd && target->type == BL_MOB)
{
TBL_MOB *md = (TBL_MOB*)target;
mobskill_event(md, src, tick, -1); //Cast targetted skill event.
- //temp: used to store mob's mode now.
if (tstatus->mode&(MD_CASTSENSOR_IDLE|MD_CASTSENSOR_CHASE) &&
battle_check_target(target, src, BCT_ENEMY) > 0)
{
@@ -1050,7 +1055,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if (!(tstatus->mode&MD_CASTSENSOR_CHASE))
break;
md->target_id = src->id;
- md->state.aggressive = (temp&MD_ANGRY)?1:0;
+ md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
md->min_chase = md->db->range3;
break;
case MSS_IDLE:
@@ -1058,7 +1063,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
if (!(tstatus->mode&MD_CASTSENSOR_IDLE))
break;
md->target_id = src->id;
- md->state.aggressive = (temp&MD_ANGRY)?1:0;
+ md->state.aggressive = (tstatus->mode&MD_ANGRY)?1:0;
md->min_chase = md->db->range3;
break;
}
@@ -1098,8 +1103,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
ud->skilltimer = add_timer( tick+casttime, skill_castend_id, src->id, 0 );
if( sd && pc_checkskill(sd,SA_FREECAST) > 0 )
status_calc_bl(&sd->bl, SCB_SPEED);
- else
- unit_stop_walking(src,1);
}
else
skill_castend_id(ud->skilltimer,tick,src->id,0);
@@ -1172,20 +1175,12 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
return 0; //Arrow-path check failed.
unit_stop_attack(src);
- ud->state.skillcastcancel = castcancel;
// moved here to prevent Suffragium from ending if skill fails
if (!(skill_get_castnodex(skill_num, skill_lv)&2))
casttime = skill_castfix_sc(src, casttime);
- if( casttime > 0 )
- {
- unit_stop_walking( src, 1);
- clif_skillcasting(src, src->id, 0, skill_x, skill_y, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
- }
- else
- ud->state.skillcastcancel=0;
-
+ ud->state.skillcastcancel = castcancel&&casttime>0?1:0;
ud->canact_tick = tick + casttime + 100;
if ( battle_config.display_status_timers && sd )
clif_status_change(src, SI_ACTIONDELAY, 1, casttime);
@@ -1211,11 +1206,11 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
if( casttime > 0 )
{
+ unit_stop_walking(src,1);
+ clif_skillcasting(src, src->id, 0, skill_x, skill_y, skill_num, skill_get_ele(skill_num, skill_lv), casttime);
ud->skilltimer = add_timer( tick+casttime, skill_castend_pos, src->id, 0 );
if( sd && pc_checkskill(sd,SA_FREECAST) > 0 )
status_calc_bl(&sd->bl, SCB_SPEED);
- else
- unit_stop_walking(src,1);
}
else
{
@@ -1283,10 +1278,9 @@ int unit_attack(struct block_list *src,int target_id,int continuous)
npc_click(sd,(TBL_NPC*)target); // submitted by leinsirk10 [Celest]
return 0;
}
- else if( pc_is90overweight(sd) )
- { // overwheight - stop attacking and walking
+ if( pc_is90overweight(sd) )
+ { // overweight - stop attacking
unit_stop_attack(src);
- unit_stop_walking(src,1);
return 0;
}
}
@@ -2117,8 +2111,7 @@ int unit_free(struct block_list *bl, int clrtype)
md->base_status = NULL;
}
if( mob_is_clone(md->class_) )
- mob_clone_delete(md->class_);
-
+ mob_clone_delete(md);
break;
}
case BL_HOM: