Weapon Efficiency Progression

Alkaline

Veteran
Veteran
Joined
Jun 30, 2020
Messages
31
Reaction score
3
First Language
English
Primarily Uses
RMMV
I want to add a mechanic to my game similar to Fire Emblem, where the more you use a weapon you level it up and can then equip better weapons of that type (i.e. start with a bronze sword and after using it enough times you can use a steel sword). Anyone knows if there is a way to implement that?
 

ATT_Turan

Veteran
Veteran
Joined
Jul 2, 2014
Messages
74
Reaction score
27
First Language
English
I Googled "RPG Maker MV weapon proficiency," and found a few existing threads about how to do this.

You'd use Galv's Weapon Proficiency to create the proficiency system, then Yanfly's Equip Requirements to set the requirements for a certain level of proficiency on each individual weapon.
 

Frostorm

[]D[][]V[][]D aka "Staf00"
Veteran
Joined
Feb 22, 2016
Messages
1,116
Reaction score
809
First Language
English
Primarily Uses
RMMV
This is copy-pasted from a conversation I had w/ @xDRAGOONx:
Weapon Mastery System

This guide will cover my implementation of a skill and variable-based weapon mastery system.

This system utilizes plugins, skills, variables and states to create a system where the more a character uses any given weapon type, the stronger they will become with it. I will cover the setup in this order:
  1. Plugins used
  2. Variable setup
  3. Skill setup
  4. State setup
  5. Notetag code
Before we dive in, there are a few things I'd like to point out in advance;

This system relies on having one skill per weapon type. If you have 30 weapon types, you'll need 30 skills, thus increasing the overall work load. I am using this with 12 weapon types and that was a decent amount of work overall. Once I got it down though it started to flow smoothly. Using this guide for 30 weapon types probably wouldn't be that much more work than what I have put into it.

I am not a veteran coder, I have worked my way up to this point by trial and error. While I have tested this system in my current project, I cannot account for anything specific to other projects that may complicate or break this system. While I am willing to work with you on this, I can't guarantee full functionality across all projects, as it does rely on multiple plugins.

This system uses 120 states, one per weapon type per mastery level. While there might be a way to create dynamic states that change based on the mastery level variables themselves or switches even, this is the route I chose. Maybe in the future, I will look into lowering the number of states used without losing any functionality, but that will definitely take more coding withing each state. Managing all 120 states is not difficult as it seems. The level 1 states are basically templates for the other levels, needing only minor changes. The passive states themselves are added to the weapons, meaning an actor can only utilize

Lastly, there may be things you want to do differently, which is great. In fact, I urge you to take from this only what you truly need.

TASK LIST:

  1. Create and Organize Variables
  2. Create Skills
  3. Create States

PLUGINS:

I won't cover the complete function of each plugin, only what is important to this system. Also, I will link to yanfly's site here, but at this point I'm not familiar with which plugins cost what amount.
  • YEP Core Engine - core engine needed for all other yanfly plugins
  • YEP Skill Core - needed to create the post damage eval notetags to control the variables
  • YEP Weapon Unleash - needed to replace the attack skill with our new weapon-type based skills
  • YEP Status Menu Core - needed for Actor Variables plugin
  • YEP_X_Actor Variables - needed to show the mastery levels in the status menu (NOTE: I am planning to look into another of yanflys plugins, custom common event menu, to create a custom menu to display the mastery variables in the future)
  • YEP Auto Passive States - needed to add the mastery bonus states to characters automatically when mastery levels go up

VARIABLES:

Organizing your variables before you begin to actually implement them can make things much easier.
1592545164844.png

TASK 1: Create 2 variables per usable weapon type for each character

I'll explain how I organized my variables to make the code easier to write.

First, I selected a completely empty block of 20 variables, this case, 101-120.

Next, I began assigning variables to the first actor's equipable weapon types, starting with the first equipable type in the database, in this case daggers(I actually started with swords, which are the second weapon type, but ignore that for now)

So, Variable 101 = actor 1's dagger mastery experience. Continue to assign the remaining usable weapon types to the variables.

Notice the empty spaces between the variable sets, I did this to further organize the variables. Each set, experience and level, are always 10 variables apart. If for some reason your characters can use more than 10 weapon types, I suggest putting as many empty spaces needed between the set to have them be 20 apart as having them a set distance apart will make things much easier when it comes to code the notetags. WHen it comes to the notetags, you will need to know which variables apply to which actors. Writing them down is good idea.

