Jump to content

Mastagoon

Members
  • Posts

    63
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by Mastagoon

  1. On 2/16/2021 at 11:07 AM, Azhul said:

    Hello everyone i'm using HD Refiner from the renewal features to my Pre-renewal server.

    I have successfully implemented it by adding the refine material id and cost to import/refine_db.yml

    What i want to know is how do i know what is the success rate of the refine method using HD refiner and how can i edit it on my own preference.

    Thanks in advance ?

    refine_db.yml 4.58 kB · 2 downloads

    The success rate for HD ores is the same rate for normal ore. Just edit Normal Chance to change it.

  2. On 2/17/2021 at 11:57 AM, itsjbrojo said:

    Hello, Can I ask for a script which the Repairman NPC checks the 

    inventory and will not repair any broken +10 equipment.. 

    because the repairall command bypasses it everytime.

     

    the idea is when I failed to refine a +10 gear to +11 with HD refiner,

    instead of downgrading or breaking.. it will have a red tag as broken...

    inorder to repair it I will need to do a quest before the repairman NPC will repair the gear. 

     

    only for +10 broken equipment.. other refines will be fine and can be repaired with zeny.

    Well, if you want to this only using scripts, it's gonna be tricky...

    you can perhaps replace the "broken" weapon with a different item, for example Damaged Weapon, and save the original weapon's data as a character array or in SQL, and then allow the players to trade the broken weapon with their original item.

     

    If your problem is only with @repairall, adding this one line in Atcommand.cpp will make the command ignore +10 equipment or higher

    ACMD_FUNC(repairall)
    {
    	int count, i;
    	nullpo_retr(-1, sd);
    
    	count = 0;
    	for (i = 0; i < MAX_INVENTORY; i++) {
    		if(sd->inventory.u.items_inventory[i].refine >= 10) continue; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Add this line
    		if (sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].card[0] != CARD0_PET && sd->inventory.u.items_inventory[i].attribute == 1) {
    			sd->inventory.u.items_inventory[i].attribute = 0;
    			clif_produceeffect(sd, 0, sd->inventory.u.items_inventory[i].nameid);
    			count++;
    		}
    	}
    
    	if (count > 0) {
    		clif_misceffect(&sd->bl, 3);
    		clif_equiplist(sd);
    		clif_displaymessage(fd, msg_txt(sd,107)); // All items have been repaired.
    	} else {
    		clif_displaymessage(fd, msg_txt(sd,108)); // No item need to be repaired.
    		return -1;
    	}
    
    	return 0;
    }

     

    • Love 1
  3. On 2/15/2021 at 6:34 PM, AIex said:

    Hello everyone!
    I have a NPC that causes two different aggressive mobs (Poison Spore and Argiope). These monsters kill another mobs.

    I also have another NPC that cause Porings.

    The task is to find out which monster (Poison Spore or Argiope) kills Poring.

     

    Or how to find Poring was killed by a player or a monster summoned by the first NPC?

    You can use event labels like @Gladius said to figure it if a monster was killed by a player or another monster, but there is no way to access the information of the killer monster without a source mod

  4. Try this

    -    script    testing    -1,{
    
    OnPCMapLoadEvent:
    if ((agitcheck() || agitcheck2()) && ( strcharinfo(3) == .@woemaps$[.@i]))
      set WoeReward, WoeReward +1; // set points
    // Check if woe is on and if you entered a castle
    end;
    
    OnAgitEnd:
    if (WoeReward >= 30) { 
      getitem 14232,1; // reward
      set WoeReward, 0; // reset the points
    }// if points is 15 or more get item
    end;
      
    OnInit:
    setarray .@woemaps$[0],"payg_cas03","prtg_cas03";
    end;
    
    }
  5. 8 hours ago, kalabasa said:

    -    script    guide::guideme    -1,{

    OnInit:
    bindatcmd "guide", strnpcinfo(3) +"::Onguide";
        
    Onguide:
    if(getmapflag(strcharinfo(3),mf_gvg ) || getmapflag(strcharinfo(3),mf_pvp) || getmapflag(strcharinfo(3),mf_gvg_castle)) {
            mes "[ Guide ]";
            mes "this command can only be used on ^FF0000 Towns. ^000000";
            end;

        }
        else {
        mes "[ Guide ]";
        mes "Hello, " + strcharinfo(0) + "!";
        mes "How may I help you?!";
    Main:

     

    i had this script where in you type @guide custom command 

    but i recieving error and debug on console how to fix it?

    Error buildin_strcharinfo fatal error player not attached

    debug: function: strcharinfo (1 parameter):

    debug: Data: number value=3 

    debug source (NPC): guide(invisible/not on a map) 

    debug source (NPC): guide(invisible/not on a map) 

     

    you forgot to end the OnInit event

    just add end; below `bindatcmd "guide", strnpcinfo(3) +"::Onguide";`

    • Upvote 1
  6. Hello everyone.

    Today i would like to share with you Yggdarsil bot, a discord bot that was created with the launch of my private server for simple verification, and has grown ever since to provide a fun and interactive game/discord experience.

    Features and commands

    Multilanguage support

    Spoiler

    Supports multiple languages (currently available languages are English & Arabic, but you can easily just add a new language file to support any language)

    The bot communicates with the users depending on their language choice.

    localization.thumb.png.de66156f6df6843e204a6d7146359cee.png

     

    Account verification (Link your in-game account to your discord account)

    Spoiler

    You can use account verification for all sort of useful things in-game.

    I have also added a server-side few functions to check the player's verification status, so that I can for example restrict some content/reward for verified players only.

    verification.gif.57310fcb197b0a91b3ded7164aca6c42.gif

    Mob/Item lookup

    Spoiler

    Yggdrasil bot can also use the divine-pride API for a quick lookup monsters/items by id or by name.

    1956021851_@item@monster.thumb.gif.ed75d20885768dc2f690a5df8a9b35d8.gif

    In-game rewards

    Spoiler

    Discord bot is also capable of giving rewards that will be attached to the discord account of the user.

    If a user is verified, they can receive their discord reward in-game.

    @reward.thumb.gif.d287b626bac687ca0ed308f5d6a25840.gif@daily.thumb.gif.d89ae5ffbdcc9927e799ddc79a4d7080.gif

    Server donation

    Spoiler

    The @donate command allows players to donate to your just like donating through a fluxCP panel. Yggdrasil bot only support Paypal currently.

    @donate.thumb.gif.4277d0fc776d05d0203f8a7e0077cde7.gif

    Vendors Search

    Spoiler

    Yggdrasil bot can also retrieve a list of vendors in-game and display their info on discord. (I'm planning to add the functionality to search individual items)

    vendors.thumb.gif.c7c9ef55a270c75a82f55871f83e844a.gif

     

    Auction System

    Spoiler

    Players may use the in-game auction NPCs to offer an item(s) to the discord auction.

    Other players can then bid on the auctioned items, If they have the Zeny, it will be deducted from their in-game character immediately

    The highest bidder wins the auction when the countdown ends.

    auction.thumb.gif.26ce3f7572647de17637e4fc71178677.gif

     

    And that's mostly all the available commands

     

    Discord Events/Minigames

    Yggdrasil Bot can also run several different minigames on discord, and reward the event winners in-game directly.

    Random Drops

    Spoiler

    On discord, a random reward box drops in a room. The first player to pick it up gets to open the box and receive the reward.

    boxes.thumb.gif.e1c4b1f892ca73afc5de84071d2c361d.gif

    Trivia Event

    Spoiler

    Pretty straight forward. The bot will ask a question and the first player with the correct answer wins the round.

    On YggdrasilRO, the event consists of ten rounds, And the players who can win the most rounds get an additional reward by the end of each month.

    Currently, Yggdrasil bot has a list of almost 300 different trivia questions.

    trivia.png.07738dd72585efa874b780c48356ddfe.png

    Disguise Event

    Spoiler

    Guess the name of the monster to win the round.

    All the mob images are imported from divine pride.

    disguise.thumb.gif.f67211e9d6b60131057c1bd1afbf909c.gif

    Boss Fights

    Spoiler

    A Turn-Based RPG style minigame.

    When the event starts, a random boss monster will appear in the chosen Discord room, and players need to prepare the best possible gear to defeat the monster.

    Every player gets to choose one weapon, one shield, and cards if they have card slots in the items they've chosen.

    Players will get to choose one of three options displayed randomly from a list of gears. After 5 minutes have passed the game will start and the players will take turns with the boss monster to fight it.

    If the players defeat the boss monster successfully, they will receive rewards depending the the amount of damage they deal.

    Also all participants will be able to loot the drops of the boss monster after the event ends.

     

    And that'd be all folks.

    Any feedback is appreciated ❤️

    • Upvote 1
    • Love 7
    • Like 1
  7. 2 hours ago, emadkm said:

    i need src support on how to turn offensive skill to passive so that i can't drag the skill from skill window 

    thanks

    if you just want to change a skill to a passive skill, no source modification is needed. Unless if you want to change the behavior of the skill .

    for changing a skill to passive:

    go to the skill_db.yml file, find the skill you want and change TargetType to passive. (or you can remove the line completely since passive is the default)
    example:
     

    - Id: 1004
          Name: AS_VENOMKNIFE
          Description: Throw Venom Knife
          MaxLevel: 1
          Type: Weapon
          #TargetType: Attack <<<<<<<<<<<<<<<< remove this line
          DamageFlags:
              IgnoreAtkCard: true
          Flags:
              IsQuest: true
              IgnoreAutoGuard: true
              IgnoreCicada: true
          Range: 9

     

    • Upvote 1
  8. Armor elements will not stack.

    the player element is set by a the bDefEle bonus script, and its value will be overwritten by the next bDefEle value.

    basically what happens is that first the gear script will be executed, so if you're wearing a water element armor, your element will become water.

    right after that the cards script will be executed. so if you have a pasana card in your armor, your element will become fire.

    and finally the random option bonuses will execute. so if you have a bonus that sets your element to wind it will change to wind, and if you have another bonus that set is to ghost then that will overwrite your element to ghost etc..

    i'm not sure about the order of the random option bonuses, but probably the last option will be the active one.

    On 1/29/2021 at 4:02 PM, chadness said:

    Is it also possible to have a script that will increase the level of an element when the same element is equipped? Example, [Armor Element] Lucius Fire Armor + [Card Slot] Pasana Card + [Random Option] Armor Element (Fire) = Level 3 Fire Armor?

    it is possible, but you'll need a source modification to achieve this

  9. this is probably the fastest way to do it: (untested) 

    if ( !isloggedin( $@partymemberaid[.@i], $@partymembercid[.@i] ) ||  // what happens if someone in the party member is offline =/
    	strcharinfo(3,$@partymembercid[.@i]) != .@mapname$ || // If the party member is not on the same map of the killer
    	checkidle(rid2name($@partymemberaid[.@i])) > 5 || // If player is idle for 30 seconds
    	getmapxy(.@membermap$, .@memberX, .@memberY, BL_PC, $partymemberaid[.@i]) == -1 || distance(.@mapx, .@mapy, .@memberX, .@memberY) > 15 ) // if the search failed or if ths distance is larger than 15 cells.

    from the docs: 

    ---------------------------------------
    
    *distance(<x0>,<y0>,<x1>,<y1>)
    
    Returns distance between 2 points.
    
    Example:
    	.@i = distance(100,200,101,202);
    
    ---------------------------------------
      
    ---------------------------------------
    
    *getmapxy("<variable for map name>",<variable for x>,<variable for y>{,<type>,"<	value>"})
    
    This function will locate a character object, NPC object or pet's coordinates
    and place their coordinates into the variables specified when calling it. It
    will return 0 if the search was successful, and -1 if the parameters given were
    not variables or the search was not successful.
    
    Type is the type of object to search for:
    
    	BL_PC   - Character object (default)
    	BL_NPC  - NPC object
    	BL_PET  - Pet object
    	BL_HOM  - Homunculus object
    	BL_MER  - Mercenary object
    	BL_ELEM - Elemental object
    
    The search value is optional. If it is not specified, the location of the
    invoking character will always be returned for types BL_PC and BL_PET,
    the location of the NPC running this function for type BL_NPC.
    
    If a search value is specified, for types BL_PC and BL_NPC, the
    character or NPC with the specified name or GID will be located.

     

    you could also try to use attachrid() to the party member and then check his location with getmapxy.

  10. Find the GM (hide and seek)


    A simple event. the GM npc will teleport to a random location in the specified map, and the first player to find him will win the round.

    //SETTINGS
    .rounds = 3; // for how many rounds should the event last?
    .map$ = "prontera"; // the event where the gm will hide
    .itemReward = 1;  
    setarray .rewards[0],909,5,716,2;   // [itemId, itemAmount, {....}]
    .zenyReward = 0;
    .zenyAmount = 1000;
    .debugMode = 0;
    .npcName$ = "GM Masta";
    .countdown = 3; // the time between event announcements and when the event actually starts.
    .automatic = 1;	// automatic event or does it need a gm to run it manually?
    .runEvery = 1;	// (ignore if manual) run the event ever X hours 
    .offset = 1;	// (ignore if manual) sometimes, you might have another event/announcement at the same time as the event announcement. you can set an offset (announce X minutes after event time.)

     


    • Submitter
    • Submitted
      01/30/2021
    • Category
    • Video
      https://www.youtube.com/watch?v=ZiXuwO0Ng9U&ab_channel=Mastagoon
    • Content Author
      Mastagoon

     

  11. if i'm understanding correctly, the problem is that the event/round ends as soon as the npc announces its coordinates? and you need to to wait 15s first?

    if that's the case, just add this line:

    if ($@ran == 2) set $@jmpmap$,"morocc";
    if ($@ran == 1) set $@jmpmap$,"prontera";
    announce "Jumper Event : Go Find me!! I'm here in "+$@jmpmap$+"!!!",bc_blue;
    set $@JmpRnd,10;
    sleep 15000; // <<<<<<<<<<<<<<< Add this
    goto OnStart;

    and the npc will wait 15 seconds after announcing its map before jumping again.

    and more importantly you should be using sleep and not sleep2 in this script. change all your "sleep2" lines with sleep.
     

    • Upvote 1
  12. 5 hours ago, wafflero said:

     

    Hi friends, i got problem on my server, the skills of Pala and Crusader do not appear in the skill tree, the tree is all white when choosing the profession, could someone help me? I already checked the skill_tree and everything is enabled. Could someone tell me how to solve the problem? Thank you very much in advance@@!

     

    screenWaffleRO Brasil001.jpg

    this  is probably a client-side problem. check your data\luafiles514\lua files\skillinfoz\skilltreeview.lub file and make sure you have the latest version from kRO

  13. 6 hours ago, DevilSupremeRO said:

    it's not working i tried to set it to 1 but my other dual character still can access inside

    sorry i had a typo in the code.
    this one should work :
     

    -	script	max_castle_guild_members	-1,{
    
    OnInit:
        //settings here 
        setarray .maps$, "prtg_cas01","prtg_cas03"; // insert your woe castles here
        .max_members_in_castle = 1;    // set the maximum number of guild members in a castle
     
        //don't edit this
     
        for(.@i = 0; .@i < getarraysize(.maps$); .@i++) {
            if(!getmapflag(.maps$[.@i], mf_loadevent)) setmapflag .maps$[.@i], mf_loadevent;
        }
        end;
     
    OnPCLoadMapEvent:
        if(inarray(.maps$, strcharinfo(3)) == -1) end;
        if(getmapguildusers(strcharinfo(3), getcharid(2)) > .max_members_in_castle) {
            dispbottom "There can only be "+.max_members_in_castle+" guild members inside a castle during woe.";
            warp "SavePoint",0,0;
        }
        end;
    }

     

    awd.jpg

    • Upvote 1
  14. @restock - get items from storage with a command


    My take on the @restock command. 

    This script allows you to set a list of item to restock from your storage, for example 100 blue gemstones and 300 white potions.

    When using the command, a ticket item will be consumed to get the specified items from storage.

    This script is so that you'll always have the needed quantity of items in the list. for example, if you have 22 gemstones in your inventory and you use @restock, you'll get the 78 gemstones missing to the full 100

    any feedback is appreciated.


    • Submitter
    • Submitted
      01/21/2021
    • Category
    • Video
    • Content Author
      Mastagoon

     

    • Love 1
    • MVP 1
  15. prontera,100,100,4	script	item_recording_npc	789,{
    	if(getgmlevel() < 99) end;
    	mes "Enter the ID of today's item.";
    	input .@itemId;
    	next;
    	mes "You're adding the item "+getitemname(.@itemId)+" to your list. continue?";
    	if(select("Yes:No") -1 ) close;
    	.@duration = gettimetick(2) + 30 * 24 * 60 * 60;
    	query_sql("INSERT INTO `recorded_items`(item_id, time) VALUES ("+.@itemId+", "+.@duration+")");
    	mes "item added succesfully!";
    	close;
    
    OnClock0000:
    	query_sql("SELECT id , record_time FROM `recorded_items`", .@ids, .@time);
    	for(.@i = 0; .@i < getarraysize(.@ids); .@i++) {
    		if(gettimetick(2) > .@time[.@i]) {
    			setarray .@deleteitems[getarraysize(.@deleteitems)], .@ids[.@i];
    		}
    	}
    	for(.@i = 0; .@i < getarraysize(.@deleteitems); .@i++) {
    		query_sql("DELETE FROM `recorded_items` WHERE id = "+.@deleteitems[.@i]);
    	}
    	end;
    OnInit:
    	.@sql$ = "CREATE TABLE IF NOT EXISTS `recorded_items`(id int(11) PRIMARY KEY AUTO_INCREMENT, item_id int(11), record_time int(11)";
    	query_sql(.@sql$);
    	end;
    }

    this npc allows a GM to add an item id to a table in the database, and checks every night at 12:00AM for any expired items (items that have been recorder more than 30 days ago) and deletes them from the database.

    there might be an easier way to do this, but maybe this  will work for you.

    please note that this code is untested.

  16. 5 minutes ago, mawjustin said:

    It basically records daily input by the GM into an NPC, and will keep that in the list for 30 days, after 30 days it will be removed. Basically and item-recording selling npc.

    and what happens if the GM skips a day ?

    also are you able to record more than 1 item per day?

  17. if you're talking about a certain boss monster, like a quest monster or so you can spawn that monster with a script and execute the reward command on the death trigger

    for example:

    -   script  boss_summoner   -1,{
    
    
    OnMobDead:
        addrid(1);
        getitem 909,1;
        end;
    
    OnInit:
        monster .map$,"--ja--",1002,1,strnpcinfo(3)+"::OnMobDead";
        end;
    }

    if you're talking about all the field & dungeon boss monsters that spawn naturally, then you can try this:

    -   script  boss_rewards   -1,{
    
    
    OnNPCKillEvent:
        if(getmonsterinfo(killedrid, MOB_MVPEXP) > 1) {
            addrid(1);
            getitem 909,1;
        }
        end;
    }

     

    • Upvote 1
  18. if you simply want to make every autoattack always crit:

    find the function "is_attack_critical" in src/map/battle.cpp

    and add this line at the end:

    switch(skill_id) {
    	case 0:
    	    return true; // <<<<<<<<<<<<<<<<<<<<<<<<<<<< Add this line
    		if(sc && !sc->data[SC_AUTOCOUNTER])
    			break;
    		clif_specialeffect(src, EF_AUTOCOUNTER, AREA);
    		status_change_end(src, SC_AUTOCOUNTER, INVALID_TIMER);
    	case KN_AUTOCOUNTER:
        .....

    save&recompile and all auto attacks will always crit.

  19.  

    what do you mean by having a normal and a hard mode instance? are we talking about 2 different instances with different monsters/story/etc..?

    if that's the case then it's fairly simple,  you want you can look at Old Glast Heim's entrance npc for example: 
     

    .@mode = select("Normal Mode:Hard Mode");
    	if(.@mode == 1) {
    		// enter intsance #1
    		
    	} else if(.@mode == 2) { // Hard Mode
    		//enter instance #2
    	}

    but if you have only 1 instance and want to make a hard mode from that instance well then it depends.

    if we're talking about a single instance you can just store the difficulty in an instance variable and edit the monster spawns and summon a harder version of the monsters in hard mode, for example:

    if('OGH_Mode < 2) // Normal Mode
    		monster 'map_name$[1],158,255,"Amdarais",2476,1,instance_npcname("#ghmemorialmob07") + "::OnMyMobDead";// MG_AMDARAIS
    	else if('OGH_Mode == 2) // Hard Mode
    		monster 'map_name$[1],158,255,"Amdarais",3150,1,instance_npcname("#ghmemorialmob07") + "::OnMyMobDead";// MG_AMDARAIS

    but yeah it really depends on what the difference between normal and hard mode is.

×
×
  • Create New...