• Hello Guest! Did you know that ProjectKorra has an official Discord server? A lot of discussion about the official server, development process, and community discussion happens over there. Feel free to join now by clicking the link below.

    Join the Discord Server

How to differentiate between ProjectKorra damage and the EntityDamageByEntityEvent

Jonathon594

New Member
So I have my own plugin which I have been working on for a while and everything is working pretty flawlessly. However; I have it so that doing damage with bending levels the respective bending skills. This works perfectly fine with the BendingAbilityDamageEvent I believe its called. Something like that. The problem is that my other skills like Swords, Axes, Unarmed etc are leveled up on the EntityDamageByEntityEvent. The way ProjectKorra does its damage is by LivingEntity.damage() I believe which calls an EntityDamageByEntityEvent. So the issue I am having is that for example if I shoot a fireblast, and then switch my hotbar to a sword. When the skill impacts the server believes that I damaged the target via melee and because I am currently holding a sword it levels the sword skill. My current fix is to add a cooldown on melee experience everytime the player does a bending move. It works but its not as clean as I'd like. Is there a way to tell the difference between Bending and Melee on the EntityDamageByEntityEvent? I see in the source code that the entities last damage reason is being set, and I was checking that but it seems to be unreliable.
 

Gareth Swan

Verified Member
I believe how I have done it in the past, and might work for you is using the
DamageHandler. If you need more assistance, feel free to pm me.

Regards
 

Loony

Verified Member
So I have my own plugin which I have been working on for a while and everything is working pretty flawlessly. However; I have it so that doing damage with bending levels the respective bending skills. This works perfectly fine with the BendingAbilityDamageEvent I believe its called. Something like that. The problem is that my other skills like Swords, Axes, Unarmed etc are leveled up on the EntityDamageByEntityEvent. The way ProjectKorra does its damage is by LivingEntity.damage() I believe which calls an EntityDamageByEntityEvent. So the issue I am having is that for example if I shoot a fireblast, and then switch my hotbar to a sword. When the skill impacts the server believes that I damaged the target via melee and because I am currently holding a sword it levels the sword skill. My current fix is to add a cooldown on melee experience everytime the player does a bending move. It works but its not as clean as I'd like. Is there a way to tell the difference between Bending and Melee on the EntityDamageByEntityEvent? I see in the source code that the entities last damage reason is being set, and I was checking that but it seems to be unreliable.
This is something I brought up with our team just yesterday and it is something we want to fix, but right now it's just about other things being priority.
@OmniCypher please comment.
 

OmniCypher

Staff member
Lead Developer
Administrator
Plugin Developer
Hello @Jonathon594, The cleanest way to do what you are asking would be to utilize the EntityDamageByEntityEvent#getCause(). We mark our bending damage as DamageCause.CUSTOM so you could easily add a check in your listener. This isn't perfect, however, in order to verify the custom damage is actually bending damage you will need to utilize our custom event AbilityDamageEntityEvent. It is important to note that this would only be necessary if you had another plugin on your server that utilized custom damage causes.

Example:
Code:
@EventHandler
    public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
        if (event.getCause() == DamageCause.CUSTOM) {
           // Possibly bending damage.
        } else {
           // Some form of vanilla damage.
        }
    }
You should be able to accomplish everything you are set out for with my explanation above, but, I see now that there is a bit of a gap between the two events, in the future, it is possible we will link our AbilityDamageEntityEvent with the EntityDamageByEntityEvent or implement some sort of comparator utility to form a more rigid connection between the two.
 

Jonathon594

New Member
I actually recently decided to move away from project korra in my server, however I decided to check the out just to see if it would have worked. The events damage cause is always EntityAttack. In your DamageHandler you created a an EntityDamageByEntityEvent and set its cause to custom, but never called the event. which is good because it would have been doubled. however, You set the entities last damage cause to that event. however I belive it is getting overwritten by the event called from LivingEntity#Damage() because checking the entities last damage cause (Event) then checking its cause is randomly custom or entityattack. Just thought I would let you know about that.
 

Gareth Swan

Verified Member
With all of my abilities, I just use
Code:
        for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location,
                collisionRadius)) {
            if (entity instanceof Entity) {
                DamageHandler.damageEntity(entity, player, damage, this);
               
            }
and then specify the damage of it in the config. Seems to work just fine for me.

Regards
 

Finn_Bueno_

Staff member
Plugin Developer
Verified Member
With all of my abilities, I just use
Code:
        for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location,
                collisionRadius)) {
            if (entity instanceof Entity) {
                DamageHandler.damageEntity(entity, player, damage, this);
              
            }
and then specify the damage of it in the config. Seems to work just fine for me.

Regards
That's not what the OP asked for at all.
 

Finn_Bueno_

Staff member
Plugin Developer
Verified Member
I was just saying what I used, please stop posting irrelevant things I already know.

Regards.
But it has nothing to do with the question. I could go around saying I use Prodent toothpaste to brush my teeth but nobody would get better from it. The OP asks how to differentiate between Bending damage and actual minecraft damage in the EntityDamageByEntityEvent.
 

MeskenasBoii

Verified Member
Using a toothpaste as a comparision doesn't work when you're comparing technical question and with somebody offering a workaround. If Gareth's is making an "irrelevant" reply, how come you didn't called out Omni on that lecture?
;)
 

