Tokei Posted January 16, 2023 Group: Members Topic Count: 16 Topics Per Day: 0.00 Content Count: 693 Reputation: 716 Joined: 11/12/12 Last Seen: 7 hours ago Share Posted January 16, 2023 Heya, These script commands are an alternative for those who do not want to use yaml for making barter shops. The shops can be reloaded by reloading the script, using the barter_clear command. The NPC location is defined just like a regular NPC and then using callshop <npc barter name>, just like regular shop types (which is already possible without this diff, but I thought I'd mention it anyway). Removes all items from a barter shop barter_clear <npc name>; Add item, not extended barter_add <npc name>,<item id>,<amount>,<req item id>,<req amount>; Add item, extended barter_add_ex <npc name>,<item id>,<amount>,<zeny>{,<req item id>,<req amount>,<req refine>}*; Here's a script example: prontera,150,188,0 script Barter NPC 77,{ mes "[Barter NPC]"; next; switch(select("Normal barter shop.:Extended barter shop.:")) { case 1: mes "[Barter NPC]"; mes "..."; close2; callshop "barter_test_npc"; end; case 2: mes "[Barter NPC]"; mes "..."; close2; callshop "barter_test_npc_ex"; end; } end; OnInit: barter_clear "barter_test_npc"; barter_add "barter_test_npc", 504, 10, 501, 20; barter_add "barter_test_npc", 504, 10, 502, 10; barter_add "barter_test_npc", "White_Potion", 10, "Yellow_Potion", 3; barter_clear "barter_test_npc_ex"; barter_add_ex "barter_test_npc_ex", "Zeny_Knife", 5, 5000, "Knife", 1, 9; barter_add_ex "barter_test_npc_ex", "Zeny_Knife", 5, 5000, "Knife", 1, 9, "White_Potion", 10, 0; barter_add_ex "barter_test_npc_ex", "Zeny_Knife", 5, 5000, "Knife", 1, 9, "White_Potion", 10, 0, "White_Potion", 10, 0; end; } prontera,152,188,0 script Barter NPC2 77,{ callshop "barter_test_npc"; end; } And here's the diff file: diff --git a/src/map/npc.cpp b/src/map/npc.cpp index d227467ed..37f50d94d 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -842,6 +842,26 @@ void BarterDatabase::loadingFinished(){ BarterDatabase barter_db; +struct npc_data* npc_create_dummy_barter_npc(const char *npcname) { + struct npc_data* nd = npc_create_npc(-1, 0, 0); + + npc_parsename(nd, npcname, nullptr, nullptr, __FILE__ ":" QUOTE(__LINE__)); + + nd->class_ = -1; + nd->speed = 200; + + nd->bl.type = BL_NPC; + nd->subtype = NPCTYPE_BARTER; + + nd->u.barter.extended = false; + + map_addiddb(&nd->bl); + + strdb_put(npcname_db, npcname, nd); + + return nd; +} + /** * Returns the viewdata for normal NPC classes. * @param class_: NPC class ID diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 0a0c104e6..82ad2cf3d 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1479,6 +1479,8 @@ enum e_npcv_status : uint8 { NPCVIEW_INVISIBLE = 0x29, NPCVIEW_CLOAK = 0x30, }; + +struct npc_data* npc_create_dummy_barter_npc(const char* npcname); struct view_data* npc_get_viewdata(int class_); int npc_chat_sub(struct block_list* bl, va_list ap); int npc_event_dequeue(map_session_data* sd,bool free_script_stack=true); diff --git a/src/map/script.cpp b/src/map/script.cpp index 5aeebe228..6742ab8c4 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -26916,6 +26916,154 @@ BUILDIN_FUNC(preg_match) { #endif } +/*========================================== + * Removes all items from a barter shop + * barter_clear <npc name>; + *------------------------------------------*/ +BUILDIN_FUNC(barter_clear) +{ + const char* npcname = script_getstr(st, 2); + std::shared_ptr<s_npc_barter> barter = barter_db.find(npcname); + + if (barter != nullptr) { + barter->items.clear(); + } + + return SCRIPT_CMD_SUCCESS; +} + +/*========================================== + * Add an item to the barter shop + * Not extended: + * barter_add <npc name>,<item id>,<amount>,<req item id>,<req amount>; + * + * Extended: + * barter_add_ex <npc name>,<item id>,<amount>,<zeny>{,<req item id>,<req amount>,<req refine>}*; + *------------------------------------------*/ +BUILDIN_FUNC(barter_add) +{ + const char* npcname = script_getstr(st, 2); + std::shared_ptr<s_npc_barter> barter = barter_db.find(npcname); + struct npc_data* nd = npc_name2id(npcname); + const char* command = script_getfuncname(st); + + if (barter == nullptr) { + barter = std::make_shared<s_npc_barter>(); + barter->name = npcname; + barter_db.put(npcname, barter); + } + + if (nd == nullptr) { + nd = npc_create_dummy_barter_npc(npcname); + } + + int index = barter->items.size(); + + std::shared_ptr<s_npc_barter_item> item = std::make_shared<s_npc_barter_item>(); + item->index = index; + barter->items[index] = item; + + if (strcmpi(command, "barter_add_ex") == 0) { + nd->u.barter.extended = true; + + if (script_isstring(st, 3)) { + const char* name = script_getstr(st, 3); + + std::shared_ptr<item_data> id = item_db.searchname(name); + + if (id == nullptr) { + ShowError("buildin_barter_add: Nonexistant item %s\n", name); + return SCRIPT_CMD_FAILURE; + } + + item->nameid = id->nameid; + } + else { + item->nameid = script_getnum(st, 3); + } + + item->stock = script_getnum(st, 4); + item->stockLimited = false; + item->price = script_getnum(st, 5); + + int offset = 6; + + while (script_hasdata(st, offset) && script_hasdata(st, offset + 1) && script_hasdata(st, offset + 2)) { + std::shared_ptr<s_npc_barter_requirement> requirement = std::make_shared<s_npc_barter_requirement>(); + + requirement->index = (uint16)item->requirements.size(); + + if (script_isstring(st, offset)) { + const char* name = script_getstr(st, offset); + + std::shared_ptr<item_data> id = item_db.searchname(name); + + if (id == nullptr) { + ShowError("buildin_barter_add: Nonexistant item %s\n", name); + return SCRIPT_CMD_FAILURE; + } + + requirement->nameid = id->nameid; + } + else { + requirement->nameid = script_getnum(st, offset); + } + + requirement->amount = script_getnum(st, offset + 1); + requirement->refine = script_getnum(st, offset + 2); + item->requirements[requirement->index] = requirement; + offset += 3; + } + } + else { + nd->u.barter.extended = false; + + if (script_isstring(st, 3)) { + const char* name = script_getstr(st, 3); + + std::shared_ptr<item_data> id = item_db.searchname(name); + + if (id == nullptr) { + ShowError("buildin_barter_add: Nonexistant item %s\n", name); + return SCRIPT_CMD_FAILURE; + } + + item->nameid = id->nameid; + } + else { + item->nameid = script_getnum(st, 3); + } + + item->stock = script_getnum(st, 4); + item->stockLimited = false; + + std::shared_ptr<s_npc_barter_requirement> requirement = std::make_shared<s_npc_barter_requirement>(); + + requirement->index = 0; + + if (script_isstring(st, 5)) { + const char* name = script_getstr(st, 5); + + std::shared_ptr<item_data> id = item_db.searchname(name); + + if (id == nullptr) { + ShowError("buildin_barter_add: Nonexistant item %s\n", name); + return SCRIPT_CMD_FAILURE; + } + + requirement->nameid = id->nameid; + } + else { + requirement->nameid = script_getnum(st, 5); + } + + requirement->amount = script_getnum(st, 6); + item->requirements[0] = requirement; + } + + return SCRIPT_CMD_SUCCESS; +} + /// script command definitions /// for an explanation on args, see add_buildin_func struct script_function buildin_func[] = { @@ -27623,6 +27771,10 @@ struct script_function buildin_func[] = { BUILDIN_DEF(isdead, "?"), BUILDIN_DEF(macro_detector, "?"), + BUILDIN_DEF(barter_clear, "s"), + BUILDIN_DEF(barter_add, "svi*"), + BUILDIN_DEF2(barter_add, "barter_add_ex", "svii*"), + #include "../custom/script_def.inc" {NULL,NULL,NULL}, Quick notes: There isn't a whole lot of error handling. Do... not use an existing NPC name for the barter name if you don't want to crash, but otherwise, should be fine! There is no handling for stocks. You can add parameters to it in the script command if you feel like it, but I've personally never used this option so I just didn't add it. barter.diff 1 2 3 Quote Link to comment Share on other sites More sharing options...
Han25 Posted January 17, 2023 Group: Members Topic Count: 16 Topics Per Day: 0.00 Content Count: 67 Reputation: 2 Joined: 08/09/13 Last Seen: June 8, 2023 Share Posted January 17, 2023 Thank you as always! Quote Link to comment Share on other sites More sharing options...
Takuyakii Posted April 13, 2023 Group: Members Topic Count: 41 Topics Per Day: 0.02 Content Count: 214 Reputation: 11 Joined: 08/30/19 Last Seen: January 28 Share Posted April 13, 2023 is this will work on 2020 Git? Quote Link to comment Share on other sites More sharing options...
Ice Bear Posted January 10, 2024 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 166 Reputation: 27 Joined: 11/20/11 Last Seen: 18 hours ago Share Posted January 10, 2024 no refine for item to barter ex +9 Note Headphones = +9 Hat and +0 Note Headphones? just asking if this is possible or not thank you :3 have a nice day everyone Quote Link to comment Share on other sites More sharing options...
Tokei Posted January 11, 2024 Group: Members Topic Count: 16 Topics Per Day: 0.00 Content Count: 693 Reputation: 716 Joined: 11/12/12 Last Seen: 7 hours ago Author Share Posted January 11, 2024 17 hours ago, Ice Bear said: no refine for item to barter ex +9 Note Headphones = +9 Hat and +0 Note Headphones? just asking if this is possible or not thank you :3 have a nice day everyone That's not possible, the client doesn't support that feature. You'd have to make a custom system for it, and it would still not display properly. A lapine box might work better? Not sure. You'll probably have to end up doing it with a boring script though, since it's hard to handle two refines otherwise. Quote Link to comment Share on other sites More sharing options...
Ice Bear Posted January 11, 2024 Group: Members Topic Count: 27 Topics Per Day: 0.01 Content Count: 166 Reputation: 27 Joined: 11/20/11 Last Seen: 18 hours ago Share Posted January 11, 2024 5 hours ago, Tokei said: ill not display properly. A lapine box might work better? Not sure. You'll probably have to end up doing it with a boring script though, since it's hard to handle two refines otherwise. I see i just remember a shop that sells items with refine (eAthena days) cant find it anymore x-x but thanks tokei for giving us explanations Quote Link to comment Share on other sites More sharing options...
Emistry Posted January 11, 2024 Group: Forum Moderator Topic Count: 93 Topics Per Day: 0.02 Content Count: 10015 Reputation: 2364 Joined: 10/28/11 Last Seen: Saturday at 07:02 PM Share Posted January 11, 2024 (edited) @offtopic On 2/29/2020 at 6:45 PM, Emistry said: as far as I know, by default shop doesn't support refined items. the only one who I have seen manage to make this mod in the past was @Epoque back in eathena, and the link is no longer available . or perhaps you could try ask him to update it if he ever have time or interested to do it. it was something that look like this https://i.imgur.com/L38UPvm.png , he probably make use of the vending system to make it possible. (dont ask me for source code, i dont have it) btw would the barter script command above with together with the existing yaml version? wouldn't it be better to make a PR have it merge into rathena too? that could help expand the way we create npc in a much interested way too Edited January 11, 2024 by Emistry Quote Link to comment Share on other sites More sharing options...
Reloadscript Posted August 21, 2024 Group: Members Topic Count: 33 Topics Per Day: 0.14 Content Count: 125 Reputation: 6 Joined: 06/26/24 Last Seen: Sunday at 07:29 AM Share Posted August 21, 2024 I found bug after update clean server master last update. \src\map\script.cpp(27526,12): warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data Quote Link to comment Share on other sites More sharing options...
Louis T Steinhil Posted December 18, 2024 Group: Members Topic Count: 37 Topics Per Day: 0.01 Content Count: 177 Reputation: 33 Joined: 06/22/13 Last Seen: 9 hours ago Share Posted December 18, 2024 Hello is there a way to put commas on that zeny requirements? Quote Link to comment Share on other sites More sharing options...
KaizenRO Posted January 12 Group: Members Topic Count: 1 Topics Per Day: 0.00 Content Count: 8 Reputation: 0 Joined: 04/19/23 Last Seen: Friday at 08:52 AM Share Posted January 12 Hello! is it possible to put an announcement if how many stocks remains on a certain item? 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.