Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/24/23 in Posts

  1. Heya, GRF Editor has undergone some big updates in the background in its new release (1.8.5.7) : The .net framework has changed from 3.5 to 4.0. It has been compiled as x64 instead of x86. The cps/lzma libraries have also been recompiled to x64. Another VC++ library is now required: Microsoft Visual Studio C++ 2022 (x64), which can be downloaded here https://aka.ms/vs/17/release/vc_redist.x64.exe A warning will be given if the VC++ library is missing, so it shouldn't be a problem. The preview for RSM/RSM2/RSW files have been remade from scratch based on BrowEdit 3. It now uses OpenGL instead of WPF 3D. While WPF 3D had good performance, it was way too limited in its options, so this change was a must (shaders weren't even possible...). Though, the performance now is somewhat unknown. If it causes too many issues, I'll add an option to revert back to WPF 3D. The new map renderer should be much more accurate to what is shown ingame: Lightmap/shadowmap is now supported. Lub effects are visible. RSM1 animations can be previewed. Maps are animated by default. Fixed a lot of transparency issues (still not perfect, but it's a huge improvement). Many new features were added for rendering. A skymap option was added but that one is still in its early stage. While the preview is focussed, F11 can bring the renderer to fullscreen. Water is now rendered I usually don't write an update post, but I did this time because I'm wary of potential issues. I'll leave here some previews:
    3 points
  2. View File GRF Editor Hello everyone, GRF Editor is an open-source tool for editing GRF files (https://github.com/Tokeiburu/GRFEditor). It offers a wide variety of features and customizations. The software is very stable and responsive, it can handle large operations without lagging your computer. How to install Download the zip archive provided from the download link at the bottom of this description or directly from there: http://www.mediafire.com/?aflylbhblrzpz0h Install the application with GRF Editor Installer.exe; if you are missing a .NET Framework you will be prompted to download it. Once you are done, you can start the program from the link on your desktop. Key features Overall speed is faster (or at least equal) than any GRF tool. Common operations: add, delete, merge, extract, preview, save. Undo and redo for any operation. It can open any GRF file format. Clean and very interactive interface. Saving formats supported : 0x300, 0x200, 0x103 and 0x102 (through the Settings page) and conversion to the Thor format. Instant filter and search options (example : "map .gat"). File association and context menus integration for .grf, .gpf, .rgz and .thor (through the Settings page). Can rebuild separated images into one file easily. Drag and drop (with the ALT key, can be modified in the Settings page). This is a big part of the software; most of the items can be moved around within the application itself or from/to Windows Explorer. If drag and drop does not work, it is most likely because you've started the program using administrator privileges. GRF Editor does not requires administrator privileges to run. Tools Grf validation: allows you to validate a GRF with multiple settings. It can detect corrupted GRF entries, invalid sprites, empty files, non-GRF files, duplicate files and a lot more. Flat maps maker: generates flat maps from .gat and .rsw files. Useful to generate WoE maps or to fasten up the loading time. Patch maker: generates a GRF patch based on two different GRFs. Hash viewer: shows the hash code (both CRC32 and MD5) for files. Image converter: converts an image to any format requested (BMP, PNG, JPG, TGA). GrfCL: used to create batch files (.bat) which can automate tasks on GRF files. See the content in GrfCL.rar in the download for more information. This tool can be customized from the sources as well. Grf encryption The encryption feature has been enabled again. It's similar to what it used to be and it has been tested on client versions ranging from 2012-08-01 to 2024-01-01. Some error messages will be displayed if necessary. If you have an issue, copy the error message (with the code, if there's one) and send me the client executable with the cps.dll file generated by GRF Editor. There shouldn't be compatibility issues anymore though! Thor files Thor files are patches used by Thor Patcher ( https://github.com/rathena/rathena/wiki/Thor-Patcher ). Because of their similarity with the GRF file structure, they have been integrated within GRF Editor. The primary utility of this feature is that it allows you to add encrypted files to a Thor patch. All the other options can be achieved by using Thor Maker. You'll find the necessary steps below, but test your patches before sending them off to players (I've done a lot of testing on my end, but better be safe). If you're using SecureGRF, then make a new GRF, add the files and encrypt it. In GRF Editor, open the encrypted GRF you just made, use "Save as" and name the new file with a .thor extension. That's it, if you want to change the output directory, click on Edit > Edit Grf/Thor settings. You can select the output mode and the GRF to merge the patch with. Simply save again if you change these properties. If you're using GRF Editor's encryption, then make a new Thor file (File > New > New Thor) and add the files you want to patch it with. Right-click on the files you want to encrypt and use Encryption > Encrypt. Technical stuff Requires .Net Framework 4.0 to run (4.0 or more will work as well). Automatically converts file name encoding to the currently selected encoding (you can change the encoding in the Settings page). Data virtualization is used as much as possible to preview files, meaning the files aren't completely loaded. Right-clicking an item will bring up the available options with that file. Preview file formats: txt, log, xml, lua, lub, bmp, png, tga, jpp, db, ebm, pal, gnd, rsw, gat, rsm, str, spr, act, imf, fna, bson, csv, ezv and wav. Services are "crash ready", meaning that you will be warned about a failed operation and no work will be lost (the application won't close and crash). It tries to continue operating even if it meets unsual conditions. Operations can be cancelled by clicking on the button near the progress bar. The warning level can be changed to avoid messages like "Please select a folder first." When prompted with an error, use Ctrl-C to copy the current dialog's content. Some screenshots! 1) Previewing an act file, while showing the search feature 2) Preview of a model file (rsm or rsm2) 3) Preview of GrfCL 4) Preview of maps 5) Preview of Grf validation 6) Search feature (press Ctrl-F or Ctrl-H to bring up within a text editor) Got a feedback? I'd gladly hear you out and fix issues you have with the program. Submitter Tokei Submitted 01/11/13 Category GRF Files Video Content Author Tokeiburu  
    1 point
  3. Hello everynyan! This free script is to help facilitate GvG events with crude but simple commands to make conducting events easier for all our event GMs out there~ Usage dispbottom "@event usage: "; dispbottom "------------------"; dispbottom "@event left (teleport left-side)"; dispbottom "@event right ((teleport right-side)"; dispbottom "@event recall (recall parties)"; dispbottom "@event debuff (debuff all)"; dispbottom "@event supply (give supply all)"; dispbottom "@event start (start event)"; dispbottom "@event stop (stop event)"; dispbottom "@event partycount (count online members)"; dispbottom "------------------"; Customizable Options //set your supplies if you wish setarray .supply_ids, 501,502,503; setarray .supply_amt, 1 ,2 ,3; //add maps that you want to allow the @event command to work on //make sure to update the OnPartyRecall event as well //make sure you add setwall and barricade spawns on those new maps as well setarray .map$, "guild_vs1", "2012rwc_06", "2012rwc_08"; GvGManager.txt
    1 point
  4. Hello everyone, A few years ago, I made a post about the modification of BOT v.3, native to the Hercules emulator. I'm resurrecting this discussion in the hope of finding someone who can help adapt this bot to work on rathena. It seems that someone has already made this modification and even put it up for sale, but I don't have confirmed information. If anyone has knowledge about this or knows someone who can help, I would greatly appreciate it. I'm eager to bring this functionality to the rathena community. Thank you in advance for everyone's attention, and I look forward to any information or assistance you can provide. Index: db/const.txt =================================================================== --- db/const.txt (revision 14530) +++ db/const.txt (working copy) @@ -1258,6 +1258,7 @@ SC__CHAOS 577 SC__FEINTBOMB_MASTER 578 SC_FALLENEMPIRE 579 +SC_BOT 581 e_gasp 0 e_what 1 Index: db/sc_config.txt =================================================================== --- db/sc_config.txt (revision 14530) +++ db/sc_config.txt (working copy) @@ -14,6 +14,7 @@ //Example: //SC_ENDURE, 21 //SC_ENDURE: cannot be removed by death and dispell and cosidered as buff. (16 + 4 + 1 = 21) +SC_BOT, 6 SC_PROVOKE, 32 SC_ENDURE, 21 SC_CLOAKING, 2 Index: npc/bot.txt =================================================================== --- npc/bot.txt (revision 0) +++ npc/bot.txt (working copy) @@ -0,0 +1,51 @@ +// +// +// Author Goddameit +// Version 2015/12/20 +// Web http://goo.gl/0vY9GV +// +// +- script bot_at -1,{ + function __onoff ; +OnInit: + bindatcmd "boton",strnpcinfo(3)+"::OnDo"; + bindatcmd "botoff",strnpcinfo(3)+"::OnDo2"; + bindatcmd "botend",strnpcinfo(3)+"::OnDo2"; + end; +OnDo: + sc_end SC_BOT; + .@SP_BOT_NA = 1; + while(1) + { + .@C = select("[Finish]","[Cancel]","Normal Attack "+__onoff(.@SP_BOT_NA))k; + if( .@C == 1 ) + break; + else if( .@C == 2 ) + close; + else + switch(.@C) + { + case 3: + .@SP_BOT_NA = !.@SP_BOT_NA; + break; + } + } + message strcharinfo(0),"RUN"; + if( .@C == 1 || .@C > 2 ) + { + mes "OK"; + close2; + } + sc_start4 SC_BOT,600000,.@SP_BOT_NA,0,0,0; + end; +OnDo2: + sc_end SC_BOT; + message strcharinfo(0),"END"; + end; + function __onoff { + if(getarg(0) == 0) + return "^BEBEBE[OFF]^000000"; + else + return "^000088[ON]^000000"; + } +} \ No newline at end of file Index: src/map/status.c =================================================================== --- src/map/status.c (revision 14530) +++ src/map/status.c (working copy) @@ -8982,6 +8982,10 @@ if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING; else val2 = MH_MD_FIGHTING; break; + case SC_BOT: + tick_time = 100; + val4 = tick / tick_time; + break; case SC_FULL_THROTTLE: status_percent_heal(bl,100,0); val2 = 7 - val1; @@ -9701,6 +9705,15 @@ } } } + + if (type == SC_BOT) + { + if (sc->data[type]->val4 > 0) + { + //Record how many time you left + pc->setreg(sd, script->add_str("@SP_BOT_LTICK"), sc->data[type]->val4 * 100); + } + } (sc->count)--; @@ -10464,6 +10477,145 @@ } while(0) switch(type) { + case SC_BOT: + if (--(sce->val4) > 0) { + { + int i_ = 0; + struct mmo_charstatus *sta = &sd->status; + unsigned short inf_ = 0; + int64 last_tick = (int64)time(NULL); + unsigned short idle_ = cap_value(DIFF_TICK32(last_tick, sd->idletime), 0, USHRT_MAX); + unsigned short tele_ = cap_value(DIFF_TICK32(last_tick, pc->readreg(sd, script->add_str("@SP_BOT_TELE"))), 0, USHRT_MAX); + unsigned int starget_id_ = bot_check_target_alive(bl, pc->readreg(sd, script->add_str("@SP_BOT_TGID"))); + {//Heal + unsigned short item_id_ = sta->hotkeys[9].id; + if ((sd->battle_status.hp * 100 / 80) < sd->battle_status.max_hp && item_id_ > 0) + { + i_ = pc->search_inventory(sd, item_id_); + if (i_ >= 0) + pc->useitem(sd, i_); + } + item_id_ = sta->hotkeys[10].id; + if ((sd->battle_status.sp * 100 / 80) < sd->battle_status.max_sp && item_id_ > 0) + { + i_ = pc->search_inventory(sd, item_id_); + if (i_ >= 0) + pc->useitem(sd, i_); + } + } + {//Buff + for (i_ = 2; i_ <= 6; i_++) + { + if ((inf_ = bot_chec_khotkeys_is_skill(sd, i_)) > 0) + { + unsigned short id_ = sta->hotkeys[i_].id; + if (inf_ == 4 || inf_ == 16) + { + if (!sc->data[status->skill2sc(id_)]) + unit->skilluse_id(bl, bl->id, id_, sta->hotkeys[i_].lv); + } + } + } + } + if (idle_ % 7 != 0)//Attack + { + { + unsigned short inf_ = 0; + starget_id_ = bot_check_target_alive(bl, pc->readreg(sd, script->add_str("@SP_BOT_TGID"))); + if (starget_id_ > 0) { + if (sce->val1 > 0) + { + switch (rand() % 10) + { + case 0: + case 1: + case 2: + inf_ = bot_chec_khotkeys_is_skill(sd, 7); + if (inf_ == 1) + { + unit->stop_attack(bl); + unit->skilluse_id(bl, starget_id_, sta->hotkeys[7].id, sta->hotkeys[7].lv); + } + break; + case 5: + case 6: + inf_ = bot_chec_khotkeys_is_skill(sd, 8); + if (inf_ == 1) + { + unit->stop_attack(bl); + unit->skilluse_id(bl, starget_id_, sta->hotkeys[8].id, sta->hotkeys[8].lv); + } + break; + default: + unit->attack(bl, starget_id_, 1); + break; + } + } + else + { + switch (rand() % 7) + { + case 0: + case 1: + case 2: + case 3: + case 4: + inf_ = bot_chec_khotkeys_is_skill(sd, 7); + if (inf_ == 1) + { + unit->skilluse_id(bl, starget_id_, sta->hotkeys[7].id, sta->hotkeys[7].lv); + } + break; + case 5: + case 6: + inf_ = bot_chec_khotkeys_is_skill(sd, 8); + if (inf_ == 1) + { + unit->skilluse_id(bl, starget_id_, sta->hotkeys[8].id, sta->hotkeys[8].lv); + } + break; + } + } + } + } + } + else + {//Move + bool flywing_ = false; + if (bot_check_target(bl, starget_id_) == false) + { + if (tele_ > 7) + { + if (sta->hotkeys[0].type == 0 && sta->hotkeys[0].id == 601 && sta->hotkeys[0].lv == 0) + { + i_ = pc->search_inventory(sd, 601); + if (i_ >= 0) + { + pc->useitem(sd, i_); + flywing_ = true; + } + } + if ((st->sp > 20) && (flywing_ == false) && (sta->hotkeys[1].type == 1 && sta->hotkeys[1].id == AL_TELEPORT && sta->hotkeys[1].lv > 0)) + { + if (pc->checkskill(sd, AL_TELEPORT) > 0) + { + pc->randomwarp(sd, CLR_TELEPORT); + status->heal(&sd->bl, 0, -(skill->get_sp(AL_TELEPORT, 1)), 1); + flywing_ = true; + } + } + if (flywing_ == true) + pc->setreg(sd, script->add_str("@SP_BOT_TELE"), last_tick); + } + } + if ((idle_ % 9 == 0 && idle_ > 0) || starget_id_ == 0) + unit->walktoxy(&sd->bl, sd->bl.x + (rand() % 2 == 0 ? -1 : 1)*(rand() % 10), sd->bl.y + (rand() % 2 == 0 ? -1 : 1)*(rand() % 10), 0); + } + } + sc_timer_next(100 + tick, status->change_timer, bl->id, data); + return 0; + } + break; case SC_MAXIMIZEPOWER: case SC_CLOAKING: if(!status->charge(bl, 0, 1)) @@ -12237,3 +12389,73 @@ status->readdb_refine = status_readdb_refine; status->readdb_scconfig = status_readdb_scconfig; } + +bool bot_check_target(struct block_list *src, unsigned int id) +{ + struct block_list *bl = map->id2bl(id); + if (bl) + { + if (path->search(NULL, src->m, src->x, src->y, bl->x, bl->y, 1, CELL_CHKNOREACH) && distance_xy(src->x, src->y, bl->x, bl->y) < 11) + { + TBL_MOB *md = BL_CAST(BL_MOB, bl); + if (md) + { + if (md->status.hp > 0) + { + return true; + } + } + } + } + return false; +} + +int buildin_autoattack_sub(struct block_list *bl, va_list ap) +{ + int *target_id = va_arg(ap, int *); + int src_id = va_arg(ap, int); + struct block_list *src = map->id2bl(src_id); + if (!src || !bl) + return 1; + if (bot_check_target(src, bl->id) == true) + *target_id = bl->id; + else + *target_id = 0; + return 1; +} + +short bot_chec_khotkeys_is_skill(struct map_session_data *sd, unsigned short idx) +{ + if (sd) + { + struct mmo_charstatus *sta = &sd->status; + if (sta) + { + if (sta->hotkeys[idx].type == 1 && pc->checkskill(sd, sta->hotkeys[idx].id) > 0 && sta->hotkeys[idx].lv > 0) + return skill->get_inf(sta->hotkeys[idx].id); + } + } + return -1; +} + +unsigned int bot_check_target_alive(struct block_list *src, unsigned int id) +{ + if (bot_check_target(src, id) == true) + return id; + { + int i_, target_id_; + for (i_ = 0; i_ < 15; i_++) + { + target_id_ = 0; + map->foreachinarea(buildin_autoattack_sub, src->m, src->x - i_, src->y - i_, src->x + i_, src->y + i_, BL_MOB, &target_id_, src->id); + if (target_id_) + { + pc->setreg(map->id2sd(src->id), script->add_str("@SP_BOT_TGID"), target_id_); + break; + } + } + if (target_id_) + return target_id_; + } + return 0; +} \ No newline at end of file Index: src/map/status.h =================================================================== --- src/map/status.h (revision 14530) +++ src/map/status.h (working copy) @@ -715,6 +715,7 @@ SC_FALLENEMPIRE, SC_FLASHCOMBO, + SC_BOT, SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; @@ -2089,4 +2090,8 @@ void status_defaults(void); +bool bot_check_target(struct block_list *src, unsigned int id); +int buildin_autoattack_sub(struct block_list *bl, va_list ap); +short bot_chec_khotkeys_is_skill(struct map_session_data *sd, unsigned short idx); +unsigned int bot_check_target_alive(struct block_list *src, unsigned int id); #endif /* MAP_STATUS_H */
    1 point
  5. Here you go. prontera,164,168,4 script Dwarf 600,{ .@item = 7420; .@quan = 0; .@freeRef = 7; .@paidRef = 10; setarray .@blacklist, 501,502,503,504,505; //add banned item here switch(select("Refino Gratis", "Refino Pago")){ case 1: setarray .@items[0],EQI_SHOES,EQI_GARMENT,EQI_HEAD_TOP,EQI_ARMOR,EQI_HAND_L,EQI_HAND_R;] for(.@i = 0; .@i < getarraysize(.@items); .@i++){ if(inarray(.@blacklist[0],getequipid(.@items[.@i])) != -1){ message strcharinfo(0),"Invalid item"; end; } } for(.@i = 0; .@i < getarraysize(.@items); .@i++){ if(getequiprefinerycnt(.@items[.@i]) < .@freeRef){ specialeffect2 154; successrefitem .@items[.@i],.@freeRef - getequiprefinerycnt(.@items[.@i]); } } end; case 2: setarray .@items[0],EQI_SHOES,EQI_GARMENT,EQI_HEAD_TOP,EQI_ARMOR,EQI_HAND_L,EQI_HAND_R; if (countitem(.@item) < .@quan){ mes "Voce nao tem os items necessarios: " + .@quan + "x "+ getitemname(.@item); close; } for(.@i = 0; .@i < getarraysize(.@items); .@i++){ if(inarray(.@blacklist[0],getequipid(.@items[.@i])) != -1){ message strcharinfo(0),"Invalid item"; end; } } for(.@i = 0; .@i < getarraysize(.@items); .@i++){ // prevent the item consuption if(getequiprefinerycnt(.@items[.@i]) != .@paidRef) .@flag = 1; if(getequiprefinerycnt(.@items[.@i]) < .@paidRef){ specialeffect2 154; successrefitem .@items[.@i],.@paidRef - getequiprefinerycnt(.@items[.@i]); } } if (.@flag == 1) delitem 7420,10; end; } OnInit: waitingroom "Refinador Mestre",0; }
    1 point
  6. Ah yes, sorry it was my mistake, please edit this line if(inarray(.@blacklist[0],.@items[.@i]) != -1){ to this if(inarray(.@blacklist[0],getequipid(.@items[.@i])) != -1){
    1 point
  7. You can add your checks here function Go { set lastwarp$, getarg(0); set lastwarpx, getarg(1,0); set lastwarpy, getarg(2,0); if(BaseLevel > 50 && Zeny < 1000){ mes "You need 1,000 Zeny."; close; } if(BaseLevel > 50) Zeny -= 1000; warp getarg(0),getarg(1,0),getarg(2,0); end; }
    1 point
  8. Hello everynyan! I'm here to present my Interactive Nyani Bot Killer! Intro, *ehem ehem*, we all know that botting is rampant across all Ragnarok Online servers, and there's only so much you can do. And I was thinking, why not make the bot check as interactive as possible? This way, it would be very hard to create a "macro" or bypass for your bot checker! And here I am, presenting my own bot killer system which is simple, and possibly, can not be bypassed. (Or not, who knows, we'll have to see~) More showcases to follow~ Features are as follows! Configurable settings for rewards and buffs Configurable settings for how many monsters to kill before checking is conducted Configurable settings for allowing certain jobs to bypass bot check (Alchemist / Creator) Configurable settings for how many failed attempts before getting jailed Add as many rooms as I want Kill counts will be retained even after logging out or getting disconnected Chat room shuffles every 5 minutes, or on demand (@command) NEW! Added a blacklist for mob ids, so that it can be skipped when doing checks (MVPs, etc) - credit to @Chaos92 for the idea NEW! Added a blacklist for maps, allowing for flexibility on where kills will be counted NEW! Added multiple areas for bot checking, simulating a randomized chatroom location, making bypassing this bot check even harder! NEW! Added check for boosts (XP/JXP/ITEMBOOST) and added the option to extend said buffs by X minutes!
    1 point
×
×
  • Create New...