Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/26/20 in all areas

  1. Happy Thanksgiving everyone. Since I couldn't get the turkey, I thought I would bring this instead. Without further ado, Let me introduce... WARP (Windows Application Revamp Package) Why this name? Because I like using acronyms and this name sounded apt. Plus it's the function & features that matter more. And no, I am not gonna change the name. Why not just fix up NEMO? The codebase for NEMO is pretty much ancient at this point. So rather than fixing it up, I decided to go the route of creating it fresh from scratch. The end result is a far superior product. OK, but what if you end up AFRO (Away From RO)again? Well, I can't promise that I will be around forever. However, this time around, I am releasing the source code for the tool as well. So, exactly what has changed? Well, quite a few things. Let's start off with how the GUI looks now. As you can see, the GUI is much more modern and aesthetically pleasing thanks to @Haziel & @Hadrias . The package comes with 3 tools - Console version (for simple patching), Main GUI, and Tester GUI (for batch testing). A big salute to @4144 for keeping NEMO alive while I was AFRO ?. Ok, jokes aside, I discussed with him about the changes he made and I have incorporated almost all of them but with some differences. Language & Styles are now on the bottom as you can see. All the remaining menus have now been shifted to drawers (moving side panels). To reveal them you can either swipe from the respective edge or click the button at the top. The right side drawer houses all the Extensions (Used to be called 'Addons' in NEMO). They are now loaded independently of the client. This avoids unnecessary redefinitions and now you can also use Extensions for activities that don't need a loaded client. All the common functions have been added to the 'Quick Actions' group and all the remaining ones are in the left drawer, which is not many. If you have suggestions for more features let me know. Moving on to the Back end (This is of no use to the regular user. So you can skip this part if you want) It was high time for us to have a proper input file format. Enter YAML. Love it or hate it but it's here to stay. Frankly, I like it more than libconfig and INI. You would be seeing YAML being used for almost every file in WARP. This includes input files for Patches & Extensions, Files defining those two, Session files, etc. Writing patches is far more flexible now. Say goodbye to PTYPE_HEX and \xAB. Now we can do wild card searches with the actual wild cards inside hex codes. Of course, we still need to have some well-defined characters for that. Currently, we have 2 forms of wildcards - Nibble wise - For e.g. => A? , ?? , ?3 Bit wise - For e.g. => [1.0...01] If you have any suggestions about it let me know. Speaking of writing hex code, I have provided functions looking almost identical to Assembly instructions for generating their equivalent hex code. This helps in making the hex code more human-readable and adds a little more flexibility. User inputs have a few more types and little more flexibility in specifying constraints now. Scripts have proper segregation now. Please follow them when adding your own. Only the scripts inside the 'Init' folder gets reloaded each time the client is loaded. This avoids unnecessary reloads. exe has now become 'Exe'. But in addition to this, you get 2 more objects - System (for filesystem activities) & Warp (whatever is outside the scope of the other two) Many of the functions used for retrieving some constant information in the 'Exe' have become properties now. For e.g. PEoffset, ImageBase, BuildDate, etc. During patching, the Diff section is only added if you have inserted any code using one of the 'Add' functions. Also, the Diff section now grows dynamically as per requirement (in increments of Section Alignment of course). In addition to the Patched Exe, The tool also generates an (Extra Patch Info) file with the suffix '.epi'. It holds just enough info for the tool to recognize existing patches in an exe from a previous patch session. So how is it useful? Let's say you have a patched client and its EPI file. But you don't have the original anymore. Now you can remove 1 or 2 patches and keep the rest OR even restore the original from the patched exe. Last, but not least, I am providing documentation about everything including the API. But bear with me for a bit, as I am still working on the documentation part. I probably forgot more points to add here, but I think this pretty much covers the important stuff. Anyways you can read in detail at the Wiki Is it ready to be used now? The tool is definitely ready. I have added most of the patches but not all just yet. But I was not able to test all the patches in-game. So please don't attack me if something failed. I would appreciate a Bug Request in Github instead. You can also come to Discord as well, if you prefer that. Also note, that some patches are still failing for new clients, and some failing for old ones. However, I saw the same behavior in NEMO, so that would be part of the next stage of operations - Updating Patch scripts. So, where do I get it from? https://github.com/Neo-Mind/WARP How to use it? There is a User Guide in the git repo (best viewed from Github itself). Everyone is used to NEMO by now, so it shouldn't be difficult to use this even without the guide. Plus the Github wiki is pretty detailed. Any last words before we close this? Just like in the case of NEMO, my intention with WARP is to create a common tool for patching without being restricted to RO or which OS you use it in. For this reason, you will be seeing multiple branches in the Git repo. If you are planning to use WARP for patching some other application, Create a branch using the 'win32' branch as a starting point That's about it from me for now.
    1 point
  2. As opposed to my previous thread made here, this one will have scripts I share with the community. I'll be adding more as time goes by, but I intend to share quite a bit. :] Do whatever you want with these, just don't claim them as your own or sell them of course. And if you could add credits to them that'd be great as well! If at least on your Features page or on the announcement when the script is added to your server. Enjoy! 1. Countdown Mini-Game (Cross-Post from Summer Festival Collection): //===== rAthena Script ======================================= //= Countdown Mini-Game Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ summer01,124,121,6 script Countdown#summ 904,{ if ( .start == 0 ) { .@n$ = "[ ^FF0000Countdown^000000 ]"; mes .@n$; mes "In order to win, you must click me after counting down to 0."; mes "Cost of participation is ^3355FF2 Festival Coins^000000"; mes "If you win, I'll give you ^3355FF35 Coins^000000"; @novacountdown = 0; deltimer "Countdown#summ::OnCountdown"; next; switch(select("Play Countdown:Leave")){ case 1: if (@NovaCount > gettimetick(2)) { .@t = @NovaCount - gettimetick(2); dispbottom "Countdown: You must wait "+.@t+" seconds before playing again."; end; } if (.start == 1) { dispbottom "Countdown: Somebody is already playing. Wait for them to finish."; end; } if(countitem(6767) < 2) { mes .@n$; mes "You don't have enough coins."; end; } initnpctimer; delitem 6767,2; @NovaCount = gettimetick(2) + 60; .start = 1; close2; .player$ = strcharinfo(0); .@timer = rand(8,11); .@r = rand(600,1000); .@timer1 = .@timer*.@r; .@timer2 = .@timer1+.@r; emotion 27; showscript "Countdown: "+.player$+"! Count in your head, and click me again when the timer reaches 0.",.gid$; dispbottom "Countdown: Count in your head, and click me on the NPC again when the timer reaches 0."; sleep2 5000; addtimer .@timer1,"Countdown#summ::OnCountdown"; addtimer .@timer2,"Countdown#summ::OnCountdown2"; .@time$ = .@timer; showscript .@time$,.gid$; sleep2 .@r; .@time$ = .@timer-1; showscript .@time$,.gid$; sleep2 .@r; .@time$ = .@timer-2; showscript .@time$,.gid$; end; case 2: end; } end; } if ( .start == 1 && .player$ == strcharinfo(0) ) { if (@novacountdown == 0) { showscript "Countdown: You went too quickly. You lose.",.gid$; .start = 0; @NovaCount = gettimetick(2) + 30; stopnpctimer; end; } if (@novacountdown == 1) { showscript "Countdown: Nice one. You win this time "+.player$+".",.gid$; .start = 0; getitem 6767,35; @NovaCount = gettimetick(2) + 30; stopnpctimer; end; } if (@novacountdown == 2) { showscript "Countdown: You went too slowly. You lose.",.gid$; .start = 0; @NovaCount = gettimetick(2) + 30; stopnpctimer; end; } end; } else { dispbottom "Somebody is already playing Countdown. Wait for them to finish."; end; } OnInit: .gid$ = getnpcid(0); end; OnCountdown: @novacountdown = 1; end; OnCountdown2: @novacountdown = 2; end; OnTimer30000: stopnpctimer; showscript "Countdown: You went too slowly. You lose.",.gid$; .start = 0; end; } 2. Character Deletion on Death: //===== rAthena Script ======================================= //= Character Deletion on Death Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ - script PERMANENTDEATH -1,{ end; OnPCDieEvent: set .@deadplayer,getcharid(0); message strcharinfo(0),"Game Over"; atcommand "@kick "+strcharinfo(0); set .@j, getarraysize( .char_delete$ ); for (.@i = 0; .@i < .@j; .@i++) { query_sql("DELETE FROM `"+ .char_delete$[.@i] +"` WHERE `char_id` = '"+ .@deadplayer +"'"); } query_sql "DELETE FROM `party` WHERE `leader_char` = '"+.@deadplayer+"'"; end; OnInit: setarray .char_delete$[0],"bonus_script","char","cart_inventory","elemental","friends","global_reg_value","guild","guild_member","homunculus","hotkey","inventory","memo","mercenary","mercenary_owner","pet","quest","sc_data","skill","skillcooldown"; end; } 3. Instance Based Dead Branch Room: //===== rAthena Script ======================================= //= Dead Branch Room Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ npc_in,9,103,6 script Branch Manager 89,{ .@n$ = "[^3355FF Branch Manager ^000000]"; .@party_id = getcharid(1); .@p_name$ = getpartyname(.@party_id); .@instance$ = "Dead Branch Room"; if (getcharid(0) == getpartyleader(.@party_id,2)) { mes .@n$; mes "Would you like to reserve a private Dead Branch Room? It'll cost 100K for two full hours."; mes "Remember, the room and everything inside it will disappear after this time frame."; next; switch(select("Rent Dead Branch Room:Enter the Room:Cancel")) { case 1: if (Zeny < 100000) { mes .@n$; mes "Are you trying to sneak in without paying? You must bring me 100,000 Zeny if you wish to rent a room."; cutin "",255; end; } if (instance_create(.@instance$) < 0) { mes "Party Name: "+.@p_name$; mes "Party Leader: "+strcharinfo(0); mes "^0000ff"+.@instance$+" ^000000- Reservation Failed!"; close; } Zeny -= 100000; mes .@n$; mes "Talk to me again to enter the room now that your room has been reserved."; close; case 2: callsub L_Enter,0,1; case 3: mes .@n$; mes "Have a nice day then, and enjoy Dead Branching in Juperos."; close; } } mes .@n$; mes "You may enter a Dead Branch Room if it's been reserved by your party leader."; next; switch(select("Enter the Dead Branch Room:Cancel")) { case 1: callsub L_Enter,1,1; case 2: mes .@n$; mes "Have a nice day then, and enjoy Dead Branching in Juperos."; end; } L_Enter: switch(instance_enter("Dead Branch Room")) { case 3: mes .@n$; mes "You are not in a party."; close; case 2: mes .@n$; mes "The private Dead Branch Room has not yet been reserved."; mes "The party leader did not pay the fee."; close; case 1: mes .@n$; mes "You can enter the room after making a party."; close; case 0: mapannounce "npc_in", strcharinfo(0)+" of the party, "+.@p_name$+", is entering a Dead Branch Room.",bc_map,"0x00ff99",FW_NORMAL,12; end; } } //================================================================================== //--------|Map Flags|--------------------------------------------------------------- //================================================================================== pvp_n_1-3 mapflag monster_noteleport pvp_n_1-3 mapflag nowarpto pvp_n_1-3 mapflag nomemo pvp_n_1-3 mapflag noteleport pvp_n_1-3 mapflag nosave SavePoint pvp_n_1-3 mapflag nopenalty Make sure you add the following line to your instance_db 16,Dead Branch Room,7200,pvp_n_1-3,99,95,pvp_n_1-3 Feel free to change the number to whatever is appropriate in your server. You'll likely also need to unset the PvP mapflags from that map, or move it to a different map, and feel free to add the following to the map according to what you want for your server: MvP Summoner, Healer, Kafra, Dead Branch Seller. 4. In-game Item Descriptions:​ //===== rAthena Script ======================================= //= In-game Item Descriptions Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ - script itemdescs -1,{ end; OnInit: bindatcmd "ii2",strnpcinfo(3)+"::OnAtcommand"; bindatcmd "itemdesc",strnpcinfo(3)+"::OnAtcommand"; end; OnAtcommand: mes "^3355FF[ Item Description Search ]^000000"; .@item = atoi(.@atcmd_parameters$[0]); mes "<ITEMLINK>"+getitemname(.@item)+"<INFO>"+.@item+"</INFO></ITEMLINK>"; mes "Click on the name of the item above."; end; } 5. Dismounter:​ npc_in,50,110,3 script Dismounter 105,{ mes "[ Dismounter ]"; mes "It seems you're stuck on your mount! I'll make that thing run away for you."; next; switch(select("Please! I can't get rid of it.:No! I want to keep my mount.")) { case 1: mes "[ Dismounter ]"; mes "OOGA BOOGA!"; if(SC_ALL_RIDING>=1) { sc_start SC_ALL_RIDING,1,0; } mes "- Your mount has ran away -"; end; case 2: mes "[ Dismounter ]"; mes "Keep your mount for all I care!"; end; } } If you rent a Halter Lead/Reins of Mount, sometimes they'll expire and leave your players stuck on them. This NPC gives them the option to dismount without the reins. 6. Level Up Function:​ - script LevelUpQuotes -1,{ end; OnInit: setarray .q$,"I have advanced forward!","There's no stopping me now!","Look at me go!","There's more where that came from.","This isn't even my final form!"; .num1 = getarraysize(.q$); setarray .maxq$,"I've made it!","I never thought I'd become this strong...","I have reached my final form."; .num2 = getarraysize(.maxq$); end; OnPCBaseLvUpEvent: if( BaseLevel > 149 && getstatus(SC_ITEMBOOST) == 0 ) { sc_start SC_ITEMBOOST,180000,200; } if( BaseLevel == 175 ) { .@r = rand(.num2); showscript strcharinfo(0)+" : "+.maxq$[.@r]; } else { .@r = rand(.num1); showscript strcharinfo(0)+" : "+.q$[.@r]; } if( getstatus(SC_INCREASEAGI) != 1 ) { sc_start SC_INCREASEAGI,30000,10; } end; } This one displays one of several quotes when a player levels up on top of their head. I removed the quotes but you can use your own, I have around 30 on my server. (Just replace Quote 1-3 and add as many as you'd like) It also gives the player 30 seconds of level 10 INC agi, and if the player is 150 or higher, 3 minutes of Bubble Gum effect. 7. Dice Hack: - script dicehack -1,{ end; OnInit: bindatcmd "dice",strnpcinfo(3)+"::OnAtcommand"; end; OnAtcommand: if (getgroupid() < 10) { end; } .@dice = atoi(.@atcmd_parameters$[0]); .@dice += 57; emotion .@dice,1; end; } This one's a silly one. It lets your GMs use @dice 1 to @dice 6 to cheat at dice. It's fun. :] 8. The Claw: //===== rAthena Script ======================================= //= The Claw Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ moc_para01,13,25,6 script The Claw 562,{ set .@n$,"[ ^FF0000The Claw^000000 ]"; mes .@n$; mes "Instructions:"; mes "You may pay 250 coins for a random headgear, or 500 to pick a specific headgear."; mes "New hats will be in stock every month."; next; switch(select("Random Hat",""+.hat1$+"",""+.hat2$+"",""+.hat3$+"",""+.hat4$+"")) { case 1: mes .@n$; mes "Are you sure you want a random hat for 250 Gold Coins?"; next; switch(select("Yes","No")) { case 1: if (countitem(671)) < (500) { mes .@n$,"You do not have enough Gold Coins to operate The Claw."; close; } if (checkweight(.@pickedhat,1) == 0 ) { mes .@n$,"The Claw detects you are over your weight limit."; close; } set .HatRandomArray,rand(1,4); delitem 671,250; if(.HatRandomArray==1) { getitem .hatid1,1; } if(.HatRandomArray==2) { getitem .hatid2,1; } if(.HatRandomArray==3) { getitem .hatid3,1; } if(.HatRandomArray==4) { getitem .hatid4,1; } mes .@n$; mes "The Claw has chosen. Here is your hat."; close; case 2: mes .@n$; mes "Come back and play again!"; close; } end; case 2: .@pickedhat = .hatid1; .@pickedname$ = .hat1$; break; case 3: .@pickedhat = .hatid2; .@pickedname$ = .hat2$; break; case 4: .@pickedhat = .hatid3; .@pickedname$ = .hat3$; break; case 5: .@pickedhat = .hatid4; .@pickedname$ = .hat4$; break; } mes .@n$; mes "Are you sure you want to buy: "; mes "<ITEMLINK>"+.@pickedname$+"<INFO>"+.@pickedhat+"</INFO></ITEMLINK> ?"; next; switch(select("Buy for 500 Gold Coins","Cancel")) { case 1: if (countitem(671)) < (500) { mes .@n$,"You do not have enough Gold Coins to operate The Claw."; close; } if (checkweight(.@pickedhat,1) == 0 ) { mes .@n$,"The Claw detects you are over your weight limit."; close; } delitem 671,500; getitem .@pickedhat,1; mes .@n$; mes "The Claw has retrieved your "+.@pickedname$+". Enjoy it."; close; case 2: mes .@n$; mes "Come back and play again!"; close; } OnInit: .hatid1 = 5474; .hatid2 = 5102; .hatid3 = 18678; .hatid4 = 5793; .hat1$ = getitemname(.hatid1); .hat2$ = getitemname(.hatid2); .hat3$ = getitemname(.hatid3); .hat4$ = getitemname(.hatid4); end; } Just change the IDs of the hats you want to rotate in for the month at the bottom, and change the Gold Coin text as well as the ID to whatever item you wish. 9. Search iRO Wiki/RMS Script (In-Game Browser): //===== rAthena Script ======================================= //= Search iRO Wiki/RMS Script (In-Game Browser) //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ - script NovaSearch -1,{ end; OnInit: bindatcmd "rms",strnpcinfo(3)+"::OnAtcommand"; bindatcmd "irowiki",strnpcinfo(3)+"::OnAtcommand"; bindatcmd "search",strnpcinfo(3)+"::OnAtcommand"; .n$ = "^3355FF[ Search Engine ]^000000"; end; OnAtcommand: mes .n$; mes "Note that some information on RMS and iRO wiki might be outdated or inaccurate."; mes "Take your search results with a grain of salt!"; next; switch(select("RMS Monster Search:RMS Item Search:iRO Wiki Search:Close")){ case 1: input .@search$; mes .n$; mes "<URL>Click here to open the browser!<INFO>http://ratemyserver.net/index.php?all_mob_select=%23&mob_id=&mob_name="+.@search$+"&element=-1&race=-1&size=-1&mlvsn=0&mlv=&mlv2=&bxpsn=0&exp=&exp2=&jxpsn=0&jexp=&jexp2=&flee=&dr=95&hit=&hr=100&rgc=0&immu=0&mvp=0&minib=0&aggr=0&assi=0&sense=0&det=0&natk=0&immo=0&chcha=0&loot=0&chtar=0&plt=0&sort_r=0&sort_o=0&page=re_mob_db&f=1&mob_search=Search,1000,1000</INFO></URL>"; close; case 2: input .@search$; mes .n$; mes "<URL>Click here to open the browser!<INFO>http://ratemyserver.net/index.php?page=re_item_db&item_id=&iname="+.@search$+"&itype=-1&islot_sign=-1&islot=-1&ij%5B+%5D=-1&iju=-1&idesc=&iscript=&i_ele=-1&i_status=-1&i_race=-1&i_bonus=-1&icfix=&sort_r=0&sort_o=0&isearch=Search,1000,1000</INFO></URL>"; close; case 3: input .@search$; mes .n$; mes "<URL>Click here to open the browser!<INFO>http://irowiki.org/w/index.php?search="+.@search$+",1000,1000</INFO></URL>"; close; case 4: end; } end; } This one's pretty simple but neat as well. It allows opening iRO wiki and RMS with searches on the in-game browser. 10. Crystal Chaos Mini-Game //===== rAthena Script ======================================= //= Crystal Chaos Mini-Game Script //===== By: ================================================== //= Nova http://www.novaragnarok.com //============================================================ prontera,152,175,6 script Crystal Chaos#summ 762,{ .@n$ = "[ ^FF0000Crystal Chaos^000000 ]"; mes .@n$; mes "You must think you have good eyes."; mes "When the shadow stops moving, select which shadow you think it stopped on."; mes "Playing costs ^3355FF"+.costqty+"x "+getitemname(.costid)+"^000000. If you win, you will get ^3355FF"+.rewardqty+"x "+getitemname(.rewardid)+"^000000."; next; switch(select("Play Crystal Chaos:Leave")){ case 1: if(.start == 0) { if (@NovaCrystal > gettimetick(2)) { .@t = @NovaCrystal - gettimetick(2); dispbottom "Crystal Chaos: You must wait "+.@t+" seconds before playing Crystal Chaos again."; end; } if(countitem(.costid) < .costqty) { mes .@n$; mes "You don't have enough "+getitemname(.rewardid)+"."; end; } delitem .costid,.costqty; @NovaCrystal = gettimetick(2) + 60; .start = 1; initnpctimer; mes .@n$; mes "Press next to start the game."; mes "Pay close attention to the Crystal's shadow,"; mes "When the shadow stops moving, select which shadow you think it stopped on."; next; mes .@n$; mes "- Round 1 -"; donpcevent "Crystal#summshufreal::OnRound1"; donpcevent "Crystal#summshufreal::OnEnable"; mes "Which Crystal did the shadow stop on?"; next; .@choice = .x[select("Left Crystal:Middle Crystal:Right Crystal") - 1]; if(getvariableofnpc(.shadow, "Crystal#summshufreal") != .@choice ) { showscript "You lose",.pchaos$; .start = 0; @NovaCrystal = gettimetick(2) + 60; end; } mes .@n$; mes "Congratulations, now for round 2!"; showscript "Round 2",.pchaos$; next; mes .@n$; mes "- Round 2 -"; donpcevent "Crystal#summshufreal::OnRound2"; donpcevent "Crystal#summshufreal::OnEnable"; mes "Which Crystal did the shadow stop on?"; next; .@choice = .x[select("Left Crystal:Middle Crystal:Right Crystal") - 1]; if(getvariableofnpc(.shadow, "Crystal#summshufreal") != .@choice ) { showscript "You lose",.pchaos$; .start = 0; @NovaCrystal = gettimetick(2) + 60; end; } mes .@n$; mes "Congratulations, now for round 3!"; showscript "Round 3",.pchaos$; next; mes .@n$; mes "- Round 3 -"; donpcevent "Crystal#summshufreal::OnRound3"; donpcevent "Crystal#summshufreal::OnEnable"; mes "Which Crystal did the shadow stop on?"; next; .@choice = .x[select("Left Crystal:Middle Crystal:Right Crystal") - 1]; if(getvariableofnpc(.shadow, "Crystal#summshufreal") != .@choice ) { showscript "You lose",.pchaos$; .start = 0; @NovaCrystal = gettimetick(2) + 60; end; } mes .@n$; mes "Congratulations, now for the final round!"; showscript "Final Round!",.pchaos$; next; mes .@n$; mes "- Final Round -"; donpcevent "Crystal#summshufreal::OnRound4"; donpcevent "Crystal#summshufreal::OnEnable"; mes "Which Crystal did the shadow stop on?"; next; .@choice = .x[select("Left Crystal:Middle Crystal:Right Crystal") - 1]; if(getvariableofnpc(.shadow, "Crystal#summshufreal") != .@choice ) { showscript "You lose",.pchaos$; .start = 0; @NovaCrystal = gettimetick(2) + 60; end; } showscript "You win!",.pchaos$; getitem .rewardid,.rewardqty; .start = 0; @NovaCrystal = gettimetick(2) + 60; end; } else { mes .@n$; mes "Somebody is already playing Crystal Chaos! Please wait until they finish."; } end; case 2: mes .@n$; mes "Come back when you're ready to play."; end; } OnTimer60000: .start = 0; stopnpctimer; end; OnInit: .start = 0; .pchaos$ = getnpcid(0); //Configure the cost of playing as well as the reward. .costid = 6767; .costqty = 2; .rewardid = 6767; .rewardqty = 30; //Set the following array to be the X Coordinates of the 3 following NPCs setarray .x,158,156,154; end; } //Make sure these NPCs are spaced apart by 2 cells on the X axis. (104, 102, 100) //The Coordinates of the last Crystal should be the same as that of the middle one. //If you change the Y coordinate (174) Make sure you also change it below inside Crystal#summshufreal prontera,158,174,4 script Right Crystal#summshuf1 1914,{ end; } prontera,156,174,4 script Middle Crystal#summshuf2 1914,{ end; } prontera,154,174,4 script Left Crystal#summshuf3 1914,{ end; } prontera,156,174,4 script Crystal#summshufreal 1914,{ end; OnInit: npcspeed 20; //Set the following array to be the X Coordinate of the 3 previous NPCs (Same as above) setarray .x,158,156,154; disablenpc "Crystal#summshufreal"; .y = 174; //Set to be the Y coordinate of the previous NPCs end; OnEnable: enablenpc "Crystal#summshufreal"; .r1 = rand(0,2); movenpc "Crystal#summshufreal",.x[.r1],.y; sleep .round; for (.@i = 0; .@i < 15; .@i++){ .r2 = rand(0,2); while (.r2 == .r1) .r2 = rand(0,2); movenpc "Crystal#summshufreal",.x[.r2],.y; sleep .round; .r1 = rand(0,2); while (.r1 == .r2) .r1 = rand(0,2); movenpc "Crystal#summshufreal",.x[.r1],.y; .shadow = .x[.r1]; sleep .round; } disablenpc "Crystal#summshufreal"; end; // Speed Configuration, change at will. OnRound1: .round = 150; end; OnRound2: .round = 100; end; OnRound3: .round = 70; end; OnRound4: .round = 45; end; } This one's one of my favorites despite being pretty simple. Make sure you configure it properly! I'll be adding more scripts over time. Oh and make sure to relocate these as most are from custom maps.
    1 point
  3. // Heroes of Vanaheim ==================== //======================================== - script at_veil_cmd -1,{ OnVeilWarp: if(agitcheck() || agitcheck2() || agitcheck3()){ mes "you can't use this command while the WoE is running!"; end; } warp "veil",120,145; end; OnInit: bindatcmd "veil", strnpcinfo(0)+"::OnVeilWarp"; }
    1 point
  4. the solution was here https://github.com/llchrisll/ROenglishRE/blob/master/Client Support/Renewal/data 202008/msgstringtable.txt
    1 point
  5. Well. There's GitHub desktop which is very useful for beginners because of it's friendly interface.. Base on my experience there are only few commands on git bash that are not visible as interface in GitHub Desktop.. Although i mostly use git bash on my workstation. i also use github desktop to easily view the comparison of my changes.
    1 point
×
×
  • Create New...