Jump to content

Scanty

Members
  • Posts

    94
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by Scanty

  1. Hi, I'm working on a ranking system inspired by League of Legends, and I decided to create these files to apply it to the players

    image.png.06a1acfafeffc9bcd19efaa7484c2a6f.png

     

    I'm new to editing this kind of stuff. I wish a professional could review it and give it a proper cleanup, but anyway, it doesn't seem too bad for now.

     

    How do use it:

     

    1) Download League of Legends Rank File.

    2) Put into your GRF.

    3) Go to your hateffectinfo.lub (data/luafiles514/hateeffectinfo)

    4) Search or something Similar.

    HAT_EF_NightSkyOfRutie = 225,

    5) Put this:

    -- Ranks Lol Tag by Scanty --
    	HAT_IRON_RANK = 231,
    	HAT_BRONCE_RANK = 232,
    	HAT_PLATA_RANK = 233,
    	HAT_ORO_RANK = 234,
    	HAT_PLATINO_RANK = 235,
    	HAT_ESMERALDA_RANK = 236,
    	HAT_DIAMANTE_RANK = 237,
    	HAT_MAESTRO_RANK = 238,
    	HAT_GM_RANK = 239,
    	HAT_RETADOR_RANK = 240,

     

    6) Now, Search for

    [HatEFID.HAT_EF_NightSkyOfRutie] = {
    		resourceFileName = "efst_NightSkyOfRutie\\christmasx3.str",
    		hatEffectPos = -11,
    		hatEffectPosX = -0.3,
    		isRenderBeforeCharacter = true,
    		isAdjustPositionWhenShrinkState = true,
    		isAdjustSizeWhenShrinkState = true
    	},

     

    7)  After that

    --- Inician Rangos de Lol - By Scanty ---
    	[HatEFID.HAT_IRON_RANK] = { resourceFileName = "custom\\rangos_lol\\iron_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_BRONCE_RANK] = { resourceFileName = "custom\\rangos_lol\\bronce_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_PLATA_RANK] = { resourceFileName = "custom\\rangos_lol\\plata_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_ORO_RANK] = { resourceFileName = "custom\\rangos_lol\\oro_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_PLATINO_RANK] = { resourceFileName = "custom\\rangos_lol\\platino_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_ESMERALDA_RANK] = { resourceFileName = "custom\\rangos_lol\\esmeralda_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_DIAMANTE_RANK] = { resourceFileName = "custom\\rangos_lol\\diamante_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_MAESTRO_RANK] = { resourceFileName = "custom\\rangos_lol\\maestro_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_GM_RANK] = { resourceFileName = "custom\\rangos_lol\\GM_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true},
    	[HatEFID.HAT_RETADOR_RANK] = { resourceFileName = "custom\\rangos_lol\\Retador_RANK.str",hatEffectPos = 6, isIgnoreRiding = false, isRenderBeforeCharacter = false, isAttachedHead = true, isAdjustPositionWhenShrinkState = true, isAdjustSizeWhenShrinkState = true}

     

    8 ) Create a script to test.

    you need to use this:

    hateffect 240, true;

     

    *hateffect(<Hat Effect ID>,<State>);
    
    This will set a Hat Effect onto the player. The state field allows you to
    enable (true) or disable (false) the effect on the player.
    The Hat Effect constants can be found in 'src/map/script_constants.hpp' starting
    with HAT_EF_*.
    
    Requires client 2015-05-13aRagEXE or newer.

     

    League of Legends Rank.rar

    • Upvote 7
    • Love 1
  2. For me, works like you have, but maybe your SQL have something.

     

    Try this.

    .@query$ = "SELECT `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, "
             + "`char`.`sex`, `char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, "
             + "`char`.`body`, `char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe`, "
             + "SUM(`mvpladder`.`kills`) AS `orderKills` "
             + "FROM `char` "
             + "RIGHT JOIN `mvpladder` ON `char`.`char_id` = `mvpladder`.`char_id` "
             + "GROUP BY `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, `char`.`sex`, "
             + "`char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, `char`.`body`, "
             + "`char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe` "
             + "ORDER BY `orderKills` DESC LIMIT " + .showstatue + ";";

     

  3. Hello. I found this script:

    Herc - Event Wheel of Fortune

    So i decide to use it.

    All credits to him: Habilis.

     

    Here's my edited Script:

     

    Spoiler
    prontera,155,176,3	script	Wheel_of_Fortune#Main	2_SLOT_MACHINE,{
    
    	if (Zeny < .Zeny_Cost) {
    		mes "[^0055FF" + .EventName$ + "^000000]";
    		mes "No tienes suficiente Zeny para girar la ruleta.";
    		close;
    	}
    
    	cutin("aca_salim02", 2);
    	mes "[^0055FF" + .EventName$ + "^000000]";
    	mes "¿Quieres girar la ruleta?";
    	mes "¡Cada giro cuesta ^FF0000" + .Zeny_Cost + " Zeny^000000!";
    	next;
    
    	while (true) {
    		.@menu = select("Girar la ruleta (" + .Zeny_Cost + " Zeny)", "Salir");
    		if (.@menu == 2 || Zeny < .Zeny_Cost) break;
    
    		Zeny -= .Zeny_Cost;
    		callsub S_Spin;
    
    		// Después del giro, preguntar si desea otro
    		next;
    		mes "[^0055FF" + .EventName$ + "^000000]";
    		mes "¿Quieres girar de nuevo?";
    	}
    
    	callsub S_End;
    
    S_Spin:
    	.@sector = .prob_pool[rand(getarraysize(.prob_pool))];
    	.@speed = .Spin_Speed;
    
    	for (.@i = 0; .@i < .nbTurns; .@i++) {
    		for (.@b = .Cutin_Range[0]; .@b <= .Cutin_Range[1]; .@b++) {
    			cutin(.Cutin$ + .@b, 4);
    			sleep2 .@speed;
    			.@speed++;
    		}
    	}
    
    	for (.@b = .Cutin_Range[0]; .@b <= .@sector; .@b++) {
    		cutin(.Cutin$ + .@b, 4);
    		sleep2 .@speed;
    	}
    	cutin(.Cutin$ + .@sector, 4);
    
    	if (.Prize_ID[.@sector] == 0) {
    		soundeffect("wheel_lost.wav", 0);
    		announce .EventName$ + " : Nada esta vez...", bc_self | bc_blue;
    		dispbottom "Parece que no has tenido suerte el día de hoy.";
    	} else {
    		soundeffect("wheel_won.wav", 0);
    		getitem .Prize_ID[.@sector], .Prize_Qty[.@sector];
    		announce .EventName$ + " : ¡Has ganado " + .Prize_Qty[.@sector] + "x " + getitemname(.Prize_ID[.@sector]) + "!", bc_self | bc_blue;
    
    		switch (.Prize_Type[.@sector]) {
    			case 1: dispbottom "¡Felicidades! Has ganado una ^FF00FFGema^000000."; break;
    			case 2: dispbottom "¡Felicidades! Has ganado un ^00CCFFPremio^000000."; break;
    			case 3: dispbottom "¡Felicidades! Has ganado un ^8888FFPremio menor^000000."; break;
    			default: dispbottom "Parece que no has tenido suerte el día de hoy."; break;
    		}
    	}
    	sleep2 1000;
    	return;
    
    S_End:
    	cutin("", 255);
    	close;
    
    OnInit:
    	set .EventName$, "Wheel Of Fortune";
    	bindatcmd "wheel_of_fortune", strnpcinfo(0) + "::OnCommand", 98, 98;
    	set .Spin_Speed, 50;
    	set .nbTurns, 2;
    	set .Zeny_Cost, 10000;
    	set .Cutin$, "ruleta_suerte\\frame_";
    	setarray .Cutin_Range, 0, 9;
    
    	// Premios por sector (frame)
    	setarray .Prize_ID, 12187,0,13277,12103,13277,12187,13277,0,13277,12103;
    	setarray .Prize_Qty, 1,0,1,1,1,1,1,0,1,1;
    	setarray .Prize_Type, 2,0,3,1,3,2,3,0,3,1;
    
    	// Probabilidad real (repetidos = peso)
    	setarray .prob_pool,
    		3, 9,         // Gema (5%)
    		0, 0, 5, 5,   // Premio (20%)
    		1, 1, 7, 7,   // Nada (20%)
    		2,2,4,4,6,6,8,8,8,8; // Premio menor (55%)
    	end;
    }

     

    And this is my Frames.

    Route: data\texture\À¯ÀúÀÎÅÍÆäÀ̽º\cardbmp\ruleta_suerte

    But you can change it via script.

    OnInit:

    set .Cutin$, "ruleta_suerte\\frame_"; <-- CHANGE this

     

    "This is my own modification. You can change everything through the script, and of course… you'll need the design. But hey, you can do it yourself! I downloaded Photoshop just an hour ago and made this, lol (no editing knowledge at all)."

     

    If you’ve got your own design and want to create frames like I did, here’s what I did

    Spoiler

    1) Open the .PSD file.

    2) You will see this:
    image.thumb.png.dd1c332c3171dedcff1c12728bd3e18c.png

     

    3) Go to File (Archivo) > image.png.b0cd78737947e01440d342b6837a13a4.png

     

    4) Search for your Generate_Frame.jsx

    5) Now it told you to find a folder to save your frames.

     

    FAQ:

    I got a this error:

    image.png.25e103d0ee34fcd97fe2a4364416a5b3.png

    Select any element > Control + T

    Go to step 2.

     

    END OF THIS FAQ LOL. wow

    Please don't ask anything about design and stuff, I'm still learning.

     

    Odin Wheel:

    Spoiler

    image.thumb.png.cad2ab55be2975137c2ee148e86e1fa2.png

     

     

    Puntero3.thumb.png.3b3363601dc54e0683cb4b3be04cf449.pngPuntero2.thumb.png.ae5d831a936471c161a0a7c932e509fc.pngPuntero.thumb.png.1b2e65be7cc6cbef41c0c7a87ed771b7.png

     

    This is just an example. If you want it to be an automated event or something like that, feel free to ask!

     

     

    Video:

     

    Frames.rar Ruleta+PSD+Gen_FramE.rar

    Odin_Wheel.rar

    • Upvote 2
  4. I did this basic script, maybe it will help you.

    CREATE TABLE IF NOT EXISTS `pvp_rank` (
      `char_id` int(11) unsigned NOT NULL,
      `kills` int(11) unsigned NOT NULL DEFAULT 0,
      `deaths` int(11) unsigned NOT NULL DEFAULT 0,
      PRIMARY KEY (`char_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

     

    And here's the script.

    prontera,196,142,5	script	PVP Warper	100,{
    	mes "[ ^FF0000PVP Warper^000000 ]";
    	mes "Welcome, ^0000FF"+strcharinfo(0)+"^000000.";
    	mes "Please select a PVP room:";
    	next;
    
    	// Dynamic menu with player counts
    	.@menu$ = "";
    	for (.@i = 0; .@i < getarraysize(.pvp_map$); .@i++) {
    		.@users = getmapusers(.pvp_map$[.@i]);
    		.@menu$ += .pvp_name$[.@i]+" ["+.@users+"/"+.pvp_max[.@i]+"]:";
    	}
    
    	.@sel = select(.@menu$) - 1;
    
    	if (BaseLevel < .pvp_level[.@sel]) {
    		mes "[ ^FF0000PVP Warper^000000 ]";
    		mes "You must be at least level "+.pvp_level[.@sel]+" to enter this room.";
    		close;
    	}
    
    	if (getmapusers(.pvp_map$[.@sel]) >= .pvp_max[.@sel]) {
    		mes "[ ^FF0000PVP Warper^000000 ]";
    		mes "This room has reached its player limit ("+.pvp_max[.@sel]+").";
    		close;
    	}
    
    	warp .pvp_map$[.@sel],0,0;
    	end;
    
    
    OnPCKillEvent:
    	// Validate if map is a valid PVP room
    	.@valid = 0;
    	for (.@i = 0; .@i < getarraysize(.pvp_map$); .@i++) {
    		if (strcharinfo(3) == .pvp_map$[.@i]) {
    			.@valid = 1;
    			break;
    		}
    	}
    	if (!.@valid) end;
    
    	// Get Killer and Victim Char IDs safely
    	.@killer_cid = getcharid(0);
    	.@victim_cid = getcharid(0, rid2name(killedrid));
    
    	if (!.@killer_cid || !.@victim_cid || .@killer_cid == .@victim_cid) end;
    
    	// Always register kills and deaths for all maps
    	query_sql("INSERT INTO pvp_rank (`char_id`, `kills`, `deaths`) VALUES ("+.@killer_cid+",1,0),("+.@victim_cid+",0,1) ON DUPLICATE KEY UPDATE `kills`=`kills`+VALUES(`kills`), `deaths`=`deaths`+VALUES(`deaths`)");
    
    	// Only grant special points in the GM-selected map
    	if (strcharinfo(3) != .points_map$) end;
    
    	// IP check validation (enabled or disabled by admin)
    	if (.ip_check_enabled) {
    		query_sql("SELECT last_ip FROM login WHERE account_id="+getcharid(3), .@killer_ip$);
    		query_sql("SELECT last_ip FROM login WHERE account_id="+killedrid, .@victim_ip$);
    		if (.@killer_ip$ == .@victim_ip$) {
    			dispbottom "[PVP Warper]: No points granted. Same IP detected.";
    			end;
    		}
    	}
    
    	// Kill cooldown validation
    	.@current_time = gettimetick(2);
    	.@cooldown = .kill_cooldown;
    
    	.@kill_cd_var$ = "kill_cd_"+.@killer_cid+"_"+.@victim_cid;
    	if (getd(.@kill_cd_var$) + .@cooldown > .@current_time) {
    		dispbottom "[PVP Warper]: You recently killed this player. Wait before earning more points.";
    		end;
    	}
    	setd .@kill_cd_var$, .@current_time;
    
    	// Add your special points reward code here.
    	// Example: set pvp_points, pvp_points + 1;
    
    	dispbottom "[PVP Warper]: You've earned special points for defeating a player.";
    	end;
    
    OnCheckRank:
    	mes "[ ^FF0000PVP Warper^000000 ]";
    	query_sql("SELECT kills, deaths FROM pvp_rank WHERE char_id="+ getcharid(0), .@kills, .@deaths);
    	mes "Tus estadísticas actuales:";
    	mes "^0000FFKills:^000000 "+ (.@kills ? .@kills : 0);
    	mes "^FF0000Muertes:^000000 "+ (.@deaths ? .@deaths : 0);
    	close;
    
    OnGMResetRank:
    	if (getgmlevel() < 60) {
    		dispbottom "No tienes permisos para usar este comando.";
    		end;
    	}
    	query_sql("TRUNCATE TABLE pvp_rank");
    	dispbottom "Ranking PVP reiniciado correctamente.";
    	end;
    
    OnInit:
    	// General Configuration
    	setarray .pvp_map$[0], "guild_vs1", "guild_vs2", "pvp_y_1-2";
    	setarray .pvp_name$[0], "PVP Room 1", "PVP Room 2", "PVP Prontera";
    	setarray .pvp_level[0], 1, 50, 99;
    	setarray .pvp_max[0], 10, 15, 20;
    
    	// Enable or disable IP check (1 = ON, 0 = OFF)
    	.ip_check_enabled = 0;
    
    	// Kill cooldown in seconds (recommended: 60-120 sec)
    	.kill_cooldown = 60;
    	
    	// GM configuration: Set the map that gives special points here (default is room 1)
    	.points_map$ = .pvp_map$[0]; // Change [0] to [1] or [2] to switch rooms
    
    	// Commands for player and GM
    	bindatcmd "pvprank",strnpcinfo(3)+"::OnCheckRank";
    	bindatcmd "resetpvprank",strnpcinfo(3)+"::OnGMResetRank",60,60;
    	end;
    }

     

    Feel free to ask for a change.

     

    • Love 1
  5. I try and it works.

    prontera	mapflag	norodex

     

     

    script_constants.hpp

    export_constant(MF_NOCASHSHOP);
    +export_constant(MF_NORODEX);

     

    atcommand.cpp:

    if (map_getmapflag(m_id, MF_NOCASHSHOP))
    		strcat(atcmd_output, " NoCashShop |");
    +if (map_getmapflag(m_id, MF_NORODEX))
    +		strcat(atcmd_output, " NoRODex |");

     

    mail.cpp

    if( !map_getmapflag(sd->bl.m, MF_TOWN) && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND) )
    	{
    		ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name);
    		return true;
    	}
    #else
    	+if( map_getmapflag( sd->bl.m, MF_NORODEX ) ){
    	+	clif_displaymessage( sd->fd, msg_txt( sd, 796 ) ); // You cannot use RODEX on this map.
    	+	return true;
    	+}

     

    map.hpp:

    MF_NOCASHSHOP, // 70
    +MF_NORODEX,

     

  6. pc.hpp:

    case SP_NO_GEMSTONE:
    			if(sd->state.lr_flag != 2 && sd->special_state.no_gemstone != 2)
    				sd->special_state.no_gemstone = 1;

     

    skill.cpp

    // Check requirement for gemstone.
    				if (itemdb_group.item_exists(IG_GEMSTONE, req.itemid[i])) {
    					if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
    						req.itemid[i] = req.amount[i] = 0;
    					else {
    						if( sd->special_state.no_gemstone || (sc && sc->getSCE(SC_INTOABYSS)) )
    						{	// All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
    							if (skill_id != SA_ABRACADABRA && skill_id != HW_GANBANTEIN)
    		 						req.itemid[i] = req.amount[i] = 0;
    							else if( --req.amount[i] < 1 )
    								req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
    						}
    					}
    				}

    There are a lot of checks, just search no_gemstone

     

    • Love 1
  7. I have an idea.

    - Id: 607
        AegisName: Yggdrasilberry
        Name: Yggdrasil Berry
        Type: Healing
        Buy: 5000
        Weight: 300
        Flags:
          BuyingStore: true
          NoConsume: true
        Delay:
          Duration: 5000
          Status: Reuse_Limit_F
        Script: |
          percentheal 100,100;

     

    Flags: Noconsume: true

     

    Now in script, put 

    if(vip_status(VIP_STATUS_ACTIVE)) { percentheal 100,100; }


    This item only gonna work if you're vip. in other case, i don't know how to do it. GL

  8. 6 hours ago, Sallycantdance said:

    savage thank you so much sir! how about if i want a multiple item in announce example

            if (.@itemID == "61966,502") {

     

    // Rolling Multiple Times
    	set .@GrandPrizes, 0;
    	set .@AnnouncePercent, 1; // = 1, 50 = 50%

     

    // Announce ONLY if the player gets the grand prize
    		if (.@itemID == 61966) {
    			announce "Congratulations! " + strcharinfo(0) + " just received " + getitemname(.@itemID) + " x " + .@itemAmount + " from PVP Gacha NPC!", 0;
    			specialeffect2 248;
    			set .@GrandPrizes, .@GrandPrizes + 1;
    		}

     

    Change to:

     

    // Automatically announce if the item has a probability less than or equal to the configuration
    		if (getd(".@P"+.@i+"[0]") <= .@AnnouncePercent) {
    			announce "Congratulations! " + strcharinfo(0) + " just received " + getitemname(.@itemID) + " x " + .@itemAmount + " from PVP Gacha NPC!", 0;
    			specialeffect2 248;
    			set .@GrandPrizes, .@GrandPrizes + 1;
    		}

     

    If you have any request, let me know.

    • Upvote 1
  9. Checkweight

     

    // PVP Gacha NPC with Multi-Roll Options and Custom Notifications
    prontera,194,140,4    script    PVP Gacha    100,{
    
        
        .@weight = 100 * Weight / MaxWeight;
        if (70 <= .@weight) {
            mes "[ ^FF7700PVP Girl^000000 ]";
            mes "You are currently at " + .@weight + " percent of your maximum weight.";
            mes "Please lighten your load before rolling!";
            close;
        }
    
    ...


     

  10. Try this.

     

    // PVP Gacha NPC with Multi-Roll Options and Custom Notifications
    prontera,194,140,4	script	PVP Gacha	100,{
    	// NPC Introduction
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "Hello Adventurer! Want to try your luck?";
    	next;
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "Exchange ^ff00005 PVP Tickets^000000 to roll for prizes!";
    	mes "You can get ^26A7DFPVP Tickets^000000 in our Grand Arena!";
    	next;
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "Consumables:";
    	mes "<ITEM>^0000ff2x Light White Potion ^000000<INFO>11501</INFO></ITEM>";    
    	mes "<ITEM>^0000ff2x Light Blue Potion ^000000<INFO>11502</INFO></ITEM>";
    	mes "<ITEM>^0000ff1x Ticket for Kafra Storage ^000000<INFO>7059</INFO></ITEM>";
    	mes "<ITEM>^0000ff1x Agility Scroll ^000000<INFO>12216</INFO></ITEM>";    
    	mes "<ITEM>^0000ff1x Blessing Scroll ^000000<INFO>12215</INFO></ITEM>";        
    	next;
    	mes "Grand Prize:[1%]";
    	mes "<ITEM>^00bfffC. PVP Ticket ^000000<INFO>61966</INFO></ITEM>";
    	next;
    
    	// Check if player has at least 5 PVP Tickets
    	if (countitem(7960) < 5) goto L_Sorry;
    
    	// Roll Options
    	switch (select("1 Roll (5 PVP Tickets):10 Rolls (50 PVP Tickets):20 Rolls (100 PVP Tickets):50 Rolls (250 PVP Tickets):No way...")) {
    		case 1: set .Rolls, 1; set .Cost, 5; break;
    		case 2: set .Rolls, 10; set .Cost, 50; break;
    		case 3: set .Rolls, 20; set .Cost, 100; break;
    		case 4: set .Rolls, 50; set .Cost, 250; break;
    		case 5: close;
    	}
    
    	// Check if player has enough tickets
    	if (countitem(7960) < .Cost) {
    		mes "[ ^FF7700PVP Girl^000000 ]";
    		mes "You don't have enough PVP Gacha Tickets!";
    		close;
    	}
    
    	// Ask player how they want their rewards displayed
    	switch(select("Show Every Roll:Just give me my rewards.")) {
    		case 1: set .ShowEachRoll, 1; break;
    		case 2: set .ShowEachRoll, 0; break;
    	}
    
    	// Remove PVP Tickets
    	delitem 7960, .Cost;
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "Here we go... Rolling " + .Rolls + " times!";
    	next;
    
    	// Prize Arrays
    	set .@Total,9;
    	setarray .@P1[0],1,61966,1;  // PVP Ticket (Grand Prize - 1%)
    	setarray .@P2[0],50,11501,5; // Light Whites
    	setarray .@P3[0],50,11502,5; // Light Blues        
    	setarray .@P4[0],40,12216,5; // Agi scroll 5x
    	setarray .@P5[0],40,12215,5; // Blessing Scroll 5x        
    	setarray .@P6[0],30,7059,1;  // Kafra Storage            
    	setarray .@P7[0],80,909,1;   // Royal Jelly
    	setarray .@P8[0],100,909,1;  // Royal Jelly
    	setarray .@P9[0],100,909,1;  // Royal Jelly    
    
    	// Rolling Multiple Times
    	set .@GrandPrizes, 0;
    	for (set .@count, 0; .@count < .Rolls; set .@count, .@count + 1) {
    		do {
    			set .@i, rand(1, .@Total);
    		} while (rand(1,100) > getd(".@P"+.@i+"[0]"));
    
    		// Get the prize item
    		set .@itemID, getd(".@P"+.@i+"[1]");
    		set .@itemAmount, getd(".@P"+.@i+"[2]");
    
    		// Give the item
    		getitem .@itemID, .@itemAmount;
    
    		// Show individual message per roll (if chosen)
    		if (.ShowEachRoll) {
    			mes "[ ^FF7700PVP Girl^000000 ]";
    			mes "You won " + .@itemAmount + "x " + getitemname(.@itemID) + "!";
    			next;
    		} else {
    			// Save rewards for summary later
    			setarray .@SummaryID[getarraysize(.@SummaryID)], .@itemID;
    			setarray .@SummaryAmount[getarraysize(.@SummaryAmount)], .@itemAmount;
    		}
    
    		// Announce ONLY if the player gets the grand prize
    		if (.@itemID == 61966) {
    			announce "Congratulations! " + strcharinfo(0) + " just received " + getitemname(.@itemID) + " x " + .@itemAmount + " from PVP Gacha NPC!", 0;
    			specialeffect2 248;
    			set .@GrandPrizes, .@GrandPrizes + 1;
    		}
    	}
    
    	// If the player chose to receive everything at once, show a summary
    	if (!.ShowEachRoll) {
    		mes "[ ^FF7700PVP Girl^000000 ]";
    		mes "Here are all your rewards:";
    		for (set .@index, 0; .@index < getarraysize(.@SummaryID); set .@index, .@index + 1) {
    			mes "- " + .@SummaryAmount[.@index] + "x " + getitemname(.@SummaryID[.@index]);
    		}
    		next;
    	}
    
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "Thanks for playing! Come back again.";
    	close;
    
    L_Sorry:
    	mes "[ ^FF7700PVP Girl^000000 ]";
    	mes "You don't have enough PVP Gacha Tickets, please get some!";
    	close;
    
    OnTimer0050:
    	showscript "PVP Gacha", getnpcid(0);
    	initnpctimer;
    	end;
    
    OnInit:
    	initnpctimer;
    	end;
    }

     

    • Upvote 1
  11. Try this.

     

    // Script de Máquina de Roll
    prontera,193,140,4	script	Máquina de Roll	100,{
    	// Configuración de costos y requisitos
    	set .Cost, 50000; // Costo en Zeny (ajustable)
    	set .ReqItemID, 969; // ID del ítem requerido (ajustable)
    	set .ReqItemAmount, 1; // Cantidad del ítem requerido (ajustable)
    
    	// Lista de premios con probabilidades (1-10000)
    	setarray .Prizes[0], 
    		12246,1,100, 9932,1,300, 616,1,1000, 11623,5,1000,
    		12100,50,1000, 12090,50,1000, 12095,50,1000, 12080,50,1000,
    		12085,50,1000, 12075,50,1000, 12263,5,1000, 12264,10,1000,
    		12265,5,1000, 607,50,1000, 608,50,1000, 25791,1,500,
    		27330,1,1, 27332,1,1, 27200,1,1, 27201,1,1,
    		27202,1,1, 27203,1,1, 300127,1,1, 300129,1,1,
    		27393,1,1, 27395,1,1, 300307,1,1, 300309,1,1,
    		300421,1,1, 300423,1,1, 300425,1,1, 27196,1,1,
    		27197,1,1, 27198,1,1, 27199,1,1, 300426,1,1,
    		300424,1,1, 300422,1,1, 300308,1,1, 300130,1,1,
    		300128,1,1, 27396,1,1, 27331,1,1, 27333,1,1;
    
    	// Menú principal
    	mes "[Máquina de Roll]";
    	mes "¡Bienvenido! ¿Quieres probar suerte?";
    	next;
    	switch(select("Jugar:Ver costo y requisitos:Salir")) {
    		case 1:
    			// Verificar si el jugador tiene suficientes Zeny e ítems
    			if (Zeny < .Cost) {
    				mes "[Máquina de Roll]";
    				mes "No tienes suficiente Zeny.";
    				close;
    			}
    			if (.ReqItemID && countitem(.ReqItemID) < .ReqItemAmount) {
    				mes "[Máquina de Roll]";
    				mes "No tienes suficiente " + getitemname(.ReqItemID) + ". Necesitas " + .ReqItemAmount + ".";
    				close;
    			}
    
    			// Restar Zeny e ítems requeridos
    			set Zeny, Zeny - .Cost;
    			if (.ReqItemID) {
    				delitem .ReqItemID, .ReqItemAmount;
    			}
    
    			// Generar número aleatorio
    			set .roll, rand(1, 10000);
    			set .accum, 0;
    			for (set .i, 0; .i < getarraysize(.Prizes); set .i, .i + 3) {
    				set .accum, .accum + .Prizes[.i + 2];
    				if (.roll <= .accum) {
    					getitem .Prizes[.i], .Prizes[.i + 1];
    					announce "[Máquina de Roll] " + strcharinfo(0) + " ha conseguido " + .Prizes[.i + 1] + "x " + getitemname(.Prizes[.i]) + "!", bc_all;
    					mes "[Máquina de Roll]";
    					mes "¡Felicidades! Has obtenido " + .Prizes[.i + 1] + "x " + getitemname(.Prizes[.i]) + ".";
    					close;
    				}
    			}
    			mes "[Máquina de Roll]";
    			mes "Lo siento, no ganaste nada esta vez.";
    			close;
    		
    		case 2:
    			mes "[Máquina de Roll]";
    			mes "Para jugar necesitas:";
    			mes "^009900-" + .Cost + " Zeny^000000.";
    			if (.ReqItemID) {
    				mes "^009900-" + .ReqItemAmount + "x " + getitemname(.ReqItemID) + "^000000.";
    			}
    			close;
    		
    		case 3:
    			mes "[Máquina de Roll]";
    			mes "¡Vuelve cuando quieras probar suerte!";
    			close;
    	}
    }

     

  12. Try this...

     

    prontera,137,156,4	script	Platinum Skill NPC	533,{
        mes "[Skill Master]";
        mes "Hello! I can teach you special skills based on your job class. Each skill costs 100,000 zeny.";
        next;
    
    
        if (Zeny < 100000) {
            mes "You need at least 100,000 zeny to learn a skill.";
            close;
        }
    
    
        deletearray .@skill_list$;
        deletearray .@desc_list$;
         // Llamar a la función para obtener habilidades disponibles
        callfunc "F_GetAvailableSkills", BaseJob, .@skill_list$, .@desc_list$;
    
        if (getarraysize(.@skill_list$) == 0) {
            mes "No skills are available for your job.";
            close;
        }
    
    
        for (.@i = 0; .@i < getarraysize(.@skill_list$); .@i++) {
            .@menu$ += (.@i > 0 ? ":" : "") + .@desc_list$[.@i];
        }
    
    
        .@choice = select(.@menu$) - 1;
        mes "You've chosen to learn " + .@desc_list$[.@choice] + ".";
        
    
        mes "It will cost you 100,000 zeny. Do you want to proceed?";
        if (select("Yes:No") == 2) {
            mes "Maybe next time!";
            close;
        }
        
        if (Zeny >= 100000) {
            Zeny -= 100000;
            skill .@skill_list$[.@choice], 1, SKILL_PERM;  // Otorgar la habilidad de forma permanente
            mes "Skill learned successfully!";
        } else {
            mes "It seems you no longer have enough zeny.";
        }
        close;
    }
    
    
    function	script	F_GetAvailableSkills	{
        .@skills$ = "";
        .@descs$ = "";
    
        switch(getarg(0)) {
        case Job_Novice:
            setarray .@skills$, "NV_FIRSTAID"; 
            setarray .@descs$, "First Aid";
            break;
        case Job_Swordman:
            setarray .@skills$, "SM_MOVINGRECOVERY", "SM_FATALBLOW", "SM_AUTOBERSERK";
            setarray .@descs$, "Moving HP Recovery", "Fatal Blow", "Auto Berserk";
            break;
        case Job_Mage:
            setarray .@skills$, "MG_ENERGYCOAT", "MG_SIGHTBLASTER";
            setarray .@descs$, "Energy Coat", "Sight Blaster";
            break;
        case Job_Archer:
            setarray .@skills$, "AC_MAKINGARROW", "AC_CHARGEARROW";
            setarray .@descs$, "Arrow Crafting", "Charge Arrow";
            break;
        case Job_Acolyte:
            setarray .@skills$, "AL_HOLYLIGHT", "PR_REDEMPTIO";
            setarray .@descs$, "Holy Light", "Redemptio";
            break;
        case Job_Merchant:
            setarray .@skills$, "MC_CARTREVOLUTION", "MC_CHANGECART", "MC_LOUD", "MC_CARTBOOST";
            setarray .@descs$, "Cart Revolution", "Change Cart", "Crazy Uproar", "Cart Boost";
            break;
        case Job_Thief:
            setarray .@skills$, "TF_SPRINKLESAND", "TF_BACKSLIDING", "TF_PICKSTONE", "TF_THROWSTONE";
            setarray .@descs$, "Sprinkle Sand", "Back Sliding", "Pick Stone", "Throw Stone";
            break;
        case Job_Knight:
            setarray .@skills$, "KN_CHARGEATK";
            setarray .@descs$, "Charge Attack";
            break;
        case Job_Priest:
            setarray .@skills$, "PR_REDEMPTIO";
            setarray .@descs$, "Redemptio";
            break;
        case Job_Wizard:
            setarray .@skills$, "WZ_SIGHTBLASTER";
            setarray .@descs$, "Sight Blaster";
            break;
        case Job_Blacksmith:
            setarray .@skills$, "BS_UNFAIRLYTRICK", "BS_GREED";
            setarray .@descs$, "Unfairly Trick", "Greed";
            break;
        case Job_Hunter:
            setarray .@skills$, "HT_PHANTASMIC";
            setarray .@descs$, "Phantasmic Arrow";
            break;
        case Job_Assassin:
            setarray .@skills$, "AS_VENOMKNIFE", "AS_SONICACCEL";
            setarray .@descs$, "Venom Knife", "Sonic Acceleration";
            break;
        case Job_Crusader:
            setarray .@skills$, "CR_SHRINK";
            setarray .@descs$, "Shrink";
            break;
        case Job_Monk:
            setarray .@skills$, "MO_KITRANSLATION", "MO_BALKYOUNG";
            setarray .@descs$, "Ki Translation", "Balkyoung";
            break;
        case Job_Sage:
            setarray .@skills$, "SA_CREATECON", "SA_ELEMENTALCHANGE";
            setarray .@descs$, "Create Elemental Converter", "Elemental Change";
            break;
        case Job_Rogue:
            setarray .@skills$, "RG_CLOSECONFINE";
            setarray .@descs$, "Close Confine";
            break;
        case Job_Alchemist:
            setarray .@skills$, "AM_BIOETHICS";
            setarray .@descs$, "Bioethics";
            break;
        case Job_Bard:
            setarray .@skills$, "BA_PANGVOICE";
            setarray .@descs$, "Pang Voice";
            break;
        case Job_Dancer:
            setarray .@skills$, "DC_WINKCHARM";
            setarray .@descs$, "Wink of Charm";
            break;
        // Agregar más clases si es necesario
        default:
            mes "No skills available for your job.";
            break;
        }
    
        
        copyarray getarg(1), .@skills$, getarraysize(.@skills$);
        copyarray getarg(2), .@descs$, getarraysize(.@descs$);
        return;
    }

     

  13. prontera,193,124,6	script	Global Exp Amplifier#EventFloatingRates	10308,{
    
    	mes "[Global Exp Amplifier]";
    	mes "Current collected funds:";
    	mes "~ [^0000ff" + callfunc("F_InsertComma", $collected_funds) + "^000000] Zeny";
    	mes "Target global funds:";
    	mes "~ [^0000ff" + callfunc("F_InsertComma", .target_funds) + "^000000] Zeny";
    	mes "Still need " + callfunc("F_InsertComma", $donation_missing) + " Zeny to reach the target.";
    	next;
    	
    	switch (select("Donate Zeny", "Cancel")) {
    		case 1:
    			mes "Enter the amount you want to donate:";
    			next;
    			input .@donation;
    
    			// Validations
    			if (.@donation < .min_donation_zeny) {
    				mes "The minimum donation amount is " + callfunc("F_InsertComma", .min_donation_zeny) + " Zeny.";
    				end;
    			}
    			if (Zeny < .@donation) {
    				mes "You don't have enough Zeny.";
    				end;
    			}
    			if (.@donation > $donation_missing) {
    				mes "The amount exceeds the remaining balance.";
    				mes "Remaining Balance: " + callfunc("F_InsertComma", $donation_missing) + " Zeny";
    				end;
    			}
    
    			// Apply the donation
    			Zeny -= .@donation;
    			$collected_funds += .@donation;
    			$donation_missing -= .@donation;
    
    			mes "Donation successful. Thank you for your contribution!";
    			
    			// Start the event if the target is reached
    			if ($collected_funds >= .target_funds) {
    				$collected_funds = 0;	
    				announce "[Global Exp Amplifier]: Target reached! Activating Floating Rates Event for 3 hours.", bc_all, 0xFF6060;
    				donpcevent strnpcinfo(3) + "::OnStart"; // Ensure the event is triggered
    			}
    			end;
    	}
    
    OnStart:
    	if (.EventActive) end; // Prevent multiple activations
    
    	// Start the event for 3 hours
    	set .EventActive, 1;
    	announce "[Floating Rates]: The event has now officially started!", bc_all, 0x00FF00;
    	initnpctimer; // Start the NPC timer
    	end;
    
    OnTimer60000: // Every 60 minutes (60,000 milliseconds)
    	if (!.EventActive) end;
    
    	// Assign random rates within the specified range
    	set .@expRate, rand(5,8);
    	set .@dropRate, rand(10,15) / 10; // 1.0x - 1.5x
    
    	setbattleflag("base_exp_rate", .@expRate * 100);
    	setbattleflag("job_exp_rate", .@expRate * 100);
    	setbattleflag("item_rate_common", .@dropRate * 100);
    
    	announce "[Floating Rates]: New Rates -> EXP: " + .@expRate + "x, DROP: " + .@dropRate + "x", bc_all, 0xFFD700;
    
    	// This function is automatically repeated due to `initnpctimer`
    	end;
    
    OnTimer10800000: // Event ends after 3 hours (3,600,000 * 3)
    	// Reset rates to normal
    	setbattleflag("base_exp_rate", 100);
    	setbattleflag("job_exp_rate", 100);
    	setbattleflag("item_rate_common", 100);
    
    	announce "[Floating Rates]: The event has ended. Rates are now back to normal.", bc_all, 0xFF0000;
    	set .EventActive, 0;
    	stopnpctimer; // Stops the NPC timer system
    	end;
    
    OnInit:
    	set .target_funds, 1000000; // Target donation amount
    	set .min_donation_zeny, 10000; // Minimum donation amount
    	set .EventActive, 0;
    	set $donation_missing, .target_funds - $collected_funds;
    	end;
    
    }

    Try this. Maye it should help you.

  14. 1 hour ago, Origami said:

    Hi ! I've already did some of this but I noticed that there are some steps I didnt done ... Can you point out what step is for not removing the buff on relogin in ... Thankyou so much btw sir

     

    image.thumb.png.b523f3f2e53b25e493027f55d48ebda7.png

    Open map.cpp and search:

    status_change_end(&sd->bl, SC_PRESERVE, INVALID_TIMER);
  15. 2 hours ago, darkpatow said:

    Thank you, @Scanty.

    Now the script runs when i use the item.

    Would you know why it's returning "null" for the item?

    I couldn't understand why it doesn't work, because I use this same script in a NPC and it works.

    image.png.171ec1fd39184b379afa3dc150680984.png

     

    Sorry i didn't see this:

    set aboxqual, rand(1,2);
    			if (a_boxqual == 1)

    this 'if (a_boxqual...)' -> aboxqual

    • Love 1
×
×
  • Create New...