Using <<TEXT>> you can hide the text between << and>> for when the variable is displayed in the menu. \I[97] draws icon 97 into the name. I did this to shorten and organize the variables in the status menu.

1592545112757.png

This is how the variables appear in the status menu before I run the initialize event to hid the weapon types still unavailable to the actors current class. Using icons for the name cleans everything up.

NOTE: the variables won't actually do anything until you implement them into the corresponding skills but you need to outline them all first. The first set is for weapon experience, while the second set is for the actual mastery level, more on that later.

Continue to assign the variables for each actor, selecting a new empty block for each. Once all you variables are assigned you can move on to the skill setup phase.


SKILLS:

As mentioned before, you'll need one new skill for each weapon type. These skills will replace the basic attack skill using a notetag from the weapon unleash plugin. This will allow us to control a specific variable based on the weapon the user has equipped. We only need one skill per weapon type due to using a switch statement that checks which actor is using the skill.

TASK: Create 1 skill per weapon type, add normal attack attribute to each

1592545086127.png

I simply named each skill after they weapon type it corresponds with. As it is, the name displayed in the editor will be the name displayed in the battle scene, which is what you want at this point. There is a way to change the name back to "Attack" but if you do that now you lose the ability to easily identify which skill you are actually using. Later we will cover how to change a skills name using a simple notetag in the skills notebox.

Before moving on to the next step, be sure to set each skill to have the "Normal Attack 100%" effect

1592545027728.png

STATES:

TASK: CREATE 1 STATE PER WEAPON PER MASTERY LEVEL


Since I have 12 weapon types and 10 mastery levels, I am using 120 states. Your system might be more or less. I chose 10 mastery levels that level slowly to create a nice bonus that the player really won't grind for but will be nice when it levels. I should point out at this point that my mastery bonuses only add a small amount of damage because I am using lower numbers for my stats and a system similar to D&D where actor and enemy base defense acts more like an armor class and does less for lowering incoming damage. If you're interested in that system, there's this.

1592544959578.png
Weapon Mastery System: Part 2

Now that we have our variables, states and skill all setup; we can continue on to adding the necessary code to the corresponding notetags.

Let's start with the sword attack replace skill:

JavaScript:
<Post-Damage Eval>

switch (user.actorId()) {

case 1: if ($gameVariables.value(111) >= 11) {

$gameVariables.setValue(111, 11)

$gameVariables.setValue(101, 'Max')

} if ($gameVariables.value(111) < 11) {

   $gameVariables.setValue(101, $gameVariables.value(101) + 1)

}

if ($gameVariables.value(101) >= $gameVariables.value(111) * 100) {

  $gameVariables.setValue(111, $gameVariables.value(111) + 1)

  $gameVariables.setValue(101, 0)

  user.startAnimation(122, false, 0)

  $gameMessage.setFaceImage(user.faceName(), user.faceIndex())

  $gameMessage.setBackground(1)

  $gameMessage.setPositionType(1)

  $gameMessage.add('\\I[97] Mastery Up!')

}

break;

case 2: if ($gameVariables.value(131) >= 11) {

$gameVariables.setValue(131, 11)

$gameVariables.setValue(121, 'Max')

} if ($gameVariables.value(131) < 11) {

   $gameVariables.setValue(121, $gameVariables.value(121) + 1)

}

if ($gameVariables.value(121) >= $gameVariables.value(131) * 100) {

  $gameVariables.setValue(131, $gameVariables.value(131) + 1)

  $gameVariables.setValue(121, 0)

  user.startAnimation(122, false, 0)

  $gameMessage.setFaceImage(user.faceName(), user.faceIndex())

  $gameMessage.setBackground(1)

  $gameMessage.setPositionType(1)

  $gameMessage.add('\\I[97] Mastery Up!')

}

break;

case 5: if ($gameVariables.value(191) >= 11) {

$gameVariables.setValue(191, 11)

$gameVariables.setValue(181, 'Max')

} if ($gameVariables.value(191) < 11) {

   $gameVariables.setValue(181, $gameVariables.value(181) + 1)

}

if ($gameVariables.value(181) >= $gameVariables.value(191) * 100) {

  $gameVariables.setValue(191, $gameVariables.value(191) + 1)

  $gameVariables.setValue(181, 0)

  user.startAnimation(122, false, 0)

  $gameMessage.setFaceImage(user.faceName(), user.faceIndex())

  $gameMessage.setBackground(1)

  $gameMessage.setPositionType(1)

  $gameMessage.add('\\I[97] Mastery Up!')

}

break;

case 6: if ($gameVariables.value(211) >= 11) {

$gameVariables.setValue(211, 11)

$gameVariables.setValue(201, 'Max')

} if ($gameVariables.value(211) < 11) {

   $gameVariables.setValue(201, $gameVariables.value(201) + 1)

}

if ($gameVariables.value(201) >= $gameVariables.value(211) * 100) {

  $gameVariables.setValue(211, $gameVariables.value(211) + 1)

  $gameVariables.setValue(201, 0)

  user.startAnimation(122, false, 0)

  $gameMessage.setFaceImage(user.faceName(), user.faceIndex())

  $gameMessage.setBackground(1)

  $gameMessage.setPositionType(1)

  $gameMessage.add('\\I[97] Mastery Up!')

}

break;

}

