Jump to content

Poring King

Members
  • Posts

    1016
  • Joined

  • Last visited

  • Days Won

    22

Posts posted by Poring King

  1. 39 minutes ago, Kater said:

    To use the skill_damage_db.txt file, is it necessary to enable it in the src? If yes, where?

    Skill dmage db is already enabled . You don't need to enable it . Just simply edit it and use @reloadskilldb to your server after applying

    • Like 1
  2. 3 hours ago, Z3R0 said:

    I won't explain exactly how to do this, but you could simply use the following information

    OnPCKillEvent:

    This special label triggers when a player kills another player. The variable
    'killedrid' is set to the ID of the player killed.

     

    *getmapxy("<variable for map name>",<variable for x>,<variable for y>{,<type>,"<search value>"})

    *getcharid(<type>{,"<character name>"}) // Type = 3 (for Account ID)

    #KAFRAPOINTS

    *attachrid(<account_id>);

    - Attaches Script to Account ID (reads information from attached account)

     

    Using the information here, we can determine the following:

     

    When the Trigger Runs, we can use getmapxy to determine the location of the user and check the map that they are on, the NPC should be hidden with a -1 and placed on the map... I believe it will only trigger if ON that map, but I could be mistaken, hence the reason to use getmapxy and check...

    Once you determined if they are on that map, the next thing to do, would be to set a variable called origrid = getcharid(3); // this will allow you to go "back" to this user, once we go to the killed user to get their information...

    So, then using attachrid(killedrid); you can attach the script to the killed player, and then store a variable (npc variable) to store the #KAFRAPOINTS they had, and no you can set those to ZERO...

    Then reattach the script back to the origrid and add that npc variable with the #KAFRAPOINTS to the original killer's #KAFRAPOINTS

    Seems like from Chat GPT

  3. 10 minutes ago, Kater said:

     

     

    Analyzing the server, I'm having spikes of 80% on map-server.
    Does anyone know what could be causing this intermittent consumption.

    Your hosting specs should be tell so we can compare or give advise to you brother

    1. Yes you can do it. Get the idea from giving Freebies there is a time period and you will get the item .
    2. This time do it single item each instead of whole package .
    3. If he/she select this item from your option/menu/switch .
    4. He will get the new item with the time period then you will delete what he got now . Just add a payment method or something in exchange . 
    5. You can play with the script and optimize or you can even add a delay or special day that player can also use it in a specific day and delay so player can't abuse it
       

    Thats a simple idea i can give it to you..

  4. Add gettimetick(2)

    Try the code below

    -    script    global    -1,{
        
    OnInit:
        setarray .@LastWhisperTime[0], 0; // Initialize an array to store the last whisper time
    
    OnWhisperglobal:
        if (getgroupid() < 5) end; // Allow only players with group ID 5 and above to use this command
        if (.@LastWhisperTime[getcharid(0)] + 20 > gettimetick(2)) {
            // If the time since the last whisper is less than 20 seconds, prevent another whisper
            dispbottom "You need to wait " + (.@LastWhisperTime[getcharid(0)] + 20 - gettimetick(2)) + " seconds before sending another message.";
            end;
        }
        // Update the last whisper time to the current time
        .@LastWhisperTime[getcharid(0)] = gettimetick(2);
        // Announce the message
        announce ""+strcharinfo(0)+": "+@whispervar0$,bc_all;
    
    end;
    
    }

     

  5. On 6/8/2024 at 4:09 PM, PARANOiA said:

    @Poring Kingdo you know any good VPS provider? btw... the ddos attack that we had broke something in the char table (i got a message that the char table needed to be fixed) so do you know from where this attack came from? the only thing that I have in mind is doing a lot of request in ranking or characters in control panel

    I use OVH since the beginning. If you dont know how to get info of ddos . You can ask there support

  6. Get a VPS Provider that give a reliable Ddos protection . By doing it on server side you can't do anything about it . You can only put a script that will let your player that the server is getting Ddos attack and it will initiate the script with in 5secs from the attack all the data will be save to avoid losing item etc . Im currently in project of the NPC that will initiate during Ddos attack . The problem is there is no way i can test it or attack my own server to test it out the NPC . So probably i will drop this NPC script that im trying to build from the scratch

    • Love 1
  7. On 6/6/2024 at 8:01 AM, nermit said:

    Hello, is there a way to restrict a player from opening a box item by mac (gepard) using script from the item rather than using npc?
    This is to prevent players from abusing free items from custom boxes.

    Yes by adding custom function . Then use it/add it to your item script in your item_db

  8. 5 minutes ago, PARANOiA said:

    before the BETWEEN the 'lv' should be changed to 'level' to work

    query_sql("SELECT ID FROM `" + .mob_db$ + "` WHERE left(name_aegis, 4) != 'meta' AND left(name_aegis, 2) != 'E_' AND base_exp > 0 AND job_exp > 0 AND (class != 'boss' OR class is null) AND (drop3_item like '%_card' OR drop4_item like '%_card' OR drop5_item like '%_card' OR drop6_item like '%_card' OR drop7_item like '%_card' OR drop8_item like '%_card' OR drop9_item like '%_card' OR drop10_item like '%_card') AND ID < 2000 AND instr('"+.Blacklist$+"',ID) = 0 AND level BETWEEN " + (BaseLevel - 20) + " AND " + (BaseLevel + 10) + " ORDER BY rand() LIMIT " + .Quests, .@mob);

    And I had to modify the values from 

     (BaseLevel - 5) + " AND " + (BaseLevel + 10)

    to:

     (BaseLevel - 20) + " AND " + (BaseLevel + 10)

    because in lvl 99 is giving me the same monsters always.

     

    Thank you so much for your help @Poring King! SOLVED

    My bad typo . Just up the post so other will know that this trend will mark as solve 

    • Upvote 1
  9. 23 minutes ago, PARANOiA said:

    Hello @Poring King is that the only line that you changed? Im not seeing any monster, Ive tried with a lvl 99 and with lvl 1

    image.png.69db63db170c5af517c46d1c7aa2b39c.png


    Try this. The SQL query may not be returning any results because there are no monsters in your database that match the specified criteria.

    query_sql("SELECT ID FROM `" + .mob_db$ + "` WHERE left(name_aegis, 4) != 'meta' AND left(name_aegis, 2) != 'E_' AND base_exp > 0 AND job_exp > 0 AND (class != 'boss' OR class is null) AND (drop3_item like '%_card' OR drop4_item like '%_card' OR drop5_item like '%_card' OR drop6_item like '%_card' OR drop7_item like '%_card' OR drop8_item like '%_card' OR drop9_item like '%_card' OR drop10_item like '%_card') AND ID < 2000 AND instr('"+.Blacklist$+"',ID) = 0 AND lv BETWEEN " + (BaseLevel - 5) + " AND " + (BaseLevel + 10) + " ORDER BY rand() LIMIT " + .Quests, .@mob);


    Seems like i didn't understand well this part 

    "between 5 levels down  and 10 levels up"

  10. Try this i adjust the SQL query that selects the monsters. Specifically, you need to add a condition that restricts the monster selection based on the player's level.


     

    //===== rAthena Script =======================================
    //= Hunting Missions
    //===== By: ==================================================
    //= Euphy
    //===== Current Version: =====================================
    //= 1.4
    //===== Compatible With: ===================================== 
    //= rAthena Project
    //===== Description: =========================================
    //= Random hunting missions.
    //= Rewards are based on quest difficulty.
    //= 
    //= NOTE: Requires SQL mob database.
    //===== Additional Comments: =================================
    //= 1.0 Initial script.
    //= 1.1 Small improvements and fixes.
    //= 1.2 Added party support and replaced blacklists with an
    //=     SQL query, both thanks to AnnieRuru.
    //= 1.3 Re-added a blacklist adapted for the SQL query.
    //= 1.3a Added mission reset options.
    //= 1.3b Function updates.
    //= 1.4 Check for deleted characters, thanks to AnnieRuru.
    //=     Syntax updates and style cleaning.
    //============================================================
    
    prontera,152,187,6	script	Hunting Missions	4_F_EDEN_MASTER,{
    function Chk;
    	mes "[Hunting Missions]";
    	mes "Hello, " + strcharinfo(0) + "!";
    	if (!#Mission_Delay) {
    		next;
    		mes "[Hunting Missions]";
    		mes "I can't find any records...";
    		mes "You must be new here!";
    		emotion ET_HUK;
    		next;
    		callsub Mission_Info;
    		emotion ET_GO;
    		#Mission_Delay = 1;
    		close;
    	}
    	mes F_Rand("Working hard, as always...", "Not slacking, I hope...");
    	mes "Is there anything I can help";
    	mes "you with?";
    	mes " ";
    	mes "^777777~ You've completed " + F_InsertPlural(Mission_Total,"mission",0,"^0055FF%d^777777 %s") + ". ~^000000";
    	next;
    	switch(select(
    		((!Mission0) ? " ~ New Mission::" : ": ~ Mission Status: ~ Abandon Mission") +
    		": ~ Information: ~ Mission Shop: ~ View Top Hunters: ~ ^777777Cancel^000000"
    	)) {
    	case 1:
    		mes "[Hunting Missions]";
    		if (#Mission_Count) {
    			mes "You've started a mission";
    			mes "on another character.";
    			if (!@hm_char_del_check) {  // check for deleted character
    				query_sql("SELECT 1 FROM `char_reg_num` WHERE `key` = 'Mission0' AND `char_id` IN(SELECT `char_id` FROM `char` WHERE `account_id` = " + getcharid(3) + ")", .@i);
    				if (!.@i) {
    					next;
    					mes "[Hunting Missions]";
    					mes "I can't seem to find any records";
    					mes "for that character, though...";
    					mes "One moment, please.";
    					emotion ET_SCRATCH;
    					#Mission_Count = 0;
    				}
    				@hm_char_del_check = true;
    			}
    			close;
    		}
    		if (#Mission_Delay > gettimetick(2) && .Delay) {
    			mes "I'm afraid you'll have to wait " + Time2Str(#Mission_Delay) + " before taking another mission.";
    			close;
    		}
    		mes "You must hunt:";
    		query_sql("SELECT ID FROM `" + .mob_db$ + "` WHERE left(name_aegis, 4) != 'meta' AND left(name_aegis, 2) != 'E_' AND base_exp > 0 AND job_exp > 0 AND (class != 'boss' OR class is null) AND (drop3_item like '%_card' OR drop4_item like '%_card' OR drop5_item like '%_card' OR drop6_item like '%_card' OR drop7_item like '%_card' OR drop8_item like '%_card' OR drop9_item like '%_card' OR drop10_item like '%_card') AND ID < 2000 AND instr('"+.Blacklist$+"',ID) = 0 AND lv BETWEEN " + (BaseLevel - 5) + " AND " + (BaseLevel + 10) + " ORDER BY rand() LIMIT " + .Quests, .@mob);
    		
    		for (.@i = 0; .@i < .Quests; .@i++) {
    			setd "Mission" + .@i, .@mob[.@i];
    			setd "Mission" + .@i +"_", 0;
    		}
    		#Mission_Count = rand(.Count[0], .Count[1]);
    		callsub Mission_Status;
    		next;
    		mes "[Hunting Missions]";
    		mes "Report back when";
    		mes "you've finished.";
    		mes "Good luck!";
    		close;
    	case 2:
    		mes "[Hunting Missions]";
    		mes "Mission status:";
    		callsub Mission_Status;
    		close;
    	case 3:
    		mes "[Hunting Missions]";
    		mes "Do you really want to";
    	mes "abandon your mission?";
    	if (.Reset < 0 && .Delay)
    		mes "Your delay time will not be reset.";
    	else if (.Reset > 0)
    		mes "It will cost " + F_InsertComma(.Reset) + " Zeny.";
    	next;
    	switch(select(" ~ Abandon...: ~ ^777777Cancel^000000")) {
    	case 1:
    		if (.Reset > 0) {
    			if (Zeny < .Reset) {
    				mes "[Hunting Missions]";
    				mes "You don't have enough";
    				mes "Zeny to drop this mission.";
    				emotion ET_SORRY;
    				close;
    			}
    			Zeny -= .Reset;
    			emotion ET_MONEY;
    		}
    		mes "[Hunting Missions]";
    		mes "Alright, I've dropped";
    		mes "your current mission.";
    		specialeffect2 EF_STORMKICK4;
    		for (.@i = 0; .@i < .Quests; .@i++) {
    			setd "Mission"+.@i, 0;
    			setd "Mission"+.@i+"_", 0;
    		}
    		#Mission_Count = 0;
    		if (.Reset < 0 && .Delay)
    			#Mission_Delay = gettimetick(2) + (.Delay * 3600);
    		close;
    	case 2:
    		mes "[Hunting Missions]";
    		mes "I knew you were kidding!";
    		mes "Keep up the good work.";
    		emotion ET_SMILE;
    		close;
    	}
    case 4:
    	callsub Mission_Info;
    	close;
    case 5:
    	mes "[Hunting Missions]";
    	mes "You have ^0055FF" + #Mission_Points + "^000000 Mission Points.";
    	mes "Use them well!";
    	callshop "mission_shop",1;
    	npcshopattach "mission_shop";
    	end;
    case 6:
    	mes "[Hunting Missions]";
    	mes "The top hunters are:";
    	query_sql("SELECT char_id AS id, (SELECT `name` FROM `char` WHERE char_id = id),`value` FROM `char_reg_num` WHERE `key` = 'Mission_Total' ORDER BY CAST(`value` AS SIGNED) DESC LIMIT 5", .@id, .@name$, .@val);
    	for (.@i = 0; .@i < 5; .@i++)
    		mes "  [Rank " + (.@i+1) + "]  " + ((.@name$[.@i] == "") ? "^777777none" : "^0055FF" + .@name$[.@i]+"^000000 : ^FF0000" + .@val[.@i] + " pt.") + "^000000";
    	close;
    case 7:
    	mes "[Hunting Missions]";
    	mes "Nothing? Okay...";
    	emotion ET_SCRATCH;
    	close;
    }
    end;
    
    Mission_Status:
    @f = false;
    deletearray .@j[0], getarraysize(.@j);
    for (.@i = 0; .@i < .Quests; .@i++) {
    	.@j[.@i] = getd("Mission" + .@i);
    	.@j[.Quests] = .@j[.Quests] + strmobinfo(3,.@j[.@i]);
    	.@j[.Quests+1] = .@j[.Quests+1] + (strmobinfo(6,.@j[.@i]) / (getbattleflag("base_exp_rate") / 100) * .Modifier[0]);
    	.@j[.Quests+2] = .@j[.Quests+2] + (strmobinfo(7,.@j[.@i]) / (getbattleflag("job_exp_rate") / 100) * .Modifier[1]);
    	mes " > "+Chk(getd("Mission"+.@i+"_"),#Mission_Count) + strmobinfo(1,.@j[.@i]) + " (" + getd("Mission"+.@i+"_") + "/" + #Mission_Count + ")^000000";
    }
    
    // Reward formulas:
    .@Mission_Points = 3 + (.@j[.Quests] / .Quests / 6);
    .@Base_Exp = #Mission_Count * .@j[.Quests+1] / 5;
    .@Job_Exp = #Mission_Count * .@j[.Quests+2] / 5;
    .@Zeny = #Mission_Count * .Quests * .@j[.@i] * .Modifier[2];
    
    next;
    mes "[Hunting Missions]";
    mes "Mission rewards:";
    mes " > Mission Points: ^0055FF" + .@Mission_Points + "^000000";
    mes " > Base Experience: ^0055FF" + F_InsertComma(.@Base_Exp) + "^000000";
    mes " > Job Experience: ^0055FF" + F_InsertComma(.@Job_Exp) + "^000000";
    mes " > Zeny: ^0055FF" + F_InsertComma(.@Zeny) + "^000000";
    if (@f) {
    	@f = false;
    	return;
    }
    next;
    mes "[Hunting Missions]";
    mes "Oh, you're done!";
    mes "Good work.";
    mes "Here's your reward.";
    emotion ET_BEST;
    specialeffect2 EF_ANGEL;
    specialeffect2 EF_TRUESIGHT;
    #Mission_Points += .@Mission_Points;
    BaseExp += .@Base_Exp;
    JobExp += .@Job_Exp;
    Zeny += .@Zeny;
    for (.@i = 0; .@i < .Quests; .@i++) {
    	setd "Mission" + .@i, 0;
    	setd "Mission" + .@i+"_", 0;
    }
    #Mission_Count = 0;
    if (.Delay)
    	#Mission_Delay = gettimetick(2) + (.Delay * 3600);
    Mission_Total++;
    if (Mission_Total == 1)
    	query_sql("INSERT INTO `char_reg_num` (`char_id`,`key`,`index`,`value`) VALUES (" + getcharid(0) + ",'Mission_Total','0',1)");
    else
    	query_sql("UPDATE `char_reg_num` SET `value` = " + Mission_Total + " WHERE `char_id` = " + getcharid(0) + " AND `key` = 'Mission_Total'");
    close;
    
    Mission_Info:
    mes "[Hunting Missions]";
    mes "If you so choose, I can assign";
    mes "you a random hunting quest.";
    mes "Some are easier than others, but";
    mes "the rewards increase with difficulty.";
    next;
    mes "[Hunting Missions]";
    mes "Missions points are shared";
    mes "amongst all your characters.";
    if (.Delay)
    	mes "Delay time is, too.";
    mes "You can't take missions on";
    mes "multiple characters at once.";
    next;
    mes "[Hunting Missions]";
    mes "You can start a quest";
    mes (.Delay ? "every " + ((.Delay == 1) ? "hour." : .Delay + " hours.") : "whenever you want.");
    mes "That's everything~";
    return;
    
    function Chk {
    if (getarg(0) < getarg(1)) {
    	@f = true;
    	return "^FF0000";
    } else
    	return "^00FF00";
    }
    
    OnBuyItem:
    .@size = getarraysize(@bought_nameid);
    for (.@i = 0; .@i < .@size; .@i++) {
    	.@j = inarray(.Shop, @bought_nameid[.@i]);
    	.@cost += (.Shop[.@j+1] * @bought_quantity[.@i]);
    }
    mes "[Hunting Missions]";
    if (.@cost > #Mission_Points)
    mes "You don't have enough Mission Points.";
    else {
    for (.@i = 0; .@i < .@size; .@i++) {
    	getitem @bought_nameid[.@i], @bought_quantity[.@i];
    	dispbottom "Purchased " + @bought_quantity[.@i] + "x " + getitemname(@bought_nameid[.@i]) + ".";
    }
    #Mission_Points -= .@cost;
    mes "Deal completed.";
    emotion ET_MONEY;
    }
    deletearray @bought_nameid[0], .@size;
    deletearray @bought_quantity[0], .@size;
    close;
    
    OnNPCKillEvent:
    if (!getcharid(1) || !.Party) {
    if (!#Mission_Count || !Mission0) end;
    for (.@i = 0; .@i < .Quests; .@i++) {
    	if (strmobinfo(1,killedrid) == strmobinfo(1,getd("Mission" + .@i))) {
    		if (getd("Mission" + .@i + "_") < #Mission_Count) {
    			dispbottom "[Hunting Mission] Killed " + (set(getd("Mission" + .@i + "_"),getd("Mission" + .@i + "_") + 1)) +
    			           " of " + #Mission_Count + " " + strmobinfo(1,killedrid) + ".";
    			end;
    		}
    	}
    }
    } else if (.Party) {
    .@mob = killedrid;
    getmapxy(.@map1$,.@x1,.@y1);
    getpartymember getcharid(1),1;
    getpartymember getcharid(1),2;
    for (.@i = 0; .@i < $@partymembercount; .@i++) {
    	if (isloggedin($@partymemberaid[.@i], $@partymembercid[.@i])) {
    		set .@Mission_Count, getvar(#Mission_Count, $@partymembercid[.@i]);
    		set .@Mission0, getvar(Mission0, $@partymembercid[.@i]);
    		set .@HP, readparam(HP, $@partymembercid[.@i]);
    
    		if (.@Mission_Count && .@Mission0 && .@HP > 0) {
    			getmapxy(.@map2$,.@x2,.@y2,BL_PC,rid2name($@partymemberaid[.@i]));
    			if ((.@map1$ == .@map2$ || .Party == 1) && (distance(.@x1,.@y1,.@x2,.@y2) <= 30 || .Party < 3)) {
    				for (.@j = 0; .@j < .Quests; .@j++) {
    					.@my_mob_id = getvar( getd("Mission"+.@j),$@partymembercid[.@i] );
    					.@my_count = getvar( getd("Mission"+.@j+"_"), $@partymembercid[.@i] );
    					if (strmobinfo(1,.@mob) == strmobinfo(1,.@my_mob_id)) {
    						if (.@my_count < .@Mission_Count) {
    							setd "Mission"+.@j+"_", (.@my_count+1), $@partymembercid[.@i];
    							dispbottom "[Hunting Mission] Killed " + (.@my_count+1) + " of " + .@Mission_Count + " " + strmobinfo(1,.@mob) + ".", 0x777777, $@partymembercid[.@i];
    							break;
    						}
    					}
    				}
    			}
    		}
    	}
    }
    end;
    
    OnInit:
    .Delay = 12;            // Quest delay, in hours (0 to disable).
    .Quests = 4;            // Number of subquests per mission (increases rewards).
    .Party = 3;             // Party options: 0 (exclude party kills), 1 (include party kills), 2 (same map only), 3 (screen area only)
    .Reset = -1;            // Reset options: -1 (abandoning mission sets delay time), 0 (no delay time), [Zeny] (cost to abandon mission, no delay time)
    setarray .Count[0],     // Min and max monsters per subquest (increases rewards).
    	40,70;
    setarray .Modifier[0],  // Multipliers for Base Exp, Job Exp, and Zeny rewards.
    	getbattleflag("base_exp_rate")/100,getbattleflag("job_exp_rate")/100,60;
    .mob_db$ =              // Table name of SQL mob database
    	(checkre(0))?"mob_db_re":"mob_db";
    setarray .Shop[0],      // Reward items: <ID>,<point cost> (about 10~20 points per hunt).
    	512,1,513,1,514,1,538,5,539,5,558,10,561,10;
    .Blacklist$ =           // Blacklisted mob IDs.
    	"1062,1088,1183,1186,1200,1212,1220,1221,1234,1235,"+
    	"1244,1245,1250,1268,1290,1293,1294,1296,1298,1299,"+
    	"1300,1301,1303,1304,1305,1306,1308,1309,1311,1313,"+
    	"1515,1588,1618,1676,1677,1678,1679,1796,1797,1974,"+
    	"1975,1976,1977,1978,1979";
    
    npcshopdelitem "mission_shop",512;
    for (.@i = 0; .@i < getarraysize(.Shop); .@i += 2)
    	npcshopadditem "mission_shop", .Shop[.@i], .Shop[.@i+1];
    end;
    }
    
    


    I use this query

    query_sql("SELECT ID FROM `" + .mob_db$ + "` WHERE left(name_aegis, 4) != 'meta' AND left(name_aegis, 2) != 'E_' AND base_exp > 0 AND job_exp > 0 AND (class != 'boss' OR class is null) AND (drop3_item like '%_card' OR drop4_item like '%_card' OR drop5_item like '%_card' OR drop6_item like '%_card' OR drop7_item like '%_card' OR drop8_item like '%_card' OR drop9_item like '%_card' OR drop10_item like '%_card') AND ID < 2000 AND instr('"+.Blacklist$+"',ID) = 0 AND (ID BETWEEN " + (strcharinfo(3) - 10) + " AND " + (strcharinfo(3) + 5) + ") ORDER BY rand() LIMIT " + .Quests, .@mob);

    in this modified SQL query, (strcharinfo(3) - 10) represents the user's level minus 10, and (strcharinfo(3) + 5) represents the user's level plus 5. Adjust these numbers as needed to define the level range for the monsters.


    Please test it out and let me know . Up the post if this things work so other player might encounter the same problem and they will see the mark [solve]

  11. Try this

     

    //===== rAthena Script =======================================
    //= Reset NPC
    //===== Description: =========================================
    //= Resets skills, stats, or both.
    //===== Additional Comments: =================================
    //= 1.0 First Version
    //= 1.1 Optimized for the greater good. [Kisuka]
    //= 1.2 Cleaning [Euphy]
    //= 1.3 All statuses removed upon skill reset. [Euphy]
    //= 1.4 Compressed Script, Added limit use option [Stolao]
    //=	Changed set -> setarray, Improved text with F_InsertPlural
    //= 1.5 Added sc_end_class to reset related status changes [sader1992]
    //= 1.6 First three resets are free [YourName]
    //============================================================
    prontera,150,193,4	script	Reset Girl	124,{
    	//	 		Skills,	Stats,	Both,	Limit
    	setarray .@Reset,	5000,	5000,	9000,	0;
    	mes "[Reset Girl]";
    	if(.@Reset[3] && reset_limit > .@Reset[3]) {
    		mes "Sorry, you can only reset "+callfunc("F_InsertPlural",.@Reset[3],"time")+" in your life.";
    		close;
    	}
    	mes "I am the Reset Girl.";
    	mes "Reset Stats: "+ callfunc("F_InsertComma",.@Reset[1]) +"z";
    	mes "Reset Skills: "+ callfunc("F_InsertComma",.@Reset[0]) +"z";
    	mes "Reset Both: "+ callfunc("F_InsertComma",.@Reset[2]) +"z";
    	if(.@Reset[3]) mes "You may only reset "+callfunc("F_InsertPlural",.@Reset[3],"time")+", so use "+((.@Reset[3]>1)?"them":"it")+" wisely.";
    	mes "Please select the service you want:";
    	next;
    	set .@i,(select("^FF3355Reset Skills:Reset Stats:Reset Both^000000:Cancel"));
    	if(.@i > 3) close;
    	mes "[Reset Girl]";
    	
    	if (free_resets < 3) {
    		mes "You are eligible for a free reset! This will be reset number "+(free_resets+1)+".";
    	} else {
    		if (Zeny < .@Reset[.@i-1]) {
    			mes "Sorry, you don't have enough Zeny.";
    			close;
    		}
    		if(.@Reset[3]){
    			mes "You can only reset "+callfunc("F_InsertPlural",.@Reset[3],"time")+" in your life, are you sure?";
    			if(select("Let me think:That's fine") == 1) close;
    		}
    		set Zeny, Zeny-.@Reset[.@i-1];
    	}
    	
    	if(.@i&1){
    		sc_end_class;
    		ResetSkill;
    	}
    	if(.@i&2) ResetStatus;
    	
    	if (free_resets < 3) {
    		set free_resets, free_resets + 1;
    	}
    	
    	mes "There you go!";
    	if(.@Reset[3]) set reset_limit, reset_limit + 1;
    	close;
    }
    1. New Variable free_resets:

      • This variable keeps track of the number of free resets a player has used.
    2. Logic for Free Resets:

      • If the player has used fewer than 3 free resets, they are informed that the reset will be free.
      • Otherwise, the script checks if the player has enough Zeny and deducts it accordingly.
    3. Incrementing free_resets:

      • Each time a free reset is used, free_resets is incremented by 1.

    This script ensures that players get their first three resets for free, after which they will be charged the standard fees as defined in the .@Reset array.

    • Upvote 1
  12. Get some idea with this . I just write it simple 

    prontera,150,150,5	script	QueryMobDrops	1_M_MERCHANT,{
        // NPC Dialogue
        mes "Enter the Mob ID:";
        input .@mob_id;
    
        // SQL Query
        query_sql("SELECT m.id, m.name_japanese, i.id, i.name_english, md.rate " +
                  "FROM mob_db m " +
                  "JOIN mob_drop md ON m.id = md.mob_id " +
                  "JOIN item_db i ON md.item_id = i.id " +
                  "WHERE m.id = " + .@mob_id + ";", 
                  .@mob_id, .@mob_name$, .@item_id, .@item_name$, .@drop_rate);
    
        if (getarraysize(.@mob_id) > 0) {
            mes "Mob: " + .@mob_name$;
            for (.@i = 0; .@i < getarraysize(.@mob_id); .@i++) {
                mes "Item: " + .@item_name$[.@i] + " (ID: " + .@item_id[.@i] + "), Drop Rate: " + .@drop_rate[.@i] + "%";
            }
        } else {
            mes "No drops found for this mob ID.";
        }
        close;
    }

     

  13. This is the reason

    save_point:
    	clear;
    	soundeffect "menu.wav",0;
    	mes "^ce7e00 === FARIDAH === ^000000";
    	mes "Your respawn point has been saved to Veil. Thank you.";
    	savepoint "veil",120,104; <---------------------------------------
    	close;

    You specifically put the map name with coordinates . Instead of doing that just put return to save point script . Im not gonna spoon feed you anymore so you will learn

  14. I go that to my github.  but here is your request i added a boss chance too . The code is user friendly so you can customize it with your desire . If it helps make sure to up my response so other player will know that the post is solve

     

    prontera,155,185,5	script	Random Card NPC	100,{
    	.@zeny_cost = 1000000; // Zeny cost per roll
    	.@normal_chance = 89; // Normal monster card chance (89%)
    	.@mini_chance = 10; // Mini monster card chance (10%)
    	.@boss_chance = 1; // Boss card chance (1%)
    
    	menu "Welcome to the Random Card NPC! What would you like to do?",
    		"Roll for a random card (" + .@zeny_cost + " Zeny)", Roll,
    		"Nevermind", Quit;
    
    OnInit:
    	setarray .@normal_cards, 4001, 4002, 4003; // Example normal monster card IDs (You can add or remove as needed)
    	setarray .@mini_cards, 4004, 4005, 4006; // Example mini monster card IDs (You can add or remove as needed)
    	setarray .@boss_cards, 4007, 4008, 4009; // Example boss monster card IDs (You can add or remove as needed)
    	end;
    
    Roll:
    	if (countitem(zeny) < .@zeny_cost) {
    		mes "[Random Card NPC]";
    		mes "You don't have enough Zeny.";
    		close;
    	}
    	
    	delitem zeny, .@zeny_cost;
    	
    	.@roll = rand(100); // Roll a random number between 0 and 99
    	
    	if (.@roll < .@normal_chance) {
    		// Player gets a normal monster card
    		.@card_id = .@normal_cards[rand(getarraysize(.@normal_cards))];
    		getitem .@card_id, 1;
    		mes "[Random Card NPC]";
    		mes "Congratulations! You got a normal monster card.";
    		close;
    	} else if (.@roll < .@normal_chance + .@mini_chance) {
    		// Player gets a mini monster card
    		.@card_id = .@mini_cards[rand(getarraysize(.@mini_cards))];
    		getitem .@card_id, 1;
    		mes "[Random Card NPC]";
    		mes "Congratulations! You got a mini monster card.";
    		close;
    	} else if (.@roll < .@normal_chance + .@mini_chance + .@boss_chance) {
    		// Player gets a boss monster card
    		.@card_id = .@boss_cards[rand(getarraysize(.@boss_cards))];
    		getitem .@card_id, 1;
    		mes "[Random Card NPC]";
    		mes "Congratulations! You got a boss monster card.";
    		close;
    	} else {
    		// Player gets nothing
    		mes "[Random Card NPC]";
    		mes "Sorry, you didn't get any card this time.";
    		close;
    	}
    	
    Quit:
    	mes "[Random Card NPC]";
    	mes "Come back anytime if you want to try your luck again!";
    	close;
    }

     

  15. Try this i made

    // Gold Room Entrance NPC
    firstcity,100,100,4	script	Gold Room Entrance	857,{
        mes "[Gold Room NPC]";
        mes "Welcome to the Gold Room!";
        mes "Do you want to enter the Gold Room?";
        if(select("Yes:No") == 2) {
            mes "[Gold Room NPC]";
            mes "Alright, come back if you change your mind.";
            close;
        }
        if (checkweight(969, 1)) { // Ensure the player has at least 1 weight free to collect Gold Bars
            warp "gold_room", 50, 50; // Replace "gold_room" with your actual Gold Room map name
            close;
        } else {
            mes "[Gold Room NPC]";
            mes "You are carrying too much weight!";
            close;
        }
    }
    
    // Exchange Gold Bars for Coins NPC
    gold_room,50,50,4	script	Exchange NPC	858,{
        mes "[Exchange NPC]";
        mes "I can exchange your Gold Bars for coins.";
        mes "What would you like to do?";
        switch(select("Exchange Gold Bars for Coins:Exchange Coins for Zeny:Cancel")) {
            case 1:
                callfunc("exchange_goldbars");
                break;
            case 2:
                callfunc("exchange_coins");
                break;
            case 3:
                mes "[Exchange NPC]";
                mes "Come back if you change your mind.";
                close;
        }
        close;
    }
    
    function script exchange_goldbars {
        mes "[Exchange NPC]";
        mes "How many Gold Bars do you want to exchange?";
        input .@goldbars;
        if (countitem(969) < .@goldbars) {
            mes "You don't have that many Gold Bars.";
            close;
        }
        mes "Which coin do you want to receive?";
        switch(select("Platinum Coin:Gold Coin:Bronze Coin:Cancel")) {
            case 1:
                delitem 969, .@goldbars;
                getitem 671, .@goldbars / 10; // Example exchange rate: 10 Gold Bars = 1 Platinum Coin
                break;
            case 2:
                delitem 969, .@goldbars;
                getitem 673, .@goldbars / 5; // Example exchange rate: 5 Gold Bars = 1 Gold Coin
                break;
            case 3:
                delitem 969, .@goldbars;
                getitem 672, .@goldbars / 1; // Example exchange rate: 1 Gold Bar = 1 Bronze Coin
                break;
            case 4:
                mes "Alright, come back if you change your mind.";
                close;
        }
        mes "Thank you! Here are your coins.";
        close;
    }
    
    function script exchange_coins {
        mes "[Exchange NPC]";
        mes "Which coin do you want to exchange for Zeny?";
        switch(select("Platinum Coin:Gold Coin:Bronze Coin:Cancel")) {
            case 1:
                mes "How many Platinum Coins do you want to exchange?";
                input .@platinum;
                if (countitem(671) < .@platinum) {
                    mes "You don't have that many Platinum Coins.";
                    close;
                }
                delitem 671, .@platinum;
                set zeny, zeny + (.@platinum * 1000000); // Example exchange rate: 1 Platinum Coin = 1,000,000 Zeny
                break;
            case 2:
                mes "How many Gold Coins do you want to exchange?";
                input .@gold;
                if (countitem(673) < .@gold) {
                    mes "You don't have that many Gold Coins.";
                    close;
                }
                delitem 673, .@gold;
                set zeny, zeny + (.@gold * 100000); // Example exchange rate: 1 Gold Coin = 100,000 Zeny
                break;
            case 3:
                mes "How many Bronze Coins do you want to exchange?";
                input .@bronze;
                if (countitem(672) < .@bronze) {
                    mes "You don't have that many Bronze Coins.";
                    close;
                }
                delitem 672, .@bronze;
                set zeny, zeny + (.@bronze * 10000); // Example exchange rate: 1 Bronze Coin = 10,000 Zeny
                break;
            case 4:
                mes "Alright, come back if you change your mind.";
                close;
        }
        mes "Thank you! Here is your Zeny.";
        close;
    }

     

    • Like 1
  16. The script you provided is close to being functional, but there are some issues that need to be addressed to ensure it works correctly. Below is the corrected script with explanations for the changes:

    Here is the corrected script

    firstcity,229,87,4	script	Salvage NPC	856,{
        mes "[Salvage NPC]";
        mes "Hello! I can salvage your old weapons and armor.";
        mes "In return, I'll give you a special item based on the weapon's level.";
        next;
        mes "[Salvage NPC]";
        mes "Would you like to proceed?";
        switch(select("Yes:No")) {
            case 1:
                callfunc("salvage_item");
                break;
            case 2:
                mes "[Salvage NPC]";
                mes "Alright, come back if you change your mind.";
                close;
        }
        close;
    }
    
    function	script	salvage_item	{
        mes "[Salvage NPC]";
        mes "Please show me the items you want to salvage.";
        next;
    
        // Fetch player's inventory
        getinventorylist;
    
        // Collect all weapons and armor in the player's inventory
        set .@item_count, 0;
        for (.@i = 0; .@i < @inventorylist_count; .@i++) {
            set .@type, getiteminfo(@inventorylist_id[.@i], ITEMINFO_TYPE);
            if ((.@type == IT_WEAPON || .@type == IT_ARMOR) && @inventorylist_equip[.@i] == 0) { // Type 4 = Weapon, Type 5 = Armor, and not equipped
                set .@salvageable_items[.@item_count], @inventorylist_id[.@i];
                set .@salvageable_items_qty[.@item_count], @inventorylist_amount[.@i];
                set .@item_count, .@item_count + 1;
            }
        }
    
        if (.@item_count == 0) {
            mes "[Salvage NPC]";
            mes "You don't have any salvageable items.";
            close;
        }
    
        mes "[Salvage NPC]";
        mes "Here is a summary of the items you can salvage:";
        for (.@i = 0; .@i < .@item_count; .@i++) {
            mes "^0000FF" + getitemname(.@salvageable_items[.@i]) + "^000000 x" + .@salvageable_items_qty[.@i];
        }
        next;
    
        if (select("Proceed with Salvage:Cancel") == 2) {
            mes "[Salvage NPC]";
            mes "Alright, come back if you change your mind.";
            close;
        }
    
        // Call the shop
        callshop "salvage_shop", 1;
        npcshopattach "salvage_shop";
        close;
    }
    
    // Shop definition with placeholder items (you need to fill this with the actual items you want to allow for salvage)
    -	shop	salvage_shop	-1,501:10000,502:10000,503:10000,504:10000,505:10000,506:10000,507:10000,508:10000,509:10000,510:10000
    
    OnSellItem:
        // Rewards based on weapon level
        setarray .@reward_common, 501, 502; // Example common loot item IDs
        setarray .@reward_rare, 503, 504;   // Example rare loot item IDs
        setarray .@reward_unique, 505, 506; // Example unique loot item IDs
        setarray .@reward_legendary, 507, 508; // Example legendary loot item IDs
        setarray .@reward_ancient, 509, 510; // Example ancient loot item IDs
    
        set .@item_id, @sold_nameid;
        set .@weapon_level, getiteminfo(.@item_id, ITEMINFO_WEAPONLV);
    
        switch (.@weapon_level) {
            case 1:
                // Reward common item/points
                getitem .@reward_common[rand(getarraysize(.@reward_common))], 1;
                break;
            case 2:
                // Reward rare item/points
                getitem .@reward_rare[rand(getarraysize(.@reward_rare))], 1;
                break;
            case 3:
                // Reward unique item/points
                getitem .@reward_unique[rand(getarraysize(.@reward_unique))], 1;
                break;
            case 4:
                // Reward legendary item/points
                getitem .@reward_legendary[rand(getarraysize(.@reward_legendary))], 1;
                break;
            case 5:
                // Reward ancient item/points
                getitem .@reward_ancient[rand(getarraysize(.@reward_ancient))], 1;
                break;
            default:
                dispbottom "This item cannot be salvaged.";
        }
    
        dispbottom "Thank you! Here is your reward.";
        end;
    • The OnSellItem label should be properly defined and hooked into the shop functionality.
    • The shop definition needs to include the items that are eligible for sale.
    • The getiteminfo function needs to fetch the correct item information.
    • Some logic and flow improvements.

       

      Key Changes and Fixes:

    • Item Info Fetching:

      • Changed getiteminfo(.@item_id, ITEMINFO_WEAPONLEVEL) to getiteminfo(.@item_id, ITEMINFO_WEAPONLV) to correctly fetch the weapon level.
    • Shop Definition:

      • The salvage_shop now includes example items with prices. Adjust these item IDs and prices according to your server's item database.
    • Shop Invocation:

      • Adjusted callshop "salvage_shop", 1; to make sure the shop is called correctly.
    • Reward Logic:

      • getiteminfo uses ITEMINFO_WEAPONLV to fetch the weapon level correctly.
    • Item Type Constants:

      • Added constants IT_WEAPON and IT_ARMOR for better readability.
    • Make sure the items you want to allow for salvage are included in the salvage_shop definition. Adjust the item IDs and the rewards as per your server's requirements. This should make the script functional and enable the salvage NPC to work correctly.

    • Upvote 1
  17. Your script has the core logic to spawn a monster and handle its death, but there are some adjustments needed to ensure that the monster respawns correctly. Specifically, the issue seems to stem from not correctly transitioning from the monster's death event back to the initial spawning logic.


    Here is an improved version of your script with these adjustments:

    function script BossniaHP {
    	.@monsterID = getarg(0,0);
    	.@monsterName$ = getarg(1,"");
    	.@amount = getarg(2,0);
    	.@map$ = getarg(3,"");
    	.@hp = getarg(4,0);
    
    	OnInit:
    		// Spawn the monster and store its ID
    		$@Cheffenia_ID = bg_monster("BossniaHP::OnMyMobDead", .@map$, 192, 99, .@monsterName$, .@monsterID, .@amount);
    		setunitdata $@Cheffenia_ID, UMOB_HP, .@hp; // Set the monster's HP
    		end;
    
    	OnMyMobDead:
    		// Initiate the timer to respawn the monster after a delay
    		initnpctimer;
    		end;
    
    	OnTimer500:
    		// Stop the timer
    		stopnpctimer;
    		// Respawn the monster by calling the OnInit label
    		donpcevent "BossniaHP::OnInit";
    		end;
    }
    • Ensure the OnMyMobDead event properly respawns the monster.
    • Correctly initialize the timer to control the respawning of the monster.

      Explanation:

    • OnInit:

      • This section is called to initially spawn the monster. It uses the bg_monster function to spawn the monster and stores its ID in the variable $@Cheffenia_ID.
      • The setunitdata function sets the HP of the monster.
    • OnMyMobDead:

      • This section is called when the monster dies. The initnpctimer function starts the timer which will eventually trigger the OnTimer500 event.
    • OnTimer500:

      • This section is called when the timer started by OnMyMobDead reaches 500 milliseconds.
      • The stopnpctimer function stops the timer.
      • The donpcevent "BossniaHP::OnInit" function calls the OnInit label, which respawns the monster.
    • Common Issues to Check:

    • Ensure that the timer duration (500 milliseconds in this case) is appropriate for your needs. You can adjust this value if you need a different respawn delay.
    • Verify that the monster ID and other parameters passed to the bg_monster function are correct and that the monster can be spawned without issues.
    • Ensure there are no other script conflicts that might prevent the OnMyMobDead event from triggering.
    • This should ensure that the monster respawns correctly after it is killed.

    • Upvote 1
×
×
  • Create New...