-
Posts
667 -
Joined
-
Last visited
-
Days Won
91
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Posts posted by Tokei
-
-
This option was removed quite a while ago, sorry!
-
On 8/21/2018 at 9:06 PM, Evrard said:
If someone can help, I am getting this error when saving:
-------------- Message -------------- Couldn't save the accessory item files. Error code = 2, state = OK -------------- Stack trace -------------- at GrfToWpfBridge.Application.DefaultErrorHandler._reportAnyManagedExceptions(String message, Exception exception, ErrorLevel errorLevel) at GrfToWpfBridge.Application.DefaultErrorHandler.Handle(Exception exception, ErrorLevel errorLevel) at SDE.Editor.Engines.LuaEngine.LuaHelper.WriteViewIds(ServerDbs dbSource, AbstractDb`1 db) at SDE.Editor.Generic.Core.DbItems.WriteDb(String dbPath, String subPath, ServerType serverType, FileType fileType) at SDE.Editor.Engines.DatabaseEngine.SdeDatabase.Save(AsyncOperation ap, IProgress progress) at SDE.View.SdeEditor._save() at GRF.Threading.GrfThread.<>c__DisplayClass4.<Start>b__3() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() -------------- Exception -------------- System.Exception: Couldn't save the accessory item files. Error code = 2, state = OK ---> System.Exception: Warning: trying to overwrite an already set accessory name. at SDE.Editor.Engines.LuaEngine.AccessoryTable._setEntry(Int32 viewId, String accessoryName, String resource) at SDE.Editor.Engines.LuaEngine.AccessoryTable._setLuaFromHeadgears() at SDE.Editor.Engines.LuaEngine.AccessoryTable.SetLuaTables() at SDE.Editor.Engines.LuaEngine.LuaHelper.WriteViewIds(ServerDbs dbSource, AbstractDb`1 db) --- End of inner exception stack trace --- -------------- Message -------------- Warning: trying to overwrite an already set accessory name. -------------- Inner exception -------------- System.Exception: Warning: trying to overwrite an already set accessory name. at SDE.Editor.Engines.LuaEngine.AccessoryTable._setEntry(Int32 viewId, String accessoryName, String resource) at SDE.Editor.Engines.LuaEngine.AccessoryTable._setLuaFromHeadgears() at SDE.Editor.Engines.LuaEngine.AccessoryTable.SetLuaTables() at SDE.Editor.Engines.LuaEngine.LuaHelper.WriteViewIds(ServerDbs dbSource, AbstractDb`1 db)
I am runing the SDE as an administrator and at this point I'm at a loss
That means you have a broken accname.lub file and it won't let you save the file until the issues are fixed (to prevent removing some work that you have done in the file yourself). In short, it means that you have lines with identical keys, for instance:
[ACCESSORY_IDs.ACCESSORY_HAT] = "_ÇÞ", // ... [ACCESSORY_IDs.ACCESSORY_HAT] = "_¸®º»",
will not be allowed.
You can disable the lub files from Settings > Edit lua settings > Uncheck "Update accessory tables when saving..."
- 1
-
23 hours ago, Rizta said:
Hi!
Theres an way to add a mobskill through SDE? If yes, how?
All my sprites arent showing and i got no errors... What im doing wrong?
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).
- 1
-
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.
-
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:
Source files: https://github.com/Tokeiburu/Mapcache-Editor
-
Submitter
-
Submitted07/08/2018
-
Category
-
Video
-
Content AuthorTokeiburu
- 7
- 1
-
-
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},
- 2
- 1
- 2
-
On 5/22/2018 at 2:28 PM, Haziel said:
@Tokei There's one issue and a suggestion I would like to talk about:
• First one, when a Headgear has animation on its static pose, the GIF output is totally misaligned regarding the head, body and the headgear itself.
• Secondly, I would like couple shortcuts for next frame/previous frame, so it would make it easy to edit every frame sequentially, any shortcut would do.
Thank you very much for the tool again!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.
-
3 hours ago, AntonLee said:
I cant seem to get my grf nor data folder inside the tool, it just wont let me drag and drop it, a restriction icon will appear and nothing will happen if i drop the grf inside, what can i do? im using windows 10 with 4k monitor ( tried using screen res of 1080 and 720 , still same problem ). pls help, btw your program is amazing and has saved me a lot of time, so thank you very much :).
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...!
-
-
6 hours ago, puccahouse said:
save problem i can't open iteminfo because classnum = ? no , any item id
slotCount = 0,
ClassNum = 0
costume = falseslotCount = 0,
ClassNum = 0,
costume = falseAaah, I see the issue. Download it again; although you'll have to fix your file manually, replace all "costume = false" with "".
-
41 minutes ago, AnnieRuru said:
[Warning]: script: showscript: self can't be used for non-players objects. [Debug]: Source (NPC): #rockno04 at prontera (155,185)
should be
prontera,155,185,3 script #rockno04 111,5,5,{ end; OnTouch: showscript "West: The Inn, East: The Sheriff's Office", getcharid(3), SELF; end; }
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.
- 1
-
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; }
- 2
- 1
-
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.
-
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 (.@i = 0; .@i < getarraysize(.prize); .@i++) { getitem .prize[.@i], .prize[.@i]; // ^ this won't work, you either need two arrays, or use .@i += 2 instead of .@i++ } 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 (.@i = 0; .@i < getarraysize(.consolation); .@i++) { getitem .consolation[.@i], .consolation[.@i]; // ^ this won't work, you either need two arrays, or use .@i += 2 instead of .@i++ } end; }
Using addrid is kind of a nightmare, and you lose the main script control which is very annoying.
-
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 { .@homunsummoned = getarg(0); // ... close/return; }
-
Heya,
Here is the issue with any GRF encryption. No matter how strong it is, no matter how complex it gets, If someone is really willing to decrypt a GRF (and has enough knowledge), they'll be able to. The problem is that the protection is client-sided and your client needs to be able to decrypt the content to be able to access your files. So the deciphering code is in 'plain sight' on your computer. And no, __encryption.info doesn't do anything, it's simply a file to let GRF Editor know the GRF is encrypted and that it should scan the files when you open it. Deleting it wouldn't change anything and hiding it wouldn't achieve much either.
And another no, GRF Editor encrypts the files you select entirely, not just the file header. Your client needs to be able to access the filename table to know where it is in your GRF. It's possible to encrypt the table, but then it makes it impossible to patch these GRFs (Thor Patcher needs to know your file positions in the GRF). Not that it would change much either way, it's simply more convenient to not encrypt the file table.
-
Hello,
GRF Editor forces the text file display back to what you have in the Settings > General > Display encoding (it does this on purpose to prevent you from doing mistakes). Your text file is encoded as UTF-8, which is not supported by your client and which will show up as what you see in GRF Editor. You have to change your text file encoding to Thai (Encoding > Character sets > Thai). In your case, you'll want to do it by "tricking" Notepad++ :
- Make a new text file, change the encoding to Thai.
- Copy your whole msgstringtable.txt file > paste it to your new file.
- Use your new file as msgstringtable.txt instead.
- As for what you'll see in GRF Editor, it should be the common 'gibberish' (unless you change it manually from Settings > General > Display encoding > Custom... > Thai is... 874).
-
It depends what you're doing. If it's headgear, then no that's not possible. You'd have to do a garment sprite but that's a whole different category.
-
Heya,
This flag doesn't seem to be implemented yet; you'd have to open a bug report over here: https://github.com/rathena/rathena/issues
-
The luafiles514 folder is meant for the newer compiled lub format (version 514 = 0x202). kRO upgraded to the new version quite a while ago, what's left in the data\lua files folder should no longer be used and it can be entirely removed. I see you have both the lua and lub file formats in there though. Depending on how you diffed your client, it will attempt to read the lua/lub before the lub/lua, so make sure you're editing the corret files.
- 1
-
I'm a bit confused as to what you're trying to achieve. From my understanding, you wanted to retrieve the account ID from a deleted character ID, to which the following did the work:
select `account_id` from `charlog` where `char_msg` like 'Deleted char (CID 1369541%'
But now you're joining tables and I don't really see why you would want to do that. (Side note, joining the picklog table is a death wish, you should never do that.)
-
You can use:
select * from `charlog` where `char_msg` like '%150368%'
(The table could use some updates though.)
- 1
-
That would be charlog on your main SQL database. Or your map-server logs (assuming you log the servers' console outputs).
-
3 hours ago, Haziel said:
...
Be able to access the specific angle/mirror for the sprite would be awesome.
Wouldn't these always be the same as the reflection of the non-mirror face?
Updated to 1.1.1:
- Forced all scripts to be recompiled.
- Ctrl-Shift-S added.
- Added adjacent frames/actions from Edit > View > Show the adjacent frames (Ctrl-Shift-F). This option also works in Setup Headgear.
- 1
GRF: GRF Editor
in Client Releases
Posted
The latest version is always provided with the latest mediafire link.
Updated to 1.8.2.7:
Brought back the software's sources for those interested: