Browse Source

Extra npc checks (#3274)

* Extra checks
- Added some extra check in npcs script to prevent wrong behaviour
Atemo 6 năm trước cách đây
mục cha
commit
6e8599cd5b

+ 2 - 1
npc/merchants/advanced_refiner.txt

@@ -93,6 +93,7 @@ S_RefineValidate:
 	.@item_req = getarg(1);
 	.@price = getarg(2);
 	.@part = getarg(3);
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 
 	// If the VIP system is enabled, the prices for non-VIP players are considerably higher.
 	if (VIP_SCRIPT && !vip_status(VIP_STATUS_ACTIVE)) {
@@ -158,7 +159,7 @@ S_RefineValidate:
 
 			// anti-hack
 			if (callfunc("F_IsEquipIDHack", .@part, getarg(4)) ||
-				callfunc("F_IsEquipRefineHack", .@part, getarg(5))) {
+				callfunc("F_IsEquipRefineHack", .@part, getarg(5)) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3])) {
 				mes "[Holink]";
 				emotion ET_FRET;
 				mes "Wait a second...";

+ 9 - 5
npc/merchants/refine.txt

@@ -609,6 +609,7 @@ function	script	refinemain	{
 	}
 	.@refineitemid = getequipid(.@part); // save id of the item
 	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID);
 