</Post-Damage Eval>


I know, that's a lot of code, right? So let's break it down. NOTE: I will include the previous portions of code in each new example. The first thing to examine is the notetag:

<Post-Damage Eval>
CODE
</Post-Damage Eval>

creates a portion of code that runs after damage has been calculated, meaning that if the attack skill misses, the code will not run. This is exactly what we want in this situation, as we don't want the actor's mastery to rise if they miss the attack.


Next, the code itself is called a switch statement. The switch statement evaluates an expression, matching the expression's value to a case clause, and executes statements associated with that case, as well as statements in cases that follow the matching case. What exactly does that mean? Well it simply means that we can use javascript to create a process that will run specific code when certain conditions are met, in our case it will be the actor using the skill.

switch (user.actorId()) {
}

The above code contains our expression: 'user.actorId() ' and it returns the numerical value of the actor using the skill, when the first actor in the database has a sword equipped and uses the attack skill, the expression simply returns the value 1, if it were the second actor using the skill, it would return 2 and so on. NOTE: Everything after our expression will need to be enclosed in curly braces, notice the lone ' } ' before the closing of the notetag.


Now, the case clauses.
switch (user.actorId()) {
case 1: CODE
break;

In the above example, '1 ' is our first case clause. When our expression returns the value of 1, the code in our first case clause will be executed. The code in case 1 will be specific to Actor 1.

NOTE: using numbers as the case clause might be a little confusing at first if you've never used switch statements. What I mean is that case clauses can be any code that can be returned from the switch expression. Our first case just so happens to be '1', not because it's our first case clause, but because we're expecting the value of 1 to be returned. We are expecting the value of 1 to be returned because the first actor can use swords. So this means we will only need a case for the actors who can use the weapon type of this particular skill. You may have noticed the case clauses go 1, 2, 5, 6. In my current project only actors 1, 2, 5 and 6 can equip swords.


Here is an empty switch statement you can use if you'd like to compile your own code:

JavaScript:
switch (EXPRESSION) {
case X:
break;
case X:
break;
case X:
break;
case X:
}


Okay so we've got our switch statement outlined, let's explore the code within the first case clause and see how it manipulates our variables to create our system in-game.

NOTE: I used if statements in the case clauses extensively, which work just like conditional branches in the event editor. If the 'if' condition returns true, the code after the condition will run, if the statement returns false, it will be skipped. With the current setup, I didn't find it necessary to use any else clauses, although a more experienced programmer might be able to achieve this same effect with much simpler code. Also, the if statement is enclosed in parenthesis and everything after the if statement is enclosed in curly braces.

switch (user.actorId()) {

case 1: if ($gameVariables.value(111) >= 11) {

$gameVariables.setValue(111, 11)

$gameVariables.setValue(101, 'Max')

}

If you remember from setting up the variables, $gameVariables.value(111) represents actor 1's sword master level, while variable 101 represents their sword mastery exp. So, if actor 1's sword mastery is greater than or equal to 11, set variable 111 to 11 and set variable 101 to 'Max'. This creates a cap for the weapon mastery level, capping at 11 and changes the exp var to read 'Max' when there are no more levels to gain. We put this first in the clause because we always want to check this first.


Now, we will process gaining the mastery exp.

if ($gameVariables.value(111) < 11) {

$gameVariables.setValue(101, $gameVariables.value(101) + 1)

}

So, if actor 1's mastery level is less than 11, add 1 to their mastery experience, simple.


Our next if statement is fun! It handles when the player gains a weapon mastery level!

if ($gameVariables.value(101) >= $gameVariables.value(111) * 100) {

$gameVariables.setValue(111, $gameVariables.value(111) + 1)

$gameVariables.setValue(101, 0)

user.startAnimation(122, false, 0)

$gameMessage.setFaceImage(user.faceName(), user.faceIndex())

$gameMessage.setBackground(1)

$gameMessage.setPositionType(1)

$gameMessage.add('\\I[97] Mastery Up!')

}

This if statement is very important, as it is what sets the amount of exp needed to gain each level. I am using a statement that multiplies the current mastery level by 100 and checks the mastery exp against that to level. This is important because it means that all my actors' mastery levels must begin at 1 or there would be no value to check the exp against to level, 0 * 100 = 0. Feel free to use any value you'd like. Honestly, I am not sure how well this formula will play out in the long run but I feel like it will be easy enough to change if it becomes too grindy at high levels. That being said, the base increase for each successful is a mere 1 exp. I have yet to implement any bonus mastery gains, although I do have plans for this in the future, through other skills and maybe equips.


So just to recap,
($gameVariables.value(101) >= $gameVariables.value(111) * 100)

is used to check the actors exp after every gain and if it is more than 100 times the current mastery level, they gain a master level. So the first level is 100 exp, the second is 200 and so on.


Next,
$gameVariables.setValue(111, $gameVariables.value(111) + 1)

$gameVariables.setValue(101, 0)

when the actor gains a master level, add 1 to their mastery level and reset the mastery experience var back to 0.


user.startAnimation(122, false, 0)

$gameMessage.setFaceImage(user.faceName(), user.faceIndex())

$gameMessage.setBackground(1)

$gameMessage.setPositionType(1)

$gameMessage.add('\\I[97] Mastery Up!')
this code plays an animation on the actor, and shows a dim message box at the top of the screen that shows the icon for the weapon being used and simply says 'Mastery Up!' If you choose to use this part of the code, make sure you select the proper animation number from your animations list as well as the corresponding weapon icon.

That is the breakdown of the first case clause for actor 1's sword mastery. Each additional case clause will be nearly identical, you will only need to change the case clause to reflect the number of the actors who can use the weapon of the skill the notetag is attached to and then the number of the variables to match the actor referenced in the case clause.

I'm gonna stop here tonight, gotta get some rest. Tomorrow night I'll go into the notetags for the states, used to create custom passive conditions that make it so the states are automatically applied in correspondence with the actors' mastery levels and if the weapon type is equipped; as well as the weapon notetag to link each passive state to the weapons by type.
So for your purposes, you can simply make certain weapons require various masteries to equip.
 
Last edited:

Alkaline

Veteran
Veteran
Joined
Jun 30, 2020
Messages
31
Reaction score
3
First Language
English
Primarily Uses
RMMV
Oh wow! That's quite a bit, the coding part kinda lost me :kaoswt:. Thanks for the replies though!
 

RK DracoRoy

Fire Emblem RPG Gamer
Veteran
Joined
Jun 29, 2017
Messages
167
Reaction score
22
First Language
English
Primarily Uses
RMMV
@Alkaline My method involves increasing the weapon and armor rank only outside of battle, based on fighting enemies.

You need these six plugins to do this and have them in this order based on Yanfly's website: http://www.yanfly.moe/wiki/Category:Yanfly_Engine_Plugins#Plugin_List
--------------------------
- YEP_EquipCore: http://www.yanfly.moe/wiki/Equip_Core_(YEP)
- YEP_ChangeBattleEquip: http://www.yanfly.moe/wiki/Change_Battle_Equip_(YEP)
- YEP_EquipRequirements: http://www.yanfly.moe/wiki/Equip_Requirements_(YEP)
- YEP_JobPoints: http://www.yanfly.moe/wiki/Job_Points_(YEP)
- YEP_SkillLearnSystem: http://www.yanfly.moe/wiki/Skill_Learn_System_(YEP)
- Moogle_X_EquipSkillSystem (below Yanfly's plugins): https://forums.rpgmakerweb.com/index.php?threads/equip-skill-system.50858/
--------------------------

1) With MoogleX's rar file download, you only need two of them: EquipSkillSystem and EQS_SkillLearnPatch (place it underneath EquipSkillSystem).

1a) Create the blank skills and name them from "Sword E-Rank" to "Sword S-Rank" (You have to make this same set but with axe, lance, bow, magic, and any weapon type you got). Then place in the notetag <EQS Ignore> and that's that.

2) With YEP_SkillLearnSystem, place in the notetag on the actor's class. It can be a list of the set of weapon type rank skills you made for the actor to learn through the menu.
<Learn Skill: x, x, x> //Sword Rank skills

