From 4eabbb012ad6e6a4b9b3343e090b96de2841c1cf Mon Sep 17 00:00:00 2001 From: Lance Date: Fri, 26 May 2006 07:21:48 +0000 Subject: * Change scripting engine's NPC scope vars to dot (.) style. * Improved and (should be fully) fixed the mob control engine. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6769 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 2 + npc/sample/monster_controller.cpp | 96 +++++++++++++++++++-------------------- src/char/char.c | 3 +- src/char_sql/char.c | 3 +- src/map/battle.c | 4 +- src/map/map.h | 1 + src/map/script.c | 64 ++++++++++++++------------ src/map/unit.c | 1 - 8 files changed, 94 insertions(+), 80 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index f0e3588b8..2db105c3b 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2006/05/26 + * Change scripting engine's NPC scope vars to dot (.) style. + * Improved and (should be fully) fixed the mob control engine. [Lance] * Fixed typos in char.c [Lance] * Rewrote fame rank lists system to reduce char-server load, as requested by Skotlex: now it has a copy of those lists, and updates only the proper one diff --git a/npc/sample/monster_controller.cpp b/npc/sample/monster_controller.cpp index 7e68d7f7f..58b5693a8 100644 --- a/npc/sample/monster_controller.cpp +++ b/npc/sample/monster_controller.cpp @@ -1,45 +1,45 @@ // Variables Logging: -// 'mc_moblist[] - ID list of mobs +// .mc_moblist[] - ID list of mobs prontera.gat,180,200,4 script Monster Controller 123,{ function display_info { - getmobdata getarg(0), '@mob_data; - set '@array_size, getarraysize('@mob_data); - for(set '@i, 0; '@i < '@array_size; set '@i, '@i + 1){ - mes '@i + " - " + '@mob_data['@i]; + getmobdata getarg(0), .@mob_data; + set .@array_size, getarraysize(.@mob_data); + for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){ + mes .@i + " - " + .@mob_data[.@i]; } return; } function remove_mob { removemob getarg(0); - set '@mob_size, getarraysize('mc_moblist); - for(set '@i, 0; '@i < '@mob_size; set '@i, '@i + 1){ - if('mc_moblist['@i] == getarg(0)) - deletearray 'mc_moblist['@i], 1; + set .@mob_size, getarraysize(.mc_moblist); + for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){ + if(.mc_moblist[.@i] == getarg(0)) + deletearray .mc_moblist[.@i], 1; } } function make_menu { - set '@array_size, getarraysize(getarg(0)); - set '@tmp_str$, ""; - for(set '@i, 0; '@i < '@array_size; set '@i, '@i + 1){ - set '@tmp_str$, '@tmp_str$ + 'mc_moblist['@i] + ":"; + set .@array_size, getarraysize(.mc_moblist); + set .@tmp_str$, ""; + for(set .@i, 0; .@i < .@array_size; set .@i, .@i + 1){ + set .@tmp_str$, .@tmp_str$ + .mc_moblist[.@i] + ":"; } - select '@tmp_str$; - return getelementofarray(getarg(0),@menu-1); + select .@tmp_str$; + return .mc_moblist[@menu-1]; } function summon_mob { - set '@mob_size, getarraysize('mc_moblist); - set 'mc_moblist['@mob_size], spawnmob("Slave - " + '@mob_size, getarg(0), "prontera.gat", 180, 200); - mobattach 'mc_moblist['@mob_size]; + set .@mob_size, getarraysize(.mc_moblist); + set .mc_moblist[.@mob_size], spawnmob("Slave - " + .@mob_size, getarg(0), "prontera.gat", 180, 200); + mobattach .mc_moblist[.@mob_size]; return; } function list_mobs { - set '@mob_size, getarraysize('mc_moblist); - for(set '@i, 0; '@i < '@mob_size; set '@i, '@i + 1){ - mes "- " + 'mc_moblist['@i]; + set .@mob_size, getarraysize(.mc_moblist); + for(set .@i, 0; .@i < .@mob_size; set .@i, .@i + 1){ + mes "- " + .mc_moblist[.@i]; } return; } @@ -59,15 +59,15 @@ L_MainMenu: goto L_MainMenu; break; case 2: // Remove - remove_mob make_menu('mc_moblist); + remove_mob make_menu(); next; goto L_MainMenu; break; case 3: // Information - set '@tmp, make_menu('mc_moblist); + set .@tmp, make_menu(); next; mes "[Monster Info]"; - display_info '@tmp; + display_info .@tmp; next; goto L_MainMenu; break; @@ -79,44 +79,44 @@ L_MainMenu: L_AttackMenu: switch(select("Walk","Follow","Attack","Stop","Defend","Talk","Emote","Random Walk","Back")){ case 1: // Walk - set '@src, make_menu('mc_moblist); - input '@x; - input '@y; - mobwalk '@src,'@x,'@y; // Mode 1: Walk to location. + set .@src, make_menu(); + input .@x; + input .@y; + mobwalk .@src,.@x,.@y; // Mode 1: Walk to location. break; case 2: // Follow - set '@src, make_menu('mc_moblist); - input '@tar; - mobwalk '@src, '@tar; // Mode 2: Walk to target. + set .@src, make_menu(); + input .@tar; + mobwalk .@src, .@tar; // Mode 2: Walk to target. break; case 3: // Attack - set '@src, make_menu('mc_moblist); - input '@tar; - mobattack '@src, '@tar; + set .@src, make_menu(); + input .@tar; + mobattack .@src, .@tar; break; case 4: // Stop - set '@src, make_menu('mc_moblist); - mobstop '@src; + set .@src, make_menu(); + mobstop .@src; break; case 5: // Defend/Assist - set '@src, make_menu('mc_moblist); - input '@tar; - mobassist '@src, '@tar; + set .@src, make_menu(); + input .@tar; + mobassist .@src, .@tar; break; case 6: // Talk - set '@src, make_menu('mc_moblist); - input '@text$; - mobtalk '@src, '@text$; + set .@src, make_menu(); + input .@text$; + mobtalk .@src, .@text$; break; case 7: // Emote - set '@src, make_menu('mc_moblist); - input '@emote; - mobemote '@src, '@emote; + set .@src, make_menu(); + input .@emote; + mobemote .@src, .@emote; break; case 8: - set '@src, make_menu('mc_moblist); - input '@flag; - mobrandomwalk '@src, '@flag; + set .@src, make_menu(); + input .@flag; + mobrandomwalk .@src, .@flag; break; case 9: next; diff --git a/src/char/char.c b/src/char/char.c index aac8135a9..34c366a84 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2917,9 +2917,10 @@ int parse_frommap(int fd) { return 0; } - if(pos) // If the player's already in the list, remove the entry and shift the following ones 1 step up + if(pos){ // If the player's already in the list, remove the entry and shift the following ones 1 step up memmove(list + pos - 1, list + pos, (size - pos) * sizeof(struct fame_list)); list[size].fame = 0; // At worst, the guy'll end up last (shouldn't happen if fame only goes up) + } for(i = 0; i < size; i++) // Find the position where the player has to be inserted if(fame >= list[i].fame) { // When found someone with less or as much fame, insert just above diff --git a/src/char_sql/char.c b/src/char_sql/char.c index ed76012d1..614140d85 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -2774,9 +2774,10 @@ int parse_frommap(int fd) { return 0; } - if(pos) // If the player's already in the list, remove the entry and shift the following ones 1 step up + if(pos){ // If the player's already in the list, remove the entry and shift the following ones 1 step up memmove(list + pos - 1, list + pos, (size - pos) * sizeof(struct fame_list)); list[size].fame = 0; // At worst, the guy'll end up last (shouldn't happen if fame only goes up) + } for(i = 0; i < size; i++) // Find the position where the player has to be inserted if(fame >= list[i].fame) { // When found someone with less or as much fame, insert just above diff --git a/src/map/battle.c b/src/map/battle.c index 77e5bc7d7..a263d4874 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3426,6 +3426,8 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f case BL_MOB: { TBL_MOB*md = (TBL_MOB*)s_bl; + if(md->state.killer) // Is on a rampage too :D + state |= BCT_ENEMY; if (!agit_flag && md->guardian_data && md->guardian_data->guild_id) return 0; //Disable guardians/emperium owned by Guilds on non-woe times. if (!md->special_state.ai) { //Normal mobs. @@ -3434,7 +3436,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 66315cadc..aa8714349 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -871,6 +871,7 @@ struct mob_data { unsigned soul_change_flag : 1; // Celest unsigned alchemist: 1; unsigned no_random_walk: 1; + unsigned killer: 1; int provoke_flag; // Celest } state; struct guardian_data* guardian_data; diff --git a/src/map/script.c b/src/map/script.c index d167f8230..88d4ef9e7 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -125,7 +125,7 @@ char tmp_sql[65535]; #endif static struct linkdb_node *sleep_db; -#define not_server_variable(prefix) (prefix != '$' && prefix != '\'') +#define not_server_variable(prefix) (prefix != '$' && prefix != '.') /*========================================== * ローカルプロトタイプ宣言 (必要な物のみ) @@ -1045,7 +1045,7 @@ static unsigned char *skip_space(unsigned char *p) static unsigned char *skip_word(unsigned char *p) { // prefix - if(*p=='\'') p++; + if(*p=='.') p++; if(*p=='$') p++; // MAP鯖内共有変数用 if(*p=='@') p++; // 一時的変数用(like weiss) if(*p=='#') p++; // account変数用 @@ -2349,7 +2349,7 @@ int get_val(struct script_state*st,struct script_data* data) if(sd) data->u.str = pc_readaccountregstr(sd,name); } - }else if(prefix=='\'') { + }else if(prefix=='.') { struct linkdb_node **n; if( data->ref ) { n = data->ref; @@ -2391,7 +2391,7 @@ int get_val(struct script_state*st,struct script_data* data) if(sd) data->u.num = pc_readaccountreg(sd,name); } - }else if(prefix=='\''){ + }else if(prefix=='.'){ struct linkdb_node **n; if( data->ref ) { n = data->ref; @@ -2444,7 +2444,7 @@ static int set_reg(struct script_state*st,struct map_session_data *sd,int num,ch pc_setaccountreg2str(sd,name,str); else pc_setaccountregstr(sd,name,str); - }else if(prefix=='\'') { + }else if(prefix=='.') { char *p; struct linkdb_node **n; if( ref ) { @@ -2482,7 +2482,7 @@ static int set_reg(struct script_state*st,struct map_session_data *sd,int num,ch pc_setaccountreg2(sd,name,val); else pc_setaccountreg(sd,name,val); - }else if(prefix == '\'') { + }else if(prefix == '.') { struct linkdb_node **n; if( ref ) { n = ref; @@ -2801,9 +2801,9 @@ int buildin_callfunc(struct script_state *st) if( s->type == C_NAME && !s->ref ) { char *name = str_buf+str_data[s->u.num&0x00ffffff].str; // '@ 変数の引き継ぎ - if( name[0] == '\'' && name[1] == '@' ) { + if( name[0] == '.' && name[1] == '@' ) { s->ref = oldval; - } else if( name[0] == '\'' ) { + } else if( name[0] == '.' ) { s->ref = &oldscr->script_vars; } } @@ -2849,7 +2849,7 @@ int buildin_callsub(struct script_state *st) if( s->type == C_NAME && !s->ref ) { char *name = str_buf+str_data[s->u.num&0x00ffffff].str; // '@ 変数の引き継ぎ - if( name[0] == '\'' && name[1] == '@' ) { + if( name[0] == '.' && name[1] == '@' ) { s->ref = oldval; } } @@ -2894,10 +2894,10 @@ int buildin_return(struct script_state *st) sd = &st->stack->stack_data[st->stack->sp-1]; if(sd->type == C_NAME) { char *name = str_buf + str_data[sd->u.num&0x00ffffff].str; - if( name[0] == '\'' && name[1] == '@') { + if( name[0] == '.' && name[1] == '@') { // '@ 変数を参照渡しにすると危険なので値渡しにする get_val(st,sd); - } else if( name[0] == '\'' && !sd->ref) { + } else if( name[0] == '.' && !sd->ref) { // ' 変数は参照渡しでも良いが、参照元が設定されていないと // 元のスクリプトの値を差してしまうので補正する。 sd->ref = &st->script->script_vars; @@ -3492,7 +3492,7 @@ int buildin_setarray(struct script_state *st) char postfix=name[strlen(name)-1]; int i,j; - if( prefix!='$' && prefix!='@' && prefix!='\''){ + if( prefix!='$' && prefix!='@' && prefix!='.'){ ShowWarning("buildin_setarray: illegal scope !\n"); return 1; } @@ -3524,7 +3524,7 @@ int buildin_cleararray(struct script_state *st) int i; void *v; - if( prefix!='$' && prefix!='@' && prefix!='\''){ + if( prefix!='$' && prefix!='@' && prefix!='.'){ ShowWarning("buildin_cleararray: illegal scope !\n"); return 1; } @@ -3558,11 +3558,11 @@ int buildin_copyarray(struct script_state *st) int sz=conv_num(st,& (st->stack->stack_data[st->start+4])); int i; - if( prefix!='$' && prefix!='@' && prefix!='\'' ){ + if( prefix!='$' && prefix!='@' && prefix!='.' ){ printf("buildin_copyarray: illeagal scope !\n"); return 0; } - if( prefix2!='$' && prefix2!='@' && prefix2!='\'' ) { + if( prefix2!='$' && prefix2!='@' && prefix2!='.' ) { printf("buildin_copyarray: illeagal scope !\n"); return 0; } @@ -3619,7 +3619,7 @@ int buildin_getarraysize(struct script_state *st) char prefix=*name; char postfix=name[strlen(name)-1]; - if( prefix!='$' && prefix!='@' && prefix!='\'' ){ + if( prefix!='$' && prefix!='@' && prefix!='.' ){ ShowWarning("buildin_copyarray: illegal scope !\n"); return 1; } @@ -3645,7 +3645,7 @@ int buildin_deletearray(struct script_state *st) if( (st->end > st->start+3) ) count=conv_num(st,& (st->stack->stack_data[st->start+3])); - if( prefix!='$' && prefix!='@' && prefix!='\'' ){ + if( prefix!='$' && prefix!='@' && prefix!='.' ){ ShowWarning("buildin_deletearray: illegal scope !\n"); return 1; } @@ -10626,23 +10626,31 @@ int buildin_setmobdata(struct script_state *st){ } int buildin_mobattack(struct script_state *st) { - int id; - char *target; + int id = 0; + char *target = NULL; struct mob_data *md = NULL; struct map_session_data *sd = NULL; struct block_list *bl = NULL; id = conv_num(st, & (st->stack->stack_data[st->start+2])); - target = conv_str(st, & (st->stack->stack_data[st->start+3])); + if(st->end > st->start + 3) + target = conv_str(st, & (st->stack->stack_data[st->start+3])); - if((sd = map_nick2sd(target)) != NULL || (bl = map_id2bl(atoi(target))) != NULL) { - if (sd) bl = &sd->bl; - md = (struct mob_data *)map_id2bl(id); + if(target){ + sd = map_nick2sd(target); + if(!sd) + bl = map_id2bl(atoi(target)); + else + bl = &sd->bl; + } + + if((md = (struct mob_data *)map_id2bl(id))){ if (md && md->bl.type == BL_MOB) { - md->target_id = bl->id; - md->special_state.ai = 1; - //md->min_chase = distance_bl(&md->bl,map_id2bl(md->target_id)) + md->db->range2; - unit_walktobl(&md->bl, bl, 65025, 2); + md->state.killer = 1; + if(bl){ + md->target_id = bl->id; + unit_walktobl(&md->bl, bl, 65025, 2); + } } } @@ -10832,7 +10840,7 @@ int buildin_getvariableofnpc(struct script_state *st) char *var_name = str_buf+str_data[num&0x00ffffff].str; char *npc_name = conv_str(st,& (st->stack->stack_data[st->start+3])); struct npc_data *nd = npc_name2id(npc_name); - if( var_name[0] != '\'' || var_name[1] == '@' ) { + if( var_name[0] != '.' || var_name[1] == '@' ) { // ' 変数以外はダメ printf("getvariableofnpc: invalid scope %s\n", var_name); push_val(st->stack,C_INT,0); diff --git a/src/map/unit.c b/src/map/unit.c index f0ce5c9ca..610590848 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1087,7 +1087,6 @@ 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