@@ -687,7 +688,7 @@ function	script	refinemain	{
 		delitem .@material,1;
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 			mes "["+ .@npc_name$ +"]";
 			emotion ET_FRET;
@@ -745,7 +746,7 @@ function	script	refinemain	{
 	}
 
 // New Refining Functions ========================
-	if(getequiprefinerycnt(.@part) < .@safe) {
+	if (.@refinerycnt < .@safe) {
 		mes "["+ .@npc_name$ +"]";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		next;
@@ -754,7 +755,7 @@ function	script	refinemain	{
 		.@menu2 = 2;
 	switch(.@menu2){
 	case 1: 
-		.@refinecnt = .@safe - getequiprefinerycnt(.@part);
+		.@refinecnt = .@safe - .@refinerycnt;
 		break;
 	case 2:
 		next;
@@ -762,7 +763,7 @@ function	script	refinemain	{
 		mes "How many times would you like me to refine your item?";
 		next;
 		input .@refinecnt;
-		.@refinecheck = .@refinecnt + getequiprefinerycnt(.@part);
+		.@refinecheck = .@refinecnt + .@refinerycnt;
 		if (.@refinecnt < 1 || .@refinecheck > 10) {
 			mes "["+ .@npc_name$ +"]";
 			mes "I can't refine this item that many times.";
@@ -808,7 +809,9 @@ function	script	refinemain	{
 			mes "Look here... you don't have any items on...";
 			close;
 		}
-		if (getequipid(.@part) != .@refineitemid || (.@menu2 == 1 && getequippercentrefinery(.@part) < 100)) {
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
+				callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt) || (.@menu2 == 1 && getequippercentrefinery(.@part) < 100)) {
 			mes "["+ .@npc_name$ +"]";
 			mes "Clang... No, but did you imagine I could be so stupid?!";
 			mes "You changed it...";
@@ -832,6 +835,7 @@ function	script	refinemain	{
 		successrefitem .@part;
 		emotion ET_BEST;
 		.@refinecnt = .@refinecnt - 1;
+		.@refinerycnt = getequiprefinerycnt(.@part);
 		next;
 	}
 	mes "["+ .@npc_name$ +"]";

+ 1 - 0
npc/other/card_trader.txt

@@ -18,6 +18,7 @@
 //============================================================ 
 
 prontera,115,90,0	script	Putty	4_F_01,{
+	disable_items;
 	setarray .@card1[0], 4001,4006,4009,4019,4075,4033,4012,4016,4026,4022,
 				4027,4028,4038,4025,4021,4050,4079,4081,4090,4094,
 				4101,4104,4110,4114,4119,4108,4095,4231,4280,4008,

+ 16 - 2
npc/quests/seals/mjolnir_seal.txt

@@ -1964,7 +1964,10 @@ mjolnir_01,35,136,7	script	Dwarf Blacksmith#west	826,{
 					mes "me to do with this?";
 					close;
 				}
-				if (getequiprefinerycnt(.@part) >= 10) {
+				.@equip_id = getequipid(.@part);
+				.@equip_refine = getequiprefinerycnt(.@part);
+				setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+				if (.@equip_refine >= 10) {
 					mes "[Vestri]";
 					mes "Oh, this is excellent! This piece here has been perfectly refined! But this isn't what I want. I can't do any work on this at all.";
 					close;
@@ -2037,6 +2040,10 @@ mjolnir_01,35,136,7	script	Dwarf Blacksmith#west	826,{
 					mes "Hurry up and get one.";
 					close;
 				}
+				// anti-hack
+				if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+					close;
+
 				if (getequippercentrefinery(.@part) > rand(100)) {
 					mes "^3355FF*Clang Clang!*^000000";
 					successrefitem .@part;
@@ -2181,7 +2188,10 @@ mjolnir_01,35,136,7	script	Dwarf Blacksmith#west	826,{
 					mes "me to do with this?";
 					close;
 				}
-				if (getequiprefinerycnt(.@part) >= 10) {
+				.@equip_id = getequipid(.@part);
+				.@equip_refine = getequiprefinerycnt(.@part);
+				setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+				if (.@equip_refine >= 10) {
 					mes "[Vestri]";
 					mes "Oh, this is excellent! This piece here has been perfectly refined! But this isn't what I want. I can't do any work on this at all.";
 					close;
@@ -2248,6 +2258,10 @@ mjolnir_01,35,136,7	script	Dwarf Blacksmith#west	826,{
 					mes "Hurry up and get one.";
 					close;
 				}
+				// anti-hack
+				if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+					close;
+
 				if (getequippercentrefinery(.@part) > rand(100)) {
 					mes "^3355FF*Clang Clang!*^000000";
 					successrefitem .@part;

+ 26 - 15
npc/re/instances/SarahAndFenrir.txt

@@ -248,25 +248,25 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 				mes "If you wish to enchant, you must equip Sarah's " + .@sarah_earring$ + " earring.";
 				close;
 			}
-			setarray .@card[0], getequipcardid(.@part,3), getequipcardid(.@part,2);
-			if (.@card[1] > 0) {// 2 enchants
+			setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+			if (.@card[2] > 0) {// 2 enchants
 				mes "[Chief Assistant]";
 				mes "A fully enchanted earring of Sarah cannot be enchanted any further.";
 				close;
 			}
-			if (.@card[0] < 1) {// none enchant
+			if (.@card[3] > 0) {// 1 enchant
 				mes "[Chief Assistant]";
-				mes "Sarah's Earring is currently in a state without enchantment.";
-				.@slot = 0;
+				mes "Sarah's Earring is currently in a state of enchantment in slot 4.";
+				.@slot = 3;
 			}
-			else {// 1 enchant
+			else {// none enchant
 				mes "[Chief Assistant]";
-				mes "Sarah's Earring is currently in a state of enchantment in slot 4.";
-				.@slot = 1;
+				mes "Sarah's Earring is currently in a state without enchantment.";
+				.@slot = 4;
 			}
 			next;
 			mes "[Chief Assistant]";
-			mes "Which ability do you want as an enchantment on slot " + (4-.@slot) + "?";
+			mes "Which ability do you want as an enchantment on slot " + .@slot + "?";
 			next;
 			switch( select( "CRI or Critical", "Expert archer or Bleed", "Conservation or MATK", "Delay Attack or Delay Skill" ) ) {
 			case 1:
@@ -278,7 +278,7 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 					4941,	// Critical4
 					4865;	// Fatal3
 				mes "[Chief Assistant]";
-				mes "Selected for CRI or Critical Enchantment slot " + (4-.@slot) + ".";
+				mes "Selected for CRI or Critical Enchantment slot " + .@slot + ".";
 				break;
 			case 2:
 				setarray .@bonus[0],
@@ -289,7 +289,7 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 					4944,	// Dodge3
 					4834;	// Expert_Archer3
 				mes "[Chief Assistant]";
-				mes "Selected for Expert Archer or Bleed Enchantment slot " + (4-.@slot) + ".";
+				mes "Selected for Expert Archer or Bleed Enchantment slot " + .@slot + ".";
 				break;
 			case 3:
 				setarray .@bonus[0],
@@ -300,7 +300,7 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 					4947,	// Thrift3
 					4899;	// Matk5p
 				mes "[Chief Assistant]";
-				mes "Selected for Conservation or MATK Enchantment slot " + (4-.@slot) + ".";
+				mes "Selected for Conservation or MATK Enchantment slot " + .@slot + ".";
 				break;
 			case 4:
 				setarray .@bonus[0],
@@ -311,7 +311,7 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 					4950,	// Skill_Delay3
 					4873;	// Attack_Delay_3
 				mes "[Chief Assistant]";
-				mes "Selected for Delay Attack or Delay Skill Enchantment slot " + (4-.@slot) + ".";
+				mes "Selected for Delay Attack or Delay Skill Enchantment slot " + .@slot + ".";
 				break;
 			}
 			next;
@@ -344,6 +344,11 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 			specialeffect2 EF_MAGICALATTHIT;
 			specialeffect2 EF_POTION2;
 			delitem 6803,4;// Shard of Gigantes
+
+			// anti-hack
+			if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]))
+				close;
+
 			delequip .@part;
 			.@r = rand(100);
 			for ( .@i = 0; .@i < .@bonus_size && (.@bonus_chance * (.@i+1)) < .@r; .@i++ );
@@ -357,9 +362,9 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 				mes "enchantment is not an easy task..";
 				close;
 			}
-			.@card[.@slot] = .@bonus[.@i];
+			.@card[.@slot-1] = .@bonus[.@i];
 			specialeffect2 EF_ANGEL2;
-			getitem2 .@sarah_item_id,1,1,0,0,0,0,.@card[1],.@card[0];
+			getitem2 .@sarah_item_id,1,1,0,0,.@card[0],.@card[1],.@card[2],.@card[3];
 			mes "[Chief Assistant]";
 			mes "Enchantment completed!";
 			close;
@@ -403,6 +408,7 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 				.@column$ = "right";
 			}
 			.@equip_id = getequipid(.@part);
+			setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 			if (.@equip_id == -1) {
 				mes "[Chief Assistant]";
 				mes "To initialize an enchantment, the relevant column must be equipped with gear.";
@@ -432,6 +438,11 @@ dali02,93,146,6	script	Assistant Professor#a1	4_M_REPAIR,{
 				specialeffect2 EF_POTION2;
 				specialeffect2 EF_ANGEL2;
 				delitem 6803,1;// Shard of Gigantes
+
+				// anti-hack
+				if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]))
+					close;
+
 				delequip .@part;
 				getitem .@sarah_item_id,1;
 				mes "[Chief Assistant]";

+ 14 - 5
npc/re/jobs/2e/kagerou_oboro.txt

@@ -2091,6 +2091,7 @@ job_ko,127,125,4	script	Red Leopard Joe#ko	730,{
 			close;
 		} else {
 			set .@equip_id, getequipid(.@part);
+			set .@equip_refine, getequiprefinerycnt(.@part);
 			if (.@equip_id == 13074 || .@equip_id == 13312) {
 				mes "[Red Leopard Joe]";
 				mes "Is that weapon yours? Let me have a look.";
@@ -2106,7 +2107,6 @@ job_ko,127,125,4	script	Red Leopard Joe#ko	730,{
 		}
 		mes "Joe took a thorough look at the seal.";
 		next;
-		set .@equip_refine, getequiprefinerycnt(.@part);
 		if (.@equip_refine < 7) {
 			mes "[Red Leopard Joe]";
 			mes "Are you that low?";
@@ -2150,6 +2150,11 @@ job_ko,127,125,4	script	Red Leopard Joe#ko	730,{
 		mes "I can feel it.";
 		mes "I will take this weapon to give it some finishing touches.";
 		next;
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+			close;
+
 		delequip .@part;
 		erasequest 5145;
 		completequest 5138;
@@ -2158,9 +2163,7 @@ job_ko,127,125,4	script	Red Leopard Joe#ko	730,{
 		mes "[Red Leopard Joe]";
 		mes "'" + strcharinfo(0) + "'";
 		mes "Passed the weapon test!!";
-		close2;
-		enable_items;
-		end;
+		close;
 	} else if (.@ko_test_03_1 == 2 && .@ko_test_03_2 == 0 && (.@ko_test_03_3 == 2 || .@ko_test_03_4 == 2) && .@ko_test_03_5 == 0) {
 		mes "[Red Leopard Joe]";
 		mes "Oh, I almost forgot.";
@@ -2429,6 +2432,8 @@ job_ko,121,121,0	script	Refinement Tools#ko_01	844,{
 		close;
 	} else {
 		set .@equip_id, getequipid(.@part);
+		set .@equip_refine, getequiprefinerycnt(.@part);
+		setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 		if (.@equip_id == 13074 || .@equip_id == 13312) {
 			mes "Analyzing the weapon.";
 			next;
@@ -2449,7 +2454,6 @@ job_ko,121,121,0	script	Refinement Tools#ko_01	844,{
 		mes "That weapon cannot be refined. Where did you get it?";  //custom translation
 		close;
 	}
-	set .@equip_refine, getequiprefinerycnt(.@part);
 	if (.@equip_refine >= 20) {
 		mes "Bzzzt";
 		mes "A warning beep comes from the tool.";
@@ -2486,6 +2490,11 @@ job_ko,121,121,0	script	Refinement Tools#ko_01	844,{
 	} else {							// 10>20 2%
 		if (.@rand < 3) set .@wlevel_up,1;
 	}
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+		close;
+
 	if (.@wlevel_up) {
 		successrefitem .@part;
 		mes "Succeeded in refining.";

+ 71 - 168
npc/re/jobs/novice/academy.txt

@@ -8227,9 +8227,8 @@ iz_ac02,162,86,4	script	Guild Staff#ac	4W_M_02,{
 		mes "[Sharp Snake's Fang]";
 		mes "Yesssssss? I wass sssent by the academy.";
 		close;
-	} else if (nov_3_guns > 7) {
-		disable_items;
 	}
+	disable_items;
 	mes "[Sharp Snake's Fang]";
 	mes "I am ^A2563ESharp Snake's Fang^000000 from the Gunslinger Guild. What do you need?";
 	next;
@@ -8239,9 +8238,7 @@ iz_ac02,162,86,4	script	Guild Staff#ac	4W_M_02,{
 		next;
 		mes "[Sharp Snake's Fang]";
 		mes "You don't need to worry, he said you're doing great!";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	mes "[Sharp Snake's Fang]";
 	mes "Do you wish to exchange your guild issued weapon?";
@@ -8249,125 +8246,66 @@ iz_ac02,162,86,4	script	Guild Staff#ac	4W_M_02,{
 	mes "[Sharp Snake's Fang]";
 	mes "Let's first check your gun's condition.";
 	next;
-	if (getequipname(EQI_HAND_R) == "") {
+	.@gun = getequipid(EQI_HAND_R);
+	.@equip_refine = getequiprefinerycnt(.@part);
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+	if (.@gun == -1) {
 		mes "[Sharp Snake's Fang]";
 		mes "If you want to proceed, you need to have your weapon equipped.";
-		close2;
-		enable_items;
-		end;
-	} else {
-		.@gun = getequipid(EQI_HAND_R);
+		close;
 	}
 	mes "[Sharp Snake's Fang]";
 	mes "Let's see...";
 	next;
+	mes "[Sharp Snake's Fang]";
 	if (.@gun == 13116) {// Novice_Revolver
 		.@gun_code$ = "RV";
 		.@now_gun$ = "Revolver";
-		mes "[Sharp Snake's Fang]";
 		mes "You want to exchange your Guild issued Revolver?";
-		next;
 	} else if (.@gun == 13180) {// Novice_Rifle
 		.@gun_code$ = "RF";
 		.@now_gun$ = "Rifle";
-		mes "[Sharp Snake's Fang]";
 		mes "You want to exchange your Guild issued Rifle?";
-		next;
 	} else if (.@gun == 13181) {// Novice_Shotgun
 		.@gun_code$ = "SG";
 		.@now_gun$ = "Shotgun";
-		mes "[Sharp Snake's Fang]";
 		mes "You want to exchange your Guild issued Shotgun?";
-		next;
 	} else if (.@gun == 13182) {// Novice_Gatling
 		.@gun_code$ = "GT";
 		.@now_gun$ = "Gatling";
-		mes "[Sharp Snake's Fang]";
 		mes "You want to exchange your Guild issued Gatling Gun?";
-		next;
 	} else if (.@gun == 13183) {// Novice_Grenade_Launcher
 		.@gun_code$ = "GL";
 		.@now_gun$ = "Grenade Launcher";
-		mes "[Sharp Snake's Fang]";
 		mes "You want to exchange your Guild issued Grenade Launcher?";
-		next;
 	} else {
-		mes "[Sharp Snake's Fang]";
 		mes "The gun you are using is was not provided by the guild.";
 		close;
 	}
+	next;
 	mes "[Sharp Snake's Fang]";
 	mes "The gun looks to be in good condition.";
 	next;
 	mes "[Sharp Snake's Fang]";
 	mes "Please select the novice weapon you wish to exchange for your "+.@now_gun$+"!";
 	next;
-	switch(select("Exchange for Revolver", "Exchange for Rifle", "Exchange for Shotgun", "Exchange for Gatling Gun", "Exchange for Grenade Launcher", "Cancel")) {
-	case 1:
-		if (.@gun == 13116) {
-			mes "[Sharp Snake's Fang]";
-			mes "You already have that gun, just use it!";
-			close2;
-			enable_items;
-			end;
-		} else {
-			delequip EQI_HAND_R;
-			getitem 13116,1;// Novice_Revolver
-		}
-		break;
-	case 2:
-		if (.@gun == 13180) {
-			mes "[Sharp Snake's Fang]";
-			mes "You already have that gun, just use it!";
-			close2;
-			enable_items;
-			end;
-		} else {
-			delequip EQI_HAND_R;
-			getitem 13180,1;// Novice_Rifle
-		}
-		break;
-	case 3:
-		if (.@gun == 13181) {
+	setarray .@selection_item_id[0], 13116, 13180, 13181, 13182, 13183;
+	.@s = select("Exchange for Revolver", "Exchange for Rifle", "Exchange for Shotgun", "Exchange for Gatling Gun", "Exchange for Grenade Launcher", "Cancel") - 1;
+	if (.@s != 5) {
+		if (.@gun == .@selection_item_id[.@s]) {
 			mes "[Sharp Snake's Fang]";
 			mes "You already have that gun, just use it!";
-			close2;
-			enable_items;
-			end;
-		} else {
-			delequip EQI_HAND_R;
-			getitem 13181,1;// Novice_Shotgun
-		}
-		break;
-	case 4:
-		if (.@gun == 13182) {
-			mes "[Sharp Snake's Fang]";
-			mes "You already have that gun, just use it!";
-			close2;
-			enable_items;
-			end;
-		} else {
-			delequip EQI_HAND_R;
-			getitem 13182,1;// Novice_Gatling
-		}
-		break;
-	case 5:
-		if (.@gun == 13183) {
-			mes "[Sharp Snake's Fang]";
-			mes "You already have that gun, just use it!";
-			close2;
-			enable_items;
-			end;
-		} else {
-			delequip EQI_HAND_R;
-			getitem 13183,1;// Novice_Grenade_Launcher
+			close;
 		}
-		break;
-	case 6:
-		break;
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@gun) || callfunc("F_IsEquipCardHack", EQI_HAND_R, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", EQI_HAND_R, .@equip_refine))
+			close;
+
+		delequip EQI_HAND_R;
+		getitem .@selection_item_id[.@s],1;
 	}
 	mes "[Sharp Snake's Fang]";
-	mes "Gun control management number ^FF0000"+.@gun_code$+""+rand(0,9)+""+rand(0,9)+""+rand(0,9)+""+rand(0,9)+""+rand(0,9)+""+rand(0,9)+"^000000.";
+	mes "Gun control management number ^FF0000"+.@gun_code$+""+rand(9)+""+rand(9)+""+rand(9)+""+rand(9)+""+rand(9)+""+rand(9)+"^000000.";
 	next;
 	mes "[Sharp Snake's Fang]";
 	mes "Are there any issues?";
@@ -8375,9 +8313,7 @@ iz_ac02,162,86,4	script	Guild Staff#ac	4W_M_02,{
 	select("No issues.");
 	mes "[Sharp Snake's Fang]";
 	mes "Cherish your gun!";
-	close2;
-	enable_items;
-	end;
+	close;
 }
 
 iz_ac02_a,162,86,4	duplicate(Guild Staff#ac)	Guild Staff#ac_a	4W_M_02
@@ -12887,9 +12823,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		mes "[Refining Machine Wagjak]";
 		mes "^ff0000- Error number 000"+.@part+" -^000000";
 		mes "Item is not equipped.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	mes "[Refining Machine Wagjak]";
 	mes "Searching for the equipment information - completed.";
@@ -12898,9 +12832,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		mes "[Refining Machine Wagjak]";
 		mes "^FF0000- error number 4444 -^000000";
 		mes "This item cannot be refined.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	// if (!getequipisidentify(.@part)) {// getequipisidentify command removed 
 		// mes "[Refining Machine Wagjak]";
@@ -12910,13 +12842,15 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		// enable_items;
 		// end;
 	// }
-	if (getequiprefinerycnt(.@part) >= 10) {
+	.@refineitemid = getequipid(.@part); // save id of the item
+	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+
+	if (.@refinerycnt >= 10) {
 		mes "[Refining Machine Wagjak]";
 		mes "^FF0000- error number 1010 -^000000";
 		mes "At the current version, you can do refining up to level 10.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	if (isbegin_quest(5153) == 1) {
 		if (getequipweaponlv(.@part) == 1) {
@@ -12928,9 +12862,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 			if (select("Refine.", "Don't Refine.") == 2) {
 				mes "[Refining Machine Wagjak]";
 				mes "Cancel the refining.";
-				close2;
-				enable_items;
-				end;
+				close;
 			}
 			if (getequippercentrefinery(.@part) < 100) {
 				mes "[Refining Machine Wagjak]";
@@ -12941,19 +12873,18 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 				if (select("Refine.", "Don't Refine.") == 2) {
 					mes "[Refining Machine Wagjak]";
 					mes "Refining has been cancelled as per the user's request.";
-					close2;
-					enable_items;
-					end;
+					close;
 				}
 			}
+			// anti-hack
+			if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt))
+				close;
 			if (getequippercentrefinery(.@part) <= rand(100)) {
 				failedrefitem .@part;
 				mes "[Refining Machine Wagjak]";
 				mes "Result : Fail";
 				mes "refining failed. The equipment was destroyed.";
-				close2;
-				enable_items;
-				end;
+				close;
 			} else {
 				successrefitem .@part;
 				mes "[Refining Machine Wagjak]";
@@ -12963,15 +12894,11 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 				next;
 				mes "[Refining Machine Wagjak]";
 				mes "Service usage coupon was used.";
-				close2;
-				enable_items;
-				end;
+				close;
 			}
 		}
 	}
 
-	.@refineitemid = getequipid(.@part); // save id of the item
-	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
 	.@price = getequiprefinecost(.@part, REFINE_COST_WAGJAK, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_WAGJAK, REFINE_MATERIAL_ID);
 
@@ -12988,9 +12915,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 	if (select("Refine.", "Don't Refine.") == 2) {
 		mes "[Refining Machine Wagjak]";
 		mes "Refining has been cancelled as per the user's request.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	if (getequippercentrefinery(.@part) < 100) {
 		mes "[Refining Machine Wagjak]";
@@ -13001,9 +12926,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		if (select("Refine.", "Don't Refine.") == 2) {
 			mes "[Refining Machine Wagjak]";
 			mes "Refining has been cancelled as per the user's request.";
-			close2;
-			enable_items;
-			end;
+			close;
 		}
 	}
 	if (countitem(.@material) > 0 && Zeny >= .@price) {
@@ -13011,8 +12934,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		Zeny -= .@price;
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
-		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 			mes "[Refining Machine Wagjak]";
 			emotion ET_FRET;
 			mes "Wait a second...";
@@ -13024,9 +12946,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		mes "[Refining Machine Wagjak]";
 		mes "^FF0000- error number 8282 -^000000";
 		mes "You are short of refining price.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	if (getequippercentrefinery(.@part) <= rand(100)) {
 		failedrefitem .@part;
@@ -13039,9 +12959,7 @@ izlude_d,153,126,1	duplicate(Refinery Owner Han#iz)	Refinery Owner Han#iz_d	4_M_
 		mes "Result : Success";
 		mes "Congratulations!! You succeeded in refining.";
 	}
-	close2;
-	enable_items;
-	end;
+	close;
 }
 
 izlude,153,121,3	duplicate(izludeWagjak)	Refining Machine Wagjak::iz	2_MONEMUS
@@ -14043,9 +13961,7 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		next;
 		mes "[Almond J]";
 		mes "If you have anything to do with the enchant association, please consult with Mounds inside.";
-		close2;
-		enable_items;
-		end;
+		close;
 	} else if (.@in_tutorial == 4) {
 		.@part = EQI_ARMOR;
 		mes "[Almond J]";
@@ -14075,25 +13991,21 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		if (select("Hidden enchant start!!", "Wait for a while.") == 2) {
 			mes "[Almond J]";
 			mes "Heh? Eh? Hik?! Come here quick.";
-			close2;
-			enable_items;
-			end;
+			close;
 		}
 		if (!getequipisequiped(.@part)) {
 			mes "[Almond J]";
 			mes "Please come back after you have equipped the Cotton Shirt.";
-			close2;
-			enable_items;
-			end;
+			close;
 		}
-		if (getequipid(EQI_ARMOR) == 2302) {
-			.@refineCount = getequiprefinerycnt(EQI_ARMOR);
+		.@equip_id = getequipid(.@part);
+		if (.@equip_id == 2302) {
+			.@refineCount = getequiprefinerycnt(.@part);
+			setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 		} else {
 			mes "[Almond J]";
 			mes "Hing, it is not a normal Cotton Shirt.";
-			close2;
-			enable_items;
-			end;
+			close;
 		}
 		mes "[Almond J]";
 		mes "Now!! Start the first hidden enchant!! Start!!!!!";
@@ -14101,8 +14013,12 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		specialeffect2 EF_REPAIRWEAPON;
 		progressbar "ffff00", 2;
 		completequest 5159;
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@refineCount))
+			close;
+
 		delequip .@part;
-		setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1);
 		getitem2 2302,1,1,.@refineCount,0,.@equip_card[0],.@equip_card[1],4800,4795;// Cotton_Shirt_ ; SP50 ; HP100
 		mes "[Almond J]";
 		mes "Zzazanzn!! Completed!!";
@@ -14115,9 +14031,7 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		mes "It's fun. I want to do it again. Hey, another trial Ok? Aaaaa!!! I want to do the hidden enchant again.";
 		next;
 		mes "Gradually you are getting into your own world. You better go back to Mounds.";
-		close2;
-		enable_items;
-		end;
+		close;
 	} else if (.@in_tutorial == 5) {
 		mes "[Almond J]";
 		mes "How about it? Don't you think the hidden enchant is great? Any chance to do another hidden enchant?";
@@ -14126,9 +14040,7 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		mes "It's fun. I want to do it again. Hey, another trial Ok? Aaaaa!!! I want to do the hidden enchant again.";
 		next;
 		mes "Gradually you are getting into your own world. You better go back to Mounds.";
-		close2;
-		enable_items;
-		end;
+		close;
 	} else if (.@in_tutorial == 6) {
 		mes "[Almond J]";
 		mes "Heh heh... how are you? I am doing a ^142CEBservice of free hidden enchant for the beginner's weapon to advertise the enchant association.^000000.";
@@ -14136,9 +14048,7 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 	} else {
 		mes "[Almond J]";
 		mes "Something strange must've happened. If this continues, please contact customer service.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	mes "[Almond J]";
 	mes "As you are still a beginner, you don't have a very, very, very functional jewelry, but soon you will have.";
@@ -14159,16 +14069,12 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		mes "[Almond J]";
 		mes "^FD4F02For Novices-";
 		mes "Cutter, Mace, Rod, Axe, Etc.";
-		close2;
-		enable_items;
-		end;
+		close;
 	case 3:
 		mes "[Almond J]";
 		mes "Ye?!?!?!?!?!";
 		mes "Where are you going? You should do the hidden enchant before going.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 
 	.@part = EQI_HAND_R;
@@ -14176,13 +14082,11 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 	if (!getequipisequiped(.@part)) {
 		mes "[Almond J]";
 		mes "Hehehe... hidden enchant makes me excited. But you should come back with your weapon armed.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	.@equip = getequipid(.@part);
 	.@equip_refine = getequiprefinerycnt(.@part);
-	setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1);
+	setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 
 	mes "[Almond J]";
 	switch(.@equip) {
@@ -14191,9 +14095,7 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 		next;
 		mes "[Almond J]";
 		mes "But this weapon might be strange to add a hidden enchant? Sorry.";
-		close2;
-		enable_items;
-		end;
+		close;
 	case 1381: // N_Battle_Axe
 	case 1545: // N_Mace
 	case 1639: // N_Rod
@@ -14206,14 +14108,12 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 	case 13182: // Novice_Gatling
 	case 13183: // Novice_Grenade_Launcher
 	case 13415: // N_Falchion
-		mes "It is!! The ^142ceb"+ getequipname(EQI_HAND_R) +"^000000.";
+		mes "It is!! The ^142ceb"+ getequipname(.@part) +"^000000.";
 		next;
 		break;
 	default:
 		mes "Ehee.. It is not a Novice Weapon. Leaving this expensive weapon to us and if broken... I'm not taking that chance.";
-		close2;
-		enable_items;
-		end;
+		close;
 	}
 	setarray .@enchantments[1],4700,4701,4702,4730,4731,4732,4740,4741,4742,4710,4711,4712,4720,4721,4722,4750,4751,4752,4760,4766,4764,4786,4791,4795,4800,4811,4832,4818,4815;
 	.@enchant1 = rand(1,35);
@@ -14234,14 +14134,17 @@ izlude,108,139,7	script	Enchanter Almond J#iz	4_CAT_SAILOR3,{
 	next;
 	specialeffect2 EF_REPAIRWEAPON;
 	progressbar "ffff00", 3;
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@equip) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+		close;
+
 	delequip .@part;
 	getitem2 .@equip,1,1,.@equip_refine,0,.@equip_card[0],.@equip_card[1],.@enchant1,.@enchant2;
 	mes "[Almond J]";
 	mes "Zzazanzn!! Completed!!";
 	mes "As I'm too excited, I can't check the options. Please check it yourself.";
-	close2;
-	enable_items;
-	end;
+	close;
 }
 
 izlude_a,108,139,7	duplicate(Enchanter Almond J#iz)	Enchanter Almond J#iz_a	4_CAT_SAILOR3

+ 10 - 4
npc/re/merchants/HorrorToyFactory_merchants.txt

@@ -446,18 +446,23 @@ xmas,240,294,3	script	Black Beard Joe#pa0829	4_M_05,{
 		mes "There is a problem, please come back again!";// custom
 		close;
 	}
-	if (.@card[3] == 0 && .@sc_type < 4) 
-		.@card[3] = .@enchant;
+	if (.@card[3] == 0 && .@sc_type < 4)
+		.@index_slot = 3;
 	else if (.@card[2] == 0 && .@sc_type < 3)
-		.@card[2] = .@enchant;
+		.@index_slot = 2;
 	else if (.@card[1] == 0 && .@sc_type < 2)
-		.@card[1] = .@enchant;
+		.@index_slot = 1;
 	else {
 		mes "I don't know what this is, but I think this isn't thing I could handle.";// custom
 		close;
 	}
 	if (countitem(7642) > 14) {// Bloody_Coin
 		delitem 7642,15;// Bloody_Coin
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@eq_num, .@item_id) || callfunc("F_IsEquipCardHack", .@eq_num, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@eq_num, .@refine))
+			close;
+
 		delequip .@eq_num;
 		if (.@enchant == 0) {
 			mes "Ouch! Poor you, the enchantment has failed and your gear is broken, Geez!";
@@ -465,6 +470,7 @@ xmas,240,294,3	script	Black Beard Joe#pa0829	4_M_05,{
 			specialeffect2 EF_LORD;
 			end;
 		}
+		.@card[ .@index_slot ] = .@enchant;
 		getitem2 .@item_id,1,1,.@refine,0,.@card[0],.@card[1],.@card[2],.@card[3];
 		mes "Hmm.. It was successful. Take a look at it.";
 		specialeffect2 EF_REPAIRWEAPON;

+ 35 - 21
npc/re/merchants/OldGlastHeim_merchants.txt

@@ -89,9 +89,11 @@ glast_01,210,273,5	script	Hugin's butler#pa0829	1_F_04,{
 	}
 	mes "[Hugin's Buttler]";
 	mes "The boots have been upgraded as you want.";
-	delequip EQI_SHOES;
-	delitem 6607,5;// Temporal_Crystal
-	getitem .@equip_type[.@s],1;
+	if (getequipid(EQI_SHOES) == 2499) {
+		delequip EQI_SHOES;
+		delitem 6607,5;// Temporal_Crystal
+		getitem .@equip_type[.@s],1;
+	}
 	close;
 }
 
@@ -164,16 +166,20 @@ glast_01,212,273,4	script	Hugin's magic master#pa0829	1_F_01,{
 	case 22111:	// Modified_DEX_Boots
 	case 22112:	// Modified_LUK_Boots
 		.@equip_name$ = getequipname(EQI_SHOES);
-		.@card2 = getequipcardid(EQI_SHOES,2);
-		.@card3 = getequipcardid(EQI_SHOES,3);
+		setarray .@card[0],
+			getequipcardid(EQI_SHOES,0),
+			getequipcardid(EQI_SHOES,1),
+			getequipcardid(EQI_SHOES,2),
+			getequipcardid(EQI_SHOES,3);
+		copyarray .@equip_card[0], .@card[0], 4;	// for final check
 		.@equip_refine = getequiprefinerycnt(EQI_SHOES);
 
-		if (.@card2 > 0) {
+		if (.@card[2] > 0) {
 			mes "[Hugin's Magic master]";
 			mes "These boots have already passed the enchanting limit. We can't enchant them any more.";
 			close;
 		}
-		if (.@card3 == 0) {// 4th slot 1st try enchanting
+		if (.@card[3] == 0) {// 4th slot 1st try enchanting
 			.@cost = .@enchant_cost[0];
 			mes "[Hugin's Magic Master]";
 			mes "Want to enchant ^0000FF" + .@equip_name$ + "^000000?";
@@ -185,12 +191,12 @@ glast_01,212,273,4	script	Hugin's magic master#pa0829	1_F_01,{
 				mes "Ok, come back when you are ready.";
 				close;
 			}
-			.@card3 = .@enchant_1[.@s];
+			.@card[3] = .@enchant_1[.@s];
 			.@string$ = "enchant number ^6300001^000000.";
 		}
 		else {
 			for ( .@enchant_num = 1; .@enchant_num < 5; .@enchant_num++ ) {
-				for ( .@enchant_type = 0; .@enchant_type < 6 && .@card3 != getd( ".@enchant_" + .@enchant_num + "[" + .@enchant_type + "]" ); .@enchant_type++ )
+				for ( .@enchant_type = 0; .@enchant_type < 6 && .@card[3] != getd( ".@enchant_" + .@enchant_num + "[" + .@enchant_type + "]" ); .@enchant_type++ )
 					continue;
 				if (.@enchant_type < 6)
 					break;
@@ -204,13 +210,13 @@ glast_01,212,273,4	script	Hugin's magic master#pa0829	1_F_01,{
 
 			mes "[Hugin's Magic Master]";
 			if (.@enchant_num == 4) {
-				.@card2 = callfunc("F_Rand",4875,4876,4877,4878,4879,4880);// Bear's_Power, Runaway_Magic, Speed_Of_Light, Muscle_Fool, Hawkeye, Lucky_Day
+				.@card[2] = callfunc("F_Rand",4875,4876,4877,4878,4879,4880);// Bear's_Power, Runaway_Magic, Speed_Of_Light, Muscle_Fool, Hawkeye, Lucky_Day
 				.@string$ = "^990000Bonus effect ^000000 upgrade.";
 				mes "4th slot is already upgraded to the final option. Would you like a random bonus effect for the 3rd slot? You need ^0000ff" + .@cost + "^000000 Coagulated Spell items.";
 			}
 			else {
 				.@number = .@enchant_num + 1;
-				.@card3 = getd( ".@enchant_" + (.@enchant_num+1) + "[" + .@enchant_type + "]" );
+				.@card[3] = getd( ".@enchant_" + (.@enchant_num+1) + "[" + .@enchant_type + "]" );
 				.@string$ = "enchant number ^630000" + .@number + "^000000.";
 				mes "Enchanting ^0000FF" + .@equip_name$ + "^000000's 4th slot as ^0000FF" + .@number + "^000000 level effect. Requires ^0000FF" + .@cost + "^000000 Coagulated Spell items.";
 			}
@@ -228,10 +234,15 @@ glast_01,212,273,4	script	Hugin's magic master#pa0829	1_F_01,{
 		}
 		specialeffect2 EF_REPAIRWEAPON;
 		delitem 6608,.@cost;// Coagulated_Spell
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+			close;
+
 		delequip EQI_SHOES;
 		mes "[Hugin's Magic Master]";
 		mes "Trying for " + .@string$;
-		getitem2 .@equip_id,1,1,.@equip_refine,0,0,0,.@card2,.@card3;
+		getitem2 .@equip_id,1,1,.@equip_refine,0,0,0,.@card[2],.@card[3];
 		close;
 	default:
 		mes "[Hugin's Magic Master]";
@@ -288,6 +299,7 @@ glast_01,210,270,0	script	Hugin's Craftsman#pa0829	4_F_JOB_BLACKSMITH,{
 	}
 
 S_Slot:
+	.@equip_id = getequipid(EQI_SHOES);
 	mes "[Hugin's Craftsman]";
 	mes "And ^FF0000all enchant or refine rates will be lost if you fail this.^000000";
 	mes "Still want to risk it?";
@@ -312,16 +324,18 @@ S_Slot:
 		close;
 	}
 	delitem 6607,5;// Temporal_Crystal
-	delequip EQI_SHOES;
-	if (rand(1,100) < 50) {
+	if (getequipid(EQI_SHOES) == .@equip_id) {
+		delequip EQI_SHOES;
+		if (rand(1,100) < 50) {
+			mes "[Hugin's Craftsman]";
+			mes "Arrggg, we failed. Better luck next time.";
+			specialeffect2 EF_PHARMACY_FAIL;
+			close;
+		}
 		mes "[Hugin's Craftsman]";
-		mes "Arrggg, we failed. Better luck next time.";
-		specialeffect2 EF_PHARMACY_FAIL;
-		close;
+		mes "Successful! Here you go.";
+		specialeffect2 EF_MAXPOWER;
+		getitem getarg(0),1;
 	}
-	mes "[Hugin's Craftsman]";
-	mes "Successful! Here you go.";
-	specialeffect2 EF_MAXPOWER;
-	getitem getarg(0),1;
 	close;
 }

+ 2 - 1
npc/re/merchants/advanced_refiner.txt

@@ -72,6 +72,7 @@ malangdo,221,174,6	script	Holink#mal_cash	559,{
 	mes "[Holink]";
 	.@refineitemid = getequipid(.@part); // save id of the item
 	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_HOLINK, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_HOLINK, REFINE_MATERIAL_ID);
 
