Browse Source

* Merged eAthena ea:15187 by ai4rei, effect list improvements (doc\effect_list.txt)
* Follow-up r16787, revised documentation and comments on MD5 hash check
* Added svn:eol-style=native property on some recent files

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

euphyy 12 years ago
parent
commit
867008b100
4 changed files with 360 additions and 365 deletions
  1. 5 4
      conf/login_athena.conf
  2. 29 29
      doc/effect_list.txt
  3. 38 44
      doc/md5_hashcheck.txt
  4. 288 288
      npc/custom/quests/hunting_missions.txt

+ 5 - 4
conf/login_athena.conf

@@ -136,13 +136,14 @@ account.engine: auto
 //account.sql.accreg_db: global_reg_value
 //account.sql.accreg_db: global_reg_value
 
 
 // Client MD5 hash check
 // Client MD5 hash check
-// Check client hash?
+// If turned on, the login server will check if the client's hash matches
+// the value below, and will not connect tampered clients.
+// Note: see doc\md5_hashcheck.txt for more details.
 client_hash_check: off
 client_hash_check: off
 
 
-// Put your client hashes here, a player can login into the server using
-// a hash with a group_id equal or lower the account group_id
+// Client MD5 hashes
+// A player can login with a client hash at or below the account group_id.
 // Format: group_id, hash
 // Format: group_id, hash
-// Examples:
 client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
 client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
 client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
 client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
 
 

+ 29 - 29
doc/effect_list.txt

@@ -739,14 +739,14 @@ Number	Description
 720.	Yellow version of Soul Breaker
 720.	Yellow version of Soul Breaker
 721.	Adoramus (lightning bolt)
 721.	Adoramus (lightning bolt)
 722.	Ignition Break (big explosion)
 722.	Ignition Break (big explosion)
-723.	Noise Sound
+723.	Hundred Spear (sound effect)
 724.	Green version of Detecting
 724.	Green version of Detecting
-725.	Detecting
+725.	Oratorio (like Detecting)
 726.	Frost Misty (blue vapor and bubbles)
 726.	Frost Misty (blue vapor and bubbles)
-727.	Comet
+727.	Crimson Rock
 728.	Small fire (part of Hell Inferno)
 728.	Small fire (part of Hell Inferno)
 729.	Marsh of Abyss (like Close Confine)
 729.	Marsh of Abyss (like Close Confine)
-730.	Small, cartoony explosion
+730.	Small, cartoony explosion (part of Soul Expansion)
 731.	Dragon Howling (blinking, expanding circle)
 731.	Dragon Howling (blinking, expanding circle)
 732.	Spike from the ground
 732.	Spike from the ground
 733.	Fluffy Ball flying by
 733.	Fluffy Ball flying by
@@ -755,35 +755,35 @@ Number	Description
 736.	(Nothing)
 736.	(Nothing)
 737.	(Nothing)
 737.	(Nothing)
 738.	(Nothing)
 738.	(Nothing)
-739.	Small pod appearing
-740.	Different small pod
-741.	Different small pod
-742.	Different small pod
-743.	Different small pod
+739.	Old Magenta Trap
+740.	Old Cobald Trap
+741.	Old Maize Trap
+742.	Old Verdure Trap
+743.	White Ranger Trap
 744.	Camouflage
 744.	Camouflage
 745.	Aimed Bolt (crosshairs)
 745.	Aimed Bolt (crosshairs)
 746.	Arrow Storm
 746.	Arrow Storm
 747.	Falling white feathers
 747.	Falling white feathers
 748.	Falling blue feathers
 748.	Falling blue feathers
-749.	Shields
+749.	Millennium Shield
 750.	Detonator (blue sparkles)
 750.	Detonator (blue sparkles)
-751.	Shots from a direction
-752.	Some blinking filter
-753.	Sparkles
+751.	Releasing summoned warlock spheres
+752.	Like Energy Coat, but not as dark
+753.	Clearance
 754.	Green warp portal (root of Epiclesis)
 754.	Green warp portal (root of Epiclesis)
 755.	Oratio (spinning blue symbol)
 755.	Oratio (spinning blue symbol)
 756.	Enchant Blade (like Berserk Potion)
 756.	Enchant Blade (like Berserk Potion)
-757.	Stargate-like wormhole animation
-758.	Rolling Cutter (1)
-759.	Rolling Cutter (2)
-760.	Rolling Cutter (3)
-761.	Rolling Cutter (4)
-762.	Rolling Cutter (5)
-763.	Rolling Cutter (6)
-764.	Rolling Cutter (7)
-765.	Rolling Cutter (8)
-766.	Rolling Cutter (9)
-767.	Rolling Cutter (10)
+757.	Third Class Aura (Middle)
+758.	Rolling Cutter - Spin Count 1
+759.	Rolling Cutter - Spin Count 2
+760.	Rolling Cutter - Spin Count 3
+761.	Rolling Cutter - Spin Count 4
+762.	Rolling Cutter - Spin Count 5
+763.	Rolling Cutter - Spin Count 6
+764.	Rolling Cutter - Spin Count 7
+765.	Rolling Cutter - Spin Count 8
+766.	Rolling Cutter - Spin Count 9
+767.	Rolling Cutter - Spin Count 10
 768.	Blinking
 768.	Blinking
 769.	Cross Ripper Slasher (flying knives)
 769.	Cross Ripper Slasher (flying knives)
 770.	Strip sound
 770.	Strip sound
