Tokei

Members
  • Content Count

    452
  • Avg. Content Per Day

    0
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Tokei

  1. Well, this adds a flat 80 hit to all players and enemies. While yes, it does help with your initial issue, it also makes flee builds a lot less worthwhile (it gives a free Phreeoni card to everyone). If that works out for you, then that's up to you...! Although it seems to me your biggest concern is the flee bonus that the higher level monsters get. Why not simply remove that instead? // Flee stat = status->flee; stat += level + status->agi + (bl->type == BL_MER ? 0 : bl->type == BL_PC ? status->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100 status->flee = cap_value(stat, 1, SHRT_MAX); to // Flee stat = status->flee; stat += (bl->type == BL_MOB ? 0 : level) + status->agi + (bl->type == BL_MER ? 0 : bl->type == BL_PC ? status->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100 status->flee = cap_value(stat, 1, SHRT_MAX);
  2. Heya, Well, the function that determines whether you hit or miss the target is is_attack_hitting in battle.cpp. This is purely based on the hit vs flee between you and the target though. Mobs with higher levels have more flee because of the formula they use (in status.cpp): // Flee stat = status->flee; stat += level + status->agi + (bl->type == BL_MER ? 0 : bl->type == BL_PC ? status->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100 status->flee = cap_value(stat, 1, SHRT_MAX); What you're asking for doesn't really fit well with the current system though.
  3. Heya, This is possible, but it usually means the solution/algoritm you're trying to use is the wrong one to start with. That aside, you can use something similar to: duplicate "prontera", 154, 182, 4, "SourceNPC", "DuplicatedNPC", 77; And you'll have to do the changes below: diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 0ce0c96a0..ffde62587 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1219,6 +1219,7 @@ void do_clear_npc(void); void do_final_npc(void); void do_init_npc(void); void npc_event_do_oninit(void); +const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath); int npc_event_do(const char* name); int npc_event_do_id(const char* name, int rid); diff --git a/src/map/script.cpp b/src/map/script.cpp index 604274ecd..9da5d4690 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -24548,6 +24548,38 @@ BUILDIN_FUNC(preg_match) { #endif } +BUILDIN_FUNC(duplicate) +{ + const char *map = script_getstr(st,2); + int x = script_getnum(st,3); + int y = script_getnum(st,4); + int dir = script_getnum(st,5); + const char *duplicate_name = script_getstr(st,6); + const char *npc_name = script_getstr(st,7); + char w1[2048], w2[2048], w3[2048], w4[2048], p[2048]; + int view_id = script_getnum(st,8); + struct npc_data* nd = map_id2nd(st->oid); + + if (!nd) { + return SCRIPT_CMD_FAILURE; + } + + sprintf(w1, "%s,%d,%d,%d", map, x, y, dir); + sprintf(w2, "duplicate(%s)", duplicate_name); + sprintf(w3, "%s", npc_name); + + if (script_hasdata(st,9) && script_hasdata(st,10)) { + sprintf(w4, "%d,%d,%d", view_id, script_getnum(st,9), script_getnum(st,10)); + } + else { + sprintf(w4, "%d", view_id); + } + + sprintf(p, "%s\t%s\t%s\t%s", w1, w2, w3, w4); + npc_parse_duplicate(w1,w2,w3,w4, p, p, nd->path); + return SCRIPT_CMD_SUCCESS; +} + /// script command definitions /// for an explanation on args, see add_buildin_func struct script_function buildin_func[] = { @@ -25170,6 +25202,8 @@ struct script_function buildin_func[] = { BUILDIN_DEF(achievement_condition,"i"), BUILDIN_DEF(getvariableofinstance,"ri"), BUILDIN_DEF(convertpcinfo,"vi"), + + BUILDIN_DEF(duplicate,"siiissi??"), #include "../custom/script_def.inc" {NULL,NULL,NULL},
  4. That means you tried to use the close command when there was no text being displayed (from the mes command). I... don't know what NPC this is, but you'll want to change that "close" for "end" instead.
  5. Heya, The job names are hard-coded in the client executable. You'll have to open an hex editor and then search for "Gunslinger".
  6. Yes, when you "receive" the item in your inventory, the button will display properly because it uses the clif_additem packet. I meant how you receive the item information packet-wise, not the source of where it came from (though that's related of course). As for why 20285 shows up and 20286 doesn't, that is because 20285 has a hat effect and these are not displayed on the client with the feature. You can remove the item from the list by opening hateffectinfo.lub and then removing the ids from effectHatItemTable. It's probably best to keep the button disabled for that one though.
  7. Heya, These are ground unit skills. You'll want to skip the BL_PC check and then adjust the skill ratios to battle.cpp: diff --git a/src/map/battle.cpp b/src/map/battle.cpp index de8167f4a..904a672d8 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -4354,6 +4354,13 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list * if (sd && pc_checkskill(sd, SU_SPIRITOFLIFE)) skillratio += skillratio * status_get_hp(src) / status_get_max_hp(src); break; + case SG_SUN_WARM: + case SG_MOON_WARM: + case SG_STAR_WARM: + if (tsd) { + skillratio += -50; + } + break; } return skillratio; } diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 3b7b4ba86..7656a247f 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -13795,7 +13795,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t do { if( bl->type == BL_PC ) status_zap(bl, 0, 15); // sp damage to players - else // mobs + if( status_charge(ss, 0, 2) ) { // costs 2 SP per hit if( !skill_attack(BF_WEAPON,ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick+(t_tick)count*sg->interval,0) ) status_charge(ss, 0, 8); //costs additional 8 SP if miss
  8. Heya, I presume you're talking about the "Preview" button from the item descriptions? If so, then it's not a file, this is decided server-side. How you receive the item makes the button appear or not. If you look in the clif_vendinglist function, you'll see some item packets sent to the client have 6 extra bytes. This part in particular: WFIFOL(fd,offset+47+i*item_length) = pc_equippoint_sub(sd,data); WFIFOW(fd,offset+51+i*item_length) = data->look; The data->look is the actual view ID that will be shown on the client for the item after clicking the button. The pc_equippoint_sub decides whether the client should display the button or not. The problem with that system is that many packets don't have that feature. If you try to preview the item from a shop NPC, it won't give you the option either. If you put the item in your cart, the button will disappear as well, etc. It's just very unreliable overall. kRO added more "locations" where this feature is available, though.
  9. Tokei

    Picklog db

    Heya, You'll need to edit log_pick in log.cpp: void log_pick(int id, int16 m, e_log_pick_type type, int amount, struct item* itm) Something along those lines: /// logs item transactions (generic) void log_pick(int id, int16 m, e_log_pick_type type, int amount, struct item* itm) { nullpo_retv(itm); if( ( log_config.enable_logs&type ) == 0 ) {// disabled return; } if( !should_log_item(itm->nameid, amount, itm->refine) ) return; //we skip logging this item set - it doesn't meet our logging conditions [Lupus] if( log_config.sql_logs ) { int i; struct map_session_data *sd = map_charid2sd(id); SqlStmt* stmt = SqlStmt_Malloc(logmysql_handle); char esc_sname[NAME_LENGTH*2+1]; StringBuf buf; StringBuf_Init(&buf); if (sd) { Sql_EscapeStringLen(logmysql_handle, esc_sname, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)); } StringBuf_Printf(&buf, "%s INTO `%s` (`time`, `char_id`, `account_id`, `name`, `type`, `nameid`, `amount`, `refine`, `map`, `unique_id`, `bound`", LOG_QUERY, log_config.log_pick); for (i = 0; i < MAX_SLOTS; ++i) StringBuf_Printf(&buf, ", `card%d`", i); for (i = 0; i < MAX_ITEM_RDM_OPT; ++i) { StringBuf_Printf(&buf, ", `option_id%d`", i); StringBuf_Printf(&buf, ", `option_val%d`", i); StringBuf_Printf(&buf, ", `option_parm%d`", i); } StringBuf_Printf(&buf, ") VALUES(NOW(),'%u','%u','%s','%c','%d','%d','%d','%s','%" PRIu64 "','%d'", id, sd ? sd->status.account_id : 0, sd ? esc_sname : "", log_picktype2char(type), itm->nameid, amount, itm->refine, map_getmapdata(m)->name[0] ? map_getmapdata(m)->name : "", itm->unique_id, itm->bound); for (i = 0; i < MAX_SLOTS; i++) StringBuf_Printf(&buf, ",'%d'", itm->card[i]); for (i = 0; i < MAX_ITEM_RDM_OPT; i++) StringBuf_Printf(&buf, ",'%d','%d','%d'", itm->option[i].id, itm->option[i].value, itm->option[i].param); StringBuf_Printf(&buf, ")"); if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_SUCCESS != SqlStmt_Execute(stmt)) SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); } else { char timestring[255]; time_t curtime; FILE* logfp; if( ( logfp = fopen(log_config.log_pick, "a") ) == NULL ) return; time(&curtime); strftime(timestring, sizeof(timestring), log_timestamp_format, localtime(&curtime)); fprintf(logfp,"%s - %d\t%c\t%hu,%d,%d,%hu,%hu,%hu,%hu,%s,'%" PRIu64 "',%d\n", timestring, id, log_picktype2char(type), itm->nameid, amount, itm->refine, itm->card[0], itm->card[1], itm->card[2], itm->card[3], map_getmapdata(m)->name[0]?map_getmapdata(m)->name:"", itm->unique_id, itm->bound); fclose(logfp); } }
  10. Heya, You can't do that (not without major changes anyway). I presume the goal here is to run a script in the source (which is a bad idea), but the easy solution here would simply be to set your variables as temporary global variables and then run an event label: In the source, you would use something like: #include "mapreg.h" #include "npc.h" [...] mapreg_setreg(reference_uid(add_str("[email protected]"), 0), MG_SAFETYWALL); mapreg_setreg(reference_uid(add_str("[email protected]"), 0), skill_id); mapreg_setregstr(reference_uid(add_str("[email protected]$"), 0), "a string"); npc_event_do_id("MyScript::OnCalled", sd->bl.id); And in the script: function script myfunction { announce "arg1: " + getarg(0) + ", arg2: " + getarg(1) + ", arg3: " + getarg(2); return; } - script MyScript -1,{ end; OnCalled: callfunc("myfunction", [email protected], [email protected], [email protected]$); end; } It would be much easier to do the code in the source directly instead though.
  11. Heya, You can use Scripts > Magnifier. It's a multiplier, so simply use a number below 1 to make it smaller.
  12. Heya, Your files are encrypted and they cannot be read/extracted from the GRF. That is the purpose of an encryption tool. Your GRF is not locked in any way. It can be merged, it can be patched, it can be modified, etc. It's meant to protect your work, sprites, custom maps, etc. What you're looking for is an anti-cheat software and this is not one...!
  13. Heya, There are no built-in tool for what you want to do, so you have to write it yourself from the script tool. The property you're looking for in your case is "SpriteIndex": foreach (var action in act) { foreach (var frame in action) { foreach (var layer in frame){ if (layer.SpriteIndex == 0 || layer.SpriteIndex == 1 || layer.SpriteIndex == 2 || layer.SpriteIndex == 9) { layer.OffsetY += 10; } } } } // or act.AllLayers(layer => { if (layer.SpriteIndex == 0 || layer.SpriteIndex == 1 || layer.SpriteIndex == 2 || layer.SpriteIndex == 9) { layer.OffsetY += 10; } }); // or foreach (var layer in act.GetAllLayers()) { if (layer.SpriteIndex == 0 || layer.SpriteIndex == 1 || layer.SpriteIndex == 2 || layer.SpriteIndex == 9) { layer.OffsetY += 10; } }
  14. Heya, Use the latest vesion (from the mediafire links), it supports the costume key...!
  15. If it fails to extract, it means the password was incorrect and it didn't properly decrypt the files.
  16. No it is not. You have to edit skill_tree on your own. The field is added because it is part of the skill_db file.
  17. Hmm, that was back when rAthena was using achievement with a libconfig format; there is no yaml parser in SDE at the moment.
  18. The latest version is always provided with the latest mediafire link. Updated to 1.8.2.7: Fixed a bug when adding a large number of files that ended up ignoring some of the added files. Updated GRF Editor Decompiler to fix some annoying issues with the LUB files. The "Use GRF Editor Decompiler" can no longer be unchecked. Removed the third-party luadec decompilers. Esc now works in the Text encoding window. The Image converter tool now works in batches and automatically set purple (and its variants) as transparent. Added more default paths when making thor files. Extracting broken directory links will no longer stop the file extraction. Brought back the software's sources for those interested: Sources
  19. This option was removed quite a while ago, sorry!
  20. 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..."
  21. 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).
  22. 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.
  23. 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  
  24. Tokei

    Mapcache Editor

    Version 1.0.1

    215 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