@@ -148,7 +149,7 @@ malangdo,221,174,6	script	Holink#mal_cash	559,{
 	set Zeny, Zeny-.@price;
 
 	// anti-hack
-	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 		mes "[Holink]";
 		emotion ET_FRET;

+ 21 - 14
npc/re/merchants/bio4_reward.txt

@@ -640,6 +640,7 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 	}
 	.@refine_count = getequiprefinerycnt(.@part);
 	.@equip_item = getequipid(.@part);
+	setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@lhz_max_num = 4000;
 	if (.@equip_item == 13069 || .@equip_item == 1291 || .@equip_item == 1392 || 
 	    .@equip_item == 1393 || .@equip_item == 1435 || .@equip_item == 1490 || 
@@ -701,7 +702,7 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 			mes "Not enough '^F2766EWill of Warrior^000000'. You need to bring 10 '^F2766EWill of Warrior^000000'";
 			close;
 		}
-		else if (getequipcardid(.@part, 3) > 0) {
+		else if (.@equip_card[3] > 0) {
 			mes "[Pudding]";
 			mes "This equipment already has the power of '^F2766EWill of Warrior^000000'.";
 			close;
@@ -715,7 +716,7 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 			mes "Not enough '^952420Thirst for Blood^000000'. You need to bring 10 '^952420Thirst for Blood^000000'";
 			close;
 		}
-		else if (getequipcardid(.@part, 2) > 0) {
+		else if (.@equip_card[2] > 0) {
 			mes "[Pudding]";
 			mes "This equipment already has the power of '^952420Thirst for Blood^000000'.";
 			close;
@@ -731,13 +732,13 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 			.@4thzptsodyd = 1;
 			.@3thzptsodyd = 1;
 		} else {
-			if (getequipcardid(.@part, 3) > 0) {
+			if (.@equip_card[3] > 0) {
 				.@menu_clear$[1] = "Remove the power of '^F2766EWill of Warrior^000000'";
 			} else {
 				.@menu_clear$[1] = "^999999There's no power to remove^000000";
 				.@4thzptsodyd = 1;
 			}
-			if (getequipcardid(.@part, 2) > 0) {
+			if (.@equip_card[2] > 0) {
 				.@menu_clear$[2] = "Remove the power of '^952420Thirst for Blood^000000'";
 			} else {
 				.@menu_clear$[2] = "^999999There's no power to remove^000000";
@@ -765,16 +766,19 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 				mes "This equipment didn't get any special power.";
 				close;
 			}
-			setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+			specialeffect EF_BEGINSPELL2;
+			progressbar "ffff00", 2;
+			specialeffect2 EF_FROSTWEAPON;
+			delitem 6471, 10; //Goast_Chill
+
+			// anti-hack
+			if (callfunc("F_IsEquipIDHack", .@part, .@equip_item) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@refine_count))
+				close;
+
 			if (.@menu == 2)
 				.@equip_card[3] = 0;
 			else
 				.@equip_card[2] = 0;
-			.@equip_item = getequipid(.@part);
-			specialeffect EF_BEGINSPELL2, AREA, "Sorcerer#Bio4Reward";
-			progressbar "ffff00", 2;
-			specialeffect2 EF_FROSTWEAPON;
-			delitem 6471, 10; //Goast_Chill
 			delequip .@part;
 			getitem2 .@equip_item, 1, 1, .@refine_count, 0, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3];
 			mes "[Pudding]";
@@ -956,15 +960,18 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 				else                 .@enchant = 0;
 			break;
 		}
-		setarray .@equip_card[0], getequipcardid(.@part,0),getequipcardid(.@part,1),getequipcardid(.@part,2),getequipcardid(.@part,3);
-		.@equip_card[(.@socket_type-1)] = .@enchant;
-		.@equip_item = getequipid(.@part);
-		specialeffect EF_BEGINSPELL3, AREA, "Sorcerer#Bio4Reward";
+		specialeffect EF_BEGINSPELL3;
 		progressbar "ffff00", 2;
 		if (.@socket_type == 3)
 			delitem 6470, 10; //Blood_Thirst
 		else
 			delitem 6469, 10; //Will_Of_Warrior
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_item) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@refine_count))
+			close;
+
+		.@equip_card[(.@socket_type-1)] = .@enchant;
 		delequip .@part;
 		
 		if (.@enchant == 0){

+ 9 - 1
npc/re/merchants/blessed_refiner.txt

@@ -68,7 +68,10 @@
 		mes "This item cannot be refined.";
 		close;
 	}
