Переглянути джерело

Merge branch 'master' of https://github.com/rathena/rathena

aleos89 10 роки тому
батько
коміт
4ffe723d8c

+ 3 - 0
conf/battle/skill.conf

@@ -306,3 +306,6 @@ teleport_on_portal: no
 // Is the knockback direction for Cart Revolution always West? (Note 1)
 // On official servers it will knock the target always to the West. If disabled it will knock the target backwards.
 cart_revo_knockback: yes
+
+// On official servers, Arrow Shower blow direction always rely on skill placed location to target instead of caster to target
+arrow_shower_knockback: yes

+ 1 - 1
conf/log_athena.conf

@@ -97,7 +97,7 @@ log_mvpdrop: no
 log_commands: yes
 
 // Log NPC 'logmes' commands (Note 1)
-log_npc: no
+log_npc: yes
 
 // Log CHAT (Global, Whisper, Party, Guild, Main chat) (Note 3)
 // LOGGING FILTERS

+ 1 - 1
db/mercenary_db.txt

@@ -8,7 +8,7 @@
 1506,DISGUISE,Disguise,55,7543,180,2,279,546,18,29,0,72,45,35,48,65,10,12,1,6,82,147,516,768,384
 1275,ALICE,Alice,62,10000,221,2,550,700,5,5,64,64,42,85,100,130,10,12,1,7,60,200,502,2304,480
 1965,M_WILD_ROSE,Wild Rose,38,2980,130,2,315,360,0,15,65,85,15,35,65,80,10,12,0,2,24,100,964,864,288
-1966,M_DOPPELGANGER,Doppelganger,72,249000,200,2,1340,1590,60,35,88,90,30,35,125,65,10,12,1,6,67,100,480,480,288
+1966,M_DOPPELGANGER,Doppelganger,72,7800,200,2,1340,1590,60,35,88,90,30,35,125,65,10,12,1,6,67,100,480,480,288
 1967,M_YGNIZEM,Egnigem Cenia,58,11200,320,2,823,1212,35,8,60,35,52,18,79,20,10,12,1,7,43,145,576,432,288
 2000,M_GAMEMASTER,[GM] Game Master,50,7000,250,2,100,50,6,17,1,109,1,60,215,111,10,0,0,7,20,150,450,432,300
 2001,F_GAMEMASTER,[GM] Game Master,50,7000,250,2,100,50,6,17,1,109,1,60,215,111,10,0,0,7,20,150,450,432,300

+ 2 - 2
db/pre-re/skill_unit_db.txt

@@ -1,7 +1,7 @@
 // Skill Unit Database
 //
 // Structure of Database:
-// ID,unit ID,unit ID 2,layout,range,interval,target,flag
+// Skill ID,Unit ID,Unit ID 2,Layout,Range,Interval,Target,Flag
 //
 // layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
 // target = friend (party +guildmates +neutral players) / party / guild
@@ -151,7 +151,7 @@
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
 2479,0xe5,    ,  0, 1,1000,enemy, 0xC006	//GN_THORNS_TRAP
-2482,0xe6,0x7f,  0, 1, 100,all,   0xD000	//GN_WALLOFTHORN
+2482,0xe6,0x7f, -1, 1, 300,enemy, 0xD000	//GN_WALLOFTHORN
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x8098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,enemy, 0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER

+ 1 - 1
db/re/item_db.txt

@@ -6990,7 +6990,7 @@
 13310,P_Huuma_Suriken1,P.Huuma Suriken I,5,0,,0,170,,1,0,0x02000000,63,2,34,3,60,0,22,{ bonus bMatk,50; },{},{}
 13311,Huuma_Shadow,Sword Huuma Shuriken,5,5000,,1500,170,,1,0,0x02000000,63,2,34,3,99,1,22,{ bonus bStr,3; },{},{}
 13312,Huuma_Job_Test,Prototype Huuma Shuriken,5,0,,3000,0,,1,0,0x02000000,63,2,34,4,99,1,22,{},{},{}
-13313,Huuma_Swirling_Petal,Flower Huuma Shuriken,5,100000,,1500,150,,1,2,0x02000000,63,2,34,3,110,1,22,{ bonus bMatk,50; bonus bAtkEle,Ele_Fire; bonus2 bSkillAtk,"KO_HUUMARANKA",20; },{},{}
+13313,Huuma_Swirling_Petal,Flower Huuma Shuriken,5,100000,,1500,150,,1,2,0x02000000,63,2,34,3,110,1,22,{ bonus bMatk,50; bonus2 bSkillAtk,"KO_HUUMARANKA",20; },{},{}
 13314,Huuma_Fluttering_Snow,Wave Huuma Shuriken,5,100000,,1500,200,,1,0,0x02000000,63,2,34,4,110,1,22,{ bonus bMatk,50; bonus bAtkEle,Ele_Water; bonus3 bAutoSpell,"NJ_HYOUSYOURAKU",(getskilllv("NJ_HYOUSYOURAKU")?getskilllv("NJ_HYOUSYOURAKU"):1),30; },{},{}
 13315,Huuma_Thunderstorm,Thunderstorm Huuma Shuriken,5,100000,,1500,200,,1,0,0x02000000,63,2,34,4,110,1,22,{ bonus bMatk,50; bonus bAtkEle,Ele_Wind; bonus3 bAutoSpell,"NJ_RAIGEKISAI",(getskilllv("NJ_RAIGEKISAI")?getskilllv("NJ_RAIGEKISAI"):1),30; },{},{}
 13316,Upg_Huuma_Shuriken,Upg Huuma Shuriken,5,20,,1500,55,,1,1,0x02000000,63,2,34,3,1,1,22,{ bonus bBaseAtk,(getrefine()*10); bonus bMatk,(getrefine()*5); bonus bLongAtkRate,(getrefine()); if(BaseLevel>70) bonus bBaseAtk,(((BaseLevel-70)/10)*5); },{},{}

+ 2 - 2
db/re/skill_unit_db.txt

