Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions minecraft-mods/bettermace/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Gradle
.gradle/
build/
out/
classes/

# IDEA
.idea/
*.iml
*.ipr
*.iws

# Eclipse
.settings/
.metadata/
.classpath
.project
bin/

# fabric-loom
.fabric/
run/

# OS
.DS_Store
Thumbs.db
77 changes: 77 additions & 0 deletions minecraft-mods/bettermace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# BetterMace

Мод для Minecraft **1.21.4** (Fabric), улучшающий использование Булавы (Mace).

> Зачем: ваниль уже неплохая, но смэш-атакой можно бить только одну цель. Этот мод делает Mace ощутимо полезнее — особенно в толпах мобов и в PvE-рейдах.

## Возможности

- **AOE-удар по площади при смэш-атаке.** Когда вы успешно бьёте врага в прыжке/падении (как ванильный smash), все враги в радиусе вокруг цели получают долю бонусного урона от падения.
- Радиус AOE масштабируется по высоте падения (есть верхний предел).
- Соседние цели слегка отбрасываются наружу от точки удара.
- Срабатывает только при настоящем смэше (fall distance > порога, без элитр).
- **Опциональная молния** при экстремально высоком падении (по умолчанию выключена; можно сделать чисто визуальной или с уроном).
- **Опциональный «прыжок» (self-bounce)** игроку после удачного смэша — дополняет ванильный Wind Burst.
- **Полностью настраивается** через `config/bettermace.json` (создастся автоматически при первом запуске).
- Не ломает ванильную логику Density / Breach / Wind Burst — работает поверх неё.

## Конфиг (`config/bettermace.json`)

| Поле | По умолчанию | Описание |
|---|---|---|
| `aoeEnabled` | `true` | Включить AOE-удар по площади |
| `aoeRadius` | `2.5` | Базовый радиус AOE (блоки) |
| `aoeRadiusPerFallBlock` | `0.15` | Прибавка к радиусу за каждый блок падения |
| `aoeRadiusMax` | `3.5` | Максимальная прибавка к радиусу |
| `aoeRadiusVertical` | `1.5` | Вертикальная полу-высота зоны |
| `aoeDamageMultiplier` | `0.6` | Доля fall-bonus урона по соседям |
| `aoeKnockbackStrength` | `0.45` | Отбрасывание соседних целей |
| `aoeMinFallDistance` | `1.5` | Минимальное падение для AOE |
| `ignoreTeammates` | `true` | Не бить союзников |
| `lightningOnCriticalFall` | `false` | Молния при сильном падении |
| `lightningFallDistance` | `12.0` | С какого падения призывать молнию |
| `lightningDamages` | `false` | Наносит ли молния урон |
| `smashSelfBounce` | `0.0` | Доп. вертикальный импульс игроку после смэша |

## Зависимости / совместимость

- Minecraft `1.21.4`
- Fabric Loader `>= 0.16.0`
- Fabric API `0.114.0+1.21.4` (или совместимая для 1.21.4)
- Java `21`

### Про Forge / NeoForge

Под Minecraft 1.21.4 Forge как такового активно не разрабатывается — эквивалент это **NeoForge**. Этот мод сейчас собран только под Fabric. Для NeoForge-версии понадобится отдельный лоадер (можно сделать через мульти-лоадер шаблон Architectury) — это не входит в текущую сборку.

## Сборка

```bash
cd minecraft-mods/bettermace
./gradlew build # на первый запуск создаст gradle wrapper jar при необходимости
# Готовый .jar появится в build/libs/bettermace-<version>.jar
```

> Для первого билда нужен интернет — Loom скачает Minecraft + Yarn + Fabric API.

## Установка

1. Установите [Fabric Loader](https://fabricmc.net/use/installer/) для 1.21.4.
2. Положите в папку `mods/`:
- `fabric-api-<version>.jar`
- `bettermace-<version>.jar`
3. Запустите игру. При первом старте появится `config/bettermace.json` — поправьте под себя.

## Как это работает (под капотом)

Мод подмешивается (`@Mixin`) в `net.minecraft.item.MaceItem#postHurtEnemy` и при условии настоящего смэш-удара:

1. Берёт `player.fallDistance` и считает «ванильную» формулу бонусного урона (`4/2/1` за блок по сегментам `0-3 / 3-8 / 8+`).
2. Находит соседних `LivingEntity` в `Box.expand(radius, vertical, radius)` вокруг ударенной цели.
3. Наносит каждому `aoeDamageMultiplier * bonus` урона через `DamageSources.mobAttack(attacker)`.
4. Толкает их наружу + спавнит партиклы `SWEEP_ATTACK` + проигрывает `MACE_SMASH_GROUND_HEAVY`.
5. По желанию — призывает молнию и/или подбрасывает игрока.

## Лицензия

MIT — см. корень репозитория.
74 changes: 74 additions & 0 deletions minecraft-mods/bettermace/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
plugins {
id 'fabric-loom' version '1.9-SNAPSHOT'
id 'maven-publish'
}

version = project.mod_version
group = project.maven_group

base {
archivesName = project.archives_base_name
}

repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}

dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}

processResources {
inputs.property "version", project.version

filesMatching("fabric.mod.json") {
expand "version": inputs.properties.version
}
}

tasks.withType(JavaCompile).configureEach {
it.options.release = 21
}

java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()

sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}" }
}
}

// configure the maven publication
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}

// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for retrieving dependencies.
}
}
17 changes: 17 additions & 0 deletions minecraft-mods/bettermace/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx2G
org.gradle.parallel=true

# Fabric Properties
# check these on https://fabricmc.net/develop/
minecraft_version=1.21.4
yarn_mappings=1.21.4+build.8
loader_version=0.16.9

# Mod Properties
mod_version=1.0.0
maven_group=dev.bettermace
archives_base_name=bettermace

# Dependencies
fabric_version=0.114.0+1.21.4
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
12 changes: 12 additions & 0 deletions minecraft-mods/bettermace/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
mavenCentral()
gradlePluginPortal()
}
}

rootProject.name = 'bettermace'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.bettermace;

import dev.bettermace.config.BetterMaceConfig;
import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BetterMace implements ModInitializer {
public static final String MOD_ID = "bettermace";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

@Override
public void onInitialize() {
BetterMaceConfig.load();
LOGGER.info("[BetterMace] loaded. AOE radius={}, AOE multiplier={}, lightning={}.",
BetterMaceConfig.get().aoeRadius,
BetterMaceConfig.get().aoeDamageMultiplier,
BetterMaceConfig.get().lightningOnCriticalFall);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dev.bettermace.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.bettermace.BetterMace;
import net.fabricmc.loader.api.FabricLoader;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Конфиг мода. Хранится в config/bettermace.json и читается при старте мода.
*/
public class BetterMaceConfig {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static BetterMaceConfig INSTANCE = new BetterMaceConfig();

// === AOE smash attack ===
/** Включает удар по площади при смэш-атаке булавы. */
public boolean aoeEnabled = true;
/** Базовый радиус AOE (в блоках). */
public double aoeRadius = 2.5;
/** Дополнительный радиус за каждый блок падения. */
public double aoeRadiusPerFallBlock = 0.15;
/** Максимальная прибавка к радиусу от падения. */
public double aoeRadiusMax = 3.5;
/** Вертикальная половина-высота AOE box. */
public double aoeRadiusVertical = 1.5;
/** Множитель урона по соседним целям относительно бонуса от падения. */
public float aoeDamageMultiplier = 0.6f;
/** Сила отбрасывания соседних целей наружу. */
public double aoeKnockbackStrength = 0.45;
/** Минимальное расстояние падения для активации AOE. */
public float aoeMinFallDistance = 1.5f;
/** Не атаковать союзников/тех-же-команда сущностей. */
public boolean ignoreTeammates = true;

// === Optional lightning on extreme fall ===
/** Призывать молнию при особо высоком падении. */
public boolean lightningOnCriticalFall = false;
/** Минимальное расстояние падения (блоков) для молнии. */
public float lightningFallDistance = 12.0f;
/** Молния наносит урон/поджигает (false = только визуал). */
public boolean lightningDamages = false;

// === Wind burst boost ===
/** Дополнительный вертикальный импульс игроку при удачном смэше (бонус к Wind Burst). */
public double smashSelfBounce = 0.0;

public static BetterMaceConfig get() {
return INSTANCE;
}

public static void load() {
Path path = FabricLoader.getInstance().getConfigDir().resolve("bettermace.json");
try {
if (Files.exists(path)) {
String json = Files.readString(path);
BetterMaceConfig loaded = GSON.fromJson(json, BetterMaceConfig.class);
if (loaded != null) {
INSTANCE = loaded;
}
} else {
save();
}
} catch (IOException | RuntimeException e) {
BetterMace.LOGGER.error("[BetterMace] failed to load config, using defaults", e);
INSTANCE = new BetterMaceConfig();
}
}

public static void save() {
Path path = FabricLoader.getInstance().getConfigDir().resolve("bettermace.json");
try {
Files.createDirectories(path.getParent());
Files.writeString(path, GSON.toJson(INSTANCE));
} catch (IOException e) {
BetterMace.LOGGER.error("[BetterMace] failed to save config", e);
}
}
}
Loading