Jump to content
  • 0

how to following NPC ?


wwshakioww

Question


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

I want npc to follow my character after the conversation
A script that can write buffs or open a warehouse as needed

Can anyone do this?

I used to see the "Dedicated Poring" script, which was problematic.
Please help me :D

 

 

Edited by wwshakioww
Link to comment
Share on other sites

14 answers to this question

Recommended Posts

  • 1

  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

3 hours ago, Hijirikawa said:

 

wtf why do it so complicated, rAthena can do the same with unit controller script commands
( hercules mob controller script commands are broken that's why I couldn't say anything there, but over here is working perfectly fine )

function	script	camp_fire	{
	monster "this", -1,-1, "--ja--", 1002, 1, "";
	.@mobid = $@mobid;
	setunitdata .@mobid, UMOB_DMGIMMUNE, true;
	setunitdata .@mobid, UMOB_MODE, MD_STATUS_IMMUNE|MD_SKILL_IMMUNE|MD_KNOCKBACK_IMMUNE;
	getunitdata .@mobid, .@unitdata;
	for ( .@i = 0; .@i < 5; ++.@i ) {
		areapercentheal mapid2name(.@unitdata[UMOB_MAPID]), .@unitdata[UMOB_X]-5, .@unitdata[UMOB_Y]-5, .@unitdata[UMOB_X]+5, .@unitdata[UMOB_Y]+5, 10,1;
		sleep 1000;
	}
	unitkill .@mobid;
	end;
}

 


ok back to topic, well asking for buff and so on needs duplicates, yeah need source modification

 src/custom/script.inc     | 197 ++++++++++++++++++++++++++++++++++++++++++++++
 src/custom/script_def.inc |   3 +
 src/map/npc.cpp           |  11 +--
 src/map/npc.hpp           |  10 +++
 4 files changed, 213 insertions(+), 8 deletions(-)

diff --git a/src/custom/script.inc b/src/custom/script.inc
index 839b990cb..70926e0a8 100644
--- a/src/custom/script.inc
+++ b/src/custom/script.inc
@@ -17,3 +17,200 @@
 //	script_pushint(st,1);
 //	return 0;
 //}