@@ -1,7 +1,7 @@
 // Skill Unit Database
 //
 // Structure of Database:
-// ID,unit ID,unit ID 2,layout,range,interval,target,flag
+// Skill ID,Unit ID,Unit ID 2,Layout,Range,Interval,Target,Flag
 //
 // layout = -1:special, 0:1*1, 1:3*3, 2:5*5, up to 5:11*11
 // target = friend (party +guildmates +neutral players) / party / guild
@@ -153,7 +153,7 @@
 2468,0xf4,    ,  0, 1,1000,all,   0x010	//SO_EARTH_INSIGNIA
 
 2479,0xe5,    ,  0, 1,1000,enemy, 0xC006	//GN_THORNS_TRAP
-2482,0xe6,0x7f,  0, 1, 100,all,   0xD000	//GN_WALLOFTHORN
+2482,0xe6,0x7f, -1, 1, 300,enemy, 0xD000	//GN_WALLOFTHORN
 2484,0x86,    ,  0, 1, 100,enemy, 0x080	//GN_CRAZYWEED_ATK
 2485,0xe7,    ,  0, 2,2000,enemy, 0x8098	//GN_DEMONIC_FIRE
 2487,0xe8,    ,  2, 0,  -1,enemy, 0x2000	//GN_FIRE_EXPANSION_SMOKE_POWDER

+ 2 - 2
npc/cities/geffen.txt