-	set .@equip_refine, getequiprefinerycnt(.@part);
+	.@equip_id = getequipid(.@part);
+	.@equip_refine = getequiprefinerycnt(.@part);
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
+
 	if (.@equip_refine < 6 || .@equip_refine > 12) {
 		mes "[Blacksmith Dister]";
 		mes "This equipment has refined to "+.@equip_refine+". I only handle items with refine levels from +6 to +12!";
@@ -134,6 +137,11 @@
 	}
 	delitem .@material,1;
 	set Zeny, Zeny-.@price;
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+		close;
+
 	mes "[Blacksmith Dister]";
 	mes "Tac! Tac! Tac!";
 	if (getequippercentrefinery(.@part, true) > rand(100)) {

+ 17 - 4
npc/re/merchants/enchan_ko.txt

@@ -151,6 +151,9 @@ que_ng,75,20,3	script	Artisan Tene#ko	762,{
 			}
 			break;
 		}
+		set .@equip_refine, getequiprefinerycnt(.@part);
+		setarray .@equip_card[0], getequipcardid(.@part,0),getequipcardid(.@part,1),getequipcardid(.@part,2),getequipcardid(.@part,3);
+		copyarray .@card[0], .@equip_card[0], 4;
 		set .@select,1;
 		break;
 	case 3:
