Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/27/24 in all areas

  1. Work perfectly by copy externalsettings file from rdata.grf to myfile.grf, thx to 4144. Load Costum lua file instead of iteminfo*.lub is missing with 2021-11-17_Ragexe client.
    3 points
  2. //===== rAthena Script ======================================= //= saders All in one Random Option Script //= Free Script!!!! //===== By: ================================================== //= sader1992 //= https://sader1992.com/ //= https://rathena.org/board/profile/30766-sader1992/ //= https://sader1992.com/?page=item&item=54 //= For more , check out here > //= https://sader1992.com/?page=ra_services //= https://sader1992.com/?page=store //= https://rathena.org/board/profile/30766-sader1992/content/?type=downloads_file //===== Current Version: ===================================== //= 1.0 //===== Compatible With: ===================================== //= rAthena Project //https://rathena.org/board/files/file/4309-all-in-one-random-options-script/ //https://github.com/sader1992/sader_scripts //===== Update Log: ========================================= //= Version 1.0 Creating the script. //===== Description: ========================================= //= This is a Highly Custumizable random option script //= you can reuse the script by just creating a new file with different setting!. //= read and understand the settings. //============================================================ payon_in01,57,67,5 script Random Option 10434,{ disable_items; function rnd; switch(select("Insert Random Options:Allowed Items List")){ case 1: mes "You must equip the item to appear here!"; for(.@i=0;.@i<EQI_MAX;.@i++){ if(getequipisequiped(.@i)) { .@m1$ += (inarray(.item_list,getequipid(.@i)) != -1?"^11AD09":"^F73831") + F_getpositionname(.@i) + "-[" + getequipname(.@i) + "]^000000"; .@exist = true; } .@m1$ += ":"; } if(!.@exist){ mes "You have to equip the item you want to insert the random options into!."; end; } .@eq = select(.@m1$) -1; clear; .@id = getequipid(.@eq); if(inarray(.item_list,.@id) == -1){ mes "Sorry , I cannot deal with this item!"; end; } .@gid = .it[.@id]; if(!.@gid){ mes "Something went wrong!"; end; } if(!getequiprandomoption(.@eq,0,ROA_ID)){ .@zeny = .nz[.@gid]; .@cashpoint = .nk[.@gid]; .@costumpoint = .nc[.@gid]; copyarray(.@item,getd(".ni_" + .@gid),getarraysize(getd(".ni_" + .@gid))); copyarray(.@amount,getd(".na_" + .@gid),getarraysize(getd(".na_" + .@gid))); }else{ if(!.g_reroll[.@gid]){ mes "Sorry , i cannot reroll the random options in this item!"; end; } .@zeny = .rz[.@gid]; .@cashpoint = .rk[.@gid]; .@costumpoint = .rc[.@gid]; copyarray(.@item,getd(".ri_" + .@gid),getarraysize(getd(".ri_" + .@gid))); copyarray(.@amount,getd(".ra_" + .@gid),getarraysize(getd(".ra_" + .@gid))); } mes "Selected Item [" + getequipname(.@eq) + "]"; mes "==== Cost ===="; if(.@zeny) mes "Zeny: " + .@zeny; if(.@cashpoint) mes "CashPoint: " + .@cashpoint; if(.@costumpoint) mes .CustomPointsName$ + ": " + .@costumpoint; for(.@i=0;.@i<getarraysize(.@item);.@i++){ mes "(" + .@amount[.@i] + "pcs.) " + getitemname(.@item[.@i]) + " (" + .@item[.@i] + ")"; } if(!.KeepItemData){ mes "^E01E00You will loss all the refine and cards in the item if you continue.^000000"; } mes "Would you like to continue?"; if(select("Yes:No") == 2){ clear; mes "Ok, see you next time!"; end; } clear; if(Zeny < .@zeny){ mes "You don't have " + .@zeny + " Zeny"; .@close = true; } if(#CASHPOINTS < .@cashpoint){ mes "You don't have " + .@cashpoint + " CashPoints"; .@close = true; } if(getd(.CustomPointsVariable$) < .@costumpoint){ mes "You don't have " + .@costumpoint + " " + .CustomPointsName$; .@close = true; } for(.@i=0;.@i<getarraysize(.@item);.@i++){ if(countitem(.@item[.@i]) < .@amount[.@i]){ mes "You don't have (" + .@amount[.@i] + ") " + getitemname(.@item[.@i]); .@close = true; } } if(.@close) end; .@r = getequiprefinerycnt(.@eq); for(.@i=0;.@i<4;.@i++){ if(getequipcardid(.@eq,.@i)){ setd ".@c" + .@i,getequipcardid(.@eq,.@i); .@re[getarraysize(.@re)] = true; } } copyarray(.@opt_id,getd(".ro_id_" + .@gid + "_0"),getarraysize(getd(".ro_id_" + .@gid + "_0"))); copyarray(.@opt_mn,getd(".ro_mn_" + .@gid + "_0"),getarraysize(getd(".ro_mn_" + .@gid + "_0"))); copyarray(.@opt_mx,getd(".ro_mx_" + .@gid + "_0"),getarraysize(getd(".ro_mx_" + .@gid + "_0"))); for(.@i=1;.@i<6;.@i++){ copyarray(getd(".@opt_id" + .@i),getd(".ro_id_" + .@gid + "_" + .@i),getarraysize(getd(".ro_id_" + .@gid + "_" + .@i))); copyarray(getd(".@opt_mn" + .@i),getd(".ro_mn_" + .@gid + "_" + .@i),getarraysize(getd(".ro_mn_" + .@gid + "_" + .@i))); copyarray(getd(".@opt_mx" + .@i),getd(".ro_mx_" + .@gid + "_" + .@i),getarraysize(getd(".ro_mx_" + .@gid + "_" + .@i))); } for(.@i=1;.@i<6;.@i++){ if(rand(100) > getd(".s_" + .@i + "[" + .@gid + "]")) break; if(getd(".ro_id_" + .@gid + "_" + .@i)){ if(!getarraysize(getd(".@opt_id" + .@i))) break; .@ndx = rand(getarraysize(getd(".@opt_id" + .@i))); .@result_id = getd(".@opt_id" + .@i + "[" + .@ndx + "]"); .@result_vl = rnd(getd(".@opt_mn" + .@i + "[" + .@ndx + "]"),getd(".@opt_mx" + .@i + "[" + .@ndx + "]")); deletearray(getd(".@opt_id" + .@i + "[" + .@ndx + "]"),1); deletearray(getd(".@opt_mn" + .@i + "[" + .@ndx + "]"),1); deletearray(getd(".@opt_mx" + .@i + "[" + .@ndx + "]"),1); }else{ if(!.@opt_id) break; .@ndx = rand(getarraysize(.@opt_id)); .@result_id = .@opt_id[.@ndx]; .@result_vl = rnd(.@opt_mn[.@ndx],.@opt_mx[.@ndx]); if(!.g_reuse[.@gid]){ deletearray(.@opt_id[.@ndx],1); deletearray(.@opt_mn[.@ndx],1); deletearray(.@opt_mx[.@ndx],1); } } if(.ex[.@result_id]){ for(.@i2=0;.@i2<getarraysize(.@r_id);.@i2++){ if(.ex[.@result_id] == .ex[.@r_id[.@i2]]){ .@reject = true; } } } if(!.@reject){ .@s1 = getarraysize(.@r_id); .@r_id[.@s1] = .@result_id; .@r_v[.@s1] = .@result_vl; }else{ .@i--; .@failsafe++; if(.@failsafe > 50){ mes "Something went wrong , The server admin need to make sure that the config is done correctly!"; end; } } } if(Zeny < .@zeny) end; if(#CASHPOINTS < .@cashpoint) end; if(getd(.CustomPointsVariable$) < .@costumpoint) end; for(.@i=0;.@i<getarraysize(.@item);.@i++){ if(countitem(.@item[.@i]) < .@amount[.@i]){ end; } } // anti-hack if (callfunc("F_IsEquipIDHack", .@eq, .@id) || callfunc("F_IsEquipCardHack", .@eq, .@c0, .@c1, .@c2, .@c3)) { // anti-hack emotion ET_FRET; mes "Item Switch detected!"; end; } Zeny -= .@zeny; #CASHPOINTS-= .@cashpoint; setd(.CustomPointsVariable$,getd(.CustomPointsVariable$) - .@costumpoint); for(.@i=0;.@i<getarraysize(.@item);.@i++){ delitem(.@item[.@i],.@amount[.@i]); } if(!.@r_id){ specialeffect2 EF_REFINEOK; mes "Look Like you didn't get any random option, your luck is really bad!"; end; } delequip(.@eq); specialeffect2 EF_REFINEOK; if(.KeepItemData) getitem3(.@id,1,1,.@r,0,.@c0,.@c1,.@c2,.@c3,.@r_id,.@r_v,.@null); else getitem3(.@id,1,1,0,0,0,0,0,0,.@r_id,.@r_v,.@null); equip(.@id); mes "Done!"; end; case 2: mes "The list of the allowed items in this npc!"; for(.@i=0;.@i<getarraysize(.item_list);.@i++){ mes "<ITEM>" + getitemname(.item_list[.@i]) + "[" + getitemslots(.item_list[.@i]) + "]<INFO>" + .item_list[.@i] + "</INFO></ITEM>"; if(.@i >= 10 && !(.@i%10)) next; } end; } end; function rnd { if(.HardBalance){ return rand(getarg(0),rand(getarg(0)+1,getarg(1))); } return rand(getarg(0),getarg(1)); } function AddGroup { .@id = getarg(0); for(.@i=1;.@i<getargcount();.@i++){ .it[getarg(.@i)] = .@id; .item_list[getarraysize(.item_list)] = getarg(.@i); } return; } function AddGroupOption { .@id = getarg(0); .g_reroll[.@id] = getarg(1); .g_reuse[.@id] = getarg(2); return; } function AddGroupCost { .@id = getarg(0); .nz[.@id] = getarg(1); .nk[.@id] = getarg(2); .nc[.@id] = getarg(3); for(.@i=4;.@i<getargcount();.@i+=2){ .@s = getarraysize(getd(".ni_" + .@id)); setd(".ni_" + .@id + "[" + .@s + "]",getarg(.@i)); setd(".na_" + .@id + "[" + .@s + "]",getarg(.@i+1)); } return; } function AddGroupReRollCost { .@id = getarg(0); .rz[.@id] = getarg(1); .rk[.@id] = getarg(2); .rc[.@id] = getarg(3); for(.@i=4;.@i<getargcount();.@i+=2){ .@s = getarraysize(getd(".ri_" + .@id)); setd(".ri_" + .@id + "[" + .@s + "]",getarg(.@i)); setd(".ra_" + .@id + "[" + .@s + "]",getarg(.@i+1)); } return; } function AddGroupChance { .@id = getarg(0); .s_1[.@id] = getarg(1); .s_2[.@id] = getarg(2); .s_3[.@id] = getarg(3); .s_4[.@id] = getarg(4); .s_5[.@id] = getarg(5); return; } function AddOpt { .@id = getarg(0); .@loc = getarg(1); .@s = getarraysize(getd(".ro_id_" + .@id + "_" + .@loc)); setd(".ro_id_" + .@id + "_" + .@loc + "[" + .@s + "]",getarg(2)); setd(".ro_mn_" + .@id + "_" + .@loc + "[" + .@s + "]",getarg(3)); setd(".ro_mx_" + .@id + "_" + .@loc + "[" + .@s + "]",getarg(4)); return; } function AddExclusiveOpt { .@s1 = getarraysize(.exv); .exv[.@s1] = true; for(.@i=0;.@i<getargcount();.@i++){ .ex[getarg(.@i)] = .@s1; } return; } OnInit: .exv = true;//DO NOT REMOVE THIS. .KeepItemData = true;//if this is 'false , the player will loss the refine+cards from the item when he use this npc. .CustomPointsVariable$ = "#COSTUMPOINTS";//The variable name of the costum points. .CustomPointsName$ = "Server RO Points";//The name of the costum points, this what the player will see. .HardBalance = true;//if this is true , it would be much harder to get high value in the random option. //AddGroup(<Group ID>,<ItemID>,<ItemID>,<ItemID>,<ItemID>,<ItemID>); /* AddGroup Doc <Group ID> = a number between 1 and MAX_INT64 DO NOT REUSE THE GROUP ID IN THE SAME FILE CONFIG! DO NOT REUSE THE SAME ITEM ID IN DIFFERENT GROUP! will create a group id you can add as many as you want items inside a group. */ //AddGroupOption(<Group ID>,<Allow ReRoll?true:false>,<Allow reuse already gotten option?true:false>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupOption Doc <Group ID> = A group id that is already created in AddGroup()!. <Allow ReRoll?true:false> = allow reroll an item with random option or not <Allow reuse already gotten option?true:false> = for exammple if you have str in the options and the player gor it , can he get it again in another slot? */ //AddGroupCost(<Group ID>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupCost Doc <Group ID> = A group id that is already created in AddGroup()!. <Zeny Cost> = the zeny cost (can be 0) <CashPoint Cost> = the cashpoints cost (can be 0) <Custom Points Cost> = if you are using costum points in the script , check out .CustomPointsVariable$ and .CustomPointsName$ at the start of the script (can be 0) <Item1 ID Cost> = the item cost <Item1 Amount Cost> = the item amount cost You can use as many item,amount cost at the end of the function. */ //AddGroupReRollCost(<Group ID>,<Zeny Cost>,<CashPoint Cost>,<Custom Points Cost>,<Item1 ID Cost>,<Item1 Amount Cost>,<Item2 ID Cost>,<Item2 Amount Cost>,<....ETC>); /* AddGroupReRollCost Doc <Group ID> = A group id that is already created in AddGroup()!. <Zeny Cost> = the zeny cost (can be 0) <CashPoint Cost> = the cashpoints cost (can be 0) <Custom Points Cost> = if you are using costum points in the script , check out .CustomPointsVariable$ and .CustomPointsName$ at the start of the script (can be 0) <Item1 ID Cost> = the item cost <Item1 Amount Cost> = the item amount cost You can use as many item,amount cost at the end of the function. */ //AddGroupChance(<Group ID>,<1st Option Chance>,<2nd Option Chance>,<3rd Option Chance>,<4th Option Chance>,<5th Option Chance>); /* AddGroupChance Doc <Group ID> = A group id that is already created in AddGroup()!. <1st Option Chance> = the Chance to get one of the random options in the slot 1 (can be 0) <2nd Option Chance> = the Chance to get one of the random options in the slot 2 (can be 0) <3rd Option Chance> = the Chance to get one of the random options in the slot 3 (can be 0) <4th Option Chance> = the Chance to get one of the random options in the slot 4 (can be 0) <5th Option Chance> = the Chance to get one of the random options in the slot 5 (can be 0) Keep inmind that if the player didn't get lucky for example at the slot 2 , all the chances after will be ignored you cannot skip a random option slot that would bug the game client. */ //AddOpt(<Group ID>,<Location>,<Random Option ID>,<Minimum Value>,<Maximum Value>); /* AddOpt Doc <Group ID> = A group id that is already created in AddGroup()!. <Location> = you can spisfiy random option to a location from 1 to 5 , but you can use 0 , if you used 0 it will apply to all locations that doesn't have spisfied random options. <Random Option ID> = random option id , you can use the id or the variable , check out the file /rathena/db/re/item_randomopt_db.yml <Minimum Value> = the minimum value <Maximum Value> = the maximum value */ //AddExclusiveOpt(<Random Option ID>,<Random Option ID>,<Random Option ID>,<Random Option ID>,<Random Option ID>); /* AddExclusiveOpt Doc this will help you to prevent a group of random opions typs in the same item in different slots for example RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET RDMOPT_DAMAGE_PROPERTY_WATER_TARGET RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET RDMOPT_DAMAGE_PROPERTY_WIND_TARGET RDMOPT_DAMAGE_PROPERTY_POISON_TARGET RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET if the player got 1 of them in a slot , he wont get another one to another slot */ //Example!!!> //this is just an example , this script allow you to create any random option system you want. //Creating Group id 1 , with Hat items inside. AddGroup(1,50001,50002,50004,50005,50006,50007,50008,50009,50010,50011,50014,50015); //Group id 1 Options AddGroupOption(1,true,false); //Group id 1 Cost AddGroupCost(1,0,0,0,677,50); //Group id 1 ReRoll Cost AddGroupReRollCost(1,0,0,0,677,50); //Group id 1 Chances. AddGroupChance(1,100,100,0,0,0); //Group id 1 Random Option List. location 0 mean all the slot locations AddOpt(1,1,RDMOPT_VAR_STRAMOUNT,5,10); AddOpt(1,1,RDMOPT_VAR_INTAMOUNT,5,10); AddOpt(1,1,RDMOPT_VAR_VITAMOUNT,5,10); AddOpt(1,1,RDMOPT_VAR_LUKAMOUNT,5,10); AddOpt(1,1,RDMOPT_VAR_AGIAMOUNT,5,10); AddOpt(1,1,RDMOPT_VAR_DEXAMOUNT,5,10); AddOpt(1,2,RDMOPT_VAR_MAXHPPERCENT,5,10); AddOpt(1,2,RDMOPT_VAR_MAXSPPERCENT,5,10); AddOpt(1,2,RDMOPT_VAR_ATKPERCENT,5,10); AddOpt(1,2,RDMOPT_VAR_MAGICATKPERCENT,5,10); AddOpt(1,2,RDMOPT_VAR_MDEFPOWER,5,10); AddOpt(1,2,RDMOPT_VAR_ITEMDEFPOWER,5,10); AddOpt(1,2,RDMOPT_VAR_HITSUCCESSVALUE,5,10); AddOpt(1,2,RDMOPT_VAR_CRITICALSUCCESSVALUE,5,10); //those enchantment you wont get unless in slot 5 AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_WATER_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_WIND_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_POISON_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET,1,100); AddOpt(1,5,RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET,1,100); //this mean those random options cannot coexist in the same item!. AddExclusiveOpt(RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET, RDMOPT_DAMAGE_PROPERTY_WATER_TARGET, RDMOPT_DAMAGE_PROPERTY_GROUND_TARGET, RDMOPT_DAMAGE_PROPERTY_FIRE_TARGET, RDMOPT_DAMAGE_PROPERTY_WIND_TARGET, RDMOPT_DAMAGE_PROPERTY_POISON_TARGET, RDMOPT_DAMAGE_PROPERTY_SAINT_TARGET, RDMOPT_DAMAGE_PROPERTY_DARKNESS_TARGET, RDMOPT_DAMAGE_PROPERTY_TELEKINESIS_TARGET, RDMOPT_DAMAGE_PROPERTY_UNDEAD_TARGET); end; } Can someone help me to add a requirment that the same item. Example to add Option in item 30002 you need another 30002 to proceed adding option same item requirment is need specially the item requirments from the script it self right now! TIA ♥
    1 point
  3. I'm glad that people enjoyed reading it. When I started, I figured that maybe I'd somehow find a way to allow rebirth for the classes that couldn't do it (always my pet peeve with the original game), I never figured it would turn into this. Still, my journey is probably nearing its end. I know I've said that before, but with any project there does come a time when you have to say "it's done!". At a certain point, there's simply not much you can add any more that meaningfully adds to the game. And I've pretty much run out of stuff I can feasibly add. There are no more maps I can harvest from Renewal. I've used almost every distinct weapon sprite in the game. There aren't really that many more skills that can be added without compromising the identity of the classes. For a few months, updates on the server have slowed as we've approached something resembling "stability". However, there remains one final frontier to tackle, and that's Guild War. I've always considered Guild War to kind of be the glue that holds Ragnarok Online together as a game. Ragnarok (at least PRE-RE) does not really have any story of defined goal. Sure, you can grind your way to max level, and my server does include significantly expanded end-game content in the form of the past, but ultimately the grind on its own can feel a little hollow at times. One of my beta testers who is new to the game asked me "sure, we can kill some of these bosses now, but what do we really need their items for other than to kill more bosses?". Of course, we all know the answer is "TO CRUSH OUR ENEMIES WITH AN IRON FIST!". Ragnarok Online is an incredibly complex game with a nearly infinite number of possible builds you can make, but the complex interplay of these builds can only shine when they're pitted against each other. The War of Emperium is an incredibly deep and interesting mode that takes all of the elements of the game and gives them their own unique and interesting way to shine. It is also an absolute nightmare to balance. I'm not actually talking about the actual gameplay balance of the mode itself. That is a concern too, of course, but it's something I've had in mind since the very beginning when designing and tweaking skills, so I don't think it should actually be too bad. No, what I'm talking about are the rewards from the mode that serve as the incentive to play it. On the official servers, the main incentive to play WOE is to get the God Items. The God Items are deliberately monstrously overpowered, which is (somewhat) balanced out by the fact that you need rare items from many different castles to assemble them. (As an aside, I see that in recent patches the god items have actually been nerfed, but to me Mejingjord will always give +40 STR). This is a problem for smaller servers, though, because you need a massive population to run War of Emperium with many castles at once. What a lot of small servers do is they only open one castle at a time. This works well, but it makes the god items impossible to get, which, to be honest, is probably a good thing because they're so gamebreaking, but it also kind of feels lame since most of the other rewards are fairly common things that you can get easily. No one is really that excited by slotted chainmail anymore. It was clear from the start that Guild War was going to need new, exclusive rewards. This was not easy, because I already added a ton of new items to the game. Clearly, the rewards from the guild war have to be good enough that you actually want them, but not so strong that gaining control of the guild castles quickly becomes an insurmountable advantage. This is a very delicate balance. Beyond this, there's the question of how to distribute the rewards. If we're adding new weapons, different classes equip different weapon types. We don't want to intentionally favour certain classes or builds by mainly adding good equipment for a single class. Each castle can spawn 2 distinct treasure boxes, which are unique to that castle. If only one castle is used, this gives us a total of 16 item slots to work with, which is not even enough for 1 of every weapon type in the game (and we want some lesser rewards like eluniums and OCAs as well). 1 castle isn't enough. My clue for how to handle this came from the classes in the game. The game has 10 base classes: Swordman, Acolyte, Mage, Archer, Thief, Merchant, Taekwon, Ninja, Gunslinger, and Summoner. We can pair these up two classes to a castle, which allows for roughly one box per class. This sounds pretty good! Under this scheme, 5 castles would be needed, which would presumably be available on a rotating schedule. We're getting somewhere, but there's just one more problem. There are four different guild war realms, Prontera, Geffen, Al De Baran, and Payon (for now, we're leaving War of Emperium 2 out of the equation). It seems to make sense to pick one castle from each. But what about the fifth castle? Well, clearly a sane person would just pick a second castle from one of the realms, but you should know by now that's not going to happen. No, of course the answer is that we're going to create a totally new fifth castle in its own realm. The cats have been disrespected for too long, so it's finally time for Malangdo to get its own guild castle. Well, maybe "totally new" is overselling it a bit. It's more like a "significantly altered version of a castle that already exists". Of the castles I didn't pick, the castle with by far the most interesting layout was payg_cas04, so this will become the basis for malg_cas01. To the map editor! There's a few things I like about this layout, but I think the most interesting thing about it has got to be this Emperium room. It's huge, there's two routes you can take, you can snipe across the gaps, and there are little barriers that protect you in certain areas. The coolest thing about it though are those double entry warps at the top! Spamming spells and traps on warp points is a super strong strategy in WoE, so having a second warp in to the emperium room is a huge deal. However, in payg_cas04, only one of the warps is actually used! This won't do, so the first thing we needed to do was to add a new route that could let you get to the second warp point. Looking at the layout of the castle, which I wasn't planning to change too drastically, there was really only one feasible place that could lead to a new warp, and that's this corridor here at the bottom of this map (the red square indicates where the warp would go). So this is where the new route would start. However, this is actually the first interior room in the castle, the warp on the far left leads to another interior room, so clearly this can't just skip you right to the emperium room. A totally new room is needed that leads to the emperium room. I decided to keep things fairly simple. The new room is a kind of back hallway that leads to a storage room, with a staircase leading down to the emperium room. Rather deliberately, this room kinda sucks for the attackers. It's super narrow, and it's very easy to trap the one-cell passage by that little barricade, or camp behind it. You can hide in the storage room to avoid someone walking through the hallway with Sight and try to slip past, but it's not hard to check the storage room since it has only one exit. However, having a second route that leads to the emperium room is already very powerful, as the defenders now need to cover both routes if they don't just want to try to hold the final room. I think there's an interesting strategy tradeoff if this route is clearly worse than the other route. Do you check it less often because clearly people won't take the bad route? Then that kind of makes it actually the good route, because you might encounter much less opposition that way. In any case, I think this layout is interesting. Of course, I couldn't just slap in a new room and call it a day, I also had to Malangdo up the place. It now has much more of a tropical theme. Interestingly, there are actually some GATing errors on this map (the GAT defines where you can and can't walk). There's a wall on the lower side of this map that you can simply walk through on the official servers, as well as a few misplaced snipe tiles. I fixed them. Still, it kind of made me feel good in a way to know that the original map creators are human too. I also retextured the entire map and replaced all of the objects with Malangdo-themed ones, which no one will probably ever notice because you really don't have time to sit and enjoy the scenery in the middle of guild war. Putting all that food on those plates is a huge pain! Oh well. I feel like if you can't tell that I made something, it means I probably did a good job of it. The gold standard is for it to look like something that could have been in the game originally. I also continue to be impressed by the ingenuity of the original level designers. Did you know that those apples on the table beside the bananas are actually christmas tree ornaments from Lutie? You'd never guess. So we have our new map, all that remains is to rig it up to work in the game. Surprisingly, Rathena provides space in agit_controller for you to insert your own custom guild castles. Has anyone other than me ever used this? Adding the new castle is surprisingly easy, you just have to remember to put it into castle_db. And here we are! Shh, no one give away my awesome hiding spot. Oh, and of course, Malangdo also needs its own Guild Dungeon! Luckily, we happen to have an unused cat-themed dungeon left over in lasagna dungeon! It's like I planned it all along! This place also plays the unused track 175. Now let's all enjoy Cat on Bullet. Only one question remains. How the heck do we actually get here? Well, the first couple screenshots may have given a clue. See, it's an intentional balancing mechanic that the guild realms aren't just inside the town. The necessity to walk back to the entrance to the guild castle increases the length of time it takes the attackers to respawn, compared to the defenders who can simply warp into the castle. So we need a spot that takes a little bit of time to walk to. How about the otherwise pointless boat in the middle of Malangdo? (I don't apologize for this dialogue). And there we have it, 5 castles (or four castles and one cattsle). All that remains is the rewards. Here's a taste of a few of them (there's actually 30 new equipment items in total) Which one do you think is the most gamebreaking? (Incidentally, "Finale" mentioned in the Dancer weapon is Amp. Someone complained that calling it Amp made no sense, which is true). Actually, a key element of this is that most of the gear is significantly restricted in terms of which classes can use it, so even if an item like the Light Manteau maybe outclasses the Heavenly Wings (Dex +1, 3 Def), the fact that only a few classes can use it prevents it from making the other item useless. In any case, they're not really out of line with a lot of the gear that's already in the game (and I don't think they're nearly as bad as a lot of the nonsense that was added in renewal), but they are probably things you would actually want, which of course is the point. Anyway, that wraps it up for this time. it might be a long time before another update, if there even is one, but I hope everyone has enjoyed reading this thread.
    1 point
  4. Note: This map was made during my Browedit tutorial. * If you are interested to learn how to develop your own custom RO Map, please check the link below. prontera v0.1 Very simple prontera map with custom texture. Image 1 Image 2 Image 3 Thanks for Downloading. speedrun_prt.grf
    1 point
  5. Version 2.0

    101 downloads

    vCP (Version 2.0) The vCP (Version 2.0) is a point-based voting system designed for the game Ragnarok. This version of the system has undergone significant updates to enhance security, ensure compatibility with the latest PHP version (8.2.1), and improve code organization. Features Point-Based Voting: Players can earn points by voting and then exchange them for items that will be delivered directly to their in-game accounts. Installation Access install/index.php and fill out the installation form. Upon completion, the system will create all the necessary infrastructure for its operation. Common Errors and Solutions: Error when altering the login table: Check if the "vcp_pontos" field does not exist in the table. If it exists, you can delete it and attempt the installation again. Error when writing the configuration file: If you encounter this error, it may be due to insufficient writing permissions in the "inc" folder. Ensure that your account has the necessary permissions. Key Improvements In this version 2.0, the following improvements have been implemented: Introduction of the vCP class instance: An instance of the vCP class has been introduced to improve code organization and maintenance. Code improvements in files: The code has been enhanced to make it more secure and robust. Practices such as input sanitization using htmlspecialchars have been adopted. Updated Charset: The charset has been changed to UTF-8, ensuring support for special characters. Sql class improvements: The Sql class has been improved to make it more robust and secure. Transition to MySQLi: The system now utilizes the MySQLi extension for database communication, enhancing query security and efficiency. How to Contribute If you wish to contribute to this project or report issues, feel free to open issues or pull requests. Contributions are welcome! Conclusion The Point-Based Voting system for Ragnarok is an excellent way to encourage player participation and increase competitiveness among servers. Additionally, it provides a richer and more diverse gaming experience. The system's installation is simple and quick and can be carried out through the install/index.php file. License This project is licensed under the MIT License. Please refer to the LICENSE file for more details. Github: https://github.com/felipemike/vcp
    Free
    1 point
  6. prontera,156,179,6 script Suhnbi#custom 85,{ disable_items; mes "[Suhnbi]"; mes "I am the Armsmith."; mes "I can refine all kinds of weapons,"; mes "armor and equipment, so let me"; mes "know what you want to refine."; next; setarray(.@indices[0], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW); for(.@i = 0; .@i < 10; .@i++) { if (getequipisequiped(.@indices[.@i])) { .@menu$[.@i] = F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]"; .@equipped = 1; } } if (.@equipped == 0) { mes "[Suhnbi]"; mes "I don't think I can refine any items you have..."; close; } .@equip = .@indices[select(implode(.@menu$, ":")) - 1]; if (!getequipisequiped(.@equip)) end; if (!getequipisenableref(.@equip)) { mes "[Suhnbi]"; mes "Go find another Blacksmith. You can't refine this thing."; close; } if (getequiprefinerycnt(.@equip) >= 20) { mes "[Suhnbi]"; mes "Hmm... someone perfected this already. I don't think I can work on it further."; close; } .@refineitemid = getequipid(.@equip); .@refinerycnt = getequiprefinerycnt(.@equip); .@price = getequiprefinecost(.@equip, REFINE_COST_NORMAL, REFINE_ZENY_COST); .@itemtype = getiteminfo(.@refineitemid, ITEMINFO_TYPE); .@equipLvl = (.@itemtype == IT_WEAPON) ? getequipweaponlv(.@equip) : getequiparmorlv(.@equip); mes "[Suhnbi]"; if (.@itemtype == IT_WEAPON) mes "You want to refine a level " + .@equipLvl + " weapon?"; mes "To refine that, you'll need to have two ^ff9999" + ((.@refinerycnt > 0) ? "+" + .@refinerycnt + " " : "") + getitemname(.@refineitemid) + "^000000 and " + callfunc("F_InsertComma", .@price) + " zeny."; mes "Would you like to continue?"; next; if(select("Yes:No") == 2) { mes "[Suhnbi]"; mes "I can't help it even if you're not happy about it..."; close; } if (getequippercentrefinery(.@equip) < 100) { if (.@itemtype == IT_WEAPON) { mes "[Suhnbi]"; mes "Wow!!"; mes "This weapon probably"; mes "looks like it's been refined..."; mes "many times..."; mes "It may break if"; mes "you refine it again."; next; mes "And if it breaks,"; mes "you can't use it anymore!"; mes "All the cards in it and the properties ^ff0000will be lost^000000!"; mes "^ff0000Besides, the equipment will break!^000000"; mes "Are you sure you still want to continue?"; next; if(select("Yes:No") == 2) { mes "[Suhnbi]"; mes "Good."; mes "Because if the weapon breaks from unreasonable refining, then I get a bad mood, too."; close; } } else { mes "[Suhnbi]"; mes "Giggle. Giggle. Oh, you have guts, daring to refine this."; mes "You know it's pretty risky, don't you?"; next; mes "If your defensive equipment is broken, you'll never be able to use it again."; mes "Even your cards and your modifications will ^ff0000completely disappear^000000."; mes "Do you really wish to continue?"; next; if(select("Yes:No") == 2) { mes "[Suhnbi]"; mes "What nonsense. You waste my precious time."; mes "Get lost, punk."; close; } } } .@idx = 0; getinventorylist(getcharid(0)); for(.@i = 0; .@i < @inventorylist_count; .@i++) { if(@inventorylist_id[.@i] == .@refineitemid && @inventorylist_refine[.@i] == .@refinerycnt && @inventorylist_equip[.@i] == 0) { .@itemReqIdxs[.@idx] = @inventorylist_idx[.@i]; .@idx++; } if(.@idx == .itemCostAmount) break; } if (getarraysize(.@itemReqIdxs) < .itemCostAmount || Zeny < .@price) { mes "[Suhnbi]"; mes "Are these all you have?"; mes "I'm very sorry, but I can't do anything without all the materials. Besides, I deserve some payments for my work, don't I?"; close; } Zeny -= .@price; for(.@i = 0; .@i < getarraysize(.@itemReqIdxs); .@i++) delitemidx(.@itemReqIdxs[.@i], 1); if (callfunc("F_IsEquipIDHack", .@equip, .@refineitemid) || callfunc("F_IsEquipRefineHack", .@equip, .@refinerycnt) || callfunc("F_IsEquipCardHack", .@equip, getequipcardid(.@equip, 0), getequipcardid(.@equip, 1), getequipcardid(.@equip, 2), getequipcardid(.@equip, 3))) { mes "[Suhnbi]"; emotion(ET_FRET); mes "Wait a second..."; mes "Do you think I'm stupid?!"; mes "You switched the item while I wasn't looking! Get out of here!"; close; } mes "[Suhnbi]"; mes "Clang! Clang! Clang!"; if (getequippercentrefinery(.@equip) > rand(100)) { successrefitem(.@equip); next; emotion(ET_BEST); mes "[Suhnbi]"; mes "There you go! It's done."; mes "It's been a while since I've made such a fine " + ((.@itemtype == IT_WEAPON) ? "weapon" : "armor") + ". You must be happy because it has become stronger!"; close; } failedrefitem(.@equip); next; emotion (!rand(5)) ? ET_MONEY : ET_HUK; mes "[Suhnbi]"; mes "Uuuuuuuuuummmmmph!!!"; next; mes "[Suhnbi]"; mes "..."; mes "....."; mes ".......Huhuhuhuhu~"; mes "........It was your choice and my ability, no regret."; close; OnInit: .itemCostAmount = 2; }
    1 point
  7. 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
  8. Hey there everyone, long time no see! So it's been a very long time since I have been on these boards and I do miss it all. Feeling a little nostalgia looking through all of these, I decided to release them all to the public, completely free. Going in no particular order after the first few, they are just my favorites. I hope you guys love them as I have. Sanctum Main town oriented map. My absolute favorite and latest work (When I was mapping). The idea I had for this was a chunck of a mountain broke off and landed here, subsequently creating a waterfall from atop and surrounding the town. Giving it protection and a perfect center for life. I never got around to finishing the outside of the map, I don't even know what I thought for the surroundings, perhaps just trees. Sanctum In And here is the inside map for Sanctum. The first picture is the general area where various NPC's can be placed. The second picture is where I planned to use a script to automatically place anyone who wished to vend in the one walkable/edited Gat. It would cycle through and remove those vending for a prolonged period of time and also anyone not vending at all. Guild Base This map was designed for the top guilds or just those who hold castles to have a domain of their own. The first picture is just a hangout spot for anyone in the guild. The second picture is for any combat/training/monster summoning to be done. The third picture is for the guild master where special NPC's can be placed as the server owners desire. Novice Starter Grounds PvP Valkyrie A little small for a PvP map but I enjoyed making it and like how it turned out. Trinity The first main town I made some time back around 2010. Don't judge me on some of the rookie mistakes I made with lighting and such haha. The following Trinity ___ maps are connected via a warp on the edges of the map. Trinity In Trinity Courtyard Before the Sanctum maps, this was my favorite creation. I just liked the feel of this one. Trinity Vending Similar to the Sanctum In vending idea, I wanted to limit vending to only those tiles with the colored objects on it. Trinity Port Anexus A simple instance based map with a boss at the end. Another one of my earlier works. Works The beginnings of my templates map. I would urge any current mapper to use this technique to create unique model compilations and copy it over to the map in progress. I have used this to create a forest that looks completely customized in a matter of minutes. Well there they are, open to any and all. I hope to hear your feedback on these! Thanks, Truly ~
    1 point
  9. 1553 downloads

    Askald This mas is public so don't try to sell it or make it your property. It is my first map, i am pretty happy with the result and i will probably make some more. Contact You can found me on discord : Sloth#6226 Github : https://github.com/SlothBM/ Crédit I would like to thank the Borf discord community for helping me with a few issues. Want to support my work ?
    Free
    1 point
×
×
  • Create New...