@@ -125,7 +125,7 @@ geffen,147,26,0	script	Ralphie	97,{
 }
 
 geffen,111,48,0	script	Stacey	101,{
-	if (getequipid(1) == 2299) {
+	if (getequipid(EQI_HEAD_TOP) == 2299) {
 		mes "[Stacey]";
 		mes "Oh...!";
 		mes "Is that an Orc Helm you're wearing?! That's so cool! Wow...";
@@ -141,7 +141,7 @@ geffen,111,48,0	script	Stacey	101,{
 		}
 		close;
 	}
-	else if (getequipid(1) == 5094) {
+	else if (getequipid(EQI_HEAD_TOP) == 5094) {
 		mes "[Stacey]";
 		mes "Oh...";
 		mes "Wow...";

+ 5 - 5
npc/custom/etc/marriage.txt

@@ -394,19 +394,19 @@ OnTimer55000:
 
 //Subfunction: Checks that the groom/bride is still wearing their stuff.
 function SF_equip_check {
-	if (Sex && getequipid(2) != 7170) {
+	if (Sex && getequipid(EQI_ARMOR) != 7170) {
 		mes "["+@name$+"]";
 		mes "Child, what did you do with your "+getitemname(7170)+"?";
 		emotion e_dots;
 		return 0;
 	}
-	if (Sex == 0 && getequipid(2) != 2338) {
+	if (Sex == 0 && getequipid(EQI_ARMOR) != 2338) {
 		mes "["+@name$+"]";
 		mes "Child, you are supposed to wear a "+getitemname(2338)+" at all times during the ceremony...";
 		emotion e_dots;
 		return 0;
 	}
-	if (Sex == 0 && $@wed_veil && getequipid(1) != 2206) {
+	if (Sex == 0 && $@wed_veil && getequipid(EQI_HEAD_TOP) != 2206) {
 		mes "["+@name$+"]";
 		mes "Child, you can't take off your "+getitemname(2206)+" yet....";
 		emotion e_dots;
@@ -692,12 +692,12 @@ function SF_TryRegister {
 	else
 		set @item, 2338;
 	
-	if (getequipid(2) != @item) {
+	if (getequipid(EQI_ARMOR) != @item) {
 		mes "["+@name$+"]";
 		mes "You should be wearing a "+getitemname(@item)+" if you want to get married.";
 		close;
 	}
-	if (Sex == 0 && $@wed_veil && getequipid(1) != 2206) {
+	if (Sex == 0 && $@wed_veil && getequipid(EQI_HEAD_TOP) != 2206) {
 		mes "["+@name$+"]";
 		mes "Where is your "+getitemname(2206)+"? It's a necessary complement to your dress.";
 		close;

+ 1 - 1
npc/custom/item_signer.txt

@@ -119,7 +119,7 @@ prt_in,24,61,7	script	Perchik	47,{
 	if (!countitem2(.@id,1,.@ref,0,.@slot[0],.@slot[1],.@slot[2],.@slot[3])) {
 		mes "Where is "+getitemname(@id)+"...?";
 		npctalk "You're a snoozy cheater!";
-		logmes "CHEATER: Tried to sign an item not having it: "+getitemname(@id);
+		logmes "Hack: Tried to sign an item not having it: "+getitemname(@id);
 		emotion e_wah;
 		close;
 	}

+ 11 - 1
npc/events/RWC_2012.txt

@@ -67,6 +67,11 @@ prontera,147,61,3	script	Driller#pron	87,{
 		mes "This item has already been enchanted. I can't work on this as it is against the rules.";
 		close;
 	}
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@equip_id))
+		close;
+
 	delequip .@part;
 	if (rand(1,10) > 5) {
 		getitem .@slotted,1;
@@ -113,7 +118,6 @@ prontera,147,59,3	script	Goldberg#pron	878,{
 		mes "Alright, then, see you next time...";
 		close;
 	}
-	set .@equip_refine, getequiprefinerycnt(.@part);
 	setarray .@equip_card[0], getequipcardid(.@part,0),getequipcardid(.@part,1),getequipcardid(.@part,2),getequipcardid(.@part,3);
 	if (.@select == 1) {
 		switch(getequipid(.@part)) {
@@ -257,6 +261,11 @@ prontera,147,59,3	script	Goldberg#pron	878,{
 		else if (.@i < 301) set .@enchant, .@enc[2];
 		else set .@enchant,9;
 
+		// 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]))
+			close;
+
 		set .@equip_card[.@slot], .@enchant;
 		if (.@slot == 2 && .@enchant == 0) {
 			set .@equip_card[3],0;
@@ -269,6 +278,7 @@ prontera,147,59,3	script	Goldberg#pron	878,{
 			set .@equip_card[3],0;
 		}
 
+		set .@equip_refine, getequiprefinerycnt(.@part);
 		delequip .@part;
 		if (.@enchant == 9) {
 			mes "[Goldberg]";

+ 1 - 1
npc/events/event_skill_reset.txt

@@ -104,6 +104,6 @@ L_Reset:
 	mes @npcname$;
 	mes "Thank you.";
 	emotion e_thx;
-	logmes "SKILL RESET EVENT";
+//	logmes "SKILL RESET EVENT";
 	close;
 }

+ 1 - 1
npc/events/valentinesday_2012.txt

@@ -118,7 +118,7 @@ mosk_in,21,244,3	script	Baker Extraordinaire	410,{
 		close;
 	} else if(#V_QUE12==1) { 
 		mes .@n$;
-		if (getequipid(1) == 5024 && getequiprefinerycnt(1) >= 8) {
+		if (getequipid(EQI_HEAD_TOP) == 5024 && getequiprefinerycnt(EQI_HEAD_TOP) >= 8) {
 			mes "Ah, so Pinkamenia told you";
 			mes "to bring me the +8 Cake";
 			mes "Hat. Now I'm going";

+ 3 - 3
npc/jobs/2-2/crusader.txt

@@ -360,7 +360,7 @@ prt_castle,164,32,1	script	Man in Anguish	733,{
 			mes "Let me take";
 			mes "a look at your face.";
 			next;
-			if(getequipid(7) != 2608 && getequipid(8) != 2608) {
+			if(getequipid(EQI_ACC_L) != 2608 && getequipid(EQI_ACC_R) != 2608) {
 				mes "[Murnak Mijoul]";
 				mes "Hmm. You wish to become a Crusader, but do not wear a Rosary? I have no business with you if you cannot uphold our customs.";
 				close;
@@ -401,7 +401,7 @@ prt_castle,164,32,1	script	Man in Anguish	733,{
 			mes "I'll let you retake the test as much as you like. But if you continuously fail, there's an inherent problem with your";
 			mes "state of mind.";
 			next;
-			if(getequipid(7) != 2608 && getequipid(8) != 2608) {
+			if(getequipid(EQI_ACC_L) != 2608 && getequipid(EQI_ACC_R) != 2608) {
 				mes "[Murnak Mijoul]";
 				mes "Wait...";
 				mes "Where have you left your Rosary? You can't let that lie around just anywhere. We are supposed to be warriors of holiness.";
@@ -888,7 +888,7 @@ prt_castle,35,151,5	script	Patron Knight	751,{
 		}
 		next;
 		if (select("I would like to begin.:Give me some time to prepare.") == 1) {
-			if(getequipid(7) != 2608 && getequipid(8) != 2608) {
+			if(getequipid(EQI_ACC_L) != 2608 && getequipid(EQI_ACC_R) != 2608) {
 				mes "[Bliant Piyord]";
 				mes "Just a second, you do not have a Rosary equipped. As a Crusader, you must always have a Rosary on your person.";
 				next;

+ 1 - 1
npc/kafras/functions_kafras.txt

@@ -578,7 +578,7 @@ function	script	F_EntKafCode	{
 	set @kafcode_try,@kafcode_try+1;
 	if(@kafcode_try>10) {
 		set @kafcode_try,0;
-		logmes "Hack: Tried to fit storage password.";
+		logmes "Tried to fit storage password.";
 	}
 	if(input(@code_) == 1) {
 		mes "You can't use such big password.";

+ 3 - 7
npc/merchants/refine.txt

@@ -708,13 +708,9 @@ function	script	refinemain	{
 		set Zeny, Zeny-.@price;
 		delitem .@material,1;
 
-		//custom checks
-		if(getequipisequiped(.@part) == 0) { // hacker has removed the item (not changed, why?)
-			mes "[" + getarg(0) + "]";
-			mes "Look here... you don't have any Items on...";
-			close;
-		}
-		if(getequiprefinerycnt(.@part) != .@refinerycnt || getequipid(.@part) != .@refineitemid) { // hacker has changed the item
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 			mes "[" + getarg(0) + "]";
 			emotion e_an;
 			mes "Wait a second...";

+ 44 - 2
npc/other/Global_Functions.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= Lupus, kobra_k88
 //===== Current Version: ===================================== 
-//= 2.23
+//= 2.24
 //===== Compatible With: ===================================== 
 //= rAthena Project
 //===== Description: ========================================= 
@@ -46,6 +46,7 @@
 //= 2.21 Added format string to "F_InsertPlural" and more checks to "F_GetPlural". [Euphy]
 //= 2.22 Further improvements to "F_GetPlural". [Euphy]
 //= 2.23 Completed article function and added "F_GetArticle". [Euphy]
+//= 2.24 Added functions to check for equipment swap hacks. [Euphy]
 //============================================================ 
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -139,7 +140,7 @@ function	script	F_ClearGarbage	{
 //////////////////////////////////////////////////////////////////////////////////
 function	script	Job_Change	{
 	jobchange getarg(0),Upper;
-	logmes "CLASS CHANGE: " +strcharinfo(0)+ " become a "+jobname(Class);
+//	logmes "CLASS CHANGE: " +strcharinfo(0)+ " become a "+jobname(Class);
 	return;
 }
 
@@ -362,6 +363,47 @@ function	script	Time2Str	{
 }
 
 
+//////////////////////////////////////////////////////////////////////////////////
+// Checks if equipment has been swapped (i.e. via hacks).
+// The function checks the current equipment at a position against the supplied
+// values, and logs any mismatches.
+// Returns 0 if match, 1 if mismatch.
+// -- callfunc "F_IsEquipIDHack",<equip position>,<equip ID>
+// -- callfunc "F_IsEquipRefineHack",<equip position>,<refine>
+// -- callfunc "F_IsEquipCardHack",<equip position>,<card 0>,<card 1>,<card 2>,<card 3>
+//////////////////////////////////////////////////////////////////////////////////
+function	script	F_IsEquipIDHack	{
+	set .@id_chk, getequipid(getarg(0));
+	set .@id, getarg(1);
+	if (.@id != .@id_chk) {
+		logmes "Hack: Tried to swap equip " + getitemname(.@id) + " for " + getitemname(.@id_chk) + ".";
+		return 1;
+	}
+	return 0;
+}
+function	script	F_IsEquipRefineHack	{
+	set .@refine_chk, getequiprefinerycnt(getarg(0));
+	set .@refine, getarg(1);
+	if (.@refine != .@refine_chk) {
+		logmes "Hack: Tried to swap equip with refine +" + .@refine + " for +" + .@refine_chk + ".";
+		return 1;
+	}
+	return 0;
+}
+function	script	F_IsEquipCardHack	{
+	set .@pos, getarg(0);
+	for (set .@i,0; .@i < 4; set .@i, .@i+1) {
+		set .@card, getarg(.@i + 1);
+		set .@card_chk, getequipcardid(.@pos, .@i);
+		if (.@card != .@card_chk) {
+			logmes "Hack: Tried to swap card " + getitemname(.@card) + " for " + getitemname(.@card_chk) + ".";
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
 //////////////////////////////////////////////////////////////////////////////////
 // Functions for text manipulation [Euphy]
 //////////////////////////////////////////////////////////////////////////////////

+ 1 - 1
npc/quests/cooking_quest.txt

@@ -79,7 +79,7 @@ prt_castle,43,30,3	script	Charles Orleans#cook	878,{
 		mes "the stairs for me, alright?";
 		goto L_End;
 	}
-	else if (getequipid(1) != 5026) {
+	else if (getequipid(EQI_HEAD_TOP) != 5026) {
 		if (Sex) {
 			cutin "orleans_5",0;
 			emotion e_an;

+ 10 - 16
npc/re/instances/WolfchevLaboratory.txt

@@ -924,20 +924,20 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 	.@refine_count = getequiprefinerycnt(.@part);
 	.@equip_item = getequipid(.@part);
 	.@lhz_max_num = 4000;
-	if (.@equip_item == Agent_Katar || .@equip_item == Guillotine_Katar || .@equip_item == Ygnus_Stale || 
-	    .@equip_item == End_Sektura || .@equip_item = Cannon_Spear || .@equip_item == Giant_Lance || 
-	    .@equip_item == Aztoe_Nail || .@equip_item == Scarletto_Nail || .@equip_item == Bloody_Cross) {
+	if (.@equip_item == 13069 || .@equip_item == 1291 || .@equip_item == 1392 || 
+	    .@equip_item == 1393 || .@equip_item = 1435 || .@equip_item == 1490 || 
+	    .@equip_item == 13069 || .@equip_item == 13070 || .@equip_item == 16017) {
 		.@type = 1;
-		if (.@equip_item == Giant_Lance)
+		if (.@equip_item == 1490)
 			.@lhz_max_num = 4200;
-	} else if (.@equip_item == Catapult || .@equip_item == Big_CrossBow || .@equip_item == Creeper_Bow) {
+	} else if (.@equip_item == 18109 || .@equip_item == 18110 || .@equip_item == 18111) {
 		.@type = 2;
-	} else if (.@equip_item == Chilly_Spell_Book || .@equip_item == Recovery_Light) {
+	} else if (.@equip_item == 1584 || .@equip_item == 1659) {
 		.@type = 3;
-	} else if (.@equip_item== Giant_Shield || .@equip_item == Geffenia_Book_Water || .@equip_item == Bible_Of_Promise2 ||
-	           .@equip_item == Salvage_Cape || .@equip_item == Assassin_Handcuffs || .@equip_item == Green_Operation_Coat || 
-	           .@equip_item == Ancient_Gold_Deco) {
-		if (.@equip_item == Salvage_Cape || .@equip_item == Ancient_Gold_Deco)
+	} else if (.@equip_item == 2160 || .@equip_item == 2161 || .@equip_item == 2162 ||
+	           .@equip_item == 2582 || .@equip_item == 2892 || .@equip_item == 15044 || 
+	           .@equip_item == 18570) {
+		if (.@equip_item == 2582 || .@equip_item == 18570)
 			.@lhz_max_num = 4200;
 	} else {
 		mes "[Pudding]";
@@ -1258,12 +1258,6 @@ lhz_cube,233,24,4	script	Sorcerer#Bio4Reward	4_M_UMDANCEKID,{
 		} else {
 			specialeffect2 EF_FIREHIT;
 			getitem2 .@equip_item, 1, 1, .@refine_count, 0, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3];
-			//dispbottom "1:"+ .@equip_item;
-			//dispbottom "1:"+ .@refine_count;
-			//dispbottom "1:"+ .@equip_card[0];
-			//dispbottom "1:"+ .@equip_card[1];
-			//dispbottom "1:"+ .@equip_card[2];
-			//dispbottom "1:"+ .@equip_card[3];
 			emotion e_ho;
 			mes "[Pudding]";
 			mes "Fortunately the power of "+((.@socket_type==3)?"'^952420Thirst for Blood^000000'":"'^F2766EWill of Warrior^000000'")+" has been dwelt well in your equipment...";

+ 5 - 0
npc/re/merchants/card_separation.txt

@@ -285,6 +285,11 @@
 
 	set .@equip_id, getequipid(.@equip_num);
 	set .@equip_refine, getequiprefinerycnt(.@equip_num);
+
+	// anti-hack
+	if (callfunc("F_IsEquipCardHack", .@equip_num, .@equip_card[0], .@equip_card[1], .@equip_card[2], .@equip_card[3]))
+		close;
+
 	delequip .@equip_num;
 
 	// Chance of retaining refine level.

+ 14 - 1
npc/re/merchants/enchan_mal.txt

@@ -318,7 +318,6 @@ L_Socket:
 	set .@select, @mal_enchant_select;
 	set .@equip_id, @mal_equip_id;
 	set .@equip_name$, getitemname(.@equip_id)+((getitemslots(.@equip_id))?"["+getitemslots(.@equip_id)+"]":"");
-	set .@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);
 	set @mal_equip_id,0;
 	set @mal_enchant_select,0;
@@ -570,6 +569,12 @@ L_Socket:
 			mes "There is something wrong. Please try again.";
 			close;
 		}
+
+		// 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]))
+			close;
+
 		     if (.@equip_card[3] == 0 && getarg(1) < 4) set .@equip_card[3],.@enchant;
 		else if (.@equip_card[2] == 0 && getarg(1) < 3) set .@equip_card[2],.@enchant;
 		else if (.@equip_card[1] == 0 && getarg(1) < 2) set .@equip_card[1],.@enchant;
@@ -595,6 +600,7 @@ 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]
@@ -629,6 +635,13 @@ L_Socket:
 		mes "[Mayomayo]";
 		mes "Initialize the enchant effect from the equipment.";
 		delitem 6417,1; //Silvervine
+
+		// 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]))
+			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]

+ 14 - 0
npc/re/merchants/enchan_mora.txt

@@ -1078,6 +1078,13 @@ L_Socket:
 			mes "Well I guess I was wrong...";
 			close;
 		}
+
+		// anti-hack
+		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;
+
 		if (.@equip_card[3] == 0 && getarg(2) < 4) {
 			set .@equip_card[3],.@enchant;
 		} else if (.@equip_card[2] == 0 && getarg(2) < 3) {
@@ -1103,6 +1110,13 @@ L_Socket:
 		}
 		delitem 6380,1; //Mora_Coin
 		set Zeny, Zeny-100000;
+
+		// anti-hack
+		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;
+
 		delequip .@part;
 		if (.@enchant == 9) {
 			specialeffect2 EF_SUI_EXPLOSION;

+ 14 - 1
npc/re/merchants/enchan_upg.txt

@@ -89,7 +89,6 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 		mes "I don't want to touch your equipment now!";
 		close;
 	}
-	set .@equip_refine, getequiprefinerycnt(.@part);
 
 	if (.@select == 1) {
 		if (!countitem(6484)) {
@@ -218,6 +217,7 @@ 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!";
@@ -228,6 +228,12 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 			mes "The slot ^9900004^000000 has been enchanted!";
 		}
 		delitem 6484,1; //Enchant_Book
+
+		// 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]))
+			close;
+
 		delequip .@part;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] .@enchant
@@ -255,6 +261,13 @@ prt_in,28,73,3	script	Devil Enchant Master#prq	63,{
 		specialeffect EF_REPAIRWEAPON;
 		mes "I initialized the enchant effects.";
 		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]))
+			close;
+
+		set .@equip_refine, getequiprefinerycnt(.@part);
 		delequip .@part;
 
 //		GetNonSlotItemSock2 .@equip_refine .@equip_id .@equip_card[0] .@equip_card[1] .@equip_card[2] 0

+ 3 - 7
npc/re/merchants/refine.txt

@@ -157,13 +157,9 @@ function	script	refinenew	{
 		set Zeny,Zeny - .@price;
 		delitem .@material,1;
 
-		//custom checks
-		if (getequipisequiped(.@part) == 0) { // hacker has removed the item (not changed, why?)
-			mes "[" + getarg(0) + "]";
-			mes "Look here... you don't have any items on...";
-			close;
-		}
-		if (getequiprefinerycnt(.@part) != .@refinerycnt || getequipid(.@part) != .@refineitemid) { // hacker has changed the item
+		// anti-hack
+		if (callfunc("F_IsEquipIDHack", .@part, .@refineitemid) ||
+		    callfunc("F_IsEquipRefineHack", .@part, .@refinerycnt)) {
 			mes "[" + getarg(0) + "]";
 			emotion e_an;
 			mes "Wait a second...";

+ 6 - 3
npc/re/quests/quests_malaya.txt

@@ -3773,7 +3773,7 @@ ma_fild01,158,243,6	script	Tribe Blacksmith#malaya	582,{
 		break;
 	}
 	
-	if (!(.@item)) {
+	if (!getequipisequiped(.@part)) {
 		mes "[Bayani]";
 		mes "You should wear the equipment to upgrade and not come without it on you.";
 		close;
@@ -3819,11 +3819,14 @@ ma_fild01,158,243,6	script	Tribe Blacksmith#malaya	582,{
 	mes "[Bayani]";
 	mes "BAM!!";
 	next;
-	
 	delitem 6499,20; //Ancient_Grudge
+
+	// anti-hack
+	if (callfunc("F_IsEquipIDHack", .@part, .@item))
+		close;
+
 	delequip .@part;
 	getitem .@newItem, 1; 
-	
 	mes "[Bayani]";
 	mes "Ha ha. Perfect.";
 	mes "Congratulations. Your armor is better than ever.";

+ 1 - 1
sql-files/item_db_re.sql

@@ -7021,7 +7021,7 @@ REPLACE INTO `item_db_re` VALUES (13309,'Huuma_Giant_Wheel_C','Huuma Giant Wheel
 REPLACE INTO `item_db_re` VALUES (13310,'P_Huuma_Suriken1','P.Huuma Suriken I',5,0,NULL,0,'170',NULL,1,0,0x02000000,63,2,34,3,'60',0,22,'bonus bMatk,50;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13311,'Huuma_Shadow','Sword Huuma Shuriken',5,5000,NULL,1500,'170',NULL,1,0,0x02000000,63,2,34,3,'99',1,22,'bonus bStr,3;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13312,'Huuma_Job_Test','Prototype Huuma Shuriken',5,0,NULL,3000,'0',NULL,1,0,0x02000000,63,2,34,4,'99',1,22,NULL,NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (13313,'Huuma_Swirling_Petal','Flower Huuma Shuriken',5,100000,NULL,1500,'150',NULL,1,2,0x02000000,63,2,34,3,'110',1,22,'bonus bMatk,50; bonus bAtkEle,Ele_Fire; bonus2 bSkillAtk,"KO_HUUMARANKA",20;',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (13313,'Huuma_Swirling_Petal','Flower Huuma Shuriken',5,100000,NULL,1500,'150',NULL,1,2,0x02000000,63,2,34,3,'110',1,22,'bonus bMatk,50; bonus2 bSkillAtk,"KO_HUUMARANKA",20;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13314,'Huuma_Fluttering_Snow','Wave Huuma Shuriken',5,100000,NULL,1500,'200',NULL,1,0,0x02000000,63,2,34,4,'110',1,22,'bonus bMatk,50; bonus bAtkEle,Ele_Water; bonus3 bAutoSpell,"NJ_HYOUSYOURAKU",(getskilllv("NJ_HYOUSYOURAKU")?getskilllv("NJ_HYOUSYOURAKU"):1),30;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13315,'Huuma_Thunderstorm','Thunderstorm Huuma Shuriken',5,100000,NULL,1500,'200',NULL,1,0,0x02000000,63,2,34,4,'110',1,22,'bonus bMatk,50; bonus bAtkEle,Ele_Wind; bonus3 bAutoSpell,"NJ_RAIGEKISAI",(getskilllv("NJ_RAIGEKISAI")?getskilllv("NJ_RAIGEKISAI"):1),30;',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13316,'Upg_Huuma_Shuriken','Upg Huuma Shuriken',5,20,NULL,1500,'55',NULL,1,1,0x02000000,63,2,34,3,'1',1,22,'bonus bBaseAtk,(getrefine()*10); bonus bMatk,(getrefine()*5); bonus bLongAtkRate,(getrefine()); if(BaseLevel>70) bonus bBaseAtk,(((BaseLevel-70)/10)*5);',NULL,NULL);

+ 5 - 4
src/map/battle.c

@@ -6277,14 +6277,14 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
  *	Initial refactoring by Baalberith
  *	Refined and optimized by helvetica
  */
-struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int count)
+struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int flag)
 {
 	struct Damage d;
 
 	switch(attack_type) {
-		case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_id,skill_lv,count); break;
-		case BF_MAGIC:  d = battle_calc_magic_attack(bl,target,skill_id,skill_lv,count);  break;
-		case BF_MISC:   d = battle_calc_misc_attack(bl,target,skill_id,skill_lv,count);   break;
+		case BF_WEAPON: d = battle_calc_weapon_attack(bl,target,skill_id,skill_lv,flag); break;
+		case BF_MAGIC:  d = battle_calc_magic_attack(bl,target,skill_id,skill_lv,flag);  break;
+		case BF_MISC:   d = battle_calc_misc_attack(bl,target,skill_id,skill_lv,flag);   break;
 		default:
 			ShowError("battle_calc_attack: unknown attack type! %d (skill_id=%d, skill_lv=%d)\n", attack_type, skill_id, skill_lv);
 			memset(&d,0,sizeof(d));
@@ -7798,6 +7798,7 @@ static const struct _battle_data {
 	{ "at_monsterignore",                   &battle_config.autotrade_monsterignore,         0,      0,      1,              },
 	{ "idletime_option",                    &battle_config.idletime_option,                 0x25,   1,      INT_MAX,        },
 	{ "spawn_direction",                    &battle_config.spawn_direction,                 0,      0,      1,              },
+	{ "arrow_shower_knockback",             &battle_config.arrow_shower_knockback,          1,      0,      1,              },
 };
 #ifndef STATS_OPT_OUT
 /**

+ 2 - 1
src/map/battle.h

@@ -79,7 +79,7 @@ struct block_list;
 
 // Damage Calculation
 
-struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int count);
+struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int flag);
 
 int64 battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, bool status_reflect);
 
@@ -567,6 +567,7 @@ extern struct Battle_Config
 	int autotrade_monsterignore;
 	int idletime_option;
 	int spawn_direction;
+	int arrow_shower_knockback;
 } battle_config;
 
 void do_init_battle(void);

+ 101 - 74
src/map/script.c

@@ -8092,29 +8092,31 @@ BUILDIN_FUNC(getequippercentrefinery)
 /*==========================================
  * Refine +1 item at pos and log and display refine
  *------------------------------------------*/
-BUILDIN_FUNC(successrefitem)
-{
-	int i = -1, num, up = 1;
+BUILDIN_FUNC(successrefitem) {
+	short i = -1, up = 1;
+	int pos;
 	TBL_PC *sd;
 
-	num = script_getnum(st,2);
+	pos = script_getnum(st,2);
 	sd = script_rid2sd(st);
-	if( sd == NULL )
+	if (sd == NULL)
 		return 0;
 
-	if( script_hasdata(st, 3) )
+	if (script_hasdata(st, 3))
 		up = script_getnum(st, 3);
 
-	if (num > 0 && num <= ARRAYLENGTH(equip))
-		i = pc_checkequip(sd,equip[num-1]);
-	if(i >= 0) {
+	if (pos > 0 && pos <= ARRAYLENGTH(equip))
+		i = pc_checkequip(sd,equip[pos-1]);
+	if (i >= 0) {
 		unsigned int ep = sd->status.inventory[i].equip;
 
 		//Logs items, got from (N)PC scripts [Lupus]
 		log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i]);
 
-		if (sd->status.inventory[i].refine >= MAX_REFINE)
+		if (sd->status.inventory[i].refine >= MAX_REFINE) {
+			script_pushint(st, MAX_REFINE);
 			return SCRIPT_CMD_SUCCESS;
+		}
 
 		sd->status.inventory[i].refine += up;
 		sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE);
@@ -8129,10 +8131,10 @@ BUILDIN_FUNC(successrefitem)
 		clif_additem(sd,i,1,0);
 		pc_equipitem(sd,i,ep);
 		clif_misceffect(&sd->bl,3);
-		if(sd->status.inventory[i].refine == MAX_REFINE &&
+		if (sd->status.inventory[i].refine == MAX_REFINE &&
 			sd->status.inventory[i].card[0] == CARD0_FORGE &&
-			sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
-		){ // Fame point system [DracoRPG]
+			sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3]))
+		{ // Fame point system [DracoRPG]
 			switch (sd->inventory_data[i]->wlv){
 				case 1:
 					pc_addfame(sd, battle_config.fame_refine_lv1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
@@ -8145,57 +8147,63 @@ BUILDIN_FUNC(successrefitem)
 					break;
 			 }
 		}
+		script_pushint(st, sd->status.inventory[i].refine);
+		return SCRIPT_CMD_SUCCESS;
 	}
 
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_successrefitem: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+	script_pushint(st, -1);
+	return SCRIPT_CMD_FAILURE;
 }
 
 /*==========================================
  * Show a failed Refine +1 attempt
  *------------------------------------------*/
-BUILDIN_FUNC(failedrefitem)
-{
-	int i=-1,num;
+BUILDIN_FUNC(failedrefitem) {
+	short i = -1;
+	int pos;
 	TBL_PC *sd;
 
-	num = script_getnum(st,2);
+	pos = script_getnum(st,2);
 	sd = script_rid2sd(st);
-	if( sd == NULL )
+	if (sd == NULL)
 		return 0;
 
-	if (num > 0 && num <= ARRAYLENGTH(equip))
-		i=pc_checkequip(sd,equip[num-1]);
-	if(i >= 0) {
+	if (pos > 0 && pos <= ARRAYLENGTH(equip))
+		i = pc_checkequip(sd,equip[pos-1]);
+	if (i >= 0) {
 		sd->status.inventory[i].refine = 0;
 		pc_unequipitem(sd,i,3); //recalculate bonus
 		clif_refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure
-
 		pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT);
-
 		clif_misceffect(&sd->bl,2); 	// display failure effect
+		script_pushint(st, 1);
+		return SCRIPT_CMD_SUCCESS;
 	}
 
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_failedrefitem: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+	script_pushint(st, 0);
+	return SCRIPT_CMD_FAILURE;
 }
 
 /*==========================================
  * Downgrades an Equipment Part by -1 . [Masao]
  *------------------------------------------*/
-BUILDIN_FUNC(downrefitem)
-{
-	int i = -1, num, down = 1;
+BUILDIN_FUNC(downrefitem) {
+	short i = -1, down = 1;
+	int pos;
 	TBL_PC *sd;
 
 	sd = script_rid2sd(st);
 	if( sd == NULL )
 		return 0;
-	num = script_getnum(st,2);
-	if( script_hasdata(st, 3) )
+	pos = script_getnum(st,2);
+	if (script_hasdata(st, 3))
 		down = script_getnum(st, 3);
 
-	if (num > 0 && num <= ARRAYLENGTH(equip))
-		i = pc_checkequip(sd,equip[num-1]);
-	if(i >= 0) {
+	if (pos > 0 && pos <= ARRAYLENGTH(equip))
+		i = pc_checkequip(sd,equip[pos-1]);
+	if (i >= 0) {
 		unsigned int ep = sd->status.inventory[i].equip;
 
 		//Logs items, got from (N)PC scripts [Lupus]
@@ -8214,30 +8222,40 @@ BUILDIN_FUNC(downrefitem)
 		clif_additem(sd,i,1,0);
 		pc_equipitem(sd,i,ep);
 		clif_misceffect(&sd->bl,2);
+		script_pushint(st, sd->status.inventory[i].refine);
+		return SCRIPT_CMD_SUCCESS;
 	}
 
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_downrefitem: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+	script_pushint(st, -1);
+	return SCRIPT_CMD_FAILURE;
 }
 
 /*==========================================
  * Delete the item equipped at pos.
  *------------------------------------------*/
-BUILDIN_FUNC(delequip)
-{
-	int i=-1,num,ret=0;
+BUILDIN_FUNC(delequip) {
+	short i = -1;
+	int pos;
+	int8 ret;
 	TBL_PC *sd;
 
-	num = script_getnum(st,2);
+	pos = script_getnum(st,2);
 	sd = script_rid2sd(st);
-	if( sd == NULL )
+	if (sd == NULL)
 		return 0;
 
-	if (num > 0 && num <= ARRAYLENGTH(equip))
-		i=pc_checkequip(sd,equip[num-1]);
-	if(i >= 0) {
+	if (pos > 0 && pos <= ARRAYLENGTH(equip))
+		i = pc_checkequip(sd,equip[pos-1]);
+	if (i >= 0) {
 		pc_unequipitem(sd,i,3); //recalculate bonus
 		ret = !(pc_delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT));
 	}
+	else {
+		ShowError("buildin_delequip: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+		st->state = END;
+		return SCRIPT_CMD_FAILURE;
+	}
 
 	script_pushint(st,ret);
 	return SCRIPT_CMD_SUCCESS;
@@ -8246,27 +8264,29 @@ BUILDIN_FUNC(delequip)
 /*==========================================
  * Break the item equipped at pos.
  *------------------------------------------*/
-BUILDIN_FUNC(breakequip)
-{
-	int i=-1,num;
+BUILDIN_FUNC(breakequip) {
+	short i = -1;
+	int pos;
 	TBL_PC *sd;
 
-	num = script_getnum(st,2);
+	pos = script_getnum(st,2);
 	sd = script_rid2sd(st);
-	if( sd == NULL )
+	if (sd == NULL)
 		return 0;
 
-	if (num > 0 && num <= ARRAYLENGTH(equip))
-		i = pc_checkequip(sd,equip[num-1]);
+	if (pos > 0 && pos <= ARRAYLENGTH(equip))
+		i = pc_checkequip(sd,equip[pos-1]);
 	if (i >= 0) {
 		sd->status.inventory[i].attribute = 1;
 		pc_unequipitem(sd,i,3);
 		clif_equiplist(sd);
 		script_pushint(st,1);
-	} else
-		script_pushint(st,0);
+		return SCRIPT_CMD_SUCCESS;
+	}
 
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_breakequip: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+	script_pushint(st,0);
+	return SCRIPT_CMD_FAILURE;
 }
 
 /*==========================================
@@ -14254,42 +14274,49 @@ BUILDIN_FUNC(day)
 //=======================================================
 // Unequip [Spectre]
 //-------------------------------------------------------
-BUILDIN_FUNC(unequip)
-{
-	size_t num;
+BUILDIN_FUNC(unequip) {
+	int pos;
 	TBL_PC *sd;
 
-	num = script_getnum(st,2);
-	sd = script_rid2sd(st);
-	if( sd != NULL && num >= 1 && num <= ARRAYLENGTH(equip) )
-	{
-		short i = pc_checkequip(sd,equip[num-1]);
-		if (i >= 0)
+	if (!(sd = script_rid2sd(st)))
+		return SCRIPT_CMD_SUCCESS;
+
+	pos = script_getnum(st,2);
+	if (pos >= 1 && pos <= ARRAYLENGTH(equip)) {
+		short i = pc_checkequip(sd,equip[pos-1]);
+		if (i >= 0) {
 			pc_unequipitem(sd,i,1|2);
+			script_pushint(st, 1);
+			return SCRIPT_CMD_SUCCESS;
+		}
 	}
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_unequip: No item equipped at pos %d (CID=%d/AID=%d).\n", pos, sd->status.char_id, sd->status.account_id);
+	script_pushint(st, 0);
+	return SCRIPT_CMD_FAILURE;
 }
 
-BUILDIN_FUNC(equip)
-{
+BUILDIN_FUNC(equip) {
 	unsigned short nameid = 0;
 	int i;
 	TBL_PC *sd;
 	struct item_data *item_data;
 
-	sd = script_rid2sd(st);
+	if (!(sd = script_rid2sd(st)))
+		return SCRIPT_CMD_SUCCESS;
 
-	nameid=script_getnum(st,2);
-	if((item_data = itemdb_exists(nameid)) == NULL)
-	{
-		ShowError("wrong item ID : equipitem(%hu)\n",nameid);
-		return 1;
+	nameid = script_getnum(st,2);
+	if ((item_data = itemdb_exists(nameid))) {
+		ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid );
+		if (i < MAX_INVENTORY) {
+			pc_equipitem(sd,i,item_data->equip);
+			script_pushint(st,1);
+			return SCRIPT_CMD_SUCCESS;
+		}
 	}
-	ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid );
-	if( i < MAX_INVENTORY )
-		pc_equipitem(sd,i,item_data->equip);
 
-	return SCRIPT_CMD_SUCCESS;
+	ShowError("buildin_equip: Item %hu cannot be equipped\n",nameid);
+	script_pushint(st,0);
+	return SCRIPT_CMD_FAILURE;
 }
 
 BUILDIN_FUNC(autoequip)

Різницю між файлами не показано, бо вона завелика
+ 267 - 236
src/map/skill.c


+ 4 - 3
src/map/skill.h

@@ -184,7 +184,8 @@ struct s_skill_db {
 };
 extern struct s_skill_db skill_db[MAX_SKILL_DB];
 
-#define MAX_SKILL_UNIT_LAYOUT	55
+#define MAX_SKILL_UNIT_LAYOUT	52
+#define MAX_SKILL_UNIT_LAYOUT2	17
 #define MAX_SQUARE_LAYOUT		5	// 11*11 Placement of a maximum unit
 #define MAX_SKILL_UNIT_COUNT ((MAX_SQUARE_LAYOUT*2+1)*(MAX_SQUARE_LAYOUT*2+1))
 struct s_skill_unit_layout {
@@ -388,7 +389,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li
 void skill_clear_unitgroup(struct block_list *src);
 int skill_clear_group(struct block_list *bl, int flag);
 void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, unsigned int tick);
-int64 skill_unit_ondamaged(struct skill_unit *unit,struct block_list *bl,int64 damage);
+int64 skill_unit_ondamaged(struct skill_unit *unit,int64 damage);
 
 int skill_castfix( struct block_list *bl, uint16 skill_id, uint16 skill_lv);
 int skill_castfix_sc( struct block_list *bl, int time);
@@ -410,7 +411,7 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
 int skill_check_unit_cell(uint16 skill_id,int16 m,int16 x,int16 y,int unit_id);
 int skill_unit_out_all( struct block_list *bl,unsigned int tick,int range);
 int skill_unit_move(struct block_list *bl,unsigned int tick,int flag);
-int skill_unit_move_unit_group( struct skill_unit_group *group, int16 m,int16 dx,int16 dy);
+void skill_unit_move_unit_group( struct skill_unit_group *group, int16 m,int16 dx,int16 dy);
 
 struct skill_unit_group *skill_check_dancing( struct block_list *src );
 

+ 1 - 1
src/map/status.c

@@ -1352,7 +1352,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
 	}
 
 	if (target->type == BL_SKILL)
-		return (int)skill_unit_ondamaged((struct skill_unit *)target, src, hp);
+		return (int)skill_unit_ondamaged((struct skill_unit *)target, hp);
 
 	status = status_get_status_data(target);
 	if(!status || status == &dummy_status )

+ 1 - 1
src/map/unit.c

@@ -898,7 +898,7 @@ uint8 unit_getdir(struct block_list *bl)
  * @param dx: Destination cell X
  * @param dy: Destination cell Y
  * @param count: How many cells to push bl
- * @param flag: Whether or not to send position packet updates
+ * @param flag: &1 Whether or not to send position packet updates
  * @return count (can be modified due to map cell restrictions)
  */
 int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag)

Деякі файли не було показано, через те що забагато файлів було змінено