Welcome to your next quest.
All right.
So the next thing we need is for enemies to have an amount of XP that the attacker gets when slaying
that enemy.
So you're going to create an XP reward curve table and you can add curves for each class.
Next, you can decide how to add that to the data asset.
You could add scalable floats for each character class.
So decide if that's the way to go and then add a getter function in our aura ability system library
that takes in the class and the level and returns the amount of XP as the reward for slaying a character
of that class and level.
And then add a get character class function in the combat interface so we can implement that.
Now that means that we may have to take that character class variable out of the enemy class and put
that into the base character class.
So handle that as well.
Pause the video and conquer this quest now.
Okay, so we need a curve table.
I'm going to go into blueprints, ability system data, and we'll put our new curve table here.
So we'll go to miscellaneous curve table and I'm going to choose cubic for this and create this curve
table.
I'm going to call it CT underscore exp underscore reward.
So we have an exp reward data table and I'm going to rename the first curve to elementalist
and then I'll add another curve.
And this one can be for Ranger.
We'll have another curve and this will be for the warrior.
So each of these classes will be worth different amounts of experience based on their level.
The warrior can perhaps be worth the least amount of experience.
So I'm going to add a key to the warrior curve first.
And set its time value to one that's going to be for its level and the amount of experience that a warrior
can give.
I'll just make it 20 and I'm going to go ahead and zoom to fit so I can see it there.
And I'll add another key.
Now I'm going to add a key for level 40.
And at level 40, I think I'm going to make a warrior worth oh, a thousand.
Let's just put a value out there and I'm going to go ahead and go to normalized view mode so I can see
both keys here, select them both and make them auto.
And so here we can see the trend.
And I'm going to make it pretty much linear, but it's going to taper off and enemies will be worth
less and less the closer we get to level 40.
Now, this very much depends on the game.
Okay, So some games you're going to see larger numbers when you get up to these levels.
For some RPGs, 40 is a high level.
For other RPGs, 40 isn't that high, but I'm just going to pick 40.
We could easily have picked 100 or anything else.
But once we get to 40, it stays at 1000.
Now, for the Ranger, I'm going to add a new key.
This one is going to be at level one.
The ranger will give, let's say, 25 experience and we'll have one more key at level 40.
And at level 40, let's say the ranger gives 1500.
And just like for the warrior, I'm going to make it an auto curve and I'll give it just about the same
trend, pretty much linear, but it tapers off.
And for the elementalist we'll add two keys.
I'll just add them both.
Now, the first one will be for level one.
I'm going to make the Elementalist the most valuable enemy to kill.
I'll give it 35 exp at level one, and for level 40 we'll change this second key to a time value of
40.
At level 40, it's going to be worth 2500 and selecting both keys, making them auto.
And again, I'm going to have this shape for my curve and I'll go back to absolute view mode so I can
zoom out and take a look at these.
And they all look the same.
They just have slightly different values.
So now that we have this curve table, we need a way to get that curve table.
And where we're going to have it is our data asset.
So we're going to go to our character class info data asset, and we can see it right here.
And one of the things we could do is have a scalable float property in our class info struct.
That way each of these will have one and we can set them to the appropriate curve from the curve table.
Another option is to just have the curve table as we have our damage calculation coefficients curve
table.
We can remind ourselves how we're using that one by going back and searching our project for damage
calculation coefficients.
And we can see that we're using those in our exact calc.
So if we go to our damage execution calculation, we can see that we're getting the character class
info which we've created a nice getter for in our blueprint function library and accessing that curve
table, finding the curve based on the name and then evaluating that curve based on the level passed
in.
Now we could do that, although this does require us to specify an F name.
What would be easier if we could simply look up that curve as a scalable float and we know how to query
scalable floats, right?
We've done that in our aura projectile spell.
If we go to abilities and in the private folder or a projectile spell in abilities and we come down
here to our damage types, which is a T map, we're getting an F scalable float that's the pair in our
loop through the T map and calling get value at level.
So either way is okay.
I think I'd prefer to put a scalable float in our data asset for each of these.
And that way we're performing a lookup based on an enum rather than having to hardcode f names into
our code.
So what I'm going to do is add a scalable float into our data asset for each of our different character
classes.
So I'm going to go ahead and close my tabs, close my folders and open up my ability system data, character
class info, data asset.
And here we have character class default info where we can put a scalable float.
So I'm going to make an F scalable float.
And this is going to be XP reward.
We'll set it equal to a default scalable float.
But we're going to set this in blueprint with edit defaults only and give it the category of class defaults.
So now that our scalable float will exist in our data asset, we need an easy to use function to look
it up.
So we're going to open our aura ability system library and we're going to make a nice new static function
for this.
Now, this is going to return a value, isn't it?
We need to get the XP reward.
Now, since these exist on curves that may or may not be on exact integers, we'll go ahead and return
a float and then we can round that float as we see fit in our calculations.
So this will be a static function.
It'll return an int 32 and we're going to call this get XP reward for class and level.
And you could specify character class as this is the kind of class.
Now it's going to take an E character class.
And if we search for E character class here, we'll see that we're using it up here.
So we don't need to worry about including anything for character class.
So first is E character class.
Next is the level and we're going to use an int 32 for level.
We'll call this character level.
And because we're going to need to access our game mode to get that data asset, we're going to add
a world context object as we're going to need a world context object to use a gameplay statics function
to get the game mode.
So we have this function.
Let's go ahead and create a definition for it.
And first thing we need to get the game mode.
So I'm going to go ahead and cut this function definition and paste it somewhere up here where we're
doing something similar, where we're getting our data asset from the game mode.
Give startup abilities is a good example.
So I'm going to paste it right here and let's get this all on one line and the first thing I'm going
to do is look to give startup abilities to see how we got character class info.
Looks like we got character class info using get character class info.
One of our functions here, we can see it down there now it could return a null pointer.
So we're going to do a null check and return if it's null and if it's null, we'll go ahead and return
zero after that.
We have our character class info.
Now we need to perform a lookup in character class info.
Let's take a look at character class info dot h.
And I'm seeing red squiggles because F scalable float is incomplete, so we're definitely going to need
to include something for that.
Going to its definition.
It's in scalable float h.
If I hover over that, I see it's in gameplay ability slash public, so I should be able to just include
scalable float.
H So I'm going to go ahead and do that.
And that should take care of that.
But we came to this class so that we could take a look at how we can access XP reward that's scalable
float.
Now we know we have a team app filled with character class information that's struct and we have a function
to get character class info based on a character class.
We're going to use that function.
So we're going to take character class info.
And on character class info we want to call get class default info and that takes the character class.
We have that.
We're going to pass it in and spelling it carefully there.
Now this returns an F character class default info which we're going to store in a local F character
class default info, and we'll call this info.
So now that we have that struct, we can then access the scalable float.
And again we can see an example of how to evaluate a scalable float in or a projectile spell.
We see that a scalable float has getvalue at level.
That's what we want to do.
So we'll access that scalable float.
That's an info and it's called exp reward and we're going to call get value at level and the level we
need to pass in we have access to here, it's character level, the input parameter.
So we're going to pass that in and we now have a value.
Now that's a float.
So we'll say float exp reward.
And since we have this in the form of a float, we can just cast it to an integer and we'll lose any
information to the right of a decimal point.
But in this game, fractions of an experience point are not going to matter.
If they mattered in your game, you would make this a float returning function.
So I'm going to return a static cast to n 32.
XRP reward.
This can be a const and so can character class default info.
It can even be a const reference.
Okay, so now we have a get exp reward for class and level.
The last of our tasks is to create a nice getter function in the combat interface to get the character
class.
So let's go to our combat interface and interaction combat interface and make a function to return the
character class.
If we're going to use the character class enum type, we're going to have to include the file that it's
defined in.
We can figure out what that is by searching our project.
It's defined in character class info, So we'll go ahead and just include ability system slash data,
slash character class info dot h and we'll create a function that returns this type.
So we'll go all the way down to the bottom.
This function will return an E character class enum.
We're going to call this get character class
and it'll be a blueprint Native event Blueprint callable.
And we just need to override get character class implementation.
And let's go to Aura character base because if we search for character class here.
We actually don't see it.
That's because it's an enemy, isn't it?
We have a character class there.
Well, we could just put this in character base instead.
Let's do that.
I'm going to go ahead and cut it and move it into a character base and the protected section, we'll
put it right here and we'll also override the function on the combat interface.
So we'll say virtual character class, get character class implementation.
That's an override and we're going to have to include the character class info.
So we'll put that here in character base.
It was an aura enemy, actually.
Right there so we can cut that out of or an enemy put it in or a character base.
Now we can use the character class and let's go ahead and create the definition and return the character
class.
That way, if we ever need to get the character class of aura, we can.
But aura is going to be an Elementalist.
So really quickly, I'm just going to go to private character or a character, and in the constructor
I'm just going to set character class equal to E character class Elementalist.
Okay.
So that's going to conclude everything.
I think the last thing to do is to actually set the curve table in character class info, the data asset,
so we can do that.
Now let's go ahead and launch and debug mode.
So back in the editor.
Let's go to character class info.
And in each of our character classes it looks like we have XP reward.
Now I'm going to set the value to one, but use our XP reward curve table and set the curve for the
Ranger.
I'm selecting the Ranger curve for the warrior.
Same thing.
Setting it to one choosing XP reward.
But for the warrior we choose warrior and for the elementalist set it to one Choose XP reward and choose
elementalist.
Now they all have their scalable floats set.
Okay, we're one step closer now that we have defined amounts of experience for each of our enemy types
and an aura ability system library function that can take in a level and a character class.
We can then see what value we get when we slay one of these enemies.
So that's a very important component to experience.
Excellent job.
We'll continue in the next video.