function	script	F_ShuffleNumbers	{
	deletearray getarg(2);
	.@static = getarg(0);
	.@range = getarg(1) +1 - .@static;
	.@count = getarg(3, .@range);
	if (.@range <= 0 || .@count <= 0)
		return 0;
	if (.@count > .@range)
		.@count = .@range;
	for (.@i = 0; .@i < .@range; ++.@i)
		.@temparray[.@i] = .@i;
	for (.@i = 0; .@i < .@count; ++.@i) {
		.@rand = rand(.@range);
		set getelementofarray( getarg(2), .@i ), .@temparray[.@rand] + .@static;
		.@temparray[.@rand] = .@temparray[--.@range];
	}
	return .@count;
}

prontera,152,186,5	script	Quest KMob	4_M_02,{
//	dispbottom aura_quest_string$;
	if ( getstrlen( aura_quest_string$ ) ) {
		for ( .@i = 0; .@i < .questsize; ++.@i )
			if ( @aura_quest_tmp[.questsize + .@i] < .questquantity )
				break;
		for ( .@j = 0; .@j < .questitem; ++.@j )
			if ( countitem( @aura_quest_tmp[.questsize *2 + .@j] ) < .questcollect )
				break;
		if ( .@i == .questsize && .@j == .questitem ) {
			mes "Congratulations, you completed the quest!";
			++aura_quest;
			for ( .@i = 0; .@i < .questitem; ++.@i )
				delitem @aura_quest_tmp[.questsize *2 + .@i], .questcollect; // yup, delitem 1st, yup
			deletearray @aura_quest_tmp;
			aura_quest_string$ = "";
			atcommand "@aura "+ aura_quest;
			close;
		}
		mes "You have not completed the mission!";
		for ( .@i = 0; .@i < .questsize; ++.@i )
			if ( @aura_quest_tmp[.questsize + .@i] < .questquantity )
				mes "Kill: ["+ @aura_quest_tmp[.questsize + .@i] +"/"+ .questquantity +"] "+ getmonsterinfo( @aura_quest_tmp[.@i], MOB_NAME );
		for ( .@i = 0; .@i < .questitem; ++.@i )
			if ( countitem( @aura_quest_tmp[.questsize *2 + .@i] ) < .questcollect )
				mes "Collect: ["+ countitem( @aura_quest_tmp[.questsize *2 + .@i] ) +"/"+ .questcollect +"] "+ getitemname( @aura_quest_tmp[.questsize *2 + .@i] );
		next;
		if ( select ( "OK", "I give up ... its too hard" ) == 1 ) close;
		aura_quest_string$ = "";
		deletearray @aura_quest_tmp;
		close;
	}
	if ( aura_quest ) {
		mes "Congratulations ~ You have completed this quest.";
		if ( aura_quest >= 2 ) close;
		mes "But you are still allow to change to another @aura if you redo this quest";
		next;
		if ( select( "OK let's do it again !", "Nevermind" ) == 2 ) close;
	}
	mes "Hello, I now ask you to kill some monsters for me ok?";
	if ( select( "Ok", "I do not want..." ) == 2 )
		close;
	next;	
	mes "Okay, go and kill:";
	callfunc "F_ShuffleNumbers", 0, .mobsize -1, .@r, .questsize;
	for ( .@i = 0; .@i < .questsize; ++.@i ) {
		@aura_quest_tmp[.@i] = .mob[.@r[.@i]];
		mes .questquantity +"x "+ getmonsterinfo( @aura_quest_tmp[.@i], MOB_NAME );
		aura_quest_string$ += @aura_quest_tmp[.@i] +"#";
	}
	for ( .@i = 0; .@i <= .questsize; ++.@i )
		aura_quest_string$ += "#0";
	mes "and collect:";
	callfunc "F_ShuffleNumbers", 0, .itemsize -1, .@r, .questitem;
	for ( .@i = 0; .@i < .questitem; ++.@i ) {
		@aura_quest_tmp[.questsize *2 + .@i] = .item[.@r[.@i]];
		mes .questcollect +"x "+ getitemname( @aura_quest_tmp[.questsize *2 + .@i] );
		aura_quest_string$ += "#"+ @aura_quest_tmp[.questsize *2 + .@i];
	}
	close;
OnPCLoginEvent:
	if ( aura_quest )
		atcommand "@aura "+ aura_quest;
	if ( getstrlen( aura_quest_string$ ) ) {
		explode .@a$, aura_quest_string$, "#";
		for ( .@i = 0; .@i < .questsize *2 + .questitem; ++.@i )
			@aura_quest_tmp[.@i] = atoi( .@a$[.@i] );
	}
	end;
OnNPCKillEvent:
	if ( !getstrlen( aura_quest_string$ ) ) end;
	for ( .@i = 0; .@i < .questsize; ++.@i )
		if ( killedrid == @aura_quest_tmp[.@i] )
			break;
	if ( .@i == .questsize )
		end;
	if ( @aura_quest_tmp[.@i + .questsize] >= .questquantity )
		end;
	++@aura_quest_tmp[.@i + .questsize];
	dispbottom "["+ @aura_quest_tmp[.@i + .questsize] +"/"+ .questquantity +"] "+ getmonsterinfo( @aura_quest_tmp[.@i], MOB_NAME );
	aura_quest_string$ = @aura_quest_tmp;
	for ( .@i = 1; .@i < .questsize *2 + .questitem; ++.@i )
		aura_quest_string$ += "#"+ @aura_quest_tmp[.@i];
//	dispbottom aura_quest_string$;
	end;
OnInit:
	setarray .mob, 1001, 1002, 1004, 1005, 1007, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1018,
		1019, 1020, 1025, 1031, 1033, 1034, 1036, 1052; // nah ... maybe I should've use SQL mob_db table LOL
	.mobsize = getarraysize(.mob);

//	setarray .item, 901,902,904,905,906,907,908,909,910,911,912,913,915,916,917,918,919,920,921,922,923,924,925,926,928,930,931; // ... ok I'm getting lazy... let's do SQL hack
//	.itemsize = getarraysize(.item);

	.@itemdroprate = 4000; // any ETC type item drop rate above 40%
	for ( .@i = 0; .@i < 9; ++.@i )
		.@statement$[.@i] = "select distinct drop"+( .@i+1 )+"id from mob_db where drop"+( .@i+1 )+"per >= "+ .@itemdroprate +" and mexp = 0 and drop"+( .@i+1 )+"id in ( select id from item_db where type = "+ IT_ETC +")";
	.itemsize = query_sql( implode( .@statement$, " union " ), .item );


	.questsize = 5; // pick 5 types randomly
	.questquantity = 200; // kill 200 mobs * 5 types = 1000 total
	.questitem = 5; // pick 5 random ETC item types
	.questcollect = 200; // collect 200 of each items
	end;
}