@@ -791,10 +791,10 @@ Number	Description
 772.	Poison particles
 772.	Poison particles
 773.	Expanding purple aura (part of Phantom Menace)
 773.	Expanding purple aura (part of Phantom Menace)
 774.	Axe Boomerang
 774.	Axe Boomerang
-775.	Spin
-776.	Half-automatic gunshots
+775.	Spinning character sprite
+776.	Like Desperado sound effect
 777.	Faded light from the ground [S]
 777.	Faded light from the ground [S]
-778.	Expanding white aura
+778.	Expanding white aura (like Clearance)
 779.	Faded light from the ground [S]
 779.	Faded light from the ground [S]
 780.	Expanding red aura (from Infrared Scan)
 780.	Expanding red aura (from Infrared Scan)
 781.	Magnetic Field (purple chains)
 781.	Magnetic Field (purple chains)
@@ -805,8 +805,8 @@ Number	Description
 786.	Symbol with bleeping sound [S]
 786.	Symbol with bleeping sound [S]
 787.	Flare Launcher (line of fire)
 787.	Flare Launcher (line of fire)
 788.	Venom Impress (green skull)
 788.	Venom Impress (green skull)
-789.	Two Ancillas
-790.	Flame symbol
+789.	Freezing Status Effect (two ancillas)
+790.	Burning Status Effect (flame symbol)
 791.	Two ice shots
 791.	Two ice shots
 792.	Upward streaming white particles
 792.	Upward streaming white particles
 793.	Same, but more brief
 793.	Same, but more brief

+ 38 - 44
doc/md5_hashcheck.txt

@@ -1,44 +1,38 @@
-//===== rAthena Documentation ================================
-//= Login Server's MD5 Hash Check
-//===== By: ==================================================
-//= rAthena Dev Team
-//===== Current Version: =====================================
-//= 20120921
-//===== Description: =========================================
-//= This file outlines how the built-in MD5 Hash Check is
-//= used and steps enable it.
-//============================================================
-
-In revision r16771, the login server received an update that allows it to perform
-a server-side check of the client to find out it's MD5 hash. This update is an
-effort towards ensuring that a user has either:
-a.) not been tampered with the client
-b.) using the client specific to that particular server
-
-At present, we know that the client can only send the correct MD5 hash to the server
-when using particular server types, so a diff is required to ensure that any client
-can send the hash. A link to the required diff plugin for WeeDiffGen can be found at:
-http://rathena.org/board/topic/70841-r16771-client-md5-hash-check/
-
-Check conf/login_athena.conf for instruction on how to enable it.
-
-In conf/login_athena.conf you will find the following:
-// Client MD5 hash check
-// Check client hash?
-client_hash_check: off
-
-This setting simply accepts on or off.
-
-
-// Put your client hashes here, a player can login into the server using
-// a hash with a group_id equal or lower the account group_id
-// Format: group_id, hash
-// Examples:
-client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
-client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
-
-Once enabled, you would use those lines to configure this feature (or even as an example).
-The group_id can be any of the groups in conf/groups.conf and can be particularly useful
-if, for example, you wanted to restrict normal players from dual-clienting and use a lower
-number for chat flooding, but wanted to allow dual-clienting and 255 lines before the chat
-flood kicks in for your GMs.
+//===== rAthena Documentation ================================
+//= MD5 Hash Check
+//===== By: ==================================================
+//= rAthena Dev Team
+//===== Current Version: =====================================
+//= 20120921
+//===== Description: =========================================
+//= This file outlines the login server's MD5 hash check.
+//============================================================
+
+The login server is able to perform a check of the client's MD5 hash.
+This will ensure that a user has not tampered with the client and that
+the client is the one specific to your server.
+
+The client can only send the correct MD5 hash to the server on certain
+server types, so a client diff is required to ensure the hash is sent.
+A link containing the required WeeDiffGen plugin can be found at:
+http://rathena.org/board/topic/70841-r16771-client-md5-hash-check/
+
+The settings for the hash check are located in conf\login_athena.conf:
+
+// Client MD5 hash check
+// If turned on, the login server will check if the client's hash matches
+// the value below, and will not connect tampered clients.
+// Note: see doc\md5_hashcheck.txt for more details.
+client_hash_check: off
+
+// Client MD5 hashes
+// A player can login with a client hash at or below the account group_id.
+// Format: group_id, hash
+client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5
+client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae
+
+To enable MD5 hash checks, set 'client_hash_check' to 'on'.
+The 'client_hash' group_id can be any of the groups in conf\groups.conf,
+and is particularly useful if you wanted to allow GMs a different client
+than normal players; for example, a GM client could be hexed differently
+with dual-clienting enabled and chat flood disabled.