Make sure that the E-Rank skill of any weapon type is on each class's Skills to Learn list at Level 1. That way, in your game, they will be able to equip E-Rank swords at the start.

3) You need EquipCore for ChangeBattleEquip and EquipRequirements.

3a) ChangeBattleEquip is what you want so you can change weapons during battle.

3b) Now in the weapon database, create "Bronze Sword" and add in this requirement notetag.

Code:
<Custom Equip Requirement Condition>
if (user.skills().contains($dataSkills[x])) { // *Weapon Type* SS-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* S-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* A-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* B-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* C-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* D-Rank
condition = true;
} else if (user.skills().contains($dataSkills[x])) { // *Weapon Type* E-Rank
condition = true;
} else {
condition = false;
}
</Custom Equip Requirement Condition>
Example Tier List: Bronze Sword (E) -> Iron Sword (D) -> Steel Sword (C) -> Silver Sword (b) -> Brave Sword (A) -> Meisterschwert (S) -> Divine Sword (SS)

If your actor unlocked D-Rank, you can equip Bronze and Iron Sword. So with Iron Sword, use that same requirement notetag but take out the line referencing E-Rank, and so forth with a higher tier weapon. (e.g. Steel Sword: take out D-Rank, Silver: take out C-rank, etc.)

4) With JobPoints, you can get JP (or another name you can set like HM ("Hero Merit" from Fire Emblem Heroes) each time you engage in battle and they build up as you fight. That's how you're going to get stronger weapon ranks through earning JP.

4a) On Sword D-Rank to Sword SS-Rank, add in these two notetags.
<Learn Require Skill: x> //e.g. D requires E learned, C requires D learned, B needs C, etc.
<Learn Cost: x JP>

