Welcome back.
We now have a melee attack ability that draws debug spheres.
How exciting.
Now we want to do more than that.
We want to cause damage at least.
Right?
So let's take a look at our current state.
Our melee enemy comes up to us and hits us and we know that it's got all live players within radius
because we're drawing a debug sphere at those players locations.
So we have Aura.
Now we want to cause damage, which means we want to apply a gameplay effect.
And we know that our melee attack is based on aura melee attack, which is based on aura damage ability
actually, or a damage gameplay ability is what it's called and that in turn is based on aura gameplay
ability.
Now, because of this inheritance hierarchy, we have a damage effect class that we can set and we've
created this damage effect, which is actually pretty nice.
I'm going to set this damage effect class to damage effect.
Why?
Because if we browse to it and open it up, we'll see that this is a gameplay effect with instant duration,
with no modifiers.
That takes a calculation class and we're using exec calc damage.
Now, what exec calc damage does is it loops through all of the damage types that exist.
So if we go to exec calc damage and take a look at execute implementation, we have this for loop that
loops through the damage types to resistances map and we have damage types and resistance gameplay tags.
And for each of these we attempt to get the set by caller magnitude for that damage type and then we
add that to the damage that's going to be subtracted from the health of the target.
So if we add a set by caller magnitude to a gameplay effect where the key is one of the damage types,
it will be taken into account in this exact calc.
And in fact the resistance will be captured from the target and we'll have a little bit of damage reduction
for the resistance.
So the cool thing is all we have to do is use this G damage type and apply a set by caller magnitude
to it.
So that's pretty handy.
So really all we'd have to do is create a gameplay effect spec so we can use make outgoing spec and
notice that the ability class, the gameplay ability has a function.
Make outgoing gameplay effects spec.
We've seen that we can take an ability system component and call make outgoing spec, but the ability
itself has this function make outgoing gameplay effects spec.
Now that's because the ability knows how to access its own ability system component.
It's smart enough to do that.
Now we can use a gameplay effect class and our class default has damage effect class.
If we search for it damage effect class, we can get it because we exposed it to the event graph and
we can set its level if we like.
We're going to leave it at one because our damage gameplay effect does not depend on level at all.
Now, once we've created the outgoing gameplay effects spec, we can apply a set by caller magnitude
by calling, assign tag set by caller magnitude and that requires a gameplay tag.
Now, if this is a melee attack, then the set by caller magnitude will take the damage type tag and
that damage type tag will be damage physical because it's a melee attack.
Now we also need to know how much damage to cause, don't we?
Well, we do have in our class defaults damage types, which is an array.
And in the array we can add an element and each element has a key that's a gameplay tag and a value
that's a scalable float.
The key is going to be the damage type.
So we're going to add physical here and the value is going to use a curve table.
Now we have CT damage, but we have to select a curve and we only have a curve for Firebolt.
So what we can do is we can add a curve for damage for Melee.
Now it's up to you if you want multiple damage curves for melee, for different types of warriors,
you can get as complex as you like with this, but I'm going to browse to CT damage and I'm going to
add a curve and I'm going to call this curve.
I'm going to rename it to Abilities Dot Melee, and I'm just going to add a new key here for level one
and it's going to be five.
And I'm going to zoom out.
I'm going to add another key.
It's going to be for level.
To and I'd like it to be 7.5 damage like that.
And I think I'll go ahead and just make one last key.
It's going to be for level, let's say 40 and we'll make it 50 damage.
So we have a trend like this.
And if we want, we can make this a smooth curve by changing it to auto.
If we want to do that and we can even mess with it.
So it looks something like this, that's fine.
But now we have a damage curve for melee, so we can save this and go back to melee attack and we can
select the melee curve.
And now we have our damage types.
So what we could do here is we can loop through damage types and we can assign the set by column magnitude.
So this is something that I think should be just inherent in or a damage gameplay ability.
There should just be a function called cause damage that will loop through all of our damage types.
It will take an effect spec and assign all the set by column magnitudes and just apply that gameplay
effect to some target.
I think that that is something that we should just have built in.
So what we can do is we can go into aura damage gameplay ability and we can make a function here for
that.
This can be a public function and it's going to just be a function for causing damage.
So we're going to say void cause damage and it'll just take an actor pointer called Target.
We'll call it Target actor.
Now this will be a new function.
I'm going to make it blueprint callable and cause damage is going to take care of all that stuff that
I was just talking about.
Loop over all of the damage types.
We have this team map called damage types.
I'd like to loop over all of the pairs in this and assign a set by color magnitude to an effect spec.
So the first thing I need to do is make that effect spec, right?
So we saw that the gameplay ability class has make outgoing gameplay effects spec.
This requires a gameplay effect class and our damage gameplay ability has that.
It's a damage gameplay effect class.
We're going to pass that in.
It requires a level.
We're not going to worry about a level we're going to pass in one and we'll store this in a local variable
and it's a spec handle.
So we're going to say EF gameplay effect spec handle.
We'll call it damage spec handle and we just need to loop over our damage.
Types.
Team map.
So we're going to say for we know this is a T tuple and it's mapping F gameplay tag to a scalable float,
right?
F scalable float.
So we're going to call this pair and it's in damage types.
And for each of these pairs, we're going to assign a set by caller magnitude using this gameplay tag
for damage type.
Now we assign a tag set by caller magnitude with you ability system blueprint library.
So we get that include included and we're going to call assign tag set by caller magnitude, which requires
a spec handle.
We're going to pass in damage spec handle.
It requires a gameplay tag we're going to pass in pair key and the last input is the magnitude itself.
So we need a float called damage magnitude and we can get that from our scalable float.
Now how do we do that?
Well, if we go back to Aura Projectile Spell, we can see how we did it there.
We looped through damage types.
We got a const float called Scaled Damage and we evaluated the curve at the level of the ability.
I'm just going to copy that line and come back to our damage ability and just paste it here.
So we'll just call it scaled damage and we'll pass that in as the magnitude.
So we're looping through all the damage types that exist in our map of tags to scalable floats in our
ability.
And once we've done all that, we can apply that ability to the target actor.
So we need the ability system component of the target actor of course.
So we're going to access you ability system blueprint library, get ability system component passing
in target actor So we have the ability system component and then we can apply the gameplay effect.
Now we can apply the gameplay effect to self on this ability system component, or we can get the ability
system component that owns this ability with get ability system component from actor info and from this
we can call apply gameplay effect spec to target.
And for this function we pass in the gameplay effect spec and the ability system component.
So for the effects back we have our spec handle we need to take damage spec handle dot data dot get
remember data is the gameplay effect spec and that's a pointer.
So we have to dereference it and for the AC we're going to pass in the target AC.
And this function will then result in applying that damage gameplay effect to the target.
So now that we have this cause damage function, we can call it here in our gameplay effect.
So we don't need these three nodes anymore.
All we have to do is call it here, but I have to close the editor and compile and launch again.
So I'm going to save all and run this from writer hitting debug.
And we'll go ahead and open up our melee attack.
And as we loop through all the live players within radius, we can cause damage.
So we have our now blueprint callable function caused damage.
We'll do this in the loop body to all players within radius using the array element.
That's the actor passing that in.
We don't need the actor location anymore.
We're now causing damage instead.
And because our class defaults are set, we have our damage types, we have our damage effect class.
We should see five damage being caused with each hit of the spear.
Let's save this.
Let's save all actually and press play.
And let's let that enemy come over and hit us and look at our health globe.
Hopefully it changes and it does.
So as we get hit from the spear, we see our damage be taken and our health goes down.
Now, here's the cool thing.
This enemy starts off at level one, but if we change that, let's search for level and its details
panel and I change it to say 40.
Well, we know that our gameplay ability is granted at the level of the enemy, which means this melee
attack will now be level 40 and at level 40 we should be causing 50 damage thanks to our handy slider
for the preview for this scalable float.
So let's see if we take 50 damage now.
Here comes the little guy and boom, 50 damage.
Excellent.
All right.
So I'm going to stick this guy's level down, back to one, and we're done.
Now, there's one actually, last thing that I noticed is that we're not actually getting those floating
text damage numbers when Aura gets hit.
So let's just find out why real quick.
Now we're showing the damage numbers in aura attributes set.
So if we go to Aura, attribute set and take a look at show floating text, let's see why we're not
getting auras damage numbers when she gets hit.
Well, for one, we're checking the source character.
That's the character causing the damage.
The Target character is the character getting hit.
So we're actually using the player controller of the source character.
We're actually casting that to or a player controller that will fail for the enemies.
So we actually need to do this for the target character as well.
So if the source character cast to or a player controller fails, then we won't make it inside this
if statement.
And if that happens, I'd like to cast for our target character.
So I'm going to copy the If statement, but change what we're casting.
We're going to cast Target character instead and then everything else will be the same.
And if we make it into the first if statement, well, that means that the source character is the player
controlled character.
So we don't need to continue at that point.
We'll just return.
So if we make it inside here, we'll show the damage number because the damage causer is the player
controlled character.
But if we don't make it inside this one, that means the damage causer is an enemy, at which point
we'll cast the target of the damage.
We'll get that player controller and show the damage number for that.
So this should fix everything.
We should see damage numbers when Ora gets hit by a goblin.
Let's try it out.
Okay, I'm going to go ahead and press play and get hit.
And there's the damage number.
Looks like we're suppressing some of that damage because we have some physical damage, resistance.
And this is physical damage, after all.
Looks like I just got a block there, too.
Cool.
All right.
So things are looking pretty good.
We still have some work to do and we'll continue with this in the next video.
I'll see you soon.