From c0f2069689110d1df816d52e36d049d4b97a7a22 Mon Sep 17 00:00:00 2001 From: skotlex Date: Fri, 15 May 2009 10:27:05 +0000 Subject: - 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 --- src/map/atcommand.c | 2 +- src/map/clif.c | 7 +++---- src/map/guild.c | 2 +- src/map/map.c | 4 ++-- src/map/mob.c | 7 +++++-- src/map/mob.h | 2 +- src/map/npc.c | 2 +- src/map/pc.c | 2 +- src/map/script.c | 6 ++++-- src/map/skill.c | 8 +++++--- src/map/status.c | 37 +++++++++++++------------------------ src/map/storage.c | 4 ++-- src/map/unit.c | 45 +++++++++++++++++++-------------------------- 13 files changed, 58 insertions(+), 70 deletions(-) (limited to 'src/map') 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: -- cgit v1.2.3-60-g2f50