Q to drop

This commit is contained in:
2026-09-25 16:42:19 -03:00
parent a254b96f65
commit d107405f62
6 changed files with 116 additions and 0 deletions
+49
View File
@@ -310,6 +310,26 @@ export class GameServer {
return entity;
}
// out of the player's face the way they're looking, like minecraft's Player.drop
throw_item(player: ServerPlayer, stack: ItemStack) {
const entity = this.spawn_item(
player.x,
player.y + PLAYER_EYE_HEIGHT - 0.3,
player.z,
stack,
PLAYER_DROP_PICKUP_DELAY,
);
// minecraft's numbers are per tick
const speed = 0.3 * TICKS_PER_SECOND;
const cos_pitch = Math.cos(player.pitch);
const spread_angle = Math.random() * Math.PI * 2;
const spread = Math.random() * 0.02 * TICKS_PER_SECOND;
entity.vx = -Math.sin(player.yaw) * cos_pitch * speed + Math.cos(spread_angle) * spread;
entity.vy = Math.sin(player.pitch) * speed + (0.1 + (Math.random() - Math.random()) * 0.1) * TICKS_PER_SECOND;
entity.vz = -Math.cos(player.yaw) * cos_pitch * speed + Math.sin(spread_angle) * spread;
return entity;
}
item_entities(): ItemEntity[] {
return [...this.#entities.values()];
}
@@ -504,6 +524,9 @@ export class GameServer {
case "click":
this.#click(player, message.container, message.index, message.button);
break;
case "drop_item":
this.#drop_item(player, message.container, message.index, message.all === true);
break;
case "close_screen":
this.#close_screen(player);
break;
@@ -645,6 +668,32 @@ export class GameServer {
this.mods.after.block_place.emit(place);
}
#drop_item(player: ServerPlayer, key: unknown, index: unknown, all: boolean) {
if (!is_int(index)) {
return;
}
const container = this.#get_container(player, key as ContainerKey);
// the crafting result isn't an item yet, minecraft crafts it first but that's not supported
if (
!container || index < 0 || index >= container.size || (key === "crafting" && index === CRAFTING_RESULT_SLOT)
) {
return;
}
const item = container.get_item(index);
if (!item) {
return;
}
const thrown = item.clone();
thrown.amount = all ? item.amount : 1;
item.amount -= thrown.amount;
container.set_item(index, item.amount > 0 ? item : undefined);
if (key === "crafting") {
update_crafting_result(container, this.recipes.shaped);
}
this.throw_item(player, thrown);
}
#click(player: ServerPlayer, key: unknown, index: unknown, button: unknown) {
if (!is_int(index) || !is_int(button)) {
return;