Browse Source

* Change scripting engine's NPC scope vars to dot (.) style.
* Improved and (should be fully) fixed the mob control engine.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6769 54d463be-8e91-2dee-dedb-b68131a5f0ec

Lance 19 years ago
parent
commit
e43f38bb0d
8 changed files with 94 additions and 80 deletions
  1. 2 0
      Changelog-Trunk.txt
  2. 48 48
      npc/sample/monster_controller.cpp
  3. 2 1
      src/char/char.c
  4. 2 1
      src/char_sql/char.c
  5. 3 1
      src/map/battle.c
  6. 1 0
      src/map/map.h
  7. 36 28
      src/map/script.c
  8. 0 1
      src/map/unit.c

+ 2 - 0
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

+ 48 - 48
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;

+ 2 - 1
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

+ 2 - 1
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

+ 3 - 1
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)

+ 1 - 0
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; 

+ 36 - 28
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);

+ 0 - 1
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;
 	}