Gareth Swan

Verified Member
@MeskenasBoii in the kindest way possible, there isn't really no need to reply to the thread anymore unless it's based around the subject of discussion, therefore differentiating between ProjectKorra Damage and EntityDamageByEntityEvent.

Regards
 

RoboMWM

Verified Member
The way ProjectKorra does its damage is by LivingEntity.damage() I believe which calls an EntityDamageByEntityEvent.
Yup, and unless PK does it another way (e.g. setHealth and related - please don't do this btw), this will call a damage event. To detect and ignore PK damage in my plugin, I just listen to BendingAbilityDamageEvent, and set metadata to the player affected. Then in the entitydamageevent listener, I check for this metadata - if it's there, I remove it and return. https://github.com/MLG-Fortress/MountainDewritoes/blob/master/src/main/java/me/robomwm/MountainDewritoes/NoKnockback.java#L47
(I should probably also have this listener fire even if the event is canceled, since I'd still want to remove the metadata regardless if the damage was canceled or not.)

Alternatively, you can also mark the entity and ignore damageevents towards this entity for the current tick, which is what I used to do.


We mark our bending damage as DamageCause.CUSTOM so you could easily add a check in your listener.
You can't change the event that comes from Entity#damage unfortunately, afaik. You do however mark it after the fact in player#setlastdamagecause

This is something I brought up with our team just yesterday and it is something we want to fix
In my opinion, the best way to fix this is to fire an invisible projectile entity with whichever bending element - or just use this created projectile as the source when calling Entity#damage (provided that it calls EntityDamageByEntity with cause as projectile). Not perfect, but it does avoid all the anticheat issues when using the attacker as the source entity, and this Projectile entity can have metadata indicating it's from a PK ability.

The only other option I can see worth trying is sticking the BendingAbilityDamageEvent (or whatever you wish) as metadata, which you set right before calling Entity#damage and then remove afterwards.

I was just saying what I used, please stop posting irrelevant things I already know.

Regards.
Your reply is correctly pointed out as irrelevant to this discussion because he is not trying to apply bending damage; instead he is attempting to detect and ignore bending damage.
 
Last edited:

Gareth Swan

Verified Member
Yup, and unless PK does it another way (e.g. setHealth and related - please don't do this btw), this will call a damage event. To detect and ignore PK damage in my plugin, I just listen to BendingAbilityDamageEvent, and set metadata to the player affected. Then in the entitydamageevent listener, I check for this metadata - if it's there, I remove it and return. https://github.com/MLG-Fortress/MountainDewritoes/blob/master/src/main/java/me/robomwm/MountainDewritoes/NoKnockback.java#L47
(I should probably also have this listener fire even if the event is canceled, since I'd still want to remove the metadata regardless if the damage was canceled or not.)

Alternatively, you can also mark the entity and ignore damageevents towards this entity for the current tick, which is what I used to do.



You can't change the event that comes from Entity#damage unfortunately, afaik. You do however mark it after the fact in player#setlastdamagecause


In my opinion, the best way to fix this is to fire an invisible projectile entity with whichever bending element - or just use this created projectile as the source when calling Entity#damage (provided that it calls EntityDamageByEntity with cause as projectile). Not perfect, but it does avoid all the anticheat issues when using the attacker as the source entity, and this Projectile entity can have metadata indicating it's from a PK ability.

The only other option I can see worth trying is sticking the BendingAbilityDamageEvent (or whatever you wish) as metadata, which you set right before calling Entity#damage and then remove afterwards.


Your reply is correctly pointed out as irrelevant to this discussion because he is not trying to apply bending damage; instead he is attempting to detect and ignore bending damage.
Interesting reply. You covered a lot of ground, it was interesting to read! As loony said, it is something we want to fix.

Regards
 

RoboMWM

Verified Member
As loony said, it is something we want to fix.
Well, not so much "fix" than perhaps make it a bit easier for other plugins to detect as such/broadcast that this is a PK damage event. Unless you do some NMS hackery, the damage cause will be an entity.

(mcMMO faces a similar situation as well - they fire a FakeEntityDamageEvent which extends EntityDamageByEntityEvent. I do not know if this interferes/causes issues with plugins watching this (it seems it does, since cnpc is required for compatibility with NCP), as I have just simply disabled mcMMO for PvP - but I'm guessing it's used for bleeding damage and related).

Since most abilities spawn particles or move blocks, teleporting/adding velocity to an invisible projectile might be a good way to go about it, though I haven't delved into how ability "hitboxes" function (nor have I tested Entity#damage(int, sourceEntity) with a projectile as the source entity). Otherwise, the metadata idea would make it easy for plugins only looking for this, since they wouldn't need to add PK as a dependency.
 
Last edited:
Top