Leaderboard
Popular Content
Showing content with the highest reputation since 05/15/25 in Posts
-
3 points
[SHOWCASE] I'm back on spriting.
Aeslix and 2 others reacted to DaviLord for a post in a topic
After a long time dealing with personal stuff, i'm back on spriting. OBS¹: My sprites/effects/images will never have the same style because i get it from a lot of sources. OBS²: Please don't ask for raw images/sprites, and i'll not teach how to get/do it. -
3 points
[Showcase] Palette Extension Tools for ACT Editor
daimyo1429 and 2 others reacted to Hanashi for a post in a topic
Hi everyone, I’ve been working on some scripts to improve palette management in ACT Editor. The main functionality and logic are already complete, but the UI still needs a lot of refinement. I’ve prepared improvements, and once ACT Editor updates to .NET Framework 4.8 (thanks to Tokei’s work), I’ll be able to integrate them properly. ✅ Included Scripts Remove Unused Palette Cleans your palette by marking unused colors in magenta. Makes it easier to spot wasted slots and optimize your palette. Sort Palette Blocks Reorders palette blocks based on color usage and brightness. Lets you keep special colors in fixed slots while organizing the rest automatically. Interactive config window for custom sorting options. Palette Generator Generates entire sets of palettes automatically. Supports hue shifts, saturation/lightness adjustments, and Photoshop-like colorize mode. Batch export .pal files with customizable naming. 🌟 Why This Matters Managing palettes manually is time-consuming and error-prone. These scripts automate the hardest parts: No more hunting for unused slots. No more messy palette orders. No more repetitive recoloring. These tools take time and effort to build. Having a clear goal helps me stay motivated and ensures I can dedicate proper time to improving them. Your support directly helps speed up development and polish. If you’d like to support, you can check out my Ko-fi page. Thanks for reading, and I’m excited to share more not only in this tool but anything related to RO. -
1 pointHello! I'm Niel, I've been working as a Spriter for several months, focusing mainly on creating custom graphics for RO servers. During this time, I’ve gained experience developing sprites with very unique custom concepts, I've created many upper headgears, garments, and of course, recolors. Feel free to drop me a PM if you’d like to collaborate or request commissions! I didn't have much time this summer but I'm definitely back~ This is my Discord Server where I post what I'm working on and finished costumes: https://discord.gg/KP3EPwnkzT // discord: nielily_ These have my sign, but if you buy them I will add your RO Server Name to the collection image as well! 😸 These are some examples of my work 💗 Minecraft Set [ Minecraft Helmet | Minecraft Sword [Garment] | Minecraft Pickaxe [Garment] Duck Set Duck Bucket | Duck Bubbles | Duck Bag [Garment] Labubus Comes in 7 different colors, just like in the original box! Okarun Set Okarun Wig | Okarun Mask | Okarun Aura | Turbo Granny [Garment] Turbo Granny Cat Upper Headgear Pokémon Sylveon Swablu Skitty Shaymin Pachirisu Buneary Bellossom Absol Thank you for watching, I appreciate you ❤️😄
-
1 pointPhilippines Ragnarök Online (PHRO) is build for classic gameplay that relive the nostalgia just like when it first started. Everything is pretty much what it is on Episode 4 (War of Emperium) guidebook that was release by levelupgames philippines with 2-1 jobs like Priest, Assassin, Blacksmith, Hunter & Wizard. We created this server for you to play whenever you have the time to spend, no fear of missing out, no pressure just fun. You may be a casual or a hardcore player. Features: -1x rates with MVP/Miniboss cards enabled -Manual job change -Single client only -No costumes -Singapore host -PC only NO MOBILE QoL -Hourly pvp refill pots -Autotrade -Autobuy store -Global chat -Mail system ***Opened last October 10, 2025*** Discord Link : https://discord.gg/HsN77DCETy Website : https://www.phro.fun
-
1 point
-
1 point
Advertiser / Video Editor | Promotional Video
vBrenth reacted to Frosch Production for a post in a topic
For OldschoolRO - Revo (Nostalgic Video) -
1 pointView File Client Rodex Return Button Handler Adds support for "Return" button in the Rodex mail UI. Allows recipients to return a mail back to the sender by clicking the button in the client interface. Compatible with the latest version of Hercules Successfully built on Windows (MSVC) and Debian 12 (GCC) Thoroughly tested with client version: 2022-04-06 and 2025-03-19 Note The "Return" button is available in client versions from approximately 2022-03-30 and later. Setup 1. Set PACKETVER >= 20220330 in /src/common/mmo.h 2. Recompile your Hercules server with the plugin 🔗 https://github.com/AcidMarco/ro-releases Submitter AcidMarco Submitted 06/05/25 Category Plugins
-
1 pointIt has been a long while since I last built one, and I never used WARP. But I think I can give you a few ideas... All those errors are related to bad lua files. Maybe the way you generated them is giving bad results, maybe you have an issue loading them. I can't guide on the translation project as I only used it once or twice to mixed results, so I usually just build my client manually... Here are some tips to try to debug these issues: 1. "attempt to call a nil value" means the function does not exists. Check if you have those LUAs and they have the required function - queryRegionInfo: data\lua files\seekparty\party_booking.lub or data\lua files\seekparty\party_booking_function.lub (I am not sure which one is loaded when, but I can see both has this function) - ResetTheHotKey: data\lua files\hotkey.lub If you don't have these functions in those files, this is likely the cause. If you do, maybe you have an issue loading your GRF. You can try tweaking how you generate your client from translation project and see if you get a better lua as output... just throwing ideas here as I don't know how to use it. 2. "attempt to index global 'JobSkillTab' (a nil value)" as far as I remember, means some code is doing JobSkillTAb[IDX] while JobSkillTab is not initialized Check if data/luafiles514/lua files/skillinfoz/skillinfo_f.lub is initializing a table: JobSkillTab = {} -- I think this is the root cause. If it is not, your lua files are bad for this client Hope this helps
-
1 pointSome time ago I adjusted the emblem display on the website, but I don't remember which file I modified. I think it was related to the imagecreatefrombmpstring function, but I could be wrong - it wasn't too difficult to fix it. Below I'm sending potential files that may have been changed, compare them with your own files. Also, pay attention to the PHP error logs - often the solution lies there. \lib\Flux\EmblemExporter.php <?php require_once 'functions/imagecreatefrombmpstring.php'; /** * */ class Flux_EmblemExporter { /** * */ public $loginAthenaGroup; /** * */ public $athenaServers = array(); /** * */ public function __construct(Flux_LoginAthenaGroup $loginAthenaGroup) { $this->loginAthenaGroup = $loginAthenaGroup; } /** * */ public function addAthenaServer(Flux_Athena $athenaServer) { if (!in_array($athenaServer, $this->loginAthenaGroup->athenaServers, true)) { throw new Flux_Error( "{$athenaServer->serverName} is not a valid char/map server defined in the {$this->loginAthenaGroup->serverName} group."); } $this->athenaServers[$athenaServer->serverName] = $athenaServer; } /** * */ public function exportArchive() { $topDir = $this->sanitizePathName($this->loginAthenaGroup->serverName); $tmpDir = FLUX_DATA_DIR.'/tmp'; $tmpFile = tempnam($tmpDir, 'zip'); // Create zip archive. $zip = new ZipArchive(); $zip->open($tmpFile, ZIPARCHIVE::OVERWRITE); $zip->addEmptyDir($topDir); foreach ($this->athenaServers as $athenaServer) { $athenaDir = $this->sanitizePathName($athenaServer->serverName); $zip->addEmptyDir("$topDir/$athenaDir"); $sql = "SELECT name, emblem_data FROM {$athenaServer->charMapDatabase}.guild WHERE emblem_len > 0 ORDER BY name ASC"; $sth = $athenaServer->connection->getStatement($sql); $sth->execute(); $guilds = $sth->fetchAll(); if ($guilds) { foreach ($guilds as $guild) { $emblemData = @gzuncompress(pack('H*', $guild->emblem_data)); $emblemImage = imagecreatefrombmpstring($emblemData); ob_start(); imagepng($emblemImage); $data = ob_get_clean(); $emblemName = sprintf('%s.png', $this->sanitizePathName($guild->name)); $zip->addFromString("$topDir/$athenaDir/$emblemName", $data); } } } // Close archive. $zip->close(); // Send out appropriate HTTP headers. $filename = urlencode(sprintf('%s-%s-emblems.zip', strtolower($topDir), date('Ymd'))); header('Content-Type: application/zip'); header('Content-Length: '.filesize($tmpFile)); header("Content-Disposition: attachment; filename=$filename"); // Read contents of the file. readfile($tmpFile); // Remove temporary file. unlink($tmpFile); exit; } /** * */ private function sanitizePathName($pathName) { return preg_replace('/[^\w\d ]+/', '', $pathName); } } ?> \lib\functions\imagecreatefrombmpstring.php <?php /** * Convert a bmp string to Image resource * @param {string} $data - BMP string content * @return {resource} image resource */ function imagecreatefrombmpstring($data) { // Read header extract( unpack("a2signature/x8/Voffset/x4/Vwidth/Vheight/x2/vbits", substr($data, 0, 30))); if ($signature !== 'BM') { return false; } // Create image $img = imagecreatetruecolor($width, $height); imagealphablending($img, false); imagesavealpha($img, true); // Load palette (if used) $paletteSize = $offset - 54; $imagePalette = array(); if ($paletteSize > 0 && $bits < 16) { $palette = unpack('C'. $paletteSize, substr($data, 54, $paletteSize)); for ($i = 1, $p = 0; $i < $paletteSize; $i += 4, $p++ ) { $b = $palette[$i+0]; $g = $palette[$i+1]; $r = $palette[$i+2]; $a = $palette[$i+3]; // Magenta is transparent. if (($r & 0xf8 === 0xf8) && ($g === 0) && ($b & 0xf8 === 0xf8)) { $a = 127; } $imagePalette[$p] = imagecolorallocatealpha($img, $r, $g, $b, $a); } } // Read ImageData $skip = ( 4 - ( (( ($bits * $width) + 7) >> 3 ) & 3 ) ) % 4; $size = $width * $height * ($bits >> 3) + $skip * $height; $imageData = unpack('C'. $size, substr($data, $offset, $size) ); switch ($bits) { // Not an original DIB file ? default: return false; // 24 bits BMP case 24: for ($i = 1, $y = $height-1; $y > -1; $y--, $i += $skip) { for ($x = 0; $x < $width; $x++, $i+=3) { $b = $imageData[$i+0]; $g = $imageData[$i+1]; $r = $imageData[$i+2]; if ($r === 255 && $g === 0 && $b === 255) { $c = imagecolorallocatealpha($img, $r, $g, $b, 127); } else { $c = imagecolorallocate($img, $r, $g, $b); } imagesetpixel($img, $x, $y, $c ); } } break; // 8 bits BMP case 8: for ($i = 1, $y = $height-1; $y > -1; $y--, $i += $skip) { for ($x = 0; $x < $width; $x++, $i++) { imagesetpixel($img, $x, $y, $imagePalette[$imageData[$i]] ); } } break; // 4 bits BMP case 4: for ($i = 1, $y = $height-1; $y > -1; $y--, $i += $skip) { for ($x = 0; $x < $width; $x+=2, $i++) { $byte = &$imageData[$i]; imagesetpixel($img, $x+0, $y, $imagePalette[$byte >> 4 ]); imagesetpixel($img, $x+1, $y, $imagePalette[$byte & 0x0F]); } } break; // 1 bit BMP case 1: for ($i = 1, $y = $height-1; $y > -1; $y--, $i += $skip) { for ($x = 0; $x < $width; $x+=8, $i++) { $byte = &$imageData[$i]; imagesetpixel($img, $x+0, $y, $imagePalette[ !!($byte & 0x80) ]); imagesetpixel($img, $x+1, $y, $imagePalette[ !!($byte & 0x40) ]); imagesetpixel($img, $x+2, $y, $imagePalette[ !!($byte & 0x20) ]); imagesetpixel($img, $x+3, $y, $imagePalette[ !!($byte & 0x10) ]); imagesetpixel($img, $x+4, $y, $imagePalette[ !!($byte & 0x08) ]); imagesetpixel($img, $x+5, $y, $imagePalette[ !!($byte & 0x04) ]); imagesetpixel($img, $x+6, $y, $imagePalette[ !!($byte & 0x02) ]); imagesetpixel($img, $x+7, $y, $imagePalette[ !!($byte & 0x01) ]); } } break; } return $img; } ?> \modules\guild\emblem.php <?php if (!defined('FLUX_ROOT')) exit; function flux_get_default_bmp_data() { $filename = sprintf('%s/emblem/%s', FLUX_DATA_DIR, Flux::config('MissingEmblemBMP')); if (file_exists($filename)) { return file_get_contents($filename); } } function flux_display_empty_emblem() { $data = flux_get_default_bmp_data(); header("Content-Type: image/bmp"); header('Content-Length: '.strlen($data)); echo $data; exit; } if (Flux::config('ForceEmptyEmblem')) flux_display_empty_emblem(); $serverName = $params->get('login'); $athenaServerName = $params->get('charmap'); $guildID = intval($params->get('id')); $athenaServer = Flux::getAthenaServerByName($serverName, $athenaServerName); if (!$athenaServer || $guildID < 0) flux_display_empty_emblem(); else { if ($interval=Flux::config('EmblemCacheInterval')) { $interval *= 60; $dirname = FLUX_DATA_DIR."/tmp/emblems/$serverName/$athenaServerName"; $filename = "$dirname/$guildID.png"; if (!is_dir($dirname)) if (Flux::config('RequireOwnership')) mkdir($dirname, 0700, true); else mkdir($dirname, 0777, true); elseif (file_exists($filename) && (time() - filemtime($filename)) < $interval) { header("Content-Type: image/png"); header('Content-Length: '.filesize($filename)); @readfile($filename); exit; } } $db = $athenaServer->charMapDatabase; $sql = "SELECT emblem_len, emblem_data FROM $db.guild WHERE guild_id = ? LIMIT 1"; $sth = $athenaServer->connection->getStatement($sql); $sth->execute(array($guildID)); $res = $sth->fetch(); if (!$res || !$res->emblem_len || is_null($res->emblem_data)) flux_display_empty_emblem(); else { $data = hex2bin($res->emblem_data); if ($data === false) { flux_display_empty_emblem(); exit; } $signature = substr($res->emblem_data, 0, 4); // First 2 bytes, because it's in hex $image_type = "image/png"; // Default if ($signature === "4749") { $image_type = "image/gif"; } elseif ($signature === "424D") { $image_type = "image/bmp"; require_once 'functions/imagecreatefrombmpstring.php'; $image = imagecreatefrombmpstring($data); if ($image === false) { flux_display_empty_emblem(); exit; } // Reassign $data to the PNG image data ob_start(); imagepng($image); $data = ob_get_contents(); ob_end_clean(); } elseif ($signature === "7801") { // Attempt zlib decompression $data = @gzuncompress($data); if ($data === false) { flux_display_empty_emblem(); exit; } // Here, further identification of the data type may be needed } header("Content-Type: {$image_type}"); header('Content-Length: '.strlen($data)); echo $data; exit; } } ?>
-
1 pointAdded bow and staff.
-
1 point
Client New Emotion System and UI Handler
akbaremonz reacted to AcidMarco for a post in a topic
View File Client New Emotion System and UI Handler The plugin adds full support for the new emotion system introduced in RO clients from ~2023-08-02 onward. It handles emotion playback packets, supports in-game emotion pack purchasing, and reads a configurable emotion pack database. Compatible with the latest version of Hercules Successfully built on Windows (MSVC) and Debian 12 (GCC) Thoroughly tested with client version: 2025-03-05 The plugin provides the following features 1. Handling of new emotion playback packets 2. Management and parsing of the emotion pack database 3. Functions for purchasing emotion packs in-game Setup 1. Set PACKETVER >= 20230802 in /src/common/mmo.h (make sure your client version supports the new emotion system) 2. Place emotion_pack_db.conf in your /db/ folder Optional Modify UI_CURRENCY_ID in the plugin. To change UI_CURRENCY_ID client-side, apply the HEX patch. Included in this post ns_client_emote_ui_handler.c — server plugin (HPM) emotion_pack_db.conf — emotion pack definitions Client-side files (LUB/UI/HEX patch) Client UI files, hex patch, and additional resources are available in the public repository: 🔗 https://github.com/AcidMarco/ro-releases Submitter AcidMarco Submitted 05/07/25 Category Plugins -
1 pointNo discord server for now, i'm still setting up. Added new weapon.
-
1 pointAdded a new weapon.
-
1 point
Mapcache for old Izlude.
aioros reacted to johnlincon for a post in a topic
I had a problem with that until I learned how to solve it. When I went to izlude's map, in some parts I couldn't walk, because the server was carrying the newest izlude mapcache (I believe), well I would like to share the old izlude mapcache that I generated, if you have a problem with that, just replace the file. \Hercules\maps\ pre-re izlude.mcache -
1 pointhttp://herc.ws/wiki/Searchstores http://herc.ws/wiki/Buyingstore Can someone explain to me how to use these commands please?
-
1 pointI really need help I would like to make a command to disable a visual effect on the player for example, this is the command to enable a visual effect: (used in skill.c file to enable a visual effect) clif->specialeffect(&sd->bl, type, (send_target)flag); and this is the function of the command clif.c file: void clif_specialeffect(struct block_list* bl, int type, enum send_target target){unsigned char buf[24];nullpo_retv(bl);memset(buf, 0, packet_len(0x1f3));WBUFW(buf,0) = 0x1f3;WBUFL(buf,2) = bl->id;WBUFL(buf,6) = type;clif->send(buf, packet_len(0x1f3), bl, target);if (disguised(bl)) {WBUFL(buf,2) = -bl->id;clif->send(buf, packet_len(0x1f3), bl, SELF);}} you know how I can redo this command to disable the visual effect? please help me, you are the one who knows the whole program! thanks please look at my problem, just need to turn off the visual effect: yet without success.
