Tokei

Members
  • Content count

    431
  • Avg. Content Per Day

    0
  • Joined

  • Last visited

  • Days Won

    41

Tokei last won the day on July 9

Tokei had the most liked content!

Community Reputation

322 Excellent

About Tokei

  • Rank
    Metaling

Profile Information

  • Gender
    Male
  • Location
    Canada

Recent Profile Visitors

8,891 profile views
  1. Zell

    I believeimage.png.9a84753046f486ba09753c3ac6c148d3.png

  2. Heya, You need to drag and drop your GRFs in the resource files as well (not just the data folder). So add your.grf, data.grf, etc. There are many ways to add new mob skills: Copy paste existing mob skills (with ctrl-c/ctrl-v). It will create a new entry by default, because mob skills are not unique and can have multiple identical entries. Edit the copied line afterwards. Ctrl-N or Edit > Add entry. Copy other mobs' skills and then edit them: Go in the mobs tab Select the skills from the Mob skills box, then right-click > copy. Go back to the mob you were editing in the mobs tab, right-click the Mob skills box > paste (this method sets the mob id automatically, which is much faster).
  3. Hmm, I'll have to disagree here. Those are nice suggestions, but the memory gains aren't worth the trouble of having non-loaded maps or having to reboot a server due to not having it in the map cache. And... as far as I know, rAthena doesn't have memory issues/huge memory usage.
  4. View File Mapcache Editor Heya, This is a tool to edit mapcache files for rAthena (db/(pre-)re/map_cache.dat). It is already part of Server Database Editor as a sub tool, but I've made it a tool on its own instead. It was made to fix the issue with WeeMapCache not assigning the water tiles properly. Otherwise, it's pretty much the same interface, but easier to use. The most recent version will always be found from the mediafire link below: http://www.mediafire.com/file/tjlnooebx6am673 Source files: https://github.com/Tokeiburu/Mapcache-Editor Submitter Tokei Submitted 07/08/2018 Category Editors Video Content Author Tokeiburu  
  5. Tokei

    Mapcache Editor

    Version 1.0.1

    66 downloads

    Heya, This is a tool to edit mapcache files for rAthena (db/(pre-)re/map_cache.dat). It is already part of Server Database Editor as a sub tool, but I've made it a tool on its own instead. It was made to fix the issue with WeeMapCache not assigning the water tiles properly. Otherwise, it's pretty much the same interface, but easier to use. The most recent version will always be found from the mediafire link below: http://www.mediafire.com/file/tjlnooebx6am673 Source files: https://github.com/Tokeiburu/Mapcache-Editor

    Free

  6. Tokei

    Replacement for addrid

    Heya, The following script commands replace addrid and they were initially implemented by Luxuri. The main advantage of these is that they do not attach the players on the current script, allowing an easier code flow. The commands: foreachinserver "<npc_label>" foreachinmap "<npc_label>", "<map_name>" foreachinparty "<npc_label>", <party_id> foreachinarea "<npc_label>", "<map_name>", <x1>, <y1>, <x2>, <y2> foreachinshootablerange "<npc_label>", "<map_name>", <x>, <y>, <range> foreachinguild "<npc_label>", <guild_id> prontera,155,185,3 script Test 77,{ foreachinserver("Test::OnEvent"); foreachinmap("Test::OnEvent", "prontera"); foreachinparty("Test::OnEvent", getcharid(1)); foreachinarea("Test::OnEvent", "this", 153, 182, 159, 177); foreachinshootablerange("Test::OnEvent", "this", 153, 182, 2); foreachinguild("Test::OnEvent", getcharid(2)); end; OnEvent: announce "Attached script to " + strcharinfo(0), 0; end; } For example, for making a script that kicks dead players without using OnPCDieEvent, you could use: prontera,155,185,3 script Test 77,{ initnpctimer; dispbottom "Kicking dead players."; end; OnTimer1000: .kicked = 0; foreachinmap("Test::OnKick", "prontera"); if (.kicked > 0) { announce .kicked + " player(s) have died!", 0; } initnpctimer; end; OnKick: if (HP <= 0) { .kicked++; getitem 501, 1; warp "alberta", 192, 147; percentheal 100, 100; } end; } You can easily make your own foreach methods (for BG, clans, etc). Diff file: diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 647a765..c60a5d7 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -2224,6 +2224,20 @@ int npc_unload(struct npc_data* nd, bool single) { return 0; } +/// Returns the NPC associated with the specified event label. +struct npc_data* npc_event_label_nd(const char* labelname) +{ + struct event_data* ev = (struct event_data*)strdb_get(ev_db, labelname); + return (ev != NULL ? ev->nd : NULL); +} + +/// Returns the bytecode position that the specified event label refers to. +int npc_event_label_pos(const char* labelname) +{ + struct event_data* ev = (struct event_data*)strdb_get(ev_db, labelname); + return (ev != NULL ? ev->pos : -1); +} + // // NPC Source Files // diff --git a/src/map/npc.hpp b/src/map/npc.hpp index d6a9b97..3049651 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1162,6 +1162,9 @@ bool npc_isnear(struct block_list * bl); int npc_get_new_npc_id(void); +struct npc_data* npc_event_label_nd(const char* labelname); +int npc_event_label_pos(const char* labelname); + int npc_addsrcfile(const char* name, bool loadscript); void npc_delsrcfile(const char* name); int npc_parsesrcfile(const char* filepath, bool runOnInit); diff --git a/src/map/script.cpp b/src/map/script.cpp index 180f9ba..5535094 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -12230,6 +12230,150 @@ BUILDIN_FUNC(isloggedin) return SCRIPT_CMD_SUCCESS; } +static int script_foreach_sub(TBL_PC* sd, const char* event) +{ + struct npc_data* nd; + int pos; + + if ((nd = npc_event_label_nd(event)) == NULL || (pos = npc_event_label_pos(event)) == -1) + return 0; + + run_script(nd->u.scr.script, pos, sd->bl.id, nd->bl.id); + return 1; +} + +static int script_foreach_sub_va_bl(struct block_list* bl, va_list args) { + const char* event = va_arg(args, const char*); + return script_foreach_sub((TBL_PC*)bl, event); +} + +static int script_foreach_sub_va_sd(TBL_PC* sd, va_list args) { + const char* event = va_arg(args, const char*); + return script_foreach_sub(sd, event); +} + +/// foreachinserver "<npc_label>" +BUILDIN_FUNC(foreachinserver) +{ + const char* event = script_getstr(st, 2); + map_foreachpc(script_foreach_sub_va_sd, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinmap "<npc_label>", "<map_name>" +BUILDIN_FUNC(foreachinmap) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinmap: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + map_foreachinmap(script_foreach_sub_va_bl, m, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinparty "<npc_label>", <party_id> +BUILDIN_FUNC(foreachinparty) +{ + const char* event = script_getstr(st, 2); + int party_id = script_getnum(st, 3); + struct party_data* p; + int i; + + if ((p = party_search(party_id)) == NULL) { + ShowWarning("buildin_foreachinparty: Party id '%d' doesn't exist or is not loaded yet.\n", party_id); + return SCRIPT_CMD_SUCCESS; + } + + for (i = 0; i < MAX_PARTY; ++i) { + TBL_PC* sd; + int char_id = p->party.member[i].char_id; + + if (char_id == 0 || (sd = map_charid2sd(char_id)) == NULL) + continue; + + script_foreach_sub(sd, event); + } + + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinarea "<npc_label>", "<map_name>", <x1>, <y1>, <x2>, <y2> +BUILDIN_FUNC(foreachinarea) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + int x1 = script_getnum(st, 4); + int y1 = script_getnum(st, 5); + int x2 = script_getnum(st, 6); + int y2 = script_getnum(st, 7); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinarea: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + map_foreachinarea(script_foreach_sub_va_bl, m, x1, y1, x2, y2, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinshootablerange "<npc_label>", "<map_name>", <x>, <y>, <range> +BUILDIN_FUNC(foreachinshootablerange) +{ + const char* event = script_getstr(st, 2); + const char* mapname = script_getstr(st, 3); + struct block_list bl; + int x1 = script_getnum(st, 4); + int y1 = script_getnum(st, 5); + int range = script_getnum(st, 6); + TBL_NPC* nd = map_id2nd(st->oid); + int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); + + if (m < 0) { + ShowWarning("buildin_foreachinarea: Invalid map name '%s'.\n", mapname); + return SCRIPT_CMD_SUCCESS; + } + + memset(&bl, 0, sizeof(struct block_list)); + bl.m = m; + bl.x = x1; + bl.y = y1; + + map_foreachinshootrange(script_foreach_sub_va_bl, &bl, range, BL_PC, event); + return SCRIPT_CMD_SUCCESS; +} + +/// foreachinguild "<npc_label>", <guild_id> +BUILDIN_FUNC(foreachinguild) +{ + const char* event = script_getstr(st, 2); + int guild_id = script_getnum(st, 3); + struct guild* g; + int i; + + if ((g = guild_search(guild_id)) == NULL) { + ShowWarning("buildin_foreachinguild: Guild id '%d' doesn't exist or is not loaded yet.\n", guild_id); + return SCRIPT_CMD_SUCCESS; + } + + for (i = 0; i < MAX_GUILD; ++i) { + TBL_PC* sd; + + if (!(sd = g->member[i].sd)) + continue; + + script_foreach_sub(sd, event); + } + + return SCRIPT_CMD_SUCCESS; +} /*========================================== * @@ -24642,6 +24786,13 @@ struct script_function buildin_func[] = { BUILDIN_DEF2(round, "floor", "i"), BUILDIN_DEF(getequiptradability, "i?"), BUILDIN_DEF(mail, "isss*"), + + BUILDIN_DEF(foreachinserver, "s"), + BUILDIN_DEF(foreachinmap, "ss"), + BUILDIN_DEF(foreachinparty, "si"), + BUILDIN_DEF(foreachinarea, "ssiiii"), + BUILDIN_DEF(foreachinshootablerange, "ssiii"), + BUILDIN_DEF(foreachinguild, "si"), #include "../custom/script_def.inc" {NULL,NULL,NULL}, foreach.diff
  7. Updated to 1.1.3 ( http://www.mediafire.com/file/uoymx2vni249mlu ) : Fixed the gif issue. Added tabs. Added next/previous frame shortcuts (ctrl-right, ctrl-left). Allowed all shortcuts to be modified from Tools > Settings > Shortcuts.
  8. Hello, You need to open the software with the same permissions you opened Windows Explorer. I'm guessing you tried to open SDE with admin privileges and your account isn't an admin (or vice versa). If you just open SDE normally you shouldn't have issues...!
  9. Udated again, sorry about that.
  10. Aaah, I see the issue. Download it again; although you'll have to fix your file manually, replace all "costume = false" with "".
  11. Tokei

    npctalk problems

    Hmmm, that script won't work though, it will be shown on the character instead of the NPC. It looks like I modified the script command to work with any input and I've added an extra parameter for the player_gid. My bad! So... it doesn't seem possible to achieve the original goal without modifying your function in the source...! The closest you'll get to is the latest option: harboro1,215,212,3 script #rockno04 111,5,5,{ end; OnTouch: showscript "West: The Inn, East: The Sheriff's Office", getnpcid(0); end; } It's visible by other players, but it's not a huge deal for what you're trying to do.
  12. Tokei

    npctalk problems

    You're looking for showscript: harboro1,215,212,3 script #rockno04 111,5,5,{ end; OnTouch: showscript "West: The Inn, East: The Sheriff's Office", getnpcid(0, "#rockno04"), SELF, getcharid(3); end; } If you want others to see it as well, then you'd use: harboro1,215,212,3 script #rockno04 111,5,5,{ end; OnTouch: showscript "West: The Inn, East: The Sheriff's Office", getnpcid(0, "#rockno04"); end; }
  13. The script is from 2016, you'll have to use the newest rAthena standards and update the functions if you want to use this script.
  14. Tokei

    Detaching RID

    There's... probably a solution that will work, but I would recommend adding new script functions instead to make your life much easier: static int script_foreach_sub_va_bl(struct block_list* bl, va_list args) { const char* label = va_arg(args, const char*); return script_foreach_sub((TBL_PC*)bl, label); } // void foreachinmap "<npc_label>", "<map name>" BUILDIN_FUNC(foreachinmap) { const char* label = script_getstr(st,2); const char* mapname = script_getstr(st,3); TBL_NPC* nd = map_id2nd(st->oid); int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); if (m < 0) { return SCRIPT_CMD_SUCCESS; } map_foreachinmap(script_foreach_sub_va_bl, m, BL_PC, label); return SCRIPT_CMD_SUCCESS; } /// void foreachinarea "<npc_label>", "<map_name>", <x1>, <y1>, <x2>, <y2> BUILDIN_FUNC(foreachinarea) { const char* label = script_getstr(st,2); const char* mapname = script_getstr(st,3); int x1 = script_getnum(st,4); int y1 = script_getnum(st,5); int x2 = script_getnum(st,6); int y2 = script_getnum(st,7); TBL_NPC* nd = map_id2nd(st->oid); int16 m = (nd && strcmp(mapname, "this") == 0) ? nd->bl.m : map_mapname2mapid(mapname); if (m < 0) { return SCRIPT_CMD_SUCCESS; } map_foreachinarea(script_foreach_sub_va_bl, m, x1, y1, x2, y2, BL_PC, label); return SCRIPT_CMD_SUCCESS; } // defs BUILDIN_DEF(foreachinmap,"ss"), BUILDIN_DEF(foreachinarea,"ssiiii"), Then your script would be: prontera,156,188,0 script dummy_script 77,{ // ... OnScriptEnd: // not sure where you get the winner from! foreachinarea(strnpcinfo(0) + "::OnReward", "this", 36, 63, 63, 36); if (.consolation) { foreachinmap(strnpcinfo(0) + "::OnConsolation", "this"); } sleep 5000; announce "Thank you for playing..."; end; OnReward: for ([email protected] = 0; [email protected] < getarraysize(.prize); [email protected]++) { getitem .prize[[email protected]], .prize[[email protected]]; // ^ this won't work, you either need two arrays, or use [email protected] += 2 instead of [email protected]++ } announce .npcName$ + " : We have a winner. " + strcharinfo(0) + " wins the death by dice event round "+ .diceRound +".",0; // ^ This will be announced multiple times if you have more than one player remaining in that area, the winner announce // should be moved to "OnScriptEnd", but you didn't post your full script. end; OnConsolation: for ([email protected] = 0; [email protected] < getarraysize(.consolation); [email protected]++) { getitem .consolation[[email protected]], .consolation[[email protected]]; // ^ this won't work, you either need two arrays, or use [email protected] += 2 instead of [email protected]++ } end; } Using addrid is kind of a nightmare, and you lose the main script control which is very annoying.
  15. Tokei

    Script crashing map server

    You should be using a function for your item instead (and don't use attachrid), something along the lines of: getitem 57000,1; callfunc("summonfunction", 2); function script summonfunction { [email protected] = getarg(0); // ... close/return; }