* Fixed mob control commands.
* Fixed memory leak in scripts (again). Still have a few lying. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6749 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
eb9892798b
commit
c7535fdff4
@ -3,6 +3,9 @@ Date Added
|
|||||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
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.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
|
2006/05/25
|
||||||
|
* Fixed mob control commands.
|
||||||
|
* Fixed memory leak in scripts (again). Still have a few lying. [Lance]
|
||||||
2006/05/24
|
2006/05/24
|
||||||
* Fix to the slave AI problem. [erKURITA], by [Skotlex], reported by Niktout.
|
* Fix to the slave AI problem. [erKURITA], by [Skotlex], reported by Niktout.
|
||||||
* Item sharing now shares the same rules as exp sharing (no sharing when
|
* Item sharing now shares the same rules as exp sharing (no sharing when
|
||||||
|
@ -3439,7 +3439,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
|||||||
else
|
else
|
||||||
state |= BCT_ENEMY; //However, all else are enemies.
|
state |= BCT_ENEMY; //However, all else are enemies.
|
||||||
} else {
|
} 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.
|
state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs.
|
||||||
}
|
}
|
||||||
if (md->master_id && (s_bl = map_id2bl(md->master_id)) == NULL)
|
if (md->master_id && (s_bl = map_id2bl(md->master_id)) == NULL)
|
||||||
|
@ -870,6 +870,7 @@ struct mob_data {
|
|||||||
unsigned steal_coin_flag : 1;
|
unsigned steal_coin_flag : 1;
|
||||||
unsigned soul_change_flag : 1; // Celest
|
unsigned soul_change_flag : 1; // Celest
|
||||||
unsigned alchemist: 1;
|
unsigned alchemist: 1;
|
||||||
|
unsigned no_random_walk: 1;
|
||||||
int provoke_flag; // Celest
|
int provoke_flag; // Celest
|
||||||
} state;
|
} state;
|
||||||
struct guardian_data* guardian_data;
|
struct guardian_data* guardian_data;
|
||||||
|
@ -906,6 +906,9 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick)
|
|||||||
return 0;
|
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(status_get_mode(&md->bl)&MD_CANMOVE)
|
||||||
{ //If the mob can move, follow around. [Check by Skotlex]
|
{ //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);
|
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;
|
return 0;
|
||||||
|
|
||||||
d =12-md->move_fail_count;
|
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);
|
mob_damage(NULL,md,md->hp,1);
|
||||||
return 0;
|
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);
|
map_foreachinmap(mob_deleteslave_sub, md->bl.m, BL_MOB,md->bl.id);
|
||||||
return 0;
|
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]
|
// Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex]
|
||||||
int mob_respawn(int tid, unsigned int tick, int id,int data )
|
int mob_respawn(int tid, unsigned int tick, int id,int data )
|
||||||
{
|
{
|
||||||
|
124
src/map/script.c
124
src/map/script.c
@ -425,6 +425,7 @@ int buildin_mobwalk(struct script_state *st);
|
|||||||
int buildin_getmobdata(struct script_state *st);
|
int buildin_getmobdata(struct script_state *st);
|
||||||
int buildin_setmobdata(struct script_state *st);
|
int buildin_setmobdata(struct script_state *st);
|
||||||
int buildin_mobattack(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_mobstop(struct script_state *st);
|
||||||
int buildin_mobassist(struct script_state *st);
|
int buildin_mobassist(struct script_state *st);
|
||||||
int buildin_mobtalk(struct script_state *st);
|
int buildin_mobtalk(struct script_state *st);
|
||||||
@ -761,6 +762,7 @@ struct {
|
|||||||
{buildin_spawnmob,"spawnmob","*"},
|
{buildin_spawnmob,"spawnmob","*"},
|
||||||
{buildin_removemob,"removemob","*"},
|
{buildin_removemob,"removemob","*"},
|
||||||
{buildin_mobwalk,"mobwalk","*"},
|
{buildin_mobwalk,"mobwalk","*"},
|
||||||
|
{buildin_mobrandomwalk,"mobrandomwalk","*"},
|
||||||
{buildin_getmobdata,"getmobdata","*"},
|
{buildin_getmobdata,"getmobdata","*"},
|
||||||
{buildin_setmobdata,"setmobdata","*"},
|
{buildin_setmobdata,"setmobdata","*"},
|
||||||
{buildin_mobattack,"mobattack","*"},
|
{buildin_mobattack,"mobattack","*"},
|
||||||
@ -10469,18 +10471,23 @@ int buildin_removemob(struct script_state *st) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int buildin_mobwalk(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;
|
struct block_list *bl = NULL;
|
||||||
|
|
||||||
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
|
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
|
||||||
x = conv_num(st, & (st->stack->stack_data[st->start+3]));
|
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);
|
bl = map_id2bl(id);
|
||||||
if(bl && bl->type == BL_MOB)
|
if(bl && bl->type == BL_MOB){
|
||||||
push_val(st->stack,C_INT,unit_walktoxy(bl,x,y,0)); // We'll use harder calculations.
|
if(y)
|
||||||
else
|
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);
|
push_val(st->stack,C_INT,0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -10491,9 +10498,9 @@ int buildin_getmobdata(struct script_state *st) {
|
|||||||
struct mob_data *md = NULL;
|
struct mob_data *md = NULL;
|
||||||
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
|
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 ){
|
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 {
|
} 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);
|
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,0,(void *)(int)md->class_);
|
||||||
setd_sub(st,map_id2sd(st->rid),name,1,(void *)(int)md->level);
|
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;
|
if (sd) bl = &sd->bl;
|
||||||
md = (struct mob_data *)map_id2bl(id);
|
md = (struct mob_data *)map_id2bl(id);
|
||||||
if (md && md->bl.type == BL_MOB) {
|
if (md && md->bl.type == BL_MOB) {
|
||||||
md->target_id = sd->bl.id;
|
md->target_id = bl->id;
|
||||||
md->special_state.ai = 1;
|
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){
|
if(bl && bl->type == BL_MOB){
|
||||||
unit_stop_attack(bl);
|
unit_stop_attack(bl);
|
||||||
unit_stop_walking(bl,0);
|
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;
|
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 buildin_mobassist(struct script_state *st) {
|
||||||
int id;
|
int id;
|
||||||
char *target;
|
char *target;
|
||||||
@ -10671,7 +10689,8 @@ int buildin_mobassist(struct script_state *st) {
|
|||||||
md->target_id = ud->target;
|
md->target_id = ud->target;
|
||||||
else if (ud->skilltarget)
|
else if (ud->skilltarget)
|
||||||
md->target_id = 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) {
|
if(st->state == END) {
|
||||||
script_free_stack (st->stack);
|
script_free_stack (st->stack);
|
||||||
st->stack = NULL;
|
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->rid = rid;
|
||||||
st->oid = oid;
|
st->oid = oid;
|
||||||
st->sleep.timer = -1;
|
st->sleep.timer = -1;
|
||||||
// let's run that stuff
|
|
||||||
run_script_main(st);
|
|
||||||
|
|
||||||
if(st->state != END){
|
if(run_script_main(st)){
|
||||||
if(st->sleep.tick > 0)
|
if(st->state != END){
|
||||||
{ //Delay execution
|
pos = st->pos;
|
||||||
st->sleep.charid = sd?sd->char_id:0;
|
if(st->sleep.tick > 0)
|
||||||
st->sleep.timer = add_timer(gettick()+st->sleep.tick,
|
{ //Delay execution
|
||||||
run_script_timer, st->sleep.charid, (int)st);
|
st->sleep.charid = sd?sd->char_id:0;
|
||||||
linkdb_insert(&sleep_db, (void*)st->oid, st);
|
st->sleep.timer = add_timer(gettick()+st->sleep.tick,
|
||||||
} else if (sd) {
|
run_script_timer, st->sleep.charid, (int)st);
|
||||||
// script is not finished, store data in sd.
|
linkdb_insert(&sleep_db, (void*)st->oid, st);
|
||||||
sd->npc_script = st->script;
|
} else if (sd) {
|
||||||
sd->npc_scriptroot = rootscript;
|
// script is not finished, store data in sd.
|
||||||
sd->npc_scriptstate = st->state;
|
sd->npc_script = st->script;
|
||||||
sd->stack = st->stack;
|
sd->npc_scriptroot = rootscript;
|
||||||
if (bck_stack) //Get rid of the backup as it can't be restored.
|
sd->npc_scriptstate = st->state;
|
||||||
script_free_stack (bck_stack);
|
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);
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
aFree(st);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==========================================
|
|
||||||
* Žw’èƒm<EFBFBD>[ƒh‚ðsleep_db‚©‚ç<EFBFBD>í<EFBFBD>œ
|
|
||||||
*------------------------------------------
|
|
||||||
*/
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* Žw’èƒm<EFBFBD>[ƒh‚ðsleep_db‚©‚ç<EFBFBD>í<EFBFBD>œ
|
* Žw’èƒm<EFBFBD>[ƒh‚ðsleep_db‚©‚ç<EFBFBD>í<EFBFBD>œ
|
||||||
*------------------------------------------
|
*------------------------------------------
|
||||||
|
@ -1041,6 +1041,7 @@ int unit_stop_attack(struct block_list *bl)
|
|||||||
|
|
||||||
delete_timer( ud->attacktimer, unit_attack_timer );
|
delete_timer( ud->attacktimer, unit_attack_timer );
|
||||||
ud->attacktimer = -1;
|
ud->attacktimer = -1;
|
||||||
|
ud->target = 0;
|
||||||
return 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 ||
|
if(battle_check_target(src,target,BCT_ENEMY)<=0 ||
|
||||||
!status_check_skilluse(src, target, 0, 0)
|
!status_check_skilluse(src, target, 0, 0)
|
||||||
) {
|
) {
|
||||||
|
ShowWarning("%d can't attack. :(",src->id);
|
||||||
unit_unattackable(src);
|
unit_unattackable(src);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user