4b) Add <Starting JP: x> to the actor database, your actor.

Playtest
----------
If you have these plugins already and followed the steps, set the starting JP to 50 and the learn cost at 1.
Then start a playtest on a map. You don't have to battle, this is just to playtest and check that this works.

On the playtest, select "Skill" and then "Learn Skills". You've already learned E-rank, and D-rank is there, click it, now equip the weapon that requires the D-rank. Go back and then hit C-rank, you can equip the weapon requiring C-rank and so forth.

That's how I can imitate the weapon rank system set in Fire Emblem in some way. I can only do this in the menu if I have enough JP earned from battles. You can also do this with staves under the armor database.
 

slimmmeiske2

Little Red Riding Hood
Global Mod
Joined
Sep 6, 2012
Messages
7,009
Reaction score
4,747
First Language
Dutch
Primarily Uses
RMXP

I've moved this thread to Plugin Requests. Please be sure to post your threads in the correct forum next time. Thank you.

 

xDRAGOONx

Veteran
Veteran
Joined
Jan 22, 2019
Messages
170
Reaction score
140
First Language
English
Primarily Uses
RMMV
This is copy-pasted from a conversation I had w/ @xDRAGOONx:


So for your purposes, you can simply make certain weapons require various masteries to equip.
Thanks for the shout out @Frostorm !!!

On the system itself, it is definitely complicated but it was born out of a desire to be better with the javascript behind rpg maker. Working on things like this have definitely opened my eyes to just how much can be achieved, even without plugins when you really dive in to the code of the system!
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Currently without internet due to storm damage and most of our state is devastated. No idea how long I'll be unable to log onto here, but I'll answer questions as soon as I can.
This is supposed to be pso2 photon blast inspired animation
I'm sure this question's been asked before, but I can't find an answer: is there any way to run the Steam version of RPGMaker *without* being logged into Steam? It's a frustrating extra step sometimes.
Been seeing bright flashes in the sky for a while, and thought it was my eyes playing tricks on me. Nope! Lightning. Now it's raining heavily. Seeing lightning, but not hearing thunder, is weird.
Small Update for myself:
>Two Dungeon maps are done, Dungeon 3 is in progress. Dungeon 4 needs work.
>4 characters set up out of a possible 6 but those come later.
>Hub area needs work.
>Game completion..., 20-25% maybe?

Forum statistics

Threads
100,714
Messages
978,680
Members
132,330
Latest member
jakobwolf
Top