Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/16/23 in Posts

  1. Need the latest kRO Install folder for your private server? Look no further! ----> Download <---- Latest: 2023-04-04 Installation: Official kRO Updated: 04/04/2023 Download Link: https://mega.nz/folder/jUsDgRxQ#ttLmLjPY9p9cfU5_ShWVCw Package contains RSU RO Patcher Lite for kRO and kRO RE by [Ai4rei] This package is maintained by [Akkarin] Note: Due to continued abuse of my webservers, the files have been moved to MEGA. You can download an extractable .zip of an installed kRO directory, or you can download the official installer from kRO's website. Note: If you require older maps that are compatible with 2021 and older clients, download the 2021 .zip. A fan of this topic? Hit the rep button
    1 point
  2. 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 point
  3. 1 point
  4. make sure u didn't diff this option
    1 point
  5. Hi there, I downloaded the script from that link and I still get: [Error]: buildin_getmapxy: Player with nick 'ECwarp_1' is not found. [Error]: buildin_getmapxy: Player with map id '0' is not found. [Info]: [Instance] Created: Endless Cellar (1). Edit: Fixed it. There was a getmapxy(.@map$,.@x,.@y,1,("ECwarp_"+'EC_Floor)); which needed to be getmapxy(.@map$,.@x,.@y,BL_NPC,("ECwarp_"+'EC_Floor));
    1 point
  6. NOTE: This script was saved from my hardisk and all credits to our good scripter @Chilly for making this such great script! Endless Tower 2: The Endless Cellar A fully instanced custom dungeon containing all monsters, mini bosses, and mvps(with a few exceptions) up to episode 13.2 that were not in Endless Tower. Its a total of 77 floors with mvps being every 4 floors, and on the last floor there are a number of mvp fights in a row including 2 event mvps. Credits to Saithis for his Endless Tower script, most of the code i used came from his script. Dont forget to add the maps: conf\maps_athena.conf map: 1@new map: 2@new map: 3@new map: 4@new map: 5@new db\map_index.txt 1@new 2@new 3@new 4@new 5@new then run mapcache.exe~ Download Link: (Script and Client-side are included on one rar file) http://www.mediafire...a52kaz75u8am238 Endless Cellar.rar
    1 point
  7. @Joseph script is closest, but not optimized enough prontera,156,177,5 script kdjfhkshf2 100,{ end; OnInit: .@interval = 5; .@step = 5; while (1) { sleep .@interval * 1000; getmapxy .@map$, .@x, .@y, 1; while ( checkcell( .@map$, .@npc_x = .@x + rand( -.@step, .@step ), .@npc_y = .@y + rand( -.@step, .@step ), cell_chknopass ) ); npcwalkto .@npc_x, .@npc_y; npctalk callfunc( "F_RandMes", 2, "I'm talking.", // 1 "Hello!" // 2 ); } end; // doesn't read } F_RandMes is 1 of the global function inside our svn its much cleaner than setting an array with getarraysize also much cleaner than switch( rand(x) ) { case 1: ... break; case2: .... break; } our crappy script engine parse switch, case and break very ugly F_RandMes is also consider 1 of the unique function only to *athena script language
    1 point
×
×
  • Create New...