Jump to content

Winterfox

Members
  • Posts

    236
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by Winterfox

  1. You can generate the navigation information of the npcs for the client by running navigenerator in the server root directory.
    Afterward, you can find the clientside files in the folder generated/clientside and copy that into your client root directory.

  2. -	script	FREEZE	FAKE_NPC,{
    	OnInit:
    		.@group = 99;
    		bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze", .@group);
    		bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze", .@group);
    	end;
    	
    	OnFreeze:
    		.@mode = 1;
    	OnUnfreeze:
    		getmapunits(BL_PC, .@atcmd_parameters$[0], .@players);
    		freeloop(1);
    		for(.@i = 0; .@i < getarraysize(.@players); .@i++)
    			pcblockmove(.@players[.@i], .@mode);
    		freeloop(0);
    }

     

    • Love 1
  3. -	script	FREEZE	FAKE_NPC,{
    	OnInit:
    		bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze");
    		bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze");
    	end;
    	
    	OnFreeze:
    		.@mode = 1;
    	OnUnfreeze:
    		getmapunits(BL_PC, .@atcmd_parameters$[0], .@players);
    		freeloop(1);
    		for(.@i = 0; .@i < getarraysize(.@players); .@i++)
    			pcblockmove(.@players[.@i], .@mode);
    		freeloop(0);
    }

     

  4. I didn't test it, but this should do what you want.
     

    -	script	FREEZE	FAKE_NPC,{
    	OnInit:
    		bindatcmd("freeze", strnpcinfo(3) + "::OnFreeze");
    		bindatcmd("unfreeze", strnpcinfo(3) + "::OnUnfreeze");
    	end;
    	
    	OnFreeze:
    		.@mode = 1;
    	OnUnfreeze:
    		getmapunits(BL_PC, getarg(0), .@players);
    		freeloop(1);
    		for(.@i = 0; .@i < getarraysize(.@players); .@i++)
    			pcblockmove(.@players[.@i], .@mode);
    		freeloop(0);
    }

     

  5. On 9/6/2023 at 8:12 PM, jamesandrew said:

    I'm making a simple fishing script.
    The rules are:
    -  Must equip a fishing rod (2764)
    - 5 seconds cast time
    - Get one reward per cast
    - Rewards rate are: Red Herb 40%; Yellow Herb 30%; White Herb 20%, Blue Herb 10%, Yggdrasil Berry 0.01%
     

    prt_fild00,278,237,0	script	Fishing School	10065,{
    set .@Rod,2764; //Fishing rod
    if (isequipped(.@Rod)){
    	specialeffect EF_BUBBLE,"Fishing School";
    	soundeffect "_attack_axe.wav",0;
    	dispbottom "[Fishing] Casting...";
    	set .@fcast,5;
    	progressbar "ffffff",.@fcast;
    	if (rand(1,10) <= 4) ||(rand(1,10) <= 3) || (rand(1,10) <= 2) || (rand(1,10) <= 1){
    		setarray .@Catch[0],507,508,509,510;// Red 40%, Yellow 30%, White 20%, Blue Herb 10%
    		set .@CatchRand,.@Catch[rand(getarraysize(.@Catch))];
    		getitem .@CatchRand,1;
    		specialeffect2 610;
    		soundeffectall "see_otter_damage.wav",0,strcharinfo(3);
    		dispbottom("[Fishing] You got "+ getitemname(.@CatchRand) +".");
    		}
    	else {
    		dispbottom "[Fishing] Nothing was caught...";
    		specialeffect2 611;
    		end;}
    			if (rand(1,100) == 1){
    				setarray .@Rare[0],607; //Yggdrasil Berry 0.01%
    				set .@RareCatch, .@Rare[rand(getarraysize(.@Rare))];
    				getitem .@RareCatch,1;
    				dispbottom("[Fishing] Congratulations you got "+ getitemname(.@RareCatch) +".");
    				specialeffect2 68;
    				end;}
    			else {
    				end;}
    	}
    else {
    	dispbottom "[Fishing] You need a Fishing Rod.";
    	end;
    	}
    }

    are these rands correct?

    Your pick code throws 4 dice with 10 eyes and checks if at least one fits, and then picks an item randomly.
    Which means your script decides if it should give loot or not (Which contradicts your 4. Rule) but in case it drops an item, it gives every item an equal chance to be dropped.

    Except Yggrasil Berry, which gets a 1% chance to be dropped regardless of if there was already a drop, which also contradicts your 4. Rule.
    Here is what I would do to change your script to make it fit your given rules:
     

    prt_fild00,278,237,0	script	Fishing School	10065,{
    	if (!isequipped(.rod)) {
    		dispbottom("[Fishing] You need a Fishing Rod.");
    		end;
    	}
    
    	specialeffect(EF_BUBBLE, "Fishing School");
    	soundeffect("_attack_axe.wav", 0);
    	dispbottom("[Fishing] Casting...");
    	progressbar("ffffff", .cast_delay);
    
    	.@pick = rand(1, .catch_weight_sum);
    	for(.@i = 0; .@i < getarraysize(.catches); .@i += 2) {
    		.@pick -= .catches[.@i + 1];
    		if(.@pick <= 0) {
    			.@catch = .catches[.@i];
    			break;
    		}
    	}
    
    	getitem(.@catch, 1);
    	specialeffect2(610);
    	soundeffectall("see_otter_damage.wav", 0, strcharinfo(3));
    	dispbottom("[Fishing] You got "+ getitemname(.@catch) + ".");
    	end;
    
        OnInit:
    		.rod = 2764;
    		.cast_delay = 5;
    		
    		// Red Herb 40%; Yellow Herb 30%; White Herb 20%, Blue Herb 10%, Yggdrasil Berry 0.01%
    		setarray(.catches, 507, 4000, 508, 3000, 509, 2000, 510, 1000, 607, 1);
    
    		for(.@i = 0; .@i < getarraysize(.catches); .@i += 2)
    			.catch_weight_sum = .catches[.@i + 1];
    }

     

    • Upvote 1
  6. 1 hour ago, namerpus18 said:

    I am sorry, I also tried that method but the thing is inside the quote should be a <condition> can be any expression similar to the <condition> in the 'if' command. I am not quite sure if doing for inside it is really possible. Thank you

    OnInit:
    questinfo(QTYPE_QUEST),QMARK_YELLOW, "checkquest (11114,HUNTING) == 2 || checkquest (11115,HUNTING) == 2 || checkquest (11116,HUNTING) == 2 || checkquest (11117,HUNTING) == 2 || checkquest (11118,HUNTING) == 2 || checkquest (11119,HUNTING) == 2 || checkquest (11120,HUNTING) == 2 || checkquest (11121,HUNTING) == 2 || checkquest (11122,HUNTING) == 2 || checkquest (11123,HUNTING) == 2";

     

    You are right, it doesn't seem like you can put anything inside the condition argument of the questinfo function that doesn't return a value directly.
    It simply evaluates if the result of the script in the conditions string results in true or false, when certain events like the completion of a quest trigger a reevaluation. 

    That means you can only use functions that the script engine knows and that return a value. 
    So what you can do alternatively is to build the condition string dynamically. 

    prontera,150,193,4	script	DEMO	124,{
    	OnInit:
    		setarray(.@quests, 11114, 11115, 11116, 11117, 11118, 11119, 11120, 11121, 11122, 11123);
    		for(.@i = 0; .@i < getarraysize(.@quests); .@i++)
    			.@condition$[.@i] = "checkquest(" + .@quests[.@i] + ", HUNTING) == 2";
    
    		questinfo(QTYPE_QUEST, QMARK_YELLOW,  implode(.@condition$, "||"));
    }

     

    • Love 1
  7. -	script	SKILL_DEMO	FAKE_NPC,{
    	OnInit:
    		monster("prontera", 150, 170, "Helper A", 1002, 1);
    		.@mob_a = $@mobid[0];
    		unitblockmove(.@mob_a, 1);
    
    		getunitdata(.@mob_a, .@mob_a_data);
    		.@pos_x = .@mob_a_data[UMOB_X];
    		.@pos_y = .@mob_a_data[UMOB_Y];
    
    		monster("prontera", 140, 160, "Helper B", 1002, 1);
    		.@mob_b = $@mobid[0];
    
    		while(.@pos_x != .@target_x || .@pos_y != .@target_y) {
    			getunitdata(.@mob_b, .@mob_b_data);
    			.@target_x = .@mob_b_data[UMOB_X];
    			.@target_y = .@mob_b_data[UMOB_Y];
    
    			if(.@pos_x != .@target_x) .@pos_x += (.@pos_x < .@target_x) ? 1 : -1;
    			if(.@pos_y != .@target_y) .@pos_y += (.@pos_y < .@target_y) ? 1 : -1;
    
    			unitskillusepos(.@mob_a, "MG_THUNDERSTORM", 10, .@pos_x, .@pos_y, -5, false, 0, true);
    			sleep(1000);
    		}
    }

     

  8. 25 minutes ago, namerpus18 said:

    Good Day everyone,

     I just need some help, if someone can help me shorten this script. My methods are too limited and i cant find a way to shorten it.

    Does it improve if i manage to optimize this script? I feel that this script alone takes a lot of checking.

    Thank you so much,

    if(getmonsterinfo(killedrid, MOB_MVPEXP) > 1 && isbegin_quest(19000) > 0 || isbegin_quest(19001) > 0 || isbegin_quest(19002) > 0 || isbegin_quest(19003) > 0 || isbegin_quest(19004) > 0 || isbegin_quest(19005) > 0 || isbegin_quest(19006) > 0 || isbegin_quest(19007) > 0 || isbegin_quest(19008) > 0 || isbegin_quest(19009) > 0 || isbegin_quest(19010) > 0 || isbegin_quest(19011) > 0 || isbegin_quest(19012) > 0 || isbegin_quest(19013) > 0 || isbegin_quest(19014) > 0 || isbegin_quest(19015) > 0 || isbegin_quest(19016) > 0 || isbegin_quest(19017) > 0 || isbegin_quest(19018) > 0 || isbegin_quest(19019) > 0 )	{
      ....
    }

     

    It is hard to really optimize the script without knowing the whole code. But to make the snippet you have more manageable, you could organize your code like this:
     

    for(.@i = 0; .@i < 20; .@i++) {
        if(isbegin_quest(19000 + .@i) > 0) {
            .@has_quest = 1;
            break;
        }
     }
    
    if(getmonsterinfo(killedrid, MOB_MVPEXP) > 1 && .@has_quest)	{
    
    }

     

  9. 4 hours ago, jamesandrew said:

    I've just tested it. It does work but it's very easy to abuse by swapping weapons 😞
    Thanks though

     

    ----edit
    Is it possible to use specialeffect2 from this list rathena/doc/effect_list.txt at master · rathena/rathena (github.com) to make your character act like auto attacking mobs?

    I am not sure if there is an effect that makes it look like a character attacks.

    Another idea I had would be to spawn an invisible mob below the ore NPC when the player meets the requirements, and then to set him up to attack that mob and lock him in this state until he killed the ore mob.
    When the ore mob is dead, you can hide the npc for the player for a certain amount of time.

    For the part of making a player attack a mob and blocking movement, you could check the commands: unitattack and, setpcblock that could help you with that. In general, the unit commands could be of help to you.
    For the part about visibility of ores, you could use the on touch area of the npc and combine that with cloakonnpc or cloakonnpcself to control which players can see the npc right now.

  10. You could attach the checks on a label that gets triggered when the mob that represents an ore gets killed.

    Here is a small example:

    -	script	MINING	FAKE_NPC,{
    	OnInit:
    		// Config
    		setarray(.mining_utils, 28116);
    
    		setarray(.minerals, 3742, 3743, 1083);
    
    		.mineral_0_name$ = "Bronze";
    		setarray(.mineral_0_maps$, "prontera");
    		setarray(.mineral_0_amounts, 10);
    		setarray(.mineral_0_areas_x_1, 150);
    		setarray(.mineral_0_areas_x_2, 163);
    		setarray(.mineral_0_areas_y_1, 175);
    		setarray(.mineral_0_areas_y_2, 137);
    		setarray(.mineral_0_items, 502, 10, 1, 5, 503, 40, 1, 5, 504, 50, 1, 5);
    
    		.mineral_1_name$ = "Silver";
    		setarray(.mineral_1_maps$, "prontera");
    		setarray(.mineral_1_amounts, 10);
    		setarray(.mineral_1_areas_x_1, 150);
    		setarray(.mineral_1_areas_x_2, 163);
    		setarray(.mineral_1_areas_y_1, 150);
    		setarray(.mineral_1_areas_y_2, 200);
    		setarray(.mineral_1_items, 505, 10, 1, 5, 506, 40, 1, 5, 507, 50, 1, 5);
    
    		.mineral_2_name$ = "Gold";
    		setarray(.mineral_2_maps$, "prontera");
    		setarray(.mineral_2_amounts, 10);
    		setarray(.mineral_2_areas_x_1, 150);
    		setarray(.mineral_2_areas_x_2, 163);
    		setarray(.mineral_2_areas_y_1, 175);
    		setarray(.mineral_2_areas_y_2, 137);
    		setarray(.mineral_2_items, 508, 10, 1, 5, 509, 40, 1, 5, 510, 50, 1, 5);
    
    		// Config End
    		for(.@i = 0; .@i < getarraysize(.minerals); .@i++) {
    			.@name$ = getd(".mineral_" + .@i + "_name$");
    			.@items = getd(".mineral_" + .@i + "_items");
    
    			.@items_size = getarraysize(getd(".mineral_" + .@i + "_items"));
    			.@item_sum = 0;
    			for(.@x = 0; .@x < .@items_size; .@x += 4)
    				.@item_sum += getd(".mineral_" + .@i + "_items[" + (.@x + 1) + "]");
    
    			setd(".mineral_" + .@i + "_item_sum", .@item_sum);
    
    			.@maps_size = getarraysize(getd(".mineral_" + .@i + "_maps$"));
    			for(.@y = 0; .@y < .@maps_size; .@y++) {
    				.@maps$ = getd(".mineral_" + .@i + "_maps$[" + .@y + "]");
    				.@amounts = getd(".mineral_" + .@i + "_amounts[" + .@y + "]");
    				.@areas_x_1 = getd(".mineral_" + .@i + "_areas_x_1[" + .@y + "]");
    				.@areas_x_2 = getd(".mineral_" + .@i + "_areas_x_2[" + .@y + "]");
    				.@areas_y_1 = getd(".mineral_" + .@i + "_areas_y_1[" + .@y + "]");
    				.@areas_y_2 = getd(".mineral_" + .@i + "_areas_y_2[" + .@y + "]");
    
    				areamonster(.@maps$, .@areas_x_1, .@areas_x_2, .@areas_y_1, .@areas_y_2, .@name$, .minerals[.@i], .@amounts, "MINING::OnMined");
    			}
    		}
    	end;
    
    	OnMined:
    		.@mineral = inarray(.minerals, killedrid);
    		.@mineral_name$ = getd(".mineral_" + .@mineral + "_name$");
    		.@util = getequipid(EQI_HAND_R);
    
    		if(inarray(.mining_utils, .@util) == -1) {
    			dispbottom("Using your " + getitemname(.@util) + " destroyed any useful resource from " + .@mineral_name$ + ".");
    			end;
    		}
    
    		.@mineral_item_sum = getd(".mineral_" + .@mineral + "_item_sum");
    		.@mineral_items_size = getarraysize(getd(".mineral_" + .@i + "_items"));
    
    		.@pick = rand(1, .@mineral_item_sum);
    		for(.@i = 0; .@i < .@mineral_items_size; .@i += 4) {
    			.@pick -=  getd(".mineral_" + .@mineral + "_items[" + (.@i + 1) + "]");
    
    			if(.@pick <= 0)
    				break;
    		}
    
    		.@item = getd(".mineral_" + .@mineral + "_items[" + .@i + "]");
    		.@item_min_amount = getd(".mineral_" + .@mineral + "_items[" + (.@i + 2) + "]");
    		.@item_max_amount = getd(".mineral_" + .@mineral + "_items[" + (.@i + 3) + "]");
    
    		getitem(.@item, rand(.@item_min_amount, .@item_max_amount));
    }

    This will spawn different minerals (in this example represented by purple ore and plants), which give different items on kill etc. once a mineral gets killed, it checks if an item from the .mining_utils array is equipped and if not gives the player the message, that using the wrong item destroyed any useful resources otherwise it will roll which and how many of an item the player gets.

    • Upvote 1
  11. The easiest way would be to create a custom mob that looks like a mineral. You could for example copy Purple Ore (id: 3742) and add the items you want the player to get by mining as drop.
    You just need to remember to add your custom mob to mob_avail,yml to tell rathena to make the client use the sprite of the original mob for your custom one.

    • Upvote 1
  12. 2 hours ago, jamesandrew said:

    Hey thanks for the reply. I tried to adjust the value to 40 but you can still do the trick as long as multiple spaces are allowed.
    image.png.1a00339a43fe7c9a53394ae563254646.png

     

    Someone actually posted this code on RMS forum. I have no idea where to start. 
    Do you think it could work?

    
    	length = strlen(output) + 1;
    
    	if (sd->chatID && pc_get_group_level(sd) < 20) {
    		int i;
    		
    		for (i = 0; i < length; i++) {
    			switch(output[i]) {
    				case '\x09':
    				case '\xA0':
    				case '\x0A':
    				case '\x0B':
    				case '\x0C':
    				case '\x0D':
    					output[i] = '\x20';
    					break;
    			}
    		}
    
    		if (stristr(output, " : ") || stristr(output, " ; ") || stristr(output, "   ") ||
    			stristr(output, "Tokei") || stristr(output, "Saga") || stristr(output, "Pegasus") ||
    			stristr(output, "GM ") || stristr(output, "[G M]") || stristr(output, " GM") || strstr(output, "GM") || stristr(output, "[GM]") || stristr(output, "(GM)") || stristr(output, "{GM}") ||
    			stristr(output, "Skype") || stristr(output, "discord") || stristr(output, "facebook")) {
    			clif_colormes(sd->fd, color_table[COLOR_RED], "You are only allowed to type a maximum of 3 spaces in a row.");
    			return;
    		}
    	}
    
    	// send message to others (using the send buffer for temp. storage)
    	clif_GlobalMessage(&sd->bl,output,sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);

     

    Looks okay. Why don't you test it?

  13. I am not sure if I really understood you 100% but if I got you right, you want your script to work like this:
     

    ma_in01,49,99,3	script	Fallen Hero#main	651,{
    	cutin("3rd_rune_knight", 2);
    	.@remaining_minutes  = (#next_fallen_gift - gettimetick(2)) / 60;
    
    	if(#next_fallen_gift > 0 && .@remaining_minutes > 0) {
    		if(.@remaining_minutes > 60)
    			.@remaining_hours = .@remaining_minutes / 60;
    
    		mes "[ ^0000FFFallen Hero^000000 ]";
    		mes "You have to wait ^FF0000" + ((.@remaining_hours > 0) ? F_InsertPlural(.@remaining_hours, "hour") : F_InsertPlural(.@remaining_minutes, "minute")) + "^000000 until you can get your next gift.";
    		close3;
    	}
    
    	mes "[ ^0000FFFallen Hero^000000 ]";
    	mes "Hello " + strcharinfo(0) + ".";
    	mes "I give you a free gift every day.";
    	mes "Let's hope that you will get something good today.";
    	next;
    	mes "[ ^0000FFFallen Hero^000000 ]";
    	mes "Let me see what I gift have for you...";
    
    	.@pick = rand(1, .items_sum);
    	for(.@i = 0; .@i < getarraysize(.items); .@i += 2) {
    			.@pick -= .items[.@i + 1];
    			if(.@pick <= 0) {
    				.@item = .items[.@i];
    				break;
    			}
    	}
    
        getitem(.@item, 1);
    	announce(strcharinfo(0) + " has obtained " + getitemname(.@item) + " from the Fallen Hero!", bc_all, 0x00FFFF, FW_NORMAL, 15);
    	mes "Here take this " + getitemname(.@item) + ".";
    	#next_fallen_gift = gettimetick(2) + .next_gift_duration;
    	next;
    	mes "[ ^0000FFFallen Hero^000000 ]";
    	mes "Come back later to receive a new gift.";
    	close3;
    
    	OnInit:
            // duration until the next gift can be gotten.
    		.next_gift_duration = 86400;
    
            // item chances <<item id>, <chance>>, <<item id>, <chance>>...
    		setarray(.items, 6232, 10, 6228, 10, 13710, 10, 12916, 10, 5184, 10, 5199, 10, 5209, 10, 5762, 10, 5467, 10, 12884, 20, 12885, 20, 12886, 20, 12887, 20, 35078, 20, 13698, 70, 13697, 70, 14175, 70, 14587, 70, 12920, 70, 12921, 70, 14192, 70, 16504, 70, 12922, 70, 7776, 70, 12412, 70, 35111, 70);
    
    		for(.@i = 0; .@i < getarraysize(.items); .@i += 2)
    			.items_sum += .items[.@i + 1];
    }

     

  14. Why don't you try to learn to write that script yourself? What you want isn't that complicated and would be quite a good beginner script to learn how to write your own NPCs.
    If you want to give learning to script a try, you can find the documentation for rAthena script here: https://github.com/rathena/rathena/blob/master/doc/script_commands.txt

    For the script you want, I would recommend you to check the commands countitem, delitem and getitem.

  15. 1 hour ago, dalubhasa333 said:

    Hi There.

     

    Yeah i didnt notice it is not saving to the itemdb since im using winscp the itemdb i opened saved to my pc not in my server 

    However. got new problem in my prerenewal server the costume/item robe is not showing when equiped, but on my renewal server everything is working fine, they are using the same ro client and grf. not sure how this could be.

    They use different item dbs, did you put the item in both?

  16. 42 minutes ago, hendra814 said:

    get error when run sql script, can you help me for this error

    image.thumb.png.c5d04bb24bd81a5578c0d53d4fa10317.png

    I am not sure what result Emistry wants to achieve since dropping the table and only creating it if it doesn't exist afterward is a bit contradictory, but you could change DELETE to DROP like this:

    DROP TABLE IF EXISTS `ero_buildmanager`;

     

    • Upvote 1
  17. prontera, 155, 180, 4	script	Guild Donation Manager	4_F_AGENTKAFRA,{
    	function listAcceptedItems {
    		for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++)
    			mes getitemname(.accepted_items[.@i]);
    	}
    
    	function saveDonation {
    		.@guild_id = getcharid(2);
    		.@character_id = getcharid(0);
    		.@zeny = getarg(0);
    			
    		for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++) {
    			.@item_row$ = "item" + (.@i + 1);
    
    			.@item_rows$ += ", " + .@item_row$;
    			.@item_insert$ += ", " + getelementofarray(getarg(1), .@i));
    			.@insert_update$ += ", " + .@item_row$ + " = " + .@item_row$ + " + " + getelementofarray(getarg(1), .@i));
    		}
    
    		query_sql("INSERT INTO guild_donations (guild_id, character_id, zeny" + .@item_rows$ + ") VALUES (" + .@guild_id + ", " + .@character_id + ", " + .@zeny + .@item_insert$ + ") ON DUPLICATE KEY UPDATE zeny = zeny + " + .@zeny + .@insert_update$);
    	}
    
    	function showHistory {
    		.@guild_id = getcharid(2);
    
    		for(.@i = 0; .@i < getarraysize(.accepted_items); .@i++)
    			.@item_rows$ += ", item" + (.@i + 1);
    
    		query_sql("SELECT character_id, zeny" + .@item_rows$ + " FROM guild_donations WHERE guild_id = " + .@guild_id, .@character_id, .@zeny, .@item1, .@item2);
    
    		for(.@i = 0; .@i < getarraysize(.@guild_id); .@i++)
    			mes "Character: " + strcharinfo(0, .@character_id[.@i]) + " Zeny: " + .@zeny[.@i] + " " + getitemname(.accepted_items[0]) + ": " + .@item1[.@i] + " " + getitemname(.accepted_items[1]) + ": " + .@item2[.@i];
    	}
    
    	if((.@guild_id = getcharid(2)) == 0) {
    		mes "[" + .npc_name$ + "]";
    		mes "Sadly i can't help you, since you are not in a guild.";
    		close;
    	}
    
    	mes "[" + .npc_name$ + "]";
    	mes "Hello Guild " + ((is_guild_leader(.@guild_id)) ? "Master" : "Member") + "!";
    	mes "How may i help you today?";
    	next;
    	switch(select("I want to donate.:Show me the donation history.")) {
    		case 1:
    			mes "[" + .npc_name$ + "]";
    			mes "What do you want to donate?";
    			next;
    			if(select("Zeny:Items") == 1) {
    				mes "[" + .npc_name$ + "]";
    				mes "How many zeny do you want to donate?";
    				next;
    				input(.@donation);
    				if (Zeny < .@donation) {
    					mes "[" + .npc_name$ + "]";
    					mes "You don't have enough zeny.";
    					close;
    				}
    				Zeny -= .@donation;
    				saveDonation(.@donation, .@items);
    				mes "[" + .npc_name$ + "]";
    				mes "Alright, i registered your donation!";
    				close;
    			} else {
    				mes "[" + .npc_name$ + "]";
    				mes "Remember i can only take the following items: ";
    				listAcceptedItems();
    				close2;
    				callshop("guild_donation_dummy_shop", 2);
    				npcshopattach("guild_donation_dummy_shop");
    				end;
    			}
    			break;
    		case 2:
    			mes "[" + .npc_name$ + "]";
    			showHistory();
    			close;
    			break;
    	}
    
    	OnSellItem:
    		for(.@i = 0; .@i < getarraysize(@sold_nameid); .@i++) {
    			if((.@index = inarray(.accepted_items[0], @sold_nameid[.@i])) == -1) {
    				mes "[" + .npc_name$ + "]";
    				mes "There are items i can't accept.";
    				mes "I only take the following items: ";
    				listAcceptedItems();
    				close;
    			}
    
    			.@items[.@index] = @sold_quantity[.@i];
    		}
    
    		for(.@i = 0; .@i < getarraysize(@sold_nameid); .@i++)
    			delitem(@sold_nameid[.@i], @sold_quantity[.@i]);
    
    		saveDonation(0, .@items);
    		end;
    
    	OnInit:
    		.npc_name$ = strnpcinfo(1);
    		setarray(.accepted_items[0], 45000, 45001);
    }
    
    -	shop	guild_donation_dummy_shop	-1,501:50.
    CREATE TABLE IF NOT EXISTS `guild_donations` (
      `guild_id` int(11) NOT NULL,
      `character_id` int(11) NOT NULL,
      `character_name` varchar(32) NOT NULL,
      `zeny` int(11) NOT NULL,
      `item1` int(11) NOT NULL,
      `item2` int(11) NOT NULL,
      PRIMARY KEY (`guild_id`,`character_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

     

    • MVP 1
  18. I didn't test it, but this should do what you want.
     

    prontera,156,178,5	script	Enchanter	100,{
    	disable_items;
    
    	mes "What do you want to enchant?";
    	next;
    	.@s = select( .menu$ ) -1;
    	.@part = .const_equip[.@s];
    	.@part_name = .menu_name$[.@s];
    
    	if (!getequipisequiped(.@part)) {
    		mes "You did not equip an " + .@part_name + " at the moment";
    		close;
    	}
    
    	.@id = getequipid(.@part);
    	.@ref = getequiprefinerycnt(.@part);
    	setarray(.@card[0], getequipcardid(.@part, 0), getequipcardid(.@part, 1), getequipcardid(.@part, 2), getequipcardid(.@part, 3));
    
    	if (.@card[0] == 255 || .@card[0] == 254) {
    		mes "I can't enchant a signed equipment";
    		close;
    	}
    
    	if (.@card[3]) {
    		mes "This " + .@part_name + " is already enchanted";
    		close;
    	}
    	
    	.@rand = rand(1, .totalchance);
    	while ((.@rand -= .rate[.@orb_level]) > 0) .@orb_level++;
    	.@orb = 4700 + rand(0, 5) * 10 + .@orb_level; // orb of str/int/dex ....
    
    	if (callfunc("F_IsEquipIDHack", .@part, .@id) ||
    		callfunc("F_IsEquipRefineHack", .@part, .@ref) || callfunc("F_IsEquipCardHack", .@part, .@card[0], .@card[1], .@card[2], .@card[3])) {
    		emotion ET_FRET;
    		mes "Wait a second...";
    		mes "Do you think I'm stupid?!";
    		mes "You switched the item while I wasn't looking! Get out of here!";
    		close;
    	}
    
    	delitem2(.@id, 1, 1, .@ref, 0, .@card[0], .@card[1], .@card[2], 0);
    	getitem2(.@id, 1, 1, .@ref, 0, .@card[0], .@card[1], .@card[2], .@orb);
    	equip(.@id);
    	end;
    
    	OnInit:
    		setarray(.rate, 55, 50, 45); //, 40, 35); // rate of getting +1 is 55%, +2 is 50% .... +10 is 10% ...
    
    		setarray(.const_equip, EQP_COSTUME_HEAD_TOP);
    		setarray(.menu_name$, "Upper Costume Headgear");
    		.menu$ = implode(.menu_name$, ":");
    
    		for(.@i = 0; .@i < getarraysize(.rate); .@i++)
    			.totalchance += .rate[.@i];
    }

     

×
×
  • Create New...