@@ -209,6 +212,10 @@ que_ng,75,20,3	script	Artisan Tene#ko	762,{
 			set .@equip_id,15056; //Special_Ninja_Suit_
 			break;
 		}
+		set .@equip_refine, getequiprefinerycnt(.@part);
+		setarray .@equip_card[0], getequipcardid(.@part,0),getequipcardid(.@part,1),getequipcardid(.@part,2),getequipcardid(.@part,3);
+		copyarray .@card[0], .@equip_card[0], 4;
+
 		mes "[Artisan Tene]";
 		mes "You want to reset ^44B7BC" + getitemname(.@equip_id) + "^000000?";
 		next;
@@ -253,9 +260,6 @@ que_ng,75,20,3	script	Artisan Tene#ko	762,{
 		close;
 	}
 
-	set .@equip_refine, getequiprefinerycnt(.@part);
-	setarray .@equip_card[0], getequipcardid(.@part,0),getequipcardid(.@part,1),getequipcardid(.@part,2),getequipcardid(.@part,3);
-
 	// Initialization
 	if (.@select == 2) {
 		if (.@sot03_ck) {// reset only 3rd slot
@@ -276,8 +280,12 @@ que_ng,75,20,3	script	Artisan Tene#ko	762,{
 		}
 		progressbar "ffff00",2;
 		set Zeny, Zeny - 100000;
-		delequip .@part;
 
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+			close;
+
+		delequip .@part;
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@equip_card[3]
 		getitem2 .@equip_id,1,1,.@equip_refine,0,.@equip_card[0],.@equip_card[1],.@equip_card[2],.@equip_card[3];
 
@@ -516,6 +524,11 @@ que_ng,75,20,3	script	Artisan Tene#ko	762,{
 		set .@equip_card[2], .@enchant;
 	progressbar "ffff00",2;
 	set Zeny, Zeny - 100000;
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+		close;
+
 	delequip .@part;
 
 //	GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@equip_card[3]

+ 3 - 4
npc/re/merchants/enchan_mal.txt

@@ -319,6 +319,7 @@ malangdo,213,167,4	script	Mayomayo#mal	555,{
 L_Socket:
 	set .@select, @mal_enchant_select;
 	set .@equip_id, @mal_equip_id;
+	set .@equip_refine, getequiprefinerycnt(EQI_HAND_R);
 	set .@equip_name$, getitemname(.@equip_id)+((getitemslots(.@equip_id))?"["+getitemslots(.@equip_id)+"]":"");
 	setarray .@equip_card[0], getequipcardid(EQI_HAND_R,0),getequipcardid(EQI_HAND_R,1),getequipcardid(EQI_HAND_R,2),getequipcardid(EQI_HAND_R,3);
 	set @mal_equip_id,0;
@@ -575,7 +576,7 @@ L_Socket:
 		}
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@equip_id) ||
+		if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@equip_id) || callfunc("F_IsEquipRefineHack", EQI_HAND_R, .@equip_refine) || 
 		    callfunc("F_IsEquipCardHack", EQI_HAND_R, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]))
 			close;
 
