Leaderboard
Popular Content
Showing content with the highest reputation on 11/21/24 in all areas
-
I know there are some paid script like this but I created this from scratch. I'm sharing it now hoping that someone can improve it and make the community thrive from such simple script. Pros' Randomly gives any character 5 collection of cards Randomly set bonus stats for each cards Submission of cards will deduct any number of cards from inventory til max Gives permanent bonus to successfully submitted collection Retrieves cards that are already submitted and will remove permanent stats Resets the card collection and bonus stats Cons' While retrieving any cards this code is somewhat bugged with the application of visual addition of stats. Although my solution is bonus_script_clear but the issue here is bonus_script_clear will clear everything added to your character by bonus_script. So if you have buffs that came from a different script that has bonus_script. This will likely to be removed as well. // Apply reverse bonus to neutralize the effect //bonus_script(.@bonus_string$ + (-.@bonus_value) + ";", 512); //bugged stats won't be applied on the second try bonus_script_clear 1; Here's the code: //============================================================ //===== rAthena Script ======================================= //= Card Collection Quest NPC //= By: Louis T Steinhil //= Mostly ChatGPT v 1.0 //= v1.1 Added Alias Name to bonuses for better readability. //= v1.2 Added Cards submission even if the player doesn't //= have the right amount it will still submit regardless. //= v1.3 Initialization and resetting of arrays and variables: //= Ensure that arrays and variables are properly initialized //= and reset to avoid data from previous iterations. //= Avoiding nested loops with the same loop counter: //= The loop counter for the outer and inner loops should be //= different to prevent conflicts. //= v1.4 Rearranged for better readability. Replaced getiteminfo //= on submit with getitemname. //============================================================ yuno_in02,93,207,5 script Card Album 4_ENERGY_WHITE,{ switch (select("Start Card Collection:Reset:Cancel")) { case 1: // Main GM OPTION // Main GM OPTION if (!getd("card_list")) { // Define the fixed number of cards to collect set .@num_cards_to_select, 5; // Display the card collection quest dialogue mes "[Card Collection NPC]"; mes "Welcome to the Card Collection Quest!"; mes "Please submit the following [ " + .@num_cards_to_select + " ] different card/s to receive rewards."; next; mes "You must collect the following cards:"; // Fetch random card IDs for the collection if (checkre(0)) { .@mob_db$ = "mob_db_re"; .@item_db$ = "item_db_re"; } else { .@mob_db$ = "mob_db"; .@item_db$ = "item_db"; } freeloop 1; for (set .@i, 0; .@i < .@num_cards_to_select; set .@i, .@i + 1) { .@string$ = "( `name_aegis` IN ( SELECT DISTINCT `drop1_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop2_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop3_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop4_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop5_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop6_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop7_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop8_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop9_item` FROM `" + .@mob_db$ + "` ) " + "OR `name_aegis` IN ( SELECT DISTINCT `drop10_item` FROM `" + .@mob_db$ + "` ) )"; .@sql_query$ = "SELECT DISTINCT `id` FROM `" + .@item_db$ + "` WHERE `type` = 'Card' AND " + .@string$ + " ORDER BY RAND()"; .@nb = query_sql(.@sql_query$, .@id[0]); freeloop 0; if (.@nb < 1) { mes "[Card Collection NPC]"; mes "There are not enough valid cards in the database."; close; } // Find a valid card that is not an enchant card for ( .@j = 0; .@j < .@nb; .@j++ ) { if (getiteminfo(.@id[.@j], ITEMINFO_SUBTYPE) != CARD_ENCHANT) { // Save the card ID setd("Card" + .@i, .@id[.@j]); break; // Exit the loop once a valid card is found } } // Check if all cards fetched are enchant cards if (.@j >= .@nb) { mes "[Card Collection NPC]"; mes "There are not enough valid cards in the database."; close; } // Generate a random number of cards to collect (between 1 and 10) set .@cards_to_collect, rand(1, 10); setd("Card" + .@i + "_", 0); setd("Collect" + .@i + "_", .@cards_to_collect); } // Clear the array for generating bonuses deletearray .@j[0], getarraysize(.@j); deletearray .@used_bonus_index[0], getarraysize(.@used_bonus_index); // Generate bonus array with bonus strings setarray .@bonus_string$, "bonus bStr,", "bonus bAgi,", "bonus bVit,", "bonus bInt,", "bonus bDex,", "bonus bLuk,"; // Generate corresponding alias array setarray .@bonus_alias$, "Str +", "Agi +", "Vit +", "Int +", "Dex +", "Luk +"; setarray .@used_bonus_index[0], false, false, false, false, false, false; // Display submitted cards and their statuses for (set .@i, 0; .@i < .@num_cards_to_select; set .@i, .@i + 1) { do { set .@random_bonus_index, rand(0, getarraysize(.@bonus_string$) - 1); } while (.@used_bonus_index[.@random_bonus_index]); set .@used_bonus_index[.@random_bonus_index], true; set .@random_number_bonus, rand(1, 10); // Store the generated bonus and its value setd("Bonus" + .@i + "_String$", .@bonus_string$[.@random_bonus_index]); setd("Bonus" + .@i + "_Alias$", .@bonus_alias$[.@random_bonus_index]); setd("Bonus" + .@i + "_Value", .@random_number_bonus); .@j[.@i] = getd("Card" + .@i); mes "(" + getd("Card" + .@i + "_") + " / " + getd("Collect" + .@i + "_") + ") - " + mesitemlink(.@j[.@i]); mes "> Deposit Reward: " + getd("Bonus" + .@i + "_Alias$") + " " + .@random_number_bonus; dispbottom("(" + getd("Card" + .@i + "_") + " / " + getd("Collect" + .@i + "_") + ") - " + itemlink(.@j[.@i]) + " > Deposit Reward: " + getd("Bonus" + .@i + "_Alias$") + " " + .@random_number_bonus); } // Set the card list flag setd("card_list", 1); close; } else { // Display regular options for starting the card collection or choosing "No" switch (select("See List:Submit Cards:Retrieve Card/s:Cancel")) { case 1: // See List // Check if bonuses have been generated before mes "[Card Collection NPC]"; mes "Here are your previously generated cards list & bonuses:"; for (set .@i, 0; .@i < 5; set .@i, .@i + 1) { // Clear the array deletearray .@j[0], getarraysize(.@j); set .@bonus_alias$, getd("Bonus" + .@i + "_Alias$"); set .@bonus_value, getd("Bonus" + .@i + "_Value"); // Display submitted cards and their statuses .@j[.@i] = getd("Card" + .@i); mes "(" + getd("Card" + .@i + "_") + " / " + getd("Collect" + .@i + "_") + ") - " + mesitemlink(.@j[.@i]); mes "> Deposit Reward: " + getd("Bonus" + .@i + "_Alias$") + " " + .@random_number_bonus; dispbottom("(" + getd("Card" + .@i + "_") + " / " + getd("Collect" + .@i + "_") + ") - " + itemlink(.@j[.@i]) + " > Deposit Reward: " + getd("Bonus" + .@i + "_Alias$") + " " + .@random_number_bonus); .@j[5] = .@j[5] + getiteminfo(.@j[.@i], ITEMINFO_AEGISNAME); } close; break; case 2: // Submit Cards // Initialize the menu string set .@menu$, ""; // Loop through the list of card IDs to populate the menu for (set .@i, 0; .@i < 5; set .@i, .@i + 1) { // Get the card name using its ID set .@card_name$, getitemname(getd("Card" + .@i)); // Get the submission count using dedicated variable set .@submission_count, getd("Card" + .@i + "_"); // Retrieve the required number of cards to collect for the chosen slot set .@required_cards, getd("Collect" + .@i + "_"); // Determine the submission status of the card set .@submission_status$, " (" + .@submission_count + " / " + .@required_cards + ")"; // Append the card name and submission status to the menu string .@menu$ += .@submission_status$ + " - " +.@card_name$ + ":"; } mes "[Card Collection NPC]"; mes "Which card would you like to submit?"; // Display the menu and handle player selection set .@selection, select(.@menu$) - 1; set .@selectedCardId, getd("Card" + .@selection); // Retrieve the submission count set .@submission_count, getd("Card" + .@selection + "_"); // Retrieve the required number of cards to collect for the chosen slot set .@required_cards, getd("Collect" + .@selection + "_"); // Calculate the number of cards to submit set .@cards_needed, .@required_cards - .@submission_count; // Get the player's inventory getinventorylist; // Check if the player has the selected card in their inventory set .@player_card_count, 0; for(set .@j, 0; .@j < @inventorylist_count; set .@j, .@j + 1) { if(@inventorylist_id[.@j] == .@selectedCardId) { set .@player_card_count, @inventorylist_amount[.@j]; break; } } // If player has no cards, inform and exit if (.@player_card_count == 0) { mes "[Card Collection NPC]"; mes "You do not have any of this card."; close; } // Calculate the actual number of cards to submit (up to the needed amount) set .@cards_to_submit, min(.@cards_needed, .@player_card_count); // Update submission count setd("Card" + .@selection + "_", .@submission_count + .@cards_to_submit); // Remove the cards from the player's inventory delitem .@selectedCardId, .@cards_to_submit; mes "[Card Collection NPC]"; mes "Card submitted successfully!"; // If the card collection is complete for this card, apply the bonus if (getd("Card" + .@selection + "_") >= getd("Collect" + .@selection + "_")) { // Retrieve the stored bonus and its value set .@bonus_string$, getd("Bonus" + .@selection + "_String$"); set .@bonus_alias$, getd("Bonus" + .@selection + "_Alias$"); set .@bonus_value, getd("Bonus" + .@selection + "_Value"); // Apply bonus bonus_script(.@bonus_string$ + .@bonus_value + ";", 512); // Display the bonus received mes "[Bonus " + (.@selection + 1) + "]: " + .@bonus_alias$ + " " + .@bonus_value; } close; break; case 3: // Retrieve Cards // Check if any cards have been submitted set .@cards_submitted, 0; for (set .@i, 0; .@i < 5; set .@i, .@i + 1) { if (getd("Card" + .@i + "_") == getd("Card" + .@i + "_")) { set .@cards_submitted, .@cards_submitted + 1; } } if (.@cards_submitted == 0) { mes "[Card Collection NPC]"; mes "You haven't submitted any cards yet."; close; } // Check if the player has already started the card collection if (getd("card_list") == 1) { mes "[Card Collection NPC]"; mes "^FF0000Warning: Retrieving cards will reset the card/s submitted and revoke any bonuses generated.^000000"; next; } // Retrieve submitted cards for 1 million zeny if (Zeny < 1000000) { mes "[Card Collection NPC]"; mes "You need 1,000,000 Zeny to retrieve the cards."; close; } // Deduct 1 million zeny set Zeny, Zeny - 1000000; // Neutralize the granted bonuses for (set .@i, 0; .@i < 5; set .@i, .@i + 1) { if (getd("Card" + .@i + "_") == getd("Card" + .@i + "_")) { // Retrieve the stored bonus and its value set .@bonus_string$, getd("Bonus" + .@i + "_String$"); set .@bonus_value, getd("Bonus" + .@i + "_Value"); // Apply reverse bonus to neutralize the effect //bonus_script(.@bonus_string$ + (-.@bonus_value) + ";", 512); //bugged stats won't be applied on the second try bonus_script_clear 1; } } // Return the cards to the player for (set .@i, 0; .@i < 5; set .@i, .@i + 1) { if (getd("Card" + .@i + "_") == getd("Card" + .@i + "_")) { getitem getd("Card" + .@i), getd("Card" + .@i + "_"); setd("Card" + .@i + "_", 0); } } mes "[Card Collection NPC]"; mes "You have retrieved your submitted cards and your bonus has been neutralized."; close; break; default: mes "[Card Collection NPC]"; mes "Alright, have a great day!"; close; break; } } case 2: // Check if the player has enough Zeny if (zeny < 5000000) { mes "[Card Collection NPC]"; mes "You don't have enough Zeny to restart the card collection."; close; } else { mes "[Card Collection NPC]"; mes "^FF0000Are you sure you want to restart the card collection? This action will deduct 5 million Zeny from your account^000000"; mes "^FF0000and the submitted card will be gone forever!^000000"; switch (select("Yes:No")) { case 1: // Deduct 5 million Zeny from the player zeny -= 5000000; // Start Card Collection again setd("card_list", 0); // Reset the flag to allow new bonuses to be generated set .BonusesGenerated, 0; next; mes "[Card Collection NPC]"; mes "Card list and Bonus Stats have been reset. 5 million Zeny has been deducted from your account."; close; break; case 2: mes "[Card Collection NPC]"; mes "Card collection reset cancelled."; close; break; } } break; default: mes "[Card Collection NPC]"; mes "Alright, have a great day!"; close; break; } OnInit: setunitdata( getnpcid(0), UNPC_GROUP_ID,6 ); setunittitle( getnpcid(0), "Universal" ); end; } Github Link: https://github.com/Qubeks/Script-Release/blob/main/Card_Collector.txt1 point
-
It's funny that every time I say I'm done I still constantly make small tweaks, mostly still to monster skill use rates and stats. Something I've been looking at lately is monster sizes, which are all over the place and make no sense 95% of the time. For example, Dullahan is Medium size, while Loli Ruri and Bloody Murderer are Large size. Okay, that kinda makes sense, they are bigger than Dullahan. But wait, Argos is Large size. Is that because it's comparatively large for a bug? I mean, sure, it's huge for a spider, but it's much smaller than Dullahan. It's also smaller than Mantis, which is considered Medium. Rocker, Metaller, and Ashhopper are even bigger and are still Medium. Argiope is Large, even though Centipede, which uses an edited version of its sprite, is only Medium. Giant Hornet is Small, even though it has the word "Giant" right in its name. The list goes on and on. It would be impossible to ever get them to be totally consistent, but I think it's getting a little better. I'm sorry Knights and users of Size cards if this disrupts your farming. I'm glad to hear you've been enjoying the topic. I will note that in Ragnarok time, 10 seconds is an eternity. I actually once had a boss (Lost Dragon) that had a 10 second cast skill, not even intentionally, but because I didn't see it when it was editing its skill list. This boss then became absurdly easy to solo by simply running around, waiting for it to try to cast that skill, beating on it for 8 seconds, then dodging the skill and repeating the process. Of course, it would help if the skill was interruptable (then it would at least fight back), but that super slow charge bar is still basically a "come hit me" indicator. Generally, peak human reaction time is around 120ms, but in Ragnarok the network latency time plays into this because the boss starts casting when the packet is sent, not when you receive it. Generally though, I tend to use around 700-1200ms as charge time on spells I want to be fairly reactable, and 500ms on spells that you can avoid if you're really paying attention. Lower cast times are basically only for skills you can only dodge if you're already moving or hovering over the "Back Slide" / "Time Slip" key. But that's fine, you're not supposed to be able to dodge everything. A key element of Ragnarok's success in my opinion is that it's only semi action-based. You can dodge some stuff, but not everything, you're still definitely going to be hit, which makes both your skill as a player and your build and equipment vital to success. In a lot of games where skill has a very large impact (generally where almost every attack is potentially avoidable) gear tends to be kind of irrelevant, or at least you only care about offense, and they just don't have the endless replayability that Ragnarok has. This is actually a good segway though because it lets us talk about Boss Design, which is actually something I've never really talked about until now. My server has over 100 bosses, and I've pretty sure I've tweaked the skill lists of all of them a few times, so I guess I can talk about some of the bigger changes to bosses and a bit of how I generally try to design them. For starters, one change I've made pretty much across the board is that bosses have far longer cooldowns on their minion summoning skills. In base, many of them can cast these every few seconds, so killing their minions is almost a total waste of time, but on my server these cooldowns are much longer. For most bosses, the cooldown on their minions is 60-120 seconds, depending generally on how hard their minions are. This makes killing them pretty viable, especially if you're planning to facetank the boss. A couple bosses have faster minions, but they're generally very weak. Dracula can call his bats every 20 seconds, but they're so wimpy that you can actually abuse "when being hit" cards to farm them. Another skill that a ton of bosses have in their lists, which is in most cases outright gone is Teleport. Of course, they still have their Rude Attack teleport, but many other bosses can Teleport every 20 seconds or so, which is unspeakably annoying, because you spend 2 minutes finding them again, hit them once, then they just do another teleport. A few bosses can still do this, generally with a cooldown of about 2-5 minutes, but most can't. There are a couple skills like Crimson Marker and Wrath of the Sun, Moon, and Stars (which seals teleporting and works on bosses) that you can use to counter the ones that can still do it. Most bosses also can no longer cast Heal, but a few still can. So what about the skills bosses can use? In most cases it's still kind of similar to base, but with a few additions and deletions here and there. For the bosses that are totally original, it's generally just based on what I think they should be able to do. For example, let's take a random look at Anglerfish, which is an original boss. Here's a quick look at his skill list: His mob is 2 Tacnu, on a 2 minute cooldown. Tacnus are kind of scary upclose fighters. His standard spells are Lightning Bolt, Thunderstorm, Chain Lightning, and Holy Light. He can cast all of these near-constantly and he has high INT, so this is much of his offense. He also has level 8 waterball, though his waterball is actually interruptable. Obviously, high level Waterball is something you really don't want to be hit with since it hits like 100 times. His melee attacks are Bleeding, Critical Wound, Blood Drain, and Jupitel Thunder (although Jupitel is a spell, he only uses it in melee range). These are less threatening than his spells so melee is a good option when his mob is down. He has Static Field, which is a new spell that was mentioned earlier, this creates damaging electric zones on the ground that can paralyze you. His cooldown on this is pretty short too, so you may have to move him if he spams a lot of these. He has Wide Confuse, which is annoying, as this makes it very hard to move around. You probably want some way to heal this off or be immune to it. Finally, he also has Reflect Shield, though it's a low-level version and on a long cooldown. Obviously, you have to be pretty careful when this is up. So what's the general idea on how you deal with this? For starters, Lightning Armor is pretty strong. It both protects you from most of his spells and gives some defense against Water Ball. If you want more elemental defense you could take additional lightning or water defense, or just MDef in general. His physical attacks aren't that scary if you can get rid of the Tacnus. You probably also want confusion immunity. Then you just attack with strong Earth element stuff or criticals or something, though you may want to be careful of EDP in case he puts reflect shield up and you instantly delete yourself. This is sort of my boss design philosophy in a nutshell. The idea is that you want to know what a boss does, then create a setup to counter that. Since RO gives you so many options to work with, there's almost nothing that's insurmountable with all the tools at your disposal. As such, I basically never worry about whether or not a boss is "too hard" because I know someone will find a way to do it. Worst case there's always boss cards, which can generally turn you into a god with just 1 or 2 of them. Wow, this got surprisingly long, and I haven't even gotten to new skills yet, of which there's a couple. For starters, there's a bugfix. Here's a fun experiment. Play a Rogue and equip a bow. Run away from an enemy, then take a shot at them and use Back Slide. Assuming you clicked directly on them without moving anywhere else first, you'll slide TOWARDS the enemy! What is this "Front Slide" madness?! We only slide back around here! The problem here is that the game doesn't update the user's facing direction when you attack. This is easily fixed by adding this code to unit_attack, unit_skilluse_pos2, and unit_skilluse_id2 (probably somewhere towards the middle of the method, after the validity checks) // make the user face the target if (src != target) unit_setdir(src, map_calc_dir(src, target->x, target->y)); You now properly slide away from your target after attacking. I can't believe it took this long for this glitch to be found. Bow Rogue really is that bad, I guess. Onto new skills. For some time, I've felt that a few classes were a little low on skills, but at the same time I didn't want to give them a ton of new stuff because I didn't want to adjust the balance too much, so it took some time to come up with an appropriate adjustment. Lord Knight now gets Trample. This is a skill I was looking at for a long time. I like that it counters Trap cheese, but I also really don't like the idea of Paladin having it. Paladin is already almost unkillable and having them running around deleting your traps would almost certainly be too oppressive for Hunters. Surprisingly it took me a long time to come up with the rather simple solution of just giving it to Lord Knight instead. It's still a good skill, but it doesn't mesh nearly as well with what Lord Knight wants to be doing, they typically just want to use Berserk and rush the Emperium, which of course prevents you from using Trample since you can't use skills during Berserk. LK is actually deceptively less tanky than you'd think a lot of the time without Berserk, especially where magic is concerned, and Trample has cast time and is even uninterruptable, so you're probably going to have to commit at least some of your build to this if you want it to be effective. I think it's probably best for Blade Beam LKs who might be running Uninterruptable Cast anyway, but that's sort of a niche build and it could probably use the help. Also, I love how the Peco does a little stamp when you use this skill. Speaking of Paladin, they now get Prestige, which is renamed to Divine Will (and has a somewhat weaker effect). Paladin is a funny class in that it got an absolutely massive buff when I first started working on the game via the reworked of Pressure, and I've had to gradually scale back their power to prevent them from being a master of all. As such, while other classes kept getting new skills, Paladin kind of fell behind and now has among the lowest total skill costs of any class, which is the main reason they get this new buff. Divine Will gives you a small boost to VIT Def and a chance to dodge spells. This is a Royal Guard ability, and of all the third classes, Royal Guard probably has the least skills that I've ported over, mainly since I find a lot of their skills really boring and the ones that aren't boring give massive boosts to sustain that Paladin absolutely shouldn't have with the Pre-RE Def formula. Even this skill is maybe kinda pushing it, but it's buried pretty deep in the tree so you're probably not getting it on Magic-oriented Paladin, so it primarily exists to make non-magic Paladin a bit more bulky against spells. Also, the most interesting thing about it is that at level 6+ it becomes a party-wide spell, and I always find team buffs to be interesting. While Paladin kinda doesn't care about getting some flat VIT Def, to a class like Wizard this could be pretty big. Champion also now has a new skill in Full Throttle. On base, this is a skill that everyone gets, but here it's limited to Champion. It's actually an even better skill than in the base game, it retains its "heal to full and get boosted stats and move speed" effect but with no downsides whatsoever, as the rebound debuff is eliminated. Instead, it has a totally different drawback. To use it, you have to be in Fury Status, which it removes, and you can't cast Fury again while it's active, so no Boosted Asura for you (unless you're using Combo Asura and lol Combo Asura). This also means there's an inherent limit to how often you can get the heal, since it has to wear off before you can cast Fury again and thus recast it. This might give you some incentive to only use the level 1 version, which gives almost no stat boost, but doesn't last very long so it's a more reliable heal, though the big stat boost on the level 10 version is also appealing. Either way, it gives Monks something else to do besides combos and Asura, which has always been a challenge. Oh, speaking of Fury / Critical Explosion, it also now shows a status icon that shows you how much time it has left. I've been going through the game and fixing most of the statuses that didn't have this by swapping them to unused EFSTs. Very tech-savvy users might know that Fury's original EFST, despite not having any description, is responsible for the colour change that accompanies Fury's animation, though I ensure that you still get this by also sending Fury's EFST in status_change_start. This also finally allowed me to fix Bard / Dancer's Up Tempo not displaying the quicken afterimage. Last, but definitely not least, we have Whitesmith. I've long felt Whitesmith was one of the most dull classes in the game, and while the new skills have helped a lot, I still felt it was missing something fun. For a long time, I've wished Blacksmith could use more of the weapons it can forge. I'd like the class to be able to use 2 Handed Swords, but this is not attainable without Client Modification. Even if we give them a sprite file for using 2 handed swords, they will always use their Attack2 animation for this weapon type, which is a punch, so it will never look good. Maybe you could make a spear animation for that, but hey, if they already have a decent looking Punch animation, why not let them use Fist-type weapons? Fist has always felt like a bit of an underappreciated weapon type because even though Priests can use it, they basically never want to, but a Brawler like Blacksmith might get some use out of it! Since it just uses Attack2's animation it looks perfectly fine with no adjustments too. Of course, the second I decided to let Whitesmith use Fist Weapons I knew what the new attack had to be. RocketPunch.mp4 GET OVER HERE! This is a heavily reworked version of Mechanic's Knuckle Boost. Obviously, the biggest change is that it now pulls the target towards you, which is a cool effect that nothing else in the game currently has. Besides its obvious PVP uses, I think this is an interesting way to increase Blacksmith's tanking skills, since they can now pull enemies towards them that might try to target backliners. It's also quite deliberate that the pull effect isn't optional - this isn't intended to be a godlike kiting skill or replace the function of Cart Cannon, it's primarily to get enemies in range for a melee beatdown faster. On a technical level, you might notice that the pull effect isn't instant, it occurs after the damage. Most skills that do knockback actually inflict the knockback before the damage, but in this case this would cause the actual projectile to visually miss, which is very lame, so here the pull effect is a "timerskill" that occurs 200ms after the damage packet. There's also a bit of a weird issue where this attack normally locks the Whitesmith into a strange hammer animation that they can't directly attack out of, which is why the skill does 2 hits, with the second being a normal attack packet. It took a deceptively long time to get this skill working properly, but I'm very happy with the result. Well, that's it for now. This is probably the end of major skill changes, though I say that every time. Still, there's now not really any classes where I'm unhappy with their skill selection, which is a good feeling. It took a long time to get here.1 point
-
[UPDATE]: Since Innova (4Game) closed my project and I can no longer open new projects, this is my parting gift to the rAthena community. You can download my sprites rework [FOR FREE] and not for sale! [DOWNLOAD] https://mega.nz/file/taQwkKwL#ikVnLwKyX52rymVMlaAqxFMd8YHsC2itTyk3GxmAjtc Hi all! I improved the NPC images (1190 sprites up to episode 18.1) using a neural network (ESRGAN) and made new HD sprites. Want to show you my final work! ? What do you thinking about it?1 point
-
View File Adaptação Npc Gacha! Sprite simples, para quem quiser. Submitter Joker Sama Submitted 11/19/23 Category NPC Sprites Video Content Author Joker Sama1 point
-
The thing is, we don't quite understand what are you guys need. can you please be more specific. EDIT: Okay so i re-read it, and somehow i know what you guys want. let me take a few minutes. EDIT 2: Here's what you guys need P.S Dont forget to upvote if i helped prontera,154,177,5 script Yumi Haruka 811,{ mes .name$; mes "Hello, i can reset an instance."; mes "What instance do you want to reset?"; next; for(.@i=0;.@i<getarraysize(.instances$);.@i+=5) set .@menu$,.@menu$+.instances$[.@i]+":"; set .@ans,select(.@menu$)-1; set .@instance$,.instances$[.@ans*5]; set .@qid,atoi(.instances$[(.@ans*5)+1]); set .@item,atoi(.instances$[(.@ans*5)+2]); set .@amt,atoi(.instances$[(.@ans*5)+3]); set .@zeny,atoi(.instances$[(.@ans*5)+4]); next; if(checkquest(.@qid,PLAYTIME)==2 || checkquest(.@qid,PLAYTIME) < 0){ mes .name$; mes "Eh? You don't need to reset this instance. You are already allowed to enter it."; end; } mes .name$; mes "So you want to reset ^FF0000"+.@instance$+"^000000?"; mes "It will cost you: "; if(.@item) mes ""+.@amt+"x ^0000FF"+getitemname(.@item)+"^000000"; if(.@zeny) mes "and ^0000FF"+.@zeny+"^000000 Zeny!"; mes "Would you like to reset now?"; next; if(select("Yes, Please Reset:No sorry")==2){ mes .name$; mes "Okay, Please come at me again once you decided"; end; } close2; if(.@item && countitem(.@item)<.@amt) goto L_NotEnough; if(.@zeny && Zeny<.@zeny) goto L_NotEnough; if(.@item) delitem .@item,.@amt; Zeny-=.@zeny; erasequest .@qid; message strcharinfo(0),"Instance has been Reset!"; end; L_NotEnough: mes .name$; mes "Sorry! But unfortunately, You don't have the requirements to reset the instance"; end; OnInit: // Instance Name, Quest ID, Item ID for Reset,Item Amount, Zeny Amount set .name$,"[ Yumi ]"; setarray .instances$[0], "Endless Tower","60200","501","10","100000", "Nidhogg Nest","3135","502","30","0", "Sealed Shrine","3045","0","0","999999"; end; }1 point