From 952432e5f073fa9d840ff4acdb3abfc53335a5d3 Mon Sep 17 00:00:00 2001 From: Lance Date: Thu, 25 May 2006 12:04:09 +0000 Subject: * Fixed mob control commands. * Fixed memory leak in scripts (again). Still have a few lying. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6749 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 2 +- src/map/map.h | 1 + src/map/mob.c | 30 ++++++++++++- src/map/script.c | 126 ++++++++++++++++++++++++++++++++----------------------- src/map/unit.c | 2 + 5 files changed, 106 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 41c2f9c16..b1e211189 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3439,7 +3439,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f else state |= BCT_ENEMY; //However, all else are enemies. } else { - if (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai) + //if (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai) state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs. } if (md->master_id && (s_bl = map_id2bl(md->master_id)) == NULL) diff --git a/src/map/map.h b/src/map/map.h index 19b039b06..1035d014b 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -870,6 +870,7 @@ struct mob_data { unsigned steal_coin_flag : 1; unsigned soul_change_flag : 1; // Celest unsigned alchemist: 1; + unsigned no_random_walk: 1; int provoke_flag; // Celest } state; struct guardian_data* guardian_data; diff --git a/src/map/mob.c b/src/map/mob.c index 0600ff531..3fbe92375 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -906,6 +906,9 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) return 0; } + if(bl->type == BL_MOB && ((TBL_MOB *)bl)->master_id && ((TBL_MOB *)bl)->master_id != md->master_id) // Just in case something screws up + md->master_id = ((TBL_MOB *)bl)->master_id; + if(status_get_mode(&md->bl)&MD_CANMOVE) { //If the mob can move, follow around. [Check by Skotlex] @@ -997,7 +1000,7 @@ int mob_randomwalk(struct mob_data *md,int tick) nullpo_retr(0, md); - if(DIFF_TICK(md->next_walktime,tick)>0 || !unit_can_move(&md->bl)) + if(DIFF_TICK(md->next_walktime,tick)>0 || md->state.no_random_walk || !unit_can_move(&md->bl)) return 0; d =12-md->move_fail_count; @@ -1509,6 +1512,23 @@ int mob_deleteslave_sub(struct block_list *bl,va_list ap) mob_damage(NULL,md,md->hp,1); return 0; } + +int mob_convertslave_sub(struct block_list *bl,va_list ap) +{ + struct mob_data *md; + int id, master; + + nullpo_retr(0, bl); + nullpo_retr(0, ap); + nullpo_retr(0, md = (struct mob_data *)bl); + + id=va_arg(ap,int); + master=va_arg(ap,int); + + if(md->master_id > 0 && md->master_id == id ) + md->master_id = master; + return 0; +} /*========================================== * *------------------------------------------ @@ -1520,6 +1540,14 @@ int mob_deleteslave(struct mob_data *md) map_foreachinmap(mob_deleteslave_sub, md->bl.m, BL_MOB,md->bl.id); return 0; } + +int mob_convertslave(struct mob_data *md) +{ + nullpo_retr(0, md); + + map_foreachinmap(mob_convertslave_sub, md->bl.m, BL_MOB,md->bl.id,md->master_id); + return 0; +} // Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex] int mob_respawn(int tid, unsigned int tick, int id,int data ) { diff --git a/src/map/script.c b/src/map/script.c index 26da3ee8f..ae509106d 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -425,6 +425,7 @@ int buildin_mobwalk(struct script_state *st); int buildin_getmobdata(struct script_state *st); int buildin_setmobdata(struct script_state *st); int buildin_mobattack(struct script_state *st); +int buildin_mobrandomwalk(struct script_state *st); int buildin_mobstop(struct script_state *st); int buildin_mobassist(struct script_state *st); int buildin_mobtalk(struct script_state *st); @@ -761,6 +762,7 @@ struct { {buildin_spawnmob,"spawnmob","*"}, {buildin_removemob,"removemob","*"}, {buildin_mobwalk,"mobwalk","*"}, + {buildin_mobrandomwalk,"mobrandomwalk","*"}, {buildin_getmobdata,"getmobdata","*"}, {buildin_setmobdata,"setmobdata","*"}, {buildin_mobattack,"mobattack","*"}, @@ -10469,18 +10471,23 @@ int buildin_removemob(struct script_state *st) { } int buildin_mobwalk(struct script_state *st){ - int id,x,y; + int id,x,y = 0; struct block_list *bl = NULL; id = conv_num(st, & (st->stack->stack_data[st->start+2])); x = conv_num(st, & (st->stack->stack_data[st->start+3])); - y = conv_num(st, & (st->stack->stack_data[st->start+4])); + if(st->end > st->start+4) + y = conv_num(st, & (st->stack->stack_data[st->start+4])); bl = map_id2bl(id); - if(bl && bl->type == BL_MOB) - push_val(st->stack,C_INT,unit_walktoxy(bl,x,y,0)); // We'll use harder calculations. - else + if(bl && bl->type == BL_MOB){ + if(y) + push_val(st->stack,C_INT,unit_walktoxy(bl,x,y,0)); // We'll use harder calculations. + else + push_val(st->stack,C_INT,unit_walktobl(bl,map_id2bl(x),1,65025)); + } else { push_val(st->stack,C_INT,0); + } return 0; } @@ -10491,9 +10498,9 @@ int buildin_getmobdata(struct script_state *st) { struct mob_data *md = NULL; id = conv_num(st, & (st->stack->stack_data[st->start+2])); if(!(md = (struct mob_data *)map_id2bl(id)) || st->stack->stack_data[st->start+3].type!=C_NAME ){ - ShowWarning("buildin_getmobdata: Error in argiment!\n"); + ShowWarning("buildin_getmobdata: Error in argument!\n"); } else { - num=st->stack->stack_data[st->start+2].u.num; + num=st->stack->stack_data[st->start+3].u.num; name=(char *)(str_buf+str_data[num&0x00ffffff].str); setd_sub(st,map_id2sd(st->rid),name,0,(void *)(int)md->class_); setd_sub(st,map_id2sd(st->rid),name,1,(void *)(int)md->level); @@ -10626,9 +10633,10 @@ int buildin_mobattack(struct script_state *st) { if (sd) bl = &sd->bl; md = (struct mob_data *)map_id2bl(id); if (md && md->bl.type == BL_MOB) { - md->target_id = sd->bl.id; + md->target_id = bl->id; md->special_state.ai = 1; - md->min_chase = distance_bl(bl,&md->bl) + md->db->range2; + //md->min_chase = distance_bl(&md->bl,map_id2bl(md->target_id)) + md->db->range2; + unit_walktobl(&md->bl, bl, 65025, 2); } } @@ -10645,12 +10653,22 @@ int buildin_mobstop(struct script_state *st) { if(bl && bl->type == BL_MOB){ unit_stop_attack(bl); unit_stop_walking(bl,0); - ((TBL_MOB*)bl)->master_id = bl->id; // Quick hack to stop random walking. + ((TBL_MOB *)bl)->target_id = 0; } return 0; } +int buildin_mobrandomwalk(struct script_state *st){ + int id = conv_num(st, &(st->stack->stack_data[st->start+2])); + int flag = conv_num(st, &(st->stack->stack_data[st->start+3])); + struct mob_data *md = (struct mob_data *)map_id2bl(id); + if(md->bl.type == BL_MOB){ + md->state.no_random_walk = flag>0?0:1; + } + return 0; +} + int buildin_mobassist(struct script_state *st) { int id; char *target; @@ -10671,7 +10689,8 @@ int buildin_mobassist(struct script_state *st) { md->target_id = ud->target; else if (ud->skilltarget) md->target_id = ud->skilltarget; - md->min_chase = distance_bl(&md->bl,map_id2bl(md->target_id)) + md->db->range2; + if(md->target_id) + unit_walktobl(&md->bl, map_id2bl(md->target_id), 65025, 2); } } } @@ -11353,9 +11372,12 @@ int run_script_main(struct script_state *st) if(st->state == END) { script_free_stack (st->stack); st->stack = NULL; + aFree(st); + st = NULL; + return 0; } - return 0; + return 1; } /*========================================== @@ -11411,52 +11433,50 @@ int run_script(struct script_code *rootscript,int pos,int rid,int oid) st->rid = rid; st->oid = oid; st->sleep.timer = -1; - // let's run that stuff - run_script_main(st); - if(st->state != END){ - if(st->sleep.tick > 0) - { //Delay execution - st->sleep.charid = sd?sd->char_id:0; - st->sleep.timer = add_timer(gettick()+st->sleep.tick, - run_script_timer, st->sleep.charid, (int)st); - linkdb_insert(&sleep_db, (void*)st->oid, st); - } else if (sd) { - // script is not finished, store data in sd. - sd->npc_script = st->script; - sd->npc_scriptroot = rootscript; - sd->npc_scriptstate = st->state; - sd->stack = st->stack; - if (bck_stack) //Get rid of the backup as it can't be restored. - script_free_stack (bck_stack); - } - return st->pos; - } - //Script finished. - if (sd) - { //Clear or restore previous script. - sd->npc_script = bck_script; - sd->npc_scriptroot = bck_scriptroot; - sd->npc_scriptstate = bck_scriptstate; - sd->stack = bck_stack; - //Since the script is done, save any changed account variables [Skotlex] - if (sd->state.reg_dirty&2) - intif_saveregistry(sd,2); - if (sd->state.reg_dirty&1) - intif_saveregistry(sd,1); - } - if(st->stack) { - script_free_stack (st->stack); - st->stack = NULL; + if(run_script_main(st)){ + if(st->state != END){ + pos = st->pos; + if(st->sleep.tick > 0) + { //Delay execution + st->sleep.charid = sd?sd->char_id:0; + st->sleep.timer = add_timer(gettick()+st->sleep.tick, + run_script_timer, st->sleep.charid, (int)st); + linkdb_insert(&sleep_db, (void*)st->oid, st); + } else if (sd) { + // script is not finished, store data in sd. + sd->npc_script = st->script; + sd->npc_scriptroot = rootscript; + sd->npc_scriptstate = st->state; + sd->stack = st->stack; + if (bck_stack) //Get rid of the backup as it can't be restored. + script_free_stack (bck_stack); + aFree(st); + } + return pos; + } else { + if(st->stack) + script_free_stack(st->stack); + aFree(st); + } + } else { + //Script finished. + if (sd) + { //Clear or restore previous script. + sd->npc_script = bck_script; + sd->npc_scriptroot = bck_scriptroot; + sd->npc_scriptstate = bck_scriptstate; + sd->stack = bck_stack; + //Since the script is done, save any changed account variables [Skotlex] + if (sd->state.reg_dirty&2) + intif_saveregistry(sd,2); + if (sd->state.reg_dirty&1) + intif_saveregistry(sd,1); + } } - aFree(st); return 0; } -/*========================================== - * 指定ノードをsleep_dbから削除 - *------------------------------------------ - */ /*========================================== * 指定ノードをsleep_dbから削除 *------------------------------------------ diff --git a/src/map/unit.c b/src/map/unit.c index cf7d88aea..f0ce5c9ca 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1041,6 +1041,7 @@ int unit_stop_attack(struct block_list *bl) delete_timer( ud->attacktimer, unit_attack_timer ); ud->attacktimer = -1; + ud->target = 0; return 0; } @@ -1086,6 +1087,7 @@ int unit_attack(struct block_list *src,int target_id,int type) if(battle_check_target(src,target,BCT_ENEMY)<=0 || !status_check_skilluse(src, target, 0, 0) ) { + ShowWarning("%d can't attack. :(",src->id); unit_unattackable(src); return 1; } -- cgit v1.2.3-60-g2f50