@@ -604,7 +605,6 @@ L_Socket:
 		mes "[Mayomayo]";
 		mes "I have enchanted ^990000slot "+.@socket+"^000000 of this equipment.";
 		delitem .@coin[.@coin_select],.@total[.@coin_select];
-		set .@equip_refine, getequiprefinerycnt(EQI_HAND_R);
 		delequip EQI_HAND_R;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@equip_card[3]
@@ -641,11 +641,10 @@ L_Socket:
 		delitem 6417,1; //Silvervine
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@equip_id) ||
+		if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@equip_id) || callfunc("F_IsEquipRefineHack", EQI_HAND_R, .@equip_refine) || 
 		    callfunc("F_IsEquipCardHack", EQI_HAND_R, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]))
 			close;
 
-		set .@equip_refine, getequiprefinerycnt(EQI_HAND_R);
 		delequip EQI_HAND_R;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@equip_card[3]

+ 19 - 3
npc/re/merchants/enchan_mora.txt

@@ -1147,6 +1147,11 @@ L_Socket:
 		mes "The ability to enhance remains.";
 		delitem 6380,1; //Mora_Coin
 		set Zeny, Zeny-100000;
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+			close;
+
 		delequip .@part;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@equip_card[3]
@@ -1331,7 +1336,8 @@ mora,124,82,4	script	Artifact Collector#blan	522,{
 		close;
 	}
 	set .@equip_id, getequipid(EQI_HAND_R);
