Skip to content

Java 接口(进阶) ​

用车包就不需要这一页。写成附属模组的好处是能和自己模组的其他内容放在一起,资源和车包完全一样(只是放在模组的 src/main/resources 里)。示例工程是 VetturaExample。

准备工程 ​

  1. 复制 VetturaExample 整个文件夹,改 gradle.properties 里的 mod_id、mod_name、mod_group_id,再把 Java 包名和 assets/vettura_example、data/vettura_example 文件夹改成你的模组 ID。
  2. gradle.properties 里的 vettura_repo 和 vextris_repo 指向两个库的 Maven 仓库(示例里是本地文件夹;正式发布后改成线上地址)。
  3. build.gradle 用 implementation fg.deobf(...) 依赖 Vettura 和 Vextris:开发环境里它们作为独立模组加载,不要把它们打进你的 jar。
  4. META-INF/mods.toml 要声明依赖 vettura,ordering="AFTER"。
  5. 开发环境需要的两行 mixin 属性已经写在示例的 build.gradle 里(mixin.env.remapRefMap、mixin.env.refMapRemappingFile),不要删。

编译:.\gradlew.bat build。启动客户端:.\gradlew.bat runClient。

注册(四件东西) ​

示例代码在 src/main/java/com/example/vetturaexample/VetturaExample.java,顺序不能乱:

java
// 1. 车型:物理参数、车身布局、声音、损伤界面的玻璃位置。必须在实体类型创建之前注册
public static final VehicleType COUPE = VehicleType.builder(COUPE_ID)
        .spec(coupeSpec())
        .layout(coupeLayout())
        .hudPanes(...)          // 可选
        .sounds(...)            // 可选,不写就用 T15 的柴油机声音
        .fuel(Fuel.PETROL)      // 可选,不写是柴油
        .keyless()              // 可选:一键启动(钥匙带在身上,按住启动键);不写是插钥匙、拧钥匙
        .paints(List.of(new VehicleSpawnerItem.Paint("my_red", 0xA51616, 0xA51616), ...))   // 可选:出厂漆色(主色、副色),至少两种
        .handbrake(null, null)  // 可选:手刹拉起、放下的声音;null 表示不响(电子手刹);不写是 T15 的棘轮手刹
        .shiftSound(null)       // 可选:换挡声;null 表示不响(自动挡);不写是 T15 的换挡杆声
        .register();

// 2. 实体类型:就是 Vettura 的载具实体,ID 和车型相同
ENTITY_TYPES.register("whitebox_coupe",
        () -> EntityType.Builder.<PickupTruckEntity>of(PickupTruckEntity::new, MobCategory.MISC)
                .sized(1.9F, 1.4F).clientTrackingRange(10).build("whitebox_coupe"));

// 3. 生成器和钥匙
ITEMS.register("whitebox_coupe", () -> new VehicleSpawnerItem(new Item.Properties().stacksTo(1), COUPE_ENTITY));
ITEMS.register("whitebox_coupe_key", () -> new VehicleKeyItem(new Item.Properties().stacksTo(1), COUPE_ID));

// 4. 客户端:用 Vettura 的渲染器
event.registerEntityRenderer(COUPE_ENTITY.get(), PickupTruckRenderer::new);

实体通过实体类型的 ID 找到车型(VehicleType.of),所以两者的 ID 必须一致。实体的 sized 只影响原版的选取框和寻路,真正的碰撞来自车身布局和碰撞外壳。