Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/08/25 in all areas

  1. This is a simple site that allows you to create your own RO Login Background. It's now fully functional. With this tool, you can upload any image of your choice and select the desired area to be cropped. You can also adjust the aspect ratio to your liking. Features: Support for t_login.jpg output for newer clients Multiple quantization algorithms for 8-bit mode (NeuQuant, Median Cut, K-Means, etc.) Optional noise dithering to improve quality of images with blending showed on the RO Client Output Options: Default output (24-bit BMP): Produces high quality images 8-bit BMP: Reduces the final output size significantly (with some quality loss) t_login.jpg: For modern clients that support JPEG backgrounds Tool URL: FroggoCutter (sapitosucio.github.io) The files generated have the following format: t_¹è°æX-Y.bmp, said files are compressed into a .zip file, then it's downloaded. Do remember those BMPs files should be placed on: data\texture\À¯ÀúÀÎÅÍÆäÀ̽º Btw everything is done locally, nothing is uploaded. You can see it's source code here Known Issues: When you try to slice a big image (>2000px) and 8Bit is selected, the browser may lock itself for a few seconds (❁´◡`❁) Froggo tip of the day: Use big images(>2000px), upscale them or something and then, slice it, the final result is quite gucci Some SS: The manipulation part: BMPs loaded by client:
    2 points
  2. Here’s the updated explanation with all points formatted for easy copying: Welcome to the Online Custom Item Generator! Website: https://rotools.ti-server.com/ What is the Custom Item Generator? The Custom Item Generator is an innovative, user-friendly online tool designed to simplify and enhance your Ragnarok Online (RO) gaming or server development experience. Whether you're a server administrator, developer, or enthusiast, this platform helps you create and manage custom items efficiently and accurately. Key Features: Custom Item Creation Automates the generation of custom items for your server. Input file names (e.g., sprites or resources), and the tool will generate the required configurations or assets seamlessly. Sprite Management Tools Organize and preview custom sprites easily. Generate item and resource file lists for smooth integration into your server. Batch Processing Handle multiple files simultaneously to speed up tedious manual tasks. Perfect for bulk sprite or resource management. Error Checking Validate configurations to ensure compatibility and reduce server-side issues. User-Friendly Interface An intuitive design makes it accessible for users of all experience levels. Who Is This For? Server Administrators: Quickly configure and manage custom items or server assets. Players: Create personalized items for your favorite private servers. RO Developers: Test and fine-tune game elements with ease. Why Choose the Custom Item Generator? Fast & Reliable: Built with automation to save you time and effort. Accessible Anywhere: Available online—no need to install software. Secure & Private: Ensures the safety of your data during processing. Start creating and managing your RO assets effortlessly by visiting the Custom Item Generator today! Feel free to share feedback or reach out for support through the platform. This layout ensures users can easily copy individual points or sections as needed. Let me know if further tweaks are required! Please let me know if you found any bugs.
    2 points
  3. pokemon.mp4 Check out my new creation! Pokemon Map In-game Video Preview pokemon.mp4 Indoor indoor.mp4
    1 point
  4. Unfortunately, hat effects were implemented on the map_session_data (player) on the emulator, while it should have been on the unit_data structure instead, which is shared by all object types. So you'll need a lot of modifications to get this working on monsters. If you apply the changes below, you'll be able to add a hat effect with this command: monster "prontera", 154, 182, "--ja--", 1002, 1; hateffect 12, true, $@mobid; Changes: diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 991b5b1b8..f2fece16d 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -1733,7 +1733,7 @@ int clif_spawn( struct block_list *bl, bool walking ){ if (sd->status.robe) clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA); clif_efst_status_change_sub(bl, bl, AREA); - clif_hat_effects(sd,bl,AREA); + clif_hat_effects(bl, bl, true, AREA); } break; case BL_MOB: @@ -1745,6 +1745,7 @@ int clif_spawn( struct block_list *bl, bool walking ){ clif_specialeffect(&md->bl,EF_BABYBODY2,AREA); if ( md->special_state.ai == AI_ABR || md->special_state.ai == AI_BIONIC ) clif_summon_init(*md); + clif_hat_effects(bl, bl, true, AREA); } break; case BL_NPC: @@ -1756,6 +1757,7 @@ int clif_spawn( struct block_list *bl, bool walking ){ clif_specialeffect(&nd->bl,EF_BABYBODY2,AREA); clif_efst_status_change_sub(bl, bl, AREA); clif_progressbar_npc_area(nd); + clif_hat_effects(bl, bl, true, AREA); } break; case BL_PET: @@ -5104,7 +5106,7 @@ void clif_getareachar_unit( map_session_data* sd,struct block_list *bl ){ if ( tsd->status.robe ) clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF); clif_efst_status_change_sub(&sd->bl, bl, SELF); - clif_hat_effects(sd,bl,SELF); + clif_hat_effects(&sd->bl, bl, true, SELF); } break; case BL_MER: // Devotion Effects @@ -5122,6 +5124,7 @@ void clif_getareachar_unit( map_session_data* sd,struct block_list *bl ){ clif_specialeffect_single(bl,EF_BABYBODY2,sd->fd); clif_efst_status_change_sub(&sd->bl, bl, SELF); clif_progressbar_npc(nd, sd); + clif_hat_effects(&sd->bl, bl, true, SELF); } break; case BL_MOB: @@ -5139,6 +5142,7 @@ void clif_getareachar_unit( map_session_data* sd,struct block_list *bl ){ clif_monster_hp_bar(md, sd->fd); } #endif + clif_hat_effects(&sd->bl, bl, true, SELF); } break; case BL_PET: @@ -21184,53 +21188,46 @@ void clif_navigateTo(map_session_data *sd, const char* mapname, uint16 x, uint16 /// Send hat effects to the client (ZC_HAT_EFFECT). /// 0A3B <Length>.W <AID>.L <Status>.B { <HatEffectId>.W } -void clif_hat_effects( map_session_data* sd, struct block_list* bl, enum send_target target ){ +void clif_hat_effects(struct block_list* src, struct block_list* bl, bool enable, enum send_target target ){ #if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - map_session_data *tsd; - struct block_list* tbl; - - if( target == SELF ){ - tsd = BL_CAST(BL_PC,bl); - tbl = &sd->bl; - }else{ - tsd = sd; - tbl = bl; - } - - nullpo_retv( tsd ); - - if( tsd->hatEffects.empty() || map_getmapdata(tbl->m)->getMapFlag(MF_NOCOSTUME) ){ + struct unit_data* ud; + + if (!src || !bl || !(ud = unit_bl2ud(bl))) return; - } - + + if (ud->hatEffects.empty() || map_getmapdata(src->m)->getMapFlag(MF_NOCOSTUME)) { + return; + } + struct PACKET_ZC_EQUIPMENT_EFFECT* p = (struct PACKET_ZC_EQUIPMENT_EFFECT*)packet_buffer; - - p->packetType = HEADER_ZC_EQUIPMENT_EFFECT; - p->packetLength = (int16)( sizeof( struct PACKET_ZC_EQUIPMENT_EFFECT ) + sizeof( int16 ) * tsd->hatEffects.size() ); - p->aid = tsd->bl.id; - p->status = 1; - - for( size_t i = 0; i < tsd->hatEffects.size(); i++ ){ - p->effects[i] = tsd->hatEffects[i]; - } - - clif_send( p, p->packetLength, tbl, target ); + + p->packetType = HEADER_ZC_EQUIPMENT_EFFECT; + + p->packetLength = (int16)( sizeof( struct PACKET_ZC_EQUIPMENT_EFFECT ) + sizeof( int16 ) * ud->hatEffects.size() ); + p->aid = bl->id; + p->status = enable; + + for (size_t i = 0; i < ud->hatEffects.size(); i++) { + p->effects[i] = ud->hatEffects[i]; + } + + clif_send(p, p->packetLength, src, target); #endif } -void clif_hat_effect_single( map_session_data* sd, uint16 effectId, bool enable ){ +void clif_hat_effect_single( struct block_list* bl, uint16 effectId, bool enable ){ #if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - nullpo_retv( sd ); - - struct PACKET_ZC_EQUIPMENT_EFFECT* p = (struct PACKET_ZC_EQUIPMENT_EFFECT*)packet_buffer; - - p->packetType = HEADER_ZC_EQUIPMENT_EFFECT; - p->packetLength = (int16)( sizeof( struct PACKET_ZC_EQUIPMENT_EFFECT ) + sizeof( int16 ) ); - p->aid = sd->bl.id; - p->status = enable; - p->effects[0] = effectId; - - clif_send( p, p->packetLength, &sd->bl, AREA ); + nullpo_retv(bl); + + struct PACKET_ZC_EQUIPMENT_EFFECT* p = (struct PACKET_ZC_EQUIPMENT_EFFECT*)packet_buffer; + + p->packetType = HEADER_ZC_EQUIPMENT_EFFECT; + p->packetLength = (int16)( sizeof( struct PACKET_ZC_EQUIPMENT_EFFECT ) + sizeof( int16 ) ); + p->aid = bl->id; + p->status = enable; + p->effects[0] = effectId; + + clif_send( p, p->packetLength, bl, AREA ); #endif } diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 1bf10b262..f6ba450b2 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -801,8 +801,8 @@ void clif_item_repair_list(map_session_data *sd, map_session_data *dstsd, int lv void clif_item_repaireffect(map_session_data *sd, int idx, int flag); void clif_item_damaged(map_session_data* sd, unsigned short position); void clif_item_refine_list(map_session_data *sd); -void clif_hat_effects( map_session_data* sd, struct block_list* bl, enum send_target target ); -void clif_hat_effect_single( map_session_data* sd, uint16 effectId, bool enable ); +void clif_hat_effects(struct block_list* src, struct block_list* bl, bool enable, enum send_target target); +void clif_hat_effect_single(struct block_list* bl, uint16 effectId, bool enable); void clif_item_skill(map_session_data *sd,uint16 skill_id,uint16 skill_lv); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 1cb25fad6..c2e9b2cc2 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2220,10 +2220,6 @@ bool pc_authok(map_session_data *sd, uint32 login_id2, time_t expiration_time, i // Initialize BG queue sd->bg_queue_id = 0; -#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - sd->hatEffects = {}; -#endif - sd->catch_target_class = PET_CATCH_FAIL; // Check EXP overflow, since in previous revision EXP on Max Level can be more than 'official' Max EXP diff --git a/src/map/pc.hpp b/src/map/pc.hpp index c37cd4fb5..3f4ceb943 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -922,10 +922,6 @@ public: short setlook_head_top, setlook_head_mid, setlook_head_bottom, setlook_robe; ///< Stores 'setlook' script command values. -#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - std::vector<int16> hatEffects; -#endif - struct{ int tid; uint16 skill_id; diff --git a/src/map/script.cpp b/src/map/script.cpp index 027587945..72a1382f1 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -24268,39 +24268,31 @@ BUILDIN_FUNC(recalculatestat) { BUILDIN_FUNC(hateffect){ #if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - map_session_data* sd; - - if( !script_rid2sd(sd) ) - return SCRIPT_CMD_FAILURE; - - int16 effectID = script_getnum(st,2); - bool enable = script_getnum(st,3) ? true : false; - - if( effectID <= HAT_EF_MIN || effectID >= HAT_EF_MAX ){ - ShowError( "buildin_hateffect: unsupported hat effect id %d\n", effectID ); - return SCRIPT_CMD_FAILURE; - } - - auto it = util::vector_get( sd->hatEffects, effectID ); - - if( enable ){ - if( it != sd->hatEffects.end() ){ - return SCRIPT_CMD_SUCCESS; - } - - sd->hatEffects.push_back( effectID ); - }else{ - if( it == sd->hatEffects.end() ){ - return SCRIPT_CMD_SUCCESS; - } - - util::vector_erase_if_exists( sd->hatEffects, effectID ); - } - - if( !sd->state.connect_new ){ - clif_hat_effect_single( sd, effectID, enable ); - } - + int16 effectID = script_getnum(st,2); + bool enable = script_getnum(st,3) ? true : false; + + // This is unecessary and annoying half the time + //if( effectID <= HAT_EF_MIN || effectID >= HAT_EF_MAX ){ + // ShowError( "buildin_hateffect: unsupported hat effect id %d\n", effectID ); + // return SCRIPT_CMD_FAILURE; + //} + + struct block_list* bl; + bool send = true; + + if (script_hasdata(st, 4)) { + bl = map_id2bl(script_getnum(st, 4)); + } + else { + bl = map_id2bl(st->rid); + map_session_data* sd = BL_CAST(BL_PC, bl); + + if (sd && sd->state.connect_new) { + send = false; + } + } + + unit_hateffect(bl, effectID, enable, send); #endif return SCRIPT_CMD_SUCCESS; } @@ -27566,7 +27558,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(adopt,"vv"), BUILDIN_DEF(getexp2,"ii?"), BUILDIN_DEF(recalculatestat,""), - BUILDIN_DEF(hateffect,"ii"), + BUILDIN_DEF(hateffect,"ii?"), BUILDIN_DEF(getrandomoptinfo, "i"), BUILDIN_DEF(getequiprandomoption, "iii?"), BUILDIN_DEF(setrandomoption,"iiiii?"), diff --git a/src/map/unit.cpp b/src/map/unit.cpp index f90529926..f57fcde6c 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -2964,6 +2964,9 @@ void unit_dataset(struct block_list *bl) ud->attackabletime = ud->canact_tick = ud->canmove_tick = gettick(); +#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) + ud->hatEffects = {}; +#endif } /** @@ -3461,10 +3464,6 @@ int unit_free(struct block_list *bl, clr_type clrtype) sd->qi_display.clear(); -#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) - sd->hatEffects.clear(); -#endif - if (sd->achievement_data.achievements) achievement_free(sd); @@ -3645,6 +3644,14 @@ int unit_free(struct block_list *bl, clr_type clrtype) break; } } + + + if (ud) { +#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) + ud->hatEffects.clear(); +#endif + } + map_deliddb(bl); @@ -3656,6 +3663,39 @@ int unit_free(struct block_list *bl, clr_type clrtype) return 0; } + +void unit_hateffect(struct block_list* bl, int16 effectID, bool enable, bool send) +{ + struct unit_data* ud; + map_session_data* sd; + + if (!bl || !(ud = unit_bl2ud(bl))) + return; + + sd = BL_CAST(BL_PC, bl); + auto it = util::vector_get(ud->hatEffects, effectID); + + if (enable) { + if (it != ud->hatEffects.end()) { + return; + } + + ud->hatEffects.push_back(effectID); + } + else { + if (it == ud->hatEffects.end()) { + return; + } + + util::vector_erase_if_exists(ud->hatEffects, effectID); + } + + if (send || !enable) { + clif_hat_effect_single(bl, effectID, enable); + } +} + + static TIMER_FUNC(unit_shadowscar_timer) { block_list *bl = map_id2bl(id); diff --git a/src/map/unit.hpp b/src/map/unit.hpp index cfd932615..0964d7438 100644 --- a/src/map/unit.hpp +++ b/src/map/unit.hpp @@ -65,6 +65,9 @@ struct unit_data { int32 group_id; std::vector<int> shadow_scar_timer; +#if PACKETVER_MAIN_NUM >= 20150507 || PACKETVER_RE_NUM >= 20150429 || defined(PACKETVER_ZERO) + std::vector<int16> hatEffects; +#endif }; struct view_data { @@ -115,6 +118,7 @@ bool unit_run(struct block_list *bl, map_session_data *sd, enum sc_type type); int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir); TIMER_FUNC(unit_delay_walktoxy_timer); TIMER_FUNC(unit_delay_walktobl_timer); +void unit_hateffect(struct block_list* bl, int16 effectID, bool enable, bool send); // Causes the target object to stop moving. int unit_stop_walking(struct block_list *bl,int type); You'll be able to use hat effects on NPCs as well. Goodluck. Edit: Updated diff to fix an error with the script function. hateffects.diff
    1 point
  5. 3755 downloads

    This is just a compilation of aura's I've had for quite a few years. I figured since you don't really see many aura's anymore I'd upload all of them from old projects I used to have. IDK who owns all of these so if anyone can look through them and maybe shoot me a pm I'll be able to change this post to give credit where due.
    Free
    1 point
×
×
  • Create New...