Jump to content

Winterfox

Members
  • Posts

    236
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Winterfox

  1. https://www.divine-pride.net/database/item/18935/there-is-something-1
  2. You can generate the navigation information of the npcs for the client by running navigenerator in the server root directory. Afterward, you can find the clientside files in the folder generated/clientside and copy that into your client root directory.
  3. Winterfox

    Autoplay

    Version 1.0.0

    4 downloads

    This is a command that basically turns a character into a bot. No source changes required. Once a player with the proper permissions uses this command, the character will start to walk around the map and attack all mobs it sees automatically. Warps are ignored and most functions like chatting etc. are disabled while in autoplay mode. Autoplay is disabled automatically when the character dies while it is active. The following things are configurable: The radius the character searches for mobs around itself. The maximum radius the player walks per move. The timeout when a character fails to attack a mob. The minimal group level to use the command. Updates and bug fixes are free and will be available here for all customers. Costumers can contact me via discord for support. My username there is hope2812.
    60.00 USD
  4. Version 1.0.0

    4 downloads

    In this game, you can place bets on one of 5 slots. Each slot has a different chance to be picked, but also gives a higher reward, the lesser the chance. After enough bets are placed, a player can pay a fee to spin the wheel. After a certain amount of time, one slot is picked and the winners can get their prize. This script is resistant to server restarts and script reloads. It always keeps track of all currently placed bets and prizes a player has. If the player is offline during a spin but wins, he gets a notification on the next login that he has pending prizes. The following things are customizable via config variables: Price per spin. Amount of bets before a spin can be started. The item used as currency for the game. The minimum amount for a bet. The sprite, name, color, bonus on win and position of each slot selection. The position and type of each slot. Updates and bug fixes are free and will be available here for all customers. Costumers can contact me via discord for support. My username there is hope2812.
    60.00 USD
  5. - script FREEZE FAKE_NPC,{ OnInit: .@group = 99; bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze", .@group); bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze", .@group); end; OnFreeze: .@mode = 1; OnUnfreeze: getmapunits(BL_PC, .@atcmd_parameters$[0], .@players); freeloop(1); for(.@i = 0; .@i < getarraysize(.@players); .@i++) pcblockmove(.@players[.@i], .@mode); freeloop(0); }
  6. Well, you wanted to be able to give it a map, so you must provide a map as first parameter: @freeze prontera.
  7. That is possible via Script, but I am not sure how well it scales for many players at the same time.
  8. - script FREEZE FAKE_NPC,{ OnInit: bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze"); bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze"); end; OnFreeze: .@mode = 1; OnUnfreeze: getmapunits(BL_PC, .@atcmd_parameters$[0], .@players); freeloop(1); for(.@i = 0; .@i < getarraysize(.@players); .@i++) pcblockmove(.@players[.@i], .@mode); freeloop(0); }
  9. I didn't test it, but this should do what you want. - script FREEZE FAKE_NPC,{ OnInit: bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze"); bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze"); end; OnFreeze: .@mode = 1; OnUnfreeze: getmapunits(BL_PC, getarg(0), .@players); freeloop(1); for(.@i = 0; .@i < getarraysize(.@players); .@i++) pcblockmove(.@players[.@i], .@mode); freeloop(0); }
  10. Your pick code throws 4 dice with 10 eyes and checks if at least one fits, and then picks an item randomly. Which means your script decides if it should give loot or not (Which contradicts your 4. Rule) but in case it drops an item, it gives every item an equal chance to be dropped. Except Yggrasil Berry, which gets a 1% chance to be dropped regardless of if there was already a drop, which also contradicts your 4. Rule. Here is what I would do to change your script to make it fit your given rules: prt_fild00,278,237,0 script Fishing School 10065,{ if (!isequipped(.rod)) { dispbottom("[Fishing] You need a Fishing Rod."); end; } specialeffect(EF_BUBBLE, "Fishing School"); soundeffect("_attack_axe.wav", 0); dispbottom("[Fishing] Casting..."); progressbar("ffffff", .cast_delay); .@pick = rand(1, .catch_weight_sum); for(.@i = 0; .@i < getarraysize(.catches); .@i += 2) { .@pick -= .catches[.@i + 1]; if(.@pick <= 0) { .@catch = .catches[.@i]; break; } } getitem(.@catch, 1); specialeffect2(610); soundeffectall("see_otter_damage.wav", 0, strcharinfo(3)); dispbottom("[Fishing] You got "+ getitemname(.@catch) + "."); end; OnInit: .rod = 2764; .cast_delay = 5; // Red Herb 40%; Yellow Herb 30%; White Herb 20%, Blue Herb 10%, Yggdrasil Berry 0.01% setarray(.catches, 507, 4000, 508, 3000, 509, 2000, 510, 1000, 607, 1); for(.@i = 0; .@i < getarraysize(.catches); .@i += 2) .catch_weight_sum = .catches[.@i + 1]; }
  11. You are right, it doesn't seem like you can put anything inside the condition argument of the questinfo function that doesn't return a value directly. It simply evaluates if the result of the script in the conditions string results in true or false, when certain events like the completion of a quest trigger a reevaluation. That means you can only use functions that the script engine knows and that return a value. So what you can do alternatively is to build the condition string dynamically. prontera,150,193,4 script DEMO 124,{ OnInit: setarray(.@quests, 11114, 11115, 11116, 11117, 11118, 11119, 11120, 11121, 11122, 11123); for(.@i = 0; .@i < getarraysize(.@quests); .@i++) .@condition$[.@i] = "checkquest(" + .@quests[.@i] + ", HUNTING) == 2"; questinfo(QTYPE_QUEST, QMARK_YELLOW, implode(.@condition$, "||")); }
  12. - script SKILL_DEMO FAKE_NPC,{ OnInit: monster("prontera", 150, 170, "Helper A", 1002, 1); .@mob_a = $@mobid[0]; unitblockmove(.@mob_a, 1); getunitdata(.@mob_a, .@mob_a_data); .@pos_x = .@mob_a_data[UMOB_X]; .@pos_y = .@mob_a_data[UMOB_Y]; monster("prontera", 140, 160, "Helper B", 1002, 1); .@mob_b = $@mobid[0]; while(.@pos_x != .@target_x || .@pos_y != .@target_y) { getunitdata(.@mob_b, .@mob_b_data); .@target_x = .@mob_b_data[UMOB_X]; .@target_y = .@mob_b_data[UMOB_Y]; if(.@pos_x != .@target_x) .@pos_x += (.@pos_x < .@target_x) ? 1 : -1; if(.@pos_y != .@target_y) .@pos_y += (.@pos_y < .@target_y) ? 1 : -1; unitskillusepos(.@mob_a, "MG_THUNDERSTORM", 10, .@pos_x, .@pos_y, -5, false, 0, true); sleep(1000); } }
  13. It is hard to really optimize the script without knowing the whole code. But to make the snippet you have more manageable, you could organize your code like this: for(.@i = 0; .@i < 20; .@i++) { if(isbegin_quest(19000 + .@i) > 0) { .@has_quest = 1; break; } } if(getmonsterinfo(killedrid, MOB_MVPEXP) > 1 && .@has_quest) { }
  14. I am not sure if there is an effect that makes it look like a character attacks. Another idea I had would be to spawn an invisible mob below the ore NPC when the player meets the requirements, and then to set him up to attack that mob and lock him in this state until he killed the ore mob. When the ore mob is dead, you can hide the npc for the player for a certain amount of time. For the part of making a player attack a mob and blocking movement, you could check the commands: unitattack and, setpcblock that could help you with that. In general, the unit commands could be of help to you. For the part about visibility of ores, you could use the on touch area of the npc and combine that with cloakonnpc or cloakonnpcself to control which players can see the npc right now.
  15. You could attach the checks on a label that gets triggered when the mob that represents an ore gets killed. Here is a small example: - script MINING FAKE_NPC,{ OnInit: // Config setarray(.mining_utils, 28116); setarray(.minerals, 3742, 3743, 1083); .mineral_0_name$ = "Bronze"; setarray(.mineral_0_maps$, "prontera"); setarray(.mineral_0_amounts, 10); setarray(.mineral_0_areas_x_1, 150); setarray(.mineral_0_areas_x_2, 163); setarray(.mineral_0_areas_y_1, 175); setarray(.mineral_0_areas_y_2, 137); setarray(.mineral_0_items, 502, 10, 1, 5, 503, 40, 1, 5, 504, 50, 1, 5); .mineral_1_name$ = "Silver"; setarray(.mineral_1_maps$, "prontera"); setarray(.mineral_1_amounts, 10); setarray(.mineral_1_areas_x_1, 150); setarray(.mineral_1_areas_x_2, 163); setarray(.mineral_1_areas_y_1, 150); setarray(.mineral_1_areas_y_2, 200); setarray(.mineral_1_items, 505, 10, 1, 5, 506, 40, 1, 5, 507, 50, 1, 5); .mineral_2_name$ = "Gold"; setarray(.mineral_2_maps$, "prontera"); setarray(.mineral_2_amounts, 10); setarray(.mineral_2_areas_x_1, 150); setarray(.mineral_2_areas_x_2, 163); setarray(.mineral_2_areas_y_1, 175); setarray(.mineral_2_areas_y_2, 137); setarray(.mineral_2_items, 508, 10, 1, 5, 509, 40, 1, 5, 510, 50, 1, 5); // Config End for(.@i = 0; .@i < getarraysize(.minerals); .@i++) { .@name$ = getd(".mineral_" + .@i + "_name$"); .@items = getd(".mineral_" + .@i + "_items"); .@items_size = getarraysize(getd(".mineral_" + .@i + "_items")); .@item_sum = 0; for(.@x = 0; .@x < .@items_size; .@x += 4) .@item_sum += getd(".mineral_" + .@i + "_items[" + (.@x + 1) + "]"); setd(".mineral_" + .@i + "_item_sum", .@item_sum); .@maps_size = getarraysize(getd(".mineral_" + .@i + "_maps$")); for(.@y = 0; .@y < .@maps_size; .@y++) { .@maps$ = getd(".mineral_" + .@i + "_maps$[" + .@y + "]"); .@amounts = getd(".mineral_" + .@i + "_amounts[" + .@y + "]"); .@areas_x_1 = getd(".mineral_" + .@i + "_areas_x_1[" + .@y + "]"); .@areas_x_2 = getd(".mineral_" + .@i + "_areas_x_2[" + .@y + "]"); .@areas_y_1 = getd(".mineral_" + .@i + "_areas_y_1[" + .@y + "]"); .@areas_y_2 = getd(".mineral_" + .@i + "_areas_y_2[" + .@y + "]"); areamonster(.@maps$, .@areas_x_1, .@areas_x_2, .@areas_y_1, .@areas_y_2, .@name$, .minerals[.@i], .@amounts, "MINING::OnMined"); } } end; OnMined: .@mineral = inarray(.minerals, killedrid); .@mineral_name$ = getd(".mineral_" + .@mineral + "_name$"); .@util = getequipid(EQI_HAND_R); if(inarray(.mining_utils, .@util) == -1) { dispbottom("Using your " + getitemname(.@util) + " destroyed any useful resource from " + .@mineral_name$ + "."); end; } .@mineral_item_sum = getd(".mineral_" + .@mineral + "_item_sum"); .@mineral_items_size = getarraysize(getd(".mineral_" + .@i + "_items")); .@pick = rand(1, .@mineral_item_sum); for(.@i = 0; .@i < .@mineral_items_size; .@i += 4) { .@pick -= getd(".mineral_" + .@mineral + "_items[" + (.@i + 1) + "]"); if(.@pick <= 0) break; } .@item = getd(".mineral_" + .@mineral + "_items[" + .@i + "]"); .@item_min_amount = getd(".mineral_" + .@mineral + "_items[" + (.@i + 2) + "]"); .@item_max_amount = getd(".mineral_" + .@mineral + "_items[" + (.@i + 3) + "]"); getitem(.@item, rand(.@item_min_amount, .@item_max_amount)); } This will spawn different minerals (in this example represented by purple ore and plants), which give different items on kill etc. once a mineral gets killed, it checks if an item from the .mining_utils array is equipped and if not gives the player the message, that using the wrong item destroyed any useful resources otherwise it will roll which and how many of an item the player gets.
  16. The easiest way would be to create a custom mob that looks like a mineral. You could for example copy Purple Ore (id: 3742) and add the items you want the player to get by mining as drop. You just need to remember to add your custom mob to mob_avail,yml to tell rathena to make the client use the sprite of the original mob for your custom one.
  17. 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]; }
  18. Where is the value for #daily_minute_count set?
  19. 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.
  20. They use different item dbs, did you put the item in both?
  21. 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`;
  22. 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;
  23. 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]; }
  24. I think that this is a thing you need to fix in the source.
×
×
  • Create New...