-	setarray .@equip_card[2], getequipcardid(EQI_HAND_R,2),getequipcardid(EQI_HAND_R,3);
+	.@equip_refine = getequiprefinerycnt(EQI_HAND_R);
+	setarray .@equip_card[0], getequipcardid(EQI_HAND_R,0), getequipcardid(EQI_HAND_R,1), getequipcardid(EQI_HAND_R,2),getequipcardid(EQI_HAND_R,3);
 	switch(.@equip_id) {
 	case 2007: //Golden_Rod_Staff
 	case 2008: //Aqua_Staff
@@ -1359,7 +1365,7 @@ mora,124,82,4	script	Artifact Collector#blan	522,{
 		mes "The weapon you have isn't one of the Artifacts I can work with.";
 		close;
 	}
-	if (getequiprefinerycnt(EQI_HAND_R) < 7) {
+	if (.@equip_refine < 7) {
 		emotion ET_FRET;
 		mes "[Artifact Collector]";
 		mes "I must insist that the refine level of the Artifact be at least +7!";
@@ -1378,7 +1384,7 @@ mora,124,82,4	script	Artifact Collector#blan	522,{
 	next;
 	emotion ET_OK;
 	mes "[Artifact Collector]";
-	mes "If you are ready I am about to show you what I can do with your +"+getequiprefinerycnt(EQI_HAND_R)+" Artifact!";
+	mes "If you are ready I am about to show you what I can do with your +" + .@equip_refine + " Artifact!";
 	next;
 	mes "[Artifact Collector]";
 	mes "I'm going to take your ^FF0000"+getequipname(EQI_HAND_R)+"^000000 and exchange it, are you ready?";
@@ -1405,6 +1411,11 @@ mora,124,82,4	script	Artifact Collector#blan	522,{
 		break;
 	}
 	emotion ET_SMILE;
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", EQI_HAND_R, .@equip_id) || callfunc("F_IsEquipCardHack", EQI_HAND_R, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]) || callfunc("F_IsEquipRefineHack", EQI_HAND_R, .@equip_refine))
+		close;
+
 	delequip EQI_HAND_R;
 	getitem .@empowered,1;
 	mes "[Artifact Collector]";
@@ -1487,6 +1498,8 @@ function	script	F_Mora_Enchant	{
 	specialeffect2 EF_REPAIRWEAPON;
 	progressbar "ffff00",3;
 	delitem 6380,5; //Mora_Coin
+	if (countitem(getarg(0)) < 1)
+		return 0;
 	delitem getarg(0),1;
 	set .@i, rand(1,4568);
 	if (.@i <= 3168) {
@@ -1516,6 +1529,7 @@ function	script	F_Mora_Enchant	{
 	return 1;
 }
 mora,105,176,4	script	Master Tailor#pa0829	509,{
+	disable_items;
 	if (checkweight(1201,1) == 0) {
 		mes "You have too many kinds of things with you to do that. Throw out some of them and try again.";
 		close;
@@ -1608,6 +1622,7 @@ mora,105,176,4	script	Master Tailor#pa0829	509,{
 }
 
 mora,123,177,6	script	Pendant Crafter#pa0829	509,{
+	disable_items;
 	if (checkweight(1201,1) == 0) {
 		mes "You have too many kinds of things with you to do that. Throw out some of them and try again.";
 		close;
@@ -1678,6 +1693,7 @@ mora,123,177,6	script	Pendant Crafter#pa0829	509,{
 }
 
 mora,134,166,4	script	Bulberry Westhood#pa0829	509,{
+	disable_items;
 	if (checkweight(1201,1) == 0) {
 		mes "You have too many kinds of things with you to do that. Throw out some of them and try again.";
 		close;

+ 7 - 8
npc/re/merchants/enchan_upg.txt

@@ -79,11 +79,12 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 		close;
 	}
 	setarray .@equip_card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
-	if (!getequipisequiped(.@part)) {
-		mes "It is dangerous to remove equipment during enchant process!";
-		close;
-	}
+	// if (!getequipisequiped(.@part)) {
+	// 	mes "It is dangerous to remove equipment during enchant process!";
+	// 	close;
+	// }
 	set .@equip_id, getequipid(.@part);
+	.@equip_refine = getequiprefinerycnt(.@part);
 	set .@item$, "|1292|1394|1491|1585|2015|13071|13115|16019|18112|21000|";
 	if (!compare(.@item$,"|"+.@equip_id+"|")) {
 		mes "I don't want to touch your equipment now!";
@@ -217,7 +218,6 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 			mes "Are you listening to me? I will only do for you if you bring the Enchant Book!";
 			close;
 		}
-		set .@equip_refine, getequiprefinerycnt(.@part);
 		if (.@enchant == 0) {
 			specialeffect EF_SHIELDCHARGE;
 			mes "Oh! Unbelievable!! It failed!! Please come again!";
@@ -230,7 +230,7 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 		delitem 6484,1; //Enchant_Book
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) ||
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine) || 
 		    callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]))
 			close;
 
@@ -263,11 +263,10 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 		set Zeny, Zeny - 100000;
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) ||
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine) || 
 		    callfunc("F_IsEquipCardHack", .@part, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]))
 			close;
 
-		set .@equip_refine, getequiprefinerycnt(.@part);
 		delequip .@part;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] 0

+ 4 - 2
npc/re/merchants/hd_refiner.txt

@@ -76,6 +76,7 @@
 	
 	.@refineitemid = getequipid(.@part); // save id of the item
 	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_HD, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_HD, REFINE_MATERIAL_ID);
 	
@@ -109,7 +110,7 @@
 	set Zeny, Zeny-.@price;
 
 	// anti-hack
-	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 		mes "[Blacksmith Mighty Hammer]";
 		emotion ET_FRET;