+
+/*==========================================
+ * Duplicate any npc on live server
+ * duplicatenpc "<Source NPC name>","<New NPC shown name>","<New NPC hidden name>","<mapname>",<map_x>,<map_y>,<dir>{, spriteid{, map_xs, map_ys}}};
+ *------------------------------------------*/
+BUILDIN_FUNC(duplicatenpc)
+{
+	int map_x = script_getnum(st, 6);
+	int map_y = script_getnum(st, 7);
+	int dir = script_getnum(st, 8);
+	int spriteid, map_xs = -1, map_ys = -1, sourceid, type, mapid, i;
+	const char *sourcename = script_getstr(st, 2);
+	const char *new_shown_name = script_getstr(st, 3);
+	const char *new_hidden_name = script_getstr(st, 4);
+	const char *mapname = script_getstr(st, 5);
+
+	char new_npc_name[24] = "";
+	struct npc_data *nd_source, *nd_target;
+
+	if(script_hasdata(st, 10))
+		map_xs = (script_getnum(st, 10) < -1) ? -1 : script_getnum(st, 10);
+
+	if(script_hasdata(st, 11))
+		map_ys = (script_getnum(st, 11) < -1) ? -1 : script_getnum(st, 10);
+
+	if(map_xs == -1 && map_ys != -1)
+		map_xs = 0;
+
+	if(map_xs != - 1 && map_ys == -1)
+		map_ys = 0;
+
+	if(strlen(new_shown_name) + strlen(new_hidden_name) > NAME_LENGTH) {
+		ShowError("buildin_duplicatenpc: New NPC shown name + New NPC hidden name is too long (max %d chars). (%s)\n", sourcename, NAME_LENGTH);
+		script_pushint(st, 0);
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	nd_source = npc_name2id(sourcename);
+
+	if(script_hasdata(st, 9))
+		spriteid = (script_getnum(st, 9) < -1) ? -1 : script_getnum(st, 9);
+	else
+		spriteid = nd_source->class_;
+
+	if(nd_source == NULL) {
+		ShowError("buildin_duplicatenpc: original npc not found for duplicate. (%s)\n", sourcename);
+		script_pushint(st, 0);
+		return SCRIPT_CMD_FAILURE;
+	}
+	
+	sourceid = nd_source->bl.id;
+	type = nd_source->subtype;
+	mapid = map_mapname2mapid(mapname);
+
+	if(mapid < 0) {
+		ShowError("buildin_duplicatenpc: target map not found. (%s)\n", mapname);
+		script_pushint(st, 0);
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	CREATE(nd_target, struct npc_data, 1);
+	
+	strcat(new_npc_name, new_shown_name);
+	strncat(new_npc_name, "#", 1);
+	strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));
+
+	safestrncpy(nd_target->name, new_npc_name , sizeof(nd_target->name));
+	safestrncpy(nd_target->exname, new_npc_name, sizeof(nd_target->exname));
+
+	nd_target->bl.prev = nd_target->bl.next = NULL;
+	nd_target->bl.m = mapid;
+	nd_target->bl.x = map_x;
+	nd_target->bl.y = map_y;
+	nd_target->bl.id = npc_get_new_npc_id();
+	nd_target->class_ = spriteid;
+	nd_target->speed = 200;
+	nd_target->src_id = sourceid;
+	nd_target->bl.type = BL_NPC;
+	nd_target->subtype = (enum npc_subtype)type;
+
+	switch(type) {
+		case NPCTYPE_SCRIPT:
+			nd_target->u.scr.xs = map_xs;
+			nd_target->u.scr.ys = map_ys;
+			nd_target->u.scr.script = nd_source->u.scr.script;
+			nd_target->u.scr.label_list = nd_source->u.scr.label_list;
+			nd_target->u.scr.label_list_num = nd_source->u.scr.label_list_num;
+			break;
+		case NPCTYPE_SHOP:
+		case NPCTYPE_CASHSHOP:
+		case NPCTYPE_ITEMSHOP:
+		case NPCTYPE_POINTSHOP:
+		case NPCTYPE_MARKETSHOP:
+			nd_target->u.shop.shop_item = nd_source->u.shop.shop_item;
+			nd_target->u.shop.count = nd_source->u.shop.count;
+			break;
+		case NPCTYPE_WARP:
+			if( !battle_config.warp_point_debug )
+				nd_target->class_ = JT_WARPNPC;
+			else
+				nd_target->class_ = JT_GUILD_FLAG;
+			nd_target->u.warp.xs = map_xs;
+			nd_target->u.warp.ys = map_ys;
+			nd_target->u.warp.mapindex = nd_source->u.warp.mapindex;
+			nd_target->u.warp.x = nd_source->u.warp.x;
+			nd_target->u.warp.y = nd_source->u.warp.y;
+			nd_target->trigger_on_hidden = nd_source->trigger_on_hidden;
+			break;
+	}
+
+	map_addnpc(mapid, nd_target);
+	status_change_init(&nd_target->bl);
+	unit_dataset(&nd_target->bl);
+	nd_target->ud.dir = dir;
+	npc_setcells(nd_target);
+	map_addblock(&nd_target->bl);
+
+	if(spriteid >= 0) {
+		status_set_viewdata(&nd_target->bl, nd_target->class_);
+		clif_spawn(&nd_target->bl);
+	}
+
+	strdb_put(npcname_db, nd_target->exname, nd_target);
+
+	if(type == NPCTYPE_SCRIPT) {
+		for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
+			char* lname = nd_target->u.scr.label_list[i].name;
+			int pos = nd_target->u.scr.label_list[i].pos;
+
+			if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) {
+				struct event_data* ev;
+				char buf[NAME_LENGTH*2+3];
+				snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd_target->exname, lname);
+
+				CREATE(ev, struct event_data, 1);
+				ev->nd = nd_target;
+				ev->pos = pos;
+				if(strdb_put(ev_db, buf, ev))
+					ShowWarning("npc_parse_duplicate : duplicate event %s (%s)\n", buf, nd_target->name);
+			}
+		}
+
+		for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
+			int t = 0, k = 0;
+			char *lname = nd_target->u.scr.label_list[i].name;
+			int pos = nd_target->u.scr.label_list[i].pos;
+			if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
+				struct npc_timerevent_list *te = nd_target->u.scr.timer_event;
+				int j, k = nd_target->u.scr.timeramount;
+				if (te == NULL)
+					te = (struct npc_timerevent_list *)aMalloc(sizeof(struct npc_timerevent_list));
+				else
+					te = (struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
+				for (j = 0; j < k; j++) {
+					if (te[j].timer > t) {
+						memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
+						break;
+					}
+				}
+				te[j].timer = t;
+				te[j].pos = pos;
+				nd_target->u.scr.timer_event = te;
+				nd_target->u.scr.timeramount++;
+			}
+		}
+		nd_target->u.scr.timerid = INVALID_TIMER;
+	}
+
+	script_pushint(st, 1);
+	return SCRIPT_CMD_SUCCESS;
+}
+
+/*==========================================
+ * Remove any npc duplicate on live server
+ * duplicateremove "<NPC name>";
+ *------------------------------------------*/
+BUILDIN_FUNC(duplicateremove)
+{
+	struct npc_data *nd;
+
+	if(script_hasdata(st, 2)) {
+		nd = npc_name2id(script_getstr(st, 2));
+		if(nd == NULL) {
+			script_pushint(st, -1);
+			return SCRIPT_CMD_FAILURE;
+		}
+	} else
+		nd = (struct npc_data *)map_id2bl(st->oid);
+
+	if(!nd->src_id)
+		npc_unload_duplicates(nd);
+	else
+		npc_unload(nd,true);
+
+	script_pushint(st, 1);
+	return SCRIPT_CMD_SUCCESS;
+}
\ No newline at end of file
diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc
index 886399273..177e5cf1a 100644
--- a/src/custom/script_def.inc
+++ b/src/custom/script_def.inc
@@ -9,3 +9,6 @@
  **/
 
 //BUILDIN_DEF(example,""),
