Jump to content

AnnieRuru

Members
  • Posts

    2044
  • Joined

  • Last visited

  • Days Won

    51

Everything posted by AnnieRuru

  1. hmm ? this script was actually written in mind by having plugin installed ... however rathena members seems very interested in this script indeed you can just disable the min_npc_vendchat_distance from battle config just test on rAthena test server, couldn't reproduce your problem try start with only 2 elements in your array, then expend slowly by @reloadscript
  2. it just some lines to help debug the script just now Secret told me that Oboro has baby support, so I just add this line to test it yeah there are some lines meant to debug and shows the value in-game
  3. prontera,155,185,5 script kjsfksdfhj 100,{ getinventorylist; for ( .@i = 0; .@i < @inventorylist_count; ++.@i ) { if ( getiteminfo( @inventorylist_id[.@i], 2 ) == IT_CARD ) { .@name$ = getitemname( @inventorylist_id[.@i] ); if ( substr( .@name$, getstrlen(.@name$) -4, getstrlen(.@name$) -1 ) == "Card" ) { .@cardid[.@c] = @inventorylist_id[.@i]; .@amount[.@c] = @inventorylist_amount[.@i]; ++.@c; } } } for ( .@i = 0; .@i < .@c; ++.@i ) .@total += .@amount[.@i]; if ( .@total < 5 ) { mes "you don't have total of 5 cards"; close; } if ( Zeny < 100000 ) { mes "You don't have enough Zeny."; close; } for ( .@i = 0; .@i < .@c; ++.@i ) .@menu$ += .@amount[.@i] +"x "+ getitemname( .@cardid[.@i] ) +":"; .@menu$ += "[Done]"; while ( true ) { mes "Choose up to 5 cards"; for ( .@i = 0; .@i < .@choose_total; ++.@i ) mes .@choose_amount[.@i] +"x "+ getitemname( .@choose_cardid[.@i] ); next; .@s = select( .@menu$ ) -1; if ( .@s == .@c ) { .@total = 0; for ( .@i = 0; .@i < .@choose_total; ++.@i ) .@total += .@choose_amount[.@i]; if ( .@total != 5 ) { mes "you didn't choose total of 5 cards"; next; } else break; } else { mes "input the amount to roll"; if ( input( .@input, 0, .@amount[.@s] ) ) { mes "invalid amount"; next; } else { for ( .@i = 0; .@i < .@choose_total; ++.@i ) { if ( .@choose_cardid[.@i] == .@cardid[.@s] ) { deletearray .@choose_cardid[.@i], 1; deletearray .@choose_amount[.@i], 1; --.@i; --.@choose_total; break; } } if ( .@input ) { .@choose_cardid[.@choose_total] = .@cardid[.@s]; .@choose_amount[.@choose_total] = .@input; ++.@choose_total; } } } } mes "Are you sure you want to use"; for ( .@i = 0; .@i < .@choose_total; ++.@i ) mes .@choose_amount[.@i] +"x "+ getitemname( .@choose_cardid[.@i] ); mes "for a random card ?"; next; if ( select ( "Yes", "No" ) == 2 ) close; for ( .@i = 0; .@i < .@choose_total; ++.@i ) { if ( countitem( .@choose_cardid[.@i] ) < .@choose_amount[.@i] ) { mes "Don't try to cheat with me !!"; close; } } if ( Zeny < 100000 ) { mes "You don't have enough Zeny."; close; } if ( !checkweight( 1201, 1 ) ) { mes "You don't have enough space"; close; } for ( .@i = 0; .@i < .@choose_total; ++.@i ) delitem .@choose_cardid[.@i], .@choose_amount[.@i]; Zeny -= 100000; getitem .cardid[ rand( .card_total ) ], 1; close; OnInit: .card_total = query_sql( "select id from item_db_re where type = "+ IT_CARD +" and name_japanese like '%Card'", .cardid ); end; } I thought this is simple request, but ends up like writing a mini-mission board like script @wingsofloveza
  4. prontera,155,185,5 script kjsfksdfhj 100,{ .@eaj = eaclass(); dispbottom .@eaj +" 0x"+ sprintf( "%X", .@eaj ); if ( (.@eaj & EAJL_THIRD) || .@eaj == EAJ_KAGEROUOBORO || .@eaj == EAJ_REBELLION ) dispbottom "say one"; else if ( Upper == 1 && (.@eaj & EAJL_2) ) dispbottom "say two"; end; } prontera,158,185,5 script kjsfksdfhj2 100,{ jobchange Class, 2; }
  5. since when they have baby version ? I must be out from RO for very long time prontera,155,185,5 script kjsfksdfhj 100,{ .@eaj = eaclass(); dispbottom .@eaj +" 0x"+ sprintf( "%X", .@eaj ); if ( .@eaj & EAJL_THIRD || (.@eaj & EAJ_KAGEROUOBORO) == EAJ_KAGEROUOBORO || (.@eaj & EAJ_REBELLION) == EAJ_KAGEROUOBORO ) dispbottom "say yes"; end; } prontera,158,185,5 script kjsfksdfhj2 100,{ jobchange Class, 2; } EDIT: WAIT a moment .... topic start says only 3rd jobs .... means NO BABY I got tricked ? means the previous post answer is correct
  6. dispbottom MAPID_REBELLION +""; // return 0 dispbottom MAPID_KAGEROUOBORO +""; // return 0 prontera,155,185,5 script kjsfksdfhj 100,{ .@eaj = eaclass(); if ( .@eaj & EAJL_THIRD || .@eaj == EAJ_KAGEROUOBORO || .@eaj == EAJ_REBELLION ) dispbottom "say yes"; end; }
  7. yes doesn't seem so, Visual Studio throw this error on me 1>------ Build started: Project: map-server, Configuration: Debug Win32 ------ 1>atcommand.cpp 1>d:\ragnarok\rathena\src\custom\atcommand.inc(15): error C2084: function 'int atcommand_go(const int,map_session_data *,const char *,const char *)' already has a body 1>d:\ragnarok\rathena\src\map\atcommand.cpp(1862): note: see previous definition of 'atcommand_go' 1>Done building project "map-server.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 7 up-to-date, 0 skipped ==========
  8. I've finished that How to make your offline RO server in more than 5 days now its time to answer your questions You have to understand 2 things 1. Everyone in this community understand how .patch file works take a look in this topic ... https://rathena.org/board/topic/117978-duel-script_command/?do=findComment&amp;comment=356427 src/map/battle.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/map/battle.cpp b/src/map/battle.cpp index bd93370fb..8df9921fe 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -7643,6 +7643,13 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( (s_bl = battle_get_master(src)) == NULL ) s_bl = src; + if ( s_bl->type == BL_PC && t_bl->type == BL_PC ) { + struct map_session_data *sd = BL_CAST( BL_PC, s_bl ); + struct map_session_data *tsd = BL_CAST( BL_PC, t_bl ); + if ( sd->status.account_id == 2000000 && tsd->status.account_id == 2000001 || sd->status.account_id == 2000001 && tsd->status.account_id == 2000000 ) + return 1; + } + if ( s_bl->type == BL_PC ) { switch( t_bl->type ) { case BL_MOB: // Source => PC, Target => MOB this is a patch script, but I don't write like that, this is auto-generated by ToitoiseGit Let me show you how I did it 1. I know the answer is edit the battle_check_target function, so I find that function and insert those lines (forgive my Hello Kitty theme) https://github.com/AnnieRuru/customs/blob/master/server setup/patch_1.png 2. notice the rAthena folder turn from Green to Red, means I have edited the file. TortoiseGit -> Diff https://github.com/AnnieRuru/customs/blob/master/server setup/patch_2.png 3. Click save unified diff https://github.com/AnnieRuru/customs/blob/master/server setup/patch_3.png 4. Ctrl + A to select all, paste the code on the forum https://github.com/AnnieRuru/customs/blob/master/server setup/patch_4.png Process 2-4 took me less than 5 seconds, its much faster than upload the whole src folder and everyone is expected to understand the patch format even if they don't, they can also always use TortoiseGit to apply the patch 2. the server you downloaded are 6 months old the server you download has this change log -> Changelog: 07 July 2018 - updated all content inside the package to their actual versions. Also, changed exe to 20180530 one from 20170614, and also repacked game clients as well too. Fixed small minor reported issues. Download links updated (please use the client) which is about 6 months old ... a lot of stuffs and codes has change since then when the developer introduce new features, or fix other things, it also break some existing code there are no source code that will last forever, I have to keep update my scripts/plugin every time the community complaint its broken that's interesting ... can you make a patch file out from it ? I usually use TortoiseGit for it, never try before with Visual Studio Yes, you don't have to install VS2017 if you already have VS2013 installed unit_skilluse_id function with the target_id on SELF
  9. as far as I understand, Emistry has dropped support for his SQL type script however, my version which doesn't use SQL at all, I still can fix it if anyone reporting bugs
  10. there's also someone in discord currently asking me how to setup an offline server properly so I start a guide How to make your (offline) server in more than 5 hours once you learned how to use Git, you can create branch in your current project, and only push the commit into your fork repo that anyone can see then we can download it in the patch file format .... there's gonna be another topic for it I am quite sure there's a function call skill_check_condition_castbegin https://github.com/rathena/rathena/blob/818ff109f3eea1715dc1477795bd1094510a4de4/src/map/skill.hpp#L484 yes please, however you have to learn how to use Git, either TortoiseGit or Sourcetree I'm more familiar with TortoiseGit, as I can upload the screenshot for it anytime
  11. https://github.com/rathena/rathena/blob/818ff109f3eea1715dc1477795bd1094510a4de4/src/map/skill.hpp#L420 honestly you should consider release your current progress already even I am drooling now your current progress has already surpass this topic
  12. src/map/battle.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/map/battle.cpp b/src/map/battle.cpp index bd93370fb..8df9921fe 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -7643,6 +7643,13 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( (s_bl = battle_get_master(src)) == NULL ) s_bl = src; + if ( s_bl->type == BL_PC && t_bl->type == BL_PC ) { + struct map_session_data *sd = BL_CAST( BL_PC, s_bl ); + struct map_session_data *tsd = BL_CAST( BL_PC, t_bl ); + if ( sd->status.account_id == 2000000 && tsd->status.account_id == 2000001 || sd->status.account_id == 2000001 && tsd->status.account_id == 2000000 ) + return 1; + } + if ( s_bl->type == BL_PC ) { switch( t_bl->type ) { case BL_MOB: // Source => PC, Target => MOB And THIS is the MOTHER of all FACTION script src/map/battle.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/map/battle.cpp b/src/map/battle.cpp index bd93370fb..769d0fc98 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -7643,6 +7643,13 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( (s_bl = battle_get_master(src)) == NULL ) s_bl = src; + if ( s_bl->type == BL_PC && t_bl->type == BL_PC ) { + struct map_session_data *sd = BL_CAST( BL_PC, s_bl ); + struct map_session_data *tsd = BL_CAST( BL_PC, t_bl ); + if ( pc_readglobalreg( sd, add_str("faction") ) != pc_readglobalreg( tsd, add_str("faction") ) ) + return 1; + } + if ( s_bl->type == BL_PC ) { switch( t_bl->type ) { case BL_MOB: // Source => PC, Target => MOB prontera,155,185,5 script ksjfdhsk 1_F_MARIA,{ input faction; }
  13. use static timer - script fssaadasd FAKE_NPC,{ OnInit: .delay_spawn = 60; // 60 seconds .need_to_kill = 10; announce ( $last_moonlight_flower + .delay_spawn ) +" "+ gettimetick(2), 0; if ( $last_moonlight_flower + .delay_spawn > gettimetick(2) ) end; monster "guild_vs2", 0,0, "--ja--", 1814, .need_to_kill, strnpcinfo(0)+"::OnDead"; end; OnDead: ++.killed; if ( .killed < .need_to_kill ) end; .killed = 0; if ( $last_moonlight_flower + .delay_spawn > gettimetick(2) ) sleep ( $last_moonlight_flower + .delay_spawn - gettimetick(2) ) * 1000; $last_moonlight_flower = gettimetick(2); monster "guild_vs2", 0,0, "--ja--", 1814, .need_to_kill, strnpcinfo(0)+"::OnDead"; end; }
  14. seeing as you are newer member here, just want to give you some advice you should consider selling or releasing this modification to public you'll be amaze the project you are doing right now, there's some demand for it in the public
  15. 3 things done wrong here no, should use map_foreachinrange because the server's unitmove command can only move 14 space away, and 14 space is area_size https://github.com/rathena/rathena/blob/master/conf/battle/client.conf#L40-L41 so if there is no monster in sight, do a random move battle_check_range https://github.com/rathena/rathena/blob/master/src/map/battle.hpp#L122 wrong, its battle_check_target
  16. - script kjshfksh FAKE_NPC,{ OnInit: .some_random_number = rand(20000,100000); // huh ? why you can't decide on an actual number ? nvm, let the script generate a random number for you setarray .map$, "alb_ship","alb2trea","alberta","alberta_in","alde_dun01","alde_dun02","alde_dun03","alde_dun04","aldeba_in","aldebaran","anthell01","anthell02","arena_room","c_tower1","c_tower2","c_tower3","c_tower4","force_1-1","force_1-2","force_1-3","force_2-1","force_2-2","force_2-3","force_3-1","force_3-2","force_3-3","gef_dun00","gef_dun01","gef_dun02","gef_dun03","gef_fild00","gef_fild01","gef_fild02","gef_fild03","gef_fild04","gef_fild05","gef_fild06","gef_fild07","gef_fild08","gef_fild09","gef_fild10","gef_fild11","gef_fild12","gef_fild13","gef_fild14","gef_tower","geffen","geffen_in","gl_cas01","gl_cas02","gl_church","gl_chyard","gl_dun01","gl_dun02","gl_in01","gl_knt01","gl_knt02","gl_prison","gl_prison1","gl_sew01","gl_sew02","gl_sew03","gl_sew04","gl_step","glast_01","hunter_1-1","hunter_2-1","hunter_3-1","in_hunter","in_moc_16","in_orcs01","in_sphinx1","in_sphinx2","in_sphinx3","in_sphinx4","in_sphinx5","iz_dun00","iz_dun01","iz_dun02","iz_dun03","iz_dun04","job_sword1","izlu2dun","izlude","izlude_in","job_thief1","knight_1-1","knight_2-1","knight_3-1","mjo_dun01","mjo_dun02","mjo_dun03","mjolnir_01","mjolnir_02","mjolnir_03","mjolnir_04","mjolnir_05","mjolnir_06","mjolnir_07","mjolnir_08","mjolnir_09","mjolnir_10","mjolnir_11","mjolnir_12","moc_castle","moc_fild01","moc_fild02","moc_fild03","moc_fild04","moc_fild05","moc_fild06","moc_fild07","moc_fild08","moc_fild09","moc_fild10","moc_fild11","moc_fild12","moc_fild13","moc_fild14","moc_fild15","moc_fild16","moc_fild17","moc_fild18","moc_fild19","moc_pryd01","moc_pryd02","moc_pryd03","moc_pryd04","moc_pryd05","moc_pryd06","moc_prydb1","moc_ruins","monk_in","morocc","morocc_in","new_1-1","new_1-2","new_1-3","new_1-4","new_2-1","new_2-2","new_2-3","new_2-4","new_3-1","new_3-2","new_3-3","new_3-4","new_4-1","new_4-2","new_4-3","new_4-4","new_5-1","new_5-2","new_5-3","new_5-4","orcsdun01","orcsdun02","ordeal_1-1","ordeal_1-2","ordeal_2-1","ordeal_2-2","ordeal_3-1","ordeal_3-2","pay_arche","pay_dun00","pay_dun01","pay_dun02","pay_dun03","pay_dun04","pay_fild01","pay_fild02","pay_fild03","pay_fild04","pay_fild05","pay_fild06","pay_fild07","pay_fild08","pay_fild09","pay_fild10","pay_fild11","payon","payon_in01","payon_in02","priest_1-1","priest_2-1","priest_3-1","prontera","prt_are_in","prt_are01","pvp_room","prt_castle","prt_church","prt_fild00","prt_fild01","prt_fild02","prt_fild03","prt_fild04","prt_fild05","prt_fild06","prt_fild07","prt_fild08","prt_fild09","prt_fild10","prt_fild11","prt_in","prt_maze01","prt_maze02","prt_maze03","prt_monk","prt_sewb1","prt_sewb2","prt_sewb3","prt_sewb4","pvp_2vs2","pvp_c_room","pvp_n_1-1","pvp_n_1-2","pvp_n_1-3","pvp_n_1-4","pvp_n_1-5","pvp_n_2-1","pvp_n_2-2","pvp_n_2-3","pvp_n_2-4","pvp_n_2-5","pvp_n_3-1","pvp_n_3-2","pvp_n_3-3","pvp_n_3-4","pvp_n_3-5","pvp_n_4-1","pvp_n_4-2","pvp_n_4-3","pvp_n_4-4","pvp_n_4-5","pvp_n_5-1","pvp_n_5-2","pvp_n_5-3","pvp_n_5-4","pvp_n_5-5","pvp_n_6-1","pvp_n_6-2","pvp_n_6-3","pvp_n_6-4","pvp_n_6-5","pvp_n_7-1","pvp_n_7-2","pvp_n_7-3","pvp_n_7-4","pvp_n_7-5","pvp_n_8-1","pvp_n_8-2","pvp_n_8-3","pvp_n_8-4","pvp_n_8-5","pvp_n_room","pvp_y_1-1","pvp_y_1-2","pvp_y_1-3","pvp_y_1-4","pvp_y_1-5","pvp_y_2-1","pvp_y_2-2","pvp_y_2-3","pvp_y_2-4","pvp_y_2-5","pvp_y_3-1","pvp_y_3-2","pvp_y_3-3","pvp_y_3-4","pvp_y_3-5","pvp_y_4-1","pvp_y_4-2","pvp_y_4-3","pvp_y_4-4","pvp_y_4-5","pvp_y_5-1","pvp_y_5-2","pvp_y_5-3","pvp_y_5-4","pvp_y_5-5","pvp_y_6-1","pvp_y_6-2","pvp_y_6-3","pvp_y_6-4","pvp_y_6-5","pvp_y_7-1","pvp_y_7-2","pvp_y_7-3","pvp_y_7-4","pvp_y_7-5","pvp_y_8-1","pvp_y_8-2","pvp_y_8-3","pvp_y_8-4","pvp_y_8-5","pvp_y_room","sword_1-1","sword_2-1","sword_3-1","treasure01","treasure02","wizard_1-1","wizard_2-1","wizard_3-1","xmas","xmas_dun01","xmas_dun02","xmas_fild01","xmas_in","beach_dun","beach_dun2","beach_dun3","cmd_fild01","cmd_fild02","cmd_fild03","cmd_fild04","cmd_fild05","cmd_fild06","cmd_fild07","cmd_fild08","cmd_fild09","cmd_in01","cmd_in02","comodo","quiz_00","quiz_01","g_room1-1","g_room1-2","g_room1-3","g_room2","tur_dun01","tur_dun02","tur_dun03","tur_dun04","tur_dun05","tur_dun06","alde_gld","aldeg_cas01","aldeg_cas02","aldeg_cas03","aldeg_cas04","aldeg_cas05","gefg_cas01","gefg_cas02","gefg_cas03","gefg_cas04","gefg_cas05","gld_dun01","gld_dun02","gld_dun03","gld_dun04","guild_room","guild_vs1","guild_vs2","guild_vs3","guild_vs4","guild_vs5","guild_vs1-1","guild_vs1-2","guild_vs1-3","guild_vs1-4","guild_vs2-1","guild_vs2-2","job_hunte","job_knt","job_prist","job_wiz","pay_gld","payg_cas01","payg_cas02","payg_cas03","payg_cas04","payg_cas05","prt_gld","prtg_cas01","prtg_cas02","prtg_cas03","prtg_cas04","prtg_cas05","alde_alche","in_rogue","job_cru","job_duncer","job_monk","job_sage","mag_dun01","mag_dun02","monk_test","quiz_test","yuno","yuno_fild01","yuno_fild02","yuno_fild03","yuno_fild04","yuno_in01","yuno_in02","yuno_in03","yuno_in04","yuno_in05","ama_dun01","ama_dun02","ama_dun03","ama_fild01","ama_in01","ama_in02","ama_test","amatsu","gon_dun01","gon_dun02","gon_dun03","gon_fild01","gon_in","gon_test","gonryun","sec_in01","sec_in02","sec_pri","umbala","um_dun01","um_dun02","um_fild01","um_fild02","um_fild03","um_fild04","um_in","niflheim","nif_fild01","nif_fild02","nif_in","yggdrasil01","valkyrie","himinn","lou_in01","lou_in02","lou_dun03","lou_dun02","lou_dun01","lou_fild01","louyang","siege_test","n_castle","nguild_gef","nguild_prt","nguild_pay","nguild_alde","jawaii","jawaii_in","gefenia01","gefenia02","gefenia03","gefenia04","new_zone01","new_zone02","new_zone03","new_zone04","payon_in03","ayothaya","ayo_in01","ayo_in02","ayo_fild01","ayo_fild02","ayo_dun01","ayo_dun02","que_god01","que_god02","yuno_fild05","yuno_fild07","yuno_fild08","yuno_fild09","yuno_fild11","yuno_fild12","alde_tt02","turbo_n_1","turbo_n_4","turbo_n_8","turbo_n_16","turbo_e_4","turbo_e_8","turbo_e_16","turbo_room","airplane","airport","einbech","einbroch","ein_dun01","ein_dun02","ein_fild06","ein_fild07","ein_fild08","ein_fild09","ein_fild10","ein_in01","que_sign01","que_sign02","ein_fild03","ein_fild04","lhz_fild02","lhz_fild03","yuno_pre","lhz_fild01","lighthalzen","lhz_in01","lhz_in02","lhz_in03","lhz_que01","lhz_dun01","lhz_dun02","lhz_dun03","lhz_cube","juperos_01","juperos_02","jupe_area1","jupe_area2","jupe_core","jupe_ele","jupe_ele_r","jupe_gate","y_airport","lhz_airport","airplane_01","jupe_cave","quiz_02","hu_fild07","hu_fild05","hu_fild04","hu_fild01","yuno_fild06","job_soul","job_star","que_job01","que_job02","que_job03","abyss_01","abyss_02","abyss_03","thana_step","thana_boss","tha_scene01","tha_t01","tha_t02","tha_t03","tha_t04","tha_t07","tha_t05","tha_t06","tha_t08","tha_t09","tha_t10","tha_t11","tha_t12","auction_01","auction_02","hugel","hu_in01","que_bingo","que_hugel","p_track01","p_track02","odin_tem01","odin_tem02","odin_tem03","hu_fild02","hu_fild03","hu_fild06","ein_fild01","ein_fild02","ein_fild05","yuno_fild10","kh_kiehl02","kh_kiehl01","kh_dun02","kh_dun01","kh_mansion","kh_rossi","kh_school","kh_vila","force_map1","force_map2","force_map3","job_hunter","job_knight","job_priest","job_wizard","ve_in02","rachel","ra_in01","ra_fild01","ra_fild02","ra_fild03","ra_fild04","ra_fild05","ra_fild06","ra_fild07","ra_fild08","ra_fild09","ra_fild10","ra_fild11","ra_fild12","ra_fild13","ra_san01","ra_san02","ra_san03","ra_san04","ra_san05","ra_temin","ra_temple","ra_temsky","que_rachel","ice_dun01","ice_dun02","ice_dun03","ice_dun04","que_thor","thor_camp","thor_v01","thor_v02","thor_v03","veins","ve_in","ve_fild01","ve_fild02","ve_fild03","ve_fild04","ve_fild05","ve_fild06","ve_fild07","poring_c01","poring_c02","que_ng","nameless_i","nameless_n","nameless_in","abbey01","abbey02","abbey03","poring_w01","poring_w02","que_san04","moscovia","mosk_in","mosk_ship","mosk_fild01","mosk_fild02","mosk_dun01","mosk_dun02","mosk_dun03","mosk_que","force_4-1","force_5-1","06guild_r","06guild_01","06guild_02","06guild_03","06guild_04","06guild_05","06guild_06","06guild_07","06guild_08","z_agit","que_temsky","itemmall","bossnia_01","bossnia_02","bossnia_03","bossnia_04","schg_cas01","schg_cas02","schg_cas03","schg_cas04","schg_cas05","sch_gld","cave","moc_fild20","moc_fild21","moc_fild22","que_ba","que_moc_16","que_moon","arug_cas01","arug_cas02","arug_cas03","arug_cas04","arug_cas05","aru_gld","bat_room","bat_a01","bat_a02","bat_b01","bat_b02","que_qsch01","que_qsch02","que_qsch03","que_qsch04","que_qsch05","que_qaru01","que_qaru02","que_qaru03","que_qaru04","que_qaru05","1@cata","2@cata","e_tower","1@tower","2@tower","3@tower","4@tower","5@tower","6@tower","mid_camp","mid_campin","man_fild01","man_fild03","spl_fild02","spl_fild03","moc_fild22b","que_dan01","que_dan02","schg_que01","schg_dun01","arug_que01","arug_dun01","1@orcs","2@orcs","1@nyd","2@nyd","nyd_dun01","nyd_dun02","manuk","man_fild02","man_in01","splendide","spl_fild01","spl_in01","spl_in02","bat_c01","bat_c02","bat_c03","moc_para01","job3_arch01","job3_arch02","job3_arch03","job3_guil01","job3_guil02","job3_guil03","job3_rang01","job3_rang02","job3_rune01","job3_rune02","job3_rune03","job3_war01","job3_war02","jupe_core2","brasilis","bra_in01","bra_fild01","bra_dun01","bra_dun02","dicastes01","dicastes02","dic_in01","dic_fild01","dic_fild02","dic_dun01","dic_dun02","job3_gen01","s_atelier","job3_sha01","mora","bif_fild01","bif_fild02","1@mist","dewata","dew_in01","dew_fild01","dew_dun01","dew_dun02","que_house_s","malangdo","mal_in01","mal_in02","mal_dun01","1@pump","2@pump","1@cash","iz_dun05","evt_mobroom","alde_tt03","dic_dun03","1@lhz","lhz_dun04","que_lhz","evt_swar_b","evt_swar_r","evt_swar_s","evt_swar_t","gld2_ald","gld2_gef","gld2_pay","gld2_prt","gld_dun01_2","gld_dun02_2","gld_dun03_2","gld_dun04_2","malaya","job_ko","ma_scene01","1@ma_b","1@ma_c","1@ma_h","ma_in01","ma_dun01","ma_fild01","ma_fild02","ma_zif01","ma_zif02","ma_zif03","ma_zif04","ma_zif05","ma_zif06","ma_zif07","ma_zif08","ma_zif09","new_event","eclage","ecl_fild01","ecl_tdun01","ecl_tdun02","ecl_tdun03","ecl_tdun04","que_avan01","1@ecl","ecl_in01","ecl_in02","ecl_in03","ecl_in04","ecl_hub01","moc_prydn1","moc_prydn2","iz_ac01","iz_ac02","treasure_n1","treasure_n2","iz_int","iz_ng01","iz_int01","iz_int02","iz_int03","iz_int04","iz_ac01_a","iz_ac02_a","iz_ac01_b","iz_ac02_b","iz_ac01_c","iz_ac02_c","iz_ac01_d","iz_ac02_d","te_prtcas01","te_prtcas02","te_prtcas03","te_prtcas04","te_prtcas05","te_aldecas1","te_aldecas2","te_aldecas3","te_aldecas4","te_aldecas5","prt_fild08a","prt_fild08b","prt_fild08c","prt_fild08d","izlude_a","izlude_b","izlude_c","izlude_d","te_prt_gld","te_alde_gld","teg_dun01","teg_dun02","1@gl_k","2@gl_k","gl_chyard_","gl_cas02_","evt_bomb","1@def01","1@def02","1@def03","1@gef","1@face","1@sara","1@gef_in","dali","dali02","1@ge_st","1@spa","1@tnm1","1@tnm2","1@tnm3","1@dth1","1@dth2","1@dth3","1@eom","1@jtb","1@rev","1@xm_d","moro_cav","moro_vol","silk_lair","c_tower2_","c_tower3_","1@mcd","ver_eju","ver_tunn","verus03","verus04","job_gun","1@air1","1@air2","1@glast","lhz_dun_n","lhz_d_n2","1@gl_kh","2@gl_kh","1@lab","1@uns","un_bk_q","un_bunker","un_myst","verus01","verus02","paramk","1@infi","1@ffp","1@mir","2@mir","1@sthb","1@sthc","1@sthd","prt_cas","prt_cas_q","prt_prison","prt_lib","prt_lib_q","prt_q","prt_pri00","int_land","int_land01","int_land02","int_land03","int_land04","lasagna","lasa_fild01","lasa_fild02","lasa_dun01","lasa_dun02","lasa_dun03","conch_in","lasa_in01","lasa_dun_q","1@pop1","1@pop2","1@pop3","1@slw","1@swat","que_swat","slabw01","rebel_in","1@md_gef","1@md_pay","har_in01","harboro1","harboro2","rockmi1","rockmi2","rockrdg1","rockrdg2","1@gl_k2","2@gl_k2","1@xm_d2","pay_d03_i","gef_d01_i","ice_d03_i","1@tre","1@begi","tur_d03_i","tur_d04_i","1@crd","ordeal_a00","ordeal_a02","pprontera","niflxmas","sch_lab","nakhyang","lasa_sea","1@drdo","x_lhz","x_prt","x_ra","prt_evt_in","vis_h01","vis_h02","vis_h03","vis_h04","ein_d02_i","com_d02_i","1@soul","star_frst","star_in","2009rwc_01","2009rwc_02","2009rwc_03","2009rwc_04","2009rwc_05","2009rwc_06","2009rwc_07","2009rwc_08","2009rwc_f01","2012rwc_01","2012rwc_02","2012rwc_03","2012rwc_04","2012rwc_05","2012rwc_06","2012rwc_07","2012rwc_08"; // PS: I use Notepad++ Macro tools to generate this list from db/map_index.txt .map_size = getarraysize(.map$); end; OnNPCKillEvent: ++.total_monster_kills; if ( .total_monster_kills < .some_random_number ) end; announce "World boss PORING has arrived !! XD", bc_all; freeloop true; for ( .@i = 0; .@i < .map_size; ++.@i ) // summon in all maps, means loop every single map in the map_index.txt if ( getmapusers( .map$[.@i] ) != 1 ) monster .map$[.@i], 0,0, "WORLD BOSS", 1002, rand(10,20), ""; // the monster is name WORLD BOSS, and summon 10~20 of them // reset the counter, regenerate random number .some_random_number = rand(20000,100000); .total_monster_kills = 0; end; } yes this is a joke script that's why you have to be more specific on your request
  17. map_foreachinrange https://github.com/rathena/rathena/blob/master/src/map/map.hpp#L1005 map_foreachinmap check my getmemberaid plugin http://herc.ws/board/topic/4593-getmemberaid-checkmes/ or check the *getunits script command and actually this can be written entirely with just script commands without touching source code well up to you want to implement in C language or rathena script language ...
  18. wait, is that even possible on LIVE server ? shouldn't the cutin image will jumble when the client receive thousand of packets at once ? I know I can make a guitar hero script, but refuse to do so because I knew it's not going to work on real live server https://www.youtube.com/watch?v=XkzFxHSN4pw the latency issue is always there, always keep in mind there is always a 50~200 ms lag when playing on a live server keyworld also said the experience of playing his own guitar hero script in his own test server and playing it live on friend's server feels entirely different
  19. /* can only bet these item types - `IT_WEAPON`: 4 - `IT_ARMOR`: 5 - `IT_CARD`: 6 - `IT_PETEGG`: 7 - `IT_PETARMOR`: 8 */ prontera,155,185,5 script sfksfjhsfj 1_F_MARIA,{ if ( .start == 1 ) goto L_StartEvent; // goto is evil, but it actually helps make script higher readability else if ( .start == 2 ) { mes "Currently rolling dice ... please be patient"; close; } mes "select an item from your inventory to bet"; next; getinventorylist; for ( .@i = 0; .@i < @inventorylist_count; ++.@i ) { if ( @inventorylist_equip[.@i] == 0 && @inventorylist_identify[.@i] == true && @inventorylist_attribute[.@i] == false && @inventorylist_expire[.@i] == 0 && @inventorylist_bound[.@i] == BOUND_NONE && ( getiteminfo( @inventorylist_id[.@i], 2 ) == IT_WEAPON || getiteminfo( @inventorylist_id[.@i], 2 ) == IT_ARMOR || getiteminfo( @inventorylist_id[.@i], 2 ) == IT_CARD || getiteminfo( @inventorylist_id[.@i], 2 ) == IT_PETEGG || getiteminfo( @inventorylist_id[.@i], 2 ) == IT_PETARMOR ) ) { .@itemname$ = callfunc( "getitemname2", @inventorylist_id[.@i], @inventorylist_identify, @inventorylist_refine, @inventorylist_attribute, @inventorylist_card1, @inventorylist_card2, @inventorylist_card3, @inventorylist_card4 ); .@menu$ = .@menu$ + @itemname2_info$ + .@itemname$ +"; "+ @inventorylist_amount[.@i] +" ea.:"; .@id[.@c] = @inventorylist_id[.@i]; .@refine[.@c] = @inventorylist_refine[.@i]; .@card1[.@c] = @inventorylist_card1[.@i]; .@card2[.@c] = @inventorylist_card2[.@i]; .@card3[.@c] = @inventorylist_card3[.@i]; .@card4[.@c] = @inventorylist_card4[.@i]; ++.@c; } } if ( !.@c ) { mes "you don't have anything useful to bet !"; close; } .@s = select(.@menu$) -1; .@id = .@id[.@s]; .@refine = .@refine[.@s]; .@card1 = .@card1[.@s]; .@card2 = .@card2[.@s]; .@card3 = .@card3[.@s]; .@card4 = .@card4[.@s]; .@itemname$ = callfunc( "getitemname2", .@id, 1, .@refine, 0, .@card1, .@card2, .@card3, .@card4 ); mes "Are you sure you want to auction your"; mes .@itemname$ +" away ?"; next; if ( select( "Yes", "No" ) == 2 ) close; mes "select the amount of "+ getitemname( .currency ) +" for the player to bet"; next; if ( input( .@amount, 1, 30000 ) ) { mes "you have input invalid value"; close; } mes "Confirm ?"; mes .@itemname$; mes .@amount +"x "+ getitemname( .currency ); if ( select ( "Yes", "No" ) == 2 ) close; close2; if ( !countitem2( .@id, 1, .@refine, 0, .@card1, .@card2, .@card3, .@card4 ) ) { dispbottom "please don't hack"; end; } if ( .start != 0 ) { dispbottom "Too slow, somebody make it faster than you"; end; } announce strcharinfo(0) +" is trying to auction "+ .@itemname$ +" !!", bc_all; delitem2 .@id, 1, 1, .@refine, 0, .@card1, .@card2, .@card3, .@card4; .id = .@id; .refine = .@refine; .card1 = .@card1; .card2 = .@card2; .card3 = .@card3; .card4 = .@card4; .aid = getcharid(3); .cid = getcharid(0); .amount = .@amount; .itemname$ = .@itemname$; .start = true; initnpctimer; end; L_StartEvent: mes "Currently there are "+ .total_bet +" players betting."; for ( .@i = 0; .@i < .total_bet; ++.@i ) mes ( .@i +1 )+". "+ rid2name(.bet_aid[.@i]); next; if ( getcharid(3) == .aid ) { mes "You are the one who placed this bet"; close; } if ( .total_bet >= .register_limit ) { mes "only accept 10 maximum bets"; close; } .@i = 0; while ( .bet_aid[.@i] != getcharid(3) && .@i < .total_bet ) ++.@i; if ( .@i < .total_bet ) { mes "You already placed the bet"; close; } mes "Are you sure you want bet"; mes .amount +"x "+ getitemname( .currency ) +" for "; mes .itemname$ +" ?"; next; if ( select ( "Yes", "No" ) == 2 ) close; if ( countitem( .currency ) < .amount ) { mes "the minimum bet is "+ .amount +"x "+ getitemname( .currency ); close; } if ( .start != 1 ) { mes "Too late"; close; } delitem .currency, .amount; announce strcharinfo(0) +" has placed "+( ( Sex )? "his":"her" )+" bet for "+ .itemname$, bc_npc|bc_area; .bet_aid[.total_bet] = getcharid(3); .bet_cid[.total_bet] = getcharid(0); ++.total_bet; close; OnTimer15000: // 15 seconds stopnpctimer; .start = 2; announce "betting is now close. Start counting now", bc_npc|bc_area; sleep 1000; announce "There are "+ .total_bet +" players bet on "+ .itemname$, bc_npc|bc_area; sleep 1000; .@amount = 1; // this stupid mail system ... .@zeny = 0; .@give_amount = .amount * .total_bet; // why do I have to make these stupid variables ?? if ( !.total_bet ) { announce "this auction has failed because nobody is joining", bc_npc|bc_area; mail .cid, "Rolling in the Deep", "Prize", "Nobody bet on your item, you get a refund", .@zeny, .id, .@amount, .card1, .card2, .card3, .card4; } else { .@r = rand(.total_bet); announce "The winner is "+ rid2name(.bet_aid[.@r]) +" !!", bc_npc|bc_area; mail .bet_cid[.@r], "Rolling in the Deep", "Prize", "This is your prize.", .@zeny, .id, .@amount, .card1, .card2, .card3, .card4; mail .cid, "Rolling in the Deep", "Prize", "There were "+ .total_bet +" players bet on your item.", .@zeny, .currency, .@give_amount; } .start = false; .id = 0; .refine = 0; .card1 = 0; .card2 = 0; .card3 = 0; .card4 = 0; .aid = 0; .amount = 0; .itemname$ = ""; deletearray .bet_aid; deletearray .bet_cid; .total_bet = 0; end; OnInit: .currency = 7539; // Poring_Coin .register_limit = 10; // only 10 people can join end; } LOL when I saw n0ttt post came out I was like ... WAH~~ somebody can actually finish script faster than me @_@ EDIT: forgot to tell the getitemname2 function, not from this topic ... 2.3 but from hercules ones, 2.4 https://herc.ws/board/topic/11275-getitemname2/ rathena one is version 2.3 made on 2013 hercules has version 2.4 made on 2015 EDIT2: Radian say cannot bet equipped items, so just add @inventorylist_equip check
  20. yes, this script has a bug, good job on pointing this out this event can only ends when someone ACTUALLY play this event, the .RoundCount variable only increase when someone answer it right if nobody ever participate in this event, or players give up after 9 correct guess, the npc will continue non-stop instead of ending after 40 minutes, its better to make it stop at exactly 10 rounds (.Rounds), including wrong guesses or nobody actually playing it change the code under OnTimer30000: into something like this OnTimer30000: if (.Timer) end; set .Change,0; setnpcdisplay "Disguise Event",795; npctalk "Disguise Event : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; specialeffect EF_DETECT2; set $MonsterName$,""; deletepset 1; stopnpctimer; setnpctimer 0; set .RoundCount,.RoundCount+1; if (.RoundCount>=.Rounds) { setnpcdisplay "Disguise Event",795; set .RoundCount,0; set .Change,0; set .EventON,0; setnpctimer 0; stopnpctimer; npctalk "Disguise Event : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; end; } initnpctimer; end; honestly speaking ... the way euphy rewrite this script is still not very optimize ... if he actually learn to use sleep command, the script will be extremely clean ... I dislike using npc timers because of this reason
  21. - pointshop pvpshop 1_F_MARIA,#pvp_points, 501:100, 502:200 prontera,155,185,5 script kjshfksdfhj 1_F_MARIA,{ callshop "pvpshop", 1; end; OnPCKillEvent: ++#pvp_points; end; }
  22. lol... fixed 2 bugs for the script on that topic, although both are rare bug 1. if the player die purposely during the counting down [5],[4],[3],[2] ... the player is permanently stuck and can only recover by log out 2. there is still 1 player left in your team, and another team members logout, even though you are still alive but the script count as you lost that round that's why the more scripts I write, the more I get wiser XD bg_pvp_round.txt @leonardofan
  23. woot, just now @Radian also told me the same thing, now I have to double check you are right, somehow the permanent monster spawn script does let the *getmapunits script command catch the dead monsters as still being alive have to make Hp check this time // pre-re/mobs/fields/prontera.txt //================================================== // prt_fild07 - Prontera Field //================================================== prt_fild07,0,0 monster Rocker 1052,80 prt_fild07,0,0 monster Poporing 1031,30 prt_fild07,0,0 monster Vocal 1088,1,1800000,1200000 prt_fild07,225,110,5,5 monster Black Mushroom 1084,3,360000,180000 - script sdjflsdf -1,{ OnInit: bindatcmd "mapmoblist", strnpcinfo(0)+"::Onaaa"; end; Onaaa: if ( .@atcmd_numparameters ) { if ( getmapusers(.@atcmd_parameters$) == -1 ) { dispbottom "Map not exist"; end; } .@map$ = .@atcmd_parameters$; } else .@map$ = strcharinfo(3); .@size = getmapunits( BL_MOB, .@map$, .@bl ); freeloop true; for ( .@i = 0; .@i < .@size; ++.@i ) { .@string$ = rid2name(.@bl[.@i]); if ( !getd(".@"+ .@string$) ) { .@mobname$[.@c] = .@string$; getunitdata .@bl[.@i], .@unitdata; .@mobx[.@c] = .@unitdata[UMOB_X]; .@moby[.@c] = .@unitdata[UMOB_Y]; .@mobhp[.@c] = .@unitdata[UMOB_HP]; .@mobmaxhp[.@c] = .@unitdata[UMOB_MAXHP]; ++.@c; } setd ".@"+ .@string$, getd(".@"+ .@string$) +1; } dispbottom " === These are monsters in "+ .@map$ +" ==="; for ( .@i = 0; .@i < .@c; ++.@i ) if ( getd(".@"+ .@mobname$[.@i]) > 1 || .@mobhp[.@i] ) dispbottom ( ++.@j )+". "+ .@mobname$[.@i] +" : "+ getd(".@"+ .@mobname$[.@i])+"x"; if ( getgmlevel() < 99 ) end; // admin only access, lucky you mention it so I make extra checks dispbottom " === Location of unique monsters === "; for ( .@i = 0; .@i < .@c; ++.@i ) if ( getd(".@"+ .@mobname$[.@i]) == 1 && .@mobhp[.@i] ) dispbottom .@mobname$[.@i] +" --> X = "+ .@mobx[.@i] +" Y = "+ .@moby[.@i] +" | Hp left = "+ .@mobhp[.@i] +"/"+ .@mobmaxhp[.@i]; end; } then I have to take a look at the @whosell source code seriously =/ I was actually joking when I only use @whosell on the *searchstore script command hmm ... cash items means item type 18 ... means only look for items not IT_CASH type ... and I probably not going to do it, I think searchstore features is complete ... isn't it ?
  24. - script sdjflsdf -1,{ OnInit: bindatcmd "whosell", strnpcinfo(0)+"::Onbbb"; bindatcmd "mapmoblist", strnpcinfo(0)+"::Onaaa"; end; Onbbb: searchstores 999, 1; // yeah I'm so cheap XD end; Onaaa: if ( .@atcmd_numparameters ) { if ( getmapusers(.@atcmd_parameters$) == -1 ) { dispbottom "Map not exist"; end; } .@map$ = .@atcmd_parameters$; } else .@map$ = strcharinfo(3); .@size = getmapunits( BL_MOB, .@map$, .@bl ); freeloop true; for ( .@i = 0; .@i < .@size; ++.@i ) { .@string$ = rid2name(.@bl[.@i]); if ( !getd(".@"+ .@string$) ) .@mobname$[.@c++] = .@string$; setd ".@"+ .@string$, getd(".@"+ .@string$) +1; } dispbottom " === These are monsters in "+ .@map$ +" ==="; for ( .@i = 0; .@i < .@c; ++.@i ) dispbottom ( .@i +1 )+". "+ .@mobname$[.@i] +" : "+ getd(".@"+ .@mobname$[.@i])+"x"; end; }
  25. you are using older rathena version, this one should work // https://rathena.org/board/topic/117531-battleground-pvp-10-annieruru-help/ function script F_ShuffleNumbers { deletearray getarg(2); .@static = getarg(0); .@range = getarg(1) +1 - .@static; .@count = getarg(3, .@range); if (.@range <= 0 || .@count <= 0) return 0; if (.@count > .@range) .@count = .@range; for (.@i = 0; .@i < .@range; ++.@i) .@temparray[.@i] = .@i; for (.@i = 0; .@i < .@count; ++.@i) { .@rand = rand(.@range); set getelementofarray( getarg(2), .@i ), .@temparray[.@rand] + .@static; .@range--; .@temparray[.@rand] = .@temparray[.@range]; } return .@count; } prontera,155,185,5 script bg_pvp 1_F_MARIA,{ .minplayer2start = 1; // 1vs1 mes "bg_pvp"; if ( .start == true ) { mes "bg_pvp is on-going"; close; } while ( .aid[.@i] != getcharid(3) && .@i < .size ) { .@i++; } if ( .@i < .size ) { mes "You already join the queue."; close; } select "join"; mes "you have to stick to this map"; close2; .aid[ .size ] = getcharid(3); .size++; for ( .@i = 0; .@i < .size; .@i++ ) { if ( !isloggedin( .aid[.@i] ) ) { deletearray .aid[.@i], 1; .@i--; .size--; } else { attachrid .aid[.@i]; if ( strcharinfo(3) != strnpcinfo(4) ) { deletearray .aid[.@i], 1; .@i--; .size--; } } } detachrid; if ( .size < .minplayer2start *2 ) { announce .size +" players join", bc_npc | bc_area; end; } .start = true; .red = bg_create( "bat_c01",53,128, strnpcinfo(0)+"::OnRedQuit", strnpcinfo(0)+"::OnRedDead" ); .blue = bg_create( "bat_c01",146,56, strnpcinfo(0)+"::OnBlueQuit", strnpcinfo(0)+"::OnBlueDead" ); callfunc "F_ShuffleNumbers", 0, .size -1, .@r; for ( .@i = 0; .@i < .size; .@i++ ) { attachrid .aid[ .@r[.@i] ]; bg_join ( .@i % 2 )? .red : .blue; } detachrid; deletearray .aid; .size = 0; bg_warp .red, "bat_c03", 53,128; bg_warp .blue, "bat_c03", 146,56; sleep 30000; // Match Duration if ( !.winside ) mapannounce "bat_c03", "Battle end as time out", bc_map; else if ( .winside == .red ) { mapannounce "bat_c03", "- Red side Won the match !", bc_map; callsub L_reward, .red; } else if ( .winside == .blue ) { mapannounce "bat_c03", "- Blue side Won the match !", bc_map; callsub L_reward, .blue; } bg_destroy .red; bg_destroy .blue; mapwarp "bat_c03", "prontera",150,185; .start = .winside = false; end; L_reward: bg_get_data getarg(0), 1; for ( .@i = 0; .@i < $@arenamemberscount; .@i++ ) getitem 501,1, $@arenamembers[.@i]; return; OnRedQuit: callsub L_Quit, .red, .blue, "Red"; OnBlueQuit: callsub L_Quit, .blue, .red, "Blue"; L_Quit: if ( bg_get_data( getarg(0), 0 ) ) end; mapannounce "bat_c03", "All "+ getarg(2) +" team members has Quit!", bc_map; .winside = getarg(1); awake strnpcinfo(0); end; OnRedDead: callsub L_Dead, .red, .blue, "Red"; OnBlueDead: callsub L_Dead, .lue, .red, "Blue"; L_Dead: bg_leave; if ( bg_get_data( getarg(0), 0 ) ) end; mapannounce "bat_c03", "All "+ getarg(2) +" team members has killed!", bc_map; .winside = getarg(1); awake strnpcinfo(0); sleep2 1250; percentheal 100,100; end; } bat_c03 mapflag battleground bat_c03 mapflag nosave SavePoint bat_c03 mapflag nowarp bat_c03 mapflag nowarpto bat_c03 mapflag noteleport bat_c03 mapflag nomemo bat_c03 mapflag nopenalty bat_c03 mapflag nobranch bat_c03 mapflag noicewall I don't understand this sentence, but based on my past experience, most people would either asked for bg_pvp_round <--- just like the one in github, but instead end in 1 round, you have to fight multiple rounds, the team with win the most rounds wins bg_pvp_points <-- each team has 15 lives, the team that quickly lose 15 points first lose the match bg_pvp_leader <-- modification of bg_pvp_points, it just kill the leader earn extra points (somehow this script is the most popular one) btw, forget those scripts on these topic, the technique was too old and might not work on latest rathena. I just provide the link because I remember I did all those stuffs before and I usually always write a new one on request because I keep finding new techniques to write bg scripts =/
×
×
  • Create New...