@@ -216,6 +217,7 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 	}
 	.@refineitemid = getequipid(.@part); // save id of the item
 	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_MATERIAL_ID);
 	switch(getequipweaponlv(.@part)) {
@@ -271,7 +273,7 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 	set Zeny, Zeny-.@price;
 
 	// anti-hack
-	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 		mes "[Basta]";
 		emotion ET_FRET;

+ 20 - 12
npc/re/merchants/refine.txt

@@ -86,12 +86,13 @@ function	script	refinenew	{
 		mes "refine this item at all...";
 		close;
 	}
-	if (getequiprefinerycnt(.@part) < 10) {
+	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	if (.@refinerycnt < 10) {
 		mes "["+ .@npc_name$ +"]";
 		mes "I said I don't work with items that are lower than Level 10.";
 		close;
 	}
-	if (getequiprefinerycnt(.@part) >= 20) { //custom check
+	if (.@refinerycnt >= 20) { //custom check
 		mes "["+ .@npc_name$ +"]";
 		mes "I can't refine this";
 		mes "any more. This is as";
@@ -99,12 +100,12 @@ function	script	refinenew	{
 		close;
 	}
 	.@refineitemid = getequipid(.@part); // save id of the item
-	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_OVER10, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_OVER10, REFINE_MATERIAL_ID);
 	.@safe = 10;
 
-	if ((getequipweaponlv(.@part) >= 1) && (getequipweaponlv(.@part) <= 4)) {
+	if (getequipweaponlv(.@part) >= 1 && getequipweaponlv(.@part) <= 4) {
 		.@article$ = "a";
 		.@type$ = "weapon";
 	} else {
@@ -118,7 +119,7 @@ function	script	refinenew	{
 	mes "I will need 1 ^003366" + getitemname(.@material) + "^000000 and " + callfunc("F_InsertComma",.@price) + " zeny.";
 	mes "Are you sure you want to continue?";
 	next;
-	if(select("Yes:No") == 2){
+	if (select("Yes:No") == 2) {
 		mes "["+ .@npc_name$ +"]";
 		mes "Hm... if you mind... never mind...";
 		close;
@@ -155,7 +156,7 @@ function	script	refinenew	{
 		delitem .@material,1;
 
 		// anti-hack
-		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 			mes "["+ .@npc_name$ +"]";
 			emotion ET_FRET;
@@ -209,7 +210,7 @@ function	script	refinenew	{
 		}
 	}
 // New +11 and above Refining Functions ========================
-	if (getequiprefinerycnt(.@part) < .@safe) {
+	if (.@refinerycnt < .@safe) {
 		mes "["+ .@npc_name$ +"]";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		next;
@@ -218,14 +219,14 @@ function	script	refinenew	{
 		.@menu2 = 2;
 	switch(.@menu2){
 	case 1: 
-		.@refinecnt = .@safe - getequiprefinerycnt(.@part);
+		.@refinecnt = .@safe - .@refinerycnt;
 		break;
 	case 2:
 		mes "["+ .@npc_name$ +"]";
 		mes "How many times would you like me to refine your item?";
 		next;
 		input .@refinecnt;
-		.@refinecheck = .@refinecnt + getequiprefinerycnt(.@part);
+		.@refinecheck = .@refinecnt + .@refinerycnt;
 		if (.@refinecnt < 1 || .@refinecheck > 20) {
 			mes "["+ .@npc_name$ +"]";
 			mes "I can't refine this item that many times.";
@@ -271,6 +272,11 @@ function	script	refinenew	{
 			mes "Look here... you don't have any items on...";
 			close;
 		}
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
+		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt))
+			close;
+
 		if (getequipid(.@part) != .@refineitemid || (.@menu2 == 1 && getequippercentrefinery(.@part) < 100)) {
 			mes "["+ .@npc_name$ +"]";
 			mes "Clang... No, but did you imagine I could be so stupid?!";
@@ -316,6 +322,7 @@ function	script	refinenew	{
 			mes "I will do a better job next time! Don't worry!";
 			close;
 		}
+		.@refinerycnt = getequiprefinerycnt(.@part);
 	}
 	emotion ET_BEST;
 	mes "["+ .@npc_name$ +"]";
@@ -433,14 +440,15 @@ malangdo,224,172,6	script	Clink#mal_normal	544,{
 		mes "This can't be refined!!";
 		close;
 	}
-	if (getequiprefinerycnt(.@part) >= 10) {
+	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	if (.@refinerycnt >= 10) {
 		mes "[Clink]";
 		mes "Perfect refining. Did I do this for you?";
 		close;
 	}
 	
 	.@refineitemid = getequipid(.@part); // save id of the item
-	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	.@price = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_ZENY_COST);
 	.@material = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID);
 	
@@ -506,7 +514,7 @@ malangdo,224,172,6	script	Clink#mal_normal	544,{
 	Zeny = Zeny-.@price;
 
 	// anti-hack
-	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+	if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) ||
 		callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 		mes "[Clink]";
 		emotion ET_FRET;

+ 11 - 4
npc/re/merchants/shadow_refiner.txt

@@ -43,8 +43,11 @@
 		mes "There's nothing here!";
 		close;
 	}
+	.@equip_id = getequipid(.@part);
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 
 	while(1) {
+		.@equip_refine = getequiprefinerycnt(.@part);
 		mes "[Shadow Blacksmith]";
 		mes "I require " + callfunc("F_InsertComma", .@zeny_cost) + " zeny as a fee for EACH refine attempt.";
 		mes "Choose your Ore and start refining.";
@@ -63,7 +66,7 @@
 			.@mate$[1] = getitemname(.@material[1]);
 		else
 			.@mate$[1] = "^8C8C8C"+ getitemname(.@material[1]) +"^000000";
-		if (getequiprefinerycnt(.@part) > 6 && countitem(.@material[2]))
+		if (.@equip_refine > 6 && countitem(.@material[2]))
 			.@mate$[2] = getitemname(.@material[2]);
 		else
 			.@mate$[2] = "^8C8C8C"+ getitemname(.@material[2]) +"^000000";
@@ -89,7 +92,7 @@
 			mes "[Shadow Blacksmith]";
 			mes "You've cancelled refining.";
 			close;
- 		}
+		}
 		if (!countitem(.@choose)) {
 			mes "[Shadow Blacksmith]";
 			mes "You do not have enough "+ getitemname(.@choose) +".";
@@ -100,7 +103,7 @@
 			mes "You do not have enough zeny.";
 			close;
 		}
-		if (getequiprefinerycnt(.@part) > 9) {
+		if (.@equip_refine > 9) {
 			mes "[Shadow Blacksmith]";
 			mes "Shadow Equipment can be refined to the maximum of 10...";
 			close;
@@ -124,12 +127,16 @@
 				close;
 			}
 		}
-
 		mes "[Shadow Blacksmith]";
 		mes "Well then.. here goes nothing!";
 		next;
 		delitem .@choose,1;
 		Zeny -= .@zeny_cost;
+
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
+			close;
+
 		if (getequippercentrefinery(.@part, .@is_enriched) > rand(100)) {
 			successrefitem .@part;
 			mes "[Shadow Blacksmith]";

+ 2 - 1
npc/re/merchants/ticket_refiner.txt

@@ -78,6 +78,7 @@ prontera,184,177,6	script	Refine Master	851,{
 	}
 	.@refineitemid = getequipid(.@part); // save id of the item
 	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3);
 	switch(getequipweaponlv(.@part)) {
 	default:
 	case 0:
@@ -150,7 +151,7 @@ prontera,184,177,6	script	Refine Master	851,{
 
 		// anti-hack
 		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
-			callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
+			callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3])) {
 			mes "[Refine Master]";
 			emotion ET_FRET;
 			mes "Wait a second...";

+ 5 - 2
npc/re/quests/quests_malaya.txt

@@ -3604,6 +3604,7 @@ ma_fild01,238,198,4	script	Tikbalang Expert#malaya	582,{
 // Upgrade Boss Equipment :: malaya_mvpitem
 //============================================================
 ma_fild01,158,243,6	script	Tribe Blacksmith#malaya	582,{
+	disable_items;
 	mes "[Bayani]";
 	mes "I will upgrade your armor if you bring one that holds enormous power.";
 	next;
@@ -3782,7 +3783,9 @@ ma_fild01,158,243,6	script	Tribe Blacksmith#malaya	582,{
 		mes "[Bayani]";
 		mes "What is this! You said you wanted to upgrade " + getitemname(.@item) + " but why are you giving me this? You should be wearing " + getitemname(.@item) + ".";
 		close;
-	} else if (getequiprefinerycnt(.@part) < 9) {
+	}
+	.@equip_refine = getequiprefinerycnt(.@part);
+	if (.@equip_refine < 9) {
 		mes "[Bayani]";
 		mes "No, the sturdiness of this item has not been tested yet. It'll have to be at least +9 refined for me to say, 'Oh this is pretty sturdy armor.";
 		close;
@@ -3823,7 +3826,7 @@ ma_fild01,158,243,6	script	Tribe Blacksmith#malaya	582,{
 	delitem 6499,20; //Ancient_Grudge
 
 	// anti-hack
-	if (callfunc("F_IsEquipIDHack", .@part, .@item))
+	if (callfunc("F_IsEquipIDHack", .@part, .@item) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine))
 		close;
 
 	delequip .@part;