Carpet

Carpet

2M Downloads

[scarpet suggestion] Custom damage events

anna-s-h opened this issue ยท 8 comments

commented

Moved to issue from #649 in order to stimulate feedback on the topic

The following is a quote from James103:

Even as of Carpet mod 1.4.20 for Minecraft 1.16.4, we still don't have a way to deal an arbitrary amount of any damage type to any entity, on behalf of any entity. I suggest that there be a function to do exactly this:

modify(e, 'damage', amount, source, source_entity)

Deals amount damage of type source to the target entity on behalf of source_entity and calls the appropriate __on_damaged (or __on_player_takes_damage) event if available. All vanilla damage types are supported (with corresponding effects and death messages), as well as custom damage types. source_entity is optional and defaults to null (to denote no source entity).
If the damage is nullified because the entity has already taken damage, the event is cancelled and no callbacks are made.

Example use cases:

You take constant fire damage while in the Nether:
modify(player, 'damage', 1, 'fire', null) or modify(player, 'damage', 1, 'fire')

Kill yourself and destroy all your equipped armor:
modify(player, 'damage', 9999, 'mob', player)

Instantly die once your hunger hits 0:
modify(player, 'damage', player~'health', 'starve', null) or modify(player, 'damage', player~'health', 'starve')

Reflect all damage you take back onto the attacker...:

__on_player_takes_damage(player, amount, source, source_entity) -> (
	modify(source_entity, 'damage', amount, source, player);
);

...and vice versa:

__on_player_deals_damage(player, amount, entity) -> (
	modify(player, 'damage', amount, 'thorns', entity);
);

Villagers attack you whenever you trade with them:

__on_player_trades(player, entity, buy_left, buy_right, sell) -> (
	modify(player, 'damage', 1, 'mob', entity);
);

A custom damage type example based on the above example

__on_player_trades(player, entity, buy_left, buy_right, sell) -> (
	modify(player, 'damage', 1, 'thorns_trade', entity);
);

Player was killed trying to trade with Farmer

As you can see, by having custom damage events, there are a lot more possibilities for challenge apps and datapacks that can damage the player and/or entities in a whole manner of different ways. Any thoughts on this?

That concludes the quote.
This is still an issue in 1.17. Also, the existing ways to damage mobs do not cause graphical effect, sound, or knockback, although the latter two can be added afterward.

commented

Actually, scrap the custom damage sources. Instead, custom damage events can only use vanilla damage sources found on this list (Origins wiki). Any unknown damage source will throw an UNKNOWN_DAMAGE_SOURCE exception.

commented

custom damage type could be created by a list_of_damage_flags.
such as by_pass_armor....
what do you think?

commented

my suggestion: use a list to specific damage source here.

if i want to use game's preset damage type. the first element will be a string. eg
['arrow',projectile_entity_value,attacker_nullable_entity_value]
['lava']
if i want to creat a new damage type, the first element will be a list.
[['my.damage.type.trans.key','victim','attacker','weapon'],projectile_nullable_entity_value,attacker_nullable_entity_value,'Flag_fire','Flag_exhaustion=0.1','Flag_magic']
if there is some of 'victim','attacker','weapon' in the inner list, those will be passed in to translation in that order.
if there is 'Flag_xxx' in the end, the source will have this attribute.

after that, use modify(entity, 'damage', amont, damagesource) to damage a entity

commented

Minecraft snapshot version 23w06a includes data-driven damage types and a new /damage command, checking off pretty much this entire proposal (aside from a Scarpet implementation of the new command).

To be more specific and quoting from the patch notes:

  • Custom damage types: "Damage Types are a new registry that can be extended through data packs. A Damage Type determines how damage is handledby the game. This includes which attributes the damage has as well as which death message is used when an entity diesdue to that type of damage" [sic]
  • /damage command: "New command to apply damage to entities." The command can specify the amount and type of damage to inflict, with optional parameters for the location of origin for the damage, the direct source of the damage, and the indirect source of the damage. All that is left is to implement this as one or more Scarpet methods.
commented

Minecraft snapshot version 23w06a includes data-driven damage types and a new /damage command, checking off pretty much this entire proposal (aside from a Scarpet implementation of the new command).

yes. there are some rewrites in damage types. it used to have many attributes (such as is_fire), but now they becomes tags.

maybe callbacks of on_damaged & __on_player_takes_damage & __on_player_deals_damage should have a new parameter for the damage_type. but i worry about that would break all carpet scripts write before.

if it will be added, it could be a string. "minecraft:lightning_bolt".
or it could be a list, besides the string above, it has a list of all the tags it is in as well. ["minecraft:lava",["#is_fire"]]

commented

might be good to specify all possible 'source' values here as well - DamageSource has an extensive list, but doesn't lists thorns_trade unless I read it wrong and this is something that could be set by datapacks, which in that case, would require to add another function to return available damage sources (tempted to shove it into the system_info world category)

commented

A resource pack can set translation strings for any arbitrary damage source (or even any translation string) via edits to the en_us.json, en_uk.json, and similar files. For example, the following resource pack renames End Stone to "Anti-Stone" and provides translation strings for the thorns_trade damage source:
test_custom_damage_source.zip

Test the translation string for the custom damage source with the following command:
tellraw @s {"translate":"death.attack.thorns_trade"}

It would still be nice to have a list of default damage sources, for which no new translation strings need to be provided in order to avoid the user needing to install a resource pack to provide these translation strings.

commented

can the datapck creation tool be used to generate the resources within the app? That would make this custom damage source thing even handier.