Quesooo Posted April 15, 2018 Group: Members Topic Count: 197 Topics Per Day: 0.07 Content Count: 883 Reputation: 28 Joined: 02/13/17 Last Seen: November 10, 2022 Share Posted April 15, 2018 anyone can update this working on rathena latest rev? Quote Link to comment Share on other sites More sharing options...
Ukiram Posted April 23, 2019 Group: Members Topic Count: 45 Topics Per Day: 0.02 Content Count: 291 Reputation: 27 Joined: 12/16/17 Last Seen: December 19, 2023 Share Posted April 23, 2019 On 4/15/2018 at 7:12 PM, Quesooo said: anyone can update this working on rathena latest rev? Not working in latest rAthena? Quote Link to comment Share on other sites More sharing options...
latios Posted March 22, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted March 22, 2020 (edited) Hi all, I've taken the time to update this script and tested it on my server running latest version of rAthena (version at the time of writing Git Hash: f8d5d45). Additional Changes NPC name can now be easily customised by replacing 2nd argument in the function call at the bottom of npc/custom/etc/costume.txt NPC checks whether the user already has the same item being restored equipped or in inventory and will prevent restoring. Fixed/tweaked some typos and grammar for the NPC dialogue and atcommand messages. costume.txt has been included inside the diff Screenshot Costume_System_v2.diff Edit: I actually just discovered that the wonderful secretdataz had already updated the diff to work with newer versions of rAthena here (https://github.com/secretdataz/rathena/pull/8/files). The main differences to my edit is secret's also handles costuming garments and there is atcommand documentation. The diff I have uploaded comes with an updated NPC script. Edited March 22, 2020 by latios Found existing diff by secretdataz 1 Quote Link to comment Share on other sites More sharing options...
Captain Posted March 26, 2020 Group: Members Topic Count: 8 Topics Per Day: 0.00 Content Count: 17 Reputation: 0 Joined: 11/04/18 Last Seen: July 25, 2022 Share Posted March 26, 2020 @latios Thx for the update, but to be able to equip the costume you must have the requirements of the normal headgear example : a costume apple of archer require lvl 30 and can't equip by a novice Quote Link to comment Share on other sites More sharing options...
latios Posted March 27, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted March 27, 2020 @Captain Yes, that's correct. Although a way around this is to "costume" the item on another character who can wear it and then put it in storage to transfer back to your other character to wear. I don't believe the item permissions (storage/trade/drop/etc ...) are modified, so if you could trade it before you can still trade it after "costuming" the item. Quote Link to comment Share on other sites More sharing options...
Captain Posted March 27, 2020 Group: Members Topic Count: 8 Topics Per Day: 0.00 Content Count: 17 Reputation: 0 Joined: 11/04/18 Last Seen: July 25, 2022 Share Posted March 27, 2020 @latios The problem is you can't equip the costume headgear if you not have the requirement of not costume headgear example on novice with costume apple of archer : Quote Link to comment Share on other sites More sharing options...
latios Posted March 28, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted March 28, 2020 @Captain Oh I see what you mean. There is a nice example of how to remove this limitation in this thread: Hopefully that meets your needs. 1 Quote Link to comment Share on other sites More sharing options...
ahloi007 Posted April 25, 2020 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 78 Reputation: 1 Joined: 10/15/12 Last Seen: May 23, 2023 Share Posted April 25, 2020 On 3/23/2020 at 1:12 AM, latios said: Hi all, I've taken the time to update this script and tested it on my server running latest version of rAthena (version at the time of writing Git Hash: f8d5d45). Additional Changes NPC name can now be easily customised by replacing 2nd argument in the function call at the bottom of npc/custom/etc/costume.txt NPC checks whether the user already has the same item being restored equipped or in inventory and will prevent restoring. Fixed/tweaked some typos and grammar for the NPC dialogue and atcommand messages. costume.txt has been included inside the diff Screenshot Costume_System_v2.diff 14.63 kB · 27 downloads Edit: I actually just discovered that the wonderful secretdataz had already updated the diff to work with newer versions of rAthena here (https://github.com/secretdataz/rathena/pull/8/files). The main differences to my edit is secret's also handles costuming garments and there is atcommand documentation. The diff I have uploaded comes with an updated NPC script. Hi latios, I failed to upload the "Costume System v2.diff", would you please guide me the step?? Thanks! Quote Link to comment Share on other sites More sharing options...
latios Posted April 25, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted April 25, 2020 (edited) @ahloi007 Ah apologies, I think I've made a mistake in the uploaded diff. I'll post a fixed version soon, one that works when you run: git apply "Costume System v2.diff" Edited April 25, 2020 by latios Quote Link to comment Share on other sites More sharing options...
ahloi007 Posted April 25, 2020 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 78 Reputation: 1 Joined: 10/15/12 Last Seen: May 23, 2023 Share Posted April 25, 2020 1 minute ago, latios said: @ahloi007 There is this StackOverflow answer but I believe there is also nice short video example here: But I recommend learning about what a "diff" is and how they work: How to read a diff file: https://www.git-tower.com/learn/git/ebook/en/command-line/advanced-topics/diffs How to use git diff: https://www.atlassian.com/git/tutorials/saving-changes/git-diff Yes...!! thats just awesome! thanks Quote Link to comment Share on other sites More sharing options...
latios Posted April 25, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted April 25, 2020 Apologies, I may not be able to fix it such that it works with "git apply" for some time. It will have to be a manual process for now. Quote Link to comment Share on other sites More sharing options...
Mael Posted April 25, 2020 Group: Forum Moderator Topic Count: 25 Topics Per Day: 0.01 Content Count: 837 Reputation: 321 Joined: 02/11/19 Last Seen: 4 hours ago Share Posted April 25, 2020 https://rathena.org/board/topic/119536-latest-costumeitem/#comment-362515 Quote Link to comment Share on other sites More sharing options...
Bolby91 Posted May 4, 2020 Group: Members Topic Count: 19 Topics Per Day: 0.00 Content Count: 60 Reputation: 0 Joined: 07/03/13 Last Seen: February 12 Share Posted May 4, 2020 whats wrong with this one? Quote Link to comment Share on other sites More sharing options...
yhanrivera Posted May 4, 2020 Group: Members Topic Count: 2 Topics Per Day: 0.00 Content Count: 5 Reputation: 0 Joined: 03/17/13 Last Seen: September 24, 2023 Share Posted May 4, 2020 14 hours ago, Jholz27 said: whats wrong with this one? You need to apply the diff, to make it work. It basically says that costume is not a command or is not present in your files. Quote Link to comment Share on other sites More sharing options...
ahloi007 Posted May 10, 2020 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 78 Reputation: 1 Joined: 10/15/12 Last Seen: May 23, 2023 Share Posted May 10, 2020 @latios , I've got this error what should I do? Quote pc.cpp: In function 'void pc_delautobonus(map_session_data*, std::vector<s_autobonus>&, bool)': pc.cpp:2705:10: error: 'j' was not declared in this scope for(j = 0; j < EQI_MAX_BONUS; j++) { ^ pc.cpp:2705:21: error: 'EQI_MAX_BONUS' was not declared in this scope for(j = 0; j < EQI_MAX_BONUS; j++) { ^ make[1]: *** [obj/pc.o] Error 1 Quote Link to comment Share on other sites More sharing options...
latios Posted May 10, 2020 Group: Members Topic Count: 3 Topics Per Day: 0.00 Content Count: 25 Reputation: 17 Joined: 12/12/15 Last Seen: June 18, 2022 Share Posted May 10, 2020 @ahloi007 The first issue is saying that "j" hasn't been defined on line 2705 in file pc.cpp. You'll want to look around the code there and try to figure out why the definition (e.g. "int j;") is missing. For example, in this part of the diff there is an "int j;" at the top, but isn't there for some reason in your code. @@ -2627,7 +2638,7 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector<s_autobonus> *bonu int j; unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for(j = 0; j < EQI_MAX; j++) { + for(j = 0; j < EQI_MAX_BONUS; j++) { if(sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } The second issue is saying that the constant "EQI_MAX_BONUS" isn't found anywhere in the pc.cpp or pc.hpp files. In the diff, there is a section which indicates it should be added to pc.hpp. You'll want to check if it's there and if it is, figure out why it might not be found in pc.cpp. Here is the part of the diff where it gets added: diff --git a/src/map/pc.hpp b/src/map/pc.hpp index b52784b..23d1a85 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -84,7 +84,8 @@ enum equip_index { EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L, - EQI_MAX + EQI_MAX, + EQI_MAX_BONUS = 10 }; Quote Link to comment Share on other sites More sharing options...
ahloi007 Posted May 10, 2020 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 78 Reputation: 1 Joined: 10/15/12 Last Seen: May 23, 2023 Share Posted May 10, 2020 26 minutes ago, latios said: @ahloi007 The first issue is saying that "j" hasn't been defined on line 2705 in file pc.cpp. You'll want to look around the code there and try to figure out why the definition (e.g. "int j;") is missing. For example, in this part of the diff there is an "int j;" at the top, but isn't there for some reason in your code. @@ -2627,7 +2638,7 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector<s_autobonus> *bonu int j; unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for(j = 0; j < EQI_MAX; j++) { + for(j = 0; j < EQI_MAX_BONUS; j++) { if(sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } The second issue is saying that the constant "EQI_MAX_BONUS" isn't found anywhere in the pc.cpp or pc.hpp files. In the diff, there is a section which indicates it should be added to pc.hpp. You'll want to check if it's there and if it is, figure out why it might not be found in pc.cpp. Here is the part of the diff where it gets added: diff --git a/src/map/pc.hpp b/src/map/pc.hpp index b52784b..23d1a85 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -84,7 +84,8 @@ enum equip_index { EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L, - EQI_MAX + EQI_MAX, + EQI_MAX_BONUS = 10 }; Okay thanks ! its working! Quote Link to comment Share on other sites More sharing options...
Jaodegwapo Posted September 3, 2020 Group: Members Topic Count: 5 Topics Per Day: 0.00 Content Count: 17 Reputation: 0 Joined: 02/22/18 Last Seen: August 25, 2024 Share Posted September 3, 2020 (edited) can you help me with this error sir? Edited September 3, 2020 by Jaodegwapo Quote Link to comment Share on other sites More sharing options...
jawbreaker Posted November 11, 2020 Group: Members Topic Count: 13 Topics Per Day: 0.00 Content Count: 68 Reputation: 1 Joined: 06/21/14 Last Seen: August 8, 2022 Share Posted November 11, 2020 is it possible to deduct headgear weight when it becomes costume? Quote Link to comment Share on other sites More sharing options...
Mael Posted November 12, 2020 Group: Forum Moderator Topic Count: 25 Topics Per Day: 0.01 Content Count: 837 Reputation: 321 Joined: 02/11/19 Last Seen: 4 hours ago Share Posted November 12, 2020 On 9/3/2020 at 9:40 AM, Jaodegwapo said: can you help me with this error sir? On 11/11/2020 at 5:22 AM, jawbreaker said: is it possible to deduct headgear weight when it becomes costume? Better use this version. Quote Link to comment Share on other sites More sharing options...
Pandee Posted May 28, 2021 Group: Members Topic Count: 8 Topics Per Day: 0.01 Content Count: 18 Reputation: 1 Joined: 03/18/21 Last Seen: June 15, 2021 Share Posted May 28, 2021 Hey im trying to apply the diff. But i get this error ~/rAthena$ git apply Costume_System_v2.diff Costume_System_v2.diff:152: new blank line at EOF. + error: patch failed: npc/scripts_custom.conf:115 error: npc/scripts_custom.conf: patch does not apply Costume_System_v2.diff:225: new blank line at EOF. + error: patch failed: src/map/status.cpp:3805 error: src/map/status.cpp: patch does not apply Using the v2 Quote Link to comment Share on other sites More sharing options...
kalabasa Posted June 25, 2021 Group: Members Topic Count: 123 Topics Per Day: 0.05 Content Count: 478 Reputation: 14 Joined: 11/30/17 Last Seen: January 23 Share Posted June 25, 2021 On 3/23/2020 at 1:12 AM, latios said: Hi all, I've taken the time to update this script and tested it on my server running latest version of rAthena (version at the time of writing Git Hash: f8d5d45). Additional Changes NPC name can now be easily customised by replacing 2nd argument in the function call at the bottom of npc/custom/etc/costume.txt NPC checks whether the user already has the same item being restored equipped or in inventory and will prevent restoring. Fixed/tweaked some typos and grammar for the NPC dialogue and atcommand messages. costume.txt has been included inside the diff Screenshot Costume_System_v2.diff 14.63 kB · 148 downloads Edit: I actually just discovered that the wonderful secretdataz had already updated the diff to work with newer versions of rAthena here (https://github.com/secretdataz/rathena/pull/8/files). The main differences to my edit is secret's also handles costuming garments and there is atcommand documentation. The diff I have uploaded comes with an updated NPC script. when converting an item with item_combo_db script the effect will remain Quote Link to comment Share on other sites More sharing options...
mhielo12 Posted November 9, 2021 Group: Members Topic Count: 23 Topics Per Day: 0.01 Content Count: 114 Reputation: 4 Joined: 08/28/14 Last Seen: Tuesday at 08:14 AM Share Posted November 9, 2021 Updated for latest git. diff --git a/conf/battle/battle.conf b/conf/battle/battle.conf index 93fe9db..0e741ad 100644 --- a/conf/battle/battle.conf +++ b/conf/battle/battle.conf @@ -167,3 +167,6 @@ warg_can_falcon: no // Should the target be able of dodging damage by snapping away to the edge of the screen? // Official behavior is "no" snap_dodge: no + +// Reserved Char ID for costume converted items. +reserved_costume_id: 999998 diff --git a/npc/custom/etc/costume.txt b/npc/custom/etc/costume.txt new file mode 100644 index 0000000..bf3772c --- /dev/null +++ b/npc/custom/etc/costume.txt @@ -0,0 +1,135 @@ +// ------------------------------------------------------------------------------- +// Script Name : Headgear to Costume converter >> Costume to Headgear converter +// ------------------------------------------------------------------------------- +// Description : +// - Allows a user to convert the equipped headgear (on Top, Mid or Low) into a +// costume item. It will remove any card and refine of the Item. +// - Allows a user to restore the equipped costume headgear (on Top, Mid or Low) +// into its original form. It will not return any card or refine of the item. +// ------------------------------------------------------------------------------- +function script costume { + .@npc_name$ = getarg(0); + disable_items; + mes "["+ .@npc_name$ +"]"; + mes "Here you can convert your headgears into a Costume Headgear or restore to its Original form."; + next; + + switch(select("I want to convert.:I want to restore.:No thanks.")) { + case 1: + setarray .@indices[1], EQI_HEAD_TOP, EQI_HEAD_MID, EQI_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear headgears that I can costume..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to convert."; + mes "Remember, cards and refine will be removed."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "You want to Costume your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ + "]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + costume .@part; // Convert the Headgear + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your costume headgear."; + close; + case 2: + setarray .@indices[1], EQI_COSTUME_HEAD_TOP, EQI_COSTUME_HEAD_MID, EQI_COSTUME_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices$[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear costumed headgears that I can restore..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to restore."; + mes "Remember, I will only restore it back without refine and cards."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + if (isequippedcnt(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You're wearing too many of the same headgear!"; + mes "How am I supposed to know which one to restore?"; + mes "See me when you have one equipped."; + close; + } + + if (countitem(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You have another " + getitemname(getequipid(.@part)) + " with you."; + mes "Put it away before restoring."; + close; + } + + mes "[" + .@npc_name$ + "]"; + mes "You want to restore your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ +"]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + // Restore headgear by recreating + a = getequipid(.@part); + delitem a,1; + getitem a,1; + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your restored headgear."; + close; + case 3: + mes "["+ .@npc_name$ +"]"; + mes "Very well. Return at once if you seek my services."; + close; + } +} + +// --------------------------------------------------------------------------- +// Add more lines to put your npc on different cities (adjust name if desired) +// --------------------------------------------------------------------------- +prontera,144,230,6 script Costume Clown#1 715,{ callfunc "costume","Costume Clown",0; end; } + diff --git a/npc/scripts_custom.conf b/npc/scripts_custom.conf index 1adf1f3..d4e5706 100644 --- a/npc/scripts_custom.conf +++ b/npc/scripts_custom.conf @@ -115,6 +115,8 @@ npc: npc/custom/etc/quest_warper.txt // -- Custom quests from official Umbalian Quests //npc: npc/custom/quests/sphinx_mask.txt //npc: npc/custom/quests/umbalian_language.txt +// -- Costume NPC script (from rAthena) +npc: npc/custom/etc/costume.txt // --------------------- ChocobotRO Scripts -------------------- // -- Peak NPC script (from FluxCP) diff --git a/src/custom/atcommand_def.inc b/src/custom/atcommand_def.inc index 54d9e74..d9b8b2d 100644 --- a/src/custom/atcommand_def.inc +++ b/src/custom/atcommand_def.inc @@ -9,3 +9,6 @@ **/ //ACMD_DEF(newcommand), + +// @costumeitem <item> +ACMD_DEF2("costumeitem", item), diff --git a/src/custom/script.inc b/src/custom/script.inc index 839b990..776120e 100644 --- a/src/custom/script.inc +++ b/src/custom/script.inc @@ -17,3 +17,44 @@ // script_pushint(st,1); // return 0; //} + +/*========================================== + * Costume Items + *------------------------------------------*/ +BUILDIN_FUNC(costume) +{ + int i = -1, num, ep; + TBL_PC *sd; + item* item; + num = script_getnum(st, 2); // Equip Slot + if (!script_rid2sd(sd)) + return 0; + if (equip_index_check(num)) + i = pc_checkequip(sd, equip_bitmask[num]); + if (i < 0) + return 0; + item = &sd->inventory.u.items_inventory[i]; + ep = item->equip; + if (!(ep&EQP_HEAD_LOW) && !(ep&EQP_HEAD_MID) && !(ep&EQP_HEAD_TOP)) + return 0; + log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, item); + pc_unequipitem(sd, i, 2); + clif_delitem(sd, i, 1, 3); + // -------------------------------------------------------------------- + item->refine = 0; + item->attribute = 0; + item->card[0] = CARD0_CREATE; + item->card[1] = 0; + item->card[2] = GetWord(battle_config.reserved_costume_id, 0); + item->card[3] = GetWord(battle_config.reserved_costume_id, 1); + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + // -------------------------------------------------------------------- + log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, item); + clif_additem(sd, i, 1, 0); + pc_equipitem(sd, i, ep); + clif_misceffect(&sd->bl, 3); + return 0; +} + diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc index 8863992..917ffea 100644 --- a/src/custom/script_def.inc +++ b/src/custom/script_def.inc @@ -9,3 +9,6 @@ **/ //BUILDIN_DEF(example,""), + +// Costume System +BUILDIN_DEF(costume,"i"), diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 266f375..8e9f8af 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -1343,7 +1343,7 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) ACMD_FUNC(item) { char item_name[100]; - int number = 0, bound = BOUND_NONE; + int number = 0, bound = BOUND_NONE, costume = 0; char flag = 0; struct item item_tmp; struct item_data *item_data[10]; @@ -1382,6 +1382,26 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } + + // Start costume conversion logic (1) + if(!strcmpi(command+1, "costumeitem")) { + if(!battle_config.reserved_costume_id) { + clif_displaymessage(fd, "Costume conversion is disabled. Set a value for reserved_costume_id in your battle.conf file."); + return -1; + } + if(!(item.get()->equip&EQP_HEAD_LOW) && + !(item.get()->equip&EQP_HEAD_MID) && + !(item.get()->equip&EQP_HEAD_TOP) && + !(item.get()->equip&EQP_COSTUME_HEAD_LOW) && + !(item.get()->equip&EQP_COSTUME_HEAD_MID) && + !(item.get()->equip&EQP_COSTUME_HEAD_TOP)) { + clif_displaymessage(fd, "You cannot costume this item. Costumes only work for headgears."); + return -1; + } + costume = 1; + + } + // End costume conversion logic (1) + itemlist = strtok(NULL, ":"); //next itemline j++; } @@ -1403,6 +1423,15 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) item_tmp.nameid = item_id; item_tmp.identify = 1; item_tmp.bound = bound; + + // Start costume conversion logic (2) + if(costume == 1) { + item_tmp.card[0] = CARD0_CREATE; + item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0); + item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1); + } + // End costume conversion logic (2) + if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif_additem(sd, 0, 0, flag); } diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 684c833..88a691b 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -8635,6 +8635,7 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, { "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, }, { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, + { "reserved_costume_id", &battle_config.reserved_costume_id, 999998, 0, INT_MAX, }, { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, }, { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, diff --git a/src/map/battle.hpp b/src/map/battle.hpp index c26efe3..58ffded 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -544,6 +544,7 @@ struct Battle_Config int item_enabled_npc; int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full. int bowling_bash_area; + int reserved_costume_id; // Costume System int drop_rateincrease; int feature_auction; int feature_banking; diff --git a/src/map/map.cpp b/src/map/map.cpp index 0aee3ce..1cb4df2 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1950,6 +1950,14 @@ void map_reqnickdb(struct map_session_data * sd, int charid) nullpo_retv(sd); + // Start costume conversion logic (3) + if( battle_config.reserved_costume_id && battle_config.reserved_costume_id == charid ) + { + clif_solved_charname(sd->fd, charid, "Costume"); + return; + } + // End costume conversion logic (3) + tsd = map_charid2sd(charid); if( tsd ) { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 658984b..2b2a8cf 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -870,7 +870,18 @@ int pc_equippoint_sub(struct map_session_data *sd,struct item_data* id){ int pc_equippoint(struct map_session_data *sd,int n){ nullpo_ret(sd); - return pc_equippoint_sub(sd,sd->inventory_data[n]); + // Start costume conversion logic (4) + int ep = pc_equippoint_sub(sd,sd->inventory_data[n]); + int char_id = 0; + if (battle_config.reserved_costume_id && + sd->inventory.u.items_inventory[n].card[0] == CARD0_CREATE && + (char_id = MakeDWord(sd->inventory.u.items_inventory[n].card[2],sd->inventory.u.items_inventory[n].card[3])) == battle_config.reserved_costume_id) { + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + } + return ep; + // End costume conversion logic (4) } /** @@ -2582,7 +2593,7 @@ void pc_delautobonus(struct map_session_data* sd, std::vector<s_autobonus> &bonu unsigned int equip_pos_idx = 0; // Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for (uint8 j = 0; j < EQI_MAX; j++) { + for (uint8 j = 0; j < EQI_MAX_BONUS; j++) { if (sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -2627,7 +2638,7 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector<s_autobonus> *bonu int j; unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for(j = 0; j < EQI_MAX; j++) { + for(j = 0; j < EQI_MAX_BONUS; j++) { if(sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -10126,7 +10137,7 @@ int pc_load_combo(struct map_session_data *sd) { *------------------------------------------*/ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswitch) { - int i, pos, flag = 0, iflag; + int i, pos, flag = 0, iflag, char_id = 0; struct item_data *id; uint8 res = ITEM_EQUIP_ACK_OK; short* equip_index; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index b52784b..23d1a85 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -84,7 +84,8 @@ enum equip_index { EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L, - EQI_MAX + EQI_MAX, + EQI_MAX_BONUS = 10 }; enum prevent_logout_trigger { diff --git a/src/map/status.cpp b/src/map/status.cpp index 09317fd..bd3699b 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3805,7 +3805,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) running_npc_stat_calc_event = false; // Parse equipment - for (i = 0; i < EQI_MAX; i++) { + for (i = 0; i < EQI_MAX_BONUS; i++) { current_equip_item_index = index = sd->equip_index[i]; // We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] current_equip_combo_pos = 0; if (index < 0) Quote Link to comment Share on other sites More sharing options...
sader1992 Posted November 9, 2021 Group: Content Moderator Topic Count: 55 Topics Per Day: 0.01 Content Count: 1691 Reputation: 716 Joined: 12/21/14 Last Seen: 1 hour ago Share Posted November 9, 2021 (edited) 23 hours ago, mhielo12 said: Updated for latest git. diff --git a/conf/battle/battle.conf b/conf/battle/battle.conf index 93fe9db..0e741ad 100644 --- a/conf/battle/battle.conf +++ b/conf/battle/battle.conf @@ -167,3 +167,6 @@ warg_can_falcon: no // Should the target be able of dodging damage by snapping away to the edge of the screen? // Official behavior is "no" snap_dodge: no + +// Reserved Char ID for costume converted items. +reserved_costume_id: 999998 diff --git a/npc/custom/etc/costume.txt b/npc/custom/etc/costume.txt new file mode 100644 index 0000000..bf3772c --- /dev/null +++ b/npc/custom/etc/costume.txt @@ -0,0 +1,135 @@ +// ------------------------------------------------------------------------------- +// Script Name : Headgear to Costume converter >> Costume to Headgear converter +// ------------------------------------------------------------------------------- +// Description : +// - Allows a user to convert the equipped headgear (on Top, Mid or Low) into a +// costume item. It will remove any card and refine of the Item. +// - Allows a user to restore the equipped costume headgear (on Top, Mid or Low) +// into its original form. It will not return any card or refine of the item. +// ------------------------------------------------------------------------------- +function script costume { + .@npc_name$ = getarg(0); + disable_items; + mes "["+ .@npc_name$ +"]"; + mes "Here you can convert your headgears into a Costume Headgear or restore to its Original form."; + next; + + switch(select("I want to convert.:I want to restore.:No thanks.")) { + case 1: + setarray .@indices[1], EQI_HEAD_TOP, EQI_HEAD_MID, EQI_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear headgears that I can costume..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to convert."; + mes "Remember, cards and refine will be removed."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "You want to Costume your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ + "]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + costume .@part; // Convert the Headgear + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your costume headgear."; + close; + case 2: + setarray .@indices[1], EQI_COSTUME_HEAD_TOP, EQI_COSTUME_HEAD_MID, EQI_COSTUME_HEAD_LOW; + for (.@i = 1; .@i<=3; ++.@i) { + if (getequipisequiped(.@indices[.@i])) { + .@menu$ = .@menu$ + F_getpositionname(.@indices$[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; + .@equipped = 1; + } + .@menu$ = .@menu$ + ":"; + } + + if (.@equipped == 0) { + mes "["+ .@npc_name$ +"]"; + mes "You need to wear costumed headgears that I can restore..."; + close; + } + + mes "["+ .@npc_name$ +"]"; + mes "Please select what to restore."; + mes "Remember, I will only restore it back without refine and cards."; + next; + + .@part = .@indices[ select(.@menu$) ]; + if (!getequipisequiped(.@part)) { + mes "["+ .@npc_name$ +"]"; + mes "You're not wearing anything there..."; + close; + } + + if (isequippedcnt(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You're wearing too many of the same headgear!"; + mes "How am I supposed to know which one to restore?"; + mes "See me when you have one equipped."; + close; + } + + if (countitem(getequipid(.@part)) > 1) { + mes "["+ .@npc_name$ +"]"; + mes "You have another " + getitemname(getequipid(.@part)) + " with you."; + mes "Put it away before restoring."; + close; + } + + mes "[" + .@npc_name$ + "]"; + mes "You want to restore your " + getitemname(getequipid(.@part)) + "?"; + next; + + if (select("Yes, proceed:No, sorry.") == 2) { + mes "["+ .@npc_name$ +"]"; + mes "Need some time to think about it, huh?"; + mes "Alright, I can understand."; + close; + } + + // Restore headgear by recreating + a = getequipid(.@part); + delitem a,1; + getitem a,1; + + mes "["+ .@npc_name$ +"]"; + mes "Done, enjoy your restored headgear."; + close; + case 3: + mes "["+ .@npc_name$ +"]"; + mes "Very well. Return at once if you seek my services."; + close; + } +} + +// --------------------------------------------------------------------------- +// Add more lines to put your npc on different cities (adjust name if desired) +// --------------------------------------------------------------------------- +prontera,144,230,6 script Costume Clown#1 715,{ callfunc "costume","Costume Clown",0; end; } + diff --git a/npc/scripts_custom.conf b/npc/scripts_custom.conf index 1adf1f3..d4e5706 100644 --- a/npc/scripts_custom.conf +++ b/npc/scripts_custom.conf @@ -115,6 +115,8 @@ npc: npc/custom/etc/quest_warper.txt // -- Custom quests from official Umbalian Quests //npc: npc/custom/quests/sphinx_mask.txt //npc: npc/custom/quests/umbalian_language.txt +// -- Costume NPC script (from rAthena) +npc: npc/custom/etc/costume.txt // --------------------- ChocobotRO Scripts -------------------- // -- Peak NPC script (from FluxCP) diff --git a/src/custom/atcommand_def.inc b/src/custom/atcommand_def.inc index 54d9e74..d9b8b2d 100644 --- a/src/custom/atcommand_def.inc +++ b/src/custom/atcommand_def.inc @@ -9,3 +9,6 @@ **/ //ACMD_DEF(newcommand), + +// @costumeitem <item> +ACMD_DEF2("costumeitem", item), diff --git a/src/custom/script.inc b/src/custom/script.inc index 839b990..776120e 100644 --- a/src/custom/script.inc +++ b/src/custom/script.inc @@ -17,3 +17,44 @@ // script_pushint(st,1); // return 0; //} + +/*========================================== + * Costume Items + *------------------------------------------*/ +BUILDIN_FUNC(costume) +{ + int i = -1, num, ep; + TBL_PC *sd; + item* item; + num = script_getnum(st, 2); // Equip Slot + if (!script_rid2sd(sd)) + return 0; + if (equip_index_check(num)) + i = pc_checkequip(sd, equip_bitmask[num]); + if (i < 0) + return 0; + item = &sd->inventory.u.items_inventory[i]; + ep = item->equip; + if (!(ep&EQP_HEAD_LOW) && !(ep&EQP_HEAD_MID) && !(ep&EQP_HEAD_TOP)) + return 0; + log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, item); + pc_unequipitem(sd, i, 2); + clif_delitem(sd, i, 1, 3); + // -------------------------------------------------------------------- + item->refine = 0; + item->attribute = 0; + item->card[0] = CARD0_CREATE; + item->card[1] = 0; + item->card[2] = GetWord(battle_config.reserved_costume_id, 0); + item->card[3] = GetWord(battle_config.reserved_costume_id, 1); + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + // -------------------------------------------------------------------- + log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, item); + clif_additem(sd, i, 1, 0); + pc_equipitem(sd, i, ep); + clif_misceffect(&sd->bl, 3); + return 0; +} + diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc index 8863992..917ffea 100644 --- a/src/custom/script_def.inc +++ b/src/custom/script_def.inc @@ -9,3 +9,6 @@ **/ //BUILDIN_DEF(example,""), + +// Costume System +BUILDIN_DEF(costume,"i"), diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 266f375..8e9f8af 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -1343,7 +1343,7 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) ACMD_FUNC(item) { char item_name[100]; - int number = 0, bound = BOUND_NONE; + int number = 0, bound = BOUND_NONE, costume = 0; char flag = 0; struct item item_tmp; struct item_data *item_data[10]; @@ -1382,6 +1382,26 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } + + // Start costume conversion logic (1) + if(!strcmpi(command+1, "costumeitem")) { + if(!battle_config.reserved_costume_id) { + clif_displaymessage(fd, "Costume conversion is disabled. Set a value for reserved_costume_id in your battle.conf file."); + return -1; + } + if(!(item.get()->equip&EQP_HEAD_LOW) && + !(item.get()->equip&EQP_HEAD_MID) && + !(item.get()->equip&EQP_HEAD_TOP) && + !(item.get()->equip&EQP_COSTUME_HEAD_LOW) && + !(item.get()->equip&EQP_COSTUME_HEAD_MID) && + !(item.get()->equip&EQP_COSTUME_HEAD_TOP)) { + clif_displaymessage(fd, "You cannot costume this item. Costumes only work for headgears."); + return -1; + } + costume = 1; + + } + // End costume conversion logic (1) + itemlist = strtok(NULL, ":"); //next itemline j++; } @@ -1403,6 +1423,15 @@ static void warp_get_suggestions(struct map_session_data* sd, const char *name) item_tmp.nameid = item_id; item_tmp.identify = 1; item_tmp.bound = bound; + + // Start costume conversion logic (2) + if(costume == 1) { + item_tmp.card[0] = CARD0_CREATE; + item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0); + item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1); + } + // End costume conversion logic (2) + if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif_additem(sd, 0, 0, flag); } diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 684c833..88a691b 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -8635,6 +8635,7 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, { "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, }, { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, + { "reserved_costume_id", &battle_config.reserved_costume_id, 999998, 0, INT_MAX, }, { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, }, { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, diff --git a/src/map/battle.hpp b/src/map/battle.hpp index c26efe3..58ffded 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -544,6 +544,7 @@ struct Battle_Config int item_enabled_npc; int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full. int bowling_bash_area; + int reserved_costume_id; // Costume System int drop_rateincrease; int feature_auction; int feature_banking; diff --git a/src/map/map.cpp b/src/map/map.cpp index 0aee3ce..1cb4df2 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1950,6 +1950,14 @@ void map_reqnickdb(struct map_session_data * sd, int charid) nullpo_retv(sd); + // Start costume conversion logic (3) + if( battle_config.reserved_costume_id && battle_config.reserved_costume_id == charid ) + { + clif_solved_charname(sd->fd, charid, "Costume"); + return; + } + // End costume conversion logic (3) + tsd = map_charid2sd(charid); if( tsd ) { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 658984b..2b2a8cf 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -870,7 +870,18 @@ int pc_equippoint_sub(struct map_session_data *sd,struct item_data* id){ int pc_equippoint(struct map_session_data *sd,int n){ nullpo_ret(sd); - return pc_equippoint_sub(sd,sd->inventory_data[n]); + // Start costume conversion logic (4) + int ep = pc_equippoint_sub(sd,sd->inventory_data[n]); + int char_id = 0; + if (battle_config.reserved_costume_id && + sd->inventory.u.items_inventory[n].card[0] == CARD0_CREATE && + (char_id = MakeDWord(sd->inventory.u.items_inventory[n].card[2],sd->inventory.u.items_inventory[n].card[3])) == battle_config.reserved_costume_id) { + if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; } + if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; } + if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; } + } + return ep; + // End costume conversion logic (4) } /** @@ -2582,7 +2593,7 @@ void pc_delautobonus(struct map_session_data* sd, std::vector<s_autobonus> &bonu unsigned int equip_pos_idx = 0; // Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for (uint8 j = 0; j < EQI_MAX; j++) { + for (uint8 j = 0; j < EQI_MAX_BONUS; j++) { if (sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -2627,7 +2638,7 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector<s_autobonus> *bonu int j; unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] - for(j = 0; j < EQI_MAX; j++) { + for(j = 0; j < EQI_MAX_BONUS; j++) { if(sd->equip_index[j] >= 0) equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; } @@ -10126,7 +10137,7 @@ int pc_load_combo(struct map_session_data *sd) { *------------------------------------------*/ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswitch) { - int i, pos, flag = 0, iflag; + int i, pos, flag = 0, iflag, char_id = 0; struct item_data *id; uint8 res = ITEM_EQUIP_ACK_OK; short* equip_index; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index b52784b..23d1a85 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -84,7 +84,8 @@ enum equip_index { EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L, - EQI_MAX + EQI_MAX, + EQI_MAX_BONUS = 10 }; enum prevent_logout_trigger { diff --git a/src/map/status.cpp b/src/map/status.cpp index 09317fd..bd3699b 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3805,7 +3805,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) running_npc_stat_calc_event = false; // Parse equipment - for (i = 0; i < EQI_MAX; i++) { + for (i = 0; i < EQI_MAX_BONUS; i++) { current_equip_item_index = index = sd->equip_index[i]; // We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] current_equip_combo_pos = 0; if (index < 0) I can see a problem in the code without testing it not sure if there is more , will leave it for you to test Edited November 10, 2021 by sader1992 Quote Link to comment Share on other sites More sharing options...
mhielo12 Posted November 10, 2021 Group: Members Topic Count: 23 Topics Per Day: 0.01 Content Count: 114 Reputation: 4 Joined: 08/28/14 Last Seen: Tuesday at 08:14 AM Share Posted November 10, 2021 On 11/9/2021 at 10:26 AM, sader1992 said: I can see a problem in the code without testing it not sure if there is more , will leave it for you to test i have tested the code and yes there is a glitch with other regular costume items. it seems it also remove all the effect for regular costume Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.