Improve damage type
This commit is contained in:
parent
ec0e8a723a
commit
5c5bc67b3a
@ -1,8 +1,9 @@
|
|||||||
use heck::{ToPascalCase, ToShoutySnakeCase};
|
use heck::ToShoutySnakeCase;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use syn::LitInt;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct DamageTypeEntry {
|
struct DamageTypeEntry {
|
||||||
@ -30,9 +31,8 @@ pub(crate) fn build() -> TokenStream {
|
|||||||
|
|
||||||
for (name, entry) in damage_types {
|
for (name, entry) in damage_types {
|
||||||
let const_ident = format_ident!("{}", name.to_shouty_snake_case());
|
let const_ident = format_ident!("{}", name.to_shouty_snake_case());
|
||||||
let enum_ident = format_ident!("{}", name.to_pascal_case());
|
|
||||||
|
|
||||||
enum_variants.push(enum_ident.clone());
|
enum_variants.push(const_ident.clone());
|
||||||
|
|
||||||
let data = &entry.components;
|
let data = &entry.components;
|
||||||
let death_message_type = match &data.death_message_type {
|
let death_message_type = match &data.death_message_type {
|
||||||
@ -43,27 +43,19 @@ pub(crate) fn build() -> TokenStream {
|
|||||||
let exhaustion = data.exhaustion;
|
let exhaustion = data.exhaustion;
|
||||||
let message_id = &data.message_id;
|
let message_id = &data.message_id;
|
||||||
let scaling = &data.scaling;
|
let scaling = &data.scaling;
|
||||||
let id = entry.id;
|
let id_lit = LitInt::new(&entry.id.to_string(), proc_macro2::Span::call_site());
|
||||||
|
|
||||||
constants.push(quote! {
|
constants.push(quote! {
|
||||||
pub const #const_ident: DamageTypeData = DamageTypeData {
|
pub const #const_ident: DamageType = DamageType {
|
||||||
death_message_type: #death_message_type,
|
death_message_type: #death_message_type,
|
||||||
exhaustion: #exhaustion,
|
exhaustion: #exhaustion,
|
||||||
message_id: #message_id,
|
message_id: #message_id,
|
||||||
scaling: #scaling,
|
scaling: #scaling,
|
||||||
id: #id,
|
id: #id_lit,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let enum_arms = enum_variants.iter().map(|variant| {
|
|
||||||
let const_name = variant.to_string().to_shouty_snake_case();
|
|
||||||
let const_ident = format_ident!("{}", &const_name);
|
|
||||||
quote! {
|
|
||||||
DamageType::#variant => &#const_ident,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let type_name_pairs = enum_variants.iter().map(|variant| {
|
let type_name_pairs = enum_variants.iter().map(|variant| {
|
||||||
let name = variant.to_string();
|
let name = variant.to_string();
|
||||||
let name_lowercase = name.to_lowercase();
|
let name_lowercase = name.to_lowercase();
|
||||||
@ -73,25 +65,9 @@ pub(crate) fn build() -> TokenStream {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let type_to_name_pairs = enum_variants.iter().map(|variant| {
|
|
||||||
let name = variant.to_string();
|
|
||||||
let name_lowercase = name.to_lowercase();
|
|
||||||
let resource_name = format!("minecraft:{}", name_lowercase);
|
|
||||||
quote! {
|
|
||||||
Self::#variant => #resource_name
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create array of all variants for values() method
|
|
||||||
let variant_array = enum_variants.iter().map(|variant| {
|
|
||||||
quote! {
|
|
||||||
DamageType::#variant
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct DamageTypeData {
|
pub struct DamageType {
|
||||||
pub death_message_type: Option<&'static str>,
|
pub death_message_type: Option<&'static str>,
|
||||||
pub exhaustion: f32,
|
pub exhaustion: f32,
|
||||||
pub message_id: &'static str,
|
pub message_id: &'static str,
|
||||||
@ -99,27 +75,8 @@ pub(crate) fn build() -> TokenStream {
|
|||||||
pub id: u32,
|
pub id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#(#constants)*
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub enum DamageType {
|
|
||||||
#(#enum_variants,)*
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DamageType {
|
impl DamageType {
|
||||||
pub const fn data(&self) -> &'static DamageTypeData {
|
#(#constants)*
|
||||||
match self {
|
|
||||||
#(#enum_arms)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = r" Get all possible damage types"]
|
|
||||||
pub fn values() -> &'static [DamageType] {
|
|
||||||
static VALUES: &[DamageType] = &[
|
|
||||||
#(#variant_array,)*
|
|
||||||
];
|
|
||||||
VALUES
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = r" Try to parse a damage type from a resource location string"]
|
#[doc = r" Try to parse a damage type from a resource location string"]
|
||||||
pub fn from_name(name: &str) -> Option<Self> {
|
pub fn from_name(name: &str) -> Option<Self> {
|
||||||
@ -129,12 +86,6 @@ pub(crate) fn build() -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = r" Get the resource location string for this damage type"]
|
|
||||||
pub const fn to_name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
#(#type_to_name_pairs,)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,11 +14,13 @@ pub struct DamageTypeArgumentConsumer;
|
|||||||
|
|
||||||
impl GetClientSideArgParser for DamageTypeArgumentConsumer {
|
impl GetClientSideArgParser for DamageTypeArgumentConsumer {
|
||||||
fn get_client_side_parser(&self) -> ArgumentType {
|
fn get_client_side_parser(&self) -> ArgumentType {
|
||||||
ArgumentType::ResourceLocation
|
ArgumentType::Resource {
|
||||||
|
identifier: "damage_type",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_client_side_suggestion_type_override(&self) -> Option<SuggestionProviders> {
|
fn get_client_side_suggestion_type_override(&self) -> Option<SuggestionProviders> {
|
||||||
Some(SuggestionProviders::AskServer)
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,15 +32,12 @@ impl ArgumentConsumer for DamageTypeArgumentConsumer {
|
|||||||
_server: &'a Server,
|
_server: &'a Server,
|
||||||
args: &mut RawArgs<'a>,
|
args: &mut RawArgs<'a>,
|
||||||
) -> Option<Arg<'a>> {
|
) -> Option<Arg<'a>> {
|
||||||
let s = args.pop()?;
|
let name = args.pop()?;
|
||||||
|
|
||||||
// Create a static damage type first
|
// Create a static damage type first
|
||||||
let damage_type = DamageType::from_name(s)?;
|
let damage_type = DamageType::from_name(name)?;
|
||||||
// Find matching static damage type from values array
|
// Find matching static damage type from values array
|
||||||
DamageType::values()
|
Some(Arg::DamageType(damage_type))
|
||||||
.iter()
|
|
||||||
.find(|&&dt| std::mem::discriminant(&dt) == std::mem::discriminant(&damage_type))
|
|
||||||
.map(Arg::DamageType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn suggest<'a>(
|
async fn suggest<'a>(
|
||||||
@ -47,18 +46,13 @@ impl ArgumentConsumer for DamageTypeArgumentConsumer {
|
|||||||
_server: &'a Server,
|
_server: &'a Server,
|
||||||
_input: &'a str,
|
_input: &'a str,
|
||||||
) -> Result<Option<Vec<CommandSuggestion>>, CommandError> {
|
) -> Result<Option<Vec<CommandSuggestion>>, CommandError> {
|
||||||
// Get all available damage types
|
Ok(None)
|
||||||
let suggestions = DamageType::values()
|
|
||||||
.iter()
|
|
||||||
.map(|dt| CommandSuggestion::new(dt.to_name().to_string(), None))
|
|
||||||
.collect();
|
|
||||||
Ok(Some(suggestions))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefaultNameArgConsumer for DamageTypeArgumentConsumer {
|
impl DefaultNameArgConsumer for DamageTypeArgumentConsumer {
|
||||||
fn default_name(&self) -> &'static str {
|
fn default_name(&self) -> &'static str {
|
||||||
"damageType"
|
"damage_type"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,7 +101,7 @@ pub enum Arg<'a> {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
Simple(&'a str),
|
Simple(&'a str),
|
||||||
SoundCategory(SoundCategory),
|
SoundCategory(SoundCategory),
|
||||||
DamageType(&'a DamageType),
|
DamageType(DamageType),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// see [`crate::commands::tree::builder::argument`] and [`CommandTree::execute`]/[`crate::commands::tree::builder::NonLeafNodeBuilder::execute`]
|
/// see [`crate::commands::tree::builder::argument`] and [`CommandTree::execute`]/[`crate::commands::tree::builder::NonLeafNodeBuilder::execute`]
|
||||||
|
|||||||
@ -82,9 +82,9 @@ impl CommandExecutor for DamageLocationExecutor {
|
|||||||
|
|
||||||
let damage_type = args
|
let damage_type = args
|
||||||
.get(ARG_DAMAGE_TYPE)
|
.get(ARG_DAMAGE_TYPE)
|
||||||
.map_or(DamageType::Generic, |arg| match arg {
|
.map_or(DamageType::GENERIC, |arg| match arg {
|
||||||
Arg::DamageType(dt) => **dt,
|
Arg::DamageType(dt) => *dt,
|
||||||
_ => DamageType::Generic,
|
_ => DamageType::GENERIC,
|
||||||
});
|
});
|
||||||
|
|
||||||
let location = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
|
let location = Position3DArgumentConsumer::find_arg(args, ARG_LOCATION)?;
|
||||||
@ -122,9 +122,9 @@ impl CommandExecutor for DamageEntityExecutor {
|
|||||||
|
|
||||||
let damage_type = args
|
let damage_type = args
|
||||||
.get(ARG_DAMAGE_TYPE)
|
.get(ARG_DAMAGE_TYPE)
|
||||||
.map_or(DamageType::Generic, |arg| match arg {
|
.map_or(DamageType::GENERIC, |arg| match arg {
|
||||||
Arg::DamageType(dt) => **dt,
|
Arg::DamageType(dt) => *dt,
|
||||||
_ => DamageType::Generic,
|
_ => DamageType::GENERIC,
|
||||||
});
|
});
|
||||||
|
|
||||||
let source = EntityArgumentConsumer::find_arg(args, ARG_ENTITY).ok();
|
let source = EntityArgumentConsumer::find_arg(args, ARG_ENTITY).ok();
|
||||||
|
|||||||
@ -50,7 +50,7 @@ impl HungerManager {
|
|||||||
} else if level == 0 {
|
} else if level == 0 {
|
||||||
self.tick_timer.fetch_add(1);
|
self.tick_timer.fetch_add(1);
|
||||||
if self.tick_timer.load() >= 80 {
|
if self.tick_timer.load() >= 80 {
|
||||||
player.living_entity.damage(1.0, DamageType::Starve).await;
|
player.living_entity.damage(1.0, DamageType::STARVE).await;
|
||||||
self.tick_timer.store(0);
|
self.tick_timer.store(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -81,7 +81,7 @@ impl LivingEntity {
|
|||||||
cause: Option<&Entity>,
|
cause: Option<&Entity>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Check invulnerability before applying damage
|
// Check invulnerability before applying damage
|
||||||
if self.entity.is_invulnerable_to(damage_type) {
|
if self.entity.is_invulnerable_to(&damage_type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ impl LivingEntity {
|
|||||||
.world
|
.world
|
||||||
.broadcast_packet_all(&CDamageEvent::new(
|
.broadcast_packet_all(&CDamageEvent::new(
|
||||||
self.entity.entity_id.into(),
|
self.entity.entity_id.into(),
|
||||||
damage_type.data().id.into(),
|
damage_type.id.into(),
|
||||||
source.map(|e| e.entity_id.into()),
|
source.map(|e| e.entity_id.into()),
|
||||||
cause.map(|e| e.entity_id.into()),
|
cause.map(|e| e.entity_id.into()),
|
||||||
position,
|
position,
|
||||||
@ -156,7 +156,7 @@ impl LivingEntity {
|
|||||||
.play_sound(Self::get_fall_sound(fall_distance as i32))
|
.play_sound(Self::get_fall_sound(fall_distance as i32))
|
||||||
.await;
|
.await;
|
||||||
// TODO: Play block fall sound
|
// TODO: Play block fall sound
|
||||||
self.damage(damage, DamageType::Fall).await; // Fall
|
self.damage(damage, DamageType::FALL).await; // Fall
|
||||||
} else if height_difference < 0.0 {
|
} else if height_difference < 0.0 {
|
||||||
let distance = self.fall_distance.load();
|
let distance = self.fall_distance.load();
|
||||||
self.fall_distance
|
self.fall_distance
|
||||||
|
|||||||
@ -357,9 +357,9 @@ impl Entity {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_invulnerable_to(&self, damage_type: DamageType) -> bool {
|
pub fn is_invulnerable_to(&self, damage_type: &DamageType) -> bool {
|
||||||
self.invulnerable.load(std::sync::atomic::Ordering::Relaxed)
|
self.invulnerable.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|| self.damage_immunities.contains(&damage_type)
|
|| self.damage_immunities.contains(damage_type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -355,7 +355,7 @@ impl Player {
|
|||||||
|
|
||||||
victim
|
victim
|
||||||
.living_entity
|
.living_entity
|
||||||
.damage(damage as f32, DamageType::PlayerAttack) // PlayerAttack
|
.damage(damage as f32, DamageType::PLAYER_ATTACK)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let mut knockback_strength = 1.0;
|
let mut knockback_strength = 1.0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user