-
Posts
245 -
Joined
-
Last visited
-
Days Won
19
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Everything posted by Winterfox
-
[SOLVED] prevent overused spaces in chat
Winterfox replied to jamesandrew's question in Scripting Support
Looks okay. Why don't you test it? -
I am not sure if I really understood you 100% but if I got you right, you want your script to work like this: ma_in01,49,99,3 script Fallen Hero#main 651,{ cutin("3rd_rune_knight", 2); .@remaining_minutes = (#next_fallen_gift - gettimetick(2)) / 60; if(#next_fallen_gift > 0 && .@remaining_minutes > 0) { if(.@remaining_minutes > 60) .@remaining_hours = .@remaining_minutes / 60; mes "[ ^0000FFFallen Hero^000000 ]"; mes "You have to wait ^FF0000" + ((.@remaining_hours > 0) ? F_InsertPlural(.@remaining_hours, "hour") : F_InsertPlural(.@remaining_minutes, "minute")) + "^000000 until you can get your next gift."; close3; } mes "[ ^0000FFFallen Hero^000000 ]"; mes "Hello " + strcharinfo(0) + "."; mes "I give you a free gift every day."; mes "Let's hope that you will get something good today."; next; mes "[ ^0000FFFallen Hero^000000 ]"; mes "Let me see what I gift have for you..."; .@pick = rand(1, .items_sum); for(.@i = 0; .@i < getarraysize(.items); .@i += 2) { .@pick -= .items[.@i + 1]; if(.@pick <= 0) { .@item = .items[.@i]; break; } } getitem(.@item, 1); announce(strcharinfo(0) + " has obtained " + getitemname(.@item) + " from the Fallen Hero!", bc_all, 0x00FFFF, FW_NORMAL, 15); mes "Here take this " + getitemname(.@item) + "."; #next_fallen_gift = gettimetick(2) + .next_gift_duration; next; mes "[ ^0000FFFallen Hero^000000 ]"; mes "Come back later to receive a new gift."; close3; OnInit: // duration until the next gift can be gotten. .next_gift_duration = 86400; // item chances <<item id>, <chance>>, <<item id>, <chance>>... setarray(.items, 6232, 10, 6228, 10, 13710, 10, 12916, 10, 5184, 10, 5199, 10, 5209, 10, 5762, 10, 5467, 10, 12884, 20, 12885, 20, 12886, 20, 12887, 20, 35078, 20, 13698, 70, 13697, 70, 14175, 70, 14587, 70, 12920, 70, 12921, 70, 14192, 70, 16504, 70, 12922, 70, 7776, 70, 12412, 70, 35111, 70); for(.@i = 0; .@i < getarraysize(.items); .@i += 2) .items_sum += .items[.@i + 1]; }
-
Where is the value for #daily_minute_count set?
-
anyone have tcg to god item & berry to bticket?
Winterfox replied to moba122096's question in Script Requests
Why don't you try to learn to write that script yourself? What you want isn't that complicated and would be quite a good beginner script to learn how to write your own NPCs. If you want to give learning to script a try, you can find the documentation for rAthena script here: https://github.com/rathena/rathena/blob/master/doc/script_commands.txt For the script you want, I would recommend you to check the commands countitem, delitem and getitem. -
They use different item dbs, did you put the item in both?
-
I am not sure what result Emistry wants to achieve since dropping the table and only creating it if it doesn't exist afterward is a bit contradictory, but you could change DELETE to DROP like this: DROP TABLE IF EXISTS `ero_buildmanager`;
-
prontera, 155, 180, 4 script Guild Donation Manager 4_F_AGENTKAFRA,{ function listAcceptedItems { for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++) mes getitemname(.accepted_items[.@i]); } function saveDonation { .@guild_id = getcharid(2); .@character_id = getcharid(0); .@zeny = getarg(0); for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++) { .@item_row$ = "item" + (.@i + 1); .@item_rows$ += ", " + .@item_row$; .@item_insert$ += ", " + getelementofarray(getarg(1), .@i)); .@insert_update$ += ", " + .@item_row$ + " = " + .@item_row$ + " + " + getelementofarray(getarg(1), .@i)); } query_sql("INSERT INTO guild_donations (guild_id, character_id, zeny" + .@item_rows$ + ") VALUES (" + .@guild_id + ", " + .@character_id + ", " + .@zeny + .@item_insert$ + ") ON DUPLICATE KEY UPDATE zeny = zeny + " + .@zeny + .@insert_update$); } function showHistory { .@guild_id = getcharid(2); for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++) .@item_rows$ += ", item" + (.@i + 1); query_sql("SELECT character_id, zeny" + .@item_rows$ + " FROM guild_donations WHERE guild_id = " + .@guild_id, .@character_id, .@zeny, .@item1, .@item2); for(.@i = 0; .@i < getarraysize(.@guild_id); .@i++) mes "Character: " + strcharinfo(0, .@character_id[.@i]) + " Zeny: " + .@zeny[.@i] + " " + getitemname(.accepted_items[0]) + ": " + .@item1[.@i] + " " + getitemname(.accepted_items[1]) + ": " + .@item2[.@i]; } if((.@guild_id = getcharid(2)) == 0) { mes "[" + .npc_name$ + "]"; mes "Sadly i can't help you, since you are not in a guild."; close; } mes "[" + .npc_name$ + "]"; mes "Hello Guild " + ((is_guild_leader(.@guild_id)) ? "Master" : "Member") + "!"; mes "How may i help you today?"; next; switch(select("I want to donate.:Show me the donation history.")) { case 1: mes "[" + .npc_name$ + "]"; mes "What do you want to donate?"; next; if(select("Zeny:Items") == 1) { mes "[" + .npc_name$ + "]"; mes "How many zeny do you want to donate?"; next; input(.@donation); if (Zeny < .@donation) { mes "[" + .npc_name$ + "]"; mes "You don't have enough zeny."; close; } Zeny -= .@donation; saveDonation(.@donation, .@items); mes "[" + .npc_name$ + "]"; mes "Alright, i registered your donation!"; close; } else { mes "[" + .npc_name$ + "]"; mes "Remember i can only take the following items: "; listAcceptedItems(); close2; callshop("guild_donation_dummy_shop", 2); npcshopattach("guild_donation_dummy_shop"); end; } break; case 2: mes "[" + .npc_name$ + "]"; showHistory(); close; break; } OnSellItem: for(.@i = 0; .@i < getarraysize(@sold_nameid); .@i++) { if((.@index = inarray(.accepted_items[0], @sold_nameid[.@i])) == -1) { mes "[" + .npc_name$ + "]"; mes "There are items i can't accept."; mes "I only take the following items: "; listAcceptedItems(); close; } .@items[.@index] = @sold_quantity[.@i]; } for(.@i = 0; .@i < getarraysize(@sold_nameid); .@i++) delitem(@sold_nameid[.@i], @sold_quantity[.@i]); saveDonation(0, .@items); end; OnInit: .npc_name$ = strnpcinfo(1); setarray(.accepted_items[0], 45000, 45001); } - shop guild_donation_dummy_shop -1,501:50. CREATE TABLE IF NOT EXISTS `guild_donations` ( `guild_id` int(11) NOT NULL, `character_id` int(11) NOT NULL, `character_name` varchar(32) NOT NULL, `zeny` int(11) NOT NULL, `item1` int(11) NOT NULL, `item2` int(11) NOT NULL, PRIMARY KEY (`guild_id`,`character_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
- 1 reply
-
- 1
-
-
How to modify this enchantment script only for upper costume headgear?
Winterfox replied to Heartfelt's question in Script Requests
I didn't test it, but this should do what you want. prontera,156,178,5 script Enchanter 100,{ disable_items; mes "What do you want to enchant?"; next; .@s = select( .menu$ ) -1; .@part = .const_equip[.@s]; .@part_name = .menu_name$[.@s]; if (!getequipisequiped(.@part)) { mes "You did not equip an " + .@part_name + " at the moment"; close; } .@id = getequipid(.@part); .@ref = getequiprefinerycnt(.@part); setarray(.@card[0], getequipcardid(.@part, 0), getequipcardid(.@part, 1), getequipcardid(.@part, 2), getequipcardid(.@part, 3)); if (.@card[0] == 255 || .@card[0] == 254) { mes "I can't enchant a signed equipment"; close; } if (.@card[3]) { mes "This " + .@part_name + " is already enchanted"; close; } .@rand = rand(1, .totalchance); while ((.@rand -= .rate[.@orb_level]) > 0) .@orb_level++; .@orb = 4700 + rand(0, 5) * 10 + .@orb_level; // orb of str/int/dex .... if (callfunc("F_IsEquipIDHack", .@part, .@id) || callfunc("F_IsEquipRefineHack", .@part, .@ref) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3])) { 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; } delitem2(.@id, 1, 1, .@ref, 0, .@card[0], .@card[1], .@card[2], 0); getitem2(.@id, 1, 1, .@ref, 0, .@card[0], .@card[1], .@card[2], .@orb); equip(.@id); end; OnInit: setarray(.rate, 55, 50, 45); //, 40, 35); // rate of getting +1 is 55%, +2 is 50% .... +10 is 10% ... setarray(.const_equip, EQP_COSTUME_HEAD_TOP); setarray(.menu_name$, "Upper Costume Headgear"); .menu$ = implode(.menu_name$, ":"); for(.@i = 0; .@i < getarraysize(.rate); .@i++) .totalchance += .rate[.@i]; } -
[SOLVED] prevent overused spaces in chat
Winterfox replied to jamesandrew's question in Scripting Support
I think that this is a thing you need to fix in the source. -
Players secretly having +10 enchants on items.
Winterfox replied to Finale's question in Scripting Support
There are many places where people can get enchantments. You can find most by searching for "Enchant", "Enchants NPCs" or for the command "item_enchant" in the npc directory. -
Getting an Error Code From Microsoft Visual C++
Winterfox replied to Theodore Konopel's question in Windows Support
Which version of Visual Studio? Is there also an Error message, or just the code? When exactly does this error pop up? -
This script will enable pvp when there is atleast one living mvp on a map. If the last mvp gets killed, it will announce the kill and end pvp until a mvp is spawned again. Optionally, you can disable the dynamic mobs option in monster.conf. This will result in pvp already being enabled on a living mvps map, when a player loads it. Otherwise, it might take a second to refresh, since the script has to check the newly loaded mobs first. The downside is of course that disabling dynamic mobs will take more ram. - script MVP_PVP_MODE FAKE_NPC,{ function mapHasAliveMVP; function mobHasMvpMode; OnInit: setarray(.mvp_maps$, "moc_pryd06","ra_fild03","ra_fild04","ve_fild01","ve_fild02", "lou_dun03","prt_maze03","abbey03", "gl_chyard","abyss_03","gef_dun02","gef_dun01","treasure02", "pay_fild10","gon_dun03","abbey02","xmas_fild01","ra_san05", "prt_sewb4","mosk_dun03","thor_v03","ama_dun03", "kh_dun02","ayo_dun02","niflheim","anthell02", "mjolnir_04","pay_dun04","gef_fild03","gef_fild10", "moc_pryd04","in_sphinx5","moc_fild17","ein_dun02","xmas_dun02", "beach_dun","thana_boss","tur_dun04","odin_tem03", "jupe_core","lhz_dun02"); freeloop(1); while(true) { for(.@i = 0; .@i < getarraysize(.mvp_maps$); .@i++) if(mapHasAliveMVP(.mvp_maps$[.@i])) pvpon(.mvp_maps$[.@i]); sleep(1000); } freeloop(0); end; OnNPCKillEvent: getunitdata(killedgid, .@data); .@map$ = mapid2name(.@data[UMOB_MAPID]); if(!mobHasMvpMode(.@data[UMOB_MODE]) || mapHasAliveMVP(.@map$)) end; announce(strcharinfo(0) + " killed " + strmobinfo(1, killedrid) + "!", bc_all); pvpoff(.@map$); end; function mapHasAliveMVP { .@map$ = getarg(0); getmapunits(BL_MOB, .@map$, .@mobs); for(.@i = 0; .@i < getarraysize(.@mobs); .@i++) { getunitdata(.@mobs[.@i], .@data); if(.@data[UMOB_HP] == 0 || !mobHasMvpMode(.@data[UMOB_MODE])) continue; return 1; } return 0; } function mobHasMvpMode { return getarg(0) & MD_MVP; } }
-
[solved] autospell mammonite should not casted while 0 zeny
Winterfox replied to jamesandrew's question in Scripting Support
This won't work as expected. The script is only run on onequip. So, the code you provide leads to the bonus3 only to be applied when the player has 500 zeny or more at the time he equips the item, but it doesn't check it on every autospell trigger. That means if mammonite consumes the last 500 zeny the following casts will still be done, since the check doesn't happen at the time of the casting. The solution would be either to instead of just providing a skill name, you could provide a script on each trigger like autobonus works or a parameter to tell the function it should check skill requirements before casting it. But those are things that need a source change. What could work but is kinda messy would be this: autobonus2("{ if(zeny >=500) bonus3(bAutoSpellWhenHit,\"MC_MAMMONITE\",5,5); }", 1000, 1000); I didn't test it but what it should do in theory is to check on each hit if the player has at least 500 zeny and if he does, apply the bonus for 1 second to check if it should trigger mammonite according to its chance. But this is very speculative. It could easily be that the bonus3 doesn't work on the attack that triggered the attachment via autobonus, but instead only on the successive attacks because of the way the state flow is organized. -
[solved] autospell mammonite should not casted while 0 zeny
Winterfox replied to jamesandrew's question in Scripting Support
You should write a git issue to make the rathena team aware of that. https://github.com/rathena/rathena/issues -
Any error messages?
-
script that reads player status effect
Winterfox replied to jamesandrew's question in Scripting Support
The best solution I came up with would be to use autobonus2, it will add a script that will execute every time the player using the item is attacked, run a check if he is poisoned and if he is, it will apply a physical damage reduction by 20% for 10 seconds. I didn't test it, but it should look similar to this: autobonus2("{ if(checkoption2(1)) bonus bNoWeaponDamage, 20; }", 1000, 10000, BF_WEAPON|BF_MAGIC|BF_MISC); -
For the modification of Ragnarok itself, you will only need C++ and rAthena Script (the language NPCs are written in). For C++ you could get some books or look online for tutorials. As resources for rAthena Script, you have the documents I linked you in my previous post. Personally I think, the best way to learn a programming language is by reading how the language works and then using that basis to do own small projects and to read and modify other peoples programs to steady your knowledge. The headgear list is a list of existing headgear sprites in the game. It only shows a picture representation of the sprite from the front. A Client is a software that connects to another software to request things from it. The Server is a software that accepts connections and handles requests from Clients. (The Server >serves< the Clients.) It processes requests and sends back the answers to the Clients. An emulator is a software that tries to exactly reproduce the behavior of another software. In the Client Server sense it would be like this: If the Server isn't the original software, but behaves like the original in that it serves the same results to the Clients the original would, it is an emulation. The essentials are rAthena Full Client Unpacked and patched exe Translation Patch GRF Editor You go into your client's folder, search for the data.grf and open it. Then you will see a list of folders. From there, you can search for the files you are interested in. Sprite files end with .spr and are most of the time paired with an .act file. They base sprites are stored in data/sprite. Model files end with .rsm or rsm2. You can find them at data/model. Here you can see what most of the folders in the grf mean to help you navigate through it a bit better: https://github.com/rathena/rathena/wiki/Data-Folder
-
Welcome Rhymaestro, if you want to modify Ragnarok to fit to your ideas, you have several options and things to learn. The simplest way to change the world itself is using scripting, it lets you do a lot of stuff, but based on how deep you want your changes to be, you will reach its limits relatively fast. This brings us to source modification, for which you will need C++, it will allow you far more agency but is also more complicated and harder to learn. Custom jobs for example would be a thing that you would implement via source modification. You will also need to grasp at least a bit of how the client works, where it gets the graphics and information from, so you can extend or modify things to your liking. Taking your custom job idea, you would need to change client files for the skill descriptions, for example. Many things you want to achieve will have been done in one way or another already. So searching the forum or checking the download section for scripts or source mods you can use as a base or learn from might be useful. You can also check the rAthena wiki at https://github.com/rathena/rathena/wiki which has a lot of guides on how to install rAthena and connect to it or how to achieve certain things you may want to do like adding custom items or mobs. Another helpful resource is the doc directory in the rAthena folder. You can find an online copy here: https://github.com/rathena/rathena/tree/master/doc it provides a lot of information regarding the structure of rAthena to make it clearer how it works. I think especially helpful are the script_commands.txt, which is a reference of all scripting commands rAthena provides and the source_doc.txt which explains how the servers communicate with each other, how the code is organized and what a lot of the acronyms often seen in the source code mean. Tool and resource wise, I can recommend you the tools from: Ai4Rei: https://nn.ai4rei.net/ (Check yourself which tools you might need) Tokei: https://rathena.org/board/files/file/2766-grf-editor/ (GRF Editor) llchrisll: https://github.com/llchrisll/ROenglishRE (English translation of the client) 4144: https://nemo.herc.ws/downloads/ (A good source for full clients, unpacked client exes, and you can get nemo patcher from there to patch your client) Feel free to ask any questions you have. I wish you the best and look forward to seeing how your project progresses.
-
Need help - Modifying Job Changer settings
Winterfox replied to Cyborg's question in Scripting Support
The easiest solution would be to remove the classes you don't want in the menu manually, for example if you want to remove ninja you would need to change it from: case Job_Novice: // First job change Job_Options(.@job_opt,Job_Swordman, Job_Mage, Job_Archer, Job_Acolyte, Job_Merchant, Job_Thief, Job_Super_Novice, Job_Taekwon, Job_Gunslinger, Job_Ninja); if( .BabyNovice ) Job_Options(.@job_opt, Job_Baby); break; to case Job_Novice: // First job change Job_Options(.@job_opt,Job_Swordman, Job_Mage, Job_Archer, Job_Acolyte, Job_Merchant, Job_Thief, Job_Super_Novice, Job_Taekwon, Job_Gunslinger); if( .BabyNovice ) Job_Options(.@job_opt, Job_Baby); break; -
You could modify it like this: At the OnInit on line 18 change: OnInit: disablenpc "The King#KoE"; disablenpc "Exit#KoE"; bindatcmd "koe", strnpcinfo(0)+"::OnCommand", 99,100; end; to OnInit: disablenpc "The King#KoE"; disablenpc "Exit#KoE"; bindatcmd "koe", strnpcinfo(0)+"::OnCommand", 99,100; setarray($@winner_items, 22783, 25, 22780, 25); // <<Item ID>, <Amount>>,... setarray($@loser_items, 22783, 10, 22780, 10); // <<Item ID>, <Amount>>,... end; and on line 87 change: guild_vs1,49,56,5 script Exit#KoE 1_M_BARD,{ mes "[Exit]"; mes "Here's the rewards."; mes "See ya!"; close2; warp "Save",0,0; if ( getcharid(2) == $koegid ) getitem 22783, 25; // Finale Token getitem 22780, 25; // Guild Weapon Box end; } to guild_vs1,49,56,5 script Exit#KoE 1_M_BARD,{ mes "[Exit]"; mes "Here's the rewards."; mes "See ya!"; close2; warp "Save",0,0; if(getcharid(2) == $koegid) copyarray(.@prizes[0], $@winner_items[0], getarraysize($@winner_items)); else copyarray(.@prizes[0], $@loser_item[0], getarraysize($@loser_items)); for(.@i = 0; .@i < getarraysize(.@prizes); .@i += 2) getitem(.@prizes[.@i], .@prizes[.@i + 1]); end; }
-
Need help - Modifying Job Changer settings
Winterfox replied to Cyborg's question in Scripting Support
That is because there is no config to disallow the first expanded classes. You can find the part where the menu is built for players with novice class on line 183. case Job_Novice: // First job change Job_Options(.@job_opt,Job_Swordman, Job_Mage, Job_Archer, Job_Acolyte, Job_Merchant, Job_Thief, Job_Super_Novice, Job_Taekwon, Job_Gunslinger, Job_Ninja); if( .BabyNovice ) Job_Options(.@job_opt, Job_Baby); break; -
What programming language/computer skills should I learn?
Winterfox replied to NEWBIE-HELPMEPLS's question in General Support
Additional to what Rynbef posted, if you want to create a website you will also need HTML, CSS and if you want interactivity JavaScript. -
card deposit system like Ragnarok Mobile has
Winterfox replied to AinsLord's question in Script Requests
I think you should better create a post in the source request section. I think, to provide a good functionality that works like the original card deposit system, there are some code changes required. Here are some reasons that come to my mind: There isn't a way to apply bonuses permanently to a character outside from having something equipped. So the adventure book would need to be an equipment There is no system to put infinite items or cards into another item. Slots are limited to 4 server side since the client limits them to max 4 due to packet size anyway. Also, only the item bonus would be applied and the cards basically removed, since the slot holds an id of an item not a copy of the item you put in. There is no way to differentiate if a card or item should apply its deposited bonuses or its normal bonuses when put into the adventure book. -
Barter Shop (increase item req limit from 5 to 10?)
Winterfox replied to Nullifier's question in Script Requests
The errormessage already tells you what is wrong. The Barters don't support more than 5 items. I am not sure why the limit is hard-coded to five, if it is because the original behavior is like this or because the client doesn't support more than five. What you could try though is to raise the limit and recompile rathena. You can find the definition of the limit in the mmo.hpp on line 117. #define MAX_BARTER_REQUIREMENTS 5