+
+BUILDIN_DEF(duplicatenpc, "ssssiii???"),
+BUILDIN_DEF(duplicateremove, "?"),
\ No newline at end of file
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 64ae5a361..cfecfcfa7 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -85,13 +85,8 @@ int npc_get_new_npc_id(void) {
 	}
 }
 
-static DBMap* ev_db; // const char* event_name -> struct event_data*
-static DBMap* npcname_db; // const char* npc_name -> struct npc_data*
-
-struct event_data {
-	struct npc_data *nd;
-	int pos;
-};
+DBMap* ev_db; // const char* event_name -> struct event_data*
+DBMap* npcname_db; // const char* npc_name -> struct npc_data*
 
 static struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
 
@@ -2140,7 +2135,7 @@ static int npc_unload_ev(DBKey key, DBData *data, va_list ap)
 
 //Chk if npc matches src_id, then unload.
 //Sub-function used to find duplicates.
-static int npc_unload_dup_sub(struct npc_data* nd, va_list args)
+int npc_unload_dup_sub(struct npc_data* nd, va_list args)
 {
 	int src_id;
 
diff --git a/src/map/npc.hpp b/src/map/npc.hpp
index ee496ad9e..6d054dcab 100644
--- a/src/map/npc.hpp
+++ b/src/map/npc.hpp
@@ -108,6 +108,14 @@ struct npc_data {
 struct eri;
 extern struct eri *npc_sc_display_ers;
 
+extern DBMap* ev_db; // const char* event_name -> struct event_data*
+extern DBMap* npcname_db; // const char* npc_name -> struct npc_data*
+
+struct event_data {
+	struct npc_data *nd;
+	int pos;
+};
+
 #define START_NPC_NUM 110000000
 
 enum e_job_types
@@ -1241,6 +1249,8 @@ int npc_instanceinit(struct npc_data* nd);
 int npc_instancedestroy(struct npc_data* nd);
 int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amount, int points);
 
+int npc_unload_dup_sub(struct npc_data *nd, va_list args);
+
 void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, int cost[2], bool display);
 
 extern struct npc_data* fake_nd;
function	script	qwerty	{ // run this from item
	getmapxy .@map$, .@x, .@y, BL_PC;
	duplicatenpc "Kafra_Follower", "Kafra_Follower", $@kafra_follower +"", .@map$, .@x, .@y, DIR_SOUTH, 1_F_MARIA;
	addtimer 1, "Kafra_Follower#"+ $@kafra_follower +"::OnStart";
	++$@kafra_follower;
	return;
}