+ 288 - 288
npc/custom/quests/hunting_missions.txt

@@ -1,289 +1,289 @@
-//===== rAthena Script =======================================
-//= Hunting Missions
-//===== By: ==================================================
-//= Euphy
-//===== Current Version: =====================================
-//= 1.1a
-//===== Compatible With: ===================================== 
-//= rAthena SVN
-//===== Description: =========================================
-//= Random hunting missions.
-//= Rewards are based on quest difficulty.
-//============================================================
-
-prontera,152,187,6	script	Hunting Missions	951,{
-function Chk; function Cm;
-	mes "[Hunting Missions]";
-	mes "Hello, "+strcharinfo(0)+"!";
-	if (!#Mission_Delay) {
-		next;
-		mes "[Hunting Missions]";
-		mes "I can't find any records...";
-		mes "You must be new here!";
-		emotion e_omg;
-		next;
-		callsub Mission_Info;
-		emotion e_go;
-		set #Mission_Delay,1;
-		close;
-	}
-	mes rand(2)?"Working hard, as always...":"Not slacking, I hope...";
-	mes "Is there anything I can help";
-	mes "you with?";
-	mes " ";
-	mes "^777777~ You've completed ^0055FF"+Mission_Total+"^777777 mission"+((Mission_Total == 1)?"":"s")+". ~^000000";
-	next;
-	switch(select(((!Mission1)?" ~ New Mission::":": ~ Mission Status: ~ Abandon Mission")+": ~ Information: ~ Mission Shop: ~ View Top Hunters: ~ ^777777Cancel^000000")) {
-	case 1:
-		mes "[Hunting Missions]";
-		if (#Mission_Count) {
-			mes "You've started a mission";
-			mes "on another character.";
-			close;
-		}
-		if (#Mission_Delay > gettimetick(2) && .Delay) {
-			set .@i, #Mission_Delay-gettimetick(2);
-			if (.@i > 3600) set .@j$, (.@i/3600)+" hour"+(((.@i/3600) == 1)?"":"s");
-			else if (.@i > 60) set .@j$, (.@i/60)+" minute"+(((.@i/60) == 1)?"":"s");
-			else set .@j$, (.@i)+" second"+((.@i == 1)?"":"s");
-			mes "I'm afraid you'll have to wait "+.@j$+" before taking another mission.";
-			close;
-		}
-		mes "You must hunt:";
-		freeloop(1);
-		set .@size, getarraysize(.NoRange);
-		for (set .@i,0; .@i<.Quests; set .@i,.@i+1) {
-			set .@valid,0;
-			while (!.@valid) {
-				set .@valid,1;
-				set .@mob, rand(1001,1999);
-				// Is mob ID blacklisted?
-				if (compare(.Restrict$[0],""+.@mob) || compare(.Restrict$[1],""+.@mob)) set .@valid,0;
-				// Is mob ID interval blacklisted?
-				if (.@valid) for(set .@j,0; .@j<.@size; set .@j,.@j+2)
-					if (.@mob > .NoRange[.@j] && .@mob < .NoRange[.@j+1]) {
-						set .@valid,0;
-						break;
-					}
-				// Is mob a duplicate?
-				if (.@valid) for(set .@j,0; .@j<.@i; set .@j,.@j+1)
-					if (strmobinfo(1,.@mob) == strmobinfo(1,getd("Mission"+.@j))) {
-						set .@valid,0;
-						break;
-					}
-				// Is mob an MVP?
-				if (.@valid) if (getmonsterinfo(.@mob,22)) set .@valid,0;
-			}
-			setd "Mission"+.@i, .@mob;
-			setd "Mission"+.@i+"_",0;
-		}
-		set #Mission_Count, rand(.Count[0],.Count[1]);
-		freeloop(0);
-		callsub Mission_Status;
-		set @f,0;
-		next;
-		mes "[Hunting Missions]";
-		mes "Report back when";
-		mes "you've finished.";
-		mes "Good luck!";
-		close;
-	case 2:
-		mes "[Hunting Missions]";
-		mes "Mission status:";
-		callsub Mission_Status;
-		if (@f) { set @f,0; close; }
-		next;
-		mes "[Hunting Missions]";
-		mes "Oh, you're done!";
-		mes "Good work.";
-		mes "Here's your reward.";
-		emotion e_no1;
-		specialeffect2 377;
-		deletearray .@j[0], getarraysize(.@j);
-		for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
-			set .@j[.@i], getd("Mission"+.@i);
-			set .@j[.Quests], .@j[.Quests]+strmobinfo(3,.@j[.@i]);
-			set .@j[.Quests+1], .@j[.Quests+1]+strmobinfo(6,.@j[.@i]);
-			set .@j[.Quests+2], .@j[.Quests+2]+strmobinfo(7,.@j[.@i]);
-			setd "Mission"+.@i,0;
-			setd "Mission"+.@i+"_",0;
-		}
-		set #Mission_Points, #Mission_Points+(3+(.@j[.Quests]/.Quests/6));
-		getexp (#Mission_Count*.@j[.Quests+1]/5),(#Mission_Count*.@j[.Quests+2]/5);
-		set Zeny, Zeny+(#Mission_Count*.Quests*.@j[.@i]*.Multiplier);
-		set #Mission_Count,0;
-		if (.Delay) set #Mission_Delay, gettimetick(2)+(.Delay*3600);
-		set Mission_Total, Mission_Total+1;
-		if (Mission_Total == 1) query_sql("INSERT INTO `global_reg_value` (`char_id`,`str`,`value`,`type`,`account_id`) VALUES ("+getcharid(0)+",'Mission_Total','1',3,0)");
-		else query_sql("UPDATE `global_reg_value` SET `value` = "+Mission_Total+" WHERE char_id = "+getcharid(0)+" AND `str` = 'Mission_Total'");
-		close;
-	case 3:
-		mes "[Hunting Missions]";
-		mes "Do you really want to";
-		mes "abandon your mission?";
-		if (.Delay) mes "Your delay time will not be reset.";
-		next;
-		switch(select(" ~ Abandon...: ~ ^777777Cancel^000000")) {
-		case 1:
-			mes "[Hunting Missions]";
-			mes "Alright, I've dropped";
-			mes "your current mission.";
-			specialeffect2 462;
-			for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
-				setd "Mission"+.@i,0;
-				setd "Mission"+.@i+"_",0;
-			}
-			set #Mission_Count,0;
-			if (.Delay) set #Mission_Delay, gettimetick(2)+(.Delay*3600);
-			close;
-		case 2:
-			mes "[Hunting Missions]";
-			mes "I knew you were kidding!";
-			mes "Keep up the good work.";
-			emotion e_heh;
-			close;
-		}
-	case 4:
-		callsub Mission_Info;
-		close;
-	case 5:
-		mes "[Hunting Missions]";
-		mes "You have ^0055FF"+#Mission_Points+"^000000 Mission Points.";
-		mes "Use them well!";
-		callshop "mission_shop",1;
-		npcshopattach "mission_shop";
-		end;
-	case 6:
-		mes "[Hunting Missions]";
-		mes "The top hunters are:";
-		query_sql("SELECT `name`,CAST(`value` AS SIGNED) FROM `global_reg_value` LEFT JOIN `char` ON `global_reg_value`.char_id = `char`.char_id WHERE `global_reg_value`.str = 'Mission_Total' ORDER BY CAST(`value` AS SIGNED) DESC LIMIT 5",.@name$,.@val);
-		for(set .@i,0; .@i<5; set .@i,.@i+1)
-			mes "  [Rank "+(.@i+1)+"]  "+((.@name$[.@i] == "")?"^777777none":"^0055FF"+.@name$[.@i]+"^000000 : ^FF0000"+.@val[.@i]+" pt.")+"^000000";
-		close;
-	case 7:
-		mes "[Hunting Missions]";
-		mes "Nothing? Okay...";
-		emotion e_hmm;
-		close;
-	}
-
-Mission_Status:
-	set @f,0;
-	deletearray .@j[0], getarraysize(.@j);
-	for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
-		set .@j[.@i], getd("Mission"+.@i);
-		set .@j[.Quests], .@j[.Quests]+strmobinfo(3,.@j[.@i]);
-		set .@j[.Quests+1], .@j[.Quests+1]+strmobinfo(6,.@j[.@i]);
-		set .@j[.Quests+2], .@j[.Quests+2]+strmobinfo(7,.@j[.@i]);
-		mes " > "+Chk(getd("Mission"+.@i+"_"),#Mission_Count)+strmobinfo(1,.@j[.@i])+" ("+getd("Mission"+.@i+"_")+"/"+#Mission_Count+")^000000";
-	}
-	set .@Mission_Points, 3+(.@j[.Quests]/.Quests/6);
-	set .@Base_Exp, #Mission_Count*.@j[.Quests+1]/5;
-	set .@Job_Exp, #Mission_Count*.@j[.Quests+2]/5;
-	set .@Zeny, #Mission_Count*.Quests*.@j[.@i]*.Multiplier;
-	next;
-	mes "[Hunting Missions]";
-	mes "Mission rewards:";
-	mes " > Mission Points: ^0055FF"+.@Mission_Points+"^000000";
-	mes " > Base Experience: ^0055FF"+Cm(.@Base_Exp)+"^000000";
-	mes " > Job Experience: ^0055FF"+Cm(.@Job_Exp)+"^000000";
-	mes " > Zeny: ^0055FF"+Cm(.@Zeny)+"^000000";
-	return;
-
-Mission_Info:
-	mes "[Hunting Missions]";
-	mes "If you so choose, I can assign";
-	mes "you a random hunting quest.";
-	mes "Some are easier than others, but";
-	mes "the rewards increase with difficulty.";
-	next;
-	mes "[Hunting Missions]";
-	mes "Missions points are shared";
-	mes "amongst all your characters.";
-	if (.Delay) mes "Delay time is, too.";
-	mes "You can't take missions on";
-	mes "multiple characters at once.";
-	next;
-	mes "[Hunting Missions]";
-	mes "You can start a quest";
-	if (.Delay) mes "every "+((.Delay == 1)?"hour.":.Delay+" hours.");
-	else mes "whenever you want.";
-	mes "That's everything~";
-	return;
-
-function Chk {
-	if (getarg(0) < getarg(1)) { set @f,1; return "^FF0000"; }
-	else return "^00FF00"; }
-
-function Cm {
-	set .@str$, getarg(0);
-	for(set .@i,getstrlen(.@str$)-3; .@i>0; set .@i,.@i-3)
-		set .@str$, insertchar(.@str$,",",.@i);
-	return .@str$; }
-
-OnBuyItem:
-	set @cost,0;
-	for(set .@i,0; .@i<getarraysize(@bought_nameid); set .@i,.@i+1)
-		for(set .@j,0; .@j<getarraysize(.Shop); set .@j,.@j+2)
-			if (@bought_nameid[.@i] == .Shop[.@j]) {
-				set @cost, @cost+(.Shop[.@j+1]*@bought_quantity[.@i]);
-				break;
-			}
-	mes "[Hunting Missions]";
-	if (@cost > #Mission_Points) mes "You don't have enough Mission Points.";
-	else {
-		for(set .@i,0; .@i<getarraysize(@bought_nameid); set .@i,.@i+1) {
-			getitem @bought_nameid[.@i], @bought_quantity[.@i];
-			dispbottom "Purchased "+@bought_quantity[.@i]+"x "+getitemname(@bought_nameid[.@i])+".";
-		}
-		set #Mission_Points, #Mission_Points-@cost;
-		mes "Deal completed.";
-		emotion e_cash;
-	}
-	set @cost,0;
-	deletearray @bought_nameid[0], getarraysize(@bought_nameid);
-	deletearray @bought_quantity[0], getarraysize(@bought_quantity);
-	close;
-
-OnNPCKillEvent:
-	if (!#Mission_Count || !Mission1) end;
-	for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
-		if (strmobinfo(1,killedrid) == strmobinfo(1,getd("Mission"+.@i))) {
-			if (getd("Mission"+.@i+"_") < #Mission_Count) {
-				set .@j, getd("Mission"+.@i+"_")+1;
-				setd "Mission"+.@i+"_", .@j;
-				dispbottom "[Hunting Mission] Killed "+.@j+" of "+#Mission_Count+" "+strmobinfo(1,killedrid)+".";
-			}
-			break;
-		}
-	}
-	end;
-
-OnInit:
-	set .Delay,12;		// Quest delay, in hours (0 to disable).
-	set .Quests,4;		// Number of subquests per quest (increases rewards).
-	set .Multiplier,60;	// Multiplier for Zeny reward calculation.
-	setarray .Count[0],	// Min and max monsters per subquest (increases rewards).
-		40,70;
-	setarray .Shop[0],	// Reward items: <ID>,<point cost> (about 10~20 points per hunt).
-		512,1,513,1,514,1,538,5,539,5,558,10,561,10;
-	setarray .Restrict$[0],	// Blacklisted mob IDs.
-	    "1003,1006,1017,1021,1022,1027,1043,1062,1075,1096,"+
-	    "1108,1120,1136,1137,1168,1171,1172,1173,1198,1200,"+
-	    "1203,1204,1205,1210,1212,1217,1218,1244,1245,1247,",
-	    "1250,1259,1262,1268,1270,1311,1313,1388,1407,1411,"+
-	    "1414,1496,1501,1502,1515,1618,1624,1625,1626,1629,"+
-	    "1669,1674,1675,1676,1677,1678,1679,1681,1834,1835,"+
-	    "1868,1990,1991,1996,1997,1998";
-	setarray .NoRange[0],	// Blacklisted mob ID ranges.
-	    1077,1094,  1180,1188,  1219,1242,  1282,1310,  1323,1365,
-	    1392,1400,  1417,1493,  1517,1613,  1639,1652,  1657,1668,
-	    1682,1692,  1703,1713,  1718,1769,  1784,1829,  1838,1864,
-	    1870,1986;
-
-	npcshopdelitem "mission_shop",512;
-	for(set .@i,0; .@i<getarraysize(.Shop); set .@i,.@i+2)
-		npcshopadditem "mission_shop", .Shop[.@i], .Shop[.@i+1];
-	end;
-}
+//===== rAthena Script =======================================
+//= Hunting Missions
+//===== By: ==================================================
+//= Euphy
+//===== Current Version: =====================================
+//= 1.1a
+//===== Compatible With: ===================================== 
+//= rAthena SVN
+//===== Description: =========================================
+//= Random hunting missions.
+//= Rewards are based on quest difficulty.
+//============================================================
+
+prontera,152,187,6	script	Hunting Missions	951,{
+function Chk; function Cm;
+	mes "[Hunting Missions]";
+	mes "Hello, "+strcharinfo(0)+"!";
+	if (!#Mission_Delay) {
+		next;
+		mes "[Hunting Missions]";
+		mes "I can't find any records...";
+		mes "You must be new here!";
+		emotion e_omg;
+		next;
+		callsub Mission_Info;
+		emotion e_go;
+		set #Mission_Delay,1;
+		close;
+	}
+	mes rand(2)?"Working hard, as always...":"Not slacking, I hope...";
+	mes "Is there anything I can help";
+	mes "you with?";
+	mes " ";
+	mes "^777777~ You've completed ^0055FF"+Mission_Total+"^777777 mission"+((Mission_Total == 1)?"":"s")+". ~^000000";
+	next;
+	switch(select(((!Mission1)?" ~ New Mission::":": ~ Mission Status: ~ Abandon Mission")+": ~ Information: ~ Mission Shop: ~ View Top Hunters: ~ ^777777Cancel^000000")) {
+	case 1:
+		mes "[Hunting Missions]";
+		if (#Mission_Count) {
+			mes "You've started a mission";
+			mes "on another character.";
+			close;
+		}
+		if (#Mission_Delay > gettimetick(2) && .Delay) {
+			set .@i, #Mission_Delay-gettimetick(2);
+			if (.@i > 3600) set .@j$, (.@i/3600)+" hour"+(((.@i/3600) == 1)?"":"s");
+			else if (.@i > 60) set .@j$, (.@i/60)+" minute"+(((.@i/60) == 1)?"":"s");
+			else set .@j$, (.@i)+" second"+((.@i == 1)?"":"s");
+			mes "I'm afraid you'll have to wait "+.@j$+" before taking another mission.";
+			close;
+		}
+		mes "You must hunt:";
+		freeloop(1);
+		set .@size, getarraysize(.NoRange);
+		for (set .@i,0; .@i<.Quests; set .@i,.@i+1) {
+			set .@valid,0;
+			while (!.@valid) {
+				set .@valid,1;
+				set .@mob, rand(1001,1999);
+				// Is mob ID blacklisted?
+				if (compare(.Restrict$[0],""+.@mob) || compare(.Restrict$[1],""+.@mob)) set .@valid,0;
+				// Is mob ID interval blacklisted?
+				if (.@valid) for(set .@j,0; .@j<.@size; set .@j,.@j+2)
+					if (.@mob > .NoRange[.@j] && .@mob < .NoRange[.@j+1]) {
+						set .@valid,0;
+						break;
+					}
+				// Is mob a duplicate?
+				if (.@valid) for(set .@j,0; .@j<.@i; set .@j,.@j+1)
+					if (strmobinfo(1,.@mob) == strmobinfo(1,getd("Mission"+.@j))) {
+						set .@valid,0;
+						break;
+					}
+				// Is mob an MVP?
+				if (.@valid) if (getmonsterinfo(.@mob,22)) set .@valid,0;
+			}
+			setd "Mission"+.@i, .@mob;
+			setd "Mission"+.@i+"_",0;
+		}
+		set #Mission_Count, rand(.Count[0],.Count[1]);
+		freeloop(0);
+		callsub Mission_Status;
+		set @f,0;
+		next;
+		mes "[Hunting Missions]";
+		mes "Report back when";
+		mes "you've finished.";
+		mes "Good luck!";
+		close;
+	case 2:
+		mes "[Hunting Missions]";
+		mes "Mission status:";
+		callsub Mission_Status;
+		if (@f) { set @f,0; close; }
+		next;
+		mes "[Hunting Missions]";
+		mes "Oh, you're done!";
+		mes "Good work.";
+		mes "Here's your reward.";
+		emotion e_no1;
+		specialeffect2 377;
+		deletearray .@j[0], getarraysize(.@j);
+		for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
+			set .@j[.@i], getd("Mission"+.@i);
+			set .@j[.Quests], .@j[.Quests]+strmobinfo(3,.@j[.@i]);
+			set .@j[.Quests+1], .@j[.Quests+1]+strmobinfo(6,.@j[.@i]);
+			set .@j[.Quests+2], .@j[.Quests+2]+strmobinfo(7,.@j[.@i]);
+			setd "Mission"+.@i,0;
+			setd "Mission"+.@i+"_",0;
+		}
+		set #Mission_Points, #Mission_Points+(3+(.@j[.Quests]/.Quests/6));
+		getexp (#Mission_Count*.@j[.Quests+1]/5),(#Mission_Count*.@j[.Quests+2]/5);
+		set Zeny, Zeny+(#Mission_Count*.Quests*.@j[.@i]*.Multiplier);
+		set #Mission_Count,0;
+		if (.Delay) set #Mission_Delay, gettimetick(2)+(.Delay*3600);
+		set Mission_Total, Mission_Total+1;
+		if (Mission_Total == 1) query_sql("INSERT INTO `global_reg_value` (`char_id`,`str`,`value`,`type`,`account_id`) VALUES ("+getcharid(0)+",'Mission_Total','1',3,0)");
+		else query_sql("UPDATE `global_reg_value` SET `value` = "+Mission_Total+" WHERE char_id = "+getcharid(0)+" AND `str` = 'Mission_Total'");
+		close;
+	case 3:
+		mes "[Hunting Missions]";
+		mes "Do you really want to";
+		mes "abandon your mission?";
+		if (.Delay) mes "Your delay time will not be reset.";
+		next;
+		switch(select(" ~ Abandon...: ~ ^777777Cancel^000000")) {
+		case 1:
+			mes "[Hunting Missions]";
+			mes "Alright, I've dropped";
+			mes "your current mission.";
+			specialeffect2 462;
+			for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
+				setd "Mission"+.@i,0;
+				setd "Mission"+.@i+"_",0;
+			}
+			set #Mission_Count,0;
+			if (.Delay) set #Mission_Delay, gettimetick(2)+(.Delay*3600);
+			close;
+		case 2:
+			mes "[Hunting Missions]";
+			mes "I knew you were kidding!";
+			mes "Keep up the good work.";
+			emotion e_heh;
+			close;
+		}
+	case 4:
+		callsub Mission_Info;
+		close;
+	case 5:
+		mes "[Hunting Missions]";
+		mes "You have ^0055FF"+#Mission_Points+"^000000 Mission Points.";
+		mes "Use them well!";
+		callshop "mission_shop",1;
+		npcshopattach "mission_shop";
+		end;
+	case 6:
+		mes "[Hunting Missions]";
+		mes "The top hunters are:";
+		query_sql("SELECT `name`,CAST(`value` AS SIGNED) FROM `global_reg_value` LEFT JOIN `char` ON `global_reg_value`.char_id = `char`.char_id WHERE `global_reg_value`.str = 'Mission_Total' ORDER BY CAST(`value` AS SIGNED) DESC LIMIT 5",.@name$,.@val);
+		for(set .@i,0; .@i<5; set .@i,.@i+1)
+			mes "  [Rank "+(.@i+1)+"]  "+((.@name$[.@i] == "")?"^777777none":"^0055FF"+.@name$[.@i]+"^000000 : ^FF0000"+.@val[.@i]+" pt.")+"^000000";
+		close;
+	case 7:
+		mes "[Hunting Missions]";
+		mes "Nothing? Okay...";
+		emotion e_hmm;
+		close;
+	}
+
+Mission_Status:
+	set @f,0;
+	deletearray .@j[0], getarraysize(.@j);
+	for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
+		set .@j[.@i], getd("Mission"+.@i);
+		set .@j[.Quests], .@j[.Quests]+strmobinfo(3,.@j[.@i]);
+		set .@j[.Quests+1], .@j[.Quests+1]+strmobinfo(6,.@j[.@i]);
+		set .@j[.Quests+2], .@j[.Quests+2]+strmobinfo(7,.@j[.@i]);
+		mes " > "+Chk(getd("Mission"+.@i+"_"),#Mission_Count)+strmobinfo(1,.@j[.@i])+" ("+getd("Mission"+.@i+"_")+"/"+#Mission_Count+")^000000";
+	}
+	set .@Mission_Points, 3+(.@j[.Quests]/.Quests/6);
+	set .@Base_Exp, #Mission_Count*.@j[.Quests+1]/5;
+	set .@Job_Exp, #Mission_Count*.@j[.Quests+2]/5;
+	set .@Zeny, #Mission_Count*.Quests*.@j[.@i]*.Multiplier;
+	next;
+	mes "[Hunting Missions]";
+	mes "Mission rewards:";
+	mes " > Mission Points: ^0055FF"+.@Mission_Points+"^000000";
+	mes " > Base Experience: ^0055FF"+Cm(.@Base_Exp)+"^000000";
+	mes " > Job Experience: ^0055FF"+Cm(.@Job_Exp)+"^000000";
+	mes " > Zeny: ^0055FF"+Cm(.@Zeny)+"^000000";
+	return;
+
+Mission_Info:
+	mes "[Hunting Missions]";
+	mes "If you so choose, I can assign";
+	mes "you a random hunting quest.";
+	mes "Some are easier than others, but";
+	mes "the rewards increase with difficulty.";
+	next;
+	mes "[Hunting Missions]";
+	mes "Missions points are shared";
+	mes "amongst all your characters.";
+	if (.Delay) mes "Delay time is, too.";
+	mes "You can't take missions on";
+	mes "multiple characters at once.";
+	next;
+	mes "[Hunting Missions]";
+	mes "You can start a quest";
+	if (.Delay) mes "every "+((.Delay == 1)?"hour.":.Delay+" hours.");
+	else mes "whenever you want.";
+	mes "That's everything~";
+	return;
+
+function Chk {
+	if (getarg(0) < getarg(1)) { set @f,1; return "^FF0000"; }
+	else return "^00FF00"; }
+
+function Cm {
+	set .@str$, getarg(0);
+	for(set .@i,getstrlen(.@str$)-3; .@i>0; set .@i,.@i-3)
+		set .@str$, insertchar(.@str$,",",.@i);
+	return .@str$; }
+
+OnBuyItem:
+	set @cost,0;
+	for(set .@i,0; .@i<getarraysize(@bought_nameid); set .@i,.@i+1)
+		for(set .@j,0; .@j<getarraysize(.Shop); set .@j,.@j+2)
+			if (@bought_nameid[.@i] == .Shop[.@j]) {
+				set @cost, @cost+(.Shop[.@j+1]*@bought_quantity[.@i]);
+				break;
+			}
+	mes "[Hunting Missions]";
+	if (@cost > #Mission_Points) mes "You don't have enough Mission Points.";
+	else {
+		for(set .@i,0; .@i<getarraysize(@bought_nameid); set .@i,.@i+1) {
+			getitem @bought_nameid[.@i], @bought_quantity[.@i];
+			dispbottom "Purchased "+@bought_quantity[.@i]+"x "+getitemname(@bought_nameid[.@i])+".";
+		}
+		set #Mission_Points, #Mission_Points-@cost;
+		mes "Deal completed.";
+		emotion e_cash;
+	}
+	set @cost,0;
+	deletearray @bought_nameid[0], getarraysize(@bought_nameid);
+	deletearray @bought_quantity[0], getarraysize(@bought_quantity);
+	close;
+
+OnNPCKillEvent:
+	if (!#Mission_Count || !Mission1) end;
+	for(set .@i,0; .@i<.Quests; set .@i,.@i+1) {
+		if (strmobinfo(1,killedrid) == strmobinfo(1,getd("Mission"+.@i))) {
+			if (getd("Mission"+.@i+"_") < #Mission_Count) {
+				set .@j, getd("Mission"+.@i+"_")+1;
+				setd "Mission"+.@i+"_", .@j;
+				dispbottom "[Hunting Mission] Killed "+.@j+" of "+#Mission_Count+" "+strmobinfo(1,killedrid)+".";
+			}
+			break;
+		}
+	}
+	end;
+
+OnInit:
+	set .Delay,12;		// Quest delay, in hours (0 to disable).
+	set .Quests,4;		// Number of subquests per quest (increases rewards).
+	set .Multiplier,60;	// Multiplier for Zeny reward calculation.
+	setarray .Count[0],	// Min and max monsters per subquest (increases rewards).
+		40,70;
+	setarray .Shop[0],	// Reward items: <ID>,<point cost> (about 10~20 points per hunt).
+		512,1,513,1,514,1,538,5,539,5,558,10,561,10;
+	setarray .Restrict$[0],	// Blacklisted mob IDs.
+	    "1003,1006,1017,1021,1022,1027,1043,1062,1075,1096,"+
+	    "1108,1120,1136,1137,1168,1171,1172,1173,1198,1200,"+
+	    "1203,1204,1205,1210,1212,1217,1218,1244,1245,1247,",
+	    "1250,1259,1262,1268,1270,1311,1313,1388,1407,1411,"+
+	    "1414,1496,1501,1502,1515,1618,1624,1625,1626,1629,"+
+	    "1669,1674,1675,1676,1677,1678,1679,1681,1834,1835,"+
+	    "1868,1990,1991,1996,1997,1998";
+	setarray .NoRange[0],	// Blacklisted mob ID ranges.
+	    1077,1094,  1180,1188,  1219,1242,  1282,1310,  1323,1365,
+	    1392,1400,  1417,1493,  1517,1613,  1639,1652,  1657,1668,
+	    1682,1692,  1703,1713,  1718,1769,  1784,1829,  1838,1864,
+	    1870,1986;
+
+	npcshopdelitem "mission_shop",512;
+	for(set .@i,0; .@i<getarraysize(.Shop); set .@i,.@i+2)
+		npcshopadditem "mission_shop", .Shop[.@i], .Shop[.@i+1];
+	end;
+}
 -	shop	mission_shop	-1,512:-1
 -	shop	mission_shop	-1,512:-1