-
Posts
248 -
Joined
-
Last visited
-
Days Won
19
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Everything posted by Winterfox
-
These cooldowns are made with the quest commands. It works by giving the player a quest that has an expiration time. Here is a small example: prontera,124,201,1 script Example NPC 726,{ // Check if the time limit is still running. if(checkquest(200000, PLAYTIME) == 0) { mes "Example"; mes "I am still preparing the cake, please wait!"; close; } // Check if the time limit expired. if(checkquest(200000, PLAYTIME) == 2) { mes "Example"; mes "Finally! Here is your cake!"; erasequest(200000); getitem(12062, 1); close; } // Give the quest with the time limit mes "Example"; mes "Hello, how may i help you?"; mes "Oh, a free special cake?"; mes "Sure, i will bake you a fresh one."; mes "Please come back in 5 minutes!"; setquest(200000); close; } The actual quest and time limit is defined in the quest_db.yml. For the Example NPC the entry would look like this: - Id: 200000 Title: "Example Cake Timer" TimeLimit: +5mn If you want to show the quest info in the client like in your screenshot, you need to edit the System/OngoingQuestInfoList_True_EN.lub. For the quest in the example, the entry could look like this: [200000] = { Title = "Example Cake Timer", Description = { "Wait for Example to prepare your cake." }, Summary = "" }
-
There is a sample in the docs under doc/samples/instancing.txt. Please note the comment that says you need to add the instance to the database, for the script to work. It is in the old format, but you shouldn't have issues to convert it to the yaml version. //===== rAthena Script ======================================= //= Sample: Instancing //===== By: ================================================== //= Euphy //===== Last Updated: ======================================== //= 20140129 //===== Description: ========================================= //= Contains elements of a basic instance script. //============================================================ // Before running this script, add the entry below to // 'db/(pre-)re/instance_db.txt': // 100,Abyss Lake Instance,3600,300,abyss_03,160,155 // Instance Creation //============================================================ prontera,151,190,6 script Sample Instance 101,{ .@instance$ = "Abyss Lake Instance"; if (instance_live_info(ILI_NAME, instance_id(IM_PARTY)) == .@instance$) { // the instance "Abyss Lake Instance" is running mes "[Sample Instance]"; mes "You are already part of an instance."; next; switch(select("Enter Instance.:Cancel.")) { case 1: break; case 2: mes "[Sample Instance]"; mes "You don't want to try again?"; emotion ET_CRY; close; } } else if (instance_id(IM_PARTY)) { // another instance is running mes "[Sample Instance]"; mes "You are part of the instance " + instance_live_info(ILI_NAME, instance_id(IM_PARTY)) + "."; close; } else { mes "[Sample Instance]"; mes "Would you like to try the sample instance in Abyss Lake 3?"; next; switch(select("Create Instance.:Cancel.")) { case 1: .@create = instance_create(.@instance$); if (.@create < 0) { mes "[Sample Instance]"; switch (.@create) { case -1: mes "ERROR: Invalid type."; break; case -2: mes "ERROR: Party not found."; break; case -3: mes "ERROR: Instance already exists."; break; case -4: mes "ERROR: No free instances."; break; } mes " "; mes "Instance creation ^FF0000failed^000000."; emotion ET_HUK; close; } mes "[Sample Instance]"; mes "Instance created."; mes " "; mes "Now entering the instance..."; next; break; case 2: mes "[Sample Instance]"; mes "Okay. Maybe next time!"; close; } } .@enter = instance_enter(.@instance$); if (.@enter != 0) { mes "[Sample Instance]"; switch (.@enter) { case 1: mes "ERROR: Party not found."; break; case 2: mes "ERROR: Party does not have an instance."; break; case 3: mes "ERROR: Unknown error."; break; } mes " "; mes "Instance entry ^FF0000failed^000000."; emotion ET_HUK; close; } close; } // Instance Scripts //============================================================ abyss_03,154,159,6 script Instance NPC#start 101,{ mes "[Instance NPC]"; mes "Are you ready to begin?"; next; switch(select("Yes.:No.")) { case 1: mes "[Instance NPC]"; mes "Good luck."; close2; donpcevent instance_npcname("#ins_abyss03_mobs")+"::OnEnable"; delwaitingroom; disablenpc instance_npcname(strnpcinfo(0)); end; case 2: mes "[Instance NPC]"; mes "Take your time."; close; } end; OnInit: // hide the NPC on the normal map disablenpc strnpcinfo(0); end; OnInstanceInit: // initialize the NPC when the instance is created disablenpc instance_npcname("abysslakedunwarp004"); // disable original warp portal (currently buggy) waitingroom "Click here to start!",0; end; } abyss_03,0,0,0 script #ins_abyss03_mobs -1,{ end; OnEnable: initnpctimer; end; OnTimer1000: //strnpcinfo(4) will retrieve the instanced map name mapannounce strnpcinfo(4),"Instance NPC: The Abyss Lake instance has begun.",bc_all; end; OnTimer4000: mapannounce strnpcinfo(4),"Instance NPC: Smash the Treasure Chest in the center of the map for a prize.",bc_all; end; OnTimer5000: stopnpctimer; // spawn mobs .@map$ = instance_mapname("abyss_03"); .@label$ = instance_npcname(strnpcinfo(0))+"::OnMyMobDead"; .@label_boss$ = instance_npcname(strnpcinfo(0))+"::OnMyBossDead"; monster .@map$,0,0,"Huge Poring",1002,20,.@label$,2; monster .@map$,0,0,"Huge Drops",1113,15,.@label$,2; monster .@map$,0,0,"Huge Poporing",1031,10,.@label$,2; monster .@map$,0,0,"Huge Marin",1242,10,.@label$,2; monster .@map$,0,0,"Tiny Zombie",1015,30,.@label$,1; monster .@map$,0,0,"Huge Mime Monkey",1585,2,.@label$,2; monster .@map$,97,102,"Treasure Chest",1732,1,.@label_boss$,2; end; OnMyMobDead: // normal mobs dispbottom "What am I doing? I should be attacking the Treasure Chest!"; viewpoint 0,97,102,0,0xFF0000; switch (rand(6)) { // for fun (: case 0: sc_start SC_STONE,5000,0; break; case 1: sc_start SC_FREEZE,5000,0; break; case 2: sc_start SC_STUN,5000,0; break; case 3: sc_start SC_SLEEP,5000,0; break; case 4: sc_start SC_CONFUSION,5000,0; break; case 5: sc_start SC_BLIND,5000,0; break; } end; OnMyBossDead: // treasure chest specialeffect2 EF_MVP; getitem 512,1; //Apple // trigger other events .@map$ = instance_mapname("abyss_03"); .@label$ = instance_npcname(strnpcinfo(0))+"::OnMyMobDead"; killmonster .@map$,.@label$; mapannounce .@map$,"Instance NPC: Good work! Please speak to me as soon as possible.",bc_all; donpcevent instance_npcname("Instance NPC#finish")+"::OnEnable"; end; } abyss_03,97,102,4 script Instance NPC#finish 101,{ mes "[Instance NPC]"; mes "Congratulations! You've finished the instance."; mes "I'll send you back to town now."; emotion ET_BEST; close2; warp "prontera",156,191; instance_destroy(); end; OnInit: disablenpc strnpcinfo(0); end; OnInstanceInit: disablenpc instance_npcname(strnpcinfo(0)); end; OnEnable: enablenpc instance_npcname(strnpcinfo(0)); specialeffect EF_HIDING; end; } abyss_03,115,26,0 script #ins_abyss03_warp 45,5,5,{ end; OnTouch: mes "Are you sure you want to leave?"; next; switch(select("Leave.:Stay.")) { case 1: warp "prontera",156,191; break; case 2: warp strnpcinfo(4),160,155; break; } close; OnInit: disablenpc strnpcinfo(0); end; }
-
Did you add the pvp_n4-5 map to the castle_db.yml? I don't think that is necessary for it to work. But if you want to keep it in the castle_db.yml, you need to add the gvg_castle mapflag to your script.
-
Is Emp Room Breaker another script, or what do you mean by that?
-
You can use the item scripts and use the @size command on equip and unequip. Example: - Id: 4126 AegisName: Minorous_Card Name: Minorous Card Type: Card Buy: 20 Weight: 10 Locations: Right_Hand: true Flags: BuyingStore: true DropEffect: CLIENT Script: | atcommand("@size 2"); bonus2 bAddSize,Size_Large,15; bonus bBaseAtk,5; UnEquipScript: | atcommand("@size 0");
-
You should really consider to research before you ask such questions. YAML isn't really hard to understand, the rAthena databases are well documented and the data you want to convert isn't really complex. Here is a good guide for YAML: https://learnxinyminutes.com/docs/yaml/ And an example how the conversion in your specific case looks: - Id: 100 Map: guild_vs1 Name: King of Emperium Hill Npc: koe
-
You use strcharinfo(3) which first of all returns a string, so your calculation fails and second it returns the name of the map the character is in, which sure isn't what you want. .@price = .@base_price * strcharinfo(3); *strcharinfo(<type>{,<char_id>}) This function will return either the name, party name or guild name for the invoking character. Whatever it returns is determined by type. To get the level of a character, you can simply use the BaseLevel variable, which is pre-defined by rAthena. This should do what you want: .@price = .@base_price * BaseLevel; Also, since you always need the same base price, you could move the variable to OnInit and use a NPC variable. This saves your script from having to assign the variable on every call. Probably this isn't really crucial performancewise, but it also helps to organize your script better, because you can use NPC variables globally in your NPC, you can use them anywhere you want and know they are defined. Lastly, you are writing the zeny price hard in your string. I assume because you want it to be comma separated. You can achieve this dynamically with the global F_InsertComma function. Here is an example of the script you provided, with what I mean: - script BUFF_CMD FAKE_NPC,{ OnInit: .basePrice = 5000; // ราคาพื้นฐานสำหรับการให้บัฟ bindatcmd "buff", strnpcinfo(0) + "::OnCommand"; end; OnCommand: .@price = BaseLevel * .basePrice; if ( getmapflag(strcharinfo(3), MF_PVP) || getmapflag(strcharinfo(3), MF_BATTLEGROUND) || getmapflag(strcharinfo(3), MF_GVG) ) { mes "ใช้ไม่ได้ในแผนที่ PVP/BG/WOE"; close; } if ( Zeny < .@price ) { mes "ต้องใช้เงิน " + F_InsertComma(.@price) + "z. ในการกดใช้บัฟ"; close; } if ( select("บัฟเลย " + F_InsertComma(.@price) + "z ก็ไหว!","ไม่เอาดีกว่า!") == 2 ) { mes "แค่ " + F_InsertComma(.@price) + "z ก็ยัง ^FF0000งก^000000 เนอะ"; mes "ตีมอนแปปเดียวก็ได้แล้ว"; mes "ฆ่ามอนยังไงก็ได้เงินไปด้วยอยู่แล้ว"; close; } Zeny -= .@price; // บัฟที่ได้ specialeffect2(42); sc_start(SC_BLESSING, 3600000, 10); specialeffect2(37); sc_start(SC_INCREASEAGI, 3600000, 10); specialeffect2(112); sc_start(SC_KYRIE, 3600000, 10); specialeffect2(76); sc_start(SC_MAGNIFICAT, 3600000, 10); mes "จัดไป!"; mes "ขอให้มีความสุขกับการเก็บเลเวล!"; mes "ด้วยความปรารถนาดีจาก TooHard-RO!"; close; }
-
About Euphy and sader1992 auto potion script
Winterfox replied to cahadeyelo's question in Scripting Support
The script checks the type of the item via getiteminfo which fails. So it seems your database is wrong. No idea which rAthena version you are using, but maybe it is too old.- 1 reply
-
- 1
-
-
For Visual Studio Code you could use the rAthena Language Support plugin to have highlighting and snippets. You can get it here: https://marketplace.visualstudio.com/items?itemName=rAthena.rathena-language-support
-
yggdrasil01,194,95,0 script Cultivated Soil HIDDEN_NPC,{ if(CSOIL_GROWTH_DURATION == 0 && countitem(.plantItemId) < .plantItemAmt) { mes "You need " + .plantItemAmt + " x " + getitemname(.plantItemId) + " to use the cultivated soil."; close; } if(CSOIL_GROWTH_DURATION == 0) { delitem(.plantItemId, .plantItemAmt); mes "Seed planted. Let's wait " + .growthDays + " days before harvesting."; CSOIL_GROWTH_DURATION = gettimetick(2) + (.growthDays * 86400); close; } if (gettimetick(2) > CSOIL_GROWTH_DURATION) { getitem(.grownItemId, .grownItemAmt); CSOIL_GROWTH_DURATION = 0; end; } mes "This is still not ripe for the picking."; mes "Let's wait until it's ready for harvest."; close; OnInit: .growthDays = 10; .plantItemId = 512; .plantItemAmt = 1; .grownItemId = 607; .grownItemAmt = 1; }
-
attach monster summoned to the guild of the player who summon it.
Winterfox replied to laonglaing's question in Script Requests
That isn't something that is possible via scripting right now. You should post your request in the Source section. -
You need to search the skill you want to change in the status.yml and under Flags you have to set NoSave to true. Here is an example from the original files: - Status: Bleeding Icon: EFST_BLOODING DurationLookup: NPC_BLEEDING CalcFlags: Regen: true Opt2: Bleeding: true Flags: SendOption: true BossResist: true NoSave: true NoClearance: true RemoveOnHermode: true Fail: Refresh: true Inspiration: true
-
- script ZENY_CONVERTER FAKE_NPC,{ OnConvert: .@amt = floor(Zeny / .convZeny, 1); if(.@amt <= 0) { dispbottom("You don't have enough zeny for a conversion. You need atleast " + callfunc("F_InsertComma", .convRate) + "z."); end; } .@price = .@amt * .convZeny; Zeny -= .@price; getitem(.itemId, .@amt * .convItem); dispbottom(callfunc("F_InsertComma", .@price) + " of your zeny got converted to " + .@amt + " x " + getitemname(.itemId)); end; OnInit: .itemId = 22787; .convItem = 1; .convZeny = 100000000; bindatcmd("convert", strnpcinfo(3) + "::OnConvert"); }
-
The changed clif.cpp uses npc_duplicate_npc_for_player when you click the button. That function is what spawns the NPC near your character. So that is not a scripting issue, but one you will have to solve via modifying the source code so that the NPC gets called instead of being spawned near the character.
-
There is nothing in that script that would make it spawn near your character. It sounds like you use duplicate_dynamic which spawns a copy of a NPC near your character. Also it doesn't make sense for a NPC that you don't want to be visible to have data about the map and sprite. - script Hourly Point Manager::GOLDPCCAFE FAKE_NPC,{ cutin("ep18_merchant.png", 2); callshop("hourly_shop", 1); npcshopattach("hourly_shop"); end; OnBuyItem: mes("[Hourly Point Manager]"); if (!checkweight2(@bought_nameid, @bought_quantity)) { mes("Sorry, you can't carry all these items!"); close3; } for (.@i = 0; .@i < getarraysize(@bought_nameid); .@i++){ .@itemIndex = inarray(.Shop, @bought_nameid[.@i]); .@costs += (.Shop[.@itemIndex + 1] * @bought_quantity[.@i]); } if (.@costs > Goldpc_Points) { mes("You don't have enough Hourly Points."); close3; } Goldpc_Points -= .@costs; for(.@i = 0; .@i < getarraysize(@bought_nameid); .@i++) { getitem(@bought_nameid[.@i], @bought_quantity[.@i]); dispbottom("Purchased " + @bought_quantity[.@i] + " x " + getitemname(@bought_nameid[.@i]) + "."); } mes("Purchased successfully!"); mes("You have ^0000ff" + Goldpc_Points + "^000000 points remaining."); close3; OnInit: setarray(.Shop[0], 13534, 1, 13810, 1, 14532, 1, 14606, 1, 12211, 1, 7776, 25); npcshopitem("hourly_shop", 13534, 1, 13810, 1, 14532, 1, 14606, 1, 12211, 1, 7776, 25); }
-
I think that is a request for the source mod section.
- 1 reply
-
- 1
-
-
- script WOE_ITEM_RESTRICTION FAKE_NPC, { OnInit: setarray(.woeMaps$[0], "prtg_cas01", "prtg_cas02", "prtg_cas03", "prtg_cas04", "prtg_cas05", "payg_cas01", "payg_cas02", "payg_cas03", "payg_cas04", "payg_cas05", "gefg_cas01", "gefg_cas02", "gefg_cas03", "gefg_cas04", "gefg_cas05", "aldeg_cas01", "aldeg_cas02", "aldeg_cas03", "aldeg_cas04", "aldeg_cas05", "arug_cas01", "arug_cas02", "arug_cas03", "arug_cas04", "arug_cas05", "schg_cas01", "schg_cas02", "schg_cas03", "schg_cas04", "schg_cas05"); end; OnPCLoadMapEvent: if(!inarray(.woeMaps$, strcharinfo(3)) || (!isequipped(45097) && !isequipped(45166))) end; mes "You can't wear Spiderman or Akatsuki suit on this map!"; close2; warp("Save", 0, 0); } prtg_cas01 mapflag loadevent prtg_cas02 mapflag loadevent prtg_cas03 mapflag loadevent prtg_cas04 mapflag loadevent prtg_cas05 mapflag loadevent payg_cas01 mapflag loadevent payg_cas02 mapflag loadevent payg_cas03 mapflag loadevent payg_cas04 mapflag loadevent payg_cas05 mapflag loadevent gefg_cas01 mapflag loadevent gefg_cas02 mapflag loadevent gefg_cas03 mapflag loadevent gefg_cas04 mapflag loadevent gefg_cas05 mapflag loadevent aldeg_cas01 mapflag loadevent aldeg_cas02 mapflag loadevent aldeg_cas03 mapflag loadevent aldeg_cas04 mapflag loadevent aldeg_cas05 mapflag loadevent arug_cas01 mapflag loadevent arug_cas02 mapflag loadevent arug_cas03 mapflag loadevent arug_cas04 mapflag loadevent arug_cas05 mapflag loadevent schg_cas01 mapflag loadevent schg_cas02 mapflag loadevent schg_cas03 mapflag loadevent schg_cas04 mapflag loadevent schg_cas05 mapflag loadevent
-
The circle with the arrow in it at the right bottom of the post you want to like.
-
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 " + .itemCostAmount + " ^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; } .@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!"; 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; OnInit: .itemCostAmount = 2; }
-
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; }
-
function script ZENYLADDER { query_sql("SELECT `c`.`name`, `c`.`class`, `c`.`base_level`, `c`.`job_level`, `c`.`zeny`, `g`.`name` FROM `char` c LEFT JOIN (`guild` g) ON (`c`.`guild_id` = `g`.`guild_id`) ORDER BY `c`.`zeny` DESC LIMIT 100", .@names$, .@classes, .@blvls, .@jlvls, .@zeny, .@guilds$); mes "[ INFORMATION ]"; for(.@i = 0; .@i < 100; .@i++) mes "^0000FF" + (.@i + 1) + ".^000000 " + .@names$[.@i] + " - ^FF0000" + callfunc("F_InsertComma", .@zeny[.@i]) + "^000000z"; close; }
-
I didn't see any security issues, but two small things that could be handled a bit smoother. The first is to add a check if the items bought can be carried by the player. if (!checkweight2(@bought_nameid, @bought_quantity)) { mes("Sorry, you can't carry all these items!"); close3; } The second is that if you use shop and the player has not enough zeny even though you want to pay with points, he can't put the item in the buy window. So pointshop is the better option. - pointshop hourly_shop -1,Goldpc_Points,13534:-1. If you use pointshop you also could omit the whole npcshopattach implementation, if you do not care about the cutin and the message boxes in between. Putting the two above mentioned changes into you npc it could look like this: - pointshop hourly_shop -1,Goldpc_Points,13534:-1. prontera,156,181,5 script Hourly Point Manager::GOLDPCCAFE 10380,{ cutin("ep18_merchant.png", 2); callshop("hourly_shop", 1); npcshopattach("hourly_shop"); end; OnBuyItem: mes("[Hourly Point Manager]"); if (!checkweight2(@bought_nameid, @bought_quantity)) { mes("Sorry, you can't carry all these items!"); close3; } for (.@i = 0; .@i < getarraysize(@bought_nameid); .@i++){ .@itemIndex = inarray(.Shop, @bought_nameid[.@i]); .@costs += (.Shop[.@itemIndex + 1] * @bought_quantity[.@i]); } if (.@costs > Goldpc_Points) { mes("You don't have enough Hourly Points."); close3; } Goldpc_Points -= .@costs; for(.@i = 0; .@i < getarraysize(@bought_nameid); .@i++) { getitem(@bought_nameid[.@i], @bought_quantity[.@i]); dispbottom("Purchased " + @bought_quantity[.@i] + " x " + getitemname(@bought_nameid[.@i]) + "."); } mes("Purchased successfully!"); mes("You have ^0000ff" + Goldpc_Points + "^000000 points remaining."); close3; OnInit: setarray(.Shop[0], 13534, 1, 13810, 1, 14532, 1, 14606, 1, 12211, 1, 7776, 25); npcshopitem("hourly_shop", 13534, 1, 13810, 1, 14532, 1, 14606, 1, 12211, 1, 7776, 25); }
-
//===== rAthena Script ======================================= //= Banker Script //===== By: ================================================== //= Syrus22 (1.0) //===== Current Version: ===================================== //= 2.0 //===== Compatible With: ===================================== //= rAthena Project //===== Description: ========================================= //= An account wide Banker to store Zeny //===== Additional Comments: ================================= //= Syrus22 - There's an optional transaction fee at the top of //= the script. To use it simply change the first set command //= to set the cost variable to whatever you want the fee to be. //= Version 2.0: Optimized and brought the script up to standard. [Jguy] //============================================================ verus04,174,216,5 script Banker 109,{ //prontera,132,217,5 script Banker 109,{ mes "[Banker]"; mes "Welcome to the First Bank of Prontera. How can I help you today?"; next; switch(select("I'd like to make a deposit.:I'd like to make a withdrawal.:What's my current balance?:Cancel")) { case 1: mes "[Banker]"; mes "Very well... How much would you like to deposit? The maximum you can deposit at once is ^00FF00999,999^000000 zeny."; next; if (.transactionFee > 0) { mes "[Banker]"; mes "Oh, and do realize there is a ^00FF00" + .transactionFee + "^000000 zeny charge on all transactions!"; next; } input(.@deposit); if (.@deposit < 1) { mes "[Banker]"; mes "Make sure you ask me to deposit a real amount."; close; } if (.@deposit > Zeny) { mes "[Banker]"; mes "It does not appear like you have the amount of zeny you're trying to deposit!"; close; } if (.@deposit + .transactionFee > Zeny) { mes "[Banker]"; mes "You need ^00FF00" +.transactionFee + "^000000 Zeny to cover the transaction fee!"; close; } if(#bankstorage + .@deposit > .maxDeposit) { mes "[Banker]"; mes "Your deposit would break the limit of ^00FF00" + .maxDeposit + "^000000 zeny!"; close; } Zeny -= .@deposit + .transactionFee; #bankstorage += .@deposit; mes "[Banker]"; mes "Thank you very much... Your zeny is in good hands."; close; case 2: mes "[Banker]"; mes "Very well... How much would you like to withdraw? The maximum you can withdraw at one time is ^00FF00999,999^000000 zeny"; next; if (.transactionFee > 0) { mes "[Banker]"; mes "Oh, and do realize there is a ^00FF00" + .transactionFee + "^000000 zeny charge on all transactions!"; next; } input(.@withdrawal); if (.@withdrawal < 1) { mes "Please don't play games. I need a real amount to withdraw."; close; } if (.@withdrawal > #bankstorage) { mes "You only have ^00FF00" + callfunc("F_InsertComma", #bankstorage) +"^000000 zeny in your account!"; close; } if (.transactionFee > Zeny && .@withdrawal > .transactionFee) { mes "[Banker]"; mes "You don't have the Zeny for the transaction fee right now. Would you like me to take the fee directly from your withdrawal?"; next; switch(select("Yes please.:No, Thanks")) { case 1: mes "[Banker]"; mes "Removing ^00FF00" + .transactionFee + "^000000 from your withdrawal to cover the deposit fee..."; .@withdrawal -= .transactionFee; #bankstorage -= .transactionFee; next; #bankstorage -= .@withdrawal; Zeny += .@withdrawal; mes "[Banker]"; mes "There's your Zeny. Have a good day."; close; case 2: mes "[Banker]"; mes "Very well... come again soon."; close; } } if(.transactionFee > Zeny) { mes "[Banker]"; mes "You need ^00FF00" + .transactionFee + "^000000 zeny to cover the transaction fee!"; close; } #bankstorage -= .@withdrawal; Zeny -= .transactionFee; Zeny += .@withdrawal; mes "[Banker]"; mes "There's your zeny. Have a good day."; close; case 3: mes "[Banker]"; mes "Hmmmm... let me check some paper work."; next; mes "*Rustle, Rustle*"; next; mes "[Banker]"; mes "You currently have ^00FF00" + callfunc("F_InsertComma", #bankstorage) + "^000000 zeny in your account."; close; case 4: mes "[Banker]"; mes "Very well... come again soon."; close; } OnInit: .transactionFee = 500; .maxDeposit = 1000000; }
- 1 reply
-
- 1
-
-
verus04,165,217,4 script MARS_01#pa0829 4_SCR_MT_ROBOTS,{ disable_items; if (checkweight(1201,1) == 0 || (MaxWeight - Weight) < 10000) { mes "^ff0000You have carried too many items, please reduce it and come back later.^000000"; close; } switch( isbegin_quest(12368) ) { case 0: mes "Blurred LCD screen may be frightened or happy and intense shaking, perhaps due to lack of power and can not complete the presentation."; next; if (select( "Just ignore it.", "Press every button." ) == 1) { mes "It may be a pre-scrap robot that is common everywhere and doesn't require much attention."; close; } mes "[?????]"; mes "Hello! I'm MARS_01, an exploration robot. Currently, I have entered hibernation mode to save power. The related functions are set as follows."; next; if (select( "Interrupt the machine", "Supply of fuel" ) == 1) { mes "The robot re-enters hibernation mode after a faint sound."; close; } mes "[MARS_01]"; mes "We are super power robot, as long as the old oil 1 will let me and the companion PLUTO has more than 90% of the power."; next; mes "[MARS_01]"; mes "If you find Old Fuel, please insert the fuel into the mouth of the bottom of the screen, so you can lift the hibernation mode."; setquest 12368; // Operate the old robot close; case 1: if (countitem(6962) < 1) { mes "[MARS_01]"; mes "If you find 1 " + getitemname(6962) + ", please insert the fuel into the mouth of the bottom of the screen, so you can lift the hibernation mode."; close; } mes "Maybe we ran out of power when we went looking for fuel. should we put in the fuel?"; next; if (select( "Quit.", "Put in the fuel" ) == 1) { mes "The old robot may be running out of power and not responding at all."; close; } mes "When the fuel is put in, the sound screen opens."; npctalk "Whoa, whoa?! It moves!!!", "Grandpa picking up scrap iron"; next; mes "[MARS_01]"; mes "Start the inspection system and confirm the damage of each part."; next; mes "[MARS_01]"; mes "Power meter 10%, dashboard normal, body skeleton 13%, perform mining operations well."; next; mes "[MARS_01]"; mes "Pluto_09 began to inject energy for mining auxiliary robot."; npctalk "Energy response confirmed. It's working.", "PLUTO_09#pa0829"; next; mes "[MARS_01]"; mes "Thank you for getting me started, I will reset the person who started me to be a manager."; next; select("Enter a name."); mes "[MARS_01]"; mes "" + strcharinfo(0) + ","; mes "Hello! The fuel has been fully charged."; delitem 6962,1;// OldTank completequest 12368; close; case 2: break; } mes "[MARS_01]"; mes "" + strcharinfo(0) + ","; mes "Hello! Can I help you?"; next; switch( select( "Note", "Enhanced " + getitemname(20773), "Enhanced " + getitemname(15128) , "Enhanced " + getitemname(28941), "Enhanced " + getitemname(22103) ) ) { // Excelion_Wing, Excelion_Suit, Excelion_Shield, Excelion_Leg case 1: mes "^0000ffSoon the instructions again.^000000"; next; mes "[MARS_01]"; mes "While waiting for the new owner, we continue to update to the latest version."; next; mes "[MARS_01]"; mes "If you bring aak Seri Wong propulsion wing, aak Seri Wong jacket equipment and strengthen the design, I will strengthen the equipment according to the design."; next; mes "[MARS_01]"; mes "According to the standard design drawings of the operation, the equipment will not be damaged during the process, but the number of maximum upgrade will change depending on the type of equipment."; next; mes "[MARS_01]"; mes "Welcome back again~"; close; case 2: .@part = EQI_GARMENT; break; case 3: .@part = EQI_ARMOR; break; case 4: .@part = EQI_HAND_L; break; case 5: .@part = EQI_SHOES; } // <item ID required>, <item enchant ID>, <max number of this enchant on armor>, <max number of this enchant on garment>, <max number of this enchant on shield>, <max number of this enchant on shoes>, <enchant on first slot only> setarray .@list[0], 6965, 4970, 1, 0, 1, 1, 1, // Reactor_P_FIRE_ Reactor_P_FIRE 6966, 4971, 1, 0, 1, 1, 1, // Reactor_P_WATER_ Reactor_P_WATER 6967, 4972, 1, 0, 1, 1, 1, // Reactor_P_GROUND_ Reactor_P_GROUND 6968, 4973, 1, 0, 1, 1, 1, // Reactor_P_WIND_ Reactor_P_WIND 6969, 4974, 0, 3, 1, 1, 0, // Reactor_T_FIRE_ Reactor_T_FIRE 6970, 4975, 0, 3, 1, 1, 0, // Reactor_T_WATER_ Reactor_T_WATER 6971, 4976, 0, 3, 1, 1, 0, // Reactor_T_GROUND_ Reactor_T_GROUND 6972, 4977, 0, 3, 1, 1, 0, // Reactor_T_WIND_ Reactor_T_WIND 6973, 4978, 3, 3, 1, 1, 0, // Reactor_Cure_101_ Reactor_Cure_101 6974, 4979, 3, 3, 1, 1, 0, // Reactor_Cure_102_ Reactor_Cure_102 6975, 4980, 3, 3, 1, 1, 0, // Reactor_Cure_201_ Reactor_Cure_201 6976, 4981, 3, 3, 1, 1, 0, // Reactor_Cure_202_ Reactor_Cure_202 6977, 4982, 1, 0, 1, 1, 0, // Reactor_A_STR_ Reactor_A_STR 6978, 4983, 1, 0, 1, 1, 0, // Reactor_A_INT_ Reactor_A_INT 6979, 4984, 3, 3, 1, 1, 0, // Reactor_A_DEF_ Reactor_A_DEF 6980, 4985, 1, 1, 1, 1, 0, // Reactor_A_AVOI_ Reactor_A_AVOI 6981, 4986, 3, 3, 1, 1, 0, // Reactor_A_ATK_ Reactor_A_ATK 6982, 4987, 3, 3, 1, 1, 0, // Reactor_A_MATK_ Reactor_A_MATK 6983, 4988, 3, 3, 1, 1, 0, // Reactor_A_MHP_ Reactor_A_MHP 6984, 4989, 3, 3, 1, 1, 0, // Reactor_A_MSP_ Reactor_A_MSP 6985, 4990, 1, 0, 1, 1, 0, // Reactor_A_FROZ_ Reactor_A_FROZ 6986, 4991, 1, 1, 1, 1, 0; // Reactor_A_ASPD_ Reactor_A_ASPD .@size = getarraysize(.@list); for ( .@i = 0; .@i < .@size; .@i += 7 ) { if (countitem(.@list[.@i]) < 1) .@menu$ += sprintf( "^aaaaaa%s (Missing)^000000:", getitemname(.@list[.@i]) ); else .@menu$ += sprintf( "%s:", getitemname(.@list[.@i]) ); } mes "[MARS_01]"; mes "" + strcharinfo(0) + ","; mes "Choose the enchant you want to use!"; next; .@s = select("Quit.:" + .@menu$) - 2; if (.@s < 0) { mes "[MARS_01]"; mes "So far."; close; } .@s *= 7; .@item_req = .@list[.@s]; .@item_enchant_id = .@list[.@s+1]; .@first_slot_only = .@list[.@s+6]; .@equip_id = getequipid(.@part); .@equip_refine = getequiprefinerycnt(.@part); setarray .@card[0], getequipcardid(.@part,0), getequipcardid(.@part,1), getequipcardid(.@part,2), getequipcardid(.@part,3); if (countitem(.@item_req) < 1) { mes "[MARS_01]"; mes "So far."; close; } if (.@part == EQI_ARMOR) .@max_num_enchant = .@list[.@s+2]; else if (.@part == EQI_GARMENT) .@max_num_enchant = .@list[.@s+3]; else if (.@part == EQI_HAND_L) .@max_num_enchant = .@list[.@s+4]; else if (.@part == EQI_SHOES) .@max_num_enchant = .@list[.@s+5]; else { mes "[MARS_01]"; mes "Please contact the administrator."; close; } // anti-hack if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine)) { mes "[MARS_01]"; mes "Did you remove your gear?"; close; } if (.@card[0] > 0 && .@item_enchant_id == .@card[0]) { .@slot_sum++; } if (.@card[1] > 0 && .@item_enchant_id == .@card[1]) { .@slot_sum++; } if (.@card[2] > 0 && .@item_enchant_id == .@card[2]) { .@slot_sum++; } if (.@card[3] > 0 && .@item_enchant_id == .@card[3]) { .@slot_sum++; } if (.@max_num_enchant < 1) { mes "[MARS_01]"; mes "The design you choose is incompatible with the equipment."; close; } if (.@first_slot_only > 0 && .@card[3] != 0) { mes "[MARS_01]"; mes "This design is only for the first time to strengthen the use, but the equipment has other performance, please use other design to strengthen it!"; close; } if (.@slot_sum >= .@max_num_enchant) { mes "[MARS_01]"; mes "The maximum number of enchants is " + .@max_num_enchant + ". The item has reached the upper limit."; close; } if (.@card[1] != 0) { mes "[MARS_01]"; mes "The number of equipment has reached the limit."; close; } // anti-hack if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine)) { mes "[MARS_01]"; mes "Please pay special attention if the equipment will be removed."; close; } switch( .@equip_id ) { case 20773: // Excelion_Wing case 15128: // Excelion_Suit case 28941: // Excelion Shield case 22103: // Excelion Leg break; default: mes "[MARS_01]"; mes "The product does not have a serial number, does not meet the specifications of the product can not be strengthened."; close; } mes "[MARS_01]^0000ff"; mes "Choose " + getequipname(.@part) + " + " + getitemname(.@item_req) + ","; mes "^000000------------------"; mes "Your selected design can be upgraded to the equipment limit ^0000ff" + .@max_num_enchant + " the same design, ^000000so far, enhanced ^0000ff" + .@slot_sum + " times^000000, do you want to continue?"; next; if (select( "I'll think about it...", "Go on." ) == 1) { mes "[MARS_01]"; mes "Come back next time you need me~"; close; } // anti-hack if (callfunc("F_IsEquipIDHack", .@part, .@equip_id) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3]) || callfunc("F_IsEquipRefineHack", .@part, .@equip_refine)) close; if (.@card[3] == 0) { .@enchant_count = 1; .@card[3] = .@item_enchant_id; } else if (.@card[2] == 0) { .@enchant_count = 2; .@card[2] = .@item_enchant_id; } else if (.@card[1] == 0) { .@enchant_count = 3; .@card[1] = .@item_enchant_id; } else { mes "[MARS_01]"; mes "The equipment has reached the upper limit of strengthening Hello!"; close; } specialeffect2 EF_REPAIRWEAPON; mes "[MARS_01]"; if (.@enchant_count < 5) mes "The first equipment has been upgraded ^990000" + .@enchant_count + " times^000000."; else mes "For additional performance equipment^990000 ^000000 upgrade."; // never displayed delitem .@item_req, 1; delequip .@part; getitem2 .@equip_id,1,1,.@equip_refine,0,.@card[0],.@card[1],.@card[2],.@card[3]; close; }
-
some way to make more less loaded this function
Winterfox replied to techi's question in Scripting Support
If the ids do not have a gap between them you could do it like this: for(.@i = 0; .@i <= 20; .@i++) { .@equipId = getequipid(.@i); if(.@equipId >= 32071 && .@equipId <= 32128) { .@hasEquip = true; break; } } if(.@hasEquip == true) mes "You wear a equipment with a id between 32071 and 32128"; else mes "You don't wear a equipment with a id between 32071 and 32128"; Otherwise you could put the ids into an array and loop trough the check.