Bladeren bron

Shadow Refiner and getequiprefinecost (#2447)

* Fixes #2445 and fixes #2446.
* Fixed shadow refiner.
— The script uses the values of the array instead of the indexes to loop through it.
* Fixed segfault in getequiprefinecost.
— No checks in getequiprefinecost meant there were possibilities using negative indexes in arrays.
* Added to the script documentation what happens on failure when calling getequiprefinecost (it returns -1).
Thanks to @vstmpf, @crazystorm2017, and @hendra814!
Vincent Stumpf 7 jaren geleden
bovenliggende
commit
cd43f32ffb
3 gewijzigde bestanden met toevoegingen van 28 en 5 verwijderingen
  1. 3 0
      doc/script_commands.txt
  2. 14 5
      npc/re/merchants/shadow_refiner.txt
  3. 11 0
      src/map/script.cpp

+ 3 - 0
doc/script_commands.txt

@@ -2760,6 +2760,9 @@ Valid information types are:
 REFINE_ZENY_COST       - Zeny
 REFINE_MATERIAL_ID     - Material Item ID
 
+This function will return -1 on failure. The function fails if the cost type
+is invalid or if there is no item in the equipment slot. 
+
 ---------------------------------------
 
 *getareadropitem("<map name>",<x1>,<y1>,<x2>,<y2>,<item>)

+ 14 - 5
npc/re/merchants/shadow_refiner.txt

@@ -15,12 +15,12 @@
 	mes "Do you want to refine a shadow item? Pick yer poison!";
 	next;
 	setarray .@indices[1], EQI_SHADOW_ARMOR, EQI_SHADOW_WEAPON, EQI_SHADOW_SHIELD, EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L;
-	for(.@i = 1; .@i <= EQI_SHADOW_ACC_L; .@i++)
+	.@indlen = getarraysize(.@indices) - 1;
+	for(.@i = 1; .@i <= .@indlen; .@i++)
 		.@menu$ = .@menu$ + (getequipisequiped(.@indices[.@i]) ? getequipname(.@indices[.@i]) : F_getpositionname(.@indices[.@i]) +"-[Not equipped]") +":";
 	.@menu$ = .@menu$ + "Refine info";
-	.@part = .@indices[select(.@menu$)];
-
-	if (.@part == EQI_SHADOW_ACC_L + 1) { // Refine info
+	.@choice = select(.@menu$);
+	if (.@choice == .@indlen + 1) { // Refine info
 		mes "[Shadow Blacksmith]";
 		mes "When a shadow item is refined, it gains extra bonuses very much like normal items.";
 		next;
@@ -35,6 +35,15 @@
 		mes "HD ores can be used for gear that is at least refine level +7 and will prevent breaking as long as you stay talking to me.";
 		close;
 	}
+	
+	.@part = .@indices[.@choice];
+	
+	if (!getequipisequiped(.@part)) {
+		mes "[Shadow Blacksmith]";
+		mes "There's nothing here!";
+		close;
+	}
+	
 	while(1) {
 		mes "[Shadow Blacksmith]";
 		mes "I require " + callfunc("F_InsertComma", .@zeny_cost) + " zeny as a fee for EACH refine attempt.";
@@ -84,7 +93,7 @@
 		.@choose = .@material[.@option-1];
 		if (!countitem(.@choose)) {
 			mes "[Shadow Blacksmith]";
-			mes "You do not have enough "+ getitemname(.@choose) +" / "+ getitemname(.@choose) +".";
+			mes "You do not have enough "+ getitemname(.@choose) +".";
 			close;
 		}
 		if (Zeny < .@zeny_cost) {

+ 11 - 0
src/map/script.cpp

@@ -23565,6 +23565,7 @@ BUILDIN_FUNC(achievementupdate) {
 /**
  * Get an equipment's refine cost
  * getequiprefinecost(<equipment slot>,<type>,<information>{,<char id>})
+ * returns -1 on fail
  */
 BUILDIN_FUNC(getequiprefinecost) {
 	int i = -1, slot, type, info;
@@ -23579,9 +23580,19 @@ BUILDIN_FUNC(getequiprefinecost) {
 		return SCRIPT_CMD_FAILURE;
 	}
 
+	if (type < 0 || type >= REFINE_COST_MAX) {
+		script_pushint(st, -1);
+		return SCRIPT_CMD_SUCCESS;
+	}
+
 	if (equip_index_check(slot))
 		i = pc_checkequip(sd, equip_bitmask[slot]);
 
+	if (i < 0) {
+		script_pushint(st, -1);
+		return SCRIPT_CMD_SUCCESS;
+	}
+
 	int weapon_lv = sd->inventory_data[i]->wlv;
 	if (sd->inventory_data[i]->type == IT_SHADOWGEAR) {
 		if (sd->inventory_data[i]->equip == EQP_SHADOW_WEAPON)