-	script	Kafra_Follower	FAKE_NPC,{
	.@id = atoi( strnpcinfo(2) );
	if ( .masteraid[.@id] != getcharid(3) ) {
		mes "already have a master";
		close;
	}
	mes "do whatever you like to me ^.^";
	next;
	if ( select("buff", "open storage") == 1 ) {
		specialeffect2 EF_INCAGILITY;
		sc_start SC_INCREASEAGI,240000,10;
		specialeffect2 EF_BLESSING;
		sc_start SC_BLESSING,240000,10;
		close;
	}
	close2;
	openstorage;
	end;
OnStart:
	.@id = atoi( strnpcinfo(2) );
	.masteraid[.@id] = getcharid(3);
	npcspeed 150;
	while ( .masteraid[.@id] ) {
		attachrid .masteraid[.@id];
		getmapxy .@map$, .@x, .@y, BL_PC;
		getmapxy .@map1$, .@x1, .@y1, BL_NPC;
		if ( .@map$ != .@map1$ || distance( .@x, .@y, .@x1, .@y1 ) > 15 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			unitwarp getnpcid(0), .@map$, .@x2, .@y2;
		}
		else if ( distance( .@x, .@y, .@x1, .@y1 ) > 5 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			npcwalkto .@x2, .@y2;
		}
		sleep 250;
	}
	duplicateremove strnpcinfo(0);
	end;
OnPCLogoutEvent:
	.@aid = getcharid(3);
	while ( countinarray( .masteraid, .@aid ) ) {
		.@id = inarray( .masteraid, .@aid );
		.masteraid[.@id] = 0;
	}
	end;
}

 

Edited by AnnieRuru
  • MVP 1
  • Like 1
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  78
  • Topics Per Day:  0.03
  • Content Count:  430
  • Reputation:   163
  • Joined:  12/12/17
  • Last Seen:  

how about let then use @storage command and for the buff, there is always item scrolls?

If I am not mistaken, there are pets that can give player buffs.. im not sure but I think there was.. (never tried it).

 

PS: There are lots of healer / buffer npcs here. you can look them up at the search bar.

Edited by pajodex
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

4 hours ago, pajodex said:

그러면 @storage 명령을 사용하고 buff에는 항상 항목 스크롤이 있습니까?

내가 틀렸다고 생각하지 않는다면, 애호가들 에게 줄 수있는 애완 동물이 있습니다 . 확실하지는 않지만 (결코 시도하지 않았습니다).

 

추신 : 힐러 / 버퍼 npcs 여기에 많이 있습니다. 당신은 검색 창에서 그들을 찾을 수 있습니다.

Thx for your answer ?

I just want to make a NPC following for 10 minutes.

I wonder how it is possible?

I want to make sure I follow it for a fixed amount of time.

 

Edited by wwshakioww
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  78
  • Topics Per Day:  0.03
  • Content Count:  430
  • Reputation:   163
  • Joined:  12/12/17
  • Last Seen:  

1 hour ago, wwshakioww said:

I wonder how it is possible?

Spoiler

	while ( .time < 60*10 ) { // set to 10 mins cuz 60 sec * 10 = 10 mins
		getmapxy(.@map$, .@x, .@y, UNITTYPE_PC);	// get character's map xy -- im not sure if still using UNITTYPE_ or BL_
		npcspeed 200;	// set npc walking speed
		npcwalkto .@x, .@y;	// npc walks to the coordinates of the player
		.time++;
		sleep 1000;
	}

 

 untested but it should work..

if you want to learn more.. check doc/script_command.txt.

Spoiler

 


*npcspeed <speed value>;
*npcwalkto <x>,<y>;
*npcstop;

These commands will make the NPC object in question move around the map. As they
currently are, they are a bit buggy and are not useful for much more than making
an NPC move randomly around the map.

'npcspeed' will set the NPCs walking speed to a specified value. As in the
@speed GM command, 200 is the slowest possible speed while 0 is the fastest
possible (instant motion). 100 is the default character walking speed.

'npcwalkto' will start the NPC sprite moving towards the specified coordinates
on the same map it is currently on. The script proceeds immediately after the
NPC begins moving.

'npcstop' will stop the motion.

While in transit, the NPC will be clickable, but invoking it will cause it to
stop moving, which will make its coordinates different from what the client
computed based on the speed and motion coordinates. The effect is rather
unnerving.

Only a few NPC sprites have walking animations, and those that do, do not get
the animation invoked when moving the NPC, due to the problem in the NPC walking
code, which looks a bit silly. You might have better success by defining a job-
sprite based sprite id in 'db/mob_avail.txt' with this.

 

 

Edited by pajodex
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

9 hours ago, pajodex said:

