Skip to content

Commit 0e37543

Browse files
zly2006Snowiiii
andauthored
Improve entity damage handling & entity name, Add death message & void damage, Weak reference to server in worlds. (Pumpkin-MC#961)
* fix: enhance damage handling with context in LivingEntity * feat: add out-of-world damage handling Fix: Pumpkin-MC#957 * fix: refine damage handling with context for entities * fix: clippy * feat: death message * fix * fix * fix * fix: review suggestions * fix * Update mod.rs * fix display name * fix display name * fix clippy * fix clippy * fix * fix * fix world load * fix logger timestamp * fix logger timestamp * fix compiling * fix fall damage * fix: pass fat ptr in damage_with_context * refactor: Refactor commands to use styled name instead of plain text. --------- Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
1 parent 2174488 commit 0e37543

30 files changed

Lines changed: 516 additions & 301 deletions

File tree

pumpkin-world/src/lock/anvil.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const SNOWMAN: &[u8] = "☃".as_bytes();
1414

1515
impl LevelLocker<Self> for AnvilLevelLocker {
1616
fn lock(folder: &Path) -> Result<Self, LockError> {
17+
std::fs::create_dir_all(folder).map_err(|_| LockError::FailedWrite)?;
1718
let file_path = folder.join(SESSION_LOCK_FILE_NAME);
1819
let mut file = File::options()
1920
.create(true)

pumpkin/src/command/args/resource/damage_type.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl ArgumentConsumer for DamageTypeArgumentConsumer {
3636
args: &mut RawArgs<'a>,
3737
) -> Option<Arg<'a>> {
3838
let name = args.pop()?;
39+
let name = name.strip_prefix("minecraft:").unwrap_or(name);
3940

4041
// Create a static damage type first
4142
let damage_type = DamageType::from_name(name)?;

pumpkin/src/command/commands/ban.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::entity::EntityBase;
12
use crate::{
23
command::{
34
CommandError, CommandExecutor, CommandSender,
@@ -90,10 +91,7 @@ async fn ban_player(sender: &CommandSender, player: &Player, reason: Option<Stri
9091
sender
9192
.send_message(TextComponent::translate(
9293
"commands.ban.success",
93-
[
94-
TextComponent::text(player.gameprofile.name.clone()),
95-
TextComponent::text(reason),
96-
],
94+
[player.get_display_name().await, TextComponent::text(reason)],
9795
))
9896
.await;
9997

pumpkin/src/command/commands/clear.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ use std::sync::Arc;
22

33
use async_trait::async_trait;
44
use pumpkin_util::text::TextComponent;
5-
use pumpkin_util::text::click::ClickEvent;
65
use pumpkin_util::text::color::NamedColor;
7-
use pumpkin_util::text::hover::HoverEvent;
86
use pumpkin_world::item::ItemStack;
97

108
use crate::command::args::entities::EntitiesArgumentConsumer;
119
use crate::command::args::{Arg, ConsumedArgs};
1210
use crate::command::tree::CommandTree;
1311
use crate::command::tree::builder::{argument, require};
1412
use crate::command::{CommandError, CommandExecutor, CommandSender};
13+
use crate::entity::EntityBase;
1514
use crate::entity::player::Player;
1615
use CommandError::InvalidConsumption;
1716

@@ -42,26 +41,17 @@ async fn clear_player(target: &Player) -> u64 {
4241
count
4342
}
4443

45-
fn clear_command_text_output(item_count: u64, targets: &[Arc<Player>]) -> TextComponent {
44+
async fn clear_command_text_output(item_count: u64, targets: &[Arc<Player>]) -> TextComponent {
4645
match targets {
47-
[target] if item_count == 0 => TextComponent::translate(
48-
"clear.failed.single",
49-
[TextComponent::text(target.gameprofile.name.clone())],
50-
)
51-
.color_named(NamedColor::Red),
46+
[target] if item_count == 0 => {
47+
TextComponent::translate("clear.failed.single", [target.get_display_name().await])
48+
.color_named(NamedColor::Red)
49+
}
5250
[target] => TextComponent::translate(
5351
"commands.clear.success.single",
5452
[
5553
TextComponent::text(item_count.to_string()),
56-
TextComponent::text(target.gameprofile.name.clone())
57-
.click_event(ClickEvent::SuggestCommand {
58-
command: format!("/tell {} ", target.gameprofile.name.clone()).into(),
59-
})
60-
.hover_event(HoverEvent::show_entity(
61-
target.living_entity.entity.entity_uuid.to_string(),
62-
target.living_entity.entity.entity_type.resource_name.into(),
63-
Some(TextComponent::text(target.gameprofile.name.clone())),
64-
)),
54+
target.get_display_name().await,
6555
],
6656
),
6757
targets if item_count == 0 => TextComponent::translate(
@@ -98,7 +88,7 @@ impl CommandExecutor for Executor {
9888
item_count += clear_player(target).await;
9989
}
10090

101-
let msg = clear_command_text_output(item_count, targets);
91+
let msg = clear_command_text_output(item_count, targets).await;
10292

10393
sender.send_message(msg).await;
10494

@@ -121,7 +111,7 @@ impl CommandExecutor for SelfExecutor {
121111
let item_count = clear_player(&target).await;
122112

123113
let hold_target = [target];
124-
let msg = clear_command_text_output(item_count, &hold_target);
114+
let msg = clear_command_text_output(item_count, &hold_target).await;
125115

126116
sender.send_message(msg).await;
127117

pumpkin/src/command/commands/damage.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::command::{
1717
builder::{argument, literal},
1818
},
1919
};
20+
use crate::entity::EntityBase;
2021

2122
const NAMES: [&str; 1] = ["damage"];
2223
const DESCRIPTION: &str = "Deals damage to entities";
@@ -38,7 +39,7 @@ async fn send_damage_result(
3839
sender: &mut CommandSender,
3940
success: bool,
4041
amount: f32,
41-
target_name: String,
42+
target_name: TextComponent,
4243
) {
4344
if !success {
4445
sender
@@ -53,10 +54,7 @@ async fn send_damage_result(
5354
sender
5455
.send_message(TextComponent::translate(
5556
"commands.damage.success",
56-
[
57-
TextComponent::text(amount.to_string()),
58-
TextComponent::text(target_name),
59-
],
57+
[TextComponent::text(amount.to_string()), target_name],
6058
))
6159
.await;
6260
}
@@ -95,7 +93,7 @@ impl CommandExecutor for LocationExecutor {
9593
.damage_with_context(amount, damage_type, Some(location), None, None)
9694
.await;
9795

98-
send_damage_result(sender, success, amount, target.gameprofile.name.clone()).await;
96+
send_damage_result(sender, success, amount, target.get_display_name().await).await;
9997

10098
Ok(())
10199
}
@@ -141,12 +139,12 @@ impl CommandExecutor for EntityExecutor {
141139
amount,
142140
damage_type,
143141
None,
144-
source.as_ref().map(|e| &e.living_entity.entity),
145-
cause.as_ref().map(|e| &e.living_entity.entity),
142+
source.as_ref().map(|e| e.as_ref() as &dyn EntityBase),
143+
cause.as_ref().map(|e| e.as_ref() as &dyn EntityBase),
146144
)
147145
.await;
148146

149-
send_damage_result(sender, success, amount, target.gameprofile.name.clone()).await;
147+
send_damage_result(sender, success, amount, target.get_display_name().await).await;
150148

151149
Ok(())
152150
}

pumpkin/src/command/commands/deop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::entity::EntityBase;
12
use crate::{
23
command::{
34
CommandError, CommandExecutor, CommandSender,
@@ -48,10 +49,9 @@ impl CommandExecutor for Executor {
4849
.await;
4950
};
5051

51-
let player_name = &player.gameprofile.name;
5252
let msg = TextComponent::translate(
5353
"commands.deop.success",
54-
[TextComponent::text(player_name.clone())],
54+
[player.get_display_name().await],
5555
);
5656
sender.send_message(msg).await;
5757
}

pumpkin/src/command/commands/effect.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::command::dispatcher::CommandError::InvalidConsumption;
99
use crate::command::tree::CommandTree;
1010
use crate::command::tree::builder::{argument, literal};
1111
use crate::command::{CommandExecutor, CommandSender};
12+
use crate::entity::EntityBase;
1213
use crate::server::Server;
1314
use async_trait::async_trait;
1415
use pumpkin_util::text::color::{Color, NamedColor};
@@ -129,10 +130,7 @@ impl CommandExecutor for GiveExecutor {
129130
sender
130131
.send_message(TextComponent::translate(
131132
"commands.effect.give.success.single",
132-
[
133-
translation_name,
134-
TextComponent::text(targets[0].gameprofile.name.clone()),
135-
],
133+
[translation_name, targets[0].get_display_name().await],
136134
))
137135
.await;
138136
} else {
@@ -190,7 +188,7 @@ impl CommandExecutor for ClearExecutor {
190188
sender
191189
.send_message(TextComponent::translate(
192190
"commands.effect.clear.everything.success.single",
193-
[TextComponent::text(targets[0].gameprofile.name.to_string())],
191+
[targets[0].get_display_name().await],
194192
))
195193
.await;
196194
} else {
@@ -234,7 +232,7 @@ impl CommandExecutor for ClearExecutor {
234232
"commands.effect.clear.specific.success.single",
235233
[
236234
TextComponent::text(effect.to_name()),
237-
TextComponent::text(targets[0].gameprofile.name.to_string()),
235+
targets[0].get_display_name().await,
238236
],
239237
))
240238
.await;

pumpkin/src/command/commands/experience.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::command::args::{ConsumedArgs, FindArg};
1111
use crate::command::tree::CommandTree;
1212
use crate::command::tree::builder::{argument, literal};
1313
use crate::command::{CommandError, CommandExecutor, CommandSender};
14+
use crate::entity::EntityBase;
1415
use crate::entity::player::Player;
1516

1617
const NAMES: [&str; 2] = ["experience", "xp"];
@@ -52,7 +53,7 @@ impl Executor {
5253
.send_message(TextComponent::translate(
5354
"commands.experience.query.levels",
5455
[
55-
TextComponent::text(target.gameprofile.name.clone()),
56+
target.get_display_name().await,
5657
TextComponent::text(level.to_string()),
5758
],
5859
))
@@ -64,7 +65,7 @@ impl Executor {
6465
.send_message(TextComponent::translate(
6566
"commands.experience.query.points",
6667
[
67-
TextComponent::text(target.gameprofile.name.clone()),
68+
target.get_display_name().await,
6869
TextComponent::text(points.to_string()),
6970
],
7071
))
@@ -78,7 +79,7 @@ impl Executor {
7879
exp_type: ExpType,
7980
amount: i32,
8081
targets_len: usize,
81-
target_name: Option<String>,
82+
target_name: Option<TextComponent>,
8283
) -> TextComponent {
8384
match (mode, exp_type) {
8485
(Mode::Add, ExpType::Points) => {
@@ -95,7 +96,7 @@ impl Executor {
9596
"commands.experience.add.points.success.single",
9697
[
9798
TextComponent::text(amount.to_string()),
98-
TextComponent::text(target_name.unwrap()),
99+
target_name.unwrap(),
99100
],
100101
)
101102
}
@@ -114,7 +115,7 @@ impl Executor {
114115
"commands.experience.add.levels.success.single",
115116
[
116117
TextComponent::text(amount.to_string()),
117-
TextComponent::text(target_name.unwrap()),
118+
target_name.unwrap(),
118119
],
119120
)
120121
}
@@ -133,7 +134,7 @@ impl Executor {
133134
"commands.experience.set.points.success.single",
134135
[
135136
TextComponent::text(amount.to_string()),
136-
TextComponent::text(target_name.unwrap()),
137+
target_name.unwrap(),
137138
],
138139
)
139140
}
@@ -152,7 +153,7 @@ impl Executor {
152153
"commands.experience.set.levels.success.single",
153154
[
154155
TextComponent::text(amount.to_string()),
155-
TextComponent::text(target_name.unwrap()),
156+
target_name.unwrap(),
156157
],
157158
)
158159
}
@@ -247,7 +248,7 @@ impl CommandExecutor for Executor {
247248
self.exp_type.unwrap(),
248249
amount,
249250
targets.len(),
250-
Some(target.gameprofile.name.clone()),
251+
Some(target.get_display_name().await),
251252
);
252253
sender.send_message(msg).await;
253254
}

pumpkin/src/command/commands/gamemode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::command::dispatcher::CommandError::{InvalidConsumption, InvalidRequir
1414
use crate::command::tree::CommandTree;
1515
use crate::command::tree::builder::{argument, require};
1616
use crate::command::{CommandExecutor, CommandSender};
17+
use crate::entity::EntityBase;
1718
use crate::server::Server;
1819

1920
const NAMES: [&str; 1] = ["gamemode"];
@@ -91,7 +92,7 @@ impl CommandExecutor for TargetPlayerExecutor {
9192
.send_message(TextComponent::translate(
9293
"commands.gamemode.success.other",
9394
[
94-
TextComponent::text(target.gameprofile.name.clone()),
95+
target.get_display_name().await,
9596
TextComponent::translate(gamemode_string, []),
9697
],
9798
))

pumpkin/src/command/commands/give.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use async_trait::async_trait;
22
use pumpkin_data::data_component::DataComponent::MaxStackSize;
33
use pumpkin_data::data_component_impl::{MaxStackSizeImpl, get};
44
use pumpkin_util::text::TextComponent;
5-
use pumpkin_util::text::click::ClickEvent;
65
use pumpkin_util::text::color::{Color, NamedColor};
76
use pumpkin_util::text::hover::HoverEvent;
87
use pumpkin_world::item::ItemStack;
@@ -14,6 +13,7 @@ use crate::command::args::{ConsumedArgs, FindArg, FindArgDefaultName};
1413
use crate::command::tree::CommandTree;
1514
use crate::command::tree::builder::{argument, argument_default_name};
1615
use crate::command::{CommandError, CommandExecutor, CommandSender};
16+
use crate::entity::EntityBase;
1717

1818
const NAMES: [&str; 1] = ["give"];
1919

@@ -95,21 +95,7 @@ impl CommandExecutor for Executor {
9595
id: item_name.to_string().into(),
9696
count: Some(item_count),
9797
}),
98-
TextComponent::text(targets[0].gameprofile.name.to_string())
99-
.hover_event(HoverEvent::show_entity(
100-
targets[0].living_entity.entity.entity_uuid.to_string(),
101-
targets[0]
102-
.living_entity
103-
.entity
104-
.entity_type
105-
.resource_name
106-
.into(),
107-
Some(TextComponent::text(targets[0].gameprofile.name.clone())),
108-
))
109-
.click_event(ClickEvent::SuggestCommand {
110-
command: format!("/tell {} ", targets[0].gameprofile.name.clone())
111-
.into(),
112-
}),
98+
targets[0].get_display_name().await,
11399
],
114100
)
115101
} else {

0 commit comments

Comments
 (0)