Jump to content

GmOcean

Community Contributors
  • Content Count

    371
  • Joined

  • Last visited

  • Days Won

    8

Reputation Activity

  1. Upvote
    GmOcean got a reaction from Clare in Npc for change job clothing sprite   
    Yes, the command I made acts exactly the same way as changebase did, so sadly there's no point in making it.
     
    Also, as for it changing when they logout / login again. Just change their disguise whenever they login, if they have a variable set to 1. Then when their VIP time is up, or whatever determines the length of their disguise, just remove the variable and undisguise them.
    OnPCLoginEvent:if (vip_status) { changebase(vip_disguise);}end;
  2. Upvote
    GmOcean got a reaction from Clare in Npc for change job clothing sprite   
    I see, alright well I think I know what the problem is. I'll test some more and release a fix if I'm able too.
     
    Edit:
    After, using the command both the original *changebase(<Job_Id>) and the custom one I made *disguiseclass(<Job_Id>)
    they both work exactly the same. That is to say, that yes, the skills do vanish, but they instead just go from the 1st/2nd/trans class, and go to the misc section.
     
    Before changing class:
     
    After Changing Class:
     
     
    So as you can see, you do have your skills, they just get pushed to misc section. This is most likely a client issue than a src one.
     
    And yes, before you ask, you are unable to obtain the skills of the new class you're disguised as, even if you tried.
  3. Upvote
    GmOcean reacted to Tokeiburu in Act Editor   
    File Name: Act Editor
    File Submitter: Tokeiburu
    File Submitted: 03 Dec 2014
    File Category: Client Resources
     
    Heya,
     
    This tool is an action file editor, it edits Act and Spr files. You will find similarities with ActOR in its design, but it should be much more enjoyable to edit animations ;].
     
    Special thanks to Nebraskka for testing this software in its early days. All the suggestions and feedbacks made this software much better.
     
    How to install
    Download the zip archive provided from the download link at the bottom of this description or directly from there : http://www.mediafire.com/download/y3amu1o5zsmgd2o
    Install the application with Act Editor Installer.exe; if you are missing a .NET Framework you will be prompted to download it.
    Once you are done, you can start the program from the link on your desktop.


     
     
    Key features
    The software has many, many features available. It would take too long to describe each one of them, so I've only focussed on the more impotant ones.
    You can undo and redo everything, scripts included.
    You can edit and add sounds easily.
    Powerful and easy to use palette editor.
    Sprite types have been abstracted - you don't have to worry or care about that.
    Animation speed can be changed easily.
    Most components have a drag and drop feature.
    Advanced scripting engine (C# language). The scripts can also be used to customize the software menus.
    Error checking when saving the act/spr to avoid invalid files. The sprite version will be automatically downgraded if RLE compression is not available.
    Frame interpolation (inbetweening/tweening) is possible via the Animation menu.
    Prompts you with an image converter dialog if the added image is invalid.
    Allows advanced edition for actions and frames via their respective menus.
    You can load files from GRFs directly (and save in the GRFs directly as well).

    Technical stuff
    Requires .Net Framework 3.5 (SP1) Client Profile to run (3.5 or more will work as well).
    When prompted with an error, use the "Copy exception" button to copy the debugging info. I will need this to fix the issue you're encountering.

    The editor's primary window
    The interface is really straightforward and similar to ActOR. I'll only focus on new elements!
     
    Rendering mode : This option changes the behavior of how layers are rendered. If you use 'Editor', you'll clearly see all the pixels when zooming in. If you use 'Ingame', it will use a linear scaling instead, which is closer to what the client does.

     
    References : These allow you to know where your item will be positionned (the yellow marker is the anchor, see below).

     
    Color mask : To edit the color of a layer, simply click on the color rectangle. You can also drag and drop the colors between different layers to quickly modify many of them.
     
    Common shortcuts : You can manipulate layers by using common shortcuts. More can be found from the Edit menu. These below are only the primary ones.
    Ctrl-A : Select all layers.
    Ctrl-C : Copy the selected layers.
    Ctrl-V : Paste the copied layers.
    Ctrl-X : Cut the selected layers.
    Alt-C : Copy current action.
    Alt-V : Paste current action.

    Advanced action and frame editions
    These expose all the available methods of the editor. You can remove a range of frames or copy a frame 10 times very quickly and easily. This dialog is found in Action/Frame > Advanced edit...

     
     
    Anchors
    You can edit anchors from the editor directly. Anchors are points that connect frames together, from different act files. Here's an example without and with anchors :
     



     
    This is mostly useful when you're using reference sprites (on the right panel). Clicking on the anchor button will let you choose where to attach the sprite (this is set semi-automatically for you though). You can edit those from the Anchors menu, but it is recommended to start from a pre-existing act to avoid doing this tedious process.
     
     
    Palette editor
    The palette editor allows you to quickly recolor sprites with an intuitive interface. Only indexed images can be edited (it's a palette editor after all) and three modes are available. The gradient mode changes an existing gradient to another color while keeping the original saturation and brightness of the colors - this makes the gradients blend in better. If there are no gradient (usually because it's a custom sprite), there's always the Adjust color mode. This one changes all color from a specified range to another one (Photoshop has a similar feature, which does work better).
     

     
    You can click on the image (on the left) to automatically select the palette indexes. These will be highlighted for a few seconds to show you what you're about to edit.
     
     
    Interpolation (tweening)
    This script can be accessed via Animation > Interpolate frames. This process fills the images between two frames by detecting the changes applied to the layers. Here's a simple example of how it can be used :
     
     
     
     
    Script engine
    The script engine can be accessed via Scripts > Script Runner. This is a big feature of Act Editor, it allows you to automate all your work with the act and much more. Click on the Help button for guides and available methods (don't hesitate to try out a script; if an error occurs the act will be reversed to its previous state). The documentation doesn't cover all of the available options and methods for obvious reasons (the .net framework is huge). Doc example :
     

     
    The language used by the script engine is C#. If you're not familiar with it, simply check out the script samples (Scripts > Open scripts folder)! I won't go into details here, questions can be asked in the support thread regarding addiotional features and methods. If you believe your script should be added in the program, send it to me and I'll probably add it.
     
     
    Customizable
    The settings dialog allows you to modify all colors in the editor easily.

     
    You'll also find the sound resources (GRFs and folders) that can be set up in the Sound tab. The Shell integration tab can associate the .act files with the software to edit them more easily.
     

     
    Don't hesitate to give me a feedbacks or suggestions!
     
    Click here to download this file
  4. Upvote
    GmOcean got a reaction from taunner in Debug Npc Pack Guild   
    Umm, in your script, you're starting each label with this command next; you need to remove those.
     
    Example:
    continuar:next;if(strcharinfo(0) == getguildmaster(.@guild))goto cadastro;query_sql "SELECT `id_guild`,`quant_menber_re`,`quant_menber_max`,`lider`,`name_guild` FROM `cadastro_pack_guild` WHERE `id_guild`='" +.@guild+"'",.@id_guild,.@Quant_RE,.@Quant_Max,.@LiderG$,.@N_Guild$;if(!getarraysize(.@id_guild) || .@id_guild == 0){goto Nocadastro; Remove the next;
    continuar:if(strcharinfo(0) == getguildmaster(.@guild))goto cadastro;query_sql "SELECT `id_guild`,`quant_menber_re`,`quant_menber_max`,`lider`,`name_guild` FROM `cadastro_pack_guild` WHERE `id_guild`='" +.@guild+"'",.@id_guild,.@Quant_RE,.@Quant_Max,.@LiderG$,.@N_Guild$;if(!getarraysize(.@id_guild) || .@id_guild == 0){goto Nocadastro;  
     
    Do this for ALL of your labels. The problem should go away.
     
     
    Edit:
    Here, I did it for you.
    prontera,146,164,4 script Pack Guild 65,{set .@conta_id,getcharid(3);set .@guild,getcharid(2);if (.@guild <= 0)goto Noguild;if(BaseLevel < 299 || JobLevel < 149)goto Nolv;if ((Class < 20 && Class == 4001 && Class == 4002 && Class == 4003 && Class == 4004 && Class == 4005 && Class == 4006 && Class == 4007))goto NoClass;if(#pegoupack == 1)goto japegou;if (Weight > 5000)goto Nopeso;query_sql "SELECT `last_mac` FROM `login` WHERE `account_id`='"+.@conta_id+"'",.@mac$;query_sql "SELECT `account_id` FROM `recebeu_packguild` WHERE `mac`='" +.@mac$+"'",.@checkaccount;if(!getarraysize(.@checkaccount)){ goto continuar;}else{ query_sql "SELECT `name_guild`,`name`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg` FROM `recebeu_packguild` WHERE `mac`='" +.@mac$+"'",.@name_guild$,.@name$,.@dia,.@mes,.@ano,.@hora,.@minuto,.@seg; mes "[^FF7F24Pack Guild^000000]"; mes "Você já pegou seu Pack Guild"; mes "Quanto você era do Clã:^FF7F24"+.@name_guild$+"^000000."; mes "Com o Char:^FF7F24"+.@name$+"^000000."; mes "No dia ^FF7F24"+.@dia+"^000000/^FF7F24"+.@mes+"^000000/^FF7F24"+.@ano+"^000000 ás ^FF7F24"+.@hora+"^000000:^FF7F24"+.@minuto+"^000000:^FF7F24"+.@seg+"^000000."; close;}continuar://next;if(strcharinfo(0) == getguildmaster(.@guild))goto cadastro;query_sql "SELECT `id_guild`,`quant_menber_re`,`quant_menber_max`,`lider`,`name_guild` FROM `cadastro_pack_guild` WHERE `id_guild`='" +.@guild+"'",.@id_guild,.@Quant_RE,.@Quant_Max,.@LiderG$,.@N_Guild$;if(!getarraysize(.@id_guild) || .@id_guild == 0){ goto Nocadastro;}else{// next; mes "[^FF7F24Pack Guild^000000]"; mes "Olá Sua Guild já esta cadastrada"; mes "Deseja receber seu pack guild?"; mes "Nome da Guild:"+.@N_Guild$+"."; mes "Membros que já receberam:"+.@Quant_RE+"."; mes "Total Max de Membros:"+.@Quant_Max+"."; mes "Líder:"+.@LiderG$+"."; switch(select(">>Sim:>>Não")) { case 1: mes "Ok receba seu pack guild"; close2; set #pegoupack,1; query_sql "INSERT INTO `recebeu_packguild` (`account_id`,`name`,`name_guild`,`mac`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg`) values ('"+.@conta_id+"','"+strcharinfo(0)+"','"+getguildname(.@guild)+"','"+.@mac$+"','"+gettimestr("%d",21)+"','"+gettimestr("%m",21)+"','"+gettimestr("%Y",21)+"','"+gettimestr("%H",21)+"','"+gettimestr("%M",21)+"','"+gettimestr("%S",21)+"')"; if(.@Quant_Max == 15){ // pack guild de 10 a 15 membros getitem 12032,100; getitem 12030,50; getitem 4195,2; getitem 4411,2; getitem 4198,1; getitem 19021,2; getitem 4047,1; }else{ // pack guild de 15 a 20 membros getitem 12032,100; getitem 12030,50; getitem 4047,1; getitem 19021,2; getitem 4174,1; } end; case 2: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok volte quando quiser"; close; }}cadastro: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Deseja Cadastra seu clã para pegar o pack guild?"; switch(select(">>Sim:>>Ver pack Guild:>>Não")) { case 1: query_sql "SELECT COUNT(*) FROM`char` WHERE `online`= 1 AND `guild_id`= '"+.@guild+"'",@Cont; set @Cont,@Cont+1; if(@Cont < 10)goto No10Menber; if(@Cont < 15 && @Cont > 10 || @Cont == 15)goto ate15menber; if(@Cont > 15)goto maisde15menber; end; case 2: next; mes "[^FF7F24Pack Guild^000000]"; mes "Pack Guild de 10 à 15 Membros"; mes "Infos"; next; mes "[^FF7F24Pack Guild^000000]"; mes "Pack Guild de 15 à 20 Membros"; mes "Infos"; close; case 3: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok volte quando quiser"; close; }Noguild: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Você não tem guild para pegar o pack guild"; close;No10Menber: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Seu clã não tem 10 Membros Online ela só tem ^FF7F24"+@Cont+"^000000."; mes "Volte quando tiver no minimo 10 online"; close;japegou: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Você já pegou o pack guild"; close;Nocadastro: //next; mes "[^FF7F24Pack Guild^000000]"; mes "A Guild "" Não está cadastrada para receber o pack guild"; mes "Chame seu Líder aqui e mande-o falar comigo!"; close;Nolv: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Você tem que ter no Minimo Level 300 e JobLv/Base 150 para pegar o Pack Guild!"; close;NoClass: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Você Precisa ser um Transclasse ou um Ninja/Guns/Tk para fala comigo volte quanto estiver na sua ultima classe"; close;Nopeso: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Você deve ter Menos que 5.000 de peso para falar comigo"; close;ate15menber: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Olá Deseja continua e Registrar?"; mes "Nome do Clã "+getguildname(.@guild)+"."; mes "Membros Online do Clã "+@Cont+"."; mes "Membros que já receberam: ""."; mes "Pack Guild Liberado a: 15 Membros"; switch(select(">>Sim:>>Não")) { case 1: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok Guild cadastrada Pode Chama Todos os membros para pegar o pack guild!"; close2; // pack de menos de 15 membros getitem 12032,100; getitem 12030,50; getitem 4195,2; getitem 4411,2; getitem 4198,1; getitem 19021,2; getitem 4047,1; getitem 5325,1; set #pegoupack,1; query_sql "INSERT INTO `recebeu_packguild` (`account_id`,`name`,`name_guild`,`mac`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg`) values ('"+.@conta_id+"','"+strcharinfo(0)+"','"+getguildname(.@guild)+"','"+.@mac$+"','"+gettimestr("%d",21)+"','"+gettimestr("%m",21)+"','"+gettimestr("%Y",21)+"','"+gettimestr("%H",21)+"','"+gettimestr("%M",21)+"','"+gettimestr("%S",21)+"')"; query_sql "INSERT INTO `cadastro_pack_guild` (`account_id_lider`,`lider`,`name_guild`,`id_guild`,`quant_menber_re`,`quant_menber_max`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg`) values ('"+.@conta_id+"','"+strcharinfo(0)+"','"+getguildname(.@guild)+"','"+.@guild+"','1','15','"+gettimestr("%d",21)+"','"+gettimestr("%m",21)+"','"+gettimestr("%Y",21)+"','"+gettimestr("%H",21)+"','"+gettimestr("%M",21)+"','"+gettimestr("%S",21)+"')"; end; case 2: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok volte quando quiser"; close; }maisde15menber: //next; mes "[^FF7F24Pack Guild^000000]"; mes "Olá Deseja continua e Registrar?"; mes "Nome do Clã "+getguildname(.@guild)+"."; mes "Membros Online do Clã "+@Cont+"."; mes "Membros que já receberam: ""."; mes "Pack Guild Liberado a: 20 Membros"; switch(select(">>Sim:>>Não")) { case 1: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok Guild cadastrada Pode Chama Todos os membros para pegar o pack guild!"; close2; // pack de mais de 15 membros getitem 12032,100; getitem 12030,50; getitem 14232,2; getitem 4047,1; getitem 19021,2; getitem 4174,1; getitem 5325,1; set #pegoupack,1; query_sql "INSERT INTO `recebeu_packguild` (`account_id`,`name`,`name_guild`,`mac`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg`) values ('"+.@conta_id+"','"+strcharinfo(0)+"','"+getguildname(.@guild)+"','"+.@mac$+"','"+gettimestr("%d",21)+"','"+gettimestr("%m",21)+"','"+gettimestr("%Y",21)+"','"+gettimestr("%H",21)+"','"+gettimestr("%M",21)+"','"+gettimestr("%S",21)+"')"; query_sql "INSERT INTO `cadastro_pack_guild` (`account_id_lider`,`lider`,`name_guild`,`id_guild`,`quant_menber_re`,`quant_menber_max`,`dia`,`mes`,`ano`,`hora`,`mto`,`seg`) values ('"+.@conta_id+"','"+strcharinfo(0)+"','"+getguildname(.@guild)+"','"+.@guild+"','1','20','"+gettimestr("%d",21)+"','"+gettimestr("%m",21)+"','"+gettimestr("%Y",21)+"','"+gettimestr("%H",21)+"','"+gettimestr("%M",21)+"','"+gettimestr("%S",21)+"')"; end; case 2: next; mes "[^FF7F24Pack Guild^000000]"; mes "Ok volte quando quiser"; close; }}
  5. Upvote
    GmOcean got a reaction from karazu in Gender Restriction (BUG)   
    Answer 1:
    On the OnEquip Section:
    if (Sex) { unequip(<equip_slot>); } For equip_slots look here.
     
    Answer 2:
    On the Script Section:
    if (checkmount()) { setmount "MOUNT_NONE" };  
    Answer 3:
    On the Script Section:
    if (Sex) { //Healing Bonus for Males } else { //Cast blessing for females }  
    All possible to do.
     
    Also, for #1, you can just set the item to only be equipable for females or males:
    item_db: (// Items Database///****************************************************************************** ************* Entry structure ************************************************ ******************************************************************************{ // =================== Mandatory fields =============================== Id: ID (int) AegisName: "Aegis_Name" (string) Name: "Item Name" (string) // =================== Optional fields ================================ Type: Item Type (int, defaults to 3 = etc item) Buy: Buy Price (int, defaults to Sell * 2) Sell: Sell Price (int, defaults to Buy / 2) Weight: Item Weight (int, defaults to 0) Atk: Attack (int, defaults to 0) Matk: Magical Attack (int, defaults to 0, ignored in pre-re) Def: Defense (int, defaults to 0) Range: Attack Range (int, defaults to 0) Slots: Slots (int, defaults to 0) Job: Job mask (int, defaults to all jobs = 0xFFFFFFFF) Upper: Upper mask (int, defaults to any = 0x3f) Gender: Gender (int, defaults to both = 2) Loc: Equip location (int, required value for equipment) WeaponLv: Weapon Level (int, defaults to 0) EquipLv: Equip required level (int, defaults to 0) EquipLv: [min, max] (alternative syntax with min / max level) Refine: Refineable (boolean, defaults to true) View: View ID (int, defaults to 0) BindOnEquip: true/false (boolean, defaults to false) BuyingStore: true/false (boolean, defaults to false) Delay: Delay to use item (int, defaults to 0) Trade: { (defaults to no restrictions) override: GroupID (int, defaults to 100) nodrop: true/false (boolean, defaults to false) notrade: true/false (boolean, defaults to false) partneroverride: true/false (boolean, defaults to false) noselltonpc: true/false (boolean, defaults to false) nocart: true/false (boolean, defaults to false) nostorage: true/false (boolean, defaults to false) nogstorage: true/false (boolean, defaults to false) nomail: true/false (boolean, defaults to false) noauction: true/false (boolean, defaults to false) } Nouse: { (defaults to no restrictions) override: GroupID (int, defaults to 100) sitting: true/false (boolean, defaults to false) } Stack: [amount, type] (int, defaults to 0) Sprite: SpriteID (int, defaults to 0) Script: <" Script (it can be multi-line) "> OnEquipScript: <" OnEquip Script (can also be multi-line) "> OnUnequipScript: <" OnUnequip Script (can also be multi-line) ">},******************************************************************************/  
    If you do it at the actual item, then you wouldn't need to check if the wearer is female or not, since they'd be the only ones able to use it.
  6. Upvote
    GmOcean got a reaction from Litro in Fakename /[TAG]   
    I see, well I'll take a look at them later, and I'll see if I can port them to Hercules so you can make use of it.
     
    Edit:
    Okay, so I took a look at them, and it seems they could easily be converted to Hercules, however i'm not 100% sure if it'll work. And if it does work, you'll still have the same issues as Digos posted when he released the whisper patch. That is, if someone uses @fakename to disguise their name as an existing player name, they won't be PM-able since it checks for real names first then fake names.
     
    Also last thing of note is, I could make a diff for the changes, but I'm too dumb to make them plugins xD. I don't know how to do the pre/post hooking yet.
  7. Upvote
    GmOcean got a reaction from stiflerxx in Fakename /[TAG]   
    I see, well I'll take a look at them later, and I'll see if I can port them to Hercules so you can make use of it.
     
    Edit:
    Okay, so I took a look at them, and it seems they could easily be converted to Hercules, however i'm not 100% sure if it'll work. And if it does work, you'll still have the same issues as Digos posted when he released the whisper patch. That is, if someone uses @fakename to disguise their name as an existing player name, they won't be PM-able since it checks for real names first then fake names.
     
    Also last thing of note is, I could make a diff for the changes, but I'm too dumb to make them plugins xD. I don't know how to do the pre/post hooking yet.
  8. Upvote
    GmOcean got a reaction from ShankS in PvP ladder cant work with sql,flux   
    The reason your script doesn't work with SQL/Flux is simply because, it doesn't use SQL at all. Everything for that ladder is stored in variables.
  9. Upvote
    GmOcean got a reaction from ShankS in Devotion   
    err nvm, it does require compiling, but you only need to delete a // to enable it:
    /*** when enabled, reflect damage doesn't bypass devotion (and thus damage is passed to crusader)* uncomment to enable**///#define DEVOTION_REFLECT_DAMAGE just delete the // before #define DEVOTION_REFLECT_DAMAGE
     
    and then recompile.
  10. Upvote
    GmOcean got a reaction from ShankS in Devotion   
    Everything he linked is already added to the revision files. Just need to change the settings in the .conf files.
  11. Upvote
    GmOcean got a reaction from NewNewbie in Scripting Tutorials & Guides   
    Scripting Tutorials and Guides
    I'm going to attempt to help everyone here with their scripts while not being directly involved in helping you with them xD.
    This will also help future/current scripters get some fresh info and maybe inspire innovative ideas towards scripting.
    So that we can prove that us " Scripters " are the superior ragnarok emulation race! Take that Source Code writers!! Jk lol, we need you too .

    What I'm going to do, is write detailed tutorials on how to write a few scripts. Starting from the basics to more advanced scripts.
    This way everyone can follow along. And hopefully this will help everyone understand how to write a few scripts and even troubleshoot their own scripts.
     
    Also please read: Scripting Standards.
    It will help you understand how to read some of the syntax and way people script things.
    // A list of <sprite id>s can be found here: Sprite_IDs Credits: Ai4rei
    Scripting Tutorials & Guides
    In this section you will learn how to write scripts ranging from Complete Begginer Level Scripts ( Me and Some of you ) -> Expert Level Scripts ( Think, Developer Status O.o; )
    - Beginner Scripts -
    Scripts for complete beginners and novice scripters.
     
     
    - Intermediate Scripts -
    Scripts for intermediate level scripters. If you completed my beginner script series, then you are ready for this section.
     
     
    - Advanced Scripts -
    Scripts for advanced level scripters. If you completed my intermediate script series and have made a few of your own intermediate scripts, then you are ready for this section.
     
     
    The idea behind this topic, is for new users, and current ones, to have a (second)place they can go to for reference when trying to write a script if they can't figure it out with script_commands.txt file. It will also help people learn how to write scripts. While hopefully, keeping script writing techniques to a ' very ' similar structure!
     
    *Read Me* - I have updated the links on this post to link to the oldboard so these guides can be viewed. However, do note that the script_commands.txt links within those guides are no longer accurate. Enjoy your scripting.
  12. Upvote
    GmOcean got a reaction from Takumirai in Disguise Event [Help]   
    So, based on what you posted it should look like this:
    OnClock2100:OnClock2200:OnClock2300:OnClock0000:OnClock0100:OnClock0200:OnClock0300:OnClock0400:OnClock0500:OnClock0600:OnClock0700:.Rounds = 5;callsub iRound5;end;OnClock0800:OnClock1000:OnClock1200:OnClock1400:OnClock1600:OnClock1800:OnClock2000: set .Rounds,10;iRound5: set .ResetCounter,.ResetCounter+1; set .EventON,1; set .Timer,1; set .Wait,1; announce "The Disguise Event will begin in 3 minutes.",bc_all | bc_blue; announce "The Event is being held in Prontera.",bc_all | bc_blue; setnpctimer 0; initnpctimer; end;
  13. Upvote
    GmOcean got a reaction from stiflerxx in script commands   
    It's just letting you know you're using a command that will be removed in the (very)near future.
    So you should use these commands instead: *setmount {<flag>}; & *checkmount()
  14. Upvote
    GmOcean got a reaction from IndieRO in Scripting Tutorials & Guides   
    Scripting Tutorials and Guides
    I'm going to attempt to help everyone here with their scripts while not being directly involved in helping you with them xD.
    This will also help future/current scripters get some fresh info and maybe inspire innovative ideas towards scripting.
    So that we can prove that us " Scripters " are the superior ragnarok emulation race! Take that Source Code writers!! Jk lol, we need you too .

    What I'm going to do, is write detailed tutorials on how to write a few scripts. Starting from the basics to more advanced scripts.
    This way everyone can follow along. And hopefully this will help everyone understand how to write a few scripts and even troubleshoot their own scripts.
     
    Also please read: Scripting Standards.
    It will help you understand how to read some of the syntax and way people script things.
    // A list of <sprite id>s can be found here: Sprite_IDs Credits: Ai4rei
    Scripting Tutorials & Guides
    In this section you will learn how to write scripts ranging from Complete Begginer Level Scripts ( Me and Some of you ) -> Expert Level Scripts ( Think, Developer Status O.o; )
    - Beginner Scripts -
    Scripts for complete beginners and novice scripters.
     
     
    - Intermediate Scripts -
    Scripts for intermediate level scripters. If you completed my beginner script series, then you are ready for this section.
     
     
    - Advanced Scripts -
    Scripts for advanced level scripters. If you completed my intermediate script series and have made a few of your own intermediate scripts, then you are ready for this section.
     
     
    The idea behind this topic, is for new users, and current ones, to have a (second)place they can go to for reference when trying to write a script if they can't figure it out with script_commands.txt file. It will also help people learn how to write scripts. While hopefully, keeping script writing techniques to a ' very ' similar structure!
     
    *Read Me* - I have updated the links on this post to link to the oldboard so these guides can be viewed. However, do note that the script_commands.txt links within those guides are no longer accurate. Enjoy your scripting.
  15. Upvote
    GmOcean got a reaction from glemor123 in gpack npc problem   
    Okay, well looking at your script I see you used the command addrid. Are you using rAthena or Hercules as your emulator?
    If your using rAthena, than you should be able to go back to the regular switch(select) option instead of doevent. But also while replacing your for(loop) and using addrid as Emistry suggested.
     
    If you're using Hercules as your emulator, then I'll have to look around for another solution.
     
     
    Edit: Okay, since you said *doevent, didn't work. Then I think the only option left, without src modifications is a timer using this command: addtimer <ticks>,"NPC::OnLabel";
    This should allow you to give each player their own timer, which upon activation you can prompt them with the menu. Can also just put the timer to 1 tick, to make it appear practically instantly.
  16. Upvote
    GmOcean got a reaction from anticlimax18 in [Request Support] Player Customized Quest Script + SQL Track [ALMOST COMPLETE]   
    Well, I wrote a variation of your script, but it's not 100% complete, nor am I fully positive it's working 100%, but script_checker says there is no errors in the syntax. Perhaps, you can use it for a comparison to your code, and find the results you need:
    prontera,164,167,0 script Quest Master 857,{mes ( .@npc$ = "[^FF0000 Quest Master ^000000" );mes "[^00FF00 Generate Requirement ^000000]";mes ""+ getitemname(.currency[0]) +" x "+ .currency[1] +"";mes "[^0000FF Taking Requirement ^000000]";mes ""+ getitemname(.currency[2]) +" x "+ .currency[3] +"";next;mes .@npc$;switch( select( "[Turn in all quests]", "[Obtain Quest]", "[Abandon Quest]", "[Generate Quests]"+ ( (getgmlevel() >= 99)?":[Generate Random Quests]" : "" )+"" ) ){ case 1: for( .@i = 0; .@i < getarraysize( @quests$ ); .@i++ ){ explode( .@array$, @quests$[.@i], ":" ); switch( atoi(.@array$[5]) ){ case 1: if( .@array$[4] == .@array$[3] ){ .@quests[.@a] = atoi( .@array$[6] ); .@a++; } break; case 2: case 3: if( countitem( atoi(.@array$[2]) ) == atoi(.@array$[3]) ){ .@quests[.@a] = atoi( .@array$[6] ); .@a++; } break; } } if( !.@quests[0] ){ mes "You don't have any completed quests."; close; } getitem .currency[0], (.currency[1] * getarraysize(.@quests)); for( .@i = 0; .@i < getarraysize( @quests$ ); .@i++ ){ explode( .@array$, @quests[.@i], ":" ); for( .@j = 0; .@j < getarraysize( .@quests ); .@j++ ){ if( .@quests[.@j] == .@array$[6] ){ @quests[.@i] = ""; .@quests$ = .@quests$ + ""+ .@array$[6] +":"; } } } callsub iRedeem, .@quests$; // Updates quests to have a reward so posters can redeem it. mes "All quests have been redeemed."; mes "Come back again, and complete some more."; close; case 2: if( max_active && ( getarraysize(@quests$) >= .max_active ) ){ mes "You can not actively pursue any more quests at the moment."; mes "You need to either complete your current quests or abandoned them."; close; } mes "Only a maximum of "+ .select_limit +" available quests will be listed from a category at a time."; mes "Select a category."; next; mes .@npc$; .@select = select( "[Hunting] - [Random Difficulty]", "[Item Gather] - [Random Difficulty]", "[Cooking] - [Hard Difficulty]"); .@count = query_sql("SELECT * FROM `Paid_Quest` WHERE `TrackID` = '0' AND `type` = '"+ .@select +"'", .@quest_id, .@name$, .@pub_id, .@track_id, .@mob_id, .@itme_id, .@tar_amt, .@type, .@time); if( !.@count ){ mes "There are no quests of this type available at this time."; close; } iQSelectLoop: if( .@count < ( .select_limit ) ){ .@select2 = ( .@count + 1 ); } else { .@select2 = ( .select_limit + 1 ); } .@select = .@select2; while( .@select == .@select2 ){ .@quest_menu$ = ""; .@i = 1; while( .@i < .@select2 ){ .@a = rand( getarraysize(.@name$) ); if( !compare( .@quest_menu$, .@name$[.@a] ) ){ .@quest_menu$ = .@quest_menu$ + .@name$[.@a] +":"; .@quest_select[.@i] = .@a; .@i++; } } .@quest_menu$ = .@quest_menu$ + "[^0000FF More Quests ^000000]"; .@select = select( .@quest_menu$ ); } .@a = .@quest_select[.@select]; mes .@name$[.@a]; switch( .@type[0] ){ case 1: mes "Objective: "+ getmonsterinfo( .@mob_id[.@a], 0 ) +""; mes "Kill amount: "+ .@tar_amt[.@a] +""; break; case 2: case 3: mes "Objective: "+ getitemname( .@item_id[.@a] ) +""; mes ""+ ( (.@type[0] == 2)? "Collect Amount" : "Cook Amount" ) +": "+ .@tar_amt[.@a] +""; break; } mes "----------------------------------"; mes "Do you accept?"; next; if( select( "Yes, I accept", "No, let me choose another" ) == 2 ){ callsub iQSelectLoop; end; } @quests$[getarraysize(@quests$)] = .@name$[.@a] +":"+ .@mob_id[.@a] +":"+ .@item_id[.@a] +":"+ .@tar_amt[.@a] +":"+ 0 +":"+ .@type[0] +":"+ .@quest_id[.@a] +""; query_sql("UPDATE `Paid_Quest` SET(`TrackID`) VALUES('"+ getcharid(0) +"') WHERE `id` = '"+ .@quest_id[.@a] +"'"); mes .@npc$; mes "Quest Accepted."; mes "All quests will be abandoned upon logging out."; close; case 3: mes "Did you want to abandon all your quests, or a specific one?"; next; mes .@npc$; if( select( "One quest", "All quests" ) == 2 ){ @quests$ = ""; mes "All quests have been abandoned."; close; } for( .@i = 0; .@i < getarraysize(@quests$); .@i++ ){ explode( .@array$, @quests$[.@i], ":" ); .@quest_menu$ = .@quest_menu$ + .@array$[0] +":"; } mes "Which quest did you want to abandon?"; next; .@select = select( .@quest_menu$ ); explode( .@array$, @quests$[( .@select - 1 )], ":" ); mes .@array$[0]; switch( .@array$[5] ){ case 1: mes "Objective: "+ getmonsterinfo( .@array$[1], 0 ) +""; mes "Progress: "+ .@array$[4] +" / "+ .@array$[3] +""; break; case 2: case 3: mes "Objective: "+ getitemname( .@array$[2] ) +""; mes "Progress: "+ countitem( .@array$[2] ) +" / "+ .@array$[3] +""; break; } mes "----------------------------------"; mes "Are you sure you want to abandon this quest?"; next; if( select( "Yes, abandon the quest.", "No, I've changed my mind." ) == 2 ){ close; } @quests$[( .@select - 1)] = ""; mes "Quest has been abandoned."; close; case 4: // Only Item Collection quests are available to create as of now. mes "What item did you want to post for a quest?"; input .@item; if( !getitemname( .@item ) == "null" ){ mes "^^FF0000 INVALID ITEM"; close; } mes "How many did you want to request?"; mes "Minimum: 1","Maximum: 1,000"; input .@amt,1,1000; query_sql("INSERT INTO `Paid_Quests` (`name`,`pub_id`,`item_id`,`tar_amt`,`type`,`time`) VALUES('"+ escape_sql("Collection: "+ getitemname(.@item) +"") +"','"+ getcharid(0) +"','"+ .@item +"','"+ .@amt +"','2','"+ gettimetick(2) +"')"); next; mes "Quest, successfully submitted."; close; case 5: // GM only quest generator. end;}iRedeem:explode( .@array$, getarg(0), ":" );for( .@x = 0; .@x < getarraysize( .@array$ ); .@x++ ){ query_sql("UPDATE `Paid_Quests` SET(`reward`) VALUES('1') WHERE `id` = '"+ atoi(.@array$[.@x]) +"'");}return;end;OnInit:// [0] = Item Required to post a quest. | [1] = Amount needed.// [2] = Item Required to accept a quest. | [3] = Amount needed.setarray .currency[0], 501, 5, 502, 1;// Amount of quests to post at a time.// Default: 3.select_limit = 3;// [0] = Start of Food item IDs// [1] = End of Food item IDs.setarray .cook_id[0], 12040, 12100;// Max amount of quests each player can actively pursue at a time.// Default: 3.max_active = 3;end;}// SQL TABLE TO BE USED./*CREATE TABLE `master_main`.`paid_quests` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `pub_id` INT(11) NOT NULL, `TrackID` INT(11) NOT NULL DEFAULT 0, `mob_id` INT(11) NOT NULL DEFAULT 0, `item_id` INT(11) NOT NULL DEFAULT 0, `tar_amt` INT(11) NOT NULL DEFAULT 0, `type` INT(11) NOT NULL DEFAULT 0, `time` BIGINT NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE INDEX `id_UNIQUE` (`id` ASC));*/  
    *Note - This hasn't been tested. Reason being, I do not want to setup a sql table, add quests and the such to do the testing for this. You can post back errors, you find and I'll will provide support for it, but right now I'm not going to alter my sql schemas*.
  17. Upvote
    GmOcean reacted to Beret in Add new database format   
    A while back when hercules was implemented new updates I gave the idea to ind use configuration (.conf), today I see how much this mode brought more easily for creation and configuration, I noticed that the item_db is now also in file  
    Well why not expand to other files which can facilitate both in future updates following the aegis, as for members who use the emulator. To make clearer how much easier to use that way, look below.     skill_db - hercules:   662,0,6,4,0,0x2,14,10,1,no,0,0x2,0,weapon,0, NPC_HELLJUDGEMENT,Hell's Judgement663,0,6,4,0,0x3,2:5:8:11:14,5,1,no,0,0x2,0,none,0, NPC_WIDESILENCE,Wide Silence661,0,6,4,0,0x2,7,5,1,no,0,0x2,0,weapon,7, NPC_PULSESTRIKE,Pulse Strike  
    skill_db - aegis:
     
    SetSkill NPC_HELLJUDGEMENTOnInit: SkillType TOME SkillMaxLv 10 SkillPattern DIRECTATTACK SkillSplash SQUARE 14 14 14 14 14 14 14 14 14 14 SkillAtkPer 100 200 300 400 500 600 700 800 900 1000returnOnSuccess: SkillHandicap HEALTHCurse 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000returnSetSkill NPC_WIDESILENCEOnInit: SkillType TOME SkillMaxLv 5 SkillSplash SQUARE 2 5 8 11 14 returnOnUse: SkillHandicap HEALTHSilence 1000 1000 1000 1000 1000 SkillNoDamagereturnSetSkill NPC_PULSESTRIKEOnInit: SkillType TOME SkillMaxLv 5 SkillSplash SQUARE 7 7 7 7 7 SkillPattern DIRECTATTACK SkillAtkPer 100 200 300 400 500returnOnSuccess: SkillKnockBack 7 7 7 7 7return  
    produce_db rune - hercules
     
    12733,24,2010,4,1096,1,7123,1,7939,1 produce_db mode rune - aegis
     
    Rune_12733 = { -- 하갈라즈 ["Elder_Branch"] = 1, ["Round_Shell"] = 1, ["Dragon's_Skin"] = 1, } produce_db cook - hercules
     
    12061,11,0,0,7472,0,518,1,514,2,501,1 produce_db cook - aegis
     
    [ [[Dex_Dish01]] ] = { Level={1}; --재료아이템 Meterial = { --아이템DB명, 개수 { [[Honey]], 1 }, { [[Grape]], 2 }, { [[Red_Potion]], 1 }, }; CreatingItembyFailed = { }; }, mercenary_skill_db - hercules
     
    6017,8207,2 //MA_DOUBLE6017,8233,1 //MER_AUTOBERSERK mercenary_skill_db - aegis
     
    "MER_ARCHER01"{ "MA_DOUBLE",2 "MER_AUTOBERSERK",1}  
    sc_config hercules
     
    SC_PROVOKE, 32 sc_config aegis
     
    EFST_PROVOKE={ ResetDead = true; ResetDispel = true; Save = true; Send = false; IgnorePretendDead = false; DeBuff = true; ResetCLEARANCE = true; ActorAppearance = false; SendMultiCast = false; ["backward compatibility send"] = true; -- 이전버젼 호환성을 위해 추가합니다.};  
    These are just a few examples, the manipulation of these files become easier when working with this format. Often you have to work with sums as 1 + 2 + 9 + 5, sum is not the problem, the question having to know what each number is, unlike when using constants, you can work as true or false for example for each option.
  18. Upvote
    GmOcean got a reaction from anticlimax18 in [Request Support] Player Customized Quest Script + SQL Track [ALMOST COMPLETE]   
    Perhaps something like this:
    - script sql_quest_generator -1,{OnHuntingCreate:freeloop(1); // Freeloop to prevent infinite loop error.while( .@hunting != .hunting_generate ){ // Loop through the below until a total of (.hunting_generate) amount of quests have been created. .@a = rand(.min_hunting_objective, .max_hunting_ojbective); // Select a random amount of objectives for this quest. .@name$ = "Hunting:"; // Start of the quest name. // Loop the below until the selected amount of objectives have been added to the proper variables. while( .@b != .@a ){ .@i = rand(1001,3000); // Selecting a random mob_id # from 1001 (Scorpion) -> 3000 ( Just going beyond what exists to add support for custom mobs ). if( !compare( .blacklist$, ""+ getmonsterinfo( .@i, 0 ) +"" ) ){ // Compares monster ID number to see if it is blacklisted or not. .@mob_objectives[.@b] = .@i; // Adds the monster as an objective. .@mob_obj_amount[.@b] = rand(.min_hunting_amount, .max_hunting_amount); // Adds a random amount to be killed to complete that objective. .@name$ = .@name$ + getmonsterinfo( .@i, 0 ); // Adds the monster's name as part of the quest name. .@b++; } } // We create an entry in our custom quest_database using just the Quest name for now. // This will serve as a pointer when adding in all the objectives later, since the amounts were dynamically chosen and not set in stone. query_sql("INSERT INTO quest_database `quest_name` = '"+ .@name$ +"'"); // Loop through this until ALL objectives & the amount needed to complete it, have been added to the quest we listed above. while( .@c < getarraysize( .@mob_objectives ) ){ // Adding in each objective and it's amount to the quest we just created above. query_sql("Update quest_database SET( `obj"+ .@c +"`, `amt"+ .@c +"'`) VALUES( '"+.@mob_objectives[.@c]+"', '"+.@mob_obj_amount[.@c]+"') WHERE `quest_name`='"+ .@name$ +"'"); .@c++; } // Set this variable +1 to say we have completed creating a quest. And to continue looping if not all of them have been created. .@hunting++;}// Freeloop(0) to let server know we are done looping and to stop trying to prevent infinite loops.freeloop(0);end;// This is where the settings go to configure the above to do what you want.OnInit:.hunting_generate = 3; // How many hunting quests to create and add to sql.// Minimum and Maximum amount of different monsters to be used as an objective..min_hunting_objective = 1;.max_hunting_objective = 5; // Note - This can not be higher than the number of objectives listed in your sql table. So if your sql table only supports 3, this can be no higher than 3.// Minimum and Maximum amount to be killed for each objective..min_hunting_amount = 5;.max_hunting_amount = 20;// Bonus, a custom command that when used, will attempt to create a (.hunting_generate) more quests and add them to the database.bindatcmd "huntgen", strnpcinfo(3)+"::OnHuntingCreate";end;}  
    It's untested, but if it works, it should generate 3 hunting quests, with random amount of 1-5 different monsters to hunt, ranging from 5-20 of each to kill. And place them into a sql database.
  19. Upvote
    GmOcean reacted to csnv in I want to learn Source code   
    I guess I'll give you a more precise suggestion. Read and follow "The C Programming Language - 2nd edition" book, along with the exercises your C knowledge should be enough to be able to understand what the emulator does and how. Then, you can fix bugs or develop your own code, but above all you'll need time to understand the emulator code.
  20. Upvote
    GmOcean reacted to Playtester in I want to learn Source code   
    Working on the emulators certainly helped me a lot also learning it. I'm not the type who reads explanations. I just look at examples and then try to imitate them. At first I started with easy code changes like just correcting the damage which is basically just finding it in the code and changing a number and then tried continuously harder things.
    Now I set debug messages everywhere and run test cases to figure out complex problems.
     
    But I guess I had programming knowledge even before joining eAthena.
     
    So going back even earlier... well I guess I simply wrote a hello world program. Also looking at an example, copying it, getting it to compile, and be happy that it showed "Hello world". And then I slowly expanded that like "When I press a key I want it to show a second message" and "Now the user should input a number and it should show the square of it" and then I started writing small minigames like "A goblin appears what to you want to do? 1. Hit it 2. Run away".
  21. Upvote
    GmOcean got a reaction from Balfear in Item description in NPC message   
    O.o I believe it's <ITEMLINK> what your looking for, but I'm not sure if we have it working here yet. All my attempts have failed. <URL> & <NAVI> works though.
  22. Upvote
    GmOcean got a reaction from hunter4565 in How to make 'unitwalk' work when distance to target is too big?   
    If it needs to walk then you have to make a small algorithm for it. So that it will walk to X recalculate route, walk to Y, recalculate route and continue in this pattern until it reaches it's destination.
    Otherwise, you could just use unitwarp if the method of arrival doesn't matter so long as they get there.
  23. Upvote
    GmOcean got a reaction from Helena in How to not attach a timer to a character (using +x hours)   
    @1 -  By default initnpctimer does not have a player attached so you can just use that if you choose to.
     
    @2 -
    TRUNCATE TABLE `table_name`
    is used when you want to delete all the data from the given table, without deleting the table from the schema.
    You shouldn't have any issues of table mix ups, since you can't have the same table name in the same schema.
     
    So, if `votegoal` isn't the table you want to TRUNCATE, then perhaps a different table is what you need to do?
     
    Additionally, if you're having issues, where `votegoal` is the name of a table inside 2 different schemas, and this is the problem, you should be able to specify which schema to truncate from:
    query_sql("TRUNCATE database.schema `table_name`");
  24. Upvote
    GmOcean got a reaction from Doch in Item Search   
    File Name: Item Search
    File Submitter: GmOcean
    File Submitted: 13 Oct 2014
    File Category: Utility
     
    =============================================================
    Description
    =============================================================
    This script will allow users to search information about an
    item in-game. Supports both renewal/non-renewal items. It
    will show the exact item if using the search directory
    function. If however using the input method, this script will
    will run a broadened search, or pull up the exact item if an
    item ID is given instead of a name.
    =============================================================
    Features
    =============================================================
    Choose between what website you want your server to use.
    Or simply leave that upto your players by enabling all sites.
    =============================================================
    NOTE - Requires a client from 2011-10-10aRagexe.exe onwards.
    NOTE2 - RateMyServer Link does not support custom items.
    =============================================================
     
    Click here to download this file
  25. Upvote
    GmOcean got a reaction from karazu in Just another Warper   
    mapname,x,y,z script npc_name 123,{mes "Where do you want to be warped?";next;.@select = select( implode( .warps$, ":" ) );mes "Are you sure you want to be warped to: "+ .warps$[.@select] +"?";if( select( "Yes, warp me now.", "No, I've changed my mind." ) == 2 ){ close; }warp .map$[.@select],.x[.@select],.y[.@select];close;OnInit:setarray .warps$[0],"Map display names","Example","Prontera","Payon","Morroc";setarray .maps$[0],"prontera","payon","morroc";setarray .x[0],150,170,140;setarray .y[0],180,190,150;end;}
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.