(.time <60 * 10) {// 60 초 × 10 분 = 10의 사촌 10 분으로 설정하면서 getmapxy ( @지도. $, @. X , Y @. , UNITTYPE_PC); // 캐릭터의 맵을 얻는다. xy - 아직 UNITTYPE_ 또는 BL_npcspeed 200을 사용하고 있는지 확실하지 않다 . // 설정 NPC 보행 속도 npcwalkto . @ X , Y @. ; // npc는 플레이어 좌표로 이동합니다 . time ++; 수면 1000; }

Thank you very much !! pajodex +_+;;

But it only moves once at first, then it does not work because there is no "Attached" connection

I looked up script_command in the doc folder and it did not work

 

dfsgsdfag.png

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  78
  • Topics Per Day:  0.03
  • Content Count:  430
  • Reputation:   163
  • Joined:  12/12/17
  • Last Seen:  

1 hour ago, wwshakioww said:

But it only moves once at first, then it does not work because there is no "Attached" connection

Yeah, actually I did not give you off the full code, I want you to learn how to do it yourself.

TIP: read about *getmapxy 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

3 hours ago, pajodex said:

네, 사실 저는 당신을 전체 코드에서 제외시키지 않았습니다, 당신이 직접하는 법을 배우기를 바랍니다.

팁 : * getmapxy에 대한 정보 

Very Thx ?

very very Thx +_+;;

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  303
  • Reputation:   117
  • Joined:  12/10/16
  • Last Seen:  

If you don't have a problem with the NPC moving anywhere and then other players unable to do the quest until the NPC arrives, then...

	if(.m$ == "") {
		getmapxy .m$,.x,.y,UNITTYPE_NPC;
		doevent strnpcinfo(0)+"::OnFollow";
	}
	end;

OnFollow:

	.@npc_id = getnpcid(0);
	.@time = 10*60/2;
	while(.@timer < .@time && playerattached()) {
		getmapxy .@m0$,.@x0,.@y0,UNITTYPE_PC;
		getmapxy .@m1$,.@x1,.@y1,UNITTYPE_NPC;
		.@dis = distance(.@x0,.@y0,.@x1,.@y1);
		getfreecell .@m0$,.@x1,.@y1,.@x0,.@y0,2,2,1|4;
		if(.@dis > 14 || .@m0$ != .@m1$)
			unitwarp .@npc_id,.@m0$,.@x1,.@y1;
		else
			npcwalkto .@x1,.@y1;
		.@timer++;
		sleep2 2000;
	}
	unitwarp .@npc_id,.m$,.x,.y;
	.m$ = "";
	.x = .y = 0;
	end;

 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

9 hours ago, n0tttt said:

If you don't have a problem with the NPC moving anywhere and then other players unable to do the quest until the NPC arrives, then...


	if(.m$ == "") {
		getmapxy .m$,.x,.y,UNITTYPE_NPC;
		doevent strnpcinfo(0)+"::OnFollow";
	}
	end;

OnFollow:

	.@npc_id = getnpcid(0);
	.@time = 10*60/2;
	while(.@timer < .@time && playerattached()) {
		getmapxy .@m0$,.@x0,.@y0,UNITTYPE_PC;
		getmapxy .@m1$,.@x1,.@y1,UNITTYPE_NPC;
		.@dis = distance(.@x0,.@y0,.@x1,.@y1);
		getfreecell .@m0$,.@x1,.@y1,.@x0,.@y0,2,2,1|4;
		if(.@dis > 14 || .@m0$ != .@m1$)
			unitwarp .@npc_id,.@m0$,.@x1,.@y1;
		else
			npcwalkto .@x1,.@y1;
		.@timer++;
		sleep2 2000;
	}
	unitwarp .@npc_id,.m$,.x,.y;
	.m$ = "";
	.x = .y = 0;
	end;

 

I was very impressed with your answer.
Let's run this script ?

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

9 hours ago, n0tttt said:

If you don't have a problem with the NPC moving anywhere and then other players unable to do the quest until the NPC arrives, then...


	if(.m$ == "") {
		getmapxy .m$,.x,.y,UNITTYPE_NPC;
		doevent strnpcinfo(0)+"::OnFollow";
	}
	end;

OnFollow:

	.@npc_id = getnpcid(0);
	.@time = 10*60/2;
	while(.@timer < .@time && playerattached()) {
		getmapxy .@m0$,.@x0,.@y0,UNITTYPE_PC;
		getmapxy .@m1$,.@x1,.@y1,UNITTYPE_NPC;
		.@dis = distance(.@x0,.@y0,.@x1,.@y1);
		getfreecell .@m0$,.@x1,.@y1,.@x0,.@y0,2,2,1|4;
		if(.@dis > 14 || .@m0$ != .@m1$)
			unitwarp .@npc_id,.@m0$,.@x1,.@y1;
		else
			npcwalkto .@x1,.@y1;
		.@timer++;
		sleep2 2000;
	}
	unitwarp .@npc_id,.m$,.x,.y;
	.m$ = "";
	.x = .y = 0;
	end;

 

wow !! very good !! +A+♥ Awesome !!

Thank you very much !!

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

prontera,155,185,4	script	Kafra Follower	1_F_MARIA,{
	if ( .masteraid ) {
		if ( .masteraid != getcharid(3) ) {
			mes "already have a master";
			close;
		}
		else {
			mes "do whatever you like to me ^.^";
			next;
			if ( select("buff", "open storage") == 1 ) {
				specialeffect2 EF_INCAGILITY;
				sc_start SC_INCREASEAGI,240000,10;
				specialeffect2 EF_BLESSING;
				sc_start SC_BLESSING,240000,10;
				close;
			}
			close2;
			openstorage;
			end;
		}
	}
	mes "my master ?";
	next;
	select "Yes";
	.masteraid = getcharid(3);
	close2;
	while ( .masteraid ) {
		attachrid .masteraid;
		getmapxy .@map$, .@x, .@y, UNITTYPE_PC;
		getmapxy .@map1$, .@x1, .@y1, UNITTYPE_NPC;
		if ( .@map$ != .@map1$ || distance( .@x, .@y, .@x1, .@y1 ) > 15 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			unitwarp getnpcid(0), .@map$, .@x2, .@y2;
		}
		else if ( distance( .@x, .@y, .@x1, .@y1 ) > 5 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			npcwalkto .@x2, .@y2;
		}
		sleep 250;
	}
	unitwarp getnpcid(0), "prontera", 155,185;
	end;
OnInit:
	npcspeed 100;
	end;
OnPCLogoutEvent:
	if ( .masteraid == getcharid(3) )
		.masteraid = 0;
	end;
}

a simple OnPCLogoutEvent should let the npc go back to its location

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  19
  • Topics Per Day:  0.01
  • Content Count:  193
  • Reputation:   41
  • Joined:  07/21/16
  • Last Seen:  

Interesting, looking at it, could this be coupled with Emistry's work? The idea being, players can get 1 exclusive NPC for their own use? I am not quite sure if it is possible, but with how the camp fire works, it should be right?

 

Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  


 

Edited by wwshakioww
Link to comment
Share on other sites

  • 0

  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  19
  • Reputation:   4
  • Joined:  10/24/18
  • Last Seen:  

16 hours ago, AnnieRuru said:

prontera,155,185,4	script	Kafra Follower	1_F_MARIA,{
	if ( .masteraid ) {
		if ( .masteraid != getcharid(3) ) {
			mes "already have a master";
			close;
		}
		else {
			mes "do whatever you like to me ^.^";
			next;
			if ( select("buff", "open storage") == 1 ) {
				specialeffect2 EF_INCAGILITY;
				sc_start SC_INCREASEAGI,240000,10;
				specialeffect2 EF_BLESSING;
				sc_start SC_BLESSING,240000,10;
				close;
			}
			close2;
			openstorage;
			end;
		}
	}
	mes "my master ?";
	next;
	select "Yes";
	.masteraid = getcharid(3);
	close2;
	while ( .masteraid ) {
		attachrid .masteraid;
		getmapxy .@map$, .@x, .@y, UNITTYPE_PC;
		getmapxy .@map1$, .@x1, .@y1, UNITTYPE_NPC;
		if ( .@map$ != .@map1$ || distance( .@x, .@y, .@x1, .@y1 ) > 15 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			unitwarp getnpcid(0), .@map$, .@x2, .@y2;
		}
		else if ( distance( .@x, .@y, .@x1, .@y1 ) > 5 ) {
			while ( checkcell( .@map$, .@x2 = .@x + rand(-2,2), .@y2 = .@y + rand(-2,2), cell_chknopass ) );
			npcwalkto .@x2, .@y2;
		}
		sleep 250;
	}
	unitwarp getnpcid(0), "prontera", 155,185;
	end;
OnInit:
	npcspeed 100;
	end;
OnPCLogoutEvent:
	if ( .masteraid == getcharid(3) )
		.masteraid = 0;
	end;
}

a simple OnPCLogoutEvent should let the npc go back to its location

Wow !!

It's perfect.
That's more than the script I wanted

Thank you very much
I was impressed with your letters.

 

I'm sorry, can I ask you one more question?

how can i this script Timer 10 min ?

 